.table td,.table th,.table-all td,.table-all th{padding:8px 8px;display:table-cell;text-align:left;vertical-align:top}
.table th:first-child,.table td:first-child,.table-all th:first-child,.table-all td:first-child{padding-left:16px}
.btn,.button{border:none;display:inline-block;padding:8px 16px;vertical-align:middle;overflow:hidden;text-decoration:none;color:inherit;background-color:inherit;text-align:center;cursor:pointer;white-space:nowrap}
-.btn:hover{box-shadow:0 8px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)}
+.btn:hover{box-shadow:0 8px 16px 0 #00000033,0 6px 20px 0 #00000030}
.btn,.button{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
.disabled,.btn:disabled,.button:disabled{cursor:not-allowed;background-color: #e6e6e6}.disabled *,:disabled *{pointer-events:none}
.btn.disabled:hover,.btn:disabled:hover{box-shadow:none}
.ul{list-style-type:none;padding:0;margin:0}.ul li{padding:8px 16px;border-bottom:1px solid #ddd}.ul li:last-child{border-bottom:none}
.tooltip,.display-container{position:relative}.tooltip .text{display:none}.tooltip:hover .text{display:inline-block}
.ripple:active{opacity:0.5}.ripple{transition:opacity 0s}
-.input{padding:6px;display:block;border: 1px solid #ccc;width:100%;background-color: #fff; }/*#e8f0fe*/
+.input{padding:6px;display:block;border: 1px solid #ccc;width:100%;background-color: #fff; border-radius: 3px; }/*#e8f0fe*/
.select{padding:2px 0; display:block;width:100%;border:1px solid #ccc;background-color: #fff;}
.dropdown-click,.dropdown-hover{position:relative;display:inline-block;cursor:pointer}
.dropdown-hover:hover .dropdown-content{display:block; }
.bar-block .dropdown-hover .dropdown-content,.bar-block .dropdown-click .dropdown-content{min-width:100%}
.bar-block .dropdown-hover .button,.bar-block .dropdown-click .button{width:100%;text-align:left;padding:8px 16px}
.main,#main{transition:margin-left .4s}
-.modal{z-index:3;display:none;padding-top:100px;position:fixed;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:rgb(0,0,0);background-color:rgba(0,0,0,0.4)}
+.modal{z-index:3;display:none;padding-top:100px;position:fixed;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:#000000;background-color:#00000066}
.modal-content{margin:auto;background-color:#fff;position:relative;padding:0;outline:0;width:600px}
.bar{width:100%}.center .bar{display:inline-block;width:auto}
.bar .bar-item{padding:6px 6px;float:left;width:auto; min-width: 50px;border:none;display:block;outline:0}
@media (max-width:992px) and (min-width:601px){.hide-medium{display:none!important}}
@media (max-width:992px){.sidebar.collapse{display:none}.main{margin-left:0!important;margin-right:0!important}.auto{max-width:100%}}
.top,.bottom{position:fixed;width:100%;z-index:1}.top{top:0}.bottom{bottom:0}
-.overlay{position:fixed;display:none;width:100%;height:100%;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,0.5);z-index:2}
+.overlay{position:fixed;display:none;width:100%;height:100%;top:0;left:0;right:0;bottom:0;background-color:#00000080;z-index:2}
.display-topleft{position:absolute;left:0;top:0}.display-topright{position:absolute;right:0;top:0}
.display-bottomleft{position:absolute;left:0;bottom:0}.display-bottomright{position:absolute;right:0;bottom:0}
.display-middle{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%)}
.code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word}
.codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%}
.card,.card-2{box-shadow:0 2px 5px 0 rgba(0,0,0,0.16)}
-.card-4,.hover-shadow:hover{box-shadow:0 4px 10px 0 rgba(0,0,0,0.2),0 4px 20px 0 rgba(0,0,0,0.19)}
+.card-4,.hover-shadow:hover{box-shadow:0 4px 10px 0 #00000033,0 4px 20px 0 #00000030}
.spin{animation:spin 2s infinite linear}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}
.animate-fading{animation:fading 2s infinite}@keyframes fading{0%{opacity:0}50%{opacity:1}100%{opacity:0}}
.animate-opacity{animation:opac 0.8s}@keyframes opac{from{opacity:0} to{opacity:1}}
textarea
{
background-color: #fff;
- border-top-color: rgba(80%,80%,80%,1);
- border-right-color: rgba(80%,80%,80%,1);
- border-bottom-color: rgba(80%,80%,80%,1);
- border-left-color: rgba(80%,80%,80%,1);
- border-top-style: solid;
- border-right-style: solid;
- border-bottom-style: solid;
- border-left-style: solid;
- border-top-width: 1pt;
- border-right-width: 1pt;
- border-bottom-width: 1pt;
- border-left-width: 1pt;
+ border-color: #cccccc;
+ border-style: solid;
+ border-width: 1pt;
font-size: 11pt;
color: #000;
line-height: 1line;
}
textarea:focus
{
- border-top-color: rgba(0%,43.9216%,81.1765%,1);
- border-right-color: rgba(0%,43.9216%,81.1765%,1);
- border-bottom-color: rgba(0%,43.9216%,81.1765%,1);
- border-left-color: rgba(0%,43.9216%,81.1765%,1);
+ border-color: #0070cf;
}
textarea:placeholder
{
- color: rgba(80%,80%,80%,1);
+ color: #cccccc;
}
/* textarea .text
{
div.group_container
{
background-color: #e3e3e3;
- border-top-color: rgba(80%,80%,80%,1);
- border-right-color: rgba(80%,80%,80%,1);
- border-bottom-color: rgba(80%,80%,80%,1);
- border-left-color: rgba(80%,80%,80%,1);
- border-top-style: solid;
- border-right-style: solid;
- border-bottom-style: solid;
- border-left-style: solid;
- border-top-width: 1pt;
- border-right-width: 1pt;
- border-bottom-width: 1pt;
- border-left-width: 1pt;
+ border-color: #cccccc;
+ border-style: solid;
+ border-width: 1pt;
padding-top: 4px;
padding-bottom: 8px;
}
/* Custom Styles */
-.ListView_Default
+/* .ListView_Default
{
background-color: rgba(0%,0%,0%,0);
margin-right: 2pt;
margin-bottom: 2pt;
margin-left: 2pt;
-}
+} */
button.btnNavigation
{
- background-color: rgba(0%,0%,0%,0);
-
- font-family: -fm-font-family(Arial,Arial-BoldMT);
+ background-color: #00000000;
font-weight: bold;
font-size: 10pt;
color: #fff;
- padding-top: 0pt;
- padding-right: 0pt;
- padding-bottom: 0pt;
- padding-left: 0pt;
+ padding: 0pt;
}
-div.PageListHeader
+/* div.PageListHeader
{
border-top-color: rgba(80%,80%,80%,1);
border-right-color: rgba(80%,80%,80%,1);
padding-right: 5pt;
padding-bottom: 5pt;
padding-left: 5pt;
-}
+} */
.moduletoolbar
{
background-color: #293146;
color: #fff;
}
-
+/*
div.BodySectionHeader
{
font-family: -fm-font-family(Arial,Arial-BoldMT);
font-weight: bold;
-}
+} */
div.PageHeadTitle
div.SectionHeader
{
+ background-color: #394462;
- background-color: rgba(22.3529%,26.6667%,38.4314%,1);
+}
+.toolbarbtn > .icon {
+ font-size: 16px;
}
button.toolbarbtn
{
- border: 0.5px solid #c6c6c6;
- background-color: rgba(0%,0%,0%,0);
- color: #fff;
+ margin: 2px;
+ background-color:#394462!important;
+ border-radius: 2px;
+ border: 1px solid #c6c6c6!important;
+ color: #fff;
+
}
button.toolbarbtn:hover
{
-
- background-color: #343434;
+ background-color: #343434!important;
color: #fff;
}
button.toolbarbtn:pressed
{
-
- background-color: rgba(20.3922%,20.3922%,20.3922%,1);
+ background-color: #343434!important;
color: #fff;
}
button.toolbarbtn:focus
{
- border-top-color: rgba(80%,80%,80%,1);
- border-right-color: rgba(80%,80%,80%,1);
- border-bottom-color: rgba(80%,80%,80%,1);
- border-left-color: rgba(80%,80%,80%,1);
+ border-color: #cccccc!important;
}
a.toolbarbtn
{
+ border-radius: 2px;
border: 0.5px solid #c6c6c6;
- background-color: rgba(0%,0%,0%,0);
color: #fff;
text-align: center;
- text-decoration: unset;
+ text-decoration: unset;
+ font-size: 16px;
}
a.toolbarbtn:hover
{
- background-color: rgba(20.3922%,20.3922%,20.3922%,1);
+ background-color: #343434;
color: #fff;
}
a.toolbarbtn:pressed
{
- background-color: rgba(20.3922%,20.3922%,20.3922%,1);
+ background-color: #343434;
color: #fff;
}
a.toolbarbtn:focus
{
- border-top-color: rgba(80%,80%,80%,1);
- border-right-color: rgba(80%,80%,80%,1);
- border-bottom-color: rgba(80%,80%,80%,1);
- border-left-color: rgba(80%,80%,80%,1);
+ border-color: #cccccc;
}
button.bodybtn
{
+ border-radius: 2px;
border: 0.5px solid #c6c6c6;
-
- background-color: rgba(0%,0%,0%,0);
-
color: #000;
}
button.bodybtn:hover
{
-
- background-color: rgba(20.3922%,20.3922%,20.3922%,1);
+ background-color: #343434;
color: #fff;
}
button.bodybtn:pressed
{
-
- background-color: rgba(20.3922%,20.3922%,20.3922%,1);
+ background-color: #343434;
color: #fff;
}
button.bodybtn:focus
{
- border-top-color: rgba(80%,80%,80%,1);
- border-right-color: rgba(80%,80%,80%,1);
- border-bottom-color: rgba(80%,80%,80%,1);
- border-left-color: rgba(80%,80%,80%,1);
+ border-color: #cccccc;
}
a.bodybtn
{
- border: 0.5px solid #c6c6c6;
-
- background-color: rgba(0%,0%,0%,0);
-
+ border-radius: 2px;
color: #000;
text-align: center;
text-decoration: unset;
a.bodybtn:hover
{
- background-color: rgba(20.3922%,20.3922%,20.3922%,1);
+ background-color: #343434;
color: #fff;
}
a.bodybtn:pressed
{
- background-color: rgba(20.3922%,20.3922%,20.3922%,1);
+ background-color: #343434;
color: #fff;
}
a.bodybtn:focus
{
- border-top-color: rgba(80%,80%,80%,1);
- border-right-color: rgba(80%,80%,80%,1);
- border-bottom-color: rgba(80%,80%,80%,1);
- border-left-color: rgba(80%,80%,80%,1);
+ border-color: #cccccc;
}
-div.ListView_Header
+/* div.ListView_Header
{
border-top-color: rgba(80%,80%,80%,1);
border-right-color: rgba(80%,80%,80%,1);
padding-right: 2pt;
padding-bottom: 2pt;
padding-left: 2pt;
-}
+} */
div.toolbar
{
-
- background-color: rgba(32.1569%,38.8235%,55.6863%,1);
-
+ background-color: #52638e;
}
div.sectiontoolbar
{
margin-top: 8px;
margin-bottom: 8px;
- background-color: rgb(97, 98, 100);
-
-}
-
-div.FooterLabel
-{
- color: #fff;
-}
-
-button.Buttom_BodyNav:hover
-{
-
- background-color: rgb(141, 141, 141);
-
- /* color: #fff; */
+ background-color: #616264;
}
-
::-webkit-scrollbar {
-webkit-appearance: none;
width: 10px;
-webkit-box-shadow: 0 0 1px rgba(255, 255, 255, .5);
}
-div.portaltextheader {
- padding: 2px;
- border: 1px solid white;
-}
-
-
-
-
select {
/* -webkit-appearance: none; */
background-size: .65em auto, 100%; */
}
-
-/* option {
- appearance: none;
- border: 1px solid 0070cf;
- padding: 2px;
-} */
select:focus
{
border: 1px solid #3a6fc3;
div.DataFooter{
background: #384462;
}
-.input-sum{padding:2px;display:block;border: 1px solid #ccc;width:100%;background-color: #4D4D4D; }
+/* .input-sum{padding:2px;display:block;border: 1px solid #ccc;width:100%;background-color: #4D4D4D; }
.currency-sum {padding:2px;display:block;border: 1px solid #ccc;width:100%;background-color: #4D4D4D;}
background-repeat: no-repeat, repeat;
background-position: right 2px top 50%, 0 0;
background-size: 9px auto, 100%;
-}
+} */
<div class="row">
<div class="cell container" style="width: 300px;">
<label class="label" for="AddFiles_file_filesize">{{filesize}}</label>
- <input class="input border text data_formname readonly" data-column="column" data-id="" data-table="table" id="AddFiles_file_filesize" readonly>
+ <input class="input text data_formname readonly" data-column="column" data-id="" data-table="table" id="AddFiles_file_filesize" readonly>
</div>
</div>
</form>
</div>
<div class="cell container">
<label class="label" for="email_body">{{mail_body}}</label>
- <textarea class="input border data_email richeditarea" style="height: 400px;" data-id="" data-column="body" data-table="email" id="email_body" ></textarea>
+ <textarea class="input data_email richeditarea" style="height: 400px;" data-id="" data-column="body" data-table="email" id="email_body" ></textarea>
</div>
</div>
<div class="cell">
<div class="container row">
<div class="cell" style="width: 50px;">
<div class="">
- <label class="label" for="offerdetails_quantity">Anzahl</label> <input class="input border number data_offerdetails right-align" data-column="quantity" data-id="" data-table="offerdetails" id="offerdetails_quantity" name=
+ <label class="label" for="offerdetails_quantity">Anzahl</label> <input class="input number data_offerdetails right-align" data-column="quantity" data-id="" data-table="offerdetails" id="offerdetails_quantity" name=
"offerdetails_quantity" onblur="dataform.savefield(this);offer.calculate();" type="number">
</div>
</div>
<div class="cell" style="width: 90px;">
<div class="">
- <label class="label" for="offerdetails_unit">Einheit</label> <input class="input border text data_offerdetails" data-column="unit" data-id="" data-table="offerdetails" id="offerdetails_unit" name="offerdetails_unit" onblur=
+ <label class="label" for="offerdetails_unit">Einheit</label> <input class="input text data_offerdetails" data-column="unit" data-id="" data-table="offerdetails" id="offerdetails_unit" name="offerdetails_unit" onblur=
"dataform.savefield(this);" type="text">
</div>
</div>
<div class="cell" style="width: 100px;">
<div class="">
- <label class="label" for="offerdetails_unitamount">Preis</label> <input class="input border currency right-align data_offerdetails" data-column="unitamount" data-id="" data-table="offerdetails" id="offerdetails_unitamount"
+ <label class="label" for="offerdetails_unitamount">Preis</label> <input class="input currency right-align data_offerdetails" data-column="unitamount" data-id="" data-table="offerdetails" id="offerdetails_unitamount"
name="offerdetails_unitamount" onblur="dataform.savefield(this);offer.calculate();" type="number">
</div>
</div>
<div class="cell" style="width: 120px;">
<div class="">
- <label class="label" for="offerdetails_taxpercent">MwSt.(%)</label> <input class="input border number right-align data_offerdetails" data-column="taxpercent" data-id="" data-table="offerdetails" id="offerdetails_taxpercent"
+ <label class="label" for="offerdetails_taxpercent">MwSt.(%)</label> <input class="input number right-align data_offerdetails" data-column="taxpercent" data-id="" data-table="offerdetails" id="offerdetails_taxpercent"
name="offerdetails_taxpercent" onblur="dataform.savefield(this);offer.calculate();" type="number">
</div>
</div>
<div class="cell" style="width: 120px;">
<div class="">
- <label class="label" for="offerdetails_taxamount">Mehrwertsteuer</label> <input class="input border currency right-align data_offerdetails" data-column="taxamount" data-id="" data-table="offerdetails" id=
+ <label class="label" for="offerdetails_taxamount">Mehrwertsteuer</label> <input class="input currency right-align data_offerdetails" data-column="taxamount" data-id="" data-table="offerdetails" id=
"offerdetails_taxamount" name="offerdetails_taxamount" onblur="dataform.savefield(this);offer.calculate();" type="number">
</div>
</div>
<div class="cell right" style="width: 120px;">
<div class="">
- <label class="label" for="offerdetails_grossamount">Brutto</label> <input class="input border currency right-align data_offerdetails readonly" data-column="grossamount" data-id="" data-table="offerdetails" id=
+ <label class="label" for="offerdetails_grossamount">Brutto</label> <input class="input currency right-align data_offerdetails readonly" data-column="grossamount" data-id="" data-table="offerdetails" id=
"offerdetails_grossamount" name="offerdetails_grossamount" onblur="dataform.savefield(this);" readonly type="number">
</div>
</div>
<div class="cell right" style="width: 120px;">
<div class="">
- <label class="label" for="offerdetails_netamount">Netto</label> <input class="input border currency right-align data_offerdetails readonly" data-column="netamount" data-id="" data-table="offerdetails" id=
+ <label class="label" for="offerdetails_netamount">Netto</label> <input class="input currency right-align data_offerdetails readonly" data-column="netamount" data-id="" data-table="offerdetails" id=
"offerdetails_netamount" name="offerdetails_netamount" onblur="dataform.savefield(this);" readonly type="number">
</div>
</div>
<div class="container row">
<div class="cell" style="width: 150px;">
<div class="">
- <label class="label" for="offerdetails_sku">SKU</label> <input class="input border text data_offerdetails" data-column="sku" data-id="" data-table="offerdetails" id="offerdetails_sku" name="offerdetails_sku" onblur=
+ <label class="label" for="offerdetails_sku">SKU</label> <input class="input text data_offerdetails" data-column="sku" data-id="" data-table="offerdetails" id="offerdetails_sku" name="offerdetails_sku" onblur=
"dataform.savefield(this);" type="text">
</div>
</div>
<div class="container row">
<div class="cell" style="width: 400px;">
<div class="">
- <label class="label" for="offerdetails_name">Name</label> <input class="input border text data_offerdetails" data-column="name" data-id="" data-table="offerdetails" id="offerdetails_name" name="offerdetails_name" onblur=
+ <label class="label" for="offerdetails_name">Name</label> <input class="input text data_offerdetails" data-column="name" data-id="" data-table="offerdetails" id="offerdetails_name" name="offerdetails_name" onblur=
"dataform.savefield(this);" type="text">
</div>
</div>
<div class="cell" style="width: 400px;">
<div class="">
<label class="label" for="offerdetails_description">Beschreibung</label>
- <textarea class="input border data_offerdetails" data-column="description" data-id="" data-table="offerdetails" id="offerdetails_description" name="offerdetails_description" onblur="dataform.savefield(this);" style=
+ <textarea class="input data_offerdetails" data-column="description" data-id="" data-table="offerdetails" id="offerdetails_description" name="offerdetails_description" onblur="dataform.savefield(this);" style=
"height: 100px;"></textarea>
</div>
</div>
<!DOCTYPE html>
-<html lang="de">
+<html lang="en">
<head>
- <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
+ <meta charset="UTF-8">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<link href="vendor/tabulator/css/tabulator_site.css?v=6" rel="stylesheet">
<link href="vendor/slimselect/slimselect.css?v=6" rel="stylesheet">
<link href="vendor/flatpickr/flatpickr.min.css?v=6" rel="stylesheet">
<link href="vendor/flatpickr/themes/airbnb.css?v=6" rel="stylesheet">
<link href="vendor/codemirror/lib/codemirror.css" rel="stylesheet">
+ <link href="vendor/summernote/summernote-lite.css" rel="stylesheet">
<link href="css/icons.css?v=6" rel="stylesheet">
<link href="css/theme.css?v=6" rel="stylesheet">
+
+
+ <script src="vendor/tabulator/js/tabulator.js?v=6" type="text/javascript"></script>
+ <script src="vendor/moment/moment-with-locales.min.js?v=6" type="text/javascript"></script>
+ <script src="vendor/slimselect/slimselect.min.js?v=6" type="text/javascript"></script>
+ <script src="vendor/flatpickr/flatpickr.min.js?v=6" type="text/javascript"></script>
+ <script src="vendor/flatpickr/l10n/de.js?v=6" type="text/javascript"></script>
+ <script src="vendor/mustache/mustache.min.js?v=6" type="text/javascript"></script>
+ <script src="vendor/tinymce/js/tinymce/tinymce.min.js" type="text/javascript"></script>
+ <script src="vendor/codemirror/lib/codemirror.js" type="text/javascript"></script>
+ <script src="vendor/codemirror/addon/mode/overlay.js" type="text/javascript"></script>
+ <script src="vendor/codemirror/mode/xml/xml.js" type="text/javascript"></script>
+ <script src="vendor/codemirror/mode/css/css.js" type="text/javascript"></script>
+ <script src="vendor/codemirror/mode/javascript/javascript.js" type="text/javascript"></script>
+ <script src="js/tableformatters.js?v=6" type="text/javascript"></script>
+
+ <!-- <script src="js/tmceplugin.js?v=6" type="text/javascript"></script> -->
+ <script src="js/request.js?v=6" type="text/javascript"></script>
+ <script src="js/myapp.js?v=6" type="text/javascript"></script>
+ <script src="js/lang/de.js?v=6" type="text/javascript"></script>
+ <script src="js/lang/fr.js?v=6" type="text/javascript"></script>
+ <script src="js/dataform.js?v=6" type="text/javascript"></script>
+ <script src="js/timecalc.js?v=6" type="text/javascript"></script>
+ <script src="js/renderer.js?v=6" type="text/javascript"></script>
+ <script src="js/sqlite.js?v=6" type="text/javascript"></script>
+ <script src="js/report.js?v=6" type="text/javascript"></script>
<title>Invoice Journal</title>
</head>
<body>
</div>
- <script src="vendor/tabulator/js/tabulator.js?v=6" type="text/javascript"></script>
- <script src="vendor/moment/moment-with-locales.min.js?v=6" type="text/javascript"></script>
- <script src="vendor/slimselect/slimselect.min.js?v=6" type="text/javascript"></script>
- <script src="vendor/flatpickr/flatpickr.min.js?v=6" type="text/javascript"></script>
- <script src="vendor/flatpickr/l10n/de.js?v=6" type="text/javascript"></script>
- <script src="vendor/mustache/mustache.min.js?v=6" type="text/javascript"></script>
- <script src="vendor/tinymce/js/tinymce/tinymce.min.js" type="text/javascript"></script>
- <script src="js/tableformatters.js?v=6" type="text/javascript"></script>
- <script src="js/request.js?v=6" type="text/javascript"></script>
- <script src="js/myapp.js?v=6" type="text/javascript"></script>
- <script src="js/lang/de.js?v=6" type="text/javascript"></script>
- <script src="js/lang/fr.js?v=6" type="text/javascript"></script>
- <script src="js/dataform.js?v=6" type="text/javascript"></script>
- <script src="js/timecalc.js?v=6" type="text/javascript"></script>
- <script src="js/renderer.js?v=6" type="text/javascript"></script>
- <script src="js/sqlite.js?v=6" type="text/javascript"></script>
- <script src="js/report.js?v=6" type="text/javascript"></script>
- <script src="js/email.js?v=6" type="text/javascript"></script>
+ <!-- <script src="js/email.js?v=6" type="text/javascript"></script> -->
<div id="modulescripts">
mail_send:"senden",
id:"Id",
color:"Farbe",
- position:"Position"
+ position:"Position",
+ page: "Seite"
}
\ No newline at end of file
backgroundColor: "#fff",
webPreferences: {
nodeIntegration: true,
- worldSafeExecuteJavaScript: true,
+ //worldSafeExecuteJavaScript: true,
defaultEncoding: 'UTF-8',
- enableRemoteModule: true,
- webviewTag: true
+ //enableRemoteModule: true,
+ //webviewTag: true
}
})
//mainWindow.webContents.openDevTools({detached: true});
<div class="display-container bar toolbar">
- <button class="bar-item toolbarbtn" onclick="myapp.gotoHome();"><span class="icon-back" style="font-size: 16px;"></span>{{back}}</button>
+ <button class="bar-item toolbarbtn" onclick="myapp.gotoHome();"><span class="icon icon-back"></span>{{back}}</button>
<div class="bar-item PageHeadTitle">{{addresses}}</div>
<div class="hide-small">
- <button class="bar-item toolbarbtn right" onclick="addresses.confirmremove();"><span class="icon-trash text-red" style="font-size: 16px;"></span>{{delete}}</button>
- <button class="bar-item toolbarbtn right" onclick="addresses.duplicate();"><span class="icon-duplicate" style="font-size: 16px;"></span>{{duplicate}}</button>
- <button class="bar-item toolbarbtn right" onclick="addresses.edit();"><span class="icon-edit" style="font-size: 16px;"></span>{{edit}}</button>
- <button class="bar-item toolbarbtn right" onclick="addresses.add();"><span class="icon-add" style="font-size: 16px;"></span> {{new}}</button>
+ <button class="bar-item toolbarbtn right" onclick="addresses.confirmremove();"><span class="icon icon-trash text-red"></span>{{delete}}</button>
+ <button class="bar-item toolbarbtn right" onclick="addresses.duplicate();"><span class="icon icon-duplicate"></span>{{duplicate}}</button>
+ <button class="bar-item toolbarbtn right" onclick="addresses.edit();"><span class="icon icon-edit"></span>{{edit}}</button>
+ <button class="bar-item toolbarbtn right" onclick="addresses.add();"><span class="icon icon-add"></span> {{new}}</button>
</div>
<div class="hide-large">
- <button class="bar-item toolbarbtn right" onclick="myapp.togglemenu();"><span class="icon-menu" style="font-size: 36px;"></span></button>
+ <button class="bar-item toolbarbtn right" onclick="myapp.togglemenu();"><span class="icon icon-menu" style="font-size: 36px;"></span></button>
<div class="bar" id="mobilemenu" style="display: none;">
- <button class="bar-item toolbarbtn right" onclick="addresses.confirmremove();"><span class="icon-trash text-red" style="font-size: 16px;"></span>{{delete}}</button>
- <button class="bar-item toolbarbtn right" onclick="addresses.duplicate();"><span class="icon-duplicate" style="font-size: 16px;"></span>{{duplicate}}</button>
- <button class="bar-item toolbarbtn right" onclick="addresses.edit();"><span class="icon-edit" style="font-size: 16px;"></span>{{edit}}</button>
- <button class="bar-item toolbarbtn right" onclick="addresses.add();"><span class="icon-add" style="font-size: 16px;"></span> {{new}}</button>
+ <button class="bar-item toolbarbtn right" onclick="addresses.confirmremove();"><span class="icon icon-trash text-red" style="font-size: 16px;"></span>{{delete}}</button>
+ <button class="bar-item toolbarbtn right" onclick="addresses.duplicate();"><span class="icon icon-duplicate" style="font-size: 16px;"></span>{{duplicate}}</button>
+ <button class="bar-item toolbarbtn right" onclick="addresses.edit();"><span class="icon icon-edit" style="font-size: 16px;"></span>{{edit}}</button>
+ <button class="bar-item toolbarbtn right" onclick="addresses.add();"><span class="icon icon-add" style="font-size: 16px;"></span> {{new}}</button>
</div>
</div>
</div>
<div class="row">
<div class="container fifth">
<label class="label" for="addresses_title">{{title}}</label>
- <input class="input border data_addresses text" data-column="title" data-id="" data-table="addresses" id="addresses_title" type="text">
+ <input class="input data_addresses text" data-column="title" data-id="" data-table="addresses" id="addresses_title" type="text">
</div>
<div class="container twofifth" >
<label class="label" for="addresses_prename">{{prename}}</label>
- <input class="input border data_addresses text" data-column="prename" data-id="" data-table="addresses" id="addresses_prename" type="text">
+ <input class="input data_addresses text" data-column="prename" data-id="" data-table="addresses" id="addresses_prename" type="text">
</div>
<div class="container twofifth">
<label class="label" for="addresses_surname">{{surname}}</label>
- <input class="input border data_addresses text" data-column="surname" data-id="" data-table="addresses" id="addresses_surname" type="text">
+ <input class="input data_addresses text" data-column="surname" data-id="" data-table="addresses" id="addresses_surname" type="text">
</div>
</div>
<div class="row">
<div class="container">
<label class="label" for="addresses_address">{{address}}</label>
- <input class="input border data_addresses text" data-column="address" data-id="" data-table="addresses" id="addresses_address" type="text">
+ <input class="input data_addresses text" data-column="address" data-id="" data-table="addresses" id="addresses_address" type="text">
</div>
</div>
<div class="row">
<div class="container fifth" >
<label class="label" for="addresses_country">{{country}}</label>
- <input class="input border data_addresses text" data-column="country" data-id="" data-table="addresses" id="addresses_country" type="text">
+ <input class="input data_addresses text" data-column="country" data-id="" data-table="addresses" id="addresses_country" type="text">
</div>
<div class="container fifth" >
<label class="label" for="addresses_zip">{{zip}}</label>
- <input class="input border data_addresses text" data-column="zip" data-id="" data-table="addresses" id="addresses_zip" type= "text">
+ <input class="input data_addresses text" data-column="zip" data-id="" data-table="addresses" id="addresses_zip" type= "text">
</div>
<div class="container threefifth">
<label class="label" for="addresses_city">{{country}}</label>
<div class="row">
<div class="container half" >
<label class="label" for="addresses_phone">{{phone}}</label>
- <input class="input border text" data-column="phone" data-id="" data-table="addresses" id="addresses_phone" type="text">
+ <input class="input text" data-column="phone" data-id="" data-table="addresses" id="addresses_phone" type="text">
</div>
</div>
<div class="row">
<div class="container twothird" >
<label class="label" for="addresses_iban">{{bankaccount}}</label>
- <input class="input border text" data-column="iban" data-id="" data-table="addresses" id="addresses_iban" type="text">
+ <input class="input text" data-column="iban" data-id="" data-table="addresses" id="addresses_iban" type="text">
</div>
<div class="container third">
<label class="label" for="addresses_bic">{{bic}}</label>
- <input class="input border text" data-column="bic" data-id="" data-table="addresses" id="addresses_bic" type="text">
+ <input class="input text" data-column="bic" data-id="" data-table="addresses" id="addresses_bic" type="text">
</div>
</div>
<div class="row">
<div class="container half" >
<label class="label" for="addresses_vatid">{{vatid}}</label>
- <input class="input border text" data-column="vatid" data-id="" data-table="addresses" id="addresses_vatid" type="text">
+ <input class="input text" data-column="vatid" data-id="" data-table="addresses" id="addresses_vatid" type="text">
</div>
<div class="container half">
<label class="label" for="addresses_lang">{{language}}</label>
- <input class="input border text" data-column="lang" data-id="" data-table="addresses" id="addresses_lang" type="text">
+ <input class="input text" data-column="lang" data-id="" data-table="addresses" id="addresses_lang" type="text">
</div>
</div>
</form>
-<div class="container bar toolbar">
+<div class="bar toolbar">
<button class="bar-item toolbarbtn" onclick="invoices.gettbldata();myapp.viewmodule('invoices');"><span class="icon-back" style="font-size: 16px;"></span>{{back}}</button>
<div class="bar-item PageHeadTitle">{{invoice}}</div>
<button class="bar-item toolbarbtn right" id="btnCreateInvoice" onclick="invoice.createPDF();"><span class="icon-prnnt" style="font-size: 16px;"></span>{{pdf_create}}</button>
- <button class="bar-item toolbarbtn right" id="btnOpenPDF" onclick="invoice.openPDF();"><span class="icon-pdf" style="font-size: 16px;"></span>{{pdf_open}}</button>
- <button class="bar-item toolbarbtn right" onclick="invoice.importPDF();"><span class="icon-download" style=
- "font-size: 16px;"></span>{{pdf_import}}</button>
+
<button class="bar-item toolbarbtn right" id="btnSendEmail" onclick="invoice.sendSMTP();"><span class="icon-email" style="font-size: 16px;"></span>{{email_send}}</button>
<button class="bar-item toolbarbtn right" id="btnSendEmail" onclick="invoice.openInMailApp();"><span class="icon-email" style="font-size: 16px;"></span>{{email_open}}</button>
</div>
-<div class="cell-row">
- <div class="container cell" style="max-height: calc(100vh - 56px);width: 400px;background-color: #e4e4e4;overflow-y: scroll;">
- <form id="frm_invoice">
- <div class="container padding">
- <input class="data_invoices" data-column="id" data-id="" data-table="invoices" id="invoices_id" name="invoices_id" type="hidden" value="">
- <input class="data_invoices" data-column="pdffile" data-id="" data-table="invoices" id="invoices_pdffile" name="invoices_pdffile" type="hidden" value="">
- <input class="data_invoices" data-column="id_accounts" data-id="" data-table="invoices" id="invoices_id_accounts" name="invoices_id_accounts" type="hidden" value="">
+<div class="display-container" style="max-height: calc(100vh - 56px);background-color: #e4e4e4;overflow-y: scroll;">
+ <form id="frm_invoice">
+ <div class="display-container">
+ <input class="data_invoices" data-column="id" data-id="" data-table="invoices" id="invoices_id" name="invoices_id" type="hidden" value="">
+ <input class="data_invoices" data-column="pdffile" data-id="" data-table="invoices" id="invoices_pdffile" name="invoices_pdffile" type="hidden" value="">
+ <input class="data_invoices" data-column="id_accounts" data-id="" data-table="invoices" id="invoices_id_accounts" name="invoices_id_accounts" type="hidden" value="">
+ <div class="quarter padding">
<div class="row">
- <div class="cell" style="width: 130px;">
+ <div class="half">
<label class="label" for="invoices_invoicetype">{{invoice_type}}</label>
<select class="select border data_invoices" data-column="invoicetype" data-id="" data-selected="" data-table="invoices" id="invoices_invoicetype" onchange="dataform.savefield(this);" value=""></select>
</div>
- <div class="cell" style="width: 130px;">
+ <div class="half">
<label class="label" for="invoices_status">{{status}}</label>
<select class="select border data_invoices" data-column="status" data-id="" data-selected="" data-table="invoices" id="invoices_status" onchange="dataform.savefield(this);invoice.changedStatus(this);" value=""></select>
</div>
</div>
- <div class="row" id="row_invoicetemplate">
- <div class="cell" style="width: 300px;">
- <label class="label" for="invoices_id_template">{{report_template}}</label>
- <select class="select border data_invoices" data-column="id_template" data-id="" data-selected="" data-table="invoices" id="invoices_id_template" name="invoices_id_template" onchange="dataform.savefield(this);" value="">
- </select>
- </div>
- </div>
+
<div class="row">
<div class="cell" style="max-width: 140px;">
<label class="label" for="invoices_invoicedate">{{invoice_date}}</label>
- <input class="input border date data_invoices datefield" data-column="invoicedate" data-id="" data-table="invoices" id="invoices_invoicedate" onblur="dataform.savefield(this);invoice.setInvoiceDates();" type="date">
+ <input class="input date data_invoices datefield" data-column="invoicedate" data-id="" data-table="invoices" id="invoices_invoicedate" onblur="dataform.savefield(this);invoice.setInvoiceDates();" type="date">
</div>
<div class="cell" style="width: 40px;">
<label class="label" for="invoices_deadlinedays">{{deadline_days}}</label>
- <input class="input border number data_invoices right-align" data-column="deadlinedays" data-id="" data-table="invoices" id="invoices_deadlinedays" onblur="dataform.savefield(this);invoice.setDeadlineDate();" type="number">
+ <input class="input number data_invoices right-align" data-column="deadlinedays" data-id="" data-table="invoices" id="invoices_deadlinedays" onblur="dataform.savefield(this);invoice.setDeadlineDate();" type="number">
</div>
<div class="cell" style="max-width: 140px;">
- <label class="label" for="invoices_deadlinedate">{{daedline_date}}</label>
- <input class="input border date data_invoices datefield" data-column="deadlinedate" data-id="" data-table="invoices" id="invoices_deadlinedate" onblur="dataform.savefield(this);invoice.setDeadlineDays();" type="date">
+ <label class="label" for="invoices_deadlinedate">{{deadline_date}}</label>
+ <input class="input date data_invoices datefield" data-column="deadlinedate" data-id="" data-table="invoices" id="invoices_deadlinedate" onblur="dataform.savefield(this);invoice.setDeadlineDays();" type="date">
</div>
</div>
<div class="row">
- <div class="cell" style="width: 100px;">
- <label class="label" for="invoices_businessyear">{{businessyear}}</label>
- <input class="input border number right-align data_invoices" data-column="businessyear" data-id="" data-table="invoices" id="invoices_businessyear" onblur="dataform.savefield(this);" type="number">
- </div>
- <div class="cell" style="width: 120px;">
- <label class="label" for="invoices_payedamount">{{payedamount}}</label>
- <input class="input border currency right-align data_invoices" data-column="payedamount" data-id="" data-table="invoices" id="invoices_payedamount" onblur="dataform.savefield(this);" type="number">
- </div>
- </div>
- <div class="row">
- <div class="cell" style="width: 400px;">
- <label class="label" for="invoices_reference">{{reference}}</label> <input class="input border text data_invoices" data-column="reference" data-id="" data-table="invoices" id="invoices_reference" onblur="dataform.savefield(this);" type="text">
+ <div>
+ <label class="label" for="invoices_reference">{{reference}}</label>
+ <input class="input text data_invoices" data-column="reference" data-id="" data-table="invoices" id="invoices_reference" onblur="dataform.savefield(this);" type="text">
</div>
</div>
+ </div>
+ <div class="quarter padding">
<div class="row">
<div class="cell" style="width: 350px;">
- <label class="label" for="invoices_accountname">{{addressee}}</label> <textarea class="input border text data_invoices" data-column="accountname" data-id="" data-table="invoices" id="invoices_accountname" name="invoices_accountname"
+ <label class="label" for="invoices_accountname">{{addressee}}</label>
+ <textarea class="input text data_invoices" data-column="accountname" data-id="" data-table="invoices" id="invoices_accountname" name="invoices_accountname"
onblur="dataform.savefield(this);" placeholder="{{companyname}}"></textarea>
</div>
<div class="cell"style="with: 50px;">
</div>
</div>
<div class="row">
- <div class="cell" style="width: 400px;">
- <input class="input border text data_invoices" data-column="accountaddress" data-id="" data-table="invoices" id="invoices_accountaddress" onblur="dataform.savefield(this);" placeholder="{{address}}"
+ <div>
+ <input class="input text data_invoices" data-column="accountaddress" data-id="" data-table="invoices" id="invoices_accountaddress" onblur="dataform.savefield(this);" placeholder="{{address}}"
type="text">
</div>
</div>
+ <div class="cell-row">
+ <div class="cell" style="width: 50px;">
+ <input class="input text data_invoices" data-column="accountcountry" data-id="" data-table="invoices" id="invoices_accountcountry" onblur="dataform.savefield(this);" placeholder="{{country}}" type=
+ "text">
+ </div>
+ <div class="cell" style="width: 130px;">
+ <input class="input text data_invoices" data-column="accountzip" data-id="" data-table="invoices" id="invoices_accountzip" onblur="dataform.savefield(this);" placeholder="{{zip}}" type="text">
+ </div>
+ <div class="cell">
+ <input class="input text data_invoices" data-column="accountcity" data-id="" data-table="invoices" id="invoices_accountcity" onblur="dataform.savefield(this);" placeholder="{{city}}" type="text">
+ </div>
+ </div>
+ </div>
+ <div class="quarter padding">
<div class="row">
- <div class="cell" style="width: 40px;">
- <input class="input border text data_invoices" data-column="accountcountry" data-id="" data-table="invoices" id="invoices_accountcountry" onblur="dataform.savefield(this);" placeholder="{{country}}" type=
+ <div class="half">
+ <label class="label" for="invoices_clientnumber">{{clientnumber}}</label>
+ <input class="input text data_invoices" data-column="clientnumber" data-id="" data-table="invoices" id="invoices_clientnumber" onblur="dataform.savefield(this);" placeholder="{{clientnumber}}" type=
"text">
</div>
- <div class="cell" style="width: 90px;">
- <input class="input border text data_invoices" data-column="accountzip" data-id="" data-table="invoices" id="invoices_accountzip" onblur="dataform.savefield(this);" placeholder="{{zip}}" type="text">
+ <div class="half">
+ <label class="label" for="invoices_accountvatid">{{vatid}}</label>
+ <input class="input text data_invoices" data-column="accountvatid" data-id="" data-table="invoices" id="invoices_accountvatid" onblur="dataform.savefield(this);" placeholder="{{vatid}}" type="text">
</div>
- <div class="cell" style="width: 270px;">
- <input class="input border text data_invoices" data-column="accountcity" data-id="" data-table="invoices" id="invoices_accountcity" onblur="dataform.savefield(this);" placeholder="{{city}}" type="text">
+ </div>
+ <div class="row" id="row_invoicetemplate">
+ <div>
+ <label class="label" for="invoices_id_template">{{report_template}}</label>
+ <select class="select border data_invoices" data-column="id_template" data-id="" data-selected="" data-table="invoices" id="invoices_id_template" name="invoices_id_template" onchange="dataform.savefield(this);" value="">
+ </select>
</div>
</div>
<div class="row">
- <div class="cell" style="width: 200px;">
- <input class="input border text data_invoices" data-column="clientnumber" data-id="" data-table="invoices" id="invoices_clientnumber" onblur="dataform.savefield(this);" placeholder="{{clientnumber}}" type=
- "text">
+ <div class="half" >
+ <label class="label" for="invoices_businessyear">{{businessyear}}</label>
+ <input class="input number right-align data_invoices" data-column="businessyear" data-id="" data-table="invoices" id="invoices_businessyear" onblur="dataform.savefield(this);" type="number">
</div>
- <div class="cell" style="width: 200px;">
- <input class="input border text data_invoices" data-column="accountvatid" data-id="" data-table="invoices" id="invoices_accountvatid" onblur="dataform.savefield(this);" placeholder="{{vatid}}" type="text">
+ <div class="half">
+ <label class="label" for="invoices_payedamount">{{payedamount}}</label>
+ <input class="input currency right-align data_invoices" data-column="payedamount" data-id="" data-table="invoices" id="invoices_payedamount" onblur="dataform.savefield(this);" type="number">
</div>
</div>
-
</div>
- </form>
- </div>
- <div class="cell">
+ </form>
+ <div class="quarter">
+ <div class="display-container">
+ <div class="bar moduletoolbar">
+ <div class="bar-item SubHeadTitle">{{files}}</div>
+ <button class="bar-item toolbarbtn right" onclick="invoices.confirmremove();"><span class="icon icon-trash text-red" ></span>{{delete}}</button>
+ <button class="bar-item toolbarbtn right" id="btnOpenPDF" onclick="invoice.openPDF();"><span class="icon-pdf" style="font-size: 16px;"></span>{{pdf_open}}</button>
+ <button class="bar-item toolbarbtn right" onclick="invoice.importPDF();"><span class="icon-download" style="font-size: 16px;"></span>{{pdf_import}}</button>
+ </div>
+ <div id="tbl_invoicefiles"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="diplay-container" >
+ <div class="row display-container">
<div class="row">
<div class="bar moduletoolbar">
<div class="bar-item subHeadTitle">{{invoice_items}}</div>
</div>
<div id="tbl_invoicebookings"></div>
</div>
+ </div>
+ <div class="half">
<div class="row" style="background-color: #e4e4e4;">
<label class="label" for="invoices_headertext">{{preface}}</label>
- <textarea class="input border data_invoices richeditarea" style="width: 100%;" data-id="" data-column="headertext" data-table="invoices" id="invoices_headertext" ></textarea>
+ <textarea class="input data_invoices richeditarea" style="width: 100%;" data-id="" data-column="headertext" data-table="invoices" id="invoices_headertext" ></textarea>
</div>
<div class="row" style="background-color: #e4e4e4;">
<label class="label" for="invoices_footertext">{{annociation}}</label>
- <textarea class="input border data_invoices richeditarea" style="width: 100%;" data-id="" data-column="headertext" data-table="invoices" id="invoices_footertext" ></textarea>
+ <textarea class="input data_invoices richeditarea" style="width: 100%;" data-id="" data-column="headertext" data-table="invoices" id="invoices_footertext" ></textarea>
</div>
</div>
- <div class="container cell" style="max-height: calc(100vh - 56px);width: 400px;">
- <div id="tbl_invoicefiles"></div>
- </div>
+
</div>
<div id="dlgInvoiceBooking" class="modal" >
<div class="modal-content animate-opacity card-4" >
</div>
<div class="cell" style="width: 450px;">
<label for="invoicebooking_name" class="label">{{item_name}}</label>
- <input type="text" data-id="" data-column="name" data-table="bookings" class="input border text data_invoicebooking" id="invoicebooking_name" name="invoicebooking_name"/>
+ <input type="text" data-id="" data-column="name" data-table="bookings" class="input text data_invoicebooking" id="invoicebooking_name" name="invoicebooking_name"/>
</div>
</div>
<div class="container row">
<div class="container row">
<div class="cell" style="width: 600px;">
<label for="invoicebooking_description" class="label">{{description}}</label>
- <textarea class="input border data_invoicebooking richtextarea" style="height: 200px;" data-id="" data-column="description" data-table="bookings" id="invoicebooking_description" name="invoicebooking_description"></textarea>
+ <textarea class="input data_invoicebooking richtextarea" style="height: 200px;" data-id="" data-column="description" data-table="bookings" id="invoicebooking_description" name="invoicebooking_description"></textarea>
</div>
</div>
</div>
});
invoice.bookingtbl = new Tabulator("#tbl_invoicefiles",{
headerFilterPlaceholder: "filter...",
- height: "calc(100vh - 60px)",
+ height: "100%",
layout: "fitColumns",
selectable: 1,
rowContext:function(e, row){ e.preventDefault(); },
<div class="display-container">
- <div class="container bar toolbar">
- <button class="bar-item toolbarbtn" onclick="myapp.gotoHome();"><span class="icon-back" style="font-size: 16px;"></span>{{back}}</button>
+ <div class="bar toolbar">
+ <button class="bar-item toolbarbtn" onclick="myapp.gotoHome();"><span class="icon-back"></span>{{back}}</button>
<div class="bar-item PageHeadTitle">Rechnungen</div>
- <button class="bar-item toolbarbtn right text-red" onclick="invoices.confirmremove();"><span class="icon icon-trash" style="font-size: 16px;"></span>{{delete}}</button>
- <button class="bar-item toolbarbtn right" onclick="invoices.duplicate();"><span class="icon icon-duplicate" style="font-size: 16px;"></span>dupl.</button>
- <button class="bar-item toolbarbtn right" onclick="invoices.edit();"><span class="icon icon-edit" style="font-size: 16px;"></span>bearb.</button>
- <button class="bar-item toolbarbtn right" onclick="invoices.add();"><span class="icon icon-add" style="font-size: 16px;"></span>{{new}}</button>
+ <button class="bar-item toolbarbtn right " onclick="invoices.confirmremove();"><span class="icon icon-trash text-red" ></span>{{delete}}</button>
+ <button class="bar-item toolbarbtn right" onclick="invoices.duplicate();"><span class="icon icon-duplicate"></span>dupl.</button>
+ <button class="bar-item toolbarbtn right" onclick="invoices.edit();"><span class="icon icon-edit"></span>bearb.</button>
+ <button class="bar-item toolbarbtn right" onclick="invoices.add();"><span class="icon icon-add"></span>{{new}}</button>
</div>
</div>
<div id="tbl_invoices"></div>
\ No newline at end of file
</div>
<div class="row">
<div class="cell" style="width: 400px;">
- <label class="label" for="offers_accountname">Addressat</label> <input class="input border text data_offers" data-column="accountname" data-id="" data-table="offers" id="offers_accountname" name="offers_accountname" onblur=
+ <label class="label" for="offers_accountname">Addressat</label> <input class="input text data_offers" data-column="accountname" data-id="" data-table="offers" id="offers_accountname" name="offers_accountname" onblur=
"dataform.savefield(this);" placeholder="Name" type="text">
</div>
</div>
<div class="row">
<div class="cell" style="width: 400px;">
- <input class="input border text data_offers" data-column="accountaddress" data-id="" data-table="offers" id="offers_accountaddress" name="offers_accountaddress" onblur="dataform.savefield(this);" placeholder="Addresse" type=
+ <input class="input text data_offers" data-column="accountaddress" data-id="" data-table="offers" id="offers_accountaddress" name="offers_accountaddress" onblur="dataform.savefield(this);" placeholder="Addresse" type=
"text">
</div>
</div>
<div class="row">
<div class="cell" style="width: 40px;">
- <input class="input border text data_offers" data-column="accountcountry" data-id="" data-table="offers" id="offers_accountcountry" name="offers_accountcountry" onblur="dataform.savefield(this);" placeholder="Land" type="text">
+ <input class="input text data_offers" data-column="accountcountry" data-id="" data-table="offers" id="offers_accountcountry" name="offers_accountcountry" onblur="dataform.savefield(this);" placeholder="Land" type="text">
</div>
<div class="cell" style="width: 90px;">
- <input class="input border text data_offers" data-column="accountzip" data-id="" data-table="offers" id="offers_accountzip" name="offers_accountzip" onblur="dataform.savefield(this);" placeholder="PLZ" type="text">
+ <input class="input text data_offers" data-column="accountzip" data-id="" data-table="offers" id="offers_accountzip" name="offers_accountzip" onblur="dataform.savefield(this);" placeholder="PLZ" type="text">
</div>
<div class="cell" style="width: 270px;">
- <input class="input border text data_offers" data-column="accountcity" data-id="" data-table="offers" id="offers_accountcity" name="offers_accountcity" onblur="dataform.savefield(this);" placeholder="Ort" type="text">
+ <input class="input text data_offers" data-column="accountcity" data-id="" data-table="offers" id="offers_accountcity" name="offers_accountcity" onblur="dataform.savefield(this);" placeholder="Ort" type="text">
</div>
</div>
<div class="row">
<div class="cell" style="width: 200px;">
- <input class="input border text data_offers" data-column="clientnumber" data-id="" data-table="offers" id="offers_clientnumber" name="offers_clientnumber" onblur="dataform.savefield(this);" placeholder="Kunden-Nr" type="text">
+ <input class="input text data_offers" data-column="clientnumber" data-id="" data-table="offers" id="offers_clientnumber" name="offers_clientnumber" onblur="dataform.savefield(this);" placeholder="Kunden-Nr" type="text">
</div>
<div class="cell" style="width: 200px;">
- <input class="input border text data_offers" data-column="vatid" data-id="" data-table="offers" id="offers_vatid" name="offers_vatid" onblur="dataform.savefield(this);" placeholder="USt.-ID" type="text">
+ <input class="input text data_offers" data-column="vatid" data-id="" data-table="offers" id="offers_vatid" name="offers_vatid" onblur="dataform.savefield(this);" placeholder="USt.-ID" type="text">
</div>
</div>
<div class="row">
<div class="cell" style="max-width: 150px;">
<div class="">
- <label class="label" for="offers_offerdate">Datum</label> <input class="input border date data_offers datefield" data-column="offerdate" data-id="" data-table="offers" id="offers_offerdate" name="offers_offerdate" onblur=
+ <label class="label" for="offers_offerdate">Datum</label> <input class="input date data_offers datefield" data-column="offerdate" data-id="" data-table="offers" id="offers_offerdate" name="offers_offerdate" onblur=
"dataform.savefield(this);offer.setofferDates();" type="date">
</div>
</div>
<div class="cell" style="width: 40px;">
<div class="">
- <label class="label" for="offers_deadlinedays">Tage</label> <input class="input border number data_offers right-align" data-column="deadlinedays" data-id="" data-table="offers" id="offers_deadlinedays" name=
+ <label class="label" for="offers_deadlinedays">Tage</label> <input class="input number data_offers right-align" data-column="deadlinedays" data-id="" data-table="offers" id="offers_deadlinedays" name=
"offers_deadlinedays" onblur="dataform.savefield(this);offer.setDeadlineDate();" type="number">
</div>
</div>
<div class="cell" style="max-width: 150px;">
<div class="">
- <label class="label" for="offers_deadlinedate">Fälligkeit</label> <input class="input border date data_offers datefield" data-column="deadlinedate" data-id="" data-table="offers" id="offers_deadlinedate" name=
+ <label class="label" for="offers_deadlinedate">Fälligkeit</label> <input class="input date data_offers datefield" data-column="deadlinedate" data-id="" data-table="offers" id="offers_deadlinedate" name=
"offers_deadlinedate" onblur="dataform.savefield(this);offer.setDeadlineDays();" type="date">
</div>
</div>
<div class="row">
<div class="cell" style="width: 400px;">
<div class="">
- <label class="label" for="offers_reference">Referenz</label> <input class="input border text data_offers" data-column="reference" data-id="" data-table="offers" id="offers_reference" name="offers_reference" onblur=
+ <label class="label" for="offers_reference">Referenz</label> <input class="input text data_offers" data-column="reference" data-id="" data-table="offers" id="offers_reference" name="offers_reference" onblur=
"dataform.savefield(this);" type="text">
</div>
</div>
<div class="container" style="height: 150px;background-color: #e4e4e4;">
<div class="cell">Vorwort</div>
<div class="cell">
- <textarea data-id="" data-column="headertext" data-table="offers" class="input border richeditarea data_offers" style="width: 600px; height: 100%;" id="offers_headertext" name="offers_headertext"></textarea>
+ <textarea data-id="" data-column="headertext" data-table="offers" class="input richeditarea data_offers" style="width: 600px; height: 100%;" id="offers_headertext" name="offers_headertext"></textarea>
</div>
</div>
<div class="display-container" id="tbl_offerdetails"></div>
<div class="container" style="height: 150px;background-color: #e4e4e4;">
<div class="cell">Nachwort</div>
<div class="cell">
- <textarea data-id="" data-column="footertext" data-table="offers" class="input border richeditarea data_offers" style="width: 600px; height: 100%;" id="offers_footertext" name="offers_footertext"></textarea>
+ <textarea data-id="" data-column="footertext" data-table="offers" class="input richeditarea data_offers" style="width: 600px; height: 100%;" id="offers_footertext" name="offers_footertext"></textarea>
</div>
</div>
</div>
</div>
<div class="container third">
<label class="label" for="products_productgroup">{{product_group}}</label>
- <input class="input border text data_products" data-column="productgroup" data-id="" data-table="products" id="products_productgroup" name="products_productgroup" type="text">
+ <input class="input text data_products" data-column="productgroup" data-id="" data-table="products" id="products_productgroup" name="products_productgroup" type="text">
</div>
<div class="container third">
<label class="label" for="products_unit">{{unit}}</label>
- <input class="input border text data_products" data-column="unit" data-id="" data-table="products" id="products_unit" name="products_unit" type="text">
+ <input class="input text data_products" data-column="unit" data-id="" data-table="products" id="products_unit" name="products_unit" type="text">
</div>
</div>
<div class="container row">
<div class="container third">
<label class="label" for="products_sku">{{sku}}</label>
- <input class="input border text data_products" data-column="sku" data-id="" data-table="products" id="products_sku" name="products_sku" type="text">
+ <input class="input text data_products" data-column="sku" data-id="" data-table="products" id="products_sku" name="products_sku" type="text">
</div>
<div class="contaienr twothird">
<label class="label" for="products_name">{{product_name}}</label>
- <input class="input border text data_products" data-column="name" data-id="" data-table="products" id="products_name" name="products_name" type="text">
+ <input class="input text data_products" data-column="name" data-id="" data-table="products" id="products_name" name="products_name" type="text">
</div>
</div>
<div class="container row">
<div class="container cell twothird" style="height: 250px;">
<label class="label" for="products_description">{{description}}</label>
- <textarea data-id="" data-column="description" data-table="products" class="input border richeditarea data_products" id="products_description" ></textarea>
+ <textarea data-id="" data-column="description" data-table="products" class="input richeditarea data_products" id="products_description" ></textarea>
</div>
</div>
</div>
<div class="container">
<label class="label" for="products_salesprice">{{netamount}}</label>
- <input class="input border currency right-align data_products" data-column="salesprice" data-id="" data-table="products" id="products_salesprice" type="number">
+ <input class="input currency right-align data_products" data-column="salesprice" data-id="" data-table="products" id="products_salesprice" type="number">
</div>
<div class="container">
<label class="label" for="products_vatpercent">{{tax}}(%)</label>
- <input class="input border percent right-align data_products" data-column="vatpercent" data-id="" data-table="products" id="products_vatpercent" type="number">
+ <input class="input percent right-align data_products" data-column="vatpercent" data-id="" data-table="products" id="products_vatpercent" type="number">
</div>
<div class="container">
<label class="label" for="products_vatamount">{{tax}}(€)</label>
- <input class="input border percent right-align data_products readonly" id="products_vatamount" type="number" readonly>
+ <input class="input percent right-align data_products readonly" id="products_vatamount" type="number" readonly>
</div>
<div class="container">
<label class="label" for="products_grossprice">{{grossamount}}</label>
- <input class="input border currency right-align data_products readonly" id="products_grossprice" type="number" readonly>
+ <input class="input currency right-align data_products readonly" id="products_grossprice" type="number" readonly>
</div>
</div>
</div>
<div class="row container group_container">
<div class="">
<label class="label">{{company}}</label>
- <input class="input border text data_defaultdata" data-column="pref" data-id="company" data-table="defaultdata" id="defaultdata_company" onblur="dataform.savefield(this);" type="text" value="">
+ <input class="input text data_defaultdata" data-column="pref" data-id="company" data-table="defaultdata" id="defaultdata_company" onblur="dataform.savefield(this);" type="text" value="">
</div>
<div class="">
<label class="label">{{address}}</label>
- <input class="input border text data_defaultdata" data-column="pref" data-id="address" data-table="defaultdata" id="defaultdata_address" onblur="dataform.savefield(this);" type="text" value="">
+ <input class="input text data_defaultdata" data-column="pref" data-id="address" data-table="defaultdata" id="defaultdata_address" onblur="dataform.savefield(this);" type="text" value="">
</div>
<div class="row">
<div class="cell" style="width: 40px;">
<label class="label">{{country}}</label>
- <input class="input border text data_defaultdata" data-column="pref" data-id="country" data-table="defaultdata" id="defaultdata_country" onblur="dataform.savefield(this);" type="text" value="">
+ <input class="input text data_defaultdata" data-column="pref" data-id="country" data-table="defaultdata" id="defaultdata_country" onblur="dataform.savefield(this);" type="text" value="">
</div>
<div class="cell" style="width: 90px;">
<label class="label">{{zip}}</label>
- <input class="input border text data_defaultdata" data-column="pref" data-id="zip" data-table="defaultdata" id="defaultdata_zip" onblur="dataform.savefield(this);" type="text" value="">
+ <input class="input text data_defaultdata" data-column="pref" data-id="zip" data-table="defaultdata" id="defaultdata_zip" onblur="dataform.savefield(this);" type="text" value="">
</div>
<div class="cell" style="width: 270px;">
<label class="label">{{city}}</label>
- <input class="input border text data_defaultdata" data-column="pref" data-id="city" data-table="defaultdata" id="defaultdata_city" onblur="dataform.savefield(this);" type="text" value="">
+ <input class="input text data_defaultdata" data-column="pref" data-id="city" data-table="defaultdata" id="defaultdata_city" onblur="dataform.savefield(this);" type="text" value="">
</div>
</div>
<div class="">
<label class="label">{{email}}</label>
- <input class="input border text data_defaultdata" data-column="pref" data-id="email" data-table="defaultdata" id="defaultdata_email" onblur="dataform.savefield(this);" type="text" value="">
+ <input class="input text data_defaultdata" data-column="pref" data-id="email" data-table="defaultdata" id="defaultdata_email" onblur="dataform.savefield(this);" type="text" value="">
</div>
<div class="">
<label class="label">{{website}}</label>
- <input class="input border text data_defaultdata" data-column="pref" data-id="website" data-table="defaultdata" id="defaultdata_website" onblur="dataform.savefield(this);" type="text">
+ <input class="input text data_defaultdata" data-column="pref" data-id="website" data-table="defaultdata" id="defaultdata_website" onblur="dataform.savefield(this);" type="text">
</div>
<div class="row">
<div class="cell">
<div class="">
<label class="label">{{vatid}}</label>
- <input class="input border text data_defaultdata" data-column="vatid" data-id="" data-table="defaultdata" id="defaultdata_vatid" onblur="dataform.savefield(this);" type="text" value="">
+ <input class="input text data_defaultdata" data-column="vatid" data-id="" data-table="defaultdata" id="defaultdata_vatid" onblur="dataform.savefield(this);" type="text" value="">
</div>
</div>
<div class="cell">
<div class="">
<label class="label">{{rcs}}</label>
- <input class="input border text data_defaultdata" data-column="rcs" data-id="" data-table="defaultdata" id="defaultdata_rcs" onblur="dataform.savefield(this);" type="text">
+ <input class="input text data_defaultdata" data-column="rcs" data-id="" data-table="defaultdata" id="defaultdata_rcs" onblur="dataform.savefield(this);" type="text">
</div>
</div>
</div>
<div class="row">
<div class="cell">
<label class="label" for="defaultdata_vat">{{tax}} (%)</label>
- <input class="input border number right-align percent text-align-right data_defaultdata" data-column="pref" data-id="vat" data-table="defaultdata" id="defaultdata_vat" onblur="dataform.savefield(this);" text-align-right="" type="number" value="">
+ <input class="input number right-align percent text-align-right data_defaultdata" data-column="pref" data-id="vat" data-table="defaultdata" id="defaultdata_vat" onblur="dataform.savefield(this);" text-align-right="" type="number" value="">
</div>
<div class="cell">
- <label class="label" for="defaultdata_pref-invoicedeadlinedays">{{deadline}} ({{days}})</label> <input class="input border number right-align text-align-right data_defaultdata" data-column="pref" data-id="invoicedeadlinedays" data-table="defaultdata" id=
+ <label class="label" for="defaultdata_pref-invoicedeadlinedays">{{deadline}} ({{days}})</label> <input class="input number right-align text-align-right data_defaultdata" data-column="pref" data-id="invoicedeadlinedays" data-table="defaultdata" id=
"defaultdata_pref-invoicedeadlinedays" onblur="dataform.savefield(this);" text-align-right="" type="number" value="">
</div>
</div>
<div class="row">
<div class="cell">
<label class="label" for="defaultdata_smtpserver">{{mail_from}}</label>
- <input class="input border text data_defaultdata" data-column="pref" data-id="smtpserver" data-table="defaultdata" id="defaultdata_smtpfrom" onblur="dataform.savefield(this);" type="text" value="">
+ <input class="input text data_defaultdata" data-column="pref" data-id="smtpserver" data-table="defaultdata" id="defaultdata_smtpfrom" onblur="dataform.savefield(this);" type="text" value="">
</div>
</div>
<div class="row">
<div class="cell">
<label class="label" for="defaultdata_smtpserver">{{mail_server}}</label>
- <input class="input border text data_defaultdata" data-column="pref" data-id="smtpserver" data-table="defaultdata" id="defaultdata_smtpserver" onblur="dataform.savefield(this);" type="text" value="">
+ <input class="input text data_defaultdata" data-column="pref" data-id="smtpserver" data-table="defaultdata" id="defaultdata_smtpserver" onblur="dataform.savefield(this);" type="text" value="">
</div>
<div class="cell">
<label class="label" for="defaultdata_smtpport">{{mail_port}}</label>
- <input class="input border number right-align text-align-right data_defaultdata" data-column="pref" data-id="smtpport" data-table="defaultdata" id="defaultdata_smtpport" onblur="dataform.savefield(this);" text-align-right="" type="number" value="">
+ <input class="input number right-align text-align-right data_defaultdata" data-column="pref" data-id="smtpport" data-table="defaultdata" id="defaultdata_smtpport" onblur="dataform.savefield(this);" text-align-right="" type="number" value="">
</div>
</div>
<div class="">
- <label class="label" for="defaultdata_smtplogin">{{mail_user}}</label> <input class="input border text data_defaultdata" data-column="pref" data-id="smtplogin" data-table="defaultdata" id="defaultdata_smtplogin" onblur="dataform.savefield(this);" type="text" value="">
+ <label class="label" for="defaultdata_smtplogin">{{mail_user}}</label> <input class="input text data_defaultdata" data-column="pref" data-id="smtplogin" data-table="defaultdata" id="defaultdata_smtplogin" onblur="dataform.savefield(this);" type="text" value="">
</div>
<div class="">
- <label class="label" for="defaultdata_pref">{{mail_password}}</label> <input class="input border password data_defaultdata" data-column="pref" data-id="smtppassword" data-table="defaultdata" id="defaultdata_smtppassword" onblur="dataform.savefield(this);" type="password" value="">
+ <label class="label" for="defaultdata_pref">{{mail_password}}</label> <input class="input password data_defaultdata" data-column="pref" data-id="smtppassword" data-table="defaultdata" id="defaultdata_smtppassword" onblur="dataform.savefield(this);" type="password" value="">
</div>
</div>
</div>
<div class="panel" id="pnl_templatereport" style="width: 100%;display: none;">
<form id="frm_templates">
<div class="row">
- <div class="cell container" style="width: 400px;">
- <label class="label" for="templates_reporttype">{{Category}}</label>
+ <div class="cell container" style="width: 200px;">
+ <label class="label" for="templates_reporttype">{{category}}</label>
<select class="select border data_templates" data-column="reporttype" data-id="" data-selected="" data-table="label" id="templates_reporttype"></select>
</div>
- <div class="cell container" style="width: 400px;">
+
+ <div class="cell container" style="width: 250px;">
<label class="label" for="templates_reportname">{{name}}</label>
<input class="input data_templates border text" data-column="reportname" data-id="" data-table="newreports" id="templates_reportname" type="text">
</div>
</div>
- <div class="row">
- <!-- <div class="cell container" style="width: 200px;">
- <label class="label" for="templates_pdfoptions-size">Size</label>
- <select class="select border data_templates" data-column="pdfoptions-size" data-id="" data-selected="" data-table="label" id="templates_pdfoptions-size">
- <option value="A4">A4</option>
- </select>
- </div>
- <div class="cell container" style="width: 200px;">
- <label class="label" for="templates_pdfoptions-orientation">Orientation</label>
- <select class="select border data_templates" data-column="pdfoptions-orientation" data-id="" data-selected="" data-table="label" id="templates_pdfoptions-orientation">
- <option value="Portrait">Portrait</option>
- <option value="Landscape">Landscape</option>
- </select>
- </div> -->
-
+ <div class="row" style="padding-bottom: 10px;">
<div class="cell container" style="width: 90px;">
<label class="label" for="templates_pdfoptions-top">{{top}} (mm)</label>
<input class="input data_templates border number right-align" data-column="pdfoptions-top" data-id="" data-table="newreports" id="templates_pdfoptions-top" type="text">
<input class="input data_templates border number right-align" data-column="pdfoptions-right" data-id="" data-table="newreports" id="templates_pdfoptions-right" type="text">
</div>
</div>
+ <div class="container" style="height: calc(100vh - 200px); overflow-y: scroll; background-color: #5e5e5e;">
+ <div class="row">
+ <div class="cell" style="width: 210mm;">
+ <label class="label" for="templates_headerhtml">{{header}}</label>
+ <textarea class="input data_templates richeditarea" style="height: 300px;" data-id="" data-column="headerhtml" data-table="table" id="templates_headerhtml" ></textarea>
+ </div>
+ </div>
<div class="row">
- <div class="cell" style="width: 100%;">
- <label class="label" for="templates_contentheader">{{header}}</label>
- <textarea class="input border data_templates richeditarea" style="height: heightpx;" data-id="" data-column="contentheader" data-table="table" id="templates_contentheader" ></textarea>
+ <div class="cell" style="width: 210mm;">
+ <label class="label" for="templates_contenthtml">{{page}}</label>
+ <textarea class="input data_templates richeditarea" style="height: 300px;" data-id="" data-column="contenthtml" data-table="table" id="templates_contenthtml" ></textarea>
</div>
- <div class="cell" style="width: 100%;">
- <label class="label" for="templates_contentheader">{{header}}</label>
- <textarea class="input border data_templates richeditarea" style="height: heightpx;" data-id="" data-column="contentheader" data-table="table" id="templates_contentheader" ></textarea>
+ </div>
+ <div class="row">
+ <div class="cell" style="width: 210mm;">
+ <label class="label" for="templates_footerhtml">{{footer}}</label>
+ <textarea class="input data_templates richeditarea" style="height: 300px;" data-id="" data-column="footerhtml" data-table="table" id="templates_footerhtml" ></textarea>
</div>
+ </div>
+ </div>
<!-- <div class="cell" style="width: 80px;">
<div class="bar-block moduletoolbar">
<button class="bar-item toolbarbtn border" onclick="myapp.viewtab('templateheader');return false;">Header</button>
<button class="bar-item toolbarbtn border" onclick="myapp.viewtab('templatereportsql');return false;">Data Queries</button>
</div>
</div> -->
- <div class="cell">
- <div id="tab_templateheader" class="row tab border" style="height:calc(100vh - 200px); width: calc(100vw - 500px); overflow-y: hidden;">
+ <!-- <div class="cell"> -->
+ <!-- <div id="tab_templateheader" class="row tab border" style="height:calc(100vh - 200px); width: calc(100vw - 500px); overflow-y: hidden;">
<div class="bar moduletoolbar">
<div class="bar-item SubHeadTitle">{{header}}</div>
</div>
- <textarea class="input border data_templates codeeditor" style="width:calc(100vw - 510px);" data-id="" data-column="headerhtml" data-table="newreports" id="templates_headerhtml"></textarea>
- </div>
- <div id="tab_templatebody" class="row tab border" style="height:calc(100vh - 200px); width: calc(100vw - 500px); overflow-y: hidden;display:none;">
+ <textarea class="input data_templates codeeditor" style="width:calc(100vw - 510px);" data-id="" data-column="headerhtml" data-table="newreports" id="templates_headerhtml"></textarea>
+ </div> -->
+ <!-- <div id="tab_templatebody" class="row tab border" style="height:calc(100vh - 200px); width: calc(100vw - 500px); overflow-y: hidden;display:none;">
<div class="bar moduletoolbar">
<div class="bar-item SubHeadTitle">{{template_pagecontent}}</div>
</div>
- <textarea class="input border data_templates codeeditor" style="width:calc(100vw - 510px);" data-id="" data-column="contenthtml" data-table="newreports" id="templates_contenthtml" ></textarea>
- </div>
- <div id="tab_templatefooter" class="row tab border" style="height:calc(100vh - 200px); width: calc(100vw - 500px); overflow-y: hidden;display:none;">
+ <textarea class="input data_templates codeeditor" style="width:calc(100vw - 510px);" data-id="" data-column="contenthtml" data-table="newreports" id="templates_contenthtml" ></textarea>
+ </div> -->
+ <!-- <div id="tab_templatefooter" class="row tab border" style="height:calc(100vh - 200px); width: calc(100vw - 500px); overflow-y: hidden;display:none;">
<div class="bar moduletoolbar">
<div class="bar-item SubHeadTitle">{{footer}}</div>
</div>
- <textarea class="input border data_templates codeeditor" style="width:calc(100vw - 510px);" data-id="" data-column="footerhtml" data-table="newreports" id="templates_footerhtml" ></textarea>
- </div>
- <div id="tab_templatestyle" class="row tab border" style="height:calc(100vh - 120px); width: calc(100vw - 500px); overflow-y: hidden;display: none;" >
+ <textarea class="input data_templates codeeditor" style="width:calc(100vw - 510px);" data-id="" data-column="footerhtml" data-table="newreports" id="templates_footerhtml" ></textarea>
+ </div> -->
+ <!-- <div id="tab_templatestyle" class="row tab border" style="height:calc(100vh - 120px); width: calc(100vw - 500px); overflow-y: hidden;display: none;" >
<div class="bar moduletoolbar">
<div class="bar-item SubHeadTitle">{{template_layout_definition}}</div>
</div>
- <textarea class="input border data_templates codeeditor" style="width:calc(100vw - 510px);" data-id="" data-column="styles" data-table="newreports" id="templates_styles" ></textarea>
+ <textarea class="input data_templates codeeditor" style="width:calc(100vw - 510px);" data-id="" data-column="styles" data-table="newreports" id="templates_styles" ></textarea>
</div>
- </div>
- <div id="tab_templatereportsql" class="row tab" style="height:calc(100vh - 120px); width: calc(100vw - 500px); overflow-y: hidden;display: none;" >
+ </div> -->
+ <!-- <div id="tab_templatereportsql" class="row tab" style="height:calc(100vh - 120px); width: calc(100vw - 500px); overflow-y: hidden;display: none;" >
<div class="bar moduletoolbar">
<div class="bar-item SubHeadTitle">Daten Abfragen</div>
<button class="bar-item toolbarbtn right text-red" onclick="templates.confirmRemoveSQL();"><span class="icon-trash" style="font-size: 16px;"></span>{{delete}}</button>
<button class="bar-item toolbarbtn right" onclick="templates.addSQL();"><span class="icon-add" style="font-size: 16px;"></span>{{new}}</button>
</div>
<div id="tbl_reportsql"></div>
- </div>
- </div>
+ </div> -->
+ <!-- </div> -->
</div>
</form>
</div>
- <div class="tab" id="pnl_templateemail" style="display: none;">
- <div class="container" style="width: 400px;">
- <label class="label" for="email_subject">Betreff</label>
- <input class="input data_templates border text" data-column="headerhtml" data-id="" data-table="newreports" id="email_subject" onblur="dataform.savefield(this);" type="text">
- </div>
- <div class="cell" style="width: 100%;">
- <label class="label" for="email_body">Nachricht</label>
- <textarea class="input border data_templates richeditarea" style="height: calc(100vh - 300px);width:calc(100vw -500px);" data-id="" data-column="contenthtml" data-table="newreports" id="email_body" ></textarea>
- </div>
- </div>
+
</div>
</div>
</div>
-<script src="vendor/codemirror/lib/codemirror.js" type="text/javascript"></script>
-<script src="vendor/codemirror/addon/mode/overlay.js" type="text/javascript"></script>
-<script src="vendor/codemirror/mode/xml/xml.js" type="text/javascript"></script>
-<script src="vendor/codemirror/mode/css/css.js" type="text/javascript"></script>
-<script src="vendor/codemirror/mode/javascript/javascript.js" type="text/javascript"></script>
+
<!--
<div class="cell container" style="width: 200px; background-color: #e4e4e4; padding-bottom: 10px;" style="background-color: #e4e4e4; padding-bottom: 10px;">
<div class="cell container" style="width: 400px;">
},
init: function(){
- CodeMirror.defineMode("mustache", function(config, parserConfig) {
- var mustacheOverlay = {
- token: function(stream, state) {
- var ch;
- if (stream.match("{{")) {
- while ((ch = stream.next()) != null)
- if (ch == "}" && stream.next() == "}") {
- stream.eat("}");
- return "mustache";
- }
- }
- while (stream.next() != null && !stream.match("{{", false)) {}
- return null;
- }
- };
- return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || "text/html"), mustacheOverlay);
- });
+
// templates.selects["templates_pdfoptions-orientation"] =new SlimSelect({
// select: "#templates_pdfoptions-orientation",
// showSearch: false
// select: "#templates_pdfoptions-size",
// showSearch: false
// });
- // templates.selects["templates_reporttype"] =new SlimSelect({
- // select: "#templates_reporttype",
- // showSearch: false
- // });
- var height = document.getElementById("tab_templateheader").style.height;
- templates.editors["templates_headerhtml"] = CodeMirror.fromTextArea(document.getElementById("templates_headerhtml"), {mode: "mustache",lineNumbers: true});
- templates.editors["templates_headerhtml"].setSize(null,height);
- templates.editors["templates_contenthtml"] = CodeMirror.fromTextArea(document.getElementById("templates_contenthtml"), {mode: "mustache",lineNumbers: true});
- templates.editors["templates_contenthtml"].setSize(null,height);
- templates.editors["templates_footerhtml"] = CodeMirror.fromTextArea(document.getElementById("templates_footerhtml"), {mode: "mustache",lineNumbers: true});
- templates.editors["templates_footerhtml"].setSize(null,height);
- templates.editors["templates_styles"] = CodeMirror.fromTextArea(document.getElementById("templates_styles"), {mode: "css",lineNumbers: true});
- templates.editors["templates_styles"].setSize(null,height);
- templates.tblreportsql = new Tabulator("#tbl_reportsql",{
- headerFilterPlaceholder: "filter...",
- height: "calc(100vh - 300px)",
- layout: "fitColumns",
- selectable: true,
- selectableRangeMode:"click",
- rowContext:function(e, row){ e.preventDefault(); },
- columns: [
- {title: "Id", field: "id", width: 80, editor:"input"},
- {title: "Abfrage-Typ", field: "type",width: 120 , edior:"select"},
- {title: "SQL", field: "sql",editor:"input"},
- ]
+
+ templates.selects["templates_reporttype"] =new SlimSelect({
+ select: "#templates_reporttype",
+ showSearch: false
});
+
+ var height = 300;
+ tinymce.init({
+ selector: '.richeditarea',
+ plugins: 'preview paste importcss searchreplace autolink directionality code visualblocks visualchars fullscreen image link media template table charmap hr nonbreaking anchor advlist lists imagetools textpattern noneditable charmap emoticons autoresize code fullpage autoresize',
+ imagetools_cors_hosts: ['picsum.photos'],
+ menubar: false,
+ // 'file edit view insert format tools table',
+ toolbar: 'undo redo | bold italic underline strikethrough | fontselect fontsizeselect | alignleft aligncenter alignright alignjustify | outdent indent | forecolor removeformat | charmap | image table code template',
+ toolbar_sticky: true,
+ language: 'de',
+ statusbar: false,
+ element_format : 'html',
+ extended_valid_elements: 'script,style',
+ templates :[
+ { title: 'Rechnung: Kunden-Nummer' ,description:"",content:'{{inv.clientnumber}}'}
+ ],
+ // content_css: [
+ // '[% abspath %]css/w3pro.css'
+ // ],
+ forced_root_block : '',
+ //min_height: 350,
+ branding: false,
+ importcss_append: true,
+ image_advtab: true,
+ image_title: true,
+ automatic_uploads: true,
+ file_picker_types: 'image',
+ file_picker_callback: function (cb, value, meta) {
+ var input = document.createElement('input');
+ input.setAttribute('type', 'file');
+ input.setAttribute('accept', 'image/*');
+ input.onchange = function () {
+ var file = this.files[0];
+
+ var reader = new FileReader();
+ reader.onload = function () {
+ var id = 'blobid' + (new Date()).getTime();
+ var blobCache = tinymce.activeEditor.editorUpload.blobCache;
+ var base64 = reader.result.split(',')[1];
+ var blobInfo = blobCache.create(id, file, base64);
+ blobCache.add(blobInfo);
+ cb(blobInfo.blobUri(), { title: file.name });
+ };
+ reader.readAsDataURL(file);
+ };
+
+ input.click();
+
+ },
+ image_caption: true,
+ noneditable_noneditable_class: "mceNonEditable",
+ contextmenu: "link image imagetools table",
+ });
+ // tinymce.init({
+ // selector: '#invoices_headertext, #invoicebooking_description, #invoices_footertext',
+ // plugins: 'paste importcss searchreplace autolink directionality visualblocks visualchars template autoresize charmap nonbreaking advlist lists textpattern noneditable charmap',
+ // menubar: false,
+ // toolbar: 'bold italic underline strikethrough fontsizeselect forecolor removeformat charmap',
+ // toolbar_sticky: true,
+ // language: 'de',
+ // // content_css: [
+ // // 'css/theme.css'
+ // // ],
+ // statusbar: false,
+ // width: '100%',
+ // min_height: 150,
+ // max_height: 150,
+ // forced_root_block : '',
+ // branding: false,
+ // importcss_append: true,
+ // noneditable_noneditable_class: "mceNonEditable",
+ // contextmenu: false,
+ // setup: function(editor) {
+ // editor.on('blur', function(e) {
+ // if (e.target.id == 'invoices_headertext' || e.target.id == 'invoices_footertext'){
+ // dataform.savefield(document.getElementById(e.target.id));
+ // }
+ // });
+ // }
+ // });
+ //document.getElementById("tab_templateheader").style.height;
+ // templates.editors["templates_headerhtml"] = CodeMirror.fromTextArea(document.getElementById("templates_headerhtml"), {mode: "mustache",lineNumbers: true});
+ // templates.editors["templates_headerhtml"].setSize(null,height);
+ // templates.editors["templates_contenthtml"] = CodeMirror.fromTextArea(document.getElementById("templates_contenthtml"), {mode: "mustache",lineNumbers: true});
+ // templates.editors["templates_contenthtml"].setSize(null,height);
+ // // templates.editors["templates_footerhtml"] = CodeMirror.fromTextArea(document.getElementById("templates_footerhtml"), {mode: "mustache",lineNumbers: true});
+ // // templates.editors["templates_footerhtml"].setSize(null,height);
+ // templates.editors["templates_styles"] = CodeMirror.fromTextArea(document.getElementById("templates_styles"), {mode: "css",lineNumbers: true});
+ // templates.editors["templates_styles"].setSize(null,height);
+ // templates.tblreportsql = new Tabulator("#tbl_reportsql",{
+ // headerFilterPlaceholder: "filter...",
+ // height: "calc(100vh - 300px)",
+ // layout: "fitColumns",
+ // selectable: true,
+ // selectableRangeMode:"click",
+ // rowContext:function(e, row){ e.preventDefault(); },
+ // columns: [
+ // {title: "Id", field: "id", width: 80, editor:"input"},
+ // {title: "Abfrage-Typ", field: "type",width: 120 , edior:"select"},
+ // {title: "SQL", field: "sql",editor:"input"},
+ // ]
+ // });
templates.tbl = new Tabulator("#tbl_templates",{
headerFilterPlaceholder: "filter...",
height: "calc(100vh - 60px)",
});
templates.gettbldata();
templates.getTypesList();
+ CodeMirror.defineMode("mustache", function(config, parserConfig) {
+ var mustacheOverlay = {
+ token: function(stream, state) {
+ var ch;
+ if (stream.match("{{")) {
+ while ((ch = stream.next()) != null)
+ if (ch == "}" && stream.next() == "}") {
+ stream.eat("}");
+ return "mustache";
+ }
+ }
+ while (stream.next() != null && !stream.match("{{", false)) {}
+ return null;
+ }
+ };
+ return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || "text/html"), mustacheOverlay);
+ });
},
gettbldata: function(){
if (templates.tbl){
- db.queryarray("select * from newreports order by reportname,reporttype;").then(data => {
+ db.queryarray("select * from reports order by reportname,reporttype;").then(data => {
console.log(data);
templates.tbl.setData(data);
});
}
},
getTypesList: function(){
- db.queryarray("SELECT reporttype as value,reporttype as text FROM newreports GROUP by reporttype ORDER BY reportname;").then(data => {
+ db.queryarray("SELECT reporttype as value,reporttype as text FROM reports GROUP by reporttype ORDER BY reportname;").then(data => {
//console.log("ReportList",data);
dataform.fillselectlist(templates.selects["templates_reporttype"],data,'value','text');
}).catch(e => { console.log(e);});;
if (fsel[0] ){
if (fsel[0].type == 'email'){
myapp.viewpanel('templateemail');
- db.query("select * from newreports where id='"+ fsel[0].id+"';").then(data => {
+ db.query("select * from reports where id='"+ fsel[0].id+"';").then(data => {
}).catch(e => { console.log(e);});
}else {
myapp.viewpanel('templatereport');
- db.query("select * from newreports where id='"+ fsel[0].id+"';").then(data => {
+ db.query("select * from reports where id='"+ fsel[0].id+"';").then(data => {
console.log("repdata",data);
document.getElementById("templates_reportname").value=data.reportname;
templates.selects["templates_reporttype"].set(data.reporttype);
//console.log("pdfoption",opt,templates.templatedata.pdfoptions[opt]);
}
let rtbldata = [];
- for (var rsql in templates.templatedata.reportsql){
- rtbldata.push({"id":rsql,"sql":templates.templatedata.reportsql[rsql].sql,"type":templates.templatedata.reportsql[rsql].type});
- console.log("reportsql",rsql,templates.templatedata.reportsql[rsql]);
- }
- console.log(rtbldata);
- templates.tblreportsql.setData(rtbldata);
- templates.editors["templates_headerhtml"].setValue(data.headerhtml);
- templates.editors["templates_contenthtml"].setValue(data.contenthtml);
- templates.editors["templates_footerhtml"].setValue(data.footerhtml);
- templates.editors["templates_styles"].setValue(data.styles);
+ // for (var rsql in templates.templatedata.reportsql){
+ // rtbldata.push({"id":rsql,"sql":templates.templatedata.reportsql[rsql].sql,"type":templates.templatedata.reportsql[rsql].type});
+ // console.log("reportsql",rsql,templates.templatedata.reportsql[rsql]);
+ // }
+ // console.log(rtbldata);
+ // templates.tblreportsql.setData(rtbldata);
+ tinymce.get("templates_headerhtml").setContent(data.headerhtml);
+ tinymce.get("templates_contenthtml").setContent(data.contenthtml);
+ tinymce.get("templates_footerhtml").setContent(data.footerhtml);
+ // templates.editors["templates_headerhtml"].setValue(data.headerhtml);
+ // templates.editors["templates_contenthtml"].setValue(data.contenthtml);
+ // templates.editors["templates_footerhtml"].setValue(data.footerhtml);
+ // templates.editors["templates_styles"].setValue(data.styles);
//document.getElementById("templates_headerhtml").value= data.headerhtml;
+++ /dev/null
-/*! jQuery v3.5.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/Tween,-effects/animatedSelector | (c) JS Foundation and other contributors | jquery.org/license */
-!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(g,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,v=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),m={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},w=g.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function C(e,t,n){var r,i,o=(n=n||w).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function T(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/Tween,-effects/animatedSelector",E=function(e,t){return new E.fn.init(e,t)};function d(e){var t=!!e&&"length"in e&&e.length,n=T(e);return!b(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}E.fn=E.prototype={jquery:f,constructor:E,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=E.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return E.each(this,e)},map:function(n){return this.pushStack(E.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(E.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(E.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},E.extend=E.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||b(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(E.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||E.isPlainObject(n)?n:{},i=!1,a[t]=E.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},E.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=y.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){C(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(d(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(d(Object(e))?E.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(d(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return v(a)},guid:1,support:m}),"function"==typeof Symbol&&(E.fn[Symbol.iterator]=t[Symbol.iterator]),E.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var p=function(n){var e,p,x,o,i,h,f,g,w,u,l,C,T,a,E,v,s,c,y,A="sizzle"+1*new Date,d=n.document,N=0,r=0,m=ue(),b=ue(),S=ue(),k=ue(),D=function(e,t){return e===t&&(l=!0),0},L={}.hasOwnProperty,t=[],j=t.pop,q=t.push,O=t.push,P=t.slice,H=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},I="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",R="[\\x20\\t\\r\\n\\f]",B="(?:\\\\[\\da-fA-F]{1,6}"+R+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",M="\\["+R+"*("+B+")(?:"+R+"*([*^$|!~]?=)"+R+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+B+"))|)"+R+"*\\]",W=":("+B+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",F=new RegExp(R+"+","g"),$=new RegExp("^"+R+"+|((?:^|[^\\\\])(?:\\\\.)*)"+R+"+$","g"),z=new RegExp("^"+R+"*,"+R+"*"),_=new RegExp("^"+R+"*([>+~]|"+R+")"+R+"*"),U=new RegExp(R+"|>"),V=new RegExp(W),X=new RegExp("^"+B+"$"),Q={ID:new RegExp("^#("+B+")"),CLASS:new RegExp("^\\.("+B+")"),TAG:new RegExp("^("+B+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+I+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,G=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,J=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+R+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){C()},ae=xe(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{O.apply(t=P.call(d.childNodes),d.childNodes),t[d.childNodes.length].nodeType}catch(e){O={apply:t.length?function(e,t){q.apply(e,P.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,d=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==d&&9!==d&&11!==d)return n;if(!r&&(C(e),e=e||T,E)){if(11!==d&&(u=Z.exec(t)))if(i=u[1]){if(9===d){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return O.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&p.getElementsByClassName&&e.getElementsByClassName)return O.apply(n,e.getElementsByClassName(i)),n}if(p.qsa&&!k[t+" "]&&(!v||!v.test(t))&&(1!==d||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===d&&(U.test(t)||_.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&p.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=A)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+be(l[o]);c=l.join(",")}try{return O.apply(n,f.querySelectorAll(c)),n}catch(e){k(t,!0)}finally{s===A&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>x.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[A]=!0,e}function ce(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)x.attrHandle[n[r]]=t}function de(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function pe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in p=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},C=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:d;return r!=T&&9===r.nodeType&&r.documentElement&&(a=(T=r).documentElement,E=!i(T),d!=T&&(n=T.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),p.scope=ce(function(e){return a.appendChild(e).appendChild(T.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),p.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),p.getElementsByTagName=ce(function(e){return e.appendChild(T.createComment("")),!e.getElementsByTagName("*").length}),p.getElementsByClassName=J.test(T.getElementsByClassName),p.getById=ce(function(e){return a.appendChild(e).id=A,!T.getElementsByName||!T.getElementsByName(A).length}),p.getById?(x.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(x.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),x.find.TAG=p.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):p.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},x.find.CLASS=p.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(p.qsa=J.test(T.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="<a id='"+A+"'></a><select id='"+A+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+R+"*(?:value|"+I+")"),e.querySelectorAll("[id~="+A+"-]").length||v.push("~="),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+R+"*name"+R+"*="+R+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+A+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=T.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(p.matchesSelector=J.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){p.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",W)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=J.test(a.compareDocumentPosition),y=t||J.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!p.sortDetached&&t.compareDocumentPosition(e)===n?e==T||e.ownerDocument==d&&y(d,e)?-1:t==T||t.ownerDocument==d&&y(d,t)?1:u?H(u,e)-H(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==T?-1:t==T?1:i?-1:o?1:u?H(u,e)-H(u,t):0;if(i===o)return de(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?de(a[r],s[r]):a[r]==d?-1:s[r]==d?1:0}),T},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(C(e),p.matchesSelector&&E&&!k[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||p.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){k(t,!0)}return 0<se(t,T,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=T&&C(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=T&&C(e);var n=x.attrHandle[t.toLowerCase()],r=n&&L.call(x.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:p.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!p.detectDuplicates,u=!p.sortStable&&e.slice(0),e.sort(D),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(x=se.selectors={cacheLength:50,createPseudo:le,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&V.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(F," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),b="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=b&&e.nodeName.toLowerCase(),d=!n&&!b,p=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(b?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&d){p=(s=(r=(i=(o=(a=c)[A]||(a[A]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===N&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(p=s=0)||u.pop())if(1===a.nodeType&&++p&&a===e){i[h]=[N,s,p];break}}else if(d&&(p=s=(r=(i=(o=(a=e)[A]||(a[A]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===N&&r[1]),!1===p)while(a=++s&&a&&a[l]||(p=s=0)||u.pop())if((b?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++p&&(d&&((i=(o=a[A]||(a[A]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[N,p]),a===e))break;return(p-=v)===g||p%g==0&&0<=p/g}}},PSEUDO:function(e,o){var t,a=x.pseudos[e]||x.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[A]?a(o):1<a.length?(t=[e,e,"",o],x.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=H(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace($,"$1"));return s[A]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return X.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===T.activeElement&&(!T.hasFocus||T.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!x.pseudos.empty(e)},header:function(e){return K.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=x.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})x.pseudos[e]=pe(e);for(e in{submit:!0,reset:!0})x.pseudos[e]=he(e);function me(){}function be(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function xe(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,d=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[N,d];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[A]||(e[A]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===N&&r[1]===d)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Ce(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Te(p,h,g,v,y,e){return v&&!v[A]&&(v=Te(v)),y&&!y[A]&&(y=Te(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!p||!e&&h?c:Ce(c,s,p,n,r),d=g?y||(e?p:l||v)?[]:t:f;if(g&&g(f,d,n,r),v){i=Ce(d,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(d[u[o]]=!(f[u[o]]=a))}if(e){if(y||p){if(y){i=[],o=d.length;while(o--)(a=d[o])&&i.push(f[o]=a);y(null,d=[],i,r)}o=d.length;while(o--)(a=d[o])&&-1<(i=y?H(e,a):s[o])&&(e[i]=!(t[i]=a))}}else d=Ce(d===t?d.splice(l,d.length):d),y?y(null,t,d,r):O.apply(t,d)})}function Ee(e){for(var i,t,n,r=e.length,o=x.relative[e[0].type],a=o||x.relative[" "],s=o?1:0,u=xe(function(e){return e===i},a,!0),l=xe(function(e){return-1<H(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=x.relative[e[s].type])c=[xe(we(c),t)];else{if((t=x.filter[e[s].type].apply(null,e[s].matches))[A]){for(n=++s;n<r;n++)if(x.relative[e[n].type])break;return Te(1<s&&we(c),1<s&&be(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace($,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&be(e))}c.push(t)}return we(c)}return me.prototype=x.filters=x.pseudos,x.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=b[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=x.preFilter;while(a){for(o in n&&!(r=z.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=_.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace($," ")}),a=a.slice(n.length)),x.filter)!(r=Q[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):b(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,b,r,i=[],o=[],a=S[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[A]?i.push(a):o.push(a);(a=S(e,(v=o,m=0<(y=i).length,b=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],d=w,p=e||b&&x.find.TAG("*",i),h=N+=null==d?1:Math.random()||.1,g=p.length;for(i&&(w=t==T||t||i);l!==g&&null!=(o=p[l]);l++){if(b&&o){a=0,t||o.ownerDocument==T||(C(o),n=!E);while(s=v[a++])if(s(o,t||T,n)){r.push(o);break}i&&(N=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=j.call(r));f=Ce(f)}O.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(N=h,w=d),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&x.relative[o[1].type]){if(!(t=(x.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=Q.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],x.relative[s=a.type])break;if((u=x.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&be(o)))return O.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},p.sortStable=A.split("").sort(D).join("")===A,p.detectDuplicates=!!l,C(),p.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(T.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),p.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(I,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(g);E.find=p,E.expr=p.selectors,E.expr[":"]=E.expr.pseudos,E.uniqueSort=E.unique=p.uniqueSort,E.text=p.getText,E.isXMLDoc=p.isXML,E.contains=p.contains,E.escapeSelector=p.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&E(e).is(n))break;r.push(e)}return r},A=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},N=E.expr.match.needsContext;function S(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var k=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return b(n)?E.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?E.grep(e,function(e){return e===n!==r}):"string"!=typeof n?E.grep(e,function(e){return-1<i.call(n,e)!==r}):E.filter(n,e,r)}E.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?E.find.matchesSelector(r,e)?[r]:[]:E.find.matches(e,E.grep(t,function(e){return 1===e.nodeType}))},E.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(E(e).filter(function(){for(t=0;t<r;t++)if(E.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)E.find(e,i[t],n);return 1<r?E.uniqueSort(n):n},filter:function(e){return this.pushStack(D(this,e||[],!1))},not:function(e){return this.pushStack(D(this,e||[],!0))},is:function(e){return!!D(this,"string"==typeof e&&N.test(e)?E(e):e||[],!1).length}});var L,j=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(E.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||L,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:j.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof E?t[0]:t,E.merge(this,E.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:w,!0)),k.test(r[1])&&E.isPlainObject(t))for(r in t)b(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=w.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(E):E.makeArray(e,this)}).prototype=E.fn,L=E(w);var q=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}E.fn.extend({has:function(e){var t=E(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(E.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&E(e);if(!N.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&E.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?E.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(E(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(E.uniqueSort(E.merge(this.get(),E(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),E.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t,n){return h(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return h(e,"nextSibling")},prevAll:function(e){return h(e,"previousSibling")},nextUntil:function(e,t,n){return h(e,"nextSibling",n)},prevUntil:function(e,t,n){return h(e,"previousSibling",n)},siblings:function(e){return A((e.parentNode||{}).firstChild,e)},children:function(e){return A(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(S(e,"template")&&(e=e.content||e),E.merge([],e.childNodes))}},function(r,i){E.fn[r]=function(e,t){var n=E.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=E.filter(t,n)),1<this.length&&(O[r]||E.uniqueSort(n),q.test(r)&&n.reverse()),this.pushStack(n)}});var H=/[^\x20\t\r\n\f]+/g;function I(e){return e}function R(e){throw e}function B(e,t,n,r){var i;try{e&&b(i=e.promise)?i.call(e).done(t).fail(n):e&&b(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}E.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},E.each(e.match(H)||[],function(e,t){n[t]=!0}),n):E.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){E.each(e,function(e,t){b(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==T(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return E.each(arguments,function(e,t){var n;while(-1<(n=E.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<E.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},E.extend({Deferred:function(e){var o=[["notify","progress",E.Callbacks("memory"),E.Callbacks("memory"),2],["resolve","done",E.Callbacks("once memory"),E.Callbacks("once memory"),0,"resolved"],["reject","fail",E.Callbacks("once memory"),E.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return E.Deferred(function(r){E.each(o,function(e,t){var n=b(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&b(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,b(t)?s?t.call(e,l(u,o,I,s),l(u,o,R,s)):(u++,t.call(e,l(u,o,I,s),l(u,o,R,s),l(u,o,I,o.notifyWith))):(a!==I&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){E.Deferred.exceptionHook&&E.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==R&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(E.Deferred.getStackHook&&(t.stackTrace=E.Deferred.getStackHook()),g.setTimeout(t))}}return E.Deferred(function(e){o[0][3].add(l(0,e,b(r)?r:I,e.notifyWith)),o[1][3].add(l(0,e,b(t)?t:I)),o[2][3].add(l(0,e,b(n)?n:R))}).promise()},promise:function(e){return null!=e?E.extend(e,a):a}},s={};return E.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=E.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(B(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||b(i[t]&&i[t].then)))return o.then();while(t--)B(i[t],a(t),o.reject);return o.promise()}});var M=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;E.Deferred.exceptionHook=function(e,t){g.console&&g.console.warn&&e&&M.test(e.name)&&g.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},E.readyException=function(e){g.setTimeout(function(){throw e})};var W=E.Deferred();function F(){w.removeEventListener("DOMContentLoaded",F),g.removeEventListener("load",F),E.ready()}E.fn.ready=function(e){return W.then(e)["catch"](function(e){E.readyException(e)}),this},E.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--E.readyWait:E.isReady)||(E.isReady=!0)!==e&&0<--E.readyWait||W.resolveWith(w,[E])}}),E.ready.then=W.then,"complete"===w.readyState||"loading"!==w.readyState&&!w.documentElement.doScroll?g.setTimeout(E.ready):(w.addEventListener("DOMContentLoaded",F),g.addEventListener("load",F));var $=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===T(n))for(s in i=!0,n)$(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,b(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(E(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},z=/^-ms-/,_=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function V(e){return e.replace(z,"ms-").replace(_,U)}var X=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function Q(){this.expando=E.expando+Q.uid++}Q.uid=1,Q.prototype={cache:function(e){var t=e[this.expando];return t||(t={},X(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[V(t)]=n;else for(r in t)i[V(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][V(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(V):(t=V(t))in r?[t]:t.match(H)||[]).length;while(n--)delete r[t[n]]}(void 0===t||E.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!E.isEmptyObject(t)}};var Y=new Q,G=new Q,K=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,J=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(J,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:K.test(i)?JSON.parse(i):i)}catch(e){}G.set(e,t,n)}else n=void 0;return n}E.extend({hasData:function(e){return G.hasData(e)||Y.hasData(e)},data:function(e,t,n){return G.access(e,t,n)},removeData:function(e,t){G.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),E.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=G.get(o),1===o.nodeType&&!Y.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=V(r.slice(5)),Z(o,r,i[r]));Y.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){G.set(this,n)}):$(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=G.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){G.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){G.remove(this,e)})}}),E.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,E.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=E.queue(e,t),r=n.length,i=n.shift(),o=E._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){E.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Y.get(e,n)||Y.access(e,n,{empty:E.Callbacks("once memory").add(function(){Y.remove(e,[t+"queue",n])})})}}),E.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?E.queue(this[0],t):void 0===n?this:this.each(function(){var e=E.queue(this,t,n);E._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&E.dequeue(this,t)})},dequeue:function(e){return this.each(function(){E.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=E.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Y.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,te=new RegExp("^(?:([+-])=|)("+ee+")([a-z%]*)$","i"),ne=["Top","Right","Bottom","Left"],re=w.documentElement,ie=function(e){return E.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return E.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&ie(e)&&"none"===E.css(e,"display")};var se={};function ue(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Y.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=se[s])||(o=a.body.appendChild(a.createElement(s)),u=E.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),se[s]=u)))):"none"!==n&&(l[c]="none",Y.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}E.fn.extend({show:function(){return ue(this,!0)},hide:function(){return ue(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?E(this).show():E(this).hide()})}});var le,ce,fe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i;le=w.createDocumentFragment().appendChild(w.createElement("div")),(ce=w.createElement("input")).setAttribute("type","radio"),ce.setAttribute("checked","checked"),ce.setAttribute("name","t"),le.appendChild(ce),m.checkClone=le.cloneNode(!0).cloneNode(!0).lastChild.checked,le.innerHTML="<textarea>x</textarea>",m.noCloneChecked=!!le.cloneNode(!0).lastChild.defaultValue,le.innerHTML="<option></option>",m.option=!!le.lastChild;var he={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ge(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&S(e,t)?E.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],"globalEval",!t||Y.get(t[n],"globalEval"))}he.tbody=he.tfoot=he.colgroup=he.caption=he.thead,he.th=he.td,m.option||(he.optgroup=he.option=[1,"<select multiple='multiple'>","</select>"]);var ye=/<|&#?\w+;/;function me(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),d=[],p=0,h=e.length;p<h;p++)if((o=e[p])||0===o)if("object"===T(o))E.merge(d,o.nodeType?[o]:o);else if(ye.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=he[s]||he._default,a.innerHTML=u[1]+E.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;E.merge(d,a.childNodes),(a=f.firstChild).textContent=""}else d.push(t.createTextNode(o));f.textContent="",p=0;while(o=d[p++])if(r&&-1<E.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ge(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])pe.test(o.type||"")&&n.push(o)}return f}var be=/^key/,xe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,we=/^([^.]*)(?:\.(.+)|)/;function Ce(){return!0}function Te(){return!1}function Ee(e,t){return e===function(){try{return w.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Te;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return E().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=E.guid++)),e.each(function(){E.event.add(this,t,i,r,n)})}function Ne(e,i,o){o?(Y.set(e,i,!1),E.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(E.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Y.set(this,i,{value:E.event.trigger(E.extend(r[0],E.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&E.event.add(e,i,Ce)}E.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,v=Y.get(t);if(X(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&E.find.matchesSelector(re,i),n.guid||(n.guid=E.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof E&&E.event.triggered!==e.type?E.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(H)||[""]).length;while(l--)p=g=(s=we.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),p&&(f=E.event.special[p]||{},p=(i?f.delegateType:f.bindType)||p,f=E.event.special[p]||{},c=E.extend({type:p,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&E.expr.match.needsContext.test(i),namespace:h.join(".")},o),(d=u[p])||((d=u[p]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(p,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,c):d.push(c),E.event.global[p]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,v=Y.hasData(e)&&Y.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(H)||[""]).length;while(l--)if(p=g=(s=we.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),p){f=E.event.special[p]||{},d=u[p=(r?f.delegateType:f.bindType)||p]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=d.length;while(o--)c=d[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(d.splice(o,1),c.selector&&d.delegateCount--,f.remove&&f.remove.call(e,c));a&&!d.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||E.removeEvent(e,p,v.handle),delete u[p])}else for(p in u)E.event.remove(e,p+t[l],n,r,!0);E.isEmptyObject(u)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=E.event.fix(e),l=(Y.get(this,"events")||Object.create(null))[u.type]||[],c=E.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=E.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((E.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<E(i,this).index(l):E.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(E.Event.prototype,t,{enumerable:!0,configurable:!0,get:b(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[E.expando]?e:new E.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return fe.test(t.type)&&t.click&&S(t,"input")&&Ne(t,"click",Ce),!1},trigger:function(e){var t=this||e;return fe.test(t.type)&&t.click&&S(t,"input")&&Ne(t,"click"),!0},_default:function(e){var t=e.target;return fe.test(t.type)&&t.click&&S(t,"input")&&Y.get(t,"click")||S(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},E.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},E.Event=function(e,t){if(!(this instanceof E.Event))return new E.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ce:Te,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&E.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[E.expando]=!0},E.Event.prototype={constructor:E.Event,isDefaultPrevented:Te,isPropagationStopped:Te,isImmediatePropagationStopped:Te,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ce,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ce,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ce,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},E.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&be.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&xe.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},E.event.addProp),E.each({focus:"focusin",blur:"focusout"},function(e,t){E.event.special[e]={setup:function(){return Ne(this,e,Ee),!1},trigger:function(){return Ne(this,e),!0},delegateType:t}}),E.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){E.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||E.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),E.fn.extend({on:function(e,t,n,r){return Ae(this,e,t,n,r)},one:function(e,t,n,r){return Ae(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,E(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Te),this.each(function(){E.event.remove(this,e,n,t)})}});var Se=/<script|<style|<link/i,ke=/checked\s*(?:[^=]|=\s*.checked.)/i,De=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Le(e,t){return S(e,"table")&&S(11!==t.nodeType?t:t.firstChild,"tr")&&E(e).children("tbody")[0]||e}function je(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)E.event.add(t,i,s[i][n]);G.hasData(e)&&(o=G.access(e),a=E.extend({},o),G.set(t,a))}}function Pe(n,r,i,o){r=v(r);var e,t,a,s,u,l,c=0,f=n.length,d=f-1,p=r[0],h=b(p);if(h||1<f&&"string"==typeof p&&!m.checkClone&&ke.test(p))return n.each(function(e){var t=n.eq(e);h&&(r[0]=p.call(this,e,t.html())),Pe(t,r,i,o)});if(f&&(t=(e=me(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=E.map(ge(e,"script"),je)).length;c<f;c++)u=e,c!==d&&(u=E.clone(u,!0,!0),s&&E.merge(a,ge(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,E.map(a,qe),c=0;c<s;c++)u=a[c],pe.test(u.type||"")&&!Y.access(u,"globalEval")&&E.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?E._evalUrl&&!u.noModule&&E._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):C(u.textContent.replace(De,""),u,l))}return n}function He(e,t,n){for(var r,i=t?E.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||E.cleanData(ge(r)),r.parentNode&&(n&&ie(r)&&ve(ge(r,"script")),r.parentNode.removeChild(r));return e}E.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(m.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||E.isXMLDoc(e)))for(a=ge(c),r=0,i=(o=ge(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&fe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ge(e),a=a||ge(c),r=0,i=o.length;r<i;r++)Oe(o[r],a[r]);else Oe(e,c);return 0<(a=ge(c,"script")).length&&ve(a,!f&&ge(e,"script")),c},cleanData:function(e){for(var t,n,r,i=E.event.special,o=0;void 0!==(n=e[o]);o++)if(X(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?E.event.remove(n,r):E.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[G.expando]&&(n[G.expando]=void 0)}}}),E.fn.extend({detach:function(e){return He(this,e,!0)},remove:function(e){return He(this,e)},text:function(e){return $(this,function(e){return void 0===e?E.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Pe(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Pe(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(E.cleanData(ge(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return E.clone(this,e,t)})},html:function(e){return $(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Se.test(e)&&!he[(de.exec(e)||["",""])[1].toLowerCase()]){e=E.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(E.cleanData(ge(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return Pe(this,arguments,function(e){var t=this.parentNode;E.inArray(this,n)<0&&(E.cleanData(ge(this)),t&&t.replaceChild(e,this))},n)}}),E.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){E.fn[e]=function(e){for(var t,n=[],r=E(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),E(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Ie=new RegExp("^("+ee+")(?!px)[a-z%]+$","i"),Re=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=g),t.getComputedStyle(e)},Be=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Me=new RegExp(ne.join("|"),"i");function We(e,t,n){var r,i,o,a,s=e.style;return(n=n||Re(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||ie(e)||(a=E.style(e,t)),!m.pixelBoxStyles()&&Ie.test(a)&&Me.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function Fe(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",re.appendChild(u).appendChild(l);var e=g.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=w.createElement("div"),l=w.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",m.clearCloneStyle="content-box"===l.style.backgroundClip,E.extend(m,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=w.createElement("table"),t=w.createElement("tr"),n=w.createElement("div"),e.style.cssText="position:absolute;left:-11111px",t.style.height="1px",n.style.height="9px",re.appendChild(e).appendChild(t).appendChild(n),r=g.getComputedStyle(t),a=3<parseInt(r.height),re.removeChild(e)),a}}))}();var $e=["Webkit","Moz","ms"],ze=w.createElement("div").style,_e={};function Ue(e){var t=E.cssProps[e]||_e[e];return t||(e in ze?e:_e[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=$e.length;while(n--)if((e=$e[n]+t)in ze)return e}(e)||e)}var Ve,Xe,Qe=/^(none|table(?!-c[ea]).+)/,Ye=/^--/,Ge={position:"absolute",visibility:"hidden",display:"block"},Ke={letterSpacing:"0",fontWeight:"400"};function Je(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ze(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=E.css(e,n+ne[a],!0,i)),r?("content"===n&&(u-=E.css(e,"padding"+ne[a],!0,i)),"margin"!==n&&(u-=E.css(e,"border"+ne[a]+"Width",!0,i))):(u+=E.css(e,"padding"+ne[a],!0,i),"padding"!==n?u+=E.css(e,"border"+ne[a]+"Width",!0,i):s+=E.css(e,"border"+ne[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function et(e,t,n){var r=Re(e),i=(!m.boxSizingReliable()||n)&&"border-box"===E.css(e,"boxSizing",!1,r),o=i,a=We(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Ie.test(a)){if(!n)return a;a="auto"}return(!m.boxSizingReliable()&&i||!m.reliableTrDimensions()&&S(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===E.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===E.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Ze(e,t,n||(i?"border":"content"),o,r,a)+"px"}E.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=We(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=V(t),u=Ye.test(t),l=e.style;if(u||(t=Ue(s)),a=E.cssHooks[t]||E.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=function(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return E.css(e,t,"")},u=s(),l=n&&n[3]||(E.cssNumber[t]?"":"px"),c=e.nodeType&&(E.cssNumber[t]||"px"!==l&&+u)&&te.exec(E.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)E.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,E.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(E.cssNumber[s]?"":"px")),m.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=V(t);return Ye.test(t)||(t=Ue(s)),(a=E.cssHooks[t]||E.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=We(e,t,r)),"normal"===i&&t in Ke&&(i=Ke[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),E.each(["height","width"],function(e,u){E.cssHooks[u]={get:function(e,t,n){if(t)return!Qe.test(E.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,u,n):Be(e,Ge,function(){return et(e,u,n)})},set:function(e,t,n){var r,i=Re(e),o=!m.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===E.css(e,"boxSizing",!1,i),s=n?Ze(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Ze(e,u,"border",!1,i)-.5)),s&&(r=te.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=E.css(e,u)),Je(0,t,s)}}}),E.cssHooks.marginLeft=Fe(m.reliableMarginLeft,function(e,t){if(t)return(parseFloat(We(e,"marginLeft"))||e.getBoundingClientRect().left-Be(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),E.each({margin:"",padding:"",border:"Width"},function(i,o){E.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(E.cssHooks[i+o].set=Je)}),E.fn.extend({css:function(e,t){return $(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Re(e),i=t.length;a<i;a++)o[t[a]]=E.css(e,t[a],!1,r);return o}return void 0!==n?E.style(e,t,n):E.css(e,t)},e,t,1<arguments.length)}}),E.fn.delay=function(r,e){return r=E.fx&&E.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=g.setTimeout(e,r);t.stop=function(){g.clearTimeout(n)}})},Ve=w.createElement("input"),Xe=w.createElement("select").appendChild(w.createElement("option")),Ve.type="checkbox",m.checkOn=""!==Ve.value,m.optSelected=Xe.selected,(Ve=w.createElement("input")).value="t",Ve.type="radio",m.radioValue="t"===Ve.value;var tt,nt=E.expr.attrHandle;E.fn.extend({attr:function(e,t){return $(this,E.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){E.removeAttr(this,e)})}}),E.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?E.prop(e,t,n):(1===o&&E.isXMLDoc(e)||(i=E.attrHooks[t.toLowerCase()]||(E.expr.match.bool.test(t)?tt:void 0)),void 0!==n?null===n?void E.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=E.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!m.radioValue&&"radio"===t&&S(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(H);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),tt={set:function(e,t,n){return!1===t?E.removeAttr(e,n):e.setAttribute(n,n),n}},E.each(E.expr.match.bool.source.match(/\w+/g),function(e,t){var a=nt[t]||E.find.attr;nt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=nt[o],nt[o]=r,r=null!=a(e,t,n)?o:null,nt[o]=i),r}});var rt=/^(?:input|select|textarea|button)$/i,it=/^(?:a|area)$/i;function ot(e){return(e.match(H)||[]).join(" ")}function at(e){return e.getAttribute&&e.getAttribute("class")||""}function st(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(H)||[]}E.fn.extend({prop:function(e,t){return $(this,E.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[E.propFix[e]||e]})}}),E.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&E.isXMLDoc(e)||(t=E.propFix[t]||t,i=E.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=E.find.attr(e,"tabindex");return t?parseInt(t,10):rt.test(e.nodeName)||it.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),m.optSelected||(E.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),E.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){E.propFix[this.toLowerCase()]=this}),E.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(b(t))return this.each(function(e){E(this).addClass(t.call(this,e,at(this)))});if((e=st(t)).length)while(n=this[u++])if(i=at(n),r=1===n.nodeType&&" "+ot(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=ot(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(b(t))return this.each(function(e){E(this).removeClass(t.call(this,e,at(this)))});if(!arguments.length)return this.attr("class","");if((e=st(t)).length)while(n=this[u++])if(i=at(n),r=1===n.nodeType&&" "+ot(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=ot(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):b(i)?this.each(function(e){E(this).toggleClass(i.call(this,e,at(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=E(this),r=st(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=at(this))&&Y.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Y.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+ot(at(n))+" ").indexOf(t))return!0;return!1}});var ut=/\r/g;E.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=b(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,E(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=E.map(t,function(e){return null==e?"":e+""})),(r=E.valHooks[this.type]||E.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=E.valHooks[t.type]||E.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(ut,""):null==e?"":e:void 0}}),E.extend({valHooks:{option:{get:function(e){var t=E.find.attr(e,"value");return null!=t?t:ot(E.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!S(n.parentNode,"optgroup"))){if(t=E(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=E.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<E.inArray(E.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),E.each(["radio","checkbox"],function(){E.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<E.inArray(E(e).val(),t)}},m.checkOn||(E.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),m.focusin="onfocusin"in g;var lt=/^(?:focusinfocus|focusoutblur)$/,ct=function(e){e.stopPropagation()};E.extend(E.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,d=[n||w],p=y.call(e,"type")?e.type:e,h=y.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||w,3!==n.nodeType&&8!==n.nodeType&&!lt.test(p+E.event.triggered)&&(-1<p.indexOf(".")&&(p=(h=p.split(".")).shift(),h.sort()),u=p.indexOf(":")<0&&"on"+p,(e=e[E.expando]?e:new E.Event(p,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:E.makeArray(t,[e]),c=E.event.special[p]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||p,lt.test(s+p)||(o=o.parentNode);o;o=o.parentNode)d.push(o),a=o;a===(n.ownerDocument||w)&&d.push(a.defaultView||a.parentWindow||g)}i=0;while((o=d[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||p,(l=(Y.get(o,"events")||Object.create(null))[e.type]&&Y.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&X(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=p,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(d.pop(),t)||!X(n)||u&&b(n[p])&&!x(n)&&((a=n[u])&&(n[u]=null),E.event.triggered=p,e.isPropagationStopped()&&f.addEventListener(p,ct),n[p](),e.isPropagationStopped()&&f.removeEventListener(p,ct),E.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=E.extend(new E.Event,n,{type:e,isSimulated:!0});E.event.trigger(r,null,t)}}),E.fn.extend({trigger:function(e,t){return this.each(function(){E.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return E.event.trigger(e,t,n,!0)}}),m.focusin||E.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){E.event.simulate(r,e.target,E.event.fix(e))};E.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}}),E.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new g.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||E.error("Invalid XML: "+e),t};var ft,dt=/\[\]$/,pt=/\r?\n/g,ht=/^(?:submit|button|image|reset|file)$/i,gt=/^(?:input|select|textarea|keygen)/i;function vt(n,e,r,i){var t;if(Array.isArray(e))E.each(e,function(e,t){r||dt.test(n)?i(n,t):vt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==T(e))i(n,e);else for(t in e)vt(n+"["+t+"]",e[t],r,i)}E.param=function(e,t){var n,r=[],i=function(e,t){var n=b(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!E.isPlainObject(e))E.each(e,function(){i(this.name,this.value)});else for(n in e)vt(n,e[n],t,i);return r.join("&")},E.fn.extend({serialize:function(){return E.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=E.prop(this,"elements");return e?E.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!E(this).is(":disabled")&>.test(this.nodeName)&&!ht.test(e)&&(this.checked||!fe.test(e))}).map(function(e,t){var n=E(this).val();return null==n?null:Array.isArray(n)?E.map(n,function(e){return{name:t.name,value:e.replace(pt,"\r\n")}}):{name:t.name,value:n.replace(pt,"\r\n")}}).get()}}),E.fn.extend({wrapAll:function(e){var t;return this[0]&&(b(e)&&(e=e.call(this[0])),t=E(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return b(n)?this.each(function(e){E(this).wrapInner(n.call(this,e))}):this.each(function(){var e=E(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=b(t);return this.each(function(e){E(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){E(this).replaceWith(this.childNodes)}),this}}),E.expr.pseudos.hidden=function(e){return!E.expr.pseudos.visible(e)},E.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},m.createHTMLDocument=((ft=w.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===ft.childNodes.length),E.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(m.createHTMLDocument?((r=(t=w.implementation.createHTMLDocument("")).createElement("base")).href=w.location.href,t.head.appendChild(r)):t=w),o=!n&&[],(i=k.exec(e))?[t.createElement(i[1])]:(i=me([e],t,o),o&&o.length&&E(o).remove(),E.merge([],i.childNodes)));var r,i,o},E.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=E.css(e,"position"),c=E(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=E.css(e,"top"),u=E.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),b(t)&&(t=t.call(e,n,E.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},E.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){E.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===E.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===E.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=E(e).offset()).top+=E.css(e,"borderTopWidth",!0),i.left+=E.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-E.css(r,"marginTop",!0),left:t.left-i.left-E.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===E.css(e,"position"))e=e.offsetParent;return e||re})}}),E.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;E.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),E.each(["top","left"],function(e,n){E.cssHooks[n]=Fe(m.pixelPosition,function(e,t){if(t)return t=We(e,n),Ie.test(t)?E(e).position()[n]+"px":t})}),E.each({Height:"height",Width:"width"},function(a,s){E.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){E.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?E.css(e,t,i):E.style(e,t,n,i)},s,n?e:void 0,n)}})}),E.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),E.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){E.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var yt=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;E.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),b(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||E.guid++,i},E.holdReady=function(e){e?E.readyWait++:E.ready(!0)},E.isArray=Array.isArray,E.parseJSON=JSON.parse,E.nodeName=S,E.isFunction=b,E.isWindow=x,E.camelCase=V,E.type=T,E.now=Date.now,E.isNumeric=function(e){var t=E.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},E.trim=function(e){return null==e?"":(e+"").replace(yt,"")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return E});var mt=g.jQuery,bt=g.$;return E.noConflict=function(e){return g.$===E&&(g.$=bt),e&&g.jQuery===E&&(g.jQuery=mt),E},"undefined"==typeof e&&(g.jQuery=g.$=E),E});
\ No newline at end of file
--- /dev/null
+.sun-editor{width:auto;height:auto;box-sizing:border-box;font-family:Helvetica Neue,sans-serif;border:1px solid #dadada;background-color:#fff;color:#000;user-select:none;-o-user-select:none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none}.sun-editor *{box-sizing:border-box;-webkit-user-drag:none;overflow:visible}.sun-editor-common button,.sun-editor-common input,.sun-editor-common select,.sun-editor-common textarea{font-size:14px;line-height:1.5}.sun-editor-common blockquote,.sun-editor-common body,.sun-editor-common button,.sun-editor-common code,.sun-editor-common dd,.sun-editor-common div,.sun-editor-common dl,.sun-editor-common dt,.sun-editor-common fieldset,.sun-editor-common form,.sun-editor-common h1,.sun-editor-common h2,.sun-editor-common h3,.sun-editor-common h4,.sun-editor-common h5,.sun-editor-common h6,.sun-editor-common input,.sun-editor-common legend,.sun-editor-common li,.sun-editor-common ol,.sun-editor-common p,.sun-editor-common pre,.sun-editor-common select,.sun-editor-common td,.sun-editor-common textarea,.sun-editor-common th,.sun-editor-common ul{margin:0;padding:0;border:0}.sun-editor-common dl,.sun-editor-common li,.sun-editor-common menu,.sun-editor-common ol,.sun-editor-common ul{list-style:none!important}.sun-editor-common hr{margin:6px 0!important}.sun-editor textarea{resize:none;border:0;padding:0}.sun-editor button{border:0;background-color:transparent;touch-action:manipulation;cursor:pointer;outline:none}.sun-editor button,.sun-editor input,.sun-editor select,.sun-editor textarea{vertical-align:middle}.sun-editor button span{display:block;margin:0;padding:0}.sun-editor button .txt{display:block;margin-top:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.sun-editor button *{pointer-events:none;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden}.sun-editor .se-svg,.sun-editor button>svg{width:16px;height:16px;margin:auto;fill:currentColor;display:block;text-align:center;float:none}.sun-editor .close>svg,.sun-editor .se-dialog-close>svg{width:10px;height:10px}.sun-editor .se-btn-select>svg{float:right;width:10px;height:10px}.sun-editor .se-btn-list>.se-list-icon{display:inline-block;width:16px;height:16px;margin:-1px 10px 0 0;vertical-align:middle}.sun-editor .se-line-breaker>button>svg{width:24px;height:24px}.sun-editor button>i:before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;font-size:15px;line-height:2}.sun-editor button>[class=se-icon-text]{font-size:20px;line-height:1}.sun-editor .se-arrow,.sun-editor .se-arrow:after{position:absolute;display:block;width:0;height:0;border:11px solid transparent}.sun-editor .se-arrow.se-arrow-up{top:-11px;left:20px;margin-left:-11px;border-top-width:0;border-bottom-color:rgba(0,0,0,.25)}.sun-editor .se-arrow.se-arrow-up:after{top:1px;margin-left:-11px;content:" ";border-top-width:0;border-bottom-color:#fff}.sun-editor .se-toolbar .se-arrow.se-arrow-up:after{border-bottom-color:#fafafa}.sun-editor .se-arrow.se-arrow-down{top:0;left:0;margin-left:-11px;border-bottom-width:0;border-top-color:rgba(0,0,0,.25)}.sun-editor .se-arrow.se-arrow-down:after{top:-12px;margin-left:-11px;content:" ";border-bottom-width:0;border-top-color:#fff}.sun-editor .se-toolbar .se-arrow.se-arrow-down:after{border-top-color:#fafafa}.sun-editor .se-container{position:relative;width:100%;height:100%}.sun-editor button{color:#000}.sun-editor .se-btn{float:left;width:34px;height:34px;border:0;border-radius:4px;margin:1px!important;padding:0;font-size:12px;line-height:27px}.sun-editor .se-btn:enabled:focus,.sun-editor .se-btn:enabled:hover{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-btn:enabled:active{background-color:#d1d1d1;border-color:#c1c1c1;-webkit-box-shadow:inset 0 3px 5px #c1c1c1;box-shadow:inset 0 3px 5px #c1c1c1}.sun-editor .se-btn-primary{color:#000;background-color:#c7deff;border:1px solid #80bdff;border-radius:4px}.sun-editor .se-btn-primary:focus,.sun-editor .se-btn-primary:hover{color:#000;background-color:#80bdff;border-color:#3f9dff;outline:0 none}.sun-editor .se-btn-primary:active{color:#fff;background-color:#3f9dff;border-color:#4592ff;-webkit-box-shadow:inset 0 3px 5px #4592ff;box-shadow:inset 0 3px 5px #4592ff}.sun-editor input,.sun-editor select,.sun-editor textarea{color:#000;border:1px solid #ccc;border-radius:4px}.sun-editor input:focus,.sun-editor select:focus,.sun-editor textarea:focus{border:1px solid #80bdff;outline:0;-webkit-box-shadow:0 0 0 .2rem #c7deff;box-shadow:0 0 0 .2rem #c7deff;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}.sun-editor .se-btn:enabled.active{color:#4592ff;outline:0 none}.sun-editor .se-btn:enabled.active:focus,.sun-editor .se-btn:enabled.active:hover{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-btn:enabled.active:active{background-color:#d1d1d1;border-color:#c1c1c1;-webkit-box-shadow:inset 0 3px 5px #c1c1c1;box-shadow:inset 0 3px 5px #c1c1c1}.sun-editor .se-btn:enabled.on{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-btn:enabled.on:focus,.sun-editor .se-btn:enabled.on:hover{background-color:#d1d1d1;border-color:#c1c1c1;outline:0 none}.sun-editor .se-btn:enabled.on:active{background-color:#c1c1c1;border-color:#b1b1b1;-webkit-box-shadow:inset 0 3px 5px #b1b1b1;box-shadow:inset 0 3px 5px #b1b1b1}.sun-editor .se-btn-list:disabled,.sun-editor .se-btn:disabled,.sun-editor button:disabled{cursor:not-allowed;background-color:inherit;color:#bdbdbd}.sun-editor .se-loading-box{position:absolute;display:none;width:100%;height:100%;top:0;left:0;background-color:#fff;opacity:.7;filter:alpha(opacity=70);z-index:2147483647}.sun-editor .se-loading-box .se-loading-effect{position:absolute;display:block;top:50%;left:50%;height:25px;width:25px;border-top:2px solid #07d;border-right:2px solid transparent;border-radius:50%;animation:spinner .8s linear infinite;margin:-25px 0 0 -25px}.sun-editor .se-line-breaker{position:absolute;display:none;width:100%;height:1px;cursor:text;border-top:1px solid #3288ff;z-index:7}.sun-editor .se-line-breaker>button.se-btn{position:relative;display:inline-block;width:30px;height:30px;top:-15px;float:none;left:-50%;background-color:#fff;border:1px solid #0c2240;opacity:.6;cursor:pointer}.sun-editor .se-line-breaker>button.se-btn:hover{opacity:.9;background-color:#fff;border-color:#041b39}.sun-editor .se-line-breaker-component{position:absolute;display:none;width:24px;height:24px;background-color:#fff;border:1px solid #0c2240;opacity:.6;border-radius:4px;cursor:pointer;z-index:7}.sun-editor .se-line-breaker-component:hover{opacity:.9}.sun-editor .se-toolbar{display:block;position:relative;height:auto;width:100%;overflow:visible;padding:4px 3px 0;margin:0;background-color:#fafafa;outline:1px solid #dadada;z-index:5}.sun-editor .se-toolbar-cover{position:absolute;display:none;font-size:36px;width:100%;height:100%;top:0;left:0;background-color:#fefefe;opacity:.5;filter:alpha(opacity=50);cursor:not-allowed;z-index:4}.sun-editor .se-toolbar-separator-vertical{display:inline-block;height:0;width:0;margin:1px;vertical-align:top}.sun-editor .se-toolbar.se-toolbar-balloon,.sun-editor .se-toolbar.se-toolbar-inline{display:none;position:absolute;z-index:2147483647;box-shadow:0 3px 9px rgba(0,0,0,.5);-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5)}.sun-editor .se-toolbar.se-toolbar-balloon{width:auto}.sun-editor .se-toolbar.se-toolbar-sticky{position:fixed;top:0}.sun-editor .se-toolbar-sticky-dummy{display:none;position:static;z-index:-1}.sun-editor .se-btn-module{display:inline-block}.sun-editor .se-btn-module-border{border:1px solid #dadada;border-radius:4px}.sun-editor .se-btn-module-enter{display:block;width:100%;height:1px;margin-bottom:5px;background-color:transparent}.sun-editor .se-toolbar-more-layer{margin:0 -3px;background-color:#f3f3f3}.sun-editor .se-toolbar-more-layer .se-more-layer{display:none;border-top:1px solid #dadada}.sun-editor .se-toolbar-more-layer .se-more-layer .se-more-form{display:inline-block;width:100%;height:auto;padding:4px 3px 0}.sun-editor .se-btn-module .se-btn-more.se-btn-more-text{width:auto;padding:0 4px}.sun-editor .se-btn-module .se-btn-more:focus,.sun-editor .se-btn-module .se-btn-more:hover{color:#000;background-color:#d1d1d1;border-color:#c1c1c1;outline:0 none}.sun-editor .se-btn-module .se-btn-more.on{color:#333;background-color:#d1d1d1;border-color:#c1c1c1;outline:0 none}.sun-editor .se-btn-module .se-btn-more.on:hover{color:#000;background-color:#c1c1c1;border-color:#b1b1b1;outline:0 none}.sun-editor .se-menu-list,.sun-editor .se-menu-list li{float:left;padding:0;margin:0}.sun-editor .se-menu-list li{position:relative}.sun-editor .se-btn-select{width:auto;display:flex;padding:4px 6px}.sun-editor .se-btn-select .txt{flex:auto;text-align:left}.sun-editor.se-rtl .se-btn-select svg{margin:auto 1px}.sun-editor .se-btn-select.se-btn-tool-font{width:100px}.sun-editor .se-btn-select.se-btn-tool-format{width:82px}.sun-editor .se-btn-select.se-btn-tool-size{width:78px}.sun-editor .se-btn-tray{position:relative;width:100%;height:100%;margin:0;padding:0}.sun-editor .se-menu-tray{position:absolute;top:0;left:0;width:100%;height:0}.sun-editor .se-submenu{overflow-x:hidden;overflow-y:auto}.sun-editor .se-list-layer{display:none;position:absolute;top:0;left:0;height:auto;z-index:5;border:1px solid #bababa;border-radius:4px;padding:6px 0;background-color:#fff;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);outline:0 none}.sun-editor .se-list-layer .se-list-inner{padding:0;margin:0;overflow-x:initial;overflow-y:initial;overflow:visible}.sun-editor .se-list-layer button{margin:0;width:100%}.sun-editor .se-list-inner .se-list-basic{width:100%;padding:0}.sun-editor .se-list-inner .se-list-basic li{width:100%}.sun-editor .se-list-inner .se-list-basic li>button{min-width:100%;width:max-content}.sun-editor .se-list-inner .se-list-basic li button.active{background-color:#80bdff;border:1px solid #3f9dff;border-left:0;border-right:0}.sun-editor .se-list-inner .se-list-basic li button.active:hover{background-color:#3f9dff;border:1px solid #4592ff;border-left:0;border-right:0}.sun-editor .se-list-inner .se-list-basic li button.active:active{background-color:#4592ff;border:1px solid #407dd1;border-left:0;border-right:0;-webkit-box-shadow:inset 0 3px 5px #407dd1;box-shadow:inset 0 3px 5px #407dd1}.sun-editor .se-btn-list{width:100%;height:auto;min-height:32px;padding:0 14px;cursor:pointer;font-size:12px;line-height:normal;text-indent:0;text-decoration:none;text-align:left}.sun-editor .se-btn-list.default_value{background-color:#f3f3f3;border-top:1px dotted #b1b1b1;border-bottom:1px dotted #b1b1b1}.sun-editor .se-btn-list:focus,.sun-editor .se-btn-list:hover{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-btn-list:active{background-color:#d1d1d1;border-color:#c1c1c1;-webkit-box-shadow:inset 0 3px 5px #c1c1c1;box-shadow:inset 0 3px 5px #c1c1c1}.sun-editor .se-list-layer.se-list-font-size{min-width:140px;max-height:300px}.sun-editor .se-list-layer.se-list-font-family{min-width:156px}.sun-editor .se-list-layer.se-list-font-family .default{border-bottom:1px solid #ccc}.sun-editor .se-list-layer.se-list-line{width:125px}.sun-editor .se-list-layer.se-list-align .se-list-inner{left:9px;width:125px}.sun-editor .se-list-layer.se-list-format{min-width:156px}.sun-editor .se-list-layer.se-list-format li{padding:0;width:100%}.sun-editor .se-list-layer.se-list-format ul .se-btn-list{line-height:100%}.sun-editor .se-list-layer.se-list-format ul .se-btn-list[data-value=h1]{height:40px}.sun-editor .se-list-layer.se-list-format ul .se-btn-list[data-value=h2]{height:34px}.sun-editor .se-list-layer.se-list-format ul p{font-size:13px}.sun-editor .se-list-layer.se-list-format ul div{font-size:13px;padding:4px 2px}.sun-editor .se-list-layer.se-list-format ul h1{font-size:2em;font-weight:700;color:#333}.sun-editor .se-list-layer.se-list-format ul h2{font-size:1.5em;font-weight:700;color:#333}.sun-editor .se-list-layer.se-list-format ul h3{font-size:1.17em;font-weight:700;color:#333}.sun-editor .se-list-layer.se-list-format ul h4{font-size:1em;font-weight:700;color:#333}.sun-editor .se-list-layer.se-list-format ul h5{font-size:.83em;font-weight:700;color:#333}.sun-editor .se-list-layer.se-list-format ul h6{font-size:.67em;font-weight:700;color:#333}.sun-editor .se-list-layer.se-list-format ul blockquote{font-size:13px;color:#999;height:22px;margin:0;background-color:transparent;line-height:1.5;border-color:#b1b1b1;padding:0 0 0 7px;border-left:5px #b1b1b1;border-style:solid}.sun-editor .se-list-layer.se-list-format ul pre{font-size:13px;color:#666;padding:4px 11px;margin:0;background-color:#f9f9f9;border:1px solid #e1e1e1;border-radius:4px}.sun-editor .se-selector-table{display:none;position:absolute;top:34px;left:1px;z-index:5;padding:5px 0;float:left;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.sun-editor .se-selector-table .se-table-size{font-size:18px;padding:0 5px}.sun-editor .se-selector-table .se-table-size-picker{position:absolute!important;z-index:3;font-size:18px;width:10em;height:10em;cursor:pointer}.sun-editor .se-selector-table .se-table-size-highlighted{position:absolute!important;z-index:2;font-size:18px;width:1em;height:1em;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAADJmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4QTZCNzMzN0I3RUYxMUU4ODcwQ0QwMjM1NTgzRTJDNyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo4QTZCNzMzNkI3RUYxMUU4ODcwQ0QwMjM1NTgzRTJDNyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0MzYyNEUxRUI3RUUxMUU4ODZGQzgwRjNBODgyNTdFOSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0MzYyNEUxRkI3RUUxMUU4ODZGQzgwRjNBODgyNTdFOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pl0yAuwAAABBSURBVDhPY/wPBAxUAGCDGvdBeWSAeicIDTfIXREiQArYeR9hEBOEohyMGkQYjBpEGAxjg6ib+yFMygCVvMbAAABj0hwMTNeKJwAAAABJRU5ErkJggg==") repeat}.sun-editor .se-selector-table .se-table-size-unhighlighted{position:relative!important;z-index:1;font-size:18px;width:10em;height:10em;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIj4+Pjp6ekKlAqjAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKhmnaJzPAAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC") repeat}.sun-editor .se-selector-table .se-table-size-display{padding-left:5px}.sun-editor .se-list-layer .se-selector-color{display:flex;width:max-content;max-width:270px;height:auto;padding:0;margin:auto}.sun-editor .se-list-layer .se-selector-color .se-color-pallet{width:100%;height:100%;padding:0}.sun-editor .se-list-layer .se-selector-color .se-color-pallet li{display:flex;float:left;position:relative;margin:0}.sun-editor .se-list-layer .se-selector-color .se-color-pallet button{display:block;cursor:default;width:30px;height:30px;text-indent:-9999px}.sun-editor .se-list-layer .se-selector-color .se-color-pallet button.active,.sun-editor .se-list-layer .se-selector-color .se-color-pallet button:focus,.sun-editor .se-list-layer .se-selector-color .se-color-pallet button:hover{border:3px solid #fff}.sun-editor .se-submenu-form-group{display:flex;width:100%;min-height:40px;height:auto;padding:4px}.sun-editor .se-submenu-form-group input{flex:auto;display:inline-block;width:auto;height:33px;color:#555;font-size:12px;margin:1px 0;padding:0;border-radius:.25rem;border:1px solid #ccc}.sun-editor .se-submenu-form-group button{float:right;width:34px;height:34px;margin:0 2px!important}.sun-editor .se-submenu-form-group button.se-btn{border:1px solid #ccc}.sun-editor .se-submenu-form-group>div{position:relative}.sun-editor .se-submenu-form-group .se-color-input{width:72px;text-transform:uppercase;border:none;border-bottom:2px solid #b1b1b1;outline:none}.sun-editor .se-submenu-form-group .se-color-input:focus{border-bottom:3px solid #b1b1b1}.sun-editor .se-wrapper{position:relative!important;width:100%;height:auto;overflow:hidden;z-index:1}.sun-editor .se-wrapper .se-wrapper-inner{width:100%;height:100%;min-height:65px;overflow-y:auto;overflow-x:auto;-webkit-overflow-scrolling:touch;user-select:text;-o-user-select:text;-moz-user-select:text;-khtml-user-select:text;-webkit-user-select:text;-ms-user-select:text}.sun-editor .se-wrapper .se-wrapper-inner:focus{outline:none}.sun-editor .se-wrapper .se-wrapper-code{background-color:#191919;color:#fff;font-size:13px;word-break:break-all;padding:4px;margin:0;resize:none!important}.sun-editor .se-wrapper .se-wrapper-wysiwyg{background-color:#fff;display:block}.sun-editor .se-wrapper .se-wrapper-code-mirror{font-size:13px}.sun-editor .se-wrapper .se-placeholder{position:absolute;display:none;white-space:nowrap;text-overflow:ellipsis;z-index:1;color:#b1b1b1;font-size:13px;line-height:1.5;top:0;left:0;right:0;overflow:hidden;margin-top:0;padding-top:16px;padding-left:16px;margin-left:0;padding-right:16px;margin-right:0;pointer-events:none;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden}.sun-editor .se-resizing-bar{display:flex;width:auto;height:auto;min-height:16px;border-top:1px solid #dadada;padding:0 4px;background-color:#fafafa;cursor:ns-resize}.sun-editor .se-resizing-bar.se-resizing-none{cursor:default}.sun-editor .se-resizing-back{position:absolute;display:none;cursor:default;top:0;left:0;width:100%;height:100%;z-index:2147483647}.sun-editor .se-resizing-bar .se-navigation{flex:auto;position:relative;width:auto;height:auto;color:#666;margin:0;padding:0;font-size:10px;font-weight:700;line-height:1.5;background:transparent}.sun-editor .se-resizing-bar .se-char-counter-wrapper{flex:none;position:relative;display:block;width:auto;height:auto;margin:0;padding:0;color:#999;font-size:13px;background:transparent}.sun-editor .se-resizing-bar .se-char-counter-wrapper.se-blink{color:#b94a48;animation:blinker .2s linear infinite}.sun-editor .se-resizing-bar .se-char-counter-wrapper .se-char-label{margin-right:4px}.sun-editor .se-dialog{position:absolute;display:none;top:0;left:0;width:100%;height:100%;z-index:2147483647}.sun-editor .se-dialog button,.sun-editor .se-dialog input,.sun-editor .se-dialog label{font-size:14px;line-height:1.5;color:#111;margin:0}.sun-editor .se-dialog .se-dialog-back{background-color:#222;opacity:.5}.sun-editor .se-dialog .se-dialog-back,.sun-editor .se-dialog .se-dialog-inner{position:absolute;width:100%;height:100%;top:0;left:0}.sun-editor .se-dialog .se-dialog-inner .se-dialog-content{position:relative;width:auto;max-width:500px;margin:20px auto;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:4px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}@media screen and (max-width:509px){.sun-editor .se-dialog .se-dialog-inner .se-dialog-content{width:100%}}.sun-editor .se-dialog .se-dialog-inner .se-dialog-content label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}.sun-editor .se-dialog .se-dialog-inner .se-dialog-content .se-btn-primary{display:inline-block;padding:6px 12px;margin:0 0 10px!important;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;border-radius:4px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-header{height:50px;padding:6px 15px;border-bottom:1px solid #e5e5e5}.sun-editor .se-dialog .se-dialog-inner .se-dialog-header .se-dialog-close{float:right;font-weight:700;text-shadow:0 1px 0 #fff;-webkit-appearance:none;filter:alpha(opacity=100);opacity:1}.sun-editor .se-dialog .se-dialog-inner .se-dialog-header .se-modal-title{float:left;font-size:14px;font-weight:700;margin:0;padding:0;line-height:2.5}.sun-editor .se-dialog .se-dialog-inner .se-dialog-body{position:relative;padding:15px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form{margin-bottom:10px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form-footer{margin-top:10px;margin-bottom:0}.sun-editor .se-dialog .se-dialog-inner input:disabled{background-color:#f3f3f3}.sun-editor .se-dialog .se-dialog-inner .se-dialog-size-text{width:100%}.sun-editor .se-dialog .se-dialog-inner .se-dialog-size-text .size-h,.sun-editor .se-dialog .se-dialog-inner .se-dialog-size-text .size-w{width:70px;text-align:center}.sun-editor .se-dialog .se-dialog-inner .se-dialog-size-x{margin:0 8px;width:25px;text-align:center}.sun-editor .se-dialog .se-dialog-inner .se-dialog-footer{height:55px;padding:10px 15px 0;text-align:right;border-top:1px solid #e5e5e5}.sun-editor .se-dialog .se-dialog-inner .se-dialog-footer>div{float:left}.sun-editor .se-dialog .se-dialog-inner .se-dialog-footer>div>label{margin:0 5px 0 0}.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-radio{margin-left:12px;margin-right:6px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-check{margin-left:12px;margin-right:4px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form-footer .se-dialog-btn-check{margin-left:0;margin-right:4px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files{position:relative;display:flex;align-items:center}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files>input{flex:auto}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files .se-dialog-files-edge-button{flex:auto;opacity:.8;border:1px solid #ccc}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files .se-dialog-files-edge-button.se-file-remove>svg{width:8px;height:8px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files .se-dialog-files-edge-button:hover{background-color:#f0f0f0;outline:0 none}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files .se-dialog-files-edge-button:active{background-color:#e9e9e9;-webkit-box-shadow:inset 0 3px 5px #d6d6d6;box-shadow:inset 0 3px 5px #d6d6d6}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-select{display:inline-block;width:auto;height:34px;font-size:14px;text-align:center;line-height:1.42857143}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-control{display:inline-block;width:70px;height:34px;font-size:14px;text-align:center;line-height:1.42857143}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-form{display:block;width:100%;height:34px;font-size:14px;line-height:1.42857143;padding:0 4px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-form.se-input-url{direction:ltr}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-form.se-input-url:disabled{text-decoration:line-through;color:#999}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-video-ratio{width:70px;margin-left:4px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form a{color:#004cff}.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-revert{border:1px solid #ccc}.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-revert:hover{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-revert:active{background-color:#d1d1d1;border-color:#c1c1c1;-webkit-box-shadow:inset 0 3px 5px #c1c1c1;box-shadow:inset 0 3px 5px #c1c1c1}.sun-editor .se-dialog-tabs{width:100%;height:25px;border-bottom:1px solid #e5e5e5}.sun-editor .se-dialog-tabs button{background-color:#e5e5e5;border-right:1px solid #e5e5e5;float:left;outline:none;padding:2px 13px;transition:.3s}.sun-editor .se-dialog-tabs button:hover{background-color:#fff}.sun-editor .se-dialog-tabs button.active{background-color:#fff;border-bottom:0}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-form.se-math-exp{resize:vertical;height:4rem;border:1px solid #ccc;font-size:13px;padding:4px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-select.se-math-size{width:6em;height:28px;margin-left:1em}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-math-preview{font-size:13px}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-math-preview>span{display:inline-block;-webkit-box-shadow:0 0 0 .1rem #c7deff;box-shadow:0 0 0 .1rem #c7deff}.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-link-preview{display:block;height:auto;max-height:18px;margin:4px 0 0 4px;font-size:13px;font-weight:400;font-family:inherit;color:#666;background-color:transparent;overflow:hidden;text-overflow:ellipsis;word-break:break-all;white-space:pre}.sun-editor .se-controller .se-arrow.se-arrow-up{border-bottom-color:rgba(0,0,0,.25)}.sun-editor .se-controller{position:absolute;display:none;overflow:visible;z-index:6;border:1px solid rgba(0,0,0,.25);border-radius:4px;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.sun-editor .se-controller .se-btn-group{position:relative;display:flex;vertical-align:middle;padding:2px;top:0;left:0}.sun-editor .se-controller .se-btn-group .se-btn-group-sub{left:50%;min-width:auto;width:max-content;display:none}.sun-editor .se-controller .se-btn-group .se-btn-group-sub button{margin:0;min-width:72px}.sun-editor .se-controller .se-btn-group button{position:relative;min-height:34px;height:auto;border:none;border-radius:4px;margin:1px;padding:5px 10px;font-size:12px;line-height:1.5;display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation}.sun-editor .se-controller .se-btn-group button:focus:enabled,.sun-editor .se-controller .se-btn-group button:hover:enabled{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-controller .se-btn-group button:active:enabled{background-color:#d1d1d1;border-color:#c1c1c1;-webkit-box-shadow:inset 0 3px 5px #c1c1c1;box-shadow:inset 0 3px 5px #c1c1c1}.sun-editor .se-controller .se-btn-group button span{display:block;padding:0;margin:0}.sun-editor .se-controller .se-btn-group button:enabled.active{color:#4592ff;outline:0 none}.sun-editor .se-controller .se-btn-group button:enabled.active:focus,.sun-editor .se-controller .se-btn-group button:enabled.active:hover{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-controller .se-btn-group button:enabled.active:active{background-color:#d1d1d1;border-color:#c1c1c1;-webkit-box-shadow:inset 0 3px 5px #c1c1c1;box-shadow:inset 0 3px 5px #c1c1c1}.sun-editor .se-controller .se-btn-group button:enabled.on{background-color:#e1e1e1;border-color:#d1d1d1;outline:0 none}.sun-editor .se-controller .se-btn-group button:enabled.on:focus,.sun-editor .se-controller .se-btn-group button:enabled.on:hover{background-color:#d1d1d1;border-color:#c1c1c1;outline:0 none}.sun-editor .se-controller .se-btn-group button:enabled.on:active{background-color:#c1c1c1;border-color:#b1b1b1;-webkit-box-shadow:inset 0 3px 5px #b1b1b1;box-shadow:inset 0 3px 5px #b1b1b1}.sun-editor .se-controller-resizing{margin-top:-50px!important;padding:0;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143}.sun-editor .se-controller-resizing .se-btn-group .se-btn-group-sub.se-resizing-align-list{width:74px}.sun-editor .se-resizing-container{position:absolute;display:none;outline:1px solid #3f9dff;background-color:transparent}.sun-editor .se-resizing-container .se-modal-resize{position:absolute;display:inline-block;background-color:#3f9dff;opacity:.3}.sun-editor .se-resizing-container .se-resize-dot{position:absolute;top:0;left:0;width:100%;height:100%}.sun-editor .se-resizing-container .se-resize-dot>span{position:absolute;width:7px;height:7px;background-color:#3f9dff;border:1px solid #4592ff}.sun-editor .se-resizing-container .se-resize-dot>span.tl{top:-5px;left:-5px;cursor:nw-resize}.sun-editor .se-resizing-container .se-resize-dot>span.tr{top:-5px;right:-5px;cursor:ne-resize}.sun-editor .se-resizing-container .se-resize-dot>span.bl{bottom:-5px;left:-5px;cursor:sw-resize}.sun-editor .se-resizing-container .se-resize-dot>span.br{right:-5px;bottom:-5px;cursor:se-resize}.sun-editor .se-resizing-container .se-resize-dot>span.lw{left:-7px;bottom:50%;cursor:w-resize}.sun-editor .se-resizing-container .se-resize-dot>span.th{left:50%;top:-7px;cursor:n-resize}.sun-editor .se-resizing-container .se-resize-dot>span.rw{right:-7px;bottom:50%;cursor:e-resize}.sun-editor .se-resizing-container .se-resize-dot>span.bh{right:50%;bottom:-7px;cursor:s-resize}.sun-editor .se-resizing-container .se-resize-display{position:absolute;right:0;bottom:0;padding:5px;margin:5px;font-size:12px;color:#fff;background-color:#333;border-radius:4px}.sun-editor .se-controller-table,.sun-editor .se-controller-table-cell{width:auto}.sun-editor .se-controller-link,.sun-editor .se-controller-table,.sun-editor .se-controller-table-cell{padding:0;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143}.sun-editor .se-controller-link:after,.sun-editor .se-controller-link:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.sun-editor .se-controller-link .link-content{padding:0;margin:0}.sun-editor .se-controller-link .link-content a{display:inline-block;color:#4592ff;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;margin-left:5px}.sun-editor .se-file-browser{position:absolute;display:none;top:0;left:0;width:100%;height:100%;z-index:2147483647}.sun-editor .se-file-browser button,.sun-editor .se-file-browser input,.sun-editor .se-file-browser label{font-size:14px;line-height:1.5;color:#111;margin:0}.sun-editor .se-file-browser .se-file-browser-back{background-color:#222;opacity:.5}.sun-editor .se-file-browser .se-file-browser-back,.sun-editor .se-file-browser .se-file-browser-inner{position:absolute;display:block;width:100%;height:100%;top:0;left:0}.sun-editor .se-file-browser .se-file-browser-inner .se-file-browser-content{position:relative;width:960px;max-width:100%;margin:20px auto;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:4px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.sun-editor .se-file-browser .se-file-browser-header{height:auto;min-height:50px;padding:6px 15px;border-bottom:1px solid #e5e5e5}.sun-editor .se-file-browser .se-file-browser-header .se-file-browser-close{float:right;font-weight:700;text-shadow:0 1px 0 #fff;-webkit-appearance:none;filter:alpha(opacity=100);opacity:1}.sun-editor .se-file-browser .se-file-browser-header .se-file-browser-close>svg{width:12px;height:12px}.sun-editor .se-file-browser .se-file-browser-header .se-file-browser-title{font-size:16px;font-weight:700;margin:0;padding:0;line-height:2.2}.sun-editor .se-file-browser .se-file-browser-tags{display:block;width:100%;padding:0;text-align:left;margin:0 -15px}.sun-editor .se-file-browser .se-file-browser-tags a{display:inline-block;background-color:#f5f5f5;padding:6px 12px;margin:8px 0 8px 8px;color:#333;text-decoration:none;border-radius:32px;-moz-border-radius:32px;-webkit-border-radius:32px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;cursor:pointer}.sun-editor .se-file-browser .se-file-browser-tags a:hover{background-color:#e1e1e1}.sun-editor .se-file-browser .se-file-browser-tags a:active{background-color:#d1d1d1}.sun-editor .se-file-browser .se-file-browser-tags a.on{background-color:#ebf3fe;color:#4592ff}.sun-editor .se-file-browser .se-file-browser-tags a.on:hover{background-color:#d8e8fe}.sun-editor .se-file-browser .se-file-browser-tags a.on:active{background-color:#c7deff}.sun-editor .se-file-browser .se-file-browser-body{position:relative;height:auto;min-height:350px;padding:20px;overflow-y:auto}.sun-editor .se-file-browser .se-file-browser-body .se-file-browser-list{position:relative;width:100%}@media screen and (max-width:992px){.sun-editor .se-file-browser .se-file-browser-inner .se-file-browser-content{width:748px}}@media screen and (max-width:768px){.sun-editor .se-file-browser .se-file-browser-inner .se-file-browser-content{width:600px}}.sun-editor .se-file-browser .se-file-browser-list .se-file-item-column{position:relative;display:block;height:auto;float:left}.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-column{width:calc(25% - 20px);margin:0 10px}@media screen and (max-width:992px){.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-column{width:calc(33% - 20px)}}@media screen and (max-width:768px){.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-column{width:calc(50% - 20px)}}.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img{position:relative;display:block;cursor:pointer;width:100%;height:auto;border-radius:4px;outline:0;margin:10px 0}.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img:hover{opacity:.8;-webkit-box-shadow:0 0 0 .2rem #3288ff;box-shadow:0 0 0 .2rem #3288ff}.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img>img{position:relative;display:block;width:100%;border-radius:4px;outline:0;height:auto}.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img>.se-file-img-name{position:absolute;z-index:1;font-size:13px;color:#fff;left:0;bottom:0;padding:5px 10px;background-color:transparent;width:100%;height:30px;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img>.se-file-img-name.se-file-name-back{background-color:#333;opacity:.6}.sun-editor .se-notice{position:absolute;top:0;display:none;z-index:7;width:100%;height:auto;word-break:break-all;font-size:13px;color:#b94a48;background-color:#f2dede;padding:15px;margin:0;border:1px solid #eed3d7;user-select:text;-o-user-select:text;-moz-user-select:text;-khtml-user-select:text;-webkit-user-select:text;-ms-user-select:text}.sun-editor .se-notice button{float:right;padding:7px}.sun-editor .se-tooltip{position:relative;overflow:visible}.sun-editor .se-tooltip .se-tooltip-inner{visibility:hidden;position:absolute;display:block;width:auto;top:120%;left:50%;background:transparent;opacity:0;z-index:1;line-height:1.5;transition:opacity .5s;margin:0;padding:0;bottom:auto;float:none;pointer-events:none;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden}.sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text{position:relative;display:inline-block;width:auto;left:-50%;font-size:.9em;margin:0;padding:4px 6px;border-radius:2px;background-color:#333;color:#fff;text-align:center;line-height:unset;white-space:nowrap;cursor:auto}.sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text:after{content:"";position:absolute;bottom:100%;left:50%;margin-left:-5px;border:5px solid transparent;border-bottom-color:#333}.sun-editor .se-tooltip:hover .se-tooltip-inner{visibility:visible;opacity:1}.sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text .se-shortcut{display:block!important}.sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text .se-shortcut>.se-shortcut-key{display:inline;font-weight:700}.sun-editor.se-rtl .se-btn-tray{direction:rtl}.sun-editor.se-rtl .se-btn-select .txt{flex:auto;text-align:right;direction:rtl}.sun-editor.se-rtl .se-btn-list{text-align:right}.sun-editor.se-rtl .se-btn-list>.se-list-icon{margin:-1px 0 0 10px}.sun-editor.se-rtl .se-menu-list,.sun-editor.se-rtl .se-menu-list li{float:right}.sun-editor.se-rtl .se-list-layer *{direction:rtl}.sun-editor.se-rtl .se-list-layer.se-list-format ul blockquote{padding:0 7px 0 0;border-right-width:5px;border-left-width:0}.sun-editor.se-rtl .se-list-layer .se-selector-color .se-color-pallet li{float:right}.sun-editor.se-rtl .se-tooltip .se-tooltip-inner .se-tooltip-text,.sun-editor.se-rtl .se-wrapper .se-placeholder{direction:rtl}.sun-editor.se-rtl .se-tooltip .se-tooltip-inner .se-tooltip-text .se-shortcut{direction:ltr}.sun-editor.se-rtl .se-dialog *{direction:rtl}.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-header .se-dialog-close{float:left}.sun-editor.se-rtl .se-dialog-tabs button,.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-header .se-modal-title{float:right}.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-size-text{padding-right:34px}.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-content .se-btn-primary{float:left}.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-footer>div{float:right}.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-footer>div>label{margin:0 0 0 5px}.sun-editor.se-rtl .se-file-browser *{direction:rtl}.sun-editor.se-rtl .se-file-browser .se-file-browser-tags{text-align:right}.sun-editor.se-rtl .se-file-browser .se-file-browser-tags a{margin:8px 8px 0}.sun-editor.se-rtl .se-file-browser .se-file-browser-header .se-file-browser-close{float:left}.sun-editor.se-rtl .se-controller .se-btn-group{direction:rtl}@keyframes blinker{50%{opacity:0}}@keyframes spinner{to{transform:rotate(361deg)}}.sun-editor-editable{font-family:Helvetica Neue,sans-serif;font-size:13px;color:#333;line-height:1.5;background-color:#fff;word-break:normal;word-wrap:break-word;padding:16px;margin:0}.sun-editor-editable *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;font-family:inherit;font-size:inherit;color:inherit}.sun-editor-editable.se-rtl *{direction:rtl}.sun-editor-editable audio,.sun-editor-editable figcaption,.sun-editor-editable figure,.sun-editor-editable iframe,.sun-editor-editable img,.sun-editor-editable td,.sun-editor-editable th,.sun-editor-editable video{position:relative}.sun-editor-editable .__se__float-left{float:left}.sun-editor-editable .__se__float-right{float:right}.sun-editor-editable .__se__float-center{float:center}.sun-editor-editable .__se__float-none{float:none}.sun-editor-editable span{display:inline;vertical-align:baseline;margin:0;padding:0}.sun-editor-editable span.katex{display:inline-block}.sun-editor-editable a{color:#004cff;text-decoration:none}.sun-editor-editable span[style~="color:"] a{color:inherit}.sun-editor-editable a:focus,.sun-editor-editable a:hover{cursor:pointer;color:#0093ff;text-decoration:underline}.sun-editor-editable pre{display:block;padding:8px;margin:0 0 10px;font-family:monospace;color:#666;line-height:1.45;background-color:#f9f9f9;border:1px solid #e1e1e1;border-radius:2px;white-space:pre-wrap;word-wrap:break-word;overflow:visible}.sun-editor-editable ol{list-style-type:decimal}.sun-editor-editable ol,.sun-editor-editable ul{list-style-position:inside;display:block;margin-block-start:1em;margin-block-end:1em;margin-inline-start:0;margin-inline-end:0;padding-inline-start:40px}.sun-editor-editable ul{list-style-type:disc}.sun-editor-editable li{display:list-item;text-align:-webkit-match-parent;margin-bottom:5px}.sun-editor-editable ol ol,.sun-editor-editable ol ul,.sun-editor-editable ul ol,.sun-editor-editable ul ul{margin:0}.sun-editor-editable ol ol,.sun-editor-editable ul ol{list-style-type:lower-alpha}.sun-editor-editable ol ol ol,.sun-editor-editable ul ol ol,.sun-editor-editable ul ul ol{list-style-type:upper-roman}.sun-editor-editable ol ul,.sun-editor-editable ul ul{list-style-type:circle}.sun-editor-editable ol ol ul,.sun-editor-editable ol ul ul,.sun-editor-editable ul ul ul{list-style-type:square}.sun-editor-editable sub,.sun-editor-editable sup{font-size:75%;line-height:0}.sun-editor-editable sub{vertical-align:sub}.sun-editor-editable sup{vertical-align:super}.sun-editor-editable p{display:block;margin:0 0 10px}.sun-editor-editable div{display:block;margin:0;padding:0}.sun-editor-editable blockquote{display:block;font-family:inherit;font-size:inherit;color:#999;margin-block-start:1em;margin-block-end:1em;margin-inline-start:0;margin-inline-end:0;padding:0 5px 0 20px;border:solid #b1b1b1;border-width:0 0 0 5px}.sun-editor-editable blockquote blockquote{border-color:#c1c1c1}.sun-editor-editable blockquote blockquote blockquote{border-color:#d1d1d1}.sun-editor-editable blockquote blockquote blockquote blockquote{border-color:#e1e1e1}.sun-editor-editable.se-rtl blockquote{padding-left:5px;padding-right:20px;border-left-width:0;border-right-width:5px}.sun-editor-editable h1{font-size:2em;margin-block-start:.67em;margin-block-end:.67em}.sun-editor-editable h1,.sun-editor-editable h2{display:block;margin-inline-start:0;margin-inline-end:0;font-weight:700}.sun-editor-editable h2{font-size:1.5em;margin-block-start:.83em;margin-block-end:.83em}.sun-editor-editable h3{font-size:1.17em;margin-block-start:1em;margin-block-end:1em}.sun-editor-editable h3,.sun-editor-editable h4{display:block;margin-inline-start:0;margin-inline-end:0;font-weight:700}.sun-editor-editable h4{font-size:1em;margin-block-start:1.33em;margin-block-end:1.33em}.sun-editor-editable h5{font-size:.83em;margin-block-start:1.67em;margin-block-end:1.67em}.sun-editor-editable h5,.sun-editor-editable h6{display:block;margin-inline-start:0;margin-inline-end:0;font-weight:700}.sun-editor-editable h6{font-size:.67em;margin-block-start:2.33em;margin-block-end:2.33em}.sun-editor-editable hr{display:flex;border-width:1px 0 0;border-color:#000;border-image:initial;height:1px}.sun-editor-editable hr.__se__solid{border-style:solid none none}.sun-editor-editable hr.__se__dotted{border-style:dotted none none}.sun-editor-editable hr.__se__dashed{border-style:dashed none none}.sun-editor-editable table{display:table;table-layout:auto;border:1px solid #ccc;width:100%;max-width:100%;margin:0 0 10px;background-color:transparent;border-spacing:0;border-collapse:collapse}.sun-editor-editable.se-rtl table{margin:0 0 10px auto}.sun-editor-editable table thead{border-bottom:2px solid #333}.sun-editor-editable table tr{border:1px solid #efefef}.sun-editor-editable table th{background-color:#f3f3f3}.sun-editor-editable table td,.sun-editor-editable table th{border:1px solid #e1e1e1;padding:.4em;background-clip:padding-box}.sun-editor-editable table.se-table-size-auto{width:auto!important}.sun-editor-editable table.se-table-size-100{width:100%!important}.sun-editor-editable table.se-table-layout-auto{table-layout:auto!important}.sun-editor-editable table.se-table-layout-fixed{table-layout:fixed!important}.sun-editor-editable table td.se-table-selected-cell,.sun-editor-editable table th.se-table-selected-cell{border:1px double #4592ff;background-color:#f1f7ff}.sun-editor-editable.se-disabled *{user-select:none;-o-user-select:none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none}.sun-editor-editable .se-component{display:flex;padding:1px;margin:0 0 10px}.sun-editor-editable .se-component.__se__float-left{margin:0 20px 10px 0}.sun-editor-editable .se-component.__se__float-right{margin:0 0 10px 20px}.sun-editor-editable[contenteditable=true] .se-component{outline:1px dashed #e1e1e1}.sun-editor-editable[contenteditable=true] .se-component.se-component-copy{-webkit-box-shadow:0 0 0 .2rem #80bdff;box-shadow:0 0 0 .2rem #3f9dff;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}.sun-editor-editable audio,.sun-editor-editable iframe,.sun-editor-editable img,.sun-editor-editable video{display:block;margin:0;padding:0;width:auto;height:auto;max-width:100%}.sun-editor-editable[contenteditable=true] figure:after{position:absolute;content:"";z-index:1;top:0;left:0;right:0;bottom:0;cursor:default;display:block;background:transparent}.sun-editor-editable[contenteditable=true] figure a,.sun-editor-editable[contenteditable=true] figure iframe,.sun-editor-editable[contenteditable=true] figure img,.sun-editor-editable[contenteditable=true] figure video{z-index:0}.sun-editor-editable[contenteditable=true] figure figcaption{display:block;z-index:2}.sun-editor-editable[contenteditable=true] figure figcaption:focus{border-color:#80bdff;outline:0;-webkit-box-shadow:0 0 0 .2rem #c7deff;box-shadow:0 0 0 .2rem #c7deff}.sun-editor-editable .se-image-container,.sun-editor-editable .se-video-container{width:auto;height:auto;max-width:100%}.sun-editor-editable figure{display:block;outline:none;margin:0;padding:0}.sun-editor-editable figure figcaption{padding:1em .5em;margin:0;background-color:#f9f9f9;outline:none}.sun-editor-editable figure figcaption p{line-height:2;margin:0}.sun-editor-editable .se-image-container a img{padding:1px;margin:1px;outline:1px solid #4592ff}.sun-editor-editable .se-video-container iframe,.sun-editor-editable .se-video-container video{outline:1px solid #9e9e9e;position:absolute;top:0;left:0;border:0;width:100%;height:100%}.sun-editor-editable .se-video-container figure{left:0;width:100%;max-width:100%}.sun-editor-editable audio{width:300px;height:54px}.sun-editor-editable audio.active{outline:2px solid #80bdff}.sun-editor-editable.se-show-block div,.sun-editor-editable.se-show-block h1,.sun-editor-editable.se-show-block h2,.sun-editor-editable.se-show-block h3,.sun-editor-editable.se-show-block h4,.sun-editor-editable.se-show-block h5,.sun-editor-editable.se-show-block h6,.sun-editor-editable.se-show-block li,.sun-editor-editable.se-show-block ol,.sun-editor-editable.se-show-block p,.sun-editor-editable.se-show-block pre,.sun-editor-editable.se-show-block ul{border:1px dashed #3f9dff!important;padding:14px 8px 8px!important}.sun-editor-editable.se-show-block ol,.sun-editor-editable.se-show-block ul{border:1px dashed #d539ff!important}.sun-editor-editable.se-show-block pre{border:1px dashed #27c022!important}.se-show-block p{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAPAQMAAAAF7dc0AAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAaSURBVAjXY/j/gwGCPvxg+F4BQiAGDP1HQQByxxw0gqOzIwAAAABJRU5ErkJggg==") no-repeat}.se-show-block div{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAPAQMAAAAxlBYoAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAmSURBVAjXY/j//wcDDH+8XsHwDYi/hwNx1A8w/nYLKH4XoQYJAwCXnSgcl2MOPgAAAABJRU5ErkJggg==") no-repeat}.se-show-block h1{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAfSURBVAjXY/j/v4EBhr+9B+LzEPrDeygfhI8j1CBhAEhmJGY4Rf6uAAAAAElFTkSuQmCC") no-repeat}.se-show-block h2{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAmSURBVAjXY/j/v4EBhr+dB+LtQPy9geEDEH97D8T3gbgdoQYJAwA51iPuD2haEAAAAABJRU5ErkJggg==") no-repeat}.se-show-block h3{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAiSURBVAjXY/j/v4EBhr+dB+LtQPy9geHDeQgN5p9HqEHCADeWI+69VG2MAAAAAElFTkSuQmCC") no-repeat}.se-show-block h4{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAPAQMAAADTSA1RAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAiSURBVAjXY/j//wADDH97DsTXIfjDdiDdDMTfIRhZHRQDAKJOJ6L+K3y7AAAAAElFTkSuQmCC") no-repeat}.se-show-block h5{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAlSURBVAjXY/j/v4EBhr+1A/F+IO5vYPiwHUh/B2IQfR6hBgkDABlWIy5uM+9GAAAAAElFTkSuQmCC") no-repeat}.se-show-block h6{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAiSURBVAjXY/j/v4EBhr+dB+LtQLy/geFDP5S9HSKOrA6KAR9GIza1ptJnAAAAAElFTkSuQmCC") no-repeat}.se-show-block li{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA7SURBVDhPYxgFcNDQ0PAfykQBIHEYhgoRB/BpwCfHBKWpBkaggYxQGgOgBzyQD1aLLA4TGwWDGjAwAACR3RcEU9Ui+wAAAABJRU5ErkJggg==") no-repeat}.se-show-block ol{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABHSURBVDhPYxgFcNDQ0PAfhKFcFIBLHCdA1oBNM0kGEmMAPgOZoDTVANUNxAqQvURMECADRiiNAWCagDSGGhyW4DRrMAEGBgAu0SX6WpGgjAAAAABJRU5ErkJggg==") no-repeat}.se-show-block ul{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA1SURBVDhPYxgFDA0NDf+hTBSALI5LDQgwQWmqgVEDKQcsUBoF4ItFGEBXA+QzQpmDGjAwAAA8DQ4Lni6gdAAAAABJRU5ErkJggg==") no-repeat}.sun-editor-editable .__se__p-bordered,.sun-editor .__se__p-bordered{border-top:1px solid #b1b1b1;border-bottom:1px solid #b1b1b1;padding:4px 0}.sun-editor-editable .__se__p-spaced,.sun-editor .__se__p-spaced{letter-spacing:1px}.sun-editor-editable .__se__p-neon,.sun-editor .__se__p-neon{font-weight:200;font-style:italic;background:#000;color:#fff;padding:6px 4px;border:2px solid #fff;border-radius:6px;text-transform:uppercase;animation:neonFlicker 1.5s infinite alternate}@keyframes neonFlicker{0%,19%,21%,23%,25%,54%,56%,to{text-shadow:-.2rem -.2rem 1rem #fff,.2rem .2rem 1rem #fff,0 0 2px #f40,0 0 4px #f40,0 0 6px #f40,0 0 8px #f40,0 0 10px #f40;box-shadow:0 0 .5px #fff,inset 0 0 .5px #fff,0 0 2px #08f,inset 0 0 2px #08f,0 0 4px #08f,inset 0 0 4px #08f}20%,24%,55%{text-shadow:none;box-shadow:none}}.sun-editor-editable .__se__t-shadow,.sun-editor .__se__t-shadow{text-shadow:-.2rem -.2rem 1rem #fff,.2rem .2rem 1rem #fff,0 0 .2rem #999,0 0 .4rem #888,0 0 .6rem #777,0 0 .8rem #666,0 0 1rem #555}.sun-editor-editable .__se__t-code,.sun-editor .__se__t-code{font-family:monospace;color:#666;background-color:rgba(27,31,35,.05);border-radius:6px;padding:.2em .4em}
\ No newline at end of file
--- /dev/null
+/* All classes used must begin with "__se__". */
+/* used color #000 , #fff , #CCC, #f9f9f9 */
+/* font color #333, background color: #fff */
+/* grey color #e1e1e1 , #d1d1d1 , #c1c1c1 , #b1b1b1 */
+/* blue color #c7deff , #80bdff , #3f9dff , #4592ff */
+/* red color #b94a48 , #f2dede , #eed3d7 */
+
+/* suneditor contents */
+.sun-editor-editable {
+ font-family: Helvetica Neue, sans-serif;
+ font-size: 13px;
+ color: #333;
+ line-height: 1.5;
+ background-color: #fff;
+ word-break: normal;
+ word-wrap: break-word;
+ padding: 16px;
+ margin: 0;
+}
+
+.sun-editor-editable * {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ font-family: inherit;
+ font-size: inherit;
+ color: inherit;
+}
+
+/* RTL - editable */
+.sun-editor-editable.se-rtl * {
+ direction: rtl;
+}
+
+/** controllers on tag */
+.sun-editor-editable td, .sun-editor-editable th,
+.sun-editor-editable figure, .sun-editor-editable figcaption, .sun-editor-editable img,
+.sun-editor-editable iframe, .sun-editor-editable video, .sun-editor-editable audio {
+ position: relative;
+}
+
+/* float */
+.sun-editor-editable .__se__float-left {
+ float: left;
+}
+.sun-editor-editable .__se__float-right {
+ float: right;
+}
+.sun-editor-editable .__se__float-center {
+ float: center;
+}
+.sun-editor-editable .__se__float-none {
+ float: none;
+}
+
+/** span */
+.sun-editor-editable span {
+ display: inline;
+ vertical-align: baseline;
+ margin: 0;
+ padding: 0;
+}
+/* katex */
+.sun-editor-editable span.katex {
+ display: inline-block;
+}
+
+/* a */
+.sun-editor-editable a {
+ color: #004cff;
+ text-decoration: none;
+}
+.sun-editor-editable span[style~="color:"] a {
+ color: inherit;
+}
+.sun-editor-editable a:hover, .sun-editor-editable a:focus {
+ cursor: pointer;
+ color: #0093ff;
+ text-decoration: underline;
+}
+
+/* pre */
+.sun-editor-editable pre {
+ display: block;
+ padding: 8px;
+ margin: 0 0 10px;
+ font-family: monospace;
+ color: #666;
+ line-height: 1.45;
+ background-color: #f9f9f9;
+ border: 1px solid #e1e1e1;
+ border-radius: 2px;
+ white-space: pre-wrap;
+ word-wrap: break-word;
+ overflow: visible;
+}
+
+/* ol, ul */
+.sun-editor-editable ol {
+ list-style-position: inside;
+ display: block;
+ list-style-type: decimal;
+ margin-block-start: 1em;
+ margin-block-end: 1em;
+ margin-inline-start: 0px;
+ margin-inline-end: 0px;
+ padding-inline-start: 40px;
+}
+.sun-editor-editable ul {
+ list-style-position: inside;
+ display: block;
+ list-style-type: disc;
+ margin-block-start: 1em;
+ margin-block-end: 1em;
+ margin-inline-start: 0px;
+ margin-inline-end: 0px;
+ padding-inline-start: 40px;
+}
+.sun-editor-editable li {
+ display: list-item;
+ text-align: -webkit-match-parent;
+ margin-bottom: 5px;
+}
+/* nested list ol, ul */
+.sun-editor-editable ol ol, .sun-editor-editable ol ul, .sun-editor-editable ul ol, .sun-editor-editable ul ul {
+ margin: 0;
+}
+.sun-editor-editable ol ol, .sun-editor-editable ul ol {
+ list-style-type: lower-alpha;
+}
+.sun-editor-editable ol ol ol, .sun-editor-editable ul ol ol, .sun-editor-editable ul ul ol {
+ list-style-type: upper-roman;
+}
+.sun-editor-editable ul ul, .sun-editor-editable ol ul {
+ list-style-type: circle;
+}
+.sun-editor-editable ul ul ul, .sun-editor-editable ol ul ul, .sun-editor-editable ol ol ul {
+ list-style-type: square;
+}
+
+/* sub, sup */
+.sun-editor-editable sub, .sun-editor-editable sup {
+ font-size: 75%;
+ line-height: 0;
+}
+.sun-editor-editable sub {
+ vertical-align: sub;
+}
+.sun-editor-editable sup {
+ vertical-align: super;
+}
+
+/** format style */
+/* p */
+.sun-editor-editable p {
+ display: block;
+ margin: 0 0 10px;
+}
+
+/* div */
+.sun-editor-editable div {
+ display: block;
+ margin: 0;
+ padding: 0;
+}
+
+/* blockquote */
+.sun-editor-editable blockquote {
+ display: block;
+ font-family: inherit;
+ font-size: inherit;
+ color: #999;
+ margin-block-start: 1em;
+ margin-block-end: 1em;
+ margin-inline-start: 0;
+ margin-inline-end: 0;
+ border-style: solid;
+ border-width: 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ border-color: #b1b1b1;
+ padding-left: 20px;
+ padding-right: 5px;
+ border-left-width: 5px;
+ border-right-width: 0px;
+}
+.sun-editor-editable blockquote blockquote {
+ border-color: #c1c1c1;
+}
+.sun-editor-editable blockquote blockquote blockquote {
+ border-color: #d1d1d1;
+}
+.sun-editor-editable blockquote blockquote blockquote blockquote {
+ border-color: #e1e1e1;
+}
+/* RTL - blockquote */
+.sun-editor-editable.se-rtl blockquote {
+ padding-left: 5px;
+ padding-right: 20px;
+ border-left-width: 0px;
+ border-right-width: 5px;
+}
+
+/* h1 */
+.sun-editor-editable h1 {
+ display: block;
+ font-size: 2em;
+ margin-block-start: 0.67em;
+ margin-block-end: 0.67em;
+ margin-inline-start: 0px;
+ margin-inline-end: 0px;
+ font-weight: bold;
+}
+/* h2 */
+.sun-editor-editable h2 {
+ display: block;
+ font-size: 1.5em;
+ margin-block-start: 0.83em;
+ margin-block-end: 0.83em;
+ margin-inline-start: 0px;
+ margin-inline-end: 0px;
+ font-weight: bold;
+}
+/* h3 */
+.sun-editor-editable h3 {
+ display: block;
+ font-size: 1.17em;
+ margin-block-start: 1em;
+ margin-block-end: 1em;
+ margin-inline-start: 0px;
+ margin-inline-end: 0px;
+ font-weight: bold;
+}
+/* h4 */
+.sun-editor-editable h4 {
+ display: block;
+ font-size: 1em;
+ margin-block-start: 1.33em;
+ margin-block-end: 1.33em;
+ margin-inline-start: 0px;
+ margin-inline-end: 0px;
+ font-weight: bold;
+}
+/* h5 */
+.sun-editor-editable h5 {
+ display: block;
+ font-size: 0.83em;
+ margin-block-start: 1.67em;
+ margin-block-end: 1.67em;
+ margin-inline-start: 0px;
+ margin-inline-end: 0px;
+ font-weight: bold;
+}
+/* h6 */
+.sun-editor-editable h6 {
+ display: block;
+ font-size: 0.67em;
+ margin-block-start: 2.33em;
+ margin-block-end: 2.33em;
+ margin-inline-start: 0px;
+ margin-inline-end: 0px;
+ font-weight: bold;
+}
+
+/* hr */
+.sun-editor-editable hr {
+ display: flex;
+ border-width: 1px 0 0;
+ border-color: black;
+ border-image: initial;
+ height: 1px;
+}
+.sun-editor-editable hr.__se__solid {
+ border-style: solid none none;
+}
+.sun-editor-editable hr.__se__dotted {
+ border-style: dotted none none;
+}
+.sun-editor-editable hr.__se__dashed {
+ border-style: dashed none none;
+}
+
+/* table */
+.sun-editor-editable table {
+ display: table;
+ table-layout: auto;
+ border: 1px solid rgb(204, 204, 204);
+ width: 100%;
+ max-width: 100%;
+ margin: 0 0 10px;
+ background-color: transparent;
+ border-spacing: 0;
+ border-collapse: collapse;
+}
+
+/* RTL - table */
+.sun-editor-editable.se-rtl table {
+ margin: 0 0 10px auto;
+}
+
+.sun-editor-editable table thead {
+ border-bottom: 2px solid #333;
+}
+.sun-editor-editable table tr {
+ border: 1px solid #efefef;
+}
+.sun-editor-editable table th {
+ background-color: #f3f3f3;
+}
+.sun-editor-editable table th, .sun-editor-editable table td {
+ border: 1px solid #e1e1e1;
+ padding:0.4em;
+ background-clip: padding-box;
+}
+/** table style class */
+.sun-editor-editable table.se-table-size-auto {
+ width: auto !important;
+}
+.sun-editor-editable table.se-table-size-100 {
+ width: 100% !important;
+}
+.sun-editor-editable table.se-table-layout-auto {
+ table-layout: auto !important;
+}
+.sun-editor-editable table.se-table-layout-fixed {
+ table-layout: fixed !important;
+}
+/** table - select class */
+.sun-editor-editable table td.se-table-selected-cell, .sun-editor-editable table th.se-table-selected-cell {
+ border: 1px double #4592ff;
+ background-color: #f1f7ff;
+}
+.sun-editor-editable.se-disabled * {
+ user-select: none;
+ -o-user-select: none;
+ -moz-user-select: none;
+ -khtml-user-select: none;
+ -webkit-user-select: none;
+ -ms-user-select: none;
+}
+
+/** component (image, iframe video) */
+.sun-editor-editable .se-component {
+ display: flex;
+ padding: 1px;
+ margin: 0 0 10px;
+}
+.sun-editor-editable .se-component.__se__float-left {
+ margin: 0 20px 10px 0;
+}
+.sun-editor-editable .se-component.__se__float-right {
+ margin: 0 0 10px 20px;
+}
+.sun-editor-editable[contenteditable=true] .se-component {
+ outline: 1px dashed #e1e1e1;
+}
+/** component copy effect */
+.sun-editor-editable[contenteditable=true] .se-component.se-component-copy {
+ -webkit-box-shadow:0 0 0 0.2rem #80bdff; box-shadow:0 0 0 0.2rem #3f9dff; transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;
+}
+
+/** image, video .. */
+.sun-editor-editable img, .sun-editor-editable iframe, .sun-editor-editable video, .sun-editor-editable audio {
+ display: block;
+ margin: 0;
+ padding: 0;
+ width: auto;
+ height: auto;
+ max-width: 100%;
+}
+/* image, video - select index */
+.sun-editor-editable[contenteditable="true"] figure::after {
+ position: absolute;
+ content: '';
+ z-index: 1;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ cursor: default;
+ display: block;
+ background: rgba(0,0,0,0);
+}
+.sun-editor-editable[contenteditable="true"] figure a, .sun-editor-editable[contenteditable="true"] figure img, .sun-editor-editable[contenteditable="true"] figure iframe, .sun-editor-editable[contenteditable="true"] figure video {
+ z-index: 0;
+}
+.sun-editor-editable[contenteditable="true"] figure figcaption {
+ display: block;
+ z-index: 2;
+}
+.sun-editor-editable[contenteditable="true"] figure figcaption:focus {
+ border-color: #80bdff;
+ outline: 0;
+ -webkit-box-shadow: 0 0 0 0.2rem #c7deff;
+ box-shadow: 0 0 0 0.2rem #c7deff;
+}
+
+/** image, video iframe figure cover */
+.sun-editor-editable .se-image-container, .sun-editor-editable .se-video-container {
+ width: auto;
+ height: auto;
+ max-width: 100%;
+}
+.sun-editor-editable figure {
+ display: block;
+ outline: none;
+ margin: 0;
+ padding: 0;
+}
+.sun-editor-editable figure figcaption {
+ padding: 1em .5em;
+ margin: 0;
+ background-color: #f9f9f9;
+ outline: none;
+}
+.sun-editor-editable figure figcaption p{
+ line-height: 2;
+ margin: 0;
+}
+
+/* image */
+.sun-editor-editable .se-image-container a img {
+ padding: 1px;
+ margin: 1px;
+ outline: 1px solid #4592ff;
+}
+
+/** video */
+.sun-editor-editable .se-video-container iframe, .sun-editor-editable .se-video-container video {
+ outline: 1px solid #9e9e9e;
+ position: absolute;
+ top: 0;
+ left: 0;
+ border: 0;
+ width: 100%;
+ height: 100%;
+}
+.sun-editor-editable .se-video-container figure {
+ left: 0px;
+ width: 100%;
+ max-width: 100%;
+}
+
+/** audio */
+.sun-editor-editable audio {
+ width: 300px;
+ height: 54px;
+}
+.sun-editor-editable audio.active {
+ outline: 2px solid #80bdff;
+}
+
+/** --- show blocks mode */
+.sun-editor-editable.se-show-block p, .sun-editor-editable.se-show-block div,
+.sun-editor-editable.se-show-block h1, .sun-editor-editable.se-show-block h2, .sun-editor-editable.se-show-block h3,
+.sun-editor-editable.se-show-block h4, .sun-editor-editable.se-show-block h5, .sun-editor-editable.se-show-block h6, .sun-editor-editable.se-show-block li,
+.sun-editor-editable.se-show-block ol, .sun-editor-editable.se-show-block ul,
+.sun-editor-editable.se-show-block pre {
+ border:1px dashed #3f9dff !important;
+ padding:14px 8px 8px 8px !important;
+}
+.sun-editor-editable.se-show-block ol, .sun-editor-editable.se-show-block ul {
+ border:1px dashed #d539ff !important;
+}
+.sun-editor-editable.se-show-block pre {
+ border:1px dashed #27c022 !important;
+}
+.se-show-block p {background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAPAQMAAAAF7dc0AAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAaSURBVAjXY/j/gwGCPvxg+F4BQiAGDP1HQQByxxw0gqOzIwAAAABJRU5ErkJggg==') no-repeat;}
+.se-show-block div {background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAPAQMAAAAxlBYoAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAmSURBVAjXY/j//wcDDH+8XsHwDYi/hwNx1A8w/nYLKH4XoQYJAwCXnSgcl2MOPgAAAABJRU5ErkJggg==') no-repeat;}
+.se-show-block h1 {background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAfSURBVAjXY/j/v4EBhr+9B+LzEPrDeygfhI8j1CBhAEhmJGY4Rf6uAAAAAElFTkSuQmCC') no-repeat;}
+.se-show-block h2 {background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAmSURBVAjXY/j/v4EBhr+dB+LtQPy9geEDEH97D8T3gbgdoQYJAwA51iPuD2haEAAAAABJRU5ErkJggg==') no-repeat;}
+.se-show-block h3 {background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAiSURBVAjXY/j/v4EBhr+dB+LtQPy9geHDeQgN5p9HqEHCADeWI+69VG2MAAAAAElFTkSuQmCC') no-repeat;}
+.se-show-block h4 {background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAPAQMAAADTSA1RAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAiSURBVAjXY/j//wADDH97DsTXIfjDdiDdDMTfIRhZHRQDAKJOJ6L+K3y7AAAAAElFTkSuQmCC') no-repeat;}
+.se-show-block h5 {background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAlSURBVAjXY/j/v4EBhr+1A/F+IO5vYPiwHUh/B2IQfR6hBgkDABlWIy5uM+9GAAAAAElFTkSuQmCC') no-repeat;}
+.se-show-block h6 {background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAPAQMAAAA4f7ZSAAAABlBMVEWAgID////n1o2sAAAAAnRSTlP/AOW3MEoAAAAiSURBVAjXY/j/v4EBhr+dB+LtQLy/geFDP5S9HSKOrA6KAR9GIza1ptJnAAAAAElFTkSuQmCC') no-repeat;}
+.se-show-block li {background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA7SURBVDhPYxgFcNDQ0PAfykQBIHEYhgoRB/BpwCfHBKWpBkaggYxQGgOgBzyQD1aLLA4TGwWDGjAwAACR3RcEU9Ui+wAAAABJRU5ErkJggg==') no-repeat;}
+.se-show-block ol {background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABHSURBVDhPYxgFcNDQ0PAfhKFcFIBLHCdA1oBNM0kGEmMAPgOZoDTVANUNxAqQvURMECADRiiNAWCagDSGGhyW4DRrMAEGBgAu0SX6WpGgjAAAAABJRU5ErkJggg==') no-repeat;}
+.se-show-block ul {background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA1SURBVDhPYxgFDA0NDf+hTBSALI5LDQgwQWmqgVEDKQcsUBoF4ItFGEBXA+QzQpmDGjAwAAA8DQ4Lni6gdAAAAABJRU5ErkJggg==') no-repeat;}
+
+/** -- Paragraph styles custom -- */
+/* Bordered */
+.sun-editor-editable .__se__p-bordered, .sun-editor .__se__p-bordered {
+ border-top: solid 1px #b1b1b1;
+ border-bottom: solid 1px #b1b1b1;
+ padding: 4px 0;
+}
+/* Spaced */
+.sun-editor-editable .__se__p-spaced, .sun-editor .__se__p-spaced {
+ letter-spacing: 1px;
+}
+/* Neon (https://codepen.io/GeorgePark/pen/MrjbEr) */
+.sun-editor-editable .__se__p-neon, .sun-editor .__se__p-neon {
+ font-weight: 200;
+ font-style: italic;
+ background: #000;
+ color: #fff;
+ padding: 6px 4px;
+ border: 2px solid #fff;
+ border-radius: 6px;
+ text-transform: uppercase;
+ animation: neonFlicker 1.5s infinite alternate;
+}
+@keyframes neonFlicker {
+ 0%, 19%, 21%, 23%, 25%, 54%, 56%, 100% {
+ text-shadow:
+ -0.2rem -0.2rem 1rem #fff,
+ 0.2rem 0.2rem 1rem #fff,
+ 0 0 2px #f40,
+ 0 0 4px #f40,
+ 0 0 6px #f40,
+ 0 0 8px #f40,
+ 0 0 10px #f40;
+ box-shadow:
+ 0 0 .5px #fff,
+ inset 0 0 .5px #fff,
+ 0 0 2px #08f,
+ inset 0 0 2px #08f,
+ 0 0 4px #08f,
+ inset 0 0 4px #08f;
+ }
+ 20%, 24%, 55% {
+ text-shadow: none;
+ box-shadow: none;
+ }
+}
+
+/* -- Text styles custom -- */
+/* Shadow */
+.sun-editor-editable .__se__t-shadow, .sun-editor .__se__t-shadow {
+ text-shadow:
+ -0.2rem -0.2rem 1rem #fff,
+ 0.2rem 0.2rem 1rem #fff,
+ 0 0 0.2rem #999,
+ 0 0 0.4rem #888,
+ 0 0 0.6rem #777,
+ 0 0 0.8rem #666,
+ 0 0 1rem #555;
+}
+/* Code */
+.sun-editor-editable .__se__t-code, .sun-editor .__se__t-code {
+ font-family: monospace;
+ color: #666;
+ background-color: rgba(27,31,35,.05);
+ border-radius: 6px;
+ padding: 0.2em 0.4em;
+}
\ No newline at end of file
--- /dev/null
+/* used color #000 , #fff , #CCC, #f5f5f5, #f9f9f9 */
+/* font color #333, background color: #fff */
+/* grey color #e1e1e1 , #d1d1d1 , #c1c1c1 , #b1b1b1 */
+/* blue color #c7deff , #80bdff , #3f9dff , #4592ff, #407dd1, #3288ff */
+/* red color #b94a48 , #f2dede , #eed3d7 */
+
+/** --- suneditor main */
+.sun-editor {width:auto; height:auto; box-sizing:border-box; font-family:Helvetica Neue, sans-serif; border:1px solid #dadada; background-color:#FFF; color:#000; user-select:none; -o-user-select:none; -moz-user-select:none; -khtml-user-select:none; -webkit-user-select:none; -ms-user-select:none;}
+.sun-editor * {box-sizing:border-box; -webkit-user-drag:none; overflow:visible;}
+.sun-editor-common input, .sun-editor-common select, .sun-editor-common textarea, .sun-editor-common button {font-size:14px; line-height:1.5;}
+.sun-editor-common body, .sun-editor-common div, .sun-editor-common dl, .sun-editor-common dt, .sun-editor-common dd, .sun-editor-common ul, .sun-editor-common ol, .sun-editor-common li,
+.sun-editor-common h1, .sun-editor-common h2, .sun-editor-common h3, .sun-editor-common h4, .sun-editor-common h5, .sun-editor-common h6, .sun-editor-common pre, .sun-editor-common code,
+.sun-editor-common form, .sun-editor-common fieldset, .sun-editor-common legend, .sun-editor-common textarea, .sun-editor-common p, .sun-editor-common blockquote, .sun-editor-common th,
+.sun-editor-common td, .sun-editor-common input, .sun-editor-common select, .sun-editor-common textarea, .sun-editor-common button {margin:0; padding:0; border:0;}
+.sun-editor-common dl, .sun-editor-common ul, .sun-editor-common ol, .sun-editor-common menu, .sun-editor-common li {list-style:none !important;}
+.sun-editor-common hr {margin:6px 0 6px 0 !important;}
+.sun-editor textarea {resize:none; border:0; padding:0;}
+.sun-editor button {border:0 none; background-color:transparent; touch-action:manipulation; cursor:pointer; outline:none;}
+.sun-editor input, .sun-editor select, .sun-editor textarea, .sun-editor button {vertical-align:middle;}
+.sun-editor button span {display:block; margin:0; padding:0;}
+.sun-editor button .txt {display:block; margin-top:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
+
+
+/* button children are pointer event none */
+.sun-editor button * {
+ pointer-events: none;
+ backface-visibility: hidden;
+ -webkit-backface-visibility: hidden;
+ -moz-backface-visibility: hidden;
+}
+
+
+/** --- Icons ---------------------------------------------------------- */
+/* default svg */
+.sun-editor button > svg, .sun-editor .se-svg {
+ width: 16px;
+ height: 16px;
+ margin: auto;
+ fill: currentColor;
+ display: block;
+ text-align: center;
+ float: none;
+}
+/* close class icon */
+.sun-editor .close > svg, .sun-editor .se-dialog-close > svg {
+ width: 10px;
+ height: 10px;
+}
+/* se-select-btn icon */
+.sun-editor .se-btn-select > svg {
+ float: right;
+ width: 10px;
+ height: 10px;
+}
+/* se-btn-list inner icon */
+.sun-editor .se-btn-list > .se-list-icon {
+ display: inline-block;
+ width: 16px;
+ height: 16px;
+ margin: -1px 10px 0 0;
+ vertical-align: middle;
+}
+/* se-line-breaker inner icon */
+.sun-editor .se-line-breaker > button > svg {
+ width: 24px;
+ height: 24px;
+}
+
+/* icon class */
+.sun-editor button > i::before {
+ -moz-osx-font-smoothing:grayscale;
+ -webkit-font-smoothing:antialiased;
+ display: inline-block;
+ font-style: normal;
+ font-variant: normal;
+ text-rendering:auto;
+ font-size: 15px;
+ line-height: 2;
+}
+.sun-editor button > [class="se-icon-text"] {
+ font-size: 20px;
+ line-height: 1;
+}
+
+/** --- arrow icon ---------------------------------------------------------- */
+.sun-editor .se-arrow, .sun-editor .se-arrow::after {position:absolute; display:block; width:0; height:0; border:11px solid transparent;}
+/* arrow up */
+.sun-editor .se-arrow.se-arrow-up {top:-11px; left:20px; margin-left:-11px; border-top-width:0; border-bottom-color:rgba(0, 0, 0, .25);}
+.sun-editor .se-arrow.se-arrow-up::after {top:1px; margin-left:-11px; content:" "; border-top-width:0; border-bottom-color:#fff;}
+.sun-editor .se-toolbar .se-arrow.se-arrow-up::after {border-bottom-color:#fafafa;}
+/* arrow down */
+.sun-editor .se-arrow.se-arrow-down {top:0px; left:0px; margin-left:-11px; border-bottom-width:0; border-top-color:rgba(0, 0, 0, .25);}
+.sun-editor .se-arrow.se-arrow-down::after {top:-12px; margin-left:-11px; content:" "; border-bottom-width:0; border-top-color:#fff;}
+.sun-editor .se-toolbar .se-arrow.se-arrow-down::after {border-top-color:#fafafa;}
+
+/** --- container */
+.sun-editor .se-container {position:relative; width:100%; height:100%;}
+
+/** button */
+.sun-editor button {color:#000;}
+
+/** --- se-btn button */
+.sun-editor .se-btn {float:left; width:34px; height:34px; border:0; border-radius:4px; margin:1px !important; padding:0; font-size:12px; line-height:27px;}
+.sun-editor .se-btn:enabled:hover, .sun-editor .se-btn:enabled:focus {background-color:#e1e1e1; border-color:#d1d1d1; outline:0 none;}
+.sun-editor .se-btn:enabled:active {background-color:#d1d1d1; border-color:#c1c1c1; -webkit-box-shadow:inset 0 3px 5px #c1c1c1; box-shadow:inset 0 3px 5px #c1c1c1;}
+/** --- primary button */
+.sun-editor .se-btn-primary {color:#000; background-color:#c7deff; border:1px solid #80bdff; border-radius:4px;}
+.sun-editor .se-btn-primary:hover, .sun-editor .se-btn-primary:focus {color:#000; background-color:#80bdff; border-color:#3f9dff; outline:0 none;}
+.sun-editor .se-btn-primary:active {color:#fff; background-color:#3f9dff; border-color:#4592ff; -webkit-box-shadow:inset 0 3px 5px #4592ff; box-shadow:inset 0 3px 5px #4592ff;}
+
+/** --- Input */
+.sun-editor input, .sun-editor select, .sun-editor textarea {color:#000; border:1px solid #ccc; border-radius:4px;}
+.sun-editor input:focus, .sun-editor select:focus, .sun-editor textarea:focus {border-color:#80bdff; border-width:1px; border-style:solid; outline:0; -webkit-box-shadow:0 0 0 0.2rem #c7deff; box-shadow:0 0 0 0.2rem #c7deff; transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;}
+
+/* se-btn button active*/
+.sun-editor .se-btn:enabled.active {color:#4592ff; outline:0 none;}
+.sun-editor .se-btn:enabled.active:hover, .sun-editor .se-btn:enabled.active:focus {background-color:#e1e1e1; border-color:#d1d1d1; outline:0 none;}
+.sun-editor .se-btn:enabled.active:active {background-color:#d1d1d1; border-color:#c1c1c1; -webkit-box-shadow:inset 0 3px 5px #c1c1c1; box-shadow:inset 0 3px 5px #c1c1c1;}
+/* se-btn button on */
+.sun-editor .se-btn:enabled.on {background-color:#e1e1e1; border-color:#d1d1d1; outline:0 none;}
+.sun-editor .se-btn:enabled.on:hover, .sun-editor .se-btn:enabled.on:focus {background-color:#d1d1d1; border-color:#c1c1c1; outline:0 none;}
+.sun-editor .se-btn:enabled.on:active {background-color:#c1c1c1; border-color:#b1b1b1; -webkit-box-shadow:inset 0 3px 5px #b1b1b1; box-shadow:inset 0 3px 5px #b1b1b1;}
+/* disabled buttons, icon blur */
+.sun-editor .se-btn:disabled, .sun-editor .se-btn-list:disabled, .sun-editor button:disabled {cursor:not-allowed; background-color:inherit; color:#bdbdbd;}
+
+/** --- loading box */
+.sun-editor .se-loading-box {position:absolute; display:none; width:100%; height:100%; top:0; left:0; background-color:#fff; opacity:.7; filter:alpha(opacity=70); z-index:2147483647;}
+.sun-editor .se-loading-box .se-loading-effect {position:absolute; display:block; top:50%; left:50%; height:25px; width:25px; border-top:2px solid #07d; border-right:2px solid transparent; border-radius:50%; animation:spinner .8s linear infinite; margin:-25px 0 0 -25px;}
+
+/** --- line breaker */
+.sun-editor .se-line-breaker {position:absolute; display:none; width:100%; height:1px; cursor:text; border-top:1px solid #3288ff; z-index:7;}
+.sun-editor .se-line-breaker > button.se-btn {position:relative; display:inline-block; width:30px; height:30px; top:-15px; float:none; left:-50%; background-color:#fff; border:1px solid #0c2240; opacity:0.6; cursor:pointer;}
+.sun-editor .se-line-breaker > button.se-btn:hover {opacity:0.9; background-color:#fff; border-color:#041b39;}
+/** --- line breaker --- component - top, bottom */
+.sun-editor .se-line-breaker-component {position:absolute; display:none; width:24px; height:24px; background-color:#fff; border:1px solid #0c2240; opacity:0.6; border-radius:4px; cursor:pointer; z-index:7;}
+.sun-editor .se-line-breaker-component:hover {opacity:0.9;}
+
+/** --- toolbar ---------------------------------------------------------- */
+.sun-editor .se-toolbar {display:block; position:relative; height:auto; width:100%; overflow:visible; padding:4px 3px 0 3px; margin:0; background-color:#fafafa; outline:1px solid #dadada; z-index:5;}
+.sun-editor .se-toolbar-cover {position:absolute; display:none; font-size:36px; width:100%; height:100%; top:0; left:0; background-color:#fefefe; opacity:.5; filter:alpha(opacity=50); cursor:not-allowed; z-index:4;}
+.sun-editor .se-toolbar-separator-vertical {display:inline-block; height:0px; width:0px; margin:1px; vertical-align:top;}
+/* inline toolbar */
+.sun-editor .se-toolbar.se-toolbar-inline {display:none; position:absolute; z-index:2147483647; box-shadow:0 3px 9px rgba(0,0,0,.5); -webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);}
+/* balloon toolbar */
+.sun-editor .se-toolbar.se-toolbar-balloon {display:none; position:absolute; z-index:2147483647; width:auto; box-shadow:0 3px 9px rgba(0,0,0,.5); -webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);}
+/* sticky toolbar */
+.sun-editor .se-toolbar.se-toolbar-sticky {position:fixed; top:0px;}
+.sun-editor .se-toolbar-sticky-dummy {display:none; position:static; z-index:-1;}
+
+/** --- tool bar --- module --- button, module, group ---------------------------------------------------------- */
+/* module */
+.sun-editor .se-btn-module {display:inline-block;}
+.sun-editor .se-btn-module-border {border:1px solid #dadada; border-radius:4px;}
+.sun-editor .se-btn-module-enter {display:block; width:100%; height:1px; margin-bottom:5px; background-color:transparent;}
+/* ---more - layer */
+.sun-editor .se-toolbar-more-layer {margin:0 -3px; background-color:#f3f3f3;}
+.sun-editor .se-toolbar-more-layer .se-more-layer {display:none; border-top:1px solid #dadada;}
+.sun-editor .se-toolbar-more-layer .se-more-layer .se-more-form {display:inline-block; width:100%; height:auto; padding:4px 3px 0 3px;}
+/* ---more - button */
+.sun-editor .se-btn-module .se-btn-more.se-btn-more-text {width:auto; padding:0 4px;}
+.sun-editor .se-btn-module .se-btn-more:hover, .sun-editor .se-btn-module .se-btn-more:focus {color:#000; background-color:#d1d1d1; border-color:#c1c1c1; outline:0 none;}
+.sun-editor .se-btn-module .se-btn-more.on {color:#333; background-color:#d1d1d1; border-color:#c1c1c1; outline:0 none;}
+.sun-editor .se-btn-module .se-btn-more.on:hover {color:#000; background-color:#c1c1c1; border-color:#b1b1b1; outline:0 none;}
+/* innser ul */
+.sun-editor .se-menu-list {float:left; padding:0; margin:0;}
+.sun-editor .se-menu-list li {position:relative; float:left; padding:0; margin:0;}
+/* tool bar select button (font, fontSize, formatBlock) */
+.sun-editor .se-btn-select {width:auto; display:flex; padding:4px 6px;}
+.sun-editor .se-btn-select .txt {flex:auto; text-align:left;}
+.sun-editor.se-rtl .se-btn-select svg {margin:auto 1px;}
+.sun-editor .se-btn-select.se-btn-tool-font {width:100px;}
+.sun-editor .se-btn-select.se-btn-tool-format {width:82px;}
+.sun-editor .se-btn-select.se-btn-tool-size {width:78px;}
+
+/** --- menu tray -------------------------------------------------------------- */
+.sun-editor .se-btn-tray {position:relative; width:100%; height:100%; margin:0; padding:0;}
+.sun-editor .se-menu-tray {position:absolute; top:0px; left:0px; width:100%; height:0px;}
+
+/** --- submenu layer ---------------------------------------------------------- */
+.sun-editor .se-submenu {overflow-x:hidden; overflow-y:auto;}
+.sun-editor .se-list-layer {display:none; position:absolute; top:0px; left:0px; height:auto; z-index:5; border:1px solid #bababa; border-radius:4px; padding:6px 0; background-color:#fff; -webkit-box-shadow:0 3px 9px rgba(0, 0, 0, .5); box-shadow:0 3px 9px rgba(0, 0, 0, .5); outline:0 none;}
+.sun-editor .se-list-layer .se-list-inner {padding:0; margin:0; overflow-x:initial; overflow-y:initial; overflow:visible;}
+.sun-editor .se-list-layer button {margin:0; width:100%;}
+/* submenu layer - common list form */
+.sun-editor .se-list-inner .se-list-basic {width:100%; padding:0;}
+.sun-editor .se-list-inner .se-list-basic li {width:100%;}
+.sun-editor .se-list-inner .se-list-basic li > button {min-width:100%; width:max-content;}
+/* submenu layer - common list form button on */
+.sun-editor .se-list-inner .se-list-basic li button.active {background-color:#80bdff; border:1px solid #3f9dff; border-left:0; border-right:0;}
+.sun-editor .se-list-inner .se-list-basic li button.active:hover {background-color:#3f9dff; border:1px solid #4592ff; border-left:0; border-right:0;}
+.sun-editor .se-list-inner .se-list-basic li button.active:active {background-color:#4592ff; border:1px solid #407dd1; border-left:0; border-right:0; -webkit-box-shadow:inset 0 3px 5px #407dd1; box-shadow:inset 0 3px 5px #407dd1;}
+/* submenu layer - list button */
+.sun-editor .se-btn-list {width:100%; height:auto; min-height:32px; padding:0 14px; cursor:pointer; font-size:12px; line-height:normal; text-indent:0; text-decoration:none; text-align:left;}
+.sun-editor .se-btn-list.default_value {background-color:#f3f3f3; border-top:1px dotted #b1b1b1; border-bottom:1px dotted #b1b1b1;}
+.sun-editor .se-btn-list:hover, .sun-editor .se-btn-list:focus {background-color:#e1e1e1; border-color:#d1d1d1; outline:0 none;}
+.sun-editor .se-btn-list:active {background-color:#d1d1d1; border-color:#c1c1c1; -webkit-box-shadow:inset 0 3px 5px #c1c1c1; box-shadow:inset 0 3px 5px #c1c1c1;}
+/** --- submenu layer - se-list-inner > exception */
+/* submenu layer - font size */
+.sun-editor .se-list-layer.se-list-font-size {min-width:140px; max-height:300px;}
+/* submenu layer - font family */
+.sun-editor .se-list-layer.se-list-font-family {min-width:156px;}
+.sun-editor .se-list-layer.se-list-font-family .default {border-bottom:1px solid #CCC;}
+/* submenu layer - hr */
+.sun-editor .se-list-layer.se-list-line {width:125px;}
+/* submenu layer - align */
+.sun-editor .se-list-layer.se-list-align .se-list-inner {left:9px; width:125px;}
+/** submenu layer - format block, paragraph style, text style */
+.sun-editor .se-list-layer.se-list-format {min-width:156px;}
+.sun-editor .se-list-layer.se-list-format li {padding:0; width:100%;}
+.sun-editor .se-list-layer.se-list-format ul .se-btn-list {line-height:100%;}
+.sun-editor .se-list-layer.se-list-format ul .se-btn-list[data-value="h1"] {height:40px;}
+.sun-editor .se-list-layer.se-list-format ul .se-btn-list[data-value="h2"] {height:34px;}
+.sun-editor .se-list-layer.se-list-format ul p {font-size:13px;}
+.sun-editor .se-list-layer.se-list-format ul div {font-size:13px; padding:4px 2px;}
+.sun-editor .se-list-layer.se-list-format ul h1 {font-size:2em; font-weight:bold; color:#333;}
+.sun-editor .se-list-layer.se-list-format ul h2 {font-size:1.5em; font-weight:bold; color:#333;}
+.sun-editor .se-list-layer.se-list-format ul h3 {font-size:1.17em; font-weight:bold; color:#333;}
+.sun-editor .se-list-layer.se-list-format ul h4 {font-size:1em; font-weight:bold; color:#333;}
+.sun-editor .se-list-layer.se-list-format ul h5 {font-size:0.83em; font-weight:bold; color:#333;}
+.sun-editor .se-list-layer.se-list-format ul h6 {font-size:0.67em; font-weight:bold; color:#333;}
+.sun-editor .se-list-layer.se-list-format ul blockquote {font-size:13px; color:#999; height:22px; margin:0; background-color:transparent; line-height:1.5; border-style:solid; border-color:#b1b1b1; padding:0 0 0 7px; border-left-width:5px;}
+.sun-editor .se-list-layer.se-list-format ul pre {font-size:13px; color:#666; padding:4px 11px; margin:0; background-color:#f9f9f9; border:1px solid #e1e1e1; border-radius:4px;}
+/* submenu layer --- table selector */
+.sun-editor .se-selector-table {display:none; position:absolute; top:34px; left:1px; z-index:5; padding:5px 0; float:left; margin:2px 0 0; font-size:14px; text-align:left; list-style:none; background-color:#fff; -webkit-background-clip:padding-box; background-clip:padding-box; border:1px solid #ccc; border-radius:4px; -webkit-box-shadow:0 6px 12px rgba(0, 0, 0, .175); box-shadow:0 6px 12px rgba(0, 0, 0, .175);}
+.sun-editor .se-selector-table .se-table-size {font-size:18px; padding:0 5px;}
+.sun-editor .se-selector-table .se-table-size-picker {position:absolute !important; z-index:3; font-size:18px; width:10em; height:10em; cursor:pointer;}
+.sun-editor .se-selector-table .se-table-size-highlighted {position:absolute !important; z-index:2; font-size:18px; width:1em; height:1em; background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAADJmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4QTZCNzMzN0I3RUYxMUU4ODcwQ0QwMjM1NTgzRTJDNyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo4QTZCNzMzNkI3RUYxMUU4ODcwQ0QwMjM1NTgzRTJDNyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0MzYyNEUxRUI3RUUxMUU4ODZGQzgwRjNBODgyNTdFOSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0MzYyNEUxRkI3RUUxMUU4ODZGQzgwRjNBODgyNTdFOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pl0yAuwAAABBSURBVDhPY/wPBAxUAGCDGvdBeWSAeicIDTfIXREiQArYeR9hEBOEohyMGkQYjBpEGAxjg6ib+yFMygCVvMbAAABj0hwMTNeKJwAAAABJRU5ErkJggg==') repeat;}
+.sun-editor .se-selector-table .se-table-size-unhighlighted {position:relative !important; z-index:1; font-size:18px; width:10em; height:10em; background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIj4+Pjp6ekKlAqjAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKhmnaJzPAAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC') repeat;}
+.sun-editor .se-selector-table .se-table-size-display {padding-left:5px;}
+/* submenu layer --- color selector button */
+.sun-editor .se-list-layer .se-selector-color {display:flex; width:max-content; max-width:270px; height:auto; padding:0; margin:auto;}
+.sun-editor .se-list-layer .se-selector-color .se-color-pallet {width:100%; height:100%; padding:0;}
+.sun-editor .se-list-layer .se-selector-color .se-color-pallet li {display:flex; float:left; position:relative; margin:0;}
+.sun-editor .se-list-layer .se-selector-color .se-color-pallet button {display:block; cursor:default; width:30px; height:30px; text-indent:-9999px;}
+.sun-editor .se-list-layer .se-selector-color .se-color-pallet button.active,
+.sun-editor .se-list-layer .se-selector-color .se-color-pallet button:hover,
+.sun-editor .se-list-layer .se-selector-color .se-color-pallet button:focus {border:3px solid #fff;}
+/* submenu layer - form group (color selector) */
+.sun-editor .se-submenu-form-group {display:flex; width:100%; min-height:40px; height:auto; padding:4px;}
+.sun-editor .se-submenu-form-group input {flex:auto; display:inline-block; width:auto; height:33px; color:#555; font-size:12px; margin:1px 0 1px 0; padding:0; border-radius:0.25rem; border:1px solid #ccc;}
+.sun-editor .se-submenu-form-group button {float:right; width:34px; height:34px; margin:0 2px !important;}
+.sun-editor .se-submenu-form-group button.se-btn {border:1px solid #ccc;}
+.sun-editor .se-submenu-form-group > div {position:relative;}
+/** submenu layer - color input */
+.sun-editor .se-submenu-form-group .se-color-input {width:72px; text-transform:uppercase; border:none; border-bottom:2px solid #b1b1b1; outline:none;}
+.sun-editor .se-submenu-form-group .se-color-input:focus {border-bottom:3px solid #b1b1b1;}
+
+/** --- editor area */
+.sun-editor .se-wrapper {position:relative !important; width:100%; height:auto; overflow:hidden; z-index:1;}
+.sun-editor .se-wrapper .se-wrapper-inner {width:100%; height:100%; min-height:65px; overflow-y:auto; overflow-x:auto; -webkit-overflow-scrolling:touch; user-select:text; -o-user-select:text; -moz-user-select:text; -khtml-user-select:text; -webkit-user-select:text; -ms-user-select:text;}
+.sun-editor .se-wrapper .se-wrapper-inner:focus {outline:none;}
+.sun-editor .se-wrapper .se-wrapper-code {background-color:#191919; color:#fff; font-size:13px; word-break:break-all; padding:4px; margin:0; resize:none !important;}
+.sun-editor .se-wrapper .se-wrapper-wysiwyg {background-color:#fff; display:block;}
+.sun-editor .se-wrapper .se-wrapper-code-mirror {font-size:13px;}
+/** --- placeholder */
+.sun-editor .se-wrapper .se-placeholder {position:absolute; display:none; white-space:nowrap; text-overflow:ellipsis; z-index:1; color:#b1b1b1; font-size:13px; line-height:1.5; top:0; left:0; right:0; overflow:hidden; margin-top:0px; padding-top:16px; padding-left:16px; margin-left:0px; padding-right:16px; margin-right:0px; pointer-events:none; backface-visibility:hidden; -webkit-backface-visibility:hidden; -moz-backface-visibility:hidden;}
+
+/** --- resizing bar */
+.sun-editor .se-resizing-bar {display:flex; width:auto; height:auto; min-height:16px; border-top:1px solid #dadada; padding:0 4px; background-color:#fafafa; cursor:ns-resize;}
+.sun-editor .se-resizing-bar.se-resizing-none {cursor:default;}
+.sun-editor .se-resizing-back {position:absolute; display:none; cursor:default; top:0; left:0; width:100%; height:100%; z-index:2147483647;}
+/** resizing bar - nabigation */
+.sun-editor .se-resizing-bar .se-navigation {flex:auto; position:relative; width:auto; height:auto; color:#666; margin:0; padding:0; font-size:10px; font-weight:bold; line-height:1.5; background:transparent;}
+/** resizing bar - charCounter */
+.sun-editor .se-resizing-bar .se-char-counter-wrapper {flex:none; position:relative; display:block; width:auto; height:auto; margin:0; padding:0; color:#999; font-size:13px; background:transparent;}
+.sun-editor .se-resizing-bar .se-char-counter-wrapper.se-blink {color:#b94a48; animation:blinker 0.2s linear infinite;}
+.sun-editor .se-resizing-bar .se-char-counter-wrapper .se-char-label {margin-right:4px;}
+
+/* --- dialog ---------------------------------------------------------- */
+.sun-editor .se-dialog {position:absolute; display:none; top:0; left:0; width:100%; height:100%; z-index:2147483647;}
+.sun-editor .se-dialog label, .sun-editor .se-dialog input, .sun-editor .se-dialog button {font-size:14px; line-height:1.5; color:#111; margin:0;}
+.sun-editor .se-dialog .se-dialog-back {position:absolute; width:100%; height:100%; top:0; left:0; background-color:#222; opacity:0.5;}
+/* dialog - modal */
+.sun-editor .se-dialog .se-dialog-inner {position:absolute; width:100%; height:100%; top:0; left:0;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-content {position:relative; width:auto; max-width:500px; margin:20px auto; background-color:#fff; -webkit-background-clip:padding-box; background-clip:padding-box; border:1px solid rgba(0, 0, 0, .2); border-radius:4px; outline:0; -webkit-box-shadow:0 3px 9px rgba(0, 0, 0, .5); box-shadow:0 3px 9px rgba(0, 0, 0, .5);}
+@media screen and (max-width:509px) { .sun-editor .se-dialog .se-dialog-inner .se-dialog-content {width:100%;} }
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-content label {display:inline-block; max-width:100%; margin-bottom:5px; font-weight:bold;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-content .se-btn-primary {display:inline-block; padding:6px 12px; margin:0 0 10px 0 !important; font-size:14px; font-weight:normal; line-height:1.42857143; text-align:center; white-space:nowrap; vertical-align:middle; -ms-touch-action:manipulation; touch-action:manipulation; border-radius:4px;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-header {height:50px; padding:6px 15px 6px 15px; border-bottom:1px solid #e5e5e5;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-header .se-dialog-close {float:right; font-weight:bold; text-shadow:0 1px 0 #fff; -webkit-appearance:none; filter:alpha(opacity=100); opacity:1;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-header .se-modal-title {float:left; font-size:14px; font-weight:bold; margin:0; padding:0; line-height:2.5;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-body {position:relative; padding:15px;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form {margin-bottom:10px;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form-footer {margin-top:10px; margin-bottom:0;}
+.sun-editor .se-dialog .se-dialog-inner input:disabled {background-color:#f3f3f3;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-size-text {width:100%;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-size-text .size-w {width:70px; text-align:center;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-size-text .size-h {width:70px; text-align:center;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-size-x {margin:0 8px 0 8px; width:25px; text-align:center;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-footer {height:55px; padding:10px 15px 0px 15px; text-align:right; border-top:1px solid #e5e5e5;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-footer > div {float:left;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-footer > div > label {margin:0 5px 0 0;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-radio {margin-left:12px; margin-right:6px;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-check {margin-left:12px; margin-right:4px;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form-footer .se-dialog-btn-check {margin-left:0; margin-right:4px;}
+/* dialog - modal - form - files */
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files {position:relative; display:flex; align-items:center;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files > input {flex:auto;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files .se-dialog-files-edge-button {flex:auto; opacity:0.8; border:1px solid #ccc;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files .se-dialog-files-edge-button.se-file-remove > svg {width:8px; height:8px;} /* custom."remove icon" */
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files .se-dialog-files-edge-button:hover {background-color:#f0f0f0; outline:0 none;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-dialog-form-files .se-dialog-files-edge-button:active {background-color:#e9e9e9; -webkit-box-shadow:inset 0 3px 5px #d6d6d6; box-shadow:inset 0 3px 5px #d6d6d6;}
+/* dialog - modal - input */
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-select {display:inline-block; width:auto; height:34px; font-size:14px; text-align:center; line-height:1.42857143;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-control {display:inline-block; width:70px; height:34px; font-size:14px; text-align:center; line-height:1.42857143;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-form {display:block; width:100%; height:34px; font-size:14px; line-height:1.42857143; padding:0 4px;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-form.se-input-url {direction:ltr;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-form.se-input-url:disabled {text-decoration:line-through; color:#999;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-video-ratio {width:70px; margin-left:4px;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form a {color:#004cff;}
+/* dialog - revert button */
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-revert {border:1px solid #ccc;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-revert:hover {background-color:#e1e1e1; border-color:#d1d1d1; outline:0 none;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-btn-revert:active {background-color:#d1d1d1; border-color:#c1c1c1; -webkit-box-shadow:inset 0 3px 5px #c1c1c1; box-shadow:inset 0 3px 5px #c1c1c1;}
+/* dialog - inner tab */
+.sun-editor .se-dialog-tabs {width:100%; height:25px; border-bottom:1px solid #e5e5e5;}
+.sun-editor .se-dialog-tabs button {background-color:#e5e5e5; border-right:1px solid #e5e5e5; float:left; outline:none; padding:2px 13px; transition:0.3s;}
+.sun-editor .se-dialog-tabs button:hover {background-color:#fff;}
+.sun-editor .se-dialog-tabs button.active {background-color:#fff;border-bottom:0;}
+
+/* dialog - modal - math */
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-form.se-math-exp {resize:vertical; height:4rem; border:1px solid #ccc; font-size:13px; padding:4px;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-input-select.se-math-size {width:6em; height:28px; margin-left:1em;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-math-preview {font-size:13px;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-math-preview > span {display:inline-block; -webkit-box-shadow:0 0 0 0.1rem #c7deff; box-shadow:0 0 0 0.1rem #c7deff;}
+/* dialog - modal - se-link-preview */
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-link-preview {display:block; height:auto; max-height:18px; margin:4px 0 0 4px; font-size:13px; font-weight:normal; font-family:inherit; color:#666; background-color:transparent; overflow:hidden; text-overflow:ellipsis; word-break:break-all; white-space:pre;}
+/* .sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-mention-item {line-height:28px;min-height:25px;padding:0 5px;cursor:pointer;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-mention-item:hover {background-color:#e1e1e1}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-mention-item.se-mention-active {background-color: #d1d1d1; border-radius:3px;}
+.sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-mention-search {margin-bottom: 10px;} */
+
+/** --- controller ---------------------------------------------------------- */
+.sun-editor .se-controller .se-arrow.se-arrow-up {border-bottom-color:rgba(0, 0, 0, .25);}
+.sun-editor .se-controller {position:absolute; display:none; overflow:visible; z-index:6; border:1px solid rgba(0, 0, 0, .25); border-radius:4px; text-align:start; text-decoration:none; text-shadow:none; text-transform:none; letter-spacing:normal; word-break:normal; word-spacing:normal; word-wrap:normal; white-space:normal; background-color:#fff; -webkit-background-clip:padding-box; background-clip:padding-box; -webkit-box-shadow:0 5px 10px rgba(0, 0, 0, .2); box-shadow:0 5px 10px rgba(0, 0, 0, .2); line-break:auto;}
+
+/* controller - button group */
+.sun-editor .se-controller .se-btn-group {position:relative; display:flex; vertical-align:middle; padding:2px; top:0; left:0;}
+.sun-editor .se-controller .se-btn-group .se-btn-group-sub {left:50%; min-width:auto; width:max-content; display:none;/* display: inline-table; */}
+.sun-editor .se-controller .se-btn-group .se-btn-group-sub button {margin:0; min-width:72px;}
+.sun-editor .se-controller .se-btn-group button {position:relative; min-height:34px; height:auto; border:none; border-radius:4px; margin:1px; padding:5px 10px; font-size:12px; line-height:1.5; display:inline-block; font-weight:normal; text-align:center; white-space:nowrap; vertical-align:middle; -ms-touch-action:manipulation; touch-action:manipulation;}
+.sun-editor .se-controller .se-btn-group button:hover:enabled, .sun-editor .se-controller .se-btn-group button:focus:enabled {background-color:#e1e1e1; border-color:#d1d1d1; outline:0 none;}
+.sun-editor .se-controller .se-btn-group button:active:enabled {background-color:#d1d1d1; border-color:#c1c1c1; -webkit-box-shadow:inset 0 3px 5px #c1c1c1; box-shadow:inset 0 3px 5px #c1c1c1;}
+.sun-editor .se-controller .se-btn-group button span {display:block; padding:0; margin:0;}
+/* controller - buttn group active */
+.sun-editor .se-controller .se-btn-group button:enabled.active {color:#4592ff; outline:0 none;}
+.sun-editor .se-controller .se-btn-group button:enabled.active:hover, .sun-editor .se-controller .se-btn-group button:enabled.active:focus {background-color:#e1e1e1; border-color:#d1d1d1; outline:0 none;}
+.sun-editor .se-controller .se-btn-group button:enabled.active:active {background-color:#d1d1d1; border-color:#c1c1c1; -webkit-box-shadow:inset 0 3px 5px #c1c1c1; box-shadow:inset 0 3px 5px #c1c1c1;}
+/* controller - buttn group on */
+.sun-editor .se-controller .se-btn-group button:enabled.on {background-color:#e1e1e1; border-color:#d1d1d1; outline:0 none;}
+.sun-editor .se-controller .se-btn-group button:enabled.on:hover, .sun-editor .se-controller .se-btn-group button:enabled.on:focus {background-color:#d1d1d1; border-color:#c1c1c1; outline:0 none;}
+.sun-editor .se-controller .se-btn-group button:enabled.on:active {background-color:#c1c1c1; border-color:#b1b1b1; -webkit-box-shadow:inset 0 3px 5px #b1b1b1; box-shadow:inset 0 3px 5px #b1b1b1;}
+
+/* controller - resizing(image, iframe) */
+.sun-editor .se-controller-resizing {margin-top:-50px !important; padding:0; font-size:14px; font-style:normal; font-weight:normal; line-height:1.42857143;}
+.sun-editor .se-controller-resizing .se-btn-group .se-btn-group-sub.se-resizing-align-list {width:74px;}
+.sun-editor .se-resizing-container {position:absolute; display:none; outline:1px solid #3f9dff; background-color:transparent;}
+.sun-editor .se-resizing-container .se-modal-resize {position:absolute; display:inline-block; background-color:#3f9dff; opacity:0.3;}
+.sun-editor .se-resizing-container .se-resize-dot {position:absolute; top:0px; left:0px; width:100%; height:100%}
+.sun-editor .se-resizing-container .se-resize-dot > span {position:absolute; width:7px; height:7px; background-color:#3f9dff; border:1px solid #4592ff;}
+.sun-editor .se-resizing-container .se-resize-dot > span.tl {top:-5px; left:-5px; cursor:nw-resize;}
+.sun-editor .se-resizing-container .se-resize-dot > span.tr {top:-5px; right:-5px; cursor:ne-resize;}
+.sun-editor .se-resizing-container .se-resize-dot > span.bl {bottom:-5px; left:-5px; cursor:sw-resize;}
+.sun-editor .se-resizing-container .se-resize-dot > span.br {right:-5px; bottom:-5px; cursor:se-resize;}
+.sun-editor .se-resizing-container .se-resize-dot > span.lw {left:-7px; bottom:50%; cursor:w-resize;}
+.sun-editor .se-resizing-container .se-resize-dot > span.th {left:50%; top:-7px; cursor:n-resize;}
+.sun-editor .se-resizing-container .se-resize-dot > span.rw {right:-7px; bottom:50%; cursor:e-resize;}
+.sun-editor .se-resizing-container .se-resize-dot > span.bh {right:50%; bottom:-7px; cursor:s-resize;}
+.sun-editor .se-resizing-container .se-resize-display {position:absolute; right:0; bottom:0; padding:5px; margin:5px; font-size:12px; color:#fff; background-color:#333; border-radius:4px;}
+/* controller - table */
+.sun-editor .se-controller-table {width:auto; padding:0; font-size:14px; font-style:normal; font-weight:normal; line-height:1.42857143;}
+.sun-editor .se-controller-table-cell {width:auto; padding:0; font-size:14px; font-style:normal; font-weight:normal; line-height:1.42857143;}
+/* controller - link */
+.sun-editor .se-controller-link {padding:0; font-size:14px; font-style:normal; font-weight:normal; line-height:1.42857143;}
+.sun-editor .se-controller-link::before, .sun-editor .se-controller-link::after {-webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box;}
+.sun-editor .se-controller-link .link-content {padding:0; margin:0;}
+.sun-editor .se-controller-link .link-content a {display:inline-block; color:#4592ff; max-width:200px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; vertical-align:middle; margin-left:5px;}
+
+/* --- browser ---------------------------------------------------------- */
+.sun-editor .se-file-browser {position:absolute; display:none; top:0; left:0; width:100%; height:100%; z-index:2147483647;}
+.sun-editor .se-file-browser label, .sun-editor .se-file-browser input, .sun-editor .se-file-browser button {font-size:14px; line-height:1.5; color:#111; margin:0;}
+.sun-editor .se-file-browser .se-file-browser-back {position:absolute; display:block; width:100%; height:100%; top:0; left:0; background-color:#222; opacity:0.5;}
+.sun-editor .se-file-browser .se-file-browser-inner {position:absolute; display:block; width:100%; height:100%; top:0; left:0;}
+.sun-editor .se-file-browser .se-file-browser-inner .se-file-browser-content {position:relative; width:960px; max-width:100%; margin:20px auto; background-color:#fff; -webkit-background-clip:padding-box; background-clip:padding-box; border:1px solid rgba(0, 0, 0, .2); border-radius:4px; outline:0; -webkit-box-shadow:0 3px 9px rgba(0, 0, 0, .5); box-shadow:0 3px 9px rgba(0, 0, 0, .5);}
+/* --- browser - header */
+.sun-editor .se-file-browser .se-file-browser-header {height:auto; min-height:50px; padding:6px 15px 6px 15px; border-bottom:1px solid #e5e5e5;}
+.sun-editor .se-file-browser .se-file-browser-header .se-file-browser-close {float:right; font-weight:bold; text-shadow:0 1px 0 #fff; -webkit-appearance:none; filter:alpha(opacity=100); opacity:1;}
+.sun-editor .se-file-browser .se-file-browser-header .se-file-browser-close > svg {width:12px; height:12px;}
+.sun-editor .se-file-browser .se-file-browser-header .se-file-browser-title {font-size:16px; font-weight:bold; margin:0; padding:0; line-height:2.2;}
+/* --- browser - header - tags */
+.sun-editor .se-file-browser .se-file-browser-tags {display:block; width:100%; padding:0; text-align:left; margin:0 -15px;}
+.sun-editor .se-file-browser .se-file-browser-tags a {display:inline-block; background-color:#f5f5f5; padding:6px 12px; margin:8px 0 8px 8px; color:#333; text-decoration:none; border-radius:32px; -moz-border-radius:32px; -webkit-border-radius:32px; -moz-background-clip:padding; -webkit-background-clip:padding-box; background-clip:padding-box; cursor:pointer;}
+.sun-editor .se-file-browser .se-file-browser-tags a:hover {background-color:#e1e1e1;}
+.sun-editor .se-file-browser .se-file-browser-tags a:active {background-color:#d1d1d1;}
+.sun-editor .se-file-browser .se-file-browser-tags a.on {background-color:#ebf3fe; color:#4592ff;}
+.sun-editor .se-file-browser .se-file-browser-tags a.on:hover {background-color:#d8e8fe;}
+.sun-editor .se-file-browser .se-file-browser-tags a.on:active {background-color:#c7deff;}
+/* --- browser - body */
+.sun-editor .se-file-browser .se-file-browser-body {position:relative; height:auto; min-height:350px; padding:20px; overflow-y:auto;}
+.sun-editor .se-file-browser .se-file-browser-body .se-file-browser-list {position:relative; width:100%;}
+@media screen and (max-width:992px) { .sun-editor .se-file-browser .se-file-browser-inner .se-file-browser-content {width:748px;} }
+@media screen and (max-width:768px) { .sun-editor .se-file-browser .se-file-browser-inner .se-file-browser-content {width:600px;} }
+/* --- browser - column */
+.sun-editor .se-file-browser .se-file-browser-list .se-file-item-column {position:relative; display:block; height:auto; float:left;}
+
+/* --- browser --- custom - "se-image-list" - column */
+.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-column {width:calc(25% - 20px); margin:0 10px;}
+@media screen and (max-width:992px) { .sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-column {width:calc(33% - 20px);} }
+@media screen and (max-width:768px) { .sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-column {width:calc(50% - 20px);} }
+/* --- browser --- custom - "se-image-list" - item */
+.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img {position:relative; display:block; cursor: pointer; width:100%; height:auto; border-radius:4px; outline:0; margin:10px 0;}
+.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img:hover {opacity:0.8; -webkit-box-shadow:0 0 0 0.2rem #3288ff; box-shadow:0 0 0 0.2rem #3288ff;}
+.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img > img {position:relative; display:block; width:100%; border-radius:4px; outline:0; height:auto;}
+.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img > .se-file-img-name {position: absolute; z-index:1; font-size:13px; color:#fff; left:0px; bottom:0; padding:5px 10px; background-color:transparent; width:100%; height:30px; border-bottom-right-radius:4px; border-bottom-left-radius:4px;}
+.sun-editor .se-file-browser .se-file-browser-list.se-image-list .se-file-item-img > .se-file-img-name.se-file-name-back {background-color:#333; opacity:0.6;}
+
+/** --- notice */
+.sun-editor .se-notice {position:absolute; top:0; display:none; z-index:7; width:100%; height:auto; word-break:break-all; font-size:13px; color:#b94a48; background-color:#f2dede; padding:15px; margin:0; border:1px solid #eed3d7; user-select:text; -o-user-select:text; -moz-user-select:text; -khtml-user-select:text; -webkit-user-select:text; -ms-user-select:text;}
+.sun-editor .se-notice button {float:right; padding:7px;}
+
+/** --- tooltip */
+.sun-editor .se-tooltip {position:relative; overflow:visible;}
+.sun-editor .se-tooltip .se-tooltip-inner {visibility:hidden; position:absolute; display:block; width:auto; top:120%; left:50%; background:transparent; opacity:0; z-index:1; line-height:1.5; transition:opacity 0.5s; margin:0; padding:0; bottom:auto; float:none; pointer-events:none; backface-visibility:hidden; -webkit-backface-visibility:hidden; -moz-backface-visibility:hidden;}
+.sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text {position:relative; display:inline-block; width:auto; left:-50%; font-size:0.9em; margin:0; padding:4px 6px; border-radius:2px; background-color:#333; color:#fff; text-align:center; line-height:unset; white-space:nowrap; cursor:auto;}
+.sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text::after {content:""; position:absolute; bottom:100%; left:50%; margin-left:-5px; border-width:5px; border-style:solid; border-color:transparent transparent #333 transparent;}
+.sun-editor .se-tooltip:hover .se-tooltip-inner {visibility:visible; opacity:1;}
+.sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text .se-shortcut {display:block !important;}
+.sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text .se-shortcut > .se-shortcut-key {display:inline; font-weight:bold;}
+
+
+/** --- RTL ---------------------------------------------------------- */
+/* tray */
+.sun-editor.se-rtl .se-btn-tray {direction:rtl;}
+
+/* button--- */
+/* button - select text */
+.sun-editor.se-rtl .se-btn-select .txt {flex:auto; text-align:right; direction:rtl;}
+/* button - se-menu-list */
+.sun-editor.se-rtl .se-btn-list {text-align:right;}
+.sun-editor.se-rtl .se-btn-list > .se-list-icon {margin:-1px 0 0 10px;}
+/* button - se-menu-list - li */
+.sun-editor.se-rtl .se-menu-list {float:right;}
+.sun-editor.se-rtl .se-menu-list li {float:right;}
+
+/* menu list--- */
+.sun-editor.se-rtl .se-list-layer * {direction:rtl;}
+/* menu list - format block */
+.sun-editor.se-rtl .se-list-layer.se-list-format ul blockquote {padding:0 7px 0 0; border-right-width:5px; border-left-width:0;}
+/* menu list - color picker */
+.sun-editor.se-rtl .se-list-layer .se-selector-color .se-color-pallet li {float:right;}
+
+/* placeholder */
+.sun-editor.se-rtl .se-wrapper .se-placeholder {direction:rtl;}
+
+/* tooltip */
+.sun-editor.se-rtl .se-tooltip .se-tooltip-inner .se-tooltip-text {direction:rtl;}
+.sun-editor.se-rtl .se-tooltip .se-tooltip-inner .se-tooltip-text .se-shortcut {direction:ltr;}
+
+/* dialog--- */
+.sun-editor.se-rtl .se-dialog * {direction:rtl;}
+/* dialog - header */
+.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-header .se-dialog-close {float:left;}
+.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-header .se-modal-title {float:right;}
+/* dialog - tabs */
+.sun-editor.se-rtl .se-dialog-tabs button {float:right;}
+.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-size-text {padding-right:34px;}
+/* dialog - footer */
+.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-content .se-btn-primary {float:left}
+.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-footer > div {float:right;}
+.sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-footer > div > label {margin:0 0 0 5px;}
+
+/* fileBrowser--- */
+.sun-editor.se-rtl .se-file-browser * {direction:rtl;}
+/* fileBrowser - header */
+.sun-editor.se-rtl .se-file-browser .se-file-browser-tags {text-align:right;}
+.sun-editor.se-rtl .se-file-browser .se-file-browser-tags a {margin: 8px 8px 0 8px;}
+.sun-editor.se-rtl .se-file-browser .se-file-browser-header .se-file-browser-close {float:left;}
+
+/** controller--- */
+.sun-editor.se-rtl .se-controller .se-btn-group {direction:rtl;}
+/** --- RTL ---------------------------------------------------------- */
+
+
+/** animation */
+@keyframes blinker { 50% {opacity:0;} }
+@keyframes spinner { to {transform:rotate(361deg);} }
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2020 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ // rtl icon
+ rtl: {
+ italic: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10.5 15.8" xml:space="preserve"><g><path d="M0.3,0.1c0.3,0,0.5,0,0.7,0c1,0.1,1.7,0.1,2.2,0.1H4L7.2,0l0.2,1.1H7c-0.5,0-1,0.1-1.5,0.3v0.4l0.3,1.9L6,4.4L6.3,6 l0.1,0.4l0.1,0.5c0.1,0.2,0.1,0.4,0.2,0.7s0.1,0.6,0.2,0.9L7,9.1l0.6,2.8l0.3,1.4c0.1,0.4,0.2,0.7,0.4,1c0.4,0.2,0.8,0.3,1.2,0.4 l0.8,0.2l0.2,0.9l-1.1,0c-0.9-0.1-1.5-0.1-1.8-0.1h-2c-0.9,0.1-1.4,0.2-1.5,0.2c-0.1,0-0.2,0-0.3,0H3.4c-0.1,0-0.2,0-0.2,0 l-0.1-0.4c0-0.2-0.1-0.4-0.1-0.6l0.7-0.1c0.4,0,0.8-0.1,1.2-0.2c0-0.1,0-0.2,0-0.3l-0.1-0.5l-0.4-2.4L4,9.6L3.4,6.4 C3.2,5.7,3,4.7,2.7,3.3c0-0.3-0.1-0.5-0.1-0.8C2.5,2.1,2.4,1.9,2.3,1.6C2,1.4,1.6,1.3,1.3,1.2C0.9,1.2,0.5,1.1,0.2,0.9L0,0.4L0,0 L0.3,0.1L0.3,0.1z"/></g></svg>',
+ indent: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 12.4" xml:space="preserve"><g><g><path d="M15.5,10.1L15.5,10.1c0.1,0,0.3,0.1,0.3,0.3v1.7c0,0.1,0,0.1-0.1,0.2c-0.1,0.1-0.1,0.1-0.2,0.1l-15.2,0 c-0.1,0-0.1,0-0.2-0.1C0,12.2,0,12.2,0,12.1l0-1.7c0-0.1,0-0.1,0.1-0.2c0.1-0.1,0.1-0.1,0.2-0.1C0.3,10.1,15.5,10.1,15.5,10.1z M9.8,6.7c0.1,0,0.1,0,0.2,0.1C10.1,6.9,10.1,7,10.1,7v1.7c0,0.1,0,0.2-0.1,0.2C10,9,9.9,9,9.8,9L0.3,9C0.2,9,0.1,9,0.1,8.9 C0,8.9,0,8.8,0,8.7V7C0,7,0,6.9,0.1,6.8c0.1-0.1,0.1-0.1,0.2-0.1C0.3,6.7,9.8,6.7,9.8,6.7z M0.3,3.4h9.6h0c0.1,0,0.3,0.1,0.3,0.3 v1.7v0c0,0.1-0.1,0.3-0.3,0.3H0.3c-0.1,0-0.1,0-0.2-0.1C0,5.5,0,5.4,0,5.3V3.6c0-0.1,0-0.1,0.1-0.2C0.1,3.4,0.2,3.4,0.3,3.4 L0.3,3.4z M0.3,0l15.2,0c0.1,0,0.1,0,0.2,0.1c0.1,0.1,0.1,0.1,0.1,0.2V2c0,0.1,0,0.2-0.1,0.2c-0.1,0.1-0.1,0.1-0.2,0.1H0.3 c-0.1,0-0.1,0-0.2-0.1C0,2.1,0,2,0,2l0-1.7c0-0.1,0-0.1,0.1-0.2C0.1,0,0.2,0,0.3,0z"/></g><path d="M13.1,3.5L15.7,6c0.1,0.1,0.1,0.3,0,0.4l-2.5,2.5C13.1,9,13,9,12.9,9c-0.1,0-0.1,0-0.2-0.1c-0.1-0.1-0.1-0.1-0.1-0.2V3.7 c0-0.1,0-0.2,0.1-0.2c0.1-0.1,0.1-0.1,0.2-0.1C13,3.4,13.1,3.4,13.1,3.5z"/></g></svg>',
+ outdent: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 12.4" xml:space="preserve"><g><g><path d="M15.5,10.1L15.5,10.1c0.1,0,0.3,0.1,0.3,0.3v1.7c0,0.1,0,0.1-0.1,0.2c-0.1,0.1-0.1,0.1-0.2,0.1l-15.2,0 c-0.1,0-0.1,0-0.2-0.1C0,12.2,0,12.2,0,12.1l0-1.7c0-0.1,0-0.1,0.1-0.2c0.1-0.1,0.1-0.1,0.2-0.1C0.3,10.1,15.5,10.1,15.5,10.1z M9.8,6.7c0.1,0,0.1,0,0.2,0.1C10.1,6.9,10.1,7,10.1,7v1.7c0,0.1,0,0.2-0.1,0.2C10,9,9.9,9,9.8,9L0.3,9C0.2,9,0.1,9,0.1,8.9 C0,8.9,0,8.8,0,8.7V7C0,7,0,6.9,0.1,6.8c0.1-0.1,0.1-0.1,0.2-0.1C0.3,6.7,9.8,6.7,9.8,6.7z M0.3,3.4h9.6h0c0.1,0,0.3,0.1,0.3,0.3 v1.7v0c0,0.1-0.1,0.3-0.3,0.3H0.3c-0.1,0-0.1,0-0.2-0.1C0,5.5,0,5.4,0,5.3V3.6c0-0.1,0-0.1,0.1-0.2C0.1,3.4,0.2,3.4,0.3,3.4 L0.3,3.4z M0.3,0l15.2,0c0.1,0,0.1,0,0.2,0.1c0.1,0.1,0.1,0.1,0.1,0.2V2c0,0.1,0,0.2-0.1,0.2c-0.1,0.1-0.1,0.1-0.2,0.1H0.3 c-0.1,0-0.1,0-0.2-0.1C0,2.1,0,2,0,2l0-1.7c0-0.1,0-0.1,0.1-0.2C0.1,0,0.2,0,0.3,0z"/></g><path d="M15.5,3.4c0.1,0,0.1,0,0.2,0.1c0.1,0.1,0.1,0.1,0.1,0.2v5.1c0,0.1,0,0.1-0.1,0.2C15.6,9,15.5,9,15.5,9 c-0.1,0-0.1,0-0.2-0.1l-2.5-2.5c-0.1-0.1-0.1-0.3,0-0.4l2.5-2.5C15.3,3.4,15.4,3.4,15.5,3.4z"/></g></svg>',
+ list_bullets: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 12.4" xml:space="preserve"><g><path d="M12.4,10.7c0,0.9,0.8,1.7,1.7,1.7c0.9,0,1.7-0.8,1.7-1.7C15.7,9.8,15,9,14.1,9c-0.4,0-0.9,0.2-1.2,0.5 C12.5,9.8,12.4,10.2,12.4,10.7C12.4,10.7,12.4,10.7,12.4,10.7z M12.4,6.2c0,0.9,0.8,1.7,1.7,1.7c0.4,0,0.9-0.2,1.2-0.5 c0.3-0.3,0.4-0.7,0.4-1.1c0-0.9-0.7-1.7-1.6-1.7C13.1,4.6,12.4,5.3,12.4,6.2C12.4,6.2,12.4,6.2,12.4,6.2z M0,9.8v1.7 c0,0.1,0,0.1,0.1,0.2c0.1,0.1,0.1,0.1,0.2,0.1l10.7,0c0,0,0,0,0,0c0.1,0,0.3-0.1,0.3-0.3V9.8c0-0.1,0-0.1-0.1-0.2 C11.1,9.6,11,9.6,11,9.6l-10.7,0c-0.1,0-0.1,0-0.2,0.1C0,9.7,0,9.8,0,9.8L0,9.8z M12.9,2.9c0.3,0.3,0.7,0.5,1.2,0.5 c0.4,0,0.9-0.2,1.2-0.5c0.7-0.7,0.7-1.7,0-2.4C14.9,0.2,14.5,0,14.1,0c-0.4,0-0.9,0.2-1.2,0.5c-0.3,0.3-0.5,0.7-0.5,1.2 C12.4,2.1,12.5,2.6,12.9,2.9z M0,5.3V7c0,0.1,0,0.1,0.1,0.2c0.1,0.1,0.1,0.1,0.2,0.1H11c0.1,0,0.1,0,0.2-0.1 c0.1-0.1,0.1-0.1,0.1-0.2V5.3c0,0,0,0,0,0c0-0.1-0.1-0.3-0.3-0.3H0.3c-0.1,0-0.1,0-0.2,0.1C0,5.2,0,5.3,0,5.3L0,5.3z M0,0.8v1.7 c0,0.1,0,0.1,0.1,0.2c0.1,0.1,0.1,0.1,0.2,0.1h10.7c0.1,0,0.1,0,0.2-0.1c0,0,0.1-0.1,0.1-0.2V0.8c0-0.1,0-0.1-0.1-0.2 c0-0.1-0.1-0.1-0.2-0.1H0.3c-0.1,0-0.1,0-0.2,0.1C0,0.7,0,0.8,0,0.8L0,0.8z"/></g></svg>',
+ list_number: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 15.7" xml:space="preserve"><g><path d="M0,11.5l0,1.7c0,0.1,0,0.1,0.1,0.2c0.1,0.1,0.1,0.1,0.2,0.1H11c0.1,0,0.2,0,0.2-0.1c0.1-0.1,0.1-0.1,0.1-0.2v-1.7 c0-0.1,0-0.1-0.1-0.2c-0.1-0.1-0.1-0.1-0.2-0.1H0.3c-0.1,0-0.2,0-0.2,0.1C0,11.4,0,11.4,0,11.5L0,11.5z M0,8.7c0,0.1,0,0.1,0.1,0.2 C0.1,8.9,0.2,9,0.3,9H11c0.1,0,0.2,0,0.2-0.1c0.1-0.1,0.1-0.1,0.1-0.2V7c0-0.1,0-0.1-0.1-0.2c-0.1-0.1-0.1-0.1-0.2-0.1l-10.7,0 c-0.1,0-0.2,0-0.2,0.1C0,6.8,0,6.9,0,7C0,7,0,8.7,0,8.7z M0,2.5v1.7c0,0.1,0,0.1,0.1,0.2c0,0,0.1,0.1,0.2,0.1l10.7,0 c0.1,0,0.2,0,0.2-0.1c0.1-0.1,0.1-0.1,0.1-0.2V2.4c0-0.1,0-0.1-0.1-0.2c-0.1,0-0.1,0-0.2,0H0.3c-0.1,0-0.1,0-0.2,0 C0,2.3,0,2.4,0,2.5L0,2.5z"/></g><path d="M15.6,14.2c0-0.3-0.1-0.6-0.3-0.8c-0.2-0.2-0.4-0.4-0.7-0.4l0.9-1v-0.8h-2.9v1.3h0.9v-0.5h0.9l0,0c-0.1,0.1-0.2,0.2-0.3,0.3 s-0.2,0.3-0.4,0.5l-0.3,0.3l0.2,0.5c0.6,0,0.9,0.1,0.9,0.5c0,0.1-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.1-0.4,0.1c-0.3,0-0.7-0.1-0.9-0.3 l-0.5,0.8c0.4,0.4,0.9,0.6,1.5,0.6c0.4,0,0.9-0.1,1.2-0.4C15.5,15.1,15.6,14.7,15.6,14.2z"/><path d="M15.6,8.7h-0.9v0.5h-1.1c0-0.2,0.2-0.4,0.4-0.5c0.2-0.2,0.4-0.3,0.7-0.4c0.3-0.2,0.5-0.3,0.7-0.6c0.2-0.2,0.3-0.5,0.3-0.8 c0-0.4-0.2-0.8-0.5-1c-0.6-0.4-1.4-0.5-2-0.1c-0.3,0.2-0.5,0.4-0.6,0.7L13.3,7c0.1-0.3,0.4-0.5,0.7-0.5c0.1,0,0.3,0,0.3,0.1 c0.1,0.1,0.1,0.2,0.1,0.3c0,0.2-0.1,0.3-0.2,0.4c-0.2,0.1-0.3,0.3-0.5,0.4c-0.2,0.1-0.4,0.3-0.6,0.4c-0.2,0.2-0.4,0.4-0.5,0.6 c-0.1,0.2-0.2,0.5-0.2,0.8c0,0.2,0,0.3,0,0.5h3.2L15.6,8.7L15.6,8.7z"/><path d="M15.6,3.6h-1V0h-0.9l-1.2,1.1l0.6,0.7c0.2-0.1,0.3-0.3,0.4-0.5l0,0v2.2h-0.9v0.9h3L15.6,3.6L15.6,3.6z"/></svg>',
+ link: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 15.7" xml:space="preserve"><g><path d="M7.4,9.9l3.1,3.1c0.3,0.3,0.8,0.5,1.3,0.5c0.5,0,0.9-0.2,1.3-0.5c0,0,0,0,0,0c0.7-0.7,0.7-1.9,0-2.6L9.9,7.3 c0-0.1,0-0.2,0-0.3C9.9,7,10,7,10.1,7l2.2-0.2c0.1,0,0.1,0,0.2,0.1l2.1,2.1c0.4,0.4,0.7,0.8,0.9,1.3c0.2,0.5,0.3,1,0.3,1.5 c0,0.5-0.1,1-0.3,1.5c-0.8,2-3.2,3-5.2,2.2c-0.5-0.2-0.9-0.5-1.3-0.9l-2.1-2.1c-0.1,0-0.1-0.1-0.1-0.2L7,10.1C7,10,7,9.9,7.1,9.9 C7.2,9.8,7.3,9.9,7.4,9.9z M1.2,1.1C1.6,0.7,2,0.4,2.5,0.3c1-0.4,2.1-0.4,3.1,0C6,0.4,6.5,0.7,6.8,1.1L9,3.2C9,3.3,9.1,3.3,9,3.4 L8.8,5.6c0,0.1-0.1,0.2-0.2,0.2c-0.1,0.1-0.2,0.1-0.3,0L5.3,2.7C5,2.3,4.5,2.1,4,2.1c-0.5,0-0.9,0.2-1.3,0.5c0,0,0,0,0,0 C2,3.4,2,4.5,2.7,5.2l3.1,3.2c0.1,0.1,0.1,0.2,0,0.3c0,0.1-0.1,0.1-0.2,0.1L3.5,9C3.4,9,3.4,9,3.3,8.9L1.2,6.8c0,0,0,0,0,0 C-0.4,5.2-0.4,2.7,1.2,1.1L1.2,1.1z M14.3,6h-2.6c0,0,0,0,0,0c-0.1,0-0.2-0.1-0.2-0.2c0-0.1,0-0.2,0.1-0.3l2.5-0.7 c0.1,0,0.1,0,0.2,0c0.1,0,0.1,0.1,0.1,0.2l0.1,0.8c0,0.1,0,0.1-0.1,0.2C14.5,6,14.4,6,14.3,6L14.3,6z M10.2,4.1 c0,0.1-0.1,0.2-0.2,0.2l0,0c0,0,0,0,0,0C9.8,4.2,9.7,4.1,9.8,4L9.7,1.4c0-0.1,0-0.1,0.1-0.2c0.1,0,0.1,0,0.2,0h0.8 c0.1,0,0.1,0,0.2,0.1c0,0.1,0,0.1,0,0.2L10.2,4.1L10.2,4.1z M1.5,9.7h1.3h1.3c0.1,0,0.2,0.1,0.2,0.2c0,0.1,0,0.2-0.1,0.3l-2.5,0.6 H1.6c0,0-0.1,0-0.1,0c-0.1,0-0.1-0.1-0.1-0.2L1.2,9.9c0-0.1,0-0.1,0.1-0.2c0-0.1,0.1-0.1,0.2-0.1L1.5,9.7z M5.6,11.6 C5.6,11.6,5.6,11.6,5.6,11.6c0-0.1,0.1-0.2,0.3-0.1c0,0,0,0,0,0c0.1,0,0.2,0.1,0.2,0.2v2.6c0,0.1,0,0.1-0.1,0.2 c0,0-0.1,0.1-0.2,0.1L5,14.5c-0.1,0-0.1,0-0.2-0.1c0-0.1,0-0.1,0-0.2L5.6,11.6L5.6,11.6z"/></g></svg>',
+ unlink: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 15.7" xml:space="preserve"><g><path d="M14.6,14.6c1.6-1.6,1.6-4.1,0-5.7l0,0l-3.1-3.1l-1.2,1.6l2.9,2.9c0.4,0.4,0.6,0.9,0.6,1.5c0,1.1-0.9,2.1-2.1,2.1l0,0 c-0.6,0-1.1-0.2-1.5-0.6l-0.4-0.4l-1.7,1l0.8,0.8C10.4,16.2,13,16.2,14.6,14.6L14.6,14.6L14.6,14.6z M3.6,6C3,5.9,2.6,5.5,2.3,5 S1.9,4,2.1,3.4C2.3,2.9,2.6,2.5,3,2.2C3.5,2,4.1,1.9,4.6,2l3.3,1.4l0.5-2L5.1,0.1C4-0.1,2.9,0,2,0.5C1.1,1.1,0.4,1.9,0.2,3 C-0.1,4,0,5.1,0.6,6C1.1,6.9,1.9,7.6,3,7.8l5.4,2l0.5-2L6.2,6.9L3.6,6z"/></g></svg>'
+ },
+ // common, ltr icon
+ redo: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.59 14.18"><g><path d="M11.58,18.48a6.84,6.84,0,1,1,6.85-6.85s0,.26,0,.67a8,8,0,0,1-.22,1.44l.91-.55a.51.51,0,0,1,.36,0,.45.45,0,0,1,.29.22.47.47,0,0,1,.06.36.45.45,0,0,1-.22.29L17.42,15.3l-.12,0h-.25l-.12-.06-.09-.09-.06-.07,0-.06-.87-2.12a.43.43,0,0,1,0-.37.49.49,0,0,1,.27-.26.41.41,0,0,1,.36,0,.53.53,0,0,1,.27.26l.44,1.09a6.51,6.51,0,0,0,.24-1.36,4.58,4.58,0,0,0,0-.64,5.83,5.83,0,0,0-1.73-4.17,5.88,5.88,0,0,0-8.34,0,5.9,5.9,0,0,0,4.17,10.06.51.51,0,0,1,.33.15.48.48,0,0,1,0,.68.53.53,0,0,1-.33.12Z" transform="translate(-4.48 -4.54)"/></g></svg>',
+ undo: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.59 14.18"><g><path d="M5,14a.43.43,0,0,1-.22-.29.46.46,0,0,1,.06-.36.43.43,0,0,1,.29-.22.56.56,0,0,1,.36,0l.91.55a8.27,8.27,0,0,1-.22-1.45,5.07,5.07,0,0,1,0-.67A6.85,6.85,0,1,1,13,18.47a.44.44,0,0,1-.33-.13.48.48,0,0,1,0-.68.51.51,0,0,1,.33-.15A5.89,5.89,0,0,0,17.15,7.45a5.88,5.88,0,0,0-8.33,0,5.84,5.84,0,0,0-1.73,4.17s0,.25,0,.65a6.49,6.49,0,0,0,.24,1.37l.44-1.09a.57.57,0,0,1,.27-.26.41.41,0,0,1,.36,0,.53.53,0,0,1,.27.26.43.43,0,0,1,0,.37L7.82,15l0,.09-.09.09-.1.07-.06,0H7.28l-.13,0-1.09-.63c-.65-.36-1-.57-1.1-.63Z" transform="translate(-4.49 -4.53)"/></g></svg>',
+ bold: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11.76 15.75"><g><path d="M6.4,3.76V19.5h6.76a5.55,5.55,0,0,0,2-.32,4.93,4.93,0,0,0,1.52-1,4.27,4.27,0,0,0,1.48-3.34,3.87,3.87,0,0,0-.69-2.37,5.74,5.74,0,0,0-.71-.83,3.44,3.44,0,0,0-1.1-.65,3.6,3.6,0,0,0,1.58-1.36,3.66,3.66,0,0,0,.53-1.93,3.7,3.7,0,0,0-1.21-2.87,4.65,4.65,0,0,0-3.25-1.1H6.4Zm2.46,6.65V5.57h3.52a4.91,4.91,0,0,1,1.36.15,2.3,2.3,0,0,1,.85.45,2.06,2.06,0,0,1,.74,1.71,2.3,2.3,0,0,1-.78,1.92,2.54,2.54,0,0,1-.86.46,4.7,4.7,0,0,1-1.32.15H8.86Zm0,7.27V12.15H12.7a4.56,4.56,0,0,1,1.38.17,3.43,3.43,0,0,1,.95.49,2.29,2.29,0,0,1,.92,2,2.73,2.73,0,0,1-.83,2.1,2.66,2.66,0,0,1-.83.58,3.25,3.25,0,0,1-1.26.2H8.86Z" transform="translate(-6.4 -3.75)"/></g></svg>',
+ underline: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 9.78 15.74"><g><path d="M14.64,3.76h2.52v7.72a4.51,4.51,0,0,1-.59,2.31,3.76,3.76,0,0,1-1.71,1.53,6.12,6.12,0,0,1-2.64.53,5,5,0,0,1-3.57-1.18,4.17,4.17,0,0,1-1.27-3.24V3.76H9.9v7.3a3,3,0,0,0,.55,2,2.3,2.3,0,0,0,1.83.65,2.26,2.26,0,0,0,1.8-.65,3.09,3.09,0,0,0,.55-2V3.76Zm2.52,13.31V19.5H7.39V17.08h9.77Z" transform="translate(-7.38 -3.76)"/></g></svg>',
+ italic: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10.49 15.76"><g><path d="M17.16,3.79l.37,0-.06.38-.14.52A10,10,0,0,1,16.21,5a9.37,9.37,0,0,0-1,.32,6.68,6.68,0,0,0-.25.89c-.06.31-.11.59-.14.85-.3,1.36-.52,2.41-.68,3.14l-.61,3.18L13.1,15l-.43,2.4-.12.46a.62.62,0,0,0,0,.28c.44.1.85.17,1.23.22l.68.11a4.51,4.51,0,0,1-.08.6l-.09.42a.92.92,0,0,0-.23,0l-.43,0a1.37,1.37,0,0,1-.29,0c-.13,0-.63-.08-1.49-.16l-2,0c-.28,0-.87,0-1.78.12L7,19.5l.17-.88.8-.2A6.61,6.61,0,0,0,9.19,18,2.62,2.62,0,0,0,9.61,17l.28-1.41.58-2.75.12-.66c.05-.3.11-.58.17-.86s.12-.51.17-.69l.12-.48.12-.43.31-1.6.15-.65.31-1.91V5.14a3.86,3.86,0,0,0-1.48-.29l-.38,0,.2-1.06,3.24.14.75,0c.45,0,1.18,0,2.18-.09.23,0,.46,0,.71,0Z" transform="translate(-7.04 -3.76)"/></g></svg>',
+ strike: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 14.9"><g><path d="M12.94,13a4.27,4.27,0,0,1,1.32.58,1.46,1.46,0,0,1,.55,1.2,1.87,1.87,0,0,1-.88,1.64,4.17,4.17,0,0,1-2.35.59,4.44,4.44,0,0,1-2.74-.71,2.72,2.72,0,0,1-1-2.17H5.57a4.56,4.56,0,0,0,1.55,3.7,7,7,0,0,0,4.47,1.23,6,6,0,0,0,4.07-1.3,4.24,4.24,0,0,0,1.52-3.37,4,4,0,0,0-.26-1.4h-4ZM6.37,10.24A3.27,3.27,0,0,1,6,8.68a4,4,0,0,1,1.48-3.3,5.92,5.92,0,0,1,3.88-1.21,5.58,5.58,0,0,1,3.91,1.24,4.36,4.36,0,0,1,1.45,3.17H14.44a2.12,2.12,0,0,0-.91-1.81,4.45,4.45,0,0,0-2.44-.55,3.69,3.69,0,0,0-2,.51A1.64,1.64,0,0,0,8.3,8.22a1.3,1.3,0,0,0,.48,1.11,7,7,0,0,0,2.1.78l.28.06.28.08H6.37Zm13.09.68a.73.73,0,0,1,.49.21.66.66,0,0,1,.2.48.64.64,0,0,1-.2.48.71.71,0,0,1-.49.19H5.1a.67.67,0,0,1-.49-.19.66.66,0,0,1-.2-.48.64.64,0,0,1,.2-.48.73.73,0,0,1,.49-.21H19.46Z" transform="translate(-4.41 -4.17)"/></g></svg>',
+ subscript: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.75 14.61"><g><path d="M15.38,4.33H12.74L11.19,7c-.28.46-.51.87-.69,1.21L10.07,9h0l-.44-.8c-.22-.4-.45-.81-.71-1.23L7.34,4.33H4.68L8.26,10,4.4,16.08H7.1l1.69-2.83c.38-.63.72-1.22,1-1.78l.25-.46h0l.49.92c.24.45.48.89.74,1.32L13,16.08h2.61L11.84,10l1.77-2.84,1.77-2.85Zm4.77,13.75H17v-.15c0-.4.05-.64.16-.72a4.42,4.42,0,0,1,1.16-.31,3.3,3.3,0,0,0,1.54-.56A1.84,1.84,0,0,0,20.15,15a1.78,1.78,0,0,0-.44-1.41A2.8,2.8,0,0,0,18,13.25a2.71,2.71,0,0,0-1.69.37,1.83,1.83,0,0,0-.44,1.43v.23H17v-.23q0-.63.18-.78a1.62,1.62,0,0,1,.88-.15,1.59,1.59,0,0,1,.88.15q.18.15.18.75t-.18.75a3.58,3.58,0,0,1-1.18.33,3.33,3.33,0,0,0-1.52.51,1.57,1.57,0,0,0-.32,1.18v1.15h4.27v-.86Z" transform="translate(-4.4 -4.33)"/></g></svg>',
+ superscript: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.75 15.42"><g><path d="M12,13.14l3.61-5.81H12.94L11.33,10c-.28.46-.51.88-.69,1.25l-.45.83h0l-.45-.85c-.22-.41-.45-.82-.71-1.24L7.4,7.33H4.68l3.66,5.81L4.4,19.33H7.14l1.74-2.87q.58-1,1-1.83l.25-.48h0l.51.94.75,1.37,1.72,2.87h2.67l-1.92-3.09c-1.12-1.8-1.76-2.83-1.92-3.1Zm4.84-4.41h0l0,.15h3.27v.86H15.77V8.58a1.66,1.66,0,0,1,.33-1.22,3.51,3.51,0,0,1,1.56-.51,3.68,3.68,0,0,0,1.21-.34c.13-.1.19-.36.19-.77S19,5.07,18.87,5A1.63,1.63,0,0,0,18,4.8a1.58,1.58,0,0,0-.91.17c-.13.11-.19.38-.19.8V6H15.78V5.76a1.87,1.87,0,0,1,.45-1.47A2.84,2.84,0,0,1,18,3.91a2.8,2.8,0,0,1,1.72.38,1.84,1.84,0,0,1,.45,1.44,1.91,1.91,0,0,1-.34,1.35,3.24,3.24,0,0,1-1.58.57A3.69,3.69,0,0,0,17,8c-.12.1-.17.35-.17.76Z" transform="translate(-4.4 -3.91)"/></g></svg>',
+ erase: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 13.76"><g><path d="M13.69,17.2h6.46v1.31H8.56L4.41,14.37,14,4.75l6.06,6.06L16.89,14l-3.2,3.19Zm-4.61,0h2.77L14.09,15,9.88,10.75,6.25,14.38l1.41,1.41c.84.82,1.31,1.29,1.42,1.41Z" transform="translate(-4.41 -4.75)"/></g></svg>',
+ indent: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 12.36"><g><path d="M19.87,15.57a.27.27,0,0,1,.19.08.25.25,0,0,1,.08.19v1.69a.27.27,0,0,1-.08.19.25.25,0,0,1-.19.08H4.68a.27.27,0,0,1-.19-.08.25.25,0,0,1-.08-.19V15.84a.27.27,0,0,1,.27-.27H19.87ZM7.5,14.45a.25.25,0,0,1-.2-.09L4.76,11.84a.29.29,0,0,1,0-.4L7.3,8.9a.29.29,0,0,1,.4,0,.31.31,0,0,1,.07.2v5.06a.32.32,0,0,1-.08.21.26.26,0,0,1-.19.08ZM19.87,8.82a.27.27,0,0,1,.19.08.25.25,0,0,1,.08.19v1.69a.27.27,0,0,1-.08.19.25.25,0,0,1-.19.08H10.31a.27.27,0,0,1-.27-.27V9.1a.27.27,0,0,1,.27-.27h9.56Zm0,3.37a.27.27,0,0,1,.19.08.28.28,0,0,1,.08.21v1.68a.32.32,0,0,1-.08.21.25.25,0,0,1-.19.08H10.31a.27.27,0,0,1-.19-.08.3.3,0,0,1-.08-.21V12.48a.32.32,0,0,1,.08-.21.24.24,0,0,1,.19-.08h9.56Zm.2-6.66a.28.28,0,0,1,.08.2V7.41a.32.32,0,0,1-.08.21.25.25,0,0,1-.19.08H4.68a.27.27,0,0,1-.19-.08.3.3,0,0,1-.08-.21V5.73a.32.32,0,0,1,.08-.21.25.25,0,0,1,.19-.08H19.87a.28.28,0,0,1,.2.09Z" transform="translate(-4.41 -5.44)"/></g></svg>',
+ outdent: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 12.36"><g><path d="M4.68,14.45a.27.27,0,0,1-.19-.08.3.3,0,0,1-.08-.21V9.1a.27.27,0,0,1,.08-.19.28.28,0,0,1,.2-.08.25.25,0,0,1,.19.07l2.54,2.54a.29.29,0,0,1,0,.4L4.88,14.36a.24.24,0,0,1-.2.09Zm15.19,1.12a.27.27,0,0,1,.19.08.25.25,0,0,1,.08.19v1.69a.27.27,0,0,1-.08.19.25.25,0,0,1-.19.08H4.68a.27.27,0,0,1-.19-.08.25.25,0,0,1-.08-.19V15.84a.27.27,0,0,1,.27-.27H19.87Zm0-3.38a.27.27,0,0,1,.19.08.28.28,0,0,1,.08.21v1.68a.32.32,0,0,1-.08.21.25.25,0,0,1-.19.08H10.31a.27.27,0,0,1-.19-.08.3.3,0,0,1-.08-.21V12.48a.32.32,0,0,1,.08-.21.24.24,0,0,1,.19-.08h9.56Zm0-3.37a.27.27,0,0,1,.19.08.25.25,0,0,1,.08.19v1.69a.27.27,0,0,1-.08.19.25.25,0,0,1-.19.08H10.31a.27.27,0,0,1-.27-.27V9.1a.27.27,0,0,1,.27-.27h9.56Zm.2-3.29a.28.28,0,0,1,.08.2V7.41a.32.32,0,0,1-.08.21.25.25,0,0,1-.19.08H4.68a.27.27,0,0,1-.19-.08.3.3,0,0,1-.08-.21V5.73a.32.32,0,0,1,.08-.21.25.25,0,0,1,.19-.08H19.87a.28.28,0,0,1,.2.09Z" transform="translate(-4.41 -5.44)"/></g></svg>',
+ expansion: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.74"><g><path d="M11.8,13.06l-5.1,5.1H9.51V19.5H4.41V14.4H5.75v2.81L8.3,14.66q2.25-2.23,2.55-2.55Zm8.35-9.3v5.1H18.81V6.05l-5.1,5.1-1-1,5.1-5.1H15.05V3.76Z" transform="translate(-4.41 -3.76)"/></g></svg>',
+ reduction: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.74"><g><path d="M14.91,10h2.87v1.38H12.55V6.12h1.38V9l5.24-5.24.48.49.49.48ZM6.77,11.92H12v5.23H10.62V14.26L5.37,19.5l-1-1L9.63,13.3H6.77Z" transform="translate(-4.4 -3.76)"/></g></svg>',
+ code_view: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.73 11.8"><g><path d="M8.09,7.94a.76.76,0,0,1,.53.22.72.72,0,0,1,.21.52.76.76,0,0,1-.22.54L6.18,11.63l2.43,2.44a.69.69,0,0,1,.2.51.66.66,0,0,1-.21.51.75.75,0,0,1-.51.22.63.63,0,0,1-.51-.21h0L4.63,12.15a.7.7,0,0,1-.22-.53.67.67,0,0,1,.25-.55L7.57,8.16a.82.82,0,0,1,.52-.22Zm12.05,3.69a.7.7,0,0,1-.23.52L17,15.1h0a.66.66,0,0,1-.51.21.73.73,0,0,1-.51-.22.75.75,0,0,1-.22-.51.63.63,0,0,1,.21-.51l2.43-2.44L15.92,9.22a.73.73,0,0,1-.22-.53A.74.74,0,0,1,17,8.18h0l2.91,2.91a.67.67,0,0,1,.27.54Zm-5.9-5.9a.73.73,0,0,1,.61.32.71.71,0,0,1,.07.68L11,17a1,1,0,0,1-.22.32.6.6,0,0,1-.35.16.75.75,0,0,1-.69-.26.69.69,0,0,1-.12-.72L13.56,6.23a.75.75,0,0,1,.26-.35.74.74,0,0,1,.42-.15Z" transform="translate(-4.41 -5.73)"/></g></svg>',
+ preview: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.65 15.66"><g><path d="M16.19,14.43l2.49,2.49a.73.73,0,0,1,.21.52.67.67,0,0,1-.22.51.7.7,0,0,1-.52.22.69.69,0,0,1-.51-.21l-2.49-2.48a5.17,5.17,0,0,1-1.34.69,4.64,4.64,0,0,1-1.48.24,4.78,4.78,0,1,1,0-9.56,4.79,4.79,0,0,1,1.84.36,4.9,4.9,0,0,1,1.56,1,4.77,4.77,0,0,1,.46,6.18ZM10,14a3.3,3.3,0,0,0,2.34.93A3.37,3.37,0,0,0,14.7,14a3.3,3.3,0,0,0-1.08-5.41,3.47,3.47,0,0,0-2.56,0A3,3,0,0,0,10,9.28,3.31,3.31,0,0,0,10,14ZM16,4a3.86,3.86,0,0,1,2.77,1.14A3.9,3.9,0,0,1,20,7.85v4a.77.77,0,0,1-.22.53.7.7,0,0,1-.52.21.72.72,0,0,1-.74-.74v-4a2.46,2.46,0,0,0-.72-1.73A2.37,2.37,0,0,0,16,5.45H8.53A2.42,2.42,0,0,0,6.08,7.89v7.52a2.41,2.41,0,0,0,.71,1.73,2.46,2.46,0,0,0,1.74.72h4.08a.73.73,0,0,1,0,1.46H8.53a3.85,3.85,0,0,1-2.78-1.14A3.93,3.93,0,0,1,4.6,15.4V7.87A3.94,3.94,0,0,1,5.76,5.09,3.88,3.88,0,0,1,8.54,4H16Z" transform="translate(-4.45 -3.8)"/></g></svg>',
+ print: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16.05 16.04"><g><path d="M19.76,15.84a1.29,1.29,0,0,0,.39-.92V8.35A2.05,2.05,0,0,0,19.57,7a1.93,1.93,0,0,0-1.38-.57H6.37a1.95,1.95,0,0,0-2,2v6.56a1.23,1.23,0,0,0,.38.92,1.35,1.35,0,0,0,.93.38h2V14.9l-2,0V8.35a.67.67,0,0,1,.18-.47.62.62,0,0,1,.48-.19H18.18a.6.6,0,0,1,.46.19.66.66,0,0,1,.18.47V14.9h-2v1.32h2A1.35,1.35,0,0,0,19.76,15.84ZM17.52,7.69V5.06a1.31,1.31,0,0,0-.38-.92,1.34,1.34,0,0,0-.94-.38H8.34A1.3,1.3,0,0,0,7,5.06V7.69H8.34V5.06h7.87V7.69h1.31ZM8.34,12.93h7.87l0,5.26H8.34V12.93Zm7.87,5.26v0Zm.65,1.31a.6.6,0,0,0,.46-.19.72.72,0,0,0,.2-.47V12.29a.74.74,0,0,0-.2-.47.6.6,0,0,0-.46-.19H7.68a.6.6,0,0,0-.46.19.72.72,0,0,0-.2.47v6.55a.74.74,0,0,0,.2.47.6.6,0,0,0,.46.19h9.18ZM16.67,9.28a.7.7,0,0,0-.94,0,.63.63,0,0,0-.18.46.67.67,0,0,0,.18.47.68.68,0,0,0,.94,0,.66.66,0,0,0,.18-.47A.58.58,0,0,0,16.67,9.28Z" transform="translate(-4.25 -3.61)"/></g></svg>',
+ template: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14.27 15.64"><g><path d="M18.18,19.16a1,1,0,0,0,1-1V5.73a1,1,0,0,0-1-1h-2v1h2V18.19H6.37V5.73h2v-1h-2A.94.94,0,0,0,5.68,5a1,1,0,0,0-.29.7V18.18a.94.94,0,0,0,.29.69,1,1,0,0,0,.69.29H18.18ZM9.82,10.31h4.92a.49.49,0,0,0,.35-.15.47.47,0,0,0,.15-.35.49.49,0,0,0-.15-.35.47.47,0,0,0-.35-.15H9.82a.49.49,0,0,0-.35.15.47.47,0,0,0-.15.35.49.49,0,0,0,.15.35.47.47,0,0,0,.35.15Zm5.9,4.92H8.83a.49.49,0,0,0-.35.15.47.47,0,0,0-.15.35.49.49,0,0,0,.15.35.47.47,0,0,0,.35.15h6.89a.49.49,0,0,0,.35-.15.47.47,0,0,0,.15-.35.51.51,0,0,0-.5-.5ZM7.36,12.77a.49.49,0,0,0,.15.35.47.47,0,0,0,.35.15h8.85a.49.49,0,0,0,.35-.15.47.47,0,0,0,.15-.35.49.49,0,0,0-.15-.35.47.47,0,0,0-.35-.15H7.85a.49.49,0,0,0-.35.15.52.52,0,0,0-.14.35Z" transform="translate(-5.14 -3.77)"/><path d="M14.24,6.71a1,1,0,0,0,1-1,1,1,0,0,0-1-1,1,1,0,0,0-1-1h-2a.94.94,0,0,0-.69.28,1,1,0,0,0-.29.7A.94.94,0,0,0,9.62,5a.91.91,0,0,0-.29.69,1,1,0,0,0,.29.7,1,1,0,0,0,.69.29h3.93Z" transform="translate(-5.14 -3.77)"/></g></svg>',
+ line_height: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.76 13.56"><g><path d="M4.4,4.88V8.26a2,2,0,0,0,.5.39s.1,0,.18-.12a.62.62,0,0,0,.17-.28c.06-.19.13-.44.21-.74s.14-.52.19-.66a.58.58,0,0,1,.21-.3,2.41,2.41,0,0,1,.63-.21,3.83,3.83,0,0,1,.88-.12,9.15,9.15,0,0,1,1.31.06.16.16,0,0,1,.11,0,.26.26,0,0,1,.06.14,4,4,0,0,1,0,.49v2l.05,3.77c0,1.41,0,2.68-.05,3.81a1.79,1.79,0,0,1-.11.49,10.68,10.68,0,0,1-1.4.45,1.12,1.12,0,0,0-.69.43v.31l0,.22.61,0c.85-.08,1.54-.12,2.06-.12a19.76,19.76,0,0,1,2.09.08,15.08,15.08,0,0,0,1.64.08,1.4,1.4,0,0,0,.29,0,1.58,1.58,0,0,0,0-.26l-.05-.43a2.26,2.26,0,0,0-.43-.17l-.77-.22-.15,0a2.55,2.55,0,0,1-.78-.28,2.56,2.56,0,0,1-.11-.75l0-1.29,0-3.15V7.53a10.51,10.51,0,0,1,.06-1.2,3.83,3.83,0,0,1,.6,0l1.88,0a2.18,2.18,0,0,1,.38,0,.45.45,0,0,1,.23.17.9.9,0,0,1,.05.25c0,.16.06.35.1.58a3.33,3.33,0,0,0,.14.55A6.39,6.39,0,0,0,15,9a2.91,2.91,0,0,0,.6-.15,2.77,2.77,0,0,0,0-.46l0-.51,0-2.95-.25,0-.38,0L15,4.94a.71.71,0,0,1-.18.15.45.45,0,0,1-.25.07l-.29,0H8.75l-.15,0H7.45a17,17,0,0,1-1.86,0L5.36,5l-.25-.13ZM19.75,16.14h-.69v-9h.69A.4.4,0,0,0,20.13,7c.06-.11,0-.24-.1-.39L18.92,5.15a.52.52,0,0,0-.86,0L17,6.58c-.12.15-.16.28-.1.39s.18.16.38.16h.69v9h-.69a.4.4,0,0,0-.38.16c-.06.11,0,.24.1.39l1.11,1.43a.52.52,0,0,0,.86,0L20,16.69c.12-.15.16-.28.1-.39a.4.4,0,0,0-.38-.16Z" transform="translate(-4.4 -4.86)"/></g></svg>',
+ paragraph_style: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11.81 15.74"><g><path d="M18.18,3.76v2h-2V19.5h-2V5.73h-2V19.5h-2V11.63a3.94,3.94,0,0,1,0-7.87h7.87Z" transform="translate(-6.37 -3.76)"/></g></svg>',
+ text_style: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13.76 15.74"><g><path d="M17.68,6.71a2.22,2.22,0,0,0,1.06-.22.74.74,0,0,0,.42-.7.73.73,0,0,0-.08-.33.67.67,0,0,0-.17-.22,1,1,0,0,0-.31-.15L18.26,5l-.45-.09A15.27,15.27,0,0,0,13.26,5V4.74c0-.66-.63-1-1.92-1-.24,0-.43.15-.59.46a4,4,0,0,0-.36,1.14h0v0a26.45,26.45,0,0,1-3.5.35A2,2,0,0,0,5.77,6a.84.84,0,0,0-.37.79,2.14,2.14,0,0,0,.41,1.29,1.23,1.23,0,0,0,1.05.63,16.62,16.62,0,0,0,3.29-.45l-.34,3.35c-.16,1.61-.29,2.9-.37,3.86s-.12,1.66-.12,2.09l0,.65a5.15,5.15,0,0,0,.05.6,1.28,1.28,0,0,0,.16.54.34.34,0,0,0,.28.18,1.16,1.16,0,0,0,.79-.46,3.66,3.66,0,0,0,.68-1,22.08,22.08,0,0,0,1-4.33q.49-3.1.78-6.15a24.69,24.69,0,0,1,4.62-.84Z" transform="translate(-5.4 -3.76)"/></g></svg>',
+ save: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.74"><g><path d="M18.53,19.5l.2-.05A1.78,1.78,0,0,0,20.13,18l0-.09V7.14a2,2,0,0,0-.28-.64A3.18,3.18,0,0,0,19.43,6c-.5-.52-1-1-1.55-1.54A2.59,2.59,0,0,0,17.37,4a1.83,1.83,0,0,0-.61-.25H6l-.21,0a1.78,1.78,0,0,0-1.4,1.49l0,.1V17.87a2.49,2.49,0,0,0,.09.37,1.79,1.79,0,0,0,1.44,1.23l.09,0Zm-6.25-.6H6.92a.61.61,0,0,1-.68-.48.78.78,0,0,1,0-.22V12.3a.62.62,0,0,1,.69-.68H17.64a.62.62,0,0,1,.69.69V18.2a.64.64,0,0,1-.71.69H12.28ZM12,9.81H8.15a.63.63,0,0,1-.72-.71v-4a.64.64,0,0,1,.72-.72h7.66a.64.64,0,0,1,.72.72v4a.65.65,0,0,1-.74.72ZM13.5,5V9.18h1.78V5Z" transform="translate(-4.41 -3.76)"/></g></svg>',
+ blockquote: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 475.082 475.081"><g><path d="M164.45,219.27h-63.954c-7.614,0-14.087-2.664-19.417-7.994c-5.327-5.33-7.994-11.801-7.994-19.417v-9.132c0-20.177,7.139-37.401,21.416-51.678c14.276-14.272,31.503-21.411,51.678-21.411h18.271c4.948,0,9.229-1.809,12.847-5.424c3.616-3.617,5.424-7.898,5.424-12.847V54.819c0-4.948-1.809-9.233-5.424-12.85c-3.617-3.612-7.898-5.424-12.847-5.424h-18.271c-19.797,0-38.684,3.858-56.673,11.563c-17.987,7.71-33.545,18.132-46.68,31.267c-13.134,13.129-23.553,28.688-31.262,46.677C3.855,144.039,0,162.931,0,182.726v200.991c0,15.235,5.327,28.171,15.986,38.834c10.66,10.657,23.606,15.985,38.832,15.985h109.639c15.225,0,28.167-5.328,38.828-15.985c10.657-10.663,15.987-23.599,15.987-38.834V274.088c0-15.232-5.33-28.168-15.994-38.832C192.622,224.6,179.675,219.27,164.45,219.27z"/><path d="M459.103,235.256c-10.656-10.656-23.599-15.986-38.828-15.986h-63.953c-7.61,0-14.089-2.664-19.41-7.994c-5.332-5.33-7.994-11.801-7.994-19.417v-9.132c0-20.177,7.139-37.401,21.409-51.678c14.271-14.272,31.497-21.411,51.682-21.411h18.267c4.949,0,9.233-1.809,12.848-5.424c3.613-3.617,5.428-7.898,5.428-12.847V54.819c0-4.948-1.814-9.233-5.428-12.85c-3.614-3.612-7.898-5.424-12.848-5.424h-18.267c-19.808,0-38.691,3.858-56.685,11.563c-17.984,7.71-33.537,18.132-46.672,31.267c-13.135,13.129-23.559,28.688-31.265,46.677c-7.707,17.987-11.567,36.879-11.567,56.674v200.991c0,15.235,5.332,28.171,15.988,38.834c10.657,10.657,23.6,15.985,38.828,15.985h109.633c15.229,0,28.171-5.328,38.827-15.985c10.664-10.663,15.985-23.599,15.985-38.834V274.088C475.082,258.855,469.76,245.92,459.103,235.256z"/></g></svg>',
+ arrow_down: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.73 8.67"><g><path d="M18.79,7.52a.8.8,0,0,1,.56-.23.82.82,0,0,1,.79.79.8.8,0,0,1-.23.56l-7.07,7.07a.79.79,0,0,1-.57.25.77.77,0,0,1-.57-.25h0L4.64,8.65a.8.8,0,0,1-.23-.57.82.82,0,0,1,.79-.79.8.8,0,0,1,.56.23L12.28,14l3.26-3.26,3.25-3.26Z" transform="translate(-4.41 -7.29)"/></g></svg>',
+ align_justify: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 13.77"><g><path d="M4.41,4.74v2H20.15v-2H4.41Zm0,5.9H20.15v-2H4.41v2Zm0,3.94H20.15v-2H4.41v2Zm0,3.93h7.87v-2H4.41v2Z" transform="translate(-4.41 -4.74)"/></g></svg>',
+ align_left: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 13.77"><g><path d="M4.41,4.74v2H20.15v-2H4.41Zm11.8,3.94H4.41v2H16.22v-2Zm-11.8,5.9H18.18v-2H4.41v2Zm0,3.93h9.84v-2H4.41v2Z" transform="translate(-4.41 -4.74)"/></g></svg>',
+ align_right: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 13.77"><g><path d="M4.41,4.74v2H20.15v-2H4.41Zm3.93,5.9H20.15v-2H8.34v2Zm-2,3.94H20.14v-2H6.37v2Zm3.94,3.93h9.84v-2H10.31v2Z" transform="translate(-4.41 -4.74)"/></g></svg>',
+ align_center: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 13.77"><g><path d="M4.41,4.74v2H20.15v-2H4.41Zm2,3.94v2H18.18v-2H6.37Zm-1,5.9H19.16v-2H5.39v2Zm2,3.93H17.2v-2H7.36v2Z" transform="translate(-4.41 -4.74)"/></g></svg>',
+ font_color: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 14.61"><g><path d="M18.5,15.57,14.28,4.32h-3.4L6.65,15.57h3l.8-2.26h4.23l.8,2.26h3ZM14,11.07H11.14L12.54,7,13.25,9c.41,1.18.64,1.86.7,2ZM4.41,16.69v2.24H20.15V16.69H4.41Z" transform="translate(-4.41 -4.32)"/></g></svg>',
+ highlight_color:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.66 15.74"><g><path d="M12.32,9.31,13.38,13H11.21l.52-1.83q.46-1.61.54-1.83ZM4.44,3.76H20.1V19.5H4.44V3.76ZM14.71,17.32h2.63L13.7,6H10.89L7.26,17.32H9.89l.63-2.24h3.55l.32,1.12c.18.65.29,1,.32,1.12Z" transform="translate(-4.44 -3.76)"/></g></svg>',
+ list_bullets: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 12.37"><g><path d="M7.77,16.12a1.59,1.59,0,0,0-.49-1.18,1.62,1.62,0,0,0-1.19-.49,1.68,1.68,0,1,0,0,3.36,1.67,1.67,0,0,0,1.68-1.69Zm0-4.48A1.67,1.67,0,0,0,6.09,10,1.68,1.68,0,0,0,4.9,12.82a1.62,1.62,0,0,0,1.19.49,1.67,1.67,0,0,0,1.68-1.67Zm12.38,3.64a.27.27,0,0,0-.08-.19.28.28,0,0,0-.2-.09H9.19a.28.28,0,0,0-.2.08.29.29,0,0,0-.08.19V17a.27.27,0,0,0,.28.28H19.87a.27.27,0,0,0,.19-.08.24.24,0,0,0,.08-.2V15.28ZM7.77,7.13a1.63,1.63,0,0,0-.49-1.2,1.61,1.61,0,0,0-1.19-.49,1.61,1.61,0,0,0-1.19.49,1.71,1.71,0,0,0,0,2.4,1.62,1.62,0,0,0,1.19.49,1.61,1.61,0,0,0,1.19-.49,1.63,1.63,0,0,0,.49-1.2Zm12.38,3.66a.28.28,0,0,0-.08-.2.29.29,0,0,0-.19-.08H9.19a.27.27,0,0,0-.28.28v1.69a.27.27,0,0,0,.08.19.24.24,0,0,0,.2.08H19.87a.27.27,0,0,0,.19-.08.25.25,0,0,0,.08-.19V10.79Zm0-4.5a.27.27,0,0,0-.08-.19A.25.25,0,0,0,19.88,6H9.19A.28.28,0,0,0,9,6.1a.26.26,0,0,0-.08.19V8A.27.27,0,0,0,9,8.17a.24.24,0,0,0,.2.08H19.87a.27.27,0,0,0,.19-.08A.25.25,0,0,0,20.14,8V6.29Z" transform="translate(-4.41 -5.44)"/></g></svg>',
+ list_number: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.69 15.74"><g><path d="M7.66,18a1.24,1.24,0,0,0-.26-.78,1.17,1.17,0,0,0-.72-.42l.85-1V15H4.58v1.34h.94v-.46l.85,0h0c-.11.11-.22.23-.32.35s-.23.27-.37.47L5.39,17l.23.51c.61-.05.92.11.92.49a.42.42,0,0,1-.18.37.79.79,0,0,1-.45.12A1.41,1.41,0,0,1,5,18.15l-.51.77A2.06,2.06,0,0,0,6,19.5a1.8,1.8,0,0,0,1.2-.41A1.38,1.38,0,0,0,7.66,18Zm0-5.54H6.75V13H5.63A.72.72,0,0,1,6,12.51a5.45,5.45,0,0,1,.66-.45,2.71,2.71,0,0,0,.67-.57,1.19,1.19,0,0,0,.31-.81,1.29,1.29,0,0,0-.45-1,1.86,1.86,0,0,0-2-.11,1.51,1.51,0,0,0-.62.7l.74.52A.87.87,0,0,1,6,10.28a.51.51,0,0,1,.35.12.42.42,0,0,1,.13.33.55.55,0,0,1-.21.4,3,3,0,0,1-.5.38c-.19.13-.39.27-.58.42a2,2,0,0,0-.5.6,1.63,1.63,0,0,0-.21.81,3.89,3.89,0,0,0,.05.48h3.2V12.44Zm12.45,2.82a.27.27,0,0,0-.08-.19.28.28,0,0,0-.21-.08H9.1a.32.32,0,0,0-.21.08.24.24,0,0,0-.08.2V17a.27.27,0,0,0,.08.19.3.3,0,0,0,.21.08H19.83a.32.32,0,0,0,.21-.08.25.25,0,0,0,.08-.19V15.26ZM7.69,7.32h-1V3.76H5.8L4.6,4.88l.63.68a1.85,1.85,0,0,0,.43-.48h0l0,2.24H4.74V8.2h3V7.32Zm12.43,3.42a.27.27,0,0,0-.08-.19.28.28,0,0,0-.21-.08H9.1a.32.32,0,0,0-.21.08.24.24,0,0,0-.08.2v1.71a.27.27,0,0,0,.08.19.3.3,0,0,0,.21.08H19.83a.32.32,0,0,0,.21-.08.25.25,0,0,0,.08-.19V10.74Zm0-4.52A.27.27,0,0,0,20,6,.28.28,0,0,0,19.83,6H9.1A.32.32,0,0,0,8.89,6a.24.24,0,0,0-.08.19V7.93a.27.27,0,0,0,.08.19.32.32,0,0,0,.21.08H19.83A.32.32,0,0,0,20,8.12a.26.26,0,0,0,.08-.2V6.22Z" transform="translate(-4.43 -3.76)"/></g></svg>',
+ table: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.74"><g><path d="M4.41,8.05V3.76H8.7V8.05H4.41Zm5.71,0V3.76h4.3V8.05h-4.3Zm5.74-4.29h4.29V8.05H15.86V3.76Zm-11.45,10V9.48H8.7v4.3H4.41Zm5.71,0V9.48h4.3v4.3h-4.3Zm5.74,0V9.48h4.29v4.3H15.86ZM4.41,19.5V15.21H8.7V19.5H4.41Zm5.71,0V15.21h4.3V19.5h-4.3Zm5.74,0V15.21h4.29V19.5H15.86Z" transform="translate(-4.41 -3.76)"/></g></svg>',
+ horizontal_rule: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 2.24"><g><path d="M20.15,12.75V10.51H4.41v2.24H20.15Z" transform="translate(-4.41 -10.51)"/></g></svg>',
+ show_blocks: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.66 15.67"><g><path d="M19.72,5.58a1.64,1.64,0,0,0-1.64-1.64H6.23a1.62,1.62,0,0,0-1.16.48,1.63,1.63,0,0,0-.48,1.16V9.63a1.6,1.6,0,0,0,.48,1.16,1.62,1.62,0,0,0,1.16.47H18.09a1.67,1.67,0,0,0,1.16-.47,1.62,1.62,0,0,0,.48-1.16V5.58Zm-.94,4.05a.68.68,0,0,1-.7.7H6.23a.66.66,0,0,1-.48-.2.74.74,0,0,1-.21-.5V5.58a.66.66,0,0,1,.2-.48.71.71,0,0,1,.48-.21H18.08a.74.74,0,0,1,.5.21.66.66,0,0,1,.2.48ZM6.48,7.72a.21.21,0,0,0,.17-.07.22.22,0,0,0,.07-.17V7.06a1.27,1.27,0,0,1,.11-.52.37.37,0,0,1,.36-.23H8.77A.25.25,0,0,0,9,6.17a.19.19,0,0,0,0-.23.27.27,0,0,0-.2-.12H7.19a.88.88,0,0,0-.72.39,1.51,1.51,0,0,0-.23.85v.42a.24.24,0,0,0,.24.24Zm-.19.81a.21.21,0,0,0,.17-.07.26.26,0,0,0,.07-.17.24.24,0,0,0-.24-.24.2.2,0,0,0-.16.09.2.2,0,0,0-.07.16.22.22,0,0,0,.07.17.23.23,0,0,0,.16.06Zm8.46,5.1a1.63,1.63,0,0,0-.47-1.16A1.61,1.61,0,0,0,13.12,12H6.23a1.6,1.6,0,0,0-1.16.46,1.62,1.62,0,0,0-.48,1.16v4.05a1.64,1.64,0,0,0,1.64,1.64h6.89a1.6,1.6,0,0,0,1.16-.48,1.62,1.62,0,0,0,.47-1.16Zm-.94,4a.7.7,0,0,1-.2.49.65.65,0,0,1-.5.2H6.23a.66.66,0,0,1-.48-.2.75.75,0,0,1-.21-.49v-4a.74.74,0,0,1,.21-.5.66.66,0,0,1,.48-.2h6.89a.68.68,0,0,1,.7.7v4Zm6.15,0v-4a1.6,1.6,0,0,0-.48-1.16A1.67,1.67,0,0,0,18.32,12H17.1a1.63,1.63,0,0,0-1.16.47,1.61,1.61,0,0,0-.47,1.16v4a1.67,1.67,0,0,0,.47,1.16,1.62,1.62,0,0,0,1.16.48h1.22A1.64,1.64,0,0,0,20,17.68Zm-.94-4v4a.75.75,0,0,1-.21.49.62.62,0,0,1-.48.2H17.11a.69.69,0,0,1-.5-.2.7.7,0,0,1-.2-.49v-4a.68.68,0,0,1,.7-.7h1.22a.66.66,0,0,1,.48.2.72.72,0,0,1,.21.5Z" transform="translate(-4.44 -3.79)"/></g></svg>',
+ cancel: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.74"><g><path d="M14.15,11.63l5.61,5.61a1.29,1.29,0,0,1,.38.93,1.27,1.27,0,0,1-.4.93,1.25,1.25,0,0,1-.92.4,1.31,1.31,0,0,1-.94-.4l-5.61-5.61L6.67,19.1a1.31,1.31,0,0,1-.94.4,1.24,1.24,0,0,1-.92-.4,1.27,1.27,0,0,1-.4-.93,1.33,1.33,0,0,1,.38-.93l5.61-5.63L4.79,6a1.26,1.26,0,0,1-.38-.93,1.22,1.22,0,0,1,.4-.92,1.28,1.28,0,0,1,.92-.39,1.38,1.38,0,0,1,.94.38l5.61,5.61,5.61-5.61a1.33,1.33,0,0,1,.94-.38,1.26,1.26,0,0,1,.92.39,1.24,1.24,0,0,1,.4.92,1.29,1.29,0,0,1-.39.93L17,8.81l-2.8,2.82Z" transform="translate(-4.41 -3.76)"/></g></svg>',
+ image: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.75 15.77"><g><path d="M8.77,8.72a.88.88,0,0,1-.61-.27.82.82,0,0,1-.25-.61.89.89,0,0,1,.25-.62A.82.82,0,0,1,8.77,7a.81.81,0,0,1,.61.25.83.83,0,0,1,.27.62.81.81,0,0,1-.25.61.91.91,0,0,1-.63.27Zm9.62-5a1.74,1.74,0,0,1,1.76,1.76V17.76a1.74,1.74,0,0,1-1.76,1.76H6.16A1.74,1.74,0,0,1,4.4,17.76V5.51A1.74,1.74,0,0,1,6.16,3.75H18.39Zm0,1.75H6.16v8L8.53,11.8a.94.94,0,0,1,.54-.17.86.86,0,0,1,.54.2L11.09,13l3.64-4.55a.78.78,0,0,1,.34-.25.85.85,0,0,1,.42-.07.89.89,0,0,1,.39.12.78.78,0,0,1,.28.29l2.24,3.67V5.51Zm0,12.24V15.6L15.3,10.53,11.89,14.8a.89.89,0,0,1-.59.32.82.82,0,0,1-.64-.18L9,13.62,6.16,15.74v2Z" transform="translate(-4.4 -3.75)"/></g></svg>',
+ video: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 14.55"><g><path d="M20.15,10.26V18.9l-3.94-1.57v1.2H4.41V10.66H16.22v1.23l2-.81,2-.82ZM14.64,17h0V12.54h0v-.31H6V17h8.67Zm3.94-.37v-4l-2.37,1v2l1.18.48,1.19.48ZM7.94,9.86A2.77,2.77,0,0,1,5.19,7.11a2.76,2.76,0,0,1,5.51,0A2.78,2.78,0,0,1,7.94,9.86Zm0-3.93a1.21,1.21,0,0,0-.83.35,1.15,1.15,0,0,0-.34.84A1.09,1.09,0,0,0,7.11,8,1.15,1.15,0,0,0,8,8.28,1.13,1.13,0,0,0,9.11,7.12,1.16,1.16,0,0,0,7.94,5.93Zm5.9,3.93a2.34,2.34,0,0,1-1.67-.68,2.3,2.3,0,0,1-.68-1.67,2.35,2.35,0,0,1,4-1.67,2.37,2.37,0,0,1,0,3.34,2.33,2.33,0,0,1-1.68.68Zm0-3.14a.75.75,0,1,0,.55.22.73.73,0,0,0-.55-.22Z" transform="translate(-4.41 -4.35)"/></g></svg>',
+ link: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.72"><g><path d="M13.05,13.63a.24.24,0,0,1,.15.22L13.42,16a.19.19,0,0,1-.08.18l-2.12,2.14a4.08,4.08,0,0,1-1.29.85A4,4,0,0,1,4.71,17a3.92,3.92,0,0,1-.3-1.52A4,4,0,0,1,4.71,14a3.91,3.91,0,0,1,.87-1.3L7.7,10.56a.25.25,0,0,1,.2-.06l2.17.22a.21.21,0,0,1,.19.15.24.24,0,0,1,0,.25L7.12,14.23a1.81,1.81,0,0,0,0,2.58,1.78,1.78,0,0,0,1.29.52,1.74,1.74,0,0,0,1.28-.52L12.8,13.7a.24.24,0,0,1,.25-.07ZM19,4.92a4,4,0,0,1,0,5.66L16.86,12.7a.25.25,0,0,1-.17.08l-2.2-.23a.21.21,0,0,1-.19-.15.22.22,0,0,1,0-.25L17.44,9a1.81,1.81,0,0,0,0-2.58,1.78,1.78,0,0,0-1.29-.52,1.74,1.74,0,0,0-1.28.52L11.76,9.57a.21.21,0,0,1-.25,0,.24.24,0,0,1-.16-.21l-.22-2.17a.19.19,0,0,1,.08-.18l2.12-2.14a4.08,4.08,0,0,1,1.29-.85,4.05,4.05,0,0,1,3.06,0,3.85,3.85,0,0,1,1.3.85ZM5.84,9.82a.25.25,0,0,1-.18-.08.19.19,0,0,1-.07-.19l.11-.77a.2.2,0,0,1,.11-.17.24.24,0,0,1,.2,0l2.5.72a.25.25,0,0,1,.15.27.22.22,0,0,1-.23.21l-2.59,0Zm4.12-2-.73-2.5a.27.27,0,0,1,0-.2A.21.21,0,0,1,9.41,5L10.19,5a.25.25,0,0,1,.19,0,.23.23,0,0,1,.08.18l-.05,2.61a.2.2,0,0,1-.19.23h0A.22.22,0,0,1,10,7.85Zm8.76,5.58a.25.25,0,0,1,.18.08.23.23,0,0,1,.06.2l-.11.77a.25.25,0,0,1-.11.17.21.21,0,0,1-.12,0l-.08,0L16,14a.25.25,0,0,1-.15-.27.22.22,0,0,1,.22-.21l1.29,0,1.33,0Zm-4.12,2,.74,2.51a.28.28,0,0,1,0,.2.23.23,0,0,1-.18.11l-.8.11a.23.23,0,0,1-.17-.07.25.25,0,0,1-.08-.18l0-2.61a.22.22,0,0,1,.22-.22.21.21,0,0,1,.26.15Z" transform="translate(-4.41 -3.77)"/></g></svg>',
+ math: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11.81 15.73"><g><path d="M17.19,5.73a1,1,0,0,0,.71-.29,1,1,0,0,0,.28-.7,1,1,0,0,0-1-1H7.35a1,1,0,0,0-1,1,.77.77,0,0,0,.13.47h0l4.58,6.43L6.68,17.81a1.25,1.25,0,0,0-.29.71.94.94,0,0,0,.28.7.92.92,0,0,0,.69.28H17.2a1,1,0,0,0,.71-.28,1,1,0,0,0,0-1.39.92.92,0,0,0-.71-.29H9.26l3.87-5.43a.86.86,0,0,0,0-.95L9.26,5.73h7.93Z" transform="translate(-6.38 -3.77)"/></g></svg>',
+ unlink: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.72"><g><path d="M19,18.32a4,4,0,0,0,0-5.68L15.85,9.5l-1.17,1.55L17.57,14a2,2,0,0,1,.61,1.47,2.08,2.08,0,0,1-2.09,2.09,2,2,0,0,1-1.47-.61l-.38-.37-1.74,1,.8.78a4,4,0,0,0,5.68,0ZM8,9.77a2,2,0,0,1-1.27-1,1.89,1.89,0,0,1-.21-1.57A2.1,2.1,0,0,1,7.45,6,2,2,0,0,1,9,5.76L12.27,7.2l.49-2L9.48,3.9a4,4,0,0,0-3.06.41A3.82,3.82,0,0,0,4.56,6.73a3.8,3.8,0,0,0,.4,3A3.78,3.78,0,0,0,7.39,11.6l5.38,2,.49-2-2.64-.94L8,9.77Z" transform="translate(-4.41 -3.76)"/></g></svg>',
+ table_header: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.75 15.74"><g><path d="M17,19.5v-.78H15.5v.78H17Zm-3,0v-.78H12.5v.78H14Zm-3,0v-.78H9.53v.78H11Zm-3,0v-.78H6.53v.78H8Zm10.55,0a1.73,1.73,0,0,0,.85-.35,1.67,1.67,0,0,0,.56-.76l-.71-.31a1.21,1.21,0,0,1-.35.4,1.34,1.34,0,0,1-.53.23l.08.38c.06.24.09.38.1.41Zm-13.7-.63.55-.55A.77.77,0,0,1,5.25,18a1.31,1.31,0,0,1-.06-.38v-.38H4.41v.38a2,2,0,0,0,.12.68,1.6,1.6,0,0,0,.35.57Zm15.27-2.12V15.26h-.78v1.49h.78Zm-15-1V14.23H4.41v1.49h.78Zm15-2V12.26h-.78v1.49h.78Zm-15-1V11.22H4.41v1.51h.78Zm15-2V9.26h-.78v1.51h.78Zm-15-1V8.17H4.41V9.74h.78Zm15-2V6.28h-.78V7.77h.78Zm-15-1.11V5.33L4.48,5.1a.77.77,0,0,0-.07.27,2.72,2.72,0,0,0,0,.28v1h.79ZM19.21,5l.63-.4A1.62,1.62,0,0,0,19.16,4a1.94,1.94,0,0,0-.91-.22v.78a1.31,1.31,0,0,1,.56.12.88.88,0,0,1,.4.36ZM6,4.54H7.78V3.76H6a.82.82,0,0,0-.28.06l.12.35c.07.21.1.33.11.36Zm10.8,0V3.76H15.28v.78h1.49Zm-3,0V3.76H12.28v.78h1.49Zm-3,0V3.76H9.28v.78h1.51ZM6,10.84h12.6V6.91H6Z" transform="translate(-4.4 -3.76)"/></g></svg>',
+ merge_cell: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.76 15.74"><g><path d="M18.92,13.5h1.23v4.15A1.84,1.84,0,0,1,18.3,19.5H14V18.27H18.3a.6.6,0,0,0,.44-.18.59.59,0,0,0,.18-.44V13.5ZM18.3,3.76a1.84,1.84,0,0,1,1.85,1.85V9.82H18.92V5.6a.6.6,0,0,0-.18-.44A.59.59,0,0,0,18.3,5H14V3.76H18.3Zm1.85,8.51H15.6L17.26,14l-.86.86-3.14-3.17L16.4,8.51l.86.86L15.62,11h4.54v1.24Zm-13.9,6h4.27V19.5H6.25A1.84,1.84,0,0,1,4.4,17.65V13.5H5.63v4.15a.61.61,0,0,0,.62.62Zm0-14.51h4.27V5H6.25a.6.6,0,0,0-.44.18.57.57,0,0,0-.17.43V9.81H4.41V5.6A1.83,1.83,0,0,1,6.25,3.76Zm5,7.9L8.15,14.83,7.3,14,9,12.27H4.41V11H8.94L7.3,9.38,7.73,9l.43-.43Z" transform="translate(-4.4 -3.76)"/></g></svg>',
+ split_cell: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.75 15.74"><g><path d="M10.37,12.25H6.74L8.4,13.94l-.87.86L4.41,11.63,7.53,8.5l.87.86L6.74,11h3.62v1.23Zm9.78-.61L17,14.81,16.13,14l1.66-1.69H14.16V11h3.63L16.13,9.37l.43-.43A5.24,5.24,0,0,1,17,8.51ZM18.9,8.22V5.61a.57.57,0,0,0-.18-.43A.65.65,0,0,0,18.29,5H12.88V18.28h5.41a.7.7,0,0,0,.44-.18.57.57,0,0,0,.18-.43V15h1.23v2.64a1.84,1.84,0,0,1-1.85,1.83h-12A1.84,1.84,0,0,1,4.94,19a1.81,1.81,0,0,1-.54-1.29V15H5.63v2.64a.57.57,0,0,0,.18.43.67.67,0,0,0,.44.18h5.41V5H6.25a.7.7,0,0,0-.44.18.56.56,0,0,0-.17.43V8.22H4.41V5.61A1.8,1.8,0,0,1,5,4.31a1.91,1.91,0,0,1,1.31-.55h12a1.89,1.89,0,0,1,1.31.55,1.8,1.8,0,0,1,.54,1.3V8.23H18.9Z" transform="translate(-4.4 -3.76)"/></g></svg>',
+ caption: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 13.79"><g><path d="M4.41,18.52H20.15v-2H4.41ZM20,4.73H18.07V6h.65v.65H20V4.73ZM17,6V4.73H14.55V6H17ZM13.49,6V4.73H11V6h2.47ZM10,6V4.73H7.5V6H10ZM5.79,6h.65V4.73H4.5V6.67H5.8V6ZM4.5,11.34H5.79V8.48H4.5ZM6.44,13.8H5.79v-.65H4.5v1.94H6.44ZM17,15.09V13.8H14.55v1.29H17Zm-3.52,0V13.8H11v1.29h2.47Zm-3.53,0V13.8H7.5v1.29H10ZM20,13.16H18.72v.65h-.65V15.1H20Zm-1.29-1.82H20V8.48h-1.3v2.86Z" transform="translate(-4.41 -4.73)"/></g></svg>',
+ edit: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.73"><g><path d="M7.51,5.68h6l1.52-1.57H6.94a2.4,2.4,0,0,0-1.79.82A2.8,2.8,0,0,0,4.41,6.8V17a2.55,2.55,0,0,0,.75,1.8A2.48,2.48,0,0,0,7,19.5H17.22a2.57,2.57,0,0,0,1.83-.74,2.52,2.52,0,0,0,.77-1.8V8.83l-1.58,1.54v6a1.54,1.54,0,0,1-1.53,1.53H7.51A1.54,1.54,0,0,1,6,16.41V7.21A1.52,1.52,0,0,1,7.51,5.68Zm5.63,7.47h0L10.7,10.74l-1,3.38,1.71-.48,1.7-.49Zm.34-.34h0l5.36-5.32L16.4,5.08,11,10.4l1.23,1.21,1.21,1.2ZM19.93,6.4a.82.82,0,0,0,.22-.48A.54.54,0,0,0,20,5.47L18.45,4A.67.67,0,0,0,18,3.77a.7.7,0,0,0-.48.21l-.74.72,2.44,2.43.37-.37.35-.36Z" transform="translate(-4.41 -3.77)"/></g></svg>',
+ delete: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.73 15.74"><g><path d="M19.16,6.71a.94.94,0,0,0,.69-.28.91.91,0,0,0,.29-.68A1,1,0,0,0,19.85,5a.93.93,0,0,0-.69-.3H14.24A.94.94,0,0,0,14,4.06a.92.92,0,0,0-.7-.3h-2a1,1,0,0,0-.7.3.93.93,0,0,0-.28.68H5.39A.92.92,0,0,0,4.7,5a1,1,0,0,0-.29.71.91.91,0,0,0,.29.68,1,1,0,0,0,.69.28H19.16Zm-12.79,1a1,1,0,0,0-.7.3.94.94,0,0,0-.28.69v8.85A1.88,1.88,0,0,0,6,18.93a1.9,1.9,0,0,0,1.39.57H17.2a1.87,1.87,0,0,0,1.39-.58,1.91,1.91,0,0,0,.58-1.39V8.68A1,1,0,0,0,18.88,8a.89.89,0,0,0-.7-.29,1,1,0,0,0-.69.29.92.92,0,0,0-.29.68v7.87a1,1,0,0,1-1,1H8.34a.94.94,0,0,1-.69-.28,1,1,0,0,1-.29-.71V8.68a1,1,0,0,0-1-1Z" transform="translate(-4.41 -3.76)"/></g></svg>',
+ modify: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 15.74"><g><path d="M19.79,15.23a.66.66,0,0,1,.3.38.59.59,0,0,1-.07.48l-.8,1.38a.66.66,0,0,1-.38.3.59.59,0,0,1-.48-.07l-.68-.38a4.55,4.55,0,0,1-1.34.77v.78a.64.64,0,0,1-.18.45.61.61,0,0,1-.45.18h-1.6a.6.6,0,0,1-.44-.18.66.66,0,0,1-.19-.45v-.78a4.36,4.36,0,0,1-1.32-.77l-.69.38a.58.58,0,0,1-.48.07.66.66,0,0,1-.38-.3l-.38-.66h.83a1.77,1.77,0,0,0,1.23-.52,1.72,1.72,0,0,0,.51-1.23v-.18a3,3,0,0,0,.49-.28l.15.09a1.83,1.83,0,0,0,.88.23A1.75,1.75,0,0,0,15.84,14l.88-1.52a1.7,1.7,0,0,0,.17-1.32,1.66,1.66,0,0,0-.3-.61,1.84,1.84,0,0,0-.51-.45l-.15-.09,0-.29,0-.28.15-.09a1,1,0,0,0,.26-.18l0,.06v.78a4.34,4.34,0,0,1,1.34.77l.68-.38a.68.68,0,0,1,.48-.06.64.64,0,0,1,.38.29l.8,1.38a.58.58,0,0,1,.07.48.63.63,0,0,1-.3.38l-.68.4a3.84,3.84,0,0,1,.08.76,4.13,4.13,0,0,1-.08.78l.34.18.32.2ZM10.17,7.86a1.9,1.9,0,0,1,1.35,3.23,1.85,1.85,0,0,1-1.35.55A1.9,1.9,0,0,1,8.83,8.41a1.92,1.92,0,0,1,1.34-.55Zm1.58,7.2a.73.73,0,0,1-.21.49.66.66,0,0,1-.48.2H9.29a.68.68,0,0,1-.69-.69V14.2a4.75,4.75,0,0,1-1.48-.86l-.75.45a.73.73,0,0,1-.7,0,.63.63,0,0,1-.25-.26L4.54,12a.67.67,0,0,1-.08-.53.71.71,0,0,1,.32-.42l.75-.43a4.8,4.8,0,0,1-.08-.85,4.71,4.71,0,0,1,.08-.85l-.74-.44a.71.71,0,0,1-.32-.42.65.65,0,0,1,.07-.54L5.42,6a.66.66,0,0,1,.42-.32l.18,0a.73.73,0,0,1,.35.09l.75.43A4.68,4.68,0,0,1,8.6,5.33V4.45a.68.68,0,0,1,.69-.69h1.77a.64.64,0,0,1,.48.2.73.73,0,0,1,.21.49v.88a4.75,4.75,0,0,1,1.48.85L14,5.75a.67.67,0,0,1,.34-.09l.18,0a.71.71,0,0,1,.42.32l.89,1.54a.67.67,0,0,1,.06.52.73.73,0,0,1-.32.43l-.75.42a4.8,4.8,0,0,1,.08.85,4.71,4.71,0,0,1-.08.85l.75.43a.66.66,0,0,1,.32.42.73.73,0,0,1-.06.54l-.89,1.52a.69.69,0,0,1-.25.26.7.7,0,0,1-.35.09.64.64,0,0,1-.34-.09l-.75-.45a4.87,4.87,0,0,1-1.48.86v.87ZM7.23,9.75a3,3,0,0,0,.86,2.08,2.94,2.94,0,1,0,4.16-4.16,3,3,0,0,0-2.08-.85A2.94,2.94,0,0,0,7.23,9.75Z" transform="translate(-4.44 -3.76)"/></g></svg>',
+ revert: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.76 14.69"><g><path d="M18.26,15V12.3l1.89-2V15a2.58,2.58,0,0,1-.24,1c-.2.58-.75.92-1.65,1H7.56v2L4.41,15.63,7.56,13v2h10.7ZM6.3,8.28V11L4.41,13V8.28a2.58,2.58,0,0,1,.24-1c.2-.58.75-.92,1.65-1H17v-2l3.15,3.34L17,10.3v-2H6.3Z" transform="translate(-4.4 -4.28)"/></g></svg>',
+ auto_size: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.74"><g><path d="M6.71,17.19,6.89,16l1.21-.15A6,6,0,0,1,6.81,13.9a5.78,5.78,0,0,1-.45-2.27A6,6,0,0,1,8.1,7.45a5.83,5.83,0,0,1,4.17-1.73l1-1-1-1A7.89,7.89,0,0,0,5,14.64a7.73,7.73,0,0,0,1.71,2.55Zm5.57,2.31h0A7.86,7.86,0,0,0,17.85,6.07L17.67,7.3l-1.21.15a5.9,5.9,0,0,1,1.29,1.92,5.81,5.81,0,0,1,.45,2.26,5.91,5.91,0,0,1-5.9,5.9l-1,1,.49.49.47.5Z" transform="translate(-4.41 -3.76)"/></g></svg>',
+ insert_row_below: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.8 15.8"><g><path d="M15.7,1.3c-0.1-0.1-0.1-0.2-0.2-0.2L15.3,1H0.4L0.3,1.1c0,0-0.1,0.1-0.1,0.1c0,0-0.1,0.1-0.1,0.1L0,1.4v7.7l0.1,0.1c0,0.1,0.1,0.1,0.2,0.2l0.1,0.1h2.3V9.3l0.1-0.5L3,8.5l0.1-0.2c-0.1,0-0.2,0-0.3,0H1.2v-6h13.3v6h-1.6c-0.1,0-0.2,0-0.3,0l0.1,0.2l0.2,0.4C12.9,9,13,9.2,13,9.3v0.1h2.3l0.2-0.1c0.1,0,0.1-0.1,0.2-0.2l0.1-0.1V1.4L15.7,1.3z"/><path d="M10.5,7.5C9.9,7.1,9.3,6.8,8.6,6.7c-0.2,0-0.5-0.1-0.7,0c-0.2,0-0.5,0-0.7,0C6.6,6.7,6.1,6.9,5.6,7.3C5.2,7.6,4.7,8,4.4,8.4C4.3,8.6,4.2,8.8,4.2,8.9C4.1,9.1,4,9.3,3.9,9.4C3.9,9.6,3.8,9.7,3.8,9.9c0,0.2-0.1,0.3-0.1,0.5v-0.1c-0.1,0.8,0.1,1.6,0.5,2.4c0.4,0.7,1,1.3,1.7,1.7c0.3,0.2,0.6,0.3,0.9,0.3c0.3,0.1,0.7,0.1,1,0.1c0.3,0,0.7,0,1-0.1c0.3-0.1,0.6-0.2,0.9-0.3c0.5-0.3,0.9-0.6,1.3-1c0.3-0.4,0.6-0.8,0.8-1.3c0.1-0.4,0.2-0.9,0.2-1.4c0-0.5-0.1-1-0.3-1.4C11.5,8.6,11.1,8,10.5,7.5z M10.1,11.3H8.5v1.6H8H7.9H7.3v0v-0.1v-1.4H5.7v-0.4v-0.2v-0.6h0h1.5V8.5h1.2v1.6h1.6V11.3z"/></g></svg>',
+ insert_row_above: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.8 15.8"><g><path d="M0.1,14.5c0.1,0.1,0.1,0.2,0.2,0.2l0.1,0.1h14.9l0.1-0.1c0,0,0.1-0.1,0.1-0.1c0,0,0.1-0.1,0.1-0.1l0.1-0.1V6.7l-0.1-0.1c0-0.1-0.1-0.1-0.2-0.2l-0.1-0.1h-2.3v0.1l-0.1,0.5l-0.2,0.4l-0.1,0.2c0.1,0,0.2,0,0.3,0h1.6v6H1.3v-6h1.6c0.1,0,0.2,0,0.3,0L3.1,7.3L2.9,6.9C2.8,6.8,2.8,6.6,2.7,6.5V6.3H0.4L0.3,6.4c-0.1,0-0.1,0.1-0.2,0.2L0,6.7v7.7L0.1,14.5z"/><path d="M5.3,8.3c0.6,0.5,1.2,0.8,1.9,0.9c0.2,0,0.5,0.1,0.7,0c0.2,0,0.5,0,0.7,0c0.6-0.1,1.1-0.3,1.6-0.6c0.5-0.3,0.9-0.7,1.2-1.2c0.1-0.2,0.2-0.3,0.3-0.5c0.1-0.2,0.2-0.4,0.2-0.5c0.1-0.1,0.1-0.3,0.1-0.4C12,5.8,12,5.6,12,5.4v0.1c0.1-0.8-0.1-1.6-0.5-2.4c-0.4-0.7-1-1.3-1.7-1.7C9.5,1.3,9.2,1.2,8.9,1.1C8.5,1,8.2,1,7.9,1c-0.3,0-0.7,0-1,0.1C6.6,1.2,6.3,1.3,6,1.4C5.5,1.7,5.1,2,4.7,2.4C4.4,2.8,4.1,3.3,3.9,3.8C3.8,4.2,3.7,4.7,3.7,5.2c0,0.5,0.1,1,0.3,1.4C4.3,7.2,4.7,7.8,5.3,8.3z M5.7,4.5h1.6V2.9h0.5h0.1h0.6v0v0.1v1.4H10v0.4v0.2v0.6h0H8.5v1.6H7.3V5.7H5.7V4.5z"/></g></svg>',
+ insert_column_left: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.8 15.8"><g><path d="M14.5,15.7c0.1-0.1,0.2-0.1,0.2-0.2l0.1-0.1V0.4l-0.1-0.1c0,0-0.1-0.1-0.1-0.1c0,0-0.1-0.1-0.1-0.1L14.4,0H6.7L6.6,0.1c-0.1,0-0.1,0.1-0.2,0.2L6.3,0.4v2.3h0.1l0.5,0.1L7.3,3l0.2,0.1c0-0.1,0-0.2,0-0.3V1.2h6v13.3h-6v-1.6c0-0.1,0-0.2,0-0.3l-0.2,0.1l-0.4,0.2C6.7,12.9,6.6,13,6.4,13H6.3v2.3l0.1,0.2c0,0.1,0.1,0.1,0.2,0.2l0.1,0.1h7.7L14.5,15.7z"/><path d="M8.3,10.5C8.7,10,9,9.3,9.1,8.6c0-0.2,0.1-0.5,0-0.7c0-0.2,0-0.5,0-0.7C9,6.7,8.8,6.1,8.5,5.7C8.2,5.2,7.8,4.8,7.3,4.5C7.2,4.4,7,4.3,6.9,4.2C6.7,4.1,6.5,4,6.4,4C6.2,3.9,6.1,3.9,5.9,3.8c-0.2,0-0.3-0.1-0.5-0.1h0.1C4.7,3.7,3.8,3.9,3.1,4.3C2.4,4.7,1.8,5.3,1.4,6C1.3,6.3,1.2,6.6,1.1,6.9C1,7.2,1,7.6,1,7.9c0,0.3,0,0.7,0.1,1c0.1,0.3,0.2,0.6,0.3,0.9c0.3,0.5,0.6,0.9,1,1.3c0.4,0.3,0.8,0.6,1.3,0.8C4.2,12,4.7,12.1,5.1,12c0.5,0,1-0.1,1.4-0.3C7.2,11.5,7.8,11.1,8.3,10.5zM4.5,10.1V8.5H2.9V8V7.9V7.3h0H3h1.4V5.7h0.4h0.2h0.6v0v1.5h1.6v1.2H5.7v1.6H4.5z"/></g></svg>',
+ insert_column_right: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.8 15.8"><g><path d="M1.3,0.1C1.2,0.2,1.1,0.2,1.1,0.3L1,0.4v14.9l0.1,0.1c0,0,0.1,0.1,0.1,0.1c0,0,0.1,0.1,0.1,0.1l0.1,0.1h7.7l0.1-0.1c0.1,0,0.1-0.1,0.2-0.2l0.1-0.1v-2.3H9.3l-0.5-0.1l-0.4-0.2l-0.2-0.1c0,0.1,0,0.2,0,0.3v1.6h-6V1.3h6v1.6c0,0.1,0,0.2,0,0.3l0.2-0.1l0.4-0.2C9,2.9,9.2,2.8,9.3,2.8h0.1V0.5L9.4,0.3c0-0.1-0.1-0.1-0.2-0.2L9.1,0H1.4L1.3,0.1z"/><path d="M7.5,5.3C7,5.8,6.7,6.5,6.6,7.2c0,0.2-0.1,0.5,0,0.7c0,0.2,0,0.5,0,0.7c0.1,0.6,0.3,1.1,0.6,1.6c0.3,0.5,0.7,0.9,1.2,1.2c0.2,0.1,0.3,0.2,0.5,0.3c0.2,0.1,0.4,0.2,0.5,0.2c0.1,0.1,0.3,0.1,0.4,0.1c0.2,0,0.3,0.1,0.5,0.1h-0.1c0.8,0.1,1.6-0.1,2.4-0.5c0.7-0.4,1.3-1,1.7-1.7c0.2-0.3,0.3-0.6,0.3-0.9c0.1-0.3,0.1-0.7,0.1-1c0-0.3,0-0.7-0.1-1c-0.1-0.3-0.2-0.6-0.3-0.9c-0.3-0.5-0.6-0.9-1-1.3C13,4.4,12.5,4.2,12,4c-0.4-0.1-0.9-0.2-1.4-0.2c-0.5,0-1,0.1-1.4,0.2C8.5,4.3,7.9,4.7,7.5,5.3z M11.3,5.7v1.6h1.6v0.5v0.1v0.6h0h-0.1h-1.4v1.6h-0.4h-0.2h-0.6v0V8.5H8.5V7.3h1.6V5.7H11.3z"/></g></svg>',
+ delete_row: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.75 13.83"><g><path d="M4.7,18.46l.12.08H19.73l.12-.08a.58.58,0,0,0,.22-.22l.08-.12,0-7.69-.08-.11a.77.77,0,0,0-.18-.18l-.11-.08-2.31,0-.08.28-.1.29a1.58,1.58,0,0,1-.12.29l-.14.34s0,0,.18,0H18.9v6H5.64v-6H7.35c.14,0,.2,0,.18,0l-.14-.34a2.85,2.85,0,0,1-.12-.29l-.1-.29-.07-.27-2.31,0-.11.08a.77.77,0,0,0-.18.18l-.08.11,0,7.69.08.12a.47.47,0,0,0,.09.12l.13.09ZM12.11,13a4,4,0,0,0,1.46-.21,4.51,4.51,0,0,0,1.31-.71A4,4,0,0,0,16.26,10a4.32,4.32,0,0,0-.08-2.54,4.34,4.34,0,0,0-1-1.52,4.15,4.15,0,0,0-1.54-1,4.34,4.34,0,0,0-1.35-.22A4.07,4.07,0,0,0,11,4.93,3.94,3.94,0,0,0,9.24,6.07,3.92,3.92,0,0,0,8.15,8.88a3.91,3.91,0,0,0,.12.95A4.16,4.16,0,0,0,12.11,13Zm2.35-4.14v.58H10.09V8.27h4.37v.58Z" transform="translate(-4.4 -4.71)"/></g></svg>',
+ delete_column: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13.81 15.74"><g><path d="M5.66,19.42l.12.08,7.69,0,.11-.08a.77.77,0,0,0,.18-.18l.08-.11,0-2.32-.15,0-.45-.15-.42-.18-.17-.07a1,1,0,0,0,0,.27v1.63h-6V5h6V6.62a.9.9,0,0,0,0,.26l.17-.07.42-.17a3.91,3.91,0,0,1,.45-.15l.15,0,0-2.32L13.75,4a.77.77,0,0,0-.18-.18l-.11-.08H5.79l-.13.07a.63.63,0,0,0-.21.22l-.08.12V19.08l.08.12a.47.47,0,0,0,.09.12.35.35,0,0,0,.12.1Zm9-3.67a4.16,4.16,0,0,0,2.36-.51,4.08,4.08,0,0,0,1.67-1.72,4,4,0,0,0,.35-.91,3.79,3.79,0,0,0,.1-1,4.71,4.71,0,0,0-.11-1,5,5,0,0,0-.3-.87,4.25,4.25,0,0,0-1-1.25,4.49,4.49,0,0,0-1.34-.81A4.26,4.26,0,0,0,15,7.48a3.88,3.88,0,0,0-1.41.25A4.32,4.32,0,0,0,11.86,9,4,4,0,0,0,11,10.94a4.4,4.4,0,0,0-.05.68,4.5,4.5,0,0,0,.05.68,3.93,3.93,0,0,0,.61,1.57,4.22,4.22,0,0,0,1.18,1.2,4.59,4.59,0,0,0,.48.27c.2.1.37.17.5.22a2.44,2.44,0,0,0,.45.12,4.61,4.61,0,0,0,.5.07Zm2.54-4.12v.58H12.87V11h4.37v.59Z" transform="translate(-5.37 -3.76)"/></g></svg>',
+ fixed_column_width: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6,5H18A1,1 0 0,1 19,6A1,1 0 0,1 18,7H6A1,1 0 0,1 5,6A1,1 0 0,1 6,5M21,2V4H3V2H21M15,8H17V22H15V8M7,8H9V22H7V8M11,8H13V22H11V8Z" /></svg>',
+ rotate_left: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.8 15.8"><g><path d="M0.5,10.2c0,0.1,0,0.2,0,0.3v0.2l0,0c0.1,0.3,0.3,0.6,0.4,0.9l0,0C1,11.8,1.3,12,1.5,11.9h0.1h0.2h0.1c0.1-0.1,0.3-0.3,0.4-0.5v-0.2c0-0.1,0-0.2-0.1-0.3l0,0c-0.2-0.2-0.3-0.4-0.3-0.7l0,0C1.8,10,1.7,9.9,1.5,9.8c-0.1,0-0.2,0-0.3,0H0.9C0.7,9.9,0.6,10,0.5,10.2L0.5,10.2z"/><path d="M2.2,11.5L2.2,11.5L2.2,11.5z"/><path d="M5.9,3.6L5.9,3.6L5.9,3.6z"/><path d="M0.1,7.9c0,0.3,0,0.6,0,0.9l0,0l0,0l0,0l0,0c0,0.2,0.1,0.3,0.2,0.4l0,0c0.2,0.1,0.3,0.2,0.5,0.2l0,0l0,0c0.2,0,0.4-0.1,0.5-0.3l0,0c0-0.1,0.1-0.3,0.1-0.4V8.6l0,0c0-0.2,0-0.5,0-0.7l0,0c0-0.2-0.1-0.4-0.2-0.5C1.1,7.3,0.9,7.2,0.7,7.2S0.3,7.3,0.2,7.4C0.1,7.5,0,7.7,0.1,7.9z"/><path d="M1.9,12.7L1.9,12.7c0,0.2,0,0.4,0.2,0.5l0,0l0.2,0.3l0,0c0.2,0.1,0.3,0.2,0.5,0.4l0,0l0,0l0,0l0,0C2.9,14,3,14.1,3.2,14.1s0.4-0.1,0.5-0.2c0.1-0.2,0.2-0.3,0.2-0.5v-0.1c0-0.2-0.1-0.4-0.2-0.5l0,0l-0.4-0.4l-0.2-0.2l0,0C3,12.1,2.8,12,2.6,12l0,0c-0.2,0-0.4,0.1-0.5,0.2l0,0C2,12.3,1.9,12.5,1.9,12.7z"/><path d="M6.6,15c0,0.2,0.1,0.4,0.2,0.5c0.1,0.1,0.2,0.2,0.4,0.3l0,0c0.3,0,0.5,0,0.7,0h0.3l0,0c0.2,0,0.4-0.1,0.5-0.2c0.1-0.2,0.2-0.3,0.2-0.5l0,0l0,0c0-0.2-0.1-0.4-0.2-0.5l0,0c-0.1-0.1-0.3-0.2-0.5-0.2l0,0H7.9c-0.1,0-0.3,0-0.5,0l0,0H7.3c-0.2-0.1-0.3,0-0.5,0.1l0,0C6.7,14.6,6.6,14.8,6.6,15L6.6,15L6.6,15L6.6,15z"/><path d="M4.2,7.4C4,7.5,4,7.7,4,7.9c0,0.2,0,0.4,0.2,0.5l0,0l3.2,3.2l0,0c0.1,0.1,0.3,0.2,0.5,0.2s0.3-0.1,0.5-0.2l0,0l3.2-3.2l0,0c0.1-0.1,0.2-0.3,0.2-0.5c0-0.2-0.1-0.4-0.2-0.5l0,0C11.5,7.3,11,6.7,10,5.8l0,0L8.4,4.2l0,0C8.3,4.1,8.1,4,7.9,4S7.5,4.1,7.4,4.2L4.2,7.4L4.2,7.4z M6.8,9L5.7,7.9l2.2-2.2l2.3,2.2l-2.3,2.2C7.7,9.9,7.3,9.5,6.8,9L6.8,9z"/><path d="M4.1,14.1C4,14.2,4,14.3,4,14.4v0.2l0,0c0.1,0.1,0.2,0.3,0.4,0.4l0,0c0.3,0.1,0.6,0.2,0.9,0.4h0.1h0.1l0,0c0.2,0,0.3-0.1,0.5-0.1l0,0c0.2-0.1,0.3-0.3,0.3-0.4l0,0l0,0l0,0l0,0v-0.2c0-0.1-0.1-0.2-0.1-0.3l0,0C6.1,14.2,6,14.1,5.8,14l0,0c-0.3-0.1-0.5-0.2-0.8-0.2l0,0c-0.1-0.1-0.2-0.1-0.3-0.1H4.5C4.3,13.7,4.2,13.9,4.1,14.1z"/><path d="M9.3,14.4c0,0.1-0.1,0.3,0,0.4V15l0,0c0,0.1,0.1,0.3,0.5,0.4c0.1,0.1,0.3,0.1,0.4,0.1l0,0h0.1l0,0c0.3-0.1,0.6-0.2,0.9-0.3l0,0c0.1-0.1,0.2-0.2,0.3-0.4l0.1-0.3c0-0.1-0.1-0.2-0.1-0.3l0,0c-0.1-0.2-0.2-0.3-0.4-0.4l0,0h-0.3c-0.1,0-0.2,0-0.3,0l0,0c-0.2,0.1-0.5,0.2-0.8,0.3l0,0C9.5,14.1,9.4,14.2,9.3,14.4L9.3,14.4z"/><path d="M11.4,14.7L11.4,14.7L11.4,14.7z"/><path d="M9.5,15.3L9.5,15.3L9.5,15.3z"/><path d="M15.9,7.9c0-1-0.2-2-0.6-3l0,0c-0.4-1-1-1.9-1.7-2.6C12.8,1.6,12,1,11,0.6l0,0C10.1,0.2,9,0,8,0C7.3,0,6.5,0.1,5.8,0.3l0,0C5.2,0.5,4.6,0.8,4,1.1L3.1,0.2l0,0C2.9,0.1,2.8,0,2.6,0H2.4l0,0C2.2,0,2,0.2,1.9,0.4l0,0L0.1,4.9l0,0C0,5,0,5.1,0,5.2c0,0.2,0.1,0.4,0.2,0.5l0,0c0.2,0.1,0.3,0.2,0.5,0.2h0.1H1l0,0l4.7-1.8l0,0C5.9,4,6.1,3.8,6.1,3.6V3.4C6.1,3.2,6,3,5.9,2.9l0,0L5.1,2.1c0.4-0.2,0.8-0.4,1.3-0.5c0.5-0.1,1.1-0.2,1.7-0.2c0.9,0,1.7,0.2,2.5,0.5l0,0c0.8,0.3,1.5,0.8,2.1,1.4c0.6,0.6,1.1,1.3,1.4,2.1l0,0c0.3,0.8,0.5,1.6,0.5,2.5s-0.2,1.7-0.5,2.5l0,0c-0.3,0.8-0.8,1.5-1.4,2.1c-0.2,0.2-0.4,0.3-0.6,0.5l0,0c-0.2,0.1-0.3,0.3-0.3,0.5v0.1c0,0.1,0,0.3,0.1,0.4l0,0c0.1,0.2,0.3,0.3,0.5,0.3l0,0c0.1,0,0.3-0.1,0.4-0.2l0,0l0,0l0,0l0,0c0.2-0.2,0.5-0.4,0.7-0.6l0,0l0,0l0,0l0,0c0.7-0.8,1.3-1.6,1.7-2.6C15.6,10,15.8,9,15.9,7.9z M1.9,4C2,3.8,2.1,3.5,2.3,3.1l0,0L2.7,2l1.2,1.2L1.9,4z"/><path d="M6.8,15.5L6.8,15.5L6.8,15.5z"/></g></svg>',
+ rotate_right: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.8 15.8"><g><path d="M9.9,15.3L9.9,15.3L9.9,15.3z"/><path d="M6.9,15.1L6.9,15.1c0,0.1,0.1,0.3,0.2,0.4l0,0c0.1,0.2,0.3,0.3,0.5,0.3l0,0h0.3c0.2,0,0.4,0,0.7,0l0,0c0.2-0.1,0.3-0.2,0.4-0.3c0.1-0.1,0.2-0.2,0.2-0.4V15c0-0.2-0.1-0.4-0.2-0.4c-0.2-0.1-0.3-0.2-0.5-0.2H8.4l0,0c-0.1,0-0.3,0-0.5,0H7.6l0,0c-0.2,0-0.4,0.1-0.5,0.2C7,14.7,6.9,14.9,6.9,15.1z"/><path d="M6.5,14.4L6.5,14.4L6.5,14.4z"/><path d="M5.8,5.8L5.8,5.8c-1,0.9-1.5,1.5-1.7,1.6l0,0C4,7.5,4,7.7,4,7.9c0,0.2,0,0.4,0.2,0.5l0,0l3.2,3.2l0,0c0.2,0.1,0.3,0.2,0.5,0.2s0.4-0.1,0.5-0.2l0,0l3.2-3.2l0,0c0.1-0.1,0.2-0.3,0.2-0.5c0-0.2-0.1-0.4-0.2-0.5l0,0L8.4,4.2C8.3,4.1,8.1,4,7.9,4C7.7,4,7.5,4.1,7.4,4.2l0,0L5.8,5.8z M5.6,7.9l2.3-2.2l2.2,2.2L9,9l0,0l0,0l0,0l0,0c-0.5,0.6-0.9,0.9-1.1,1.1L5.6,7.9z"/><path d="M9,15.5L9,15.5L9,15.5z"/><path d="M9.6,14.7v0.2l0,0l0,0l0,0l0,0c0.1,0.2,0.1,0.3,0.3,0.3c0.1,0.1,0.3,0.1,0.4,0.1l0,0h0.1h0.1c0.3-0.1,0.6-0.3,0.9-0.4l0,0c0.1-0.1,0.2-0.2,0.3-0.4l0,0v-0.2c0-0.1,0-0.2-0.1-0.3c-0.1-0.2-0.2-0.3-0.4-0.4H11c-0.1,0-0.2,0.1-0.3,0.1l0,0c-0.2,0.1-0.4,0.2-0.7,0.3l0,0l0,0c-0.1,0.1-0.3,0.2-0.4,0.4C9.6,14.5,9.6,14.6,9.6,14.7z"/><path d="M9,14.5L9,14.5L9,14.5z"/><path d="M9.6,14.4L9.6,14.4L9.6,14.4z"/><path d="M11.7,14L11.7,14L11.7,14z"/><path d="M15.6,7.4L15.6,7.4L15.6,7.4z"/><path d="M15,9.4c0.2,0,0.4,0,0.6-0.2l0,0c0.1-0.1,0.2-0.2,0.2-0.4l0,0l0,0l0,0l0,0c0-0.3,0-0.6,0-0.9c0-0.2-0.1-0.4-0.2-0.5c-0.1-0.1-0.3-0.2-0.5-0.2s-0.4,0.1-0.5,0.2c-0.1,0.1-0.2,0.3-0.2,0.5l0,0c0,0.2,0,0.4,0,0.7l0,0v0.1c0,0.1,0,0.3,0.1,0.4l0,0C14.6,9.3,14.8,9.4,15,9.4L15,9.4L15,9.4z"/><path d="M14,12h0.1h0.2h0.1c0.2,0,0.5-0.2,0.6-0.4l0,0c0.2-0.3,0.3-0.6,0.4-0.9l0,0v-0.2c0-0.1-0.1-0.2-0.1-0.3c-0.1-0.2-0.2-0.3-0.4-0.4h-0.3c-0.1,0-0.2,0-0.3,0C14.2,9.9,14,10,14,10.3l0,0c-0.1,0.2-0.2,0.5-0.3,0.7l0,0c-0.1,0.1-0.1,0.2-0.1,0.3v0.2l0,0l0,0C13.6,11.6,13.8,11.8,14,12z"/><path d="M14.6,7.4L14.6,7.4L14.6,7.4z"/><path d="M4.4,14.2c-0.1,0.1-0.1,0.2-0.1,0.3l0.1,0.2c0,0.2,0.2,0.3,0.3,0.4l0,0c0.3,0.1,0.6,0.3,1.1,0.4l0,0h0.1l0,0c0.1,0,0.2-0.1,0.4-0.2c0.1,0,0.2-0.2,0.3-0.3l0,0v-0.2c0-0.1-0.1-0.3-0.2-0.4c-0.1-0.1-0.2-0.2-0.4-0.3l0,0c-0.2-0.1-0.5-0.2-0.7-0.3l0,0c-0.1,0-0.2,0-0.3,0H4.7l0,0C4.6,13.9,4.4,14,4.4,14.2L4.4,14.2z"/><path d="M11.9,13.3c0,0.2,0.1,0.4,0.2,0.6c0.1,0.1,0.3,0.2,0.5,0.2s0.4-0.1,0.5-0.2l0,0l0,0l0,0l0,0c0.1-0.1,0.3-0.3,0.4-0.4l0,0l0.2-0.3l0,0c0.1-0.2,0.2-0.3,0.2-0.5l0,0c0-0.2-0.1-0.4-0.2-0.5l0,0c-0.1-0.1-0.3-0.2-0.5-0.2l0,0c-0.2,0-0.4,0.1-0.5,0.2l0,0l-0.2,0.2l-0.4,0.4l0,0C12,13,11.9,13.1,11.9,13.3L11.9,13.3z"/><path d="M12.1,13.8L12.1,13.8L12.1,13.8z"/><path d="M11.9,13.3L11.9,13.3L11.9,13.3z"/><path d="M15.9,5.2c0-0.1-0.1-0.2-0.1-0.3l0,0L14,0.4l0,0C13.9,0.2,13.7,0,13.5,0l0,0l0,0h-0.2c-0.2,0-0.4,0.1-0.5,0.2l0,0l-0.9,0.9c-0.5-0.3-1.1-0.6-1.8-0.8l0,0C9.4,0.1,8.7,0,7.9,0c-1,0-2,0.2-3,0.6S3,1.6,2.3,2.3C1.6,3.1,1,3.9,0.6,4.9l0,0C0.2,5.8,0,6.8,0,7.9c0,1,0.2,2,0.6,3s0.9,1.8,1.7,2.6l0,0l0,0l0,0l0,0c0.2,0.2,0.5,0.4,0.7,0.6l0,0l0,0l0,0l0,0c0.2,0.1,0.3,0.2,0.5,0.2l0,0c0.2,0,0.4-0.1,0.6-0.3l0,0c0.1-0.1,0.1-0.3,0.1-0.4v-0.1l0,0C4.1,13.3,4,13.1,3.9,13l0,0c-0.2-0.1-0.4-0.3-0.6-0.5c-0.6-0.6-1.1-1.3-1.4-2.1l0,0C1.6,9.6,1.4,8.8,1.4,7.9s0.2-1.7,0.5-2.5l0,0c0.3-0.8,0.8-1.5,1.4-2.1c0.6-0.6,1.3-1.1,2.1-1.4l0,0C6.2,1.6,7,1.4,7.9,1.4c0.6,0,1.1,0.1,1.7,0.2c0.5,0.1,0.9,0.3,1.3,0.5l-0.8,0.8l0,0C10,3.1,9.9,3.2,9.9,3.4v0.2l0,0l0,0c0,0.2,0.2,0.4,0.4,0.5l0,0l4.5,1.8l0,0H15h0.1c0.2,0,0.4-0.1,0.5-0.2l0,0C15.7,5.6,15.8,5.4,15.9,5.2z M11.8,3.2L13,2l0.4,1.1l0,0c0.2,0.4,0.3,0.7,0.4,0.9L11.8,3.2z"/></g></svg>',
+ mirror_horizontal: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14.75 15.74"><g><path d="M13.75,3.76l5.9,15.74h-5.9V3.76ZM4.9,19.5,10.8,3.76V19.5H4.9Z" transform="translate(-4.9 -3.76)"/></g></svg>',
+ mirror_vertical: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 14.75"><g><path d="M20.15,13.1,4.41,19V13.1H20.15ZM4.41,4.25l15.74,5.9H4.41V4.25Z" transform="translate(-4.41 -4.25)"/></g></svg>',
+ checked: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.75 12.1"><g><path d="M4.59,12.23l.12.18L9.43,17.5a.58.58,0,0,0,.84,0L20,7.45h0a.58.58,0,0,0,0-.84l-.85-.85a.58.58,0,0,0-.84,0H18.2l-8.12,8.41a.29.29,0,0,1-.42,0l-3.4-3.63a.58.58,0,0,0-.84,0l-.85.85a.6.6,0,0,0-.14.21.51.51,0,0,0,0,.44c.05.06.1.13.16.19Z" transform="translate(-4.38 -5.58)"/></g></svg>',
+ line_break: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19,6a1,1,0,0,0-1,1v4a1,1,0,0,1-1,1H7.41l1.3-1.29A1,1,0,0,0,7.29,9.29l-3,3a1,1,0,0,0-.21.33,1,1,0,0,0,0,.76,1,1,0,0,0,.21.33l3,3a1,1,0,0,0,1.42,0,1,1,0,0,0,0-1.42L7.41,14H17a3,3,0,0,0,3-3V7A1,1,0,0,0,19,6Z"/></svg>',
+ audio: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.84 14,18.7V20.77C18,19.86 21,16.28 21,12C21,7.72 18,4.14 14,3.23M16.5,12C16.5,10.23 15.5,8.71 14,7.97V16C15.5,15.29 16.5,13.76 16.5,12M3,9V15H7L12,20V4L7,9H3Z" /></svg>',
+ image_gallery: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="30 30 150 150"><g><path d="M152.775,120.548V51.651c0-12.271-9.984-22.254-22.254-22.254H43.727c-12.271,0-22.254,9.983-22.254,22.254v68.896c0,12.27,9.983,22.254,22.254,22.254h86.795C142.791,142.802,152.775,132.817,152.775,120.548z M36.394,51.651c0-4.042,3.291-7.333,7.333-7.333h86.795c4.042,0,7.332,3.291,7.332,7.333v23.917l-14.938-17.767c-1.41-1.678-3.487-2.649-5.68-2.658h-0.029c-2.184,0-4.255,0.954-5.674,2.613L76.709,98.519l-9.096-9.398c-1.427-1.474-3.392-2.291-5.448-2.273c-2.052,0.025-4.004,0.893-5.396,2.4L36.394,111.32V51.651z M41.684,127.585l20.697-22.416l9.312,9.622c1.461,1.511,3.489,2.334,5.592,2.27c2.101-0.066,4.075-1.013,5.44-2.612l34.436-40.308l20.693,24.613v21.794c0,4.042-3.29,7.332-7.332,7.332H43.727C43.018,127.88,42.334,127.775,41.684,127.585z M182.616,152.5V75.657c0-4.12-3.34-7.46-7.461-7.46c-4.119,0-7.46,3.34-7.46,7.46V152.5c0,4.112-3.347,7.46-7.461,7.46h-94c-4.119,0-7.46,3.339-7.46,7.459c0,4.123,3.341,7.462,7.46,7.462h94C172.576,174.881,182.616,164.841,182.616,152.5z"/></g></svg>',
+ // More icons
+ more_text: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="10 10 180 180"><g><path d="M49.711,142.188h49.027c2.328,0.002,4.394,1.492,5.129,3.699l9.742,29.252c0.363,1.092,1.385,1.828,2.537,1.83l15.883,0.01c0.859,0,1.667-0.412,2.17-1.109s0.641-1.594,0.37-2.41l-16.625-50.045L86.503,28.953c-0.36-1.097-1.383-1.839-2.537-1.842H64.532c-1.153-0.001-2.178,0.736-2.542,1.831L13.847,173.457c-0.271,0.816-0.135,1.713,0.369,2.412c0.503,0.697,1.311,1.109,2.171,1.109h15.872c1.151,0,2.173-0.736,2.537-1.828l9.793-29.287C45.325,143.66,47.39,142.18,49.711,142.188L49.711,142.188z M53.493,119.098l15.607-46.9c0.744-2.196,2.806-3.674,5.125-3.674s4.381,1.478,5.125,3.674l15.607,46.904c0.537,1.621,0.263,3.402-0.736,4.789c-1.018,1.408-2.649,2.24-4.386,2.24H58.615c-1.736,0-3.368-0.832-4.386-2.24C53.23,122.504,52.956,120.721,53.493,119.098L53.493,119.098z M190.465,63.32c0-2.919-1.015-5.396-3.059-7.428c-2.029-2.031-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.016-7.388,3.047c-2.029,2.032-3.056,4.498-3.056,7.386c0,2.889,1.026,5.354,3.056,7.385c2.032,2.032,4.499,3.059,7.388,3.059c2.887,0,5.354-1.026,7.383-3.059C189.45,68.633,190.465,66.178,190.465,63.32L190.465,63.32z M190.465,101.994c0-2.858-1.015-5.313-3.059-7.333c-2.029-2.042-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.005-7.388,3.047c-2.029,2.021-3.056,4.486-3.056,7.376c0,2.887,1.026,5.352,3.056,7.395c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,107.389,190.465,104.914,190.465,101.994L190.465,101.994z M190.465,140.76c0-2.918-1.015-5.395-3.059-7.438c-2.029-2.041-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.006-7.388,3.047c-2.029,2.043-3.056,4.52-3.056,7.438c0,2.922,1.026,5.398,3.056,7.439c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,146.158,190.465,143.682,190.465,140.76L190.465,140.76z"/></g></svg>',
+ more_paragraph: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="10 10 180 180"><g><path d="M128.39,28.499H63.493c-25.558,0-46.354,20.796-46.354,46.354c0,25.559,20.796,46.353,46.354,46.353h9.271v55.625h18.542V47.04h9.271V176.83h18.543V47.04h9.271V28.499z M72.764,102.664h-9.271c-15.337,0-27.813-12.475-27.813-27.812c0-15.336,12.476-27.813,27.813-27.813h9.271V102.664z M190.465,63.32c0-2.919-1.015-5.396-3.059-7.428c-2.029-2.031-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.016-7.388,3.047c-2.029,2.032-3.056,4.498-3.056,7.386c0,2.889,1.026,5.354,3.056,7.385c2.032,2.032,4.499,3.059,7.388,3.059c2.887,0,5.354-1.026,7.383-3.059C189.45,68.633,190.465,66.178,190.465,63.32L190.465,63.32z M190.465,101.994c0-2.858-1.015-5.313-3.059-7.333c-2.029-2.042-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.005-7.388,3.047c-2.029,2.021-3.056,4.486-3.056,7.376c0,2.887,1.026,5.352,3.056,7.395c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,107.389,190.465,104.914,190.465,101.994L190.465,101.994z M190.465,140.76c0-2.918-1.015-5.395-3.059-7.438c-2.029-2.041-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.006-7.388,3.047c-2.029,2.043-3.056,4.52-3.056,7.438c0,2.922,1.026,5.398,3.056,7.439c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,146.158,190.465,143.682,190.465,140.76L190.465,140.76z"/></g></svg>',
+ more_plus: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="35 30 140 140"><g><path d="M137.215,102.045c0,3.498-2.835,6.332-6.333,6.332H24.549c-3.498,0-6.334-2.834-6.334-6.332l0,0c0-3.498,2.836-6.333,6.334-6.333h106.333C134.38,95.711,137.215,98.547,137.215,102.045L137.215,102.045z M77.715,161.545c-3.498,0-6.333-2.836-6.333-6.334V48.878c0-3.498,2.836-6.333,6.333-6.333l0,0c3.498,0,6.334,2.835,6.334,6.333v106.333C84.049,158.709,81.213,161.545,77.715,161.545L77.715,161.545z M190.465,63.32c0-2.919-1.015-5.396-3.059-7.428c-2.029-2.031-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.016-7.388,3.047c-2.029,2.032-3.056,4.498-3.056,7.386c0,2.889,1.026,5.354,3.056,7.385c2.032,2.032,4.499,3.059,7.388,3.059c2.887,0,5.354-1.026,7.383-3.059C189.45,68.632,190.465,66.177,190.465,63.32L190.465,63.32z M190.465,101.993c0-2.858-1.015-5.313-3.059-7.333c-2.029-2.042-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.005-7.388,3.047c-2.029,2.021-3.056,4.486-3.056,7.376c0,2.888,1.026,5.353,3.056,7.396c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,107.389,190.465,104.914,190.465,101.993L190.465,101.993z M190.465,140.76c0-2.918-1.015-5.395-3.059-7.438c-2.029-2.041-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.006-7.388,3.047c-2.029,2.043-3.056,4.52-3.056,7.438c0,2.922,1.026,5.398,3.056,7.439c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,146.158,190.465,143.682,190.465,140.76L190.465,140.76z"/></g></svg>',
+ more_horizontal: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.76 3.58"><g><path d="M4.64,10.73a1.84,1.84,0,0,1,.65-.65,1.76,1.76,0,0,1,1.79,0A1.79,1.79,0,0,1,8,11.63a1.84,1.84,0,0,1-.25.9,1.69,1.69,0,0,1-.65.65,1.8,1.8,0,0,1-2.69-1.55A2.08,2.08,0,0,1,4.64,10.73Zm6.09,0a1.84,1.84,0,0,1,.65-.65,1.78,1.78,0,0,1,2.67,1.55,1.73,1.73,0,0,1-.24.9,1.84,1.84,0,0,1-.65.65,1.76,1.76,0,0,1-1.79,0,1.79,1.79,0,0,1-.64-2.44Zm6.08,0a1.69,1.69,0,0,1,.65-.65,1.76,1.76,0,0,1,1.79,0,1.79,1.79,0,0,1,.9,1.54,1.73,1.73,0,0,1-.24.9,1.84,1.84,0,0,1-.65.65,1.8,1.8,0,0,1-2.69-1.55A2,2,0,0,1,16.81,10.73Z" transform="translate(-4.39 -9.84)"/></g></svg>',
+ more_vertical: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3.94 15.75"><g><path d="M12.28,7.69a1.92,1.92,0,0,1-1.39-.58,2,2,0,0,1-.58-1.39,1.92,1.92,0,0,1,.58-1.39,2,2,0,0,1,1.39-.58,1.92,1.92,0,0,1,1.39.58,2,2,0,0,1,.58,1.39,1.92,1.92,0,0,1-.58,1.39,2,2,0,0,1-1.39.58Zm0,2a1.92,1.92,0,0,1,1.39.58,2,2,0,0,1,.58,1.39A1.92,1.92,0,0,1,13.67,13a2,2,0,0,1-1.39.58A1.92,1.92,0,0,1,10.89,13a2,2,0,0,1-.58-1.39,2,2,0,0,1,2-2Zm0,5.9a1.92,1.92,0,0,1,1.39.58,2,2,0,0,1,.58,1.39,1.92,1.92,0,0,1-.58,1.39,2,2,0,0,1-1.39.58,1.92,1.92,0,0,1-1.39-.58,2,2,0,0,1-.58-1.39,1.92,1.92,0,0,1,.58-1.39,1.94,1.94,0,0,1,1.39-.58Z" transform="translate(-10.31 -3.75)"/></g></svg>',
+ // Not currently used
+ attachment: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8.38 15.68"><g><path d="M15.23,6h1v9.78a3.88,3.88,0,0,1-1.31,2.45,4,4,0,0,1-6.57-2.45V7A3,3,0,0,1,9.2,4.89a3,3,0,0,1,5,2.09v8.31a1.92,1.92,0,0,1-.58,1.39,2,2,0,0,1-1.39.58,1.92,1.92,0,0,1-1.39-.58,2,2,0,0,1-.58-1.39V8h1v7.32a1,1,0,0,0,.29.69,1,1,0,0,0,.69.28A.9.9,0,0,0,13,16a1,1,0,0,0,.29-.69V7a1.92,1.92,0,0,0-.58-1.39A2,2,0,0,0,11.27,5a1.92,1.92,0,0,0-1.39.58A2,2,0,0,0,9.33,7v8.31a3,3,0,1,0,5.9,0V6Z" transform="translate(-8.08 -3.78)"/></g></svg>',
+ map: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11.7 15.62"><g><path d="M12.05,12.42a2.93,2.93,0,1,1,2.07-5A2.88,2.88,0,0,1,15,9.49a3,3,0,0,1-.86,2.07,2.89,2.89,0,0,1-2.07.86Zm0-5.36a2.43,2.43,0,0,0-1.72,4.16,2.48,2.48,0,0,0,1.72.72,2.44,2.44,0,0,0,0-4.88Zm0-3.3A5.84,5.84,0,0,1,17.9,9.62a9.94,9.94,0,0,1-1.73,5A33.59,33.59,0,0,1,12.84,19a1.52,1.52,0,0,1-.23.2,1,1,0,0,1-.55.2h0a1,1,0,0,1-.55-.2,1.52,1.52,0,0,1-.23-.2,33.59,33.59,0,0,1-3.33-4.32,9.93,9.93,0,0,1-1.72-5,5.84,5.84,0,0,1,5.85-5.86ZM12,18.34l.08.05.06-.06a35.58,35.58,0,0,0,3.06-3.93,9.35,9.35,0,0,0,1.74-4.77,4.88,4.88,0,0,0-4.88-4.88A4.79,4.79,0,0,0,8.6,6.17,4.84,4.84,0,0,0,7.17,9.62,9.29,9.29,0,0,0,8.91,14.4,36,36,0,0,0,12,18.34Z" transform="translate(-6.2 -3.76)"/></g></svg>',
+ magic_stick: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.73 15.75"><g><path d="M19.86,19.21a1,1,0,0,0,.28-.68,1,1,0,0,0-.28-.7L13,10.93a1,1,0,0,0-.7-.28,1,1,0,0,0-.68,1.65l6.9,6.9a1,1,0,0,0,.69.29.93.93,0,0,0,.69-.28ZM9.19,8.55a3,3,0,0,0,1.68,0,14.12,14.12,0,0,0,1.41-.32A11.26,11.26,0,0,0,10.8,7.06c-.56-.36-.86-.56-.91-.58S10,5.91,10,5.11s0-1.26-.15-1.37a4.35,4.35,0,0,0-1.19.71c-.53.4-.81.62-.87.68a9,9,0,0,0-2-.6,6.84,6.84,0,0,0-.76-.09s0,.27.08.77a8.6,8.6,0,0,0,.61,2q-.09.09-.69.87a3.59,3.59,0,0,0-.68,1.17c.12.17.57.23,1.36.15S7,9.26,7.15,9.23s.21.36.57.91a10.49,10.49,0,0,0,1.14,1.48c0-.1.14-.57.31-1.4a3,3,0,0,0,0-1.67Z" transform="translate(-4.41 -3.74)"/></g></svg>',
+ empty_file: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12.78 15.75"><g><path d="M14.73,3.76,18.67,7.7v9.84a2,2,0,0,1-2,2H7.84a1.89,1.89,0,0,1-1.38-.58,2,2,0,0,1-.57-1.39V5.73a1.93,1.93,0,0,1,.57-1.38,2,2,0,0,1,1.38-.58h6.62l.26,0v0Zm2.95,4.92h-2a1.93,1.93,0,0,1-1.38-.57,2,2,0,0,1-.58-1.4V6.17c0-.36,0-.84,0-1.43H7.85a1,1,0,0,0-.7.29,1,1,0,0,0-.29.7V17.54a1,1,0,0,0,.29.69,1,1,0,0,0,.69.29h8.85a1,1,0,0,0,.71-.29.92.92,0,0,0,.28-.69Zm0-1L14.73,4.74v2A1,1,0,0,0,15,7.4a1,1,0,0,0,.69.29Z" transform="translate(-5.89 -3.76)"/></g></svg>'
+};
--- /dev/null
+export interface Lang {
+ code: string,
+ toolbar: {
+ default: string,
+ save: string,
+ font: string,
+ formats: string,
+ fontSize: string,
+ bold: string,
+ underline: string,
+ italic: string,
+ strike: string,
+ subscript: string,
+ superscript: string,
+ removeFormat: string,
+ fontColor: string,
+ hiliteColor: string,
+ indent: string,
+ outdent: string,
+ align: string,
+ alignLeft: string,
+ alignRight: string,
+ alignCenter: string,
+ alignJustify: string,
+ list: string,
+ orderList: string,
+ unorderList: string,
+ horizontalRule: string,
+ hr_solid: string,
+ hr_dotted: string,
+ hr_dashed: string,
+ table: string,
+ link: string,
+ math: string,
+ image: string,
+ video: string,
+ audio: string,
+ fullScreen: string,
+ showBlocks: string,
+ codeView: string,
+ undo: string,
+ redo: string,
+ preview: string,
+ print: string,
+ tag_p: string,
+ tag_div: string,
+ tag_h: string,
+ tag_blockquote: string,
+ tag_pre: string,
+ template: string,
+ lineHeight: string,
+ paragraphStyle: string,
+ textStyle: string,
+ imageGallery: string,
+ mention: string
+ };
+ dialogBox: {
+ linkBox: {
+ title: string,
+ url: string,
+ text: string,
+ newWindowCheck: string
+ },
+ mathBox: {
+ title: string,
+ inputLabel: string,
+ fontSizeLabel: string,
+ previewLabel: string
+ },
+ imageBox: {
+ title: string,
+ file: string,
+ url: string,
+ altText: string
+ },
+ videoBox: {
+ title: string,
+ file: string,
+ url: string
+ },
+ audioBox: {
+ title: string,
+ file: string,
+ url: string
+ },
+ browser: {
+ tags: string,
+ search: string,
+ },
+ caption: string,
+ close: string,
+ submitButton: string,
+ revertButton: string,
+ proportion: string,
+ basic: string,
+ left: string,
+ right: string,
+ center: string,
+ width: string,
+ height: string,
+ size: string,
+ ratio: string
+ };
+ controller: {
+ edit: string,
+ unlink: string,
+ remove: string,
+ insertRowAbove: string,
+ insertRowBelow: string,
+ deleteRow: string,
+ insertColumnBefore: string,
+ insertColumnAfter: string,
+ deleteColumn: string,
+ fixedColumnWidth: string,
+ resize100: string,
+ resize75: string,
+ resize50: string,
+ resize25: string,
+ autoSize: string,
+ mirrorHorizontal: string,
+ mirrorVertical: string,
+ rotateLeft: string,
+ rotateRight: string,
+ maxSize: string,
+ minSize: string,
+ tableHeader: string,
+ mergeCells: string,
+ splitCells: string,
+ HorizontalSplit: string,
+ VerticalSplit: string
+ };
+ menu: {
+ spaced: string,
+ bordered: string,
+ neon: string,
+ translucent: string,
+ shadow: string
+ code: string
+ };
+}
\ No newline at end of file
--- /dev/null
+import { Lang } from './Lang';
+
+declare const ckb: Lang;
+
+export default ckb;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'ckb',
+ toolbar: {
+ default: 'بنهڕهت',
+ save: 'پاشهكهوتكردن',
+ font: 'فۆنت',
+ formats: 'Formats',
+ fontSize: 'قهباره',
+ bold: 'تۆخكردن',
+ underline: 'هێڵ بهژێردا بێنه',
+ italic: 'لار',
+ strike: 'هێڵ بهناودا بێنه',
+ subscript: 'ژێرسکریپت',
+ superscript: 'سەرنووس',
+ removeFormat: 'لابردنی فۆرمات',
+ fontColor: 'رهنگی فۆنت',
+ hiliteColor: 'رهنگی دیاركراو',
+ indent: 'بۆشایی بەجێهێشتن',
+ outdent: 'لابردنی بۆشایی',
+ align: 'ئاراسته',
+ alignLeft: 'لای چهپ',
+ alignRight: 'لای راست',
+ alignCenter: 'ناوهند',
+ alignJustify: 'بهرێكی دابهش بكه',
+ list: 'لیست',
+ orderList: 'لیستی ریزكراو',
+ unorderList: 'لیستی ریزنهكراو',
+ horizontalRule: 'هێڵی ئاسۆیی',
+ hr_solid: 'پتهو',
+ hr_dotted: 'نوكته نوكته',
+ hr_dashed: 'داش داش',
+ table: 'خشته',
+ link: 'بهستهر',
+ math: 'بیركاری',
+ image: 'وێنه',
+ video: 'ڤیدیۆ',
+ audio: 'دهنگ',
+ fullScreen: 'پڕ به شاشه',
+ showBlocks: 'بڵۆك نیشانبده',
+ codeView: 'بینینی كۆدهكان',
+ undo: 'وەک خۆی لێ بکەوە',
+ redo: 'هەڵگەڕاندنەوە',
+ preview: 'پێشبینین',
+ print: 'پرینت',
+ tag_p: 'پهرهگراف',
+ tag_div: 'ی ئاسایی (DIV)',
+ tag_h: 'سەرپەڕە',
+ tag_blockquote: 'دهق',
+ tag_pre: 'كۆد',
+ template: 'قاڵب',
+ lineHeight: 'بڵندی دێر',
+ paragraphStyle: 'ستایلی پهرهگراف',
+ textStyle: 'ستایلی نوسین',
+ imageGallery: 'گالهری وێنهكان',
+ mention: 'تنويه ب'
+ },
+ dialogBox: {
+ linkBox: {
+ title: 'بهستهر دابنێ',
+ url: 'بهستهر',
+ text: 'تێكستی بهستهر',
+ newWindowCheck: 'له پهنجهرهیهكی نوێ بكهرهوه'
+ },
+ mathBox: {
+ title: 'بیركاری',
+ inputLabel: 'نیشانهكانی بیركاری',
+ fontSizeLabel: 'قهبارهی فۆنت',
+ previewLabel: 'پێشبینین'
+ },
+ imageBox: {
+ title: 'وێنهیهك دابنێ',
+ file: 'فایلێك ههڵبژێره',
+ url: 'بهستهری وێنه',
+ altText: 'نوسینی جێگرهوه'
+ },
+ videoBox: {
+ title: 'ڤیدیۆیهك دابنێ',
+ file: 'فایلێك ههڵبژێره',
+ url: 'YouTube/Vimeo بهستهری لهناودانان وهك '
+ },
+ audioBox: {
+ title: 'دهنگێك دابنێ',
+ file: 'فایلێك ههڵبژێره',
+ url: 'بهستهری دهنگ'
+ },
+ browser: {
+ tags: 'تاگهكان',
+ search: 'گهران',
+ },
+ caption: 'پێناسهیهك دابنێ',
+ close: 'داخستن',
+ submitButton: 'ناردن',
+ revertButton: 'بیگەڕێنەوە سەر باری سەرەتایی',
+ proportion: 'رێژهكان وهك خۆی بهێڵهوه',
+ basic: 'سهرهتایی',
+ left: 'چهپ',
+ right: 'راست',
+ center: 'ناوەڕاست',
+ width: 'پانی',
+ height: 'بهرزی',
+ size: 'قهباره',
+ ratio: 'رێژه'
+ },
+ controller: {
+ edit: 'دەسکاریکردن',
+ unlink: 'سڕینەوەی بەستەر',
+ remove: 'سڕینهوه',
+ insertRowAbove: 'ریزك له سهرهوه زیادبكه',
+ insertRowBelow: 'ریزێك له خوارهوه زیادبكه',
+ deleteRow: 'ریز بسرهوه',
+ insertColumnBefore: 'ستونێك له پێشهوه زیادبكه',
+ insertColumnAfter: 'ستونێك له دواوه زیادبكه',
+ deleteColumn: 'ستونێك بسرهوه',
+ fixedColumnWidth: 'پانی ستون نهگۆربكه',
+ resize100: 'قهباره بگۆره بۆ ١٠٠%',
+ resize75: 'قهباره بگۆره بۆ ٧٥%',
+ resize50: 'قهباره بگۆره بۆ ٥٠%',
+ resize25: 'قهباره بگۆره بۆ ٢٥%',
+ autoSize: 'قهبارهی خۆكارانه',
+ mirrorHorizontal: 'ههڵگهرێنهوه بهدهوری تهوهرهی ئاسۆیی',
+ mirrorVertical: 'ههڵگهرێنهوه بهدهوری تهوهرهی ستونی',
+ rotateLeft: 'بسوڕێنه بهلای چهپدا',
+ rotateRight: 'بسورێنه بهلای راستدا',
+ maxSize: 'گهورهترین قهباره',
+ minSize: 'بچوكترین قهباره',
+ tableHeader: 'سهردێری خشتهك',
+ mergeCells: 'خانهكان تێكهڵبكه',
+ splitCells: 'خانهكان لێك جیابكهوه',
+ HorizontalSplit: 'جیاكردنهوهی ئاسۆیی',
+ VerticalSplit: 'جیاكردنهوهی ستونی'
+ },
+ menu: {
+ spaced: 'بۆشای ههبێت',
+ bordered: 'لێواری ههبێت',
+ neon: 'نیۆن',
+ translucent: 'كهمێك وهك شووشه',
+ shadow: 'سێبهر',
+ code: 'كۆد'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'ckb', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
\ No newline at end of file
--- /dev/null
+import { Lang } from './Lang';
+
+declare const da: Lang;
+
+export default da;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ *
+ * Danish translation by davidkonrad at github or gmail
+ *
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'da',
+ toolbar: {
+ default: 'Default',
+ save: 'Gem',
+ font: 'Skrifttype',
+ formats: 'Format',
+ fontSize: 'Skriftstørrelse',
+ bold: 'Fed',
+ underline: 'Understreget',
+ italic: 'Skråskrift',
+ strike: 'Overstreget',
+ subscript: 'Sænket skrift',
+ superscript: 'Hævet skrift',
+ removeFormat: 'Fjern formatering',
+ fontColor: 'Skriftfarve',
+ hiliteColor: 'Baggrundsfarve',
+ indent: 'Ryk ind',
+ outdent: 'Ryk ud',
+ align: 'Justering',
+ alignLeft: 'Venstrejustering',
+ alignRight: 'Højrejustering',
+ alignCenter: 'Midterjustering',
+ alignJustify: 'Tilpas margin',
+ list: 'Lister',
+ orderList: 'Nummereret liste',
+ unorderList: 'Uordnet liste',
+ horizontalRule: 'Horisontal linie',
+ hr_solid: 'Almindelig',
+ hr_dotted: 'Punkteret',
+ hr_dashed: 'Streget',
+ table: 'Tabel',
+ link: 'Link',
+ math: 'Math',
+ image: 'Billede',
+ video: 'Video',
+ audio: 'Audio',
+ fullScreen: 'Fuld skærm',
+ showBlocks: 'Vis blokke',
+ codeView: 'Vis koder',
+ undo: 'Undo',
+ redo: 'Redo',
+ preview: 'Preview',
+ print: 'Print',
+ tag_p: 'Paragraph',
+ tag_div: 'Normal (DIV)',
+ tag_h: 'Overskrift',
+ tag_blockquote: 'Citer',
+ tag_pre: 'Code',
+ template: 'Schablone',
+ lineHeight: 'Linjehøjde',
+ paragraphStyle: 'Afsnitstil',
+ textStyle: 'Tekststil',
+ imageGallery: 'Billedgalleri',
+ mention: 'Nævne'
+ },
+ dialogBox: {
+ linkBox: {
+ title: 'Indsæt link',
+ url: 'URL til link',
+ text: 'Tekst for link',
+ newWindowCheck: 'Åben i nyt faneblad'
+ },
+ mathBox: {
+ title: 'Math',
+ inputLabel: 'Matematisk notation',
+ fontSizeLabel: 'Skriftstørrelse',
+ previewLabel: 'Preview'
+ },
+ imageBox: {
+ title: 'Indsæt billede',
+ file: 'Indsæt fra fil',
+ url: 'Indsæt fra URL',
+ altText: 'Alternativ tekst'
+ },
+ videoBox: {
+ title: 'Indsæt Video',
+ file: 'Indsæt fra fil',
+ url: 'Indlejr video / YouTube,Vimeo'
+ },
+ audioBox: {
+ title: 'Indsæt Audio',
+ file: 'Indsæt fra fil',
+ url: 'Indsæt fra URL'
+ },
+ browser: {
+ tags: 'Tags',
+ search: 'Søg',
+ },
+ caption: 'Indsæt beskrivelse',
+ close: 'Luk',
+ submitButton: 'Gennemfør',
+ revertButton: 'Gendan',
+ proportion: 'Bevar proportioner',
+ basic: 'Basis',
+ left: 'Venstre',
+ right: 'Højre',
+ center: 'Center',
+ width: 'Bredde',
+ height: 'Højde',
+ size: 'Størrelse',
+ ratio: 'Forhold'
+ },
+ controller: {
+ edit: 'Rediger',
+ unlink: 'Fjern link',
+ remove: 'Fjern',
+ insertRowAbove: 'Indsæt række foroven',
+ insertRowBelow: 'Indsæt række nedenfor',
+ deleteRow: 'Slet række',
+ insertColumnBefore: 'Indsæt kolonne før',
+ insertColumnAfter: 'Indsæt kolonne efter',
+ deleteColumn: 'Slet kolonne',
+ fixedColumnWidth: 'Fast søjlebredde',
+ resize100: 'Forstør 100%',
+ resize75: 'Forstør 75%',
+ resize50: 'Forstør 50%',
+ resize25: 'Forstør 25%',
+ autoSize: 'Auto størrelse',
+ mirrorHorizontal: 'Spejling, horisontal',
+ mirrorVertical: 'Spejling, vertikal',
+ rotateLeft: 'Roter til venstre',
+ rotateRight: 'Toter til højre',
+ maxSize: 'Max størrelse',
+ minSize: 'Min størrelse',
+ tableHeader: 'Tabel overskrift',
+ mergeCells: 'Sammenlæg celler (merge)',
+ splitCells: 'Opdel celler',
+ HorizontalSplit: 'Opdel horisontalt',
+ VerticalSplit: 'Opdel vertikalt'
+ },
+ menu: {
+ spaced: 'Brev Afstand',
+ bordered: 'Afgrænsningslinje',
+ neon: 'Neon',
+ translucent: 'Gennemsigtig',
+ shadow: 'Skygge',
+ code: 'Code'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'da', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
--- /dev/null
+import { Lang } from './Lang';
+
+declare const de: Lang;
+
+export default de;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2019 @Gundolf68
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'de',
+ toolbar: {
+ default: 'Standard',
+ save: 'Speichern',
+ font: 'Schriftart',
+ formats: 'Format',
+ fontSize: 'Schriftgröße',
+ bold: 'Fett',
+ underline: 'Unterstrichen',
+ italic: 'Kursiv',
+ strike: 'Durchgestrichen',
+ subscript: 'Tiefgestellt',
+ superscript: 'Hochgestellt',
+ removeFormat: 'Format entfernen',
+ fontColor: 'Schriftfarbe',
+ hiliteColor: 'Farbe für Hervorhebungen',
+ indent: 'Einzug vergrößern',
+ outdent: 'Einzug verkleinern',
+ align: 'Ausrichtung',
+ alignLeft: 'Links ausrichten',
+ alignRight: 'Rechts ausrichten',
+ alignCenter: 'Zentriert ausrichten',
+ alignJustify: 'Blocksatz',
+ list: 'Liste',
+ orderList: 'Nummerierte Liste',
+ unorderList: 'Aufzählung',
+ horizontalRule: 'Horizontale Linie',
+ hr_solid: 'Strich',
+ hr_dotted: 'Gepunktet',
+ hr_dashed: 'Gestrichelt',
+ table: 'Tabelle',
+ link: 'Link',
+ math: 'Mathematik',
+ image: 'Bild',
+ video: 'Video',
+ audio: 'Audio',
+ fullScreen: 'Vollbild',
+ showBlocks: 'Blockformatierungen anzeigen',
+ codeView: 'Quelltext anzeigen',
+ undo: 'Rückgängig',
+ redo: 'Wiederholen',
+ preview: 'Vorschau',
+ print: 'Drucken',
+ tag_p: 'Absatz',
+ tag_div: 'Normal (DIV)',
+ tag_h: 'Header',
+ tag_blockquote: 'Zitat',
+ tag_pre: 'Quellcode',
+ template: 'Vorlage',
+ lineHeight: 'Zeilenhöhe',
+ paragraphStyle: 'Absatzstil',
+ textStyle: 'Textstil',
+ imageGallery: 'Bildergalerie',
+ mention: 'Erwähnen'
+ },
+ dialogBox: {
+ linkBox: {
+ title: 'Link einfügen',
+ url: 'Link-URL',
+ text: 'Link-Text',
+ newWindowCheck: 'In neuem Fenster anzeigen'
+ },
+ mathBox: {
+ title: 'Mathematik',
+ inputLabel: 'Mathematische Notation',
+ fontSizeLabel: 'Schriftgröße',
+ previewLabel: 'Vorschau'
+ },
+ imageBox: {
+ title: 'Bild einfügen',
+ file: 'Datei auswählen',
+ url: 'Bild-URL',
+ altText: 'Alternativer Text'
+ },
+ videoBox: {
+ title: 'Video enfügen',
+ file: 'Datei auswählen',
+ url: 'Video-URL, YouTube/Vimeo'
+ },
+ audioBox: {
+ title: 'Audio enfügen',
+ file: 'Datei auswählen',
+ url: 'Audio-URL'
+ },
+ browser: {
+ tags: 'Stichworte',
+ search: 'Suche',
+ },
+ caption: 'Beschreibung eingeben',
+ close: 'Schließen',
+ submitButton: 'Übernehmen',
+ revertButton: 'Rückgängig',
+ proportion: 'Seitenverhältnis beibehalten',
+ basic: 'Standard',
+ left: 'Links',
+ right: 'Rechts',
+ center: 'Zentriert',
+ width: 'Breite',
+ height: 'Höhe',
+ size: 'Größe',
+ ratio: 'Verhältnis'
+ },
+ controller: {
+ edit: 'Bearbeiten',
+ unlink: 'Link entfernen',
+ remove: 'Löschen',
+ insertRowAbove: 'Zeile oberhalb einfügen',
+ insertRowBelow: 'Zeile unterhalb einfügen',
+ deleteRow: 'Zeile löschen',
+ insertColumnBefore: 'Spalte links einfügen',
+ insertColumnAfter: 'Spalte rechts einfügen',
+ deleteColumn: 'Spalte löschen',
+ fixedColumnWidth: 'Feste Spaltenbreite',
+ resize100: 'Zoom 100%',
+ resize75: 'Zoom 75%',
+ resize50: 'Zoom 50%',
+ resize25: 'Zoom 25%',
+ autoSize: 'Automatische Größenanpassung',
+ mirrorHorizontal: 'Horizontal spiegeln',
+ mirrorVertical: 'Vertikal spiegeln',
+ rotateLeft: 'Nach links drehen',
+ rotateRight: 'Nach rechts drehen',
+ maxSize: 'Maximale Größe',
+ minSize: 'Mindestgröße',
+ tableHeader: 'Tabellenüberschrift',
+ mergeCells: 'Zellen verbinden',
+ splitCells: 'Zellen teilen',
+ HorizontalSplit: 'Horizontal teilen',
+ VerticalSplit: 'Vertikal teilen'
+ },
+ menu: {
+ spaced: 'Buchstabenabstand',
+ bordered: 'Umrandet',
+ neon: 'Neon',
+ translucent: 'Durchscheinend',
+ shadow: 'Schatten',
+ code: 'Quellcode'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'de', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
\ No newline at end of file
--- /dev/null
+import { Lang } from './Lang';
+
+declare const en: Lang;
+
+export default en;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'en',
+ toolbar: {
+ default: 'Default',
+ save: 'Save',
+ font: 'Font',
+ formats: 'Formats',
+ fontSize: 'Size',
+ bold: 'Bold',
+ underline: 'Underline',
+ italic: 'Italic',
+ strike: 'Strike',
+ subscript: 'Subscript',
+ superscript: 'Superscript',
+ removeFormat: 'Remove Format',
+ fontColor: 'Font Color',
+ hiliteColor: 'Highlight Color',
+ indent: 'Indent',
+ outdent: 'Outdent',
+ align: 'Align',
+ alignLeft: 'Align left',
+ alignRight: 'Align right',
+ alignCenter: 'Align center',
+ alignJustify: 'Align justify',
+ list: 'List',
+ orderList: 'Ordered list',
+ unorderList: 'Unordered list',
+ horizontalRule: 'Horizontal line',
+ hr_solid: 'Solid',
+ hr_dotted: 'Dotted',
+ hr_dashed: 'Dashed',
+ table: 'Table',
+ link: 'Link',
+ math: 'Math',
+ image: 'Image',
+ video: 'Video',
+ audio: 'Audio',
+ fullScreen: 'Full screen',
+ showBlocks: 'Show blocks',
+ codeView: 'Code view',
+ undo: 'Undo',
+ redo: 'Redo',
+ preview: 'Preview',
+ print: 'print',
+ tag_p: 'Paragraph',
+ tag_div: 'Normal (DIV)',
+ tag_h: 'Header',
+ tag_blockquote: 'Quote',
+ tag_pre: 'Code',
+ template: 'Template',
+ lineHeight: 'Line height',
+ paragraphStyle: 'Paragraph style',
+ textStyle: 'Text style',
+ imageGallery: 'Image gallery',
+ mention: 'Mention'
+ },
+ dialogBox: {
+ linkBox: {
+ title: 'Insert Link',
+ url: 'URL to link',
+ text: 'Text to display',
+ newWindowCheck: 'Open in new window'
+ },
+ mathBox: {
+ title: 'Math',
+ inputLabel: 'Mathematical Notation',
+ fontSizeLabel: 'Font Size',
+ previewLabel: 'Preview'
+ },
+ imageBox: {
+ title: 'Insert image',
+ file: 'Select from files',
+ url: 'Image URL',
+ altText: 'Alternative text'
+ },
+ videoBox: {
+ title: 'Insert Video',
+ file: 'Select from files',
+ url: 'Media embed URL, YouTube/Vimeo'
+ },
+ audioBox: {
+ title: 'Insert Audio',
+ file: 'Select from files',
+ url: 'Audio URL'
+ },
+ browser: {
+ tags: 'Tags',
+ search: 'Search',
+ },
+ caption: 'Insert description',
+ close: 'Close',
+ submitButton: 'Submit',
+ revertButton: 'Revert',
+ proportion: 'Constrain proportions',
+ basic: 'Basic',
+ left: 'Left',
+ right: 'Right',
+ center: 'Center',
+ width: 'Width',
+ height: 'Height',
+ size: 'Size',
+ ratio: 'Ratio'
+ },
+ controller: {
+ edit: 'Edit',
+ unlink: 'Unlink',
+ remove: 'Remove',
+ insertRowAbove: 'Insert row above',
+ insertRowBelow: 'Insert row below',
+ deleteRow: 'Delete row',
+ insertColumnBefore: 'Insert column before',
+ insertColumnAfter: 'Insert column after',
+ deleteColumn: 'Delete column',
+ fixedColumnWidth: 'Fixed column width',
+ resize100: 'Resize 100%',
+ resize75: 'Resize 75%',
+ resize50: 'Resize 50%',
+ resize25: 'Resize 25%',
+ autoSize: 'Auto size',
+ mirrorHorizontal: 'Mirror, Horizontal',
+ mirrorVertical: 'Mirror, Vertical',
+ rotateLeft: 'Rotate left',
+ rotateRight: 'Rotate right',
+ maxSize: 'Max size',
+ minSize: 'Min size',
+ tableHeader: 'Table header',
+ mergeCells: 'Merge cells',
+ splitCells: 'Split Cells',
+ HorizontalSplit: 'Horizontal split',
+ VerticalSplit: 'Vertical split'
+ },
+ menu: {
+ spaced: 'Spaced',
+ bordered: 'Bordered',
+ neon: 'Neon',
+ translucent: 'Translucent',
+ shadow: 'Shadow',
+ code: 'Code'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'en', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
\ No newline at end of file
--- /dev/null
+import { Lang } from './Lang';
+
+declare const es: Lang;
+
+export default es;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'es',
+ toolbar: {
+ default: 'Valor por defecto',
+ save: 'Guardar',
+ font: 'Fuente',
+ formats: 'Formato',
+ fontSize: 'Tamaño de fuente',
+ bold: 'Negrita',
+ underline: 'Subrayado',
+ italic: 'Cursiva',
+ strike: 'Tachado',
+ subscript: 'Subíndice',
+ superscript: 'Superíndice',
+ removeFormat: 'Eliminar formato',
+ fontColor: 'Color de fuente',
+ hiliteColor: 'Color de resaltado',
+ indent: 'Más tabulación',
+ outdent: 'Menos tabulación',
+ align: 'Alinear',
+ alignLeft: 'Alinear a la izquierda',
+ alignRight: 'Alinear a la derecha',
+ alignCenter: 'Alinear al centro',
+ alignJustify: 'Justificar',
+ list: 'Lista',
+ orderList: 'Lista ordenada',
+ unorderList: 'Lista desordenada',
+ horizontalRule: 'Horizontal line',
+ hr_solid: 'Línea horizontal solida',
+ hr_dotted: 'Línea horizontal punteada',
+ hr_dashed: 'Línea horizontal discontinua',
+ table: 'Tabla',
+ link: 'Link',
+ math: 'Matemáticas',
+ image: 'Imagen',
+ video: 'Video',
+ audio: 'Audio',
+ fullScreen: 'Pantalla completa',
+ showBlocks: 'Ver bloques',
+ codeView: 'Ver código fuente',
+ undo: 'UndoDeshacer última acción',
+ redo: 'Rehacer última acción',
+ preview: 'Vista previa',
+ print: 'Imprimir',
+ tag_p: 'Párrafo',
+ tag_div: 'Normal (DIV)',
+ tag_h: 'Header',
+ tag_blockquote: 'Cita',
+ tag_pre: 'Código',
+ template: 'Plantilla',
+ lineHeight: 'Altura de la línea',
+ paragraphStyle: 'Estilo del parrafo',
+ textStyle: 'Estilo del texto',
+ imageGallery: 'Galería de imágenes',
+ mention: 'Mencionar'
+ },
+ dialogBox: {
+ linkBox: {
+ title: 'Insertar Link',
+ url: '¿Hacia que URL lleva el link?',
+ text: 'Texto para mostrar',
+ newWindowCheck: 'Abrir en una nueva ventana'
+ },
+ mathBox: {
+ title: 'Matemáticas',
+ inputLabel: 'Notación Matemática',
+ fontSizeLabel: 'Tamaño de fuente',
+ previewLabel: 'Vista previa'
+ },
+ imageBox: {
+ title: 'Insertar imagen',
+ file: 'Seleccionar desde los archivos',
+ url: 'URL de la imagen',
+ altText: 'Texto alternativo'
+ },
+ videoBox: {
+ title: 'Insertar Video',
+ file: 'Seleccionar desde los archivos',
+ url: '¿URL del vídeo? Youtube/Vimeo'
+ },
+ audioBox: {
+ title: 'Insertar Audio',
+ file: 'Seleccionar desde los archivos',
+ url: 'URL de la audio'
+ },
+ browser: {
+ tags: 'Etiquetas',
+ search: 'Buscar',
+ },
+ caption: 'Insertar descripción',
+ close: 'Cerrar',
+ submitButton: 'Enviar',
+ revertButton: 'revertir',
+ proportion: 'Restringir las proporciones',
+ basic: 'Basico',
+ left: 'Izquierda',
+ right: 'derecha',
+ center: 'Centro',
+ width: 'Ancho',
+ height: 'Alto',
+ size: 'Tamaño',
+ ratio: 'Proporción'
+ },
+ controller: {
+ edit: 'Editar',
+ unlink: 'Desvincular',
+ remove: 'RemoveQuitar',
+ insertRowAbove: 'Insertar fila arriba',
+ insertRowBelow: 'Insertar fila debajo',
+ deleteRow: 'Eliminar fila',
+ insertColumnBefore: 'Insertar columna antes',
+ insertColumnAfter: 'Insertar columna después',
+ deleteColumn: 'Eliminar columna',
+ fixedColumnWidth: 'Ancho de columna fijo',
+ resize100: 'Redimensionar 100%',
+ resize75: 'Redimensionar 75%',
+ resize50: 'Redimensionar 50%',
+ resize25: 'Redimensionar 25%',
+ autoSize: 'Tamaño automático',
+ mirrorHorizontal: 'Espejo, Horizontal',
+ mirrorVertical: 'Espejo, Vertical',
+ rotateLeft: 'Girar a la izquierda',
+ rotateRight: 'Girar a la derecha',
+ maxSize: 'Tamaño máximo',
+ minSize: 'Tamaño minímo',
+ tableHeader: 'Encabezado de tabla',
+ mergeCells: 'Combinar celdas',
+ splitCells: 'Dividir celdas',
+ HorizontalSplit: 'División horizontal',
+ VerticalSplit: 'División vertical'
+ },
+ menu: {
+ spaced: 'Espaciado',
+ bordered: 'Bordeado',
+ neon: 'Neón',
+ translucent: 'Translúcido',
+ shadow: 'Sombreado',
+ code: 'Código'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'es', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
\ No newline at end of file
--- /dev/null
+import { Lang } from './Lang';
+
+declare const fr: Lang;
+
+export default fr;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2019 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'fr',
+ toolbar: {
+ default: 'Défaut',
+ save: 'Sauvegarder',
+ font: 'Police',
+ formats: 'Formats',
+ fontSize: 'Taille',
+ bold: 'Gras',
+ underline: 'Souligné',
+ italic: 'Italique',
+ strike: 'Barré',
+ subscript: 'Indice',
+ superscript: 'Exposant',
+ removeFormat: 'Éffacer le Formatage',
+ fontColor: 'Couleur du texte',
+ hiliteColor: 'Couleur en arrière plan',
+ indent: 'Indenter',
+ outdent: 'Désindenter',
+ align: 'Alignenement',
+ alignLeft: 'À gauche',
+ alignRight: 'À droite',
+ alignCenter: 'Centré',
+ alignJustify: 'Justifié',
+ list: 'Liste',
+ orderList: 'Ordonnée',
+ unorderList: 'Non-ordonnée',
+ horizontalRule: 'Ligne horizontale',
+ hr_solid: 'Solide',
+ hr_dotted: 'Points',
+ hr_dashed: 'Tirets',
+ table: 'Table',
+ link: 'Lien',
+ math: 'Math',
+ image: 'Image',
+ video: 'Video',
+ audio: 'l\'audio',
+ fullScreen: 'Plein écran',
+ showBlocks: 'Voir les blocs',
+ codeView: 'Voir le code',
+ undo: 'Annuler',
+ redo: 'Rétablir',
+ preview: 'Previsualiser',
+ print: 'Imprimer',
+ tag_p: 'Paragraphe',
+ tag_div: 'Normal (DIV)',
+ tag_h: 'Titre',
+ tag_blockquote: 'Citation',
+ tag_pre: 'Code',
+ template: 'Template',
+ lineHeight: 'Hauteur de la ligne',
+ paragraphStyle: 'Style de paragraphe',
+ textStyle: 'Style de texte',
+ imageGallery: 'Galerie d\'images',
+ mention: 'Mention'
+ },
+ dialogBox: {
+ linkBox: {
+ title: 'Insérer un lien',
+ url: 'Adresse URL du lien',
+ text: 'Texte à afficher',
+ newWindowCheck: 'Ouvrir dans une nouvelle fenêtre'
+ },
+ mathBox: {
+ title: 'Math',
+ inputLabel: 'Notation mathématique',
+ fontSizeLabel: 'Taille',
+ previewLabel: 'Previsualiser'
+ },
+ imageBox: {
+ title: 'Insérer une image',
+ file: 'Sélectionner le fichier',
+ url: 'Adresse URL du fichier',
+ altText: 'Texte Alternatif'
+ },
+ videoBox: {
+ title: 'Insérer une Vidéo',
+ file: 'Sélectionner le fichier',
+ url: 'URL d’intégration du média, YouTube/Vimeo'
+ },
+ audioBox: {
+ title: 'Insertar une l\'audio',
+ file: 'Sélectionner le fichier',
+ url: 'Adresse URL du fichier'
+ },
+ browser: {
+ tags: 'Mots clés',
+ search: 'Chercher',
+ },
+ caption: 'Insérer une description',
+ close: 'Fermer',
+ submitButton: 'Appliquer',
+ revertButton: 'Revenir en arrière',
+ proportion: 'Maintenir le rapport hauteur/largeur',
+ basic: 'Basique',
+ left: 'Gauche',
+ right: 'Droite',
+ center: 'Centré',
+ width: 'Largeur',
+ height: 'Hauteur',
+ size: 'La taille',
+ ratio: 'Rapport'
+ },
+ controller: {
+ edit: 'Modifier',
+ unlink: 'Supprimer un lien',
+ remove: 'Effacer',
+ insertRowAbove: 'Insérer une ligne en dessous',
+ insertRowBelow: 'Insérer une ligne au dessus',
+ deleteRow: 'Effacer la ligne',
+ insertColumnBefore: 'Insérer une colonne avant',
+ insertColumnAfter: 'Insérer une colonne après',
+ deleteColumn: 'Effacer la colonne',
+ fixedColumnWidth: 'Largeur de colonne fixe',
+ resize100: 'Redimensionner à 100%',
+ resize75: 'Redimensionner à 75%',
+ resize50: 'Redimensionner à 50%',
+ resize25: 'Redimensionner à 25%',
+ autoSize: 'Taille automatique',
+ mirrorHorizontal: 'Mirroir, Horizontal',
+ mirrorVertical: 'Mirroir, Vertical',
+ rotateLeft: 'Rotation à gauche',
+ rotateRight: 'Rotation à droite',
+ maxSize: 'Taille max',
+ minSize: 'Taille min',
+ tableHeader: 'En-tête de table',
+ mergeCells: 'Fusionner les cellules',
+ splitCells: 'Diviser les Cellules',
+ HorizontalSplit: 'Scission horizontale',
+ VerticalSplit: 'Scission verticale'
+ },
+ menu: {
+ spaced: 'Espacement',
+ bordered: 'Ligne de démarcation',
+ neon: 'Néon',
+ translucent: 'Translucide',
+ shadow: 'L\'ombre',
+ code: 'Code'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'fr', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
--- /dev/null
+import ckb from './ckb';
+import da from './da';
+import de from './de';
+import en from './en';
+import es from './es';
+import fr from './fr';
+import it from './it';
+import ja from './ja';
+import ko from './ko';
+import lv from './lv';
+import pl from './pl';
+import pt_br from './pt_br';
+import ro from './ro';
+import ru from './ru';
+import zh_cn from './zh_cn';
+
+export { ckb, da, de, en, es, fr, it, ja, ko, lv, pl, pt_br, ro, ru, zh_cn };
--- /dev/null
+'use strict';
+
+import ckb from './ckb';
+import da from './da';
+import de from './de';
+import en from './en';
+import es from './es';
+import fr from './fr';
+import it from './it';
+import ja from './ja';
+import ko from './ko';
+import lv from './lv';
+import pl from './pl';
+import pt_br from './pt_br';
+import ro from './ro';
+import ru from './ru';
+import zh_cn from './zh_cn';
+
+export { ckb, da, de, en, es, fr, it, ja, ko, lv, pl, pt_br, ro, ru, zh_cn };
+export default { ckb, da, de, en, es, fr, it, ja, ko, lv, pl, pt_br, ro, ru, zh_cn };
--- /dev/null
+import { Lang } from './Lang';
+
+declare const it: Lang;
+
+export default it;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG una finestra con un documento');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'it',
+ toolbar: {
+ default: 'Predefinita',
+ save: 'Salva',
+ font: 'Font',
+ formats: 'Formato',
+ fontSize: 'Grandezza',
+ bold: 'Grassetto',
+ underline: 'Sottolineato',
+ italic: 'Italico',
+ strike: 'Cancellato',
+ subscript: 'Apice',
+ superscript: 'Pedice',
+ removeFormat: 'Rimuovi Formattazione',
+ fontColor: 'Colore Testo',
+ hiliteColor: 'Colore Sottolineatura',
+ indent: 'Aumenta rientro',
+ outdent: 'Riduci rientro',
+ align: 'Allinea',
+ alignLeft: 'Sinistra',
+ alignRight: 'Destra',
+ alignCenter: 'Centrato',
+ alignJustify: 'Giustificato',
+ list: 'Lista',
+ orderList: 'Lista numerata',
+ unorderList: 'Lista Puntata',
+ horizontalRule: 'Linea Orizzontale',
+ hr_solid: 'Linea',
+ hr_dotted: 'Puntinato',
+ hr_dashed: 'Tratteggiato',
+ table: 'Tabella',
+ link: 'Link',
+ math: 'Matematica',
+ image: 'Immagine',
+ video: 'Video',
+ audio: 'Audio',
+ fullScreen: 'Tutto Schermo',
+ showBlocks: 'Visualizza Blocchi',
+ codeView: 'Visualizza Codice',
+ undo: 'Annulla',
+ redo: 'Ripristina',
+ preview: 'Anteprima',
+ print: 'Stampa',
+ tag_p: 'Paragrafo',
+ tag_div: 'DIV Normale',
+ tag_h: 'Intestazione',
+ tag_blockquote: 'Citazione',
+ tag_pre: 'Codice',
+ template: 'Template',
+ lineHeight: 'Altezza linea',
+ paragraphStyle: 'Stile Paragrafo',
+ textStyle: 'Stile Testo',
+ imageGallery: 'Galleria di immagini',
+ mention: 'Citare'
+ },
+ dialogBox: {
+ linkBox: {
+ title: 'Inserisci un Link',
+ url: 'Indirizzo in link',
+ text: 'Applica Testo da visualizzare',
+ newWindowCheck: 'Apri in una nuova finestra'
+ },
+ mathBox: {
+ title: 'Matematica',
+ inputLabel: 'Notazione matematica',
+ fontSizeLabel: 'Grandezza testo',
+ previewLabel: 'Anteprima'
+ },
+ imageBox: {
+ title: 'Inserisci Immagine',
+ file: 'Seleziona da file',
+ url: 'Indirizzo immagine',
+ altText: 'Testo alternativo (ALT)'
+ },
+ videoBox: {
+ title: 'Inserisci Video',
+ file: 'Seleziona da file',
+ url: 'Indirizzo video, YouTube/Vimeo'
+ },
+ audioBox: {
+ title: 'Insertar Audio',
+ file: 'Seleziona da file',
+ url: 'Indirizzo audio'
+ },
+ browser: {
+ tags: 'tag',
+ search: 'Ricerca',
+ },
+ caption: 'Inserisci descrizione',
+ close: 'ClChiudiose',
+ submitButton: 'Invia',
+ revertButton: 'Annulla',
+ proportion: 'Proporzionale',
+ basic: 'Da impostazione',
+ left: 'Sinistra',
+ right: 'Destra',
+ center: 'Centrato',
+ width: 'Larghezza',
+ height: 'Altezza',
+ size: 'Peso',
+ ratio: 'Rapporto'
+ },
+ controller: {
+ edit: 'Modifica',
+ unlink: 'Elimina link',
+ remove: 'Rimuovi',
+ insertRowAbove: 'Inserisci linea sopra',
+ insertRowBelow: 'Inserisci linea sotto',
+ deleteRow: 'Cancella riga',
+ insertColumnBefore: 'Inserisci una colonna prima',
+ insertColumnAfter: 'Inserisci una colonna dopo',
+ deleteColumn: 'Cancella colonna',
+ fixedColumnWidth: 'Larghezza della colonna fissa',
+ resize100: 'Ridimensiona 100%',
+ resize75: 'Ridimensiona 75%',
+ resize50: 'Ridimensiona 50%',
+ resize25: 'Ridimensiona 25%',
+ autoSize: 'Ridimensione automatica',
+ mirrorHorizontal: 'Specchia, orizontale',
+ mirrorVertical: 'Specchia, verticale',
+ rotateLeft: 'Ruota a sinistra',
+ rotateRight: 'Ruota a destra',
+ maxSize: 'Dimensione massima',
+ minSize: 'Dimensione minima',
+ tableHeader: 'Intestazione Tabella',
+ mergeCells: 'Unisci celle',
+ splitCells: 'Dividi celle',
+ HorizontalSplit: 'Separa orizontale',
+ VerticalSplit: 'Separa verticale'
+ },
+ menu: {
+ spaced: 'Spaziatura',
+ bordered: 'Bordo',
+ neon: 'Luminoso',
+ translucent: 'Translucente',
+ shadow: 'Ombra',
+ code: 'Codice'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'it', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
--- /dev/null
+import { Lang } from './Lang';
+
+declare const ja: Lang;
+
+export default ja;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2019 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'ja',
+ toolbar: {
+ default: 'デフォルト',
+ save: '保存',
+ font: 'フォント',
+ formats: '段落形式',
+ fontSize: 'サイズ',
+ bold: '太字',
+ underline: '下線',
+ italic: 'イタリック',
+ strike: '取り消し線',
+ subscript: '下付き',
+ superscript: '上付き',
+ removeFormat: '形式を削除',
+ fontColor: '文字色',
+ hiliteColor: '文字の背景色',
+ indent: 'インデント',
+ outdent: 'インデント',
+ align: 'ソート',
+ alignLeft: '左揃え',
+ alignRight: '右揃え',
+ alignCenter: '中央揃え',
+ alignJustify: '両端揃え',
+ list: 'リスト',
+ orderList: '数値ブリット',
+ unorderList: '円形ブリット',
+ horizontalRule: '水平線を挿入',
+ hr_solid: '実線',
+ hr_dotted: '点線',
+ hr_dashed: 'ダッシュ',
+ table: 'テーブル',
+ link: 'リンク',
+ math: '数学',
+ image: '画像',
+ video: '動画',
+ audio: 'オーディオ',
+ fullScreen: 'フルスクリーン',
+ showBlocks: 'ブロック表示',
+ codeView: 'HTMLの編集',
+ undo: '元に戻す',
+ redo: '再実行',
+ preview: 'プレビュー',
+ print: '印刷',
+ tag_p: '本文',
+ tag_div: '基本(DIV)',
+ tag_h: 'タイトル',
+ tag_blockquote: '引用',
+ tag_pre: 'コード',
+ template: 'テンプレート',
+ lineHeight: '行の高さ',
+ paragraphStyle: '段落スタイル',
+ textStyle: 'テキストスタイル',
+ imageGallery: 'イメージギャラリー',
+ mention: '言及する'
+ },
+ dialogBox: {
+ linkBox: {
+ title: 'リンクの挿入',
+ url: 'インターネットアドレス',
+ text: '画面のテキスト',
+ newWindowCheck: '別ウィンドウで開く'
+ },
+ mathBox: {
+ title: '数学',
+ inputLabel: '数学表記',
+ fontSizeLabel: 'サイズ',
+ previewLabel: 'プレビュー'
+ },
+ imageBox: {
+ title: '画像の挿入',
+ file: 'ファイルの選択',
+ url: 'イメージアドレス',
+ altText: '置換文字列'
+ },
+ videoBox: {
+ title: '動画を挿入',
+ file: 'ファイルの選択',
+ url: 'メディア埋め込みアドレス, YouTube/Vimeo'
+ },
+ audioBox: {
+ title: 'オーディオを挿入',
+ file: 'ファイルの選択',
+ url: 'オーディオアドレス'
+ },
+ browser: {
+ tags: 'タグ',
+ search: '探す',
+ },
+ caption: '説明付け',
+ close: '閉じる',
+ submitButton: '確認',
+ revertButton: '元に戻す',
+ proportion: 'の割合カスタマイズ',
+ basic: '基本',
+ left: '左',
+ right: '右',
+ center: '中央',
+ width: '横',
+ height: '縦',
+ size: 'サイズ',
+ ratio: '比率'
+ },
+ controller: {
+ edit: '編集',
+ unlink: 'リンク解除',
+ remove: '削除',
+ insertRowAbove: '上に行を挿入',
+ insertRowBelow: '下に行を挿入',
+ deleteRow: '行の削除',
+ insertColumnBefore: '左に列を挿入',
+ insertColumnAfter: '右に列を挿入',
+ deleteColumn: '列を削除する',
+ fixedColumnWidth: '固定列幅',
+ resize100: '100% サイズ',
+ resize75: '75% サイズ',
+ resize50: '50% サイズ',
+ resize25: '25% サイズ',
+ autoSize: '自動サイズ',
+ mirrorHorizontal: '左右反転',
+ mirrorVertical: '上下反転',
+ rotateLeft: '左に回転',
+ rotateRight: '右に回転',
+ maxSize: '最大サイズ',
+ minSize: '最小サイズ',
+ tableHeader: '表のヘッダー',
+ mergeCells: 'セルの結合',
+ splitCells: 'セルを分割',
+ HorizontalSplit: '横分割',
+ VerticalSplit: '垂直分割'
+ },
+ menu: {
+ spaced: '文字間隔',
+ bordered: '境界線',
+ neon: 'ネオン',
+ translucent: '半透明',
+ shadow: '影',
+ code: 'コード'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'ja', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
\ No newline at end of file
--- /dev/null
+import { Lang } from './Lang';
+
+declare const ko: Lang;
+
+export default ko;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'ko',
+ toolbar: {
+ default: '기본값',
+ save: '저장',
+ font: '글꼴',
+ formats: '문단 형식',
+ fontSize: '크기',
+ bold: '굵게',
+ underline: '밑줄',
+ italic: '기울임',
+ strike: '취소선',
+ subscript: '아래 첨자',
+ superscript: '위 첨자',
+ removeFormat: '형식 제거',
+ fontColor: '글자색',
+ hiliteColor: '배경색',
+ indent: '들여쓰기',
+ outdent: '내어쓰기',
+ align: '정렬',
+ alignLeft: '왼쪽 정렬',
+ alignRight: '오른쪽 정렬',
+ alignCenter: '가운데 정렬',
+ alignJustify: '양쪽 정렬',
+ list: '리스트',
+ orderList: '숫자형 리스트',
+ unorderList: '원형 리스트',
+ horizontalRule: '가로 줄 삽입',
+ hr_solid: '실선',
+ hr_dotted: '점선',
+ hr_dashed: '대시',
+ table: '테이블',
+ link: '링크',
+ math: '수식',
+ image: '이미지',
+ video: '동영상',
+ audio: '오디오',
+ fullScreen: '전체 화면',
+ showBlocks: '블록 보기',
+ codeView: 'HTML 편집',
+ undo: '실행 취소',
+ redo: '다시 실행',
+ preview: '미리보기',
+ print: '인쇄',
+ tag_p: '본문',
+ tag_div: '기본 (DIV)',
+ tag_h: '제목',
+ tag_blockquote: '인용문',
+ tag_pre: '코드',
+ template: '템플릿',
+ lineHeight: '줄 높이',
+ paragraphStyle: '문단 스타일',
+ textStyle: '글자 스타일',
+ imageGallery: '이미지 갤러리',
+ mention: '멘션'
+ },
+ dialogBox: {
+ linkBox: {
+ title: '링크 삽입',
+ url: '인터넷 주소',
+ text: '화면 텍스트',
+ newWindowCheck: '새창으로 열기'
+ },
+ mathBox: {
+ title: '수식',
+ inputLabel: '수학적 표기법',
+ fontSizeLabel: '글자 크기',
+ previewLabel: '미리보기'
+ },
+ imageBox: {
+ title: '이미지 삽입',
+ file: '파일 선택',
+ url: '이미지 주소',
+ altText: '대체 문자열'
+ },
+ videoBox: {
+ title: '동영상 삽입',
+ file: '파일 선택',
+ url: '미디어 임베드 주소, 유튜브/비메오'
+ },
+ audioBox: {
+ title: '오디오 삽입',
+ file: '파일 선택',
+ url: '오디오 파일 주소'
+ },
+ browser: {
+ tags: '태그',
+ search: '검색',
+ },
+ caption: '설명 넣기',
+ close: '닫기',
+ submitButton: '확인',
+ revertButton: '되돌리기',
+ proportion: '비율 맞춤',
+ basic: '기본',
+ left: '왼쪽',
+ right: '오른쪽',
+ center: '가운데',
+ width: '가로',
+ height: '세로',
+ size: '크기',
+ ratio: '비율'
+ },
+ controller: {
+ edit: '편집',
+ unlink: '링크 해제',
+ remove: '삭제',
+ insertRowAbove: '위에 행 삽입',
+ insertRowBelow: '아래에 행 삽입',
+ deleteRow: '행 삭제',
+ insertColumnBefore: '왼쪽에 열 삽입',
+ insertColumnAfter: '오른쪽에 열 삽입',
+ deleteColumn: '열 삭제',
+ fixedColumnWidth: '고정 된 열 너비',
+ resize100: '100% 크기',
+ resize75: '75% 크기',
+ resize50: '50% 크기',
+ resize25: '25% 크기',
+ autoSize: '자동 크기',
+ mirrorHorizontal: '좌우 반전',
+ mirrorVertical: '상하 반전',
+ rotateLeft: '왼쪽으로 회전',
+ rotateRight: '오른쪽으로 회전',
+ maxSize: '최대화',
+ minSize: '최소화',
+ tableHeader: '테이블 제목',
+ mergeCells: '셀 병합',
+ splitCells: '셀 분할',
+ HorizontalSplit: '가로 분할',
+ VerticalSplit: '세로 분할'
+ },
+ menu: {
+ spaced: '글자 간격',
+ bordered: '경계선',
+ neon: '네온',
+ translucent: '반투명',
+ shadow: '그림자',
+ code: '코드'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'ko', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
\ No newline at end of file
--- /dev/null
+import { Lang } from './Lang';
+
+declare const lv: Lang;
+
+export default lv;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'lv',
+ toolbar: {
+ default: 'Noklusējuma',
+ save: 'Saglabāt',
+ font: 'Fonts',
+ formats: 'Formāti',
+ fontSize: 'Fonta lielums',
+ bold: 'Treknraksts',
+ underline: 'Pasvītrot',
+ italic: 'Slīpraksts',
+ strike: 'Pārsvītrojums',
+ subscript: 'Apakšraksts',
+ superscript: 'Augšraksts',
+ removeFormat: 'Noņemt formātu',
+ fontColor: 'Fonta krāsa',
+ hiliteColor: 'Teksta iezīmēšanas krāsa',
+ indent: 'Palielināt atkāpi',
+ outdent: 'Samazināt atkāpi',
+ align: 'Izlīdzināt',
+ alignLeft: 'Līdzināt pa kreisi',
+ alignRight: 'Līdzināt pa labi',
+ alignCenter: 'Centrēt',
+ alignJustify: 'Taisnot',
+ list: 'Saraksts',
+ orderList: 'Numerācija',
+ unorderList: 'Aizzimes',
+ horizontalRule: 'Horizontāla līnija',
+ hr_solid: 'Ciets',
+ hr_dotted: 'Punktiņš',
+ hr_dashed: 'Braša',
+ table: 'Tabula',
+ link: 'Saite',
+ math: 'Matemātika',
+ image: 'Attēls',
+ video: 'Video',
+ audio: 'Audio',
+ fullScreen: 'Pilnekrāna režīms',
+ showBlocks: 'Parādit blokus',
+ codeView: 'Koda skats',
+ undo: 'Atsaukt',
+ redo: 'Atkārtot',
+ preview: 'Priekšskatījums',
+ print: 'Drukāt',
+ tag_p: 'Paragrāfs',
+ tag_div: 'Normāli (DIV)',
+ tag_h: 'Galvene',
+ tag_blockquote: 'Citāts',
+ tag_pre: 'Kods',
+ template: 'Veidne',
+ lineHeight: 'Līnijas augstums',
+ paragraphStyle: 'Paragrāfa stils',
+ textStyle: 'Teksta stils',
+ imageGallery: 'Attēlu galerija',
+ mention: 'Pieminēt'
+ },
+ dialogBox: {
+ linkBox: {
+ title: 'Ievietot saiti',
+ url: 'Saites URL',
+ text: 'Parādāmais teksts',
+ newWindowCheck: 'Atvērt jaunā logā'
+ },
+ mathBox: {
+ title: 'Matemātika',
+ inputLabel: 'Matemātiskā notācija',
+ fontSizeLabel: 'Fonta lielums',
+ previewLabel: 'Priekšskatījums'
+ },
+ imageBox: {
+ title: 'Ievietot attēlu',
+ file: 'Izvēlieties no failiem',
+ url: 'Attēla URL',
+ altText: 'Alternatīvs teksts'
+ },
+ videoBox: {
+ title: 'Ievietot video',
+ file: 'Izvēlieties no failiem',
+ url: 'Multivides iegulšanas URL, YouTube/Vimeo'
+ },
+ audioBox: {
+ title: 'Ievietot audio',
+ file: 'Izvēlieties no failiem',
+ url: 'Audio URL'
+ },
+ browser: {
+ tags: 'Tagi',
+ search: 'Meklēt'
+ },
+ caption: 'Ievietot aprakstu',
+ close: 'Aizvērt',
+ submitButton: 'Iesniegt',
+ revertButton: 'Atjaunot',
+ proportion: 'Ierobežo proporcijas',
+ basic: 'Nav iesaiņojuma',
+ left: 'Pa kreisi',
+ right: 'Labajā pusē',
+ center: 'Centrs',
+ width: 'Platums',
+ height: 'Augstums',
+ size: 'Izmērs',
+ ratio: 'Attiecība'
+ },
+ controller: {
+ edit: 'Rediģēt',
+ unlink: 'Atsaistīt',
+ remove: 'Noņemt',
+ insertRowAbove: 'Ievietot rindu virs',
+ insertRowBelow: 'Ievietot rindu zemāk',
+ deleteRow: 'Dzēst rindu',
+ insertColumnBefore: 'Ievietot kolonnu pirms',
+ insertColumnAfter: 'Ievietot kolonnu aiz',
+ deleteColumn: 'Dzēst kolonnu',
+ fixColumnWidth: 'Fiksēts kolonnas platums',
+ resize100: 'Mainīt izmēru 100%',
+ resize75: 'Mainīt izmēru 75%',
+ resize50: 'Mainīt izmēru 50%',
+ resize25: 'Mainīt izmēru 25%',
+ autoSize: 'Automātiskais izmērs',
+ mirrorHorizontal: 'Spogulis, horizontāls',
+ mirrorVertical: 'Spogulis, vertikāls',
+ rotateLeft: 'Pagriezt pa kreisi',
+ rotateRight: 'Pagriezt pa labi',
+ maxSize: 'Maksimālais izmērs',
+ minSize: 'Minimālais izmērs',
+ tableHeader: 'Tabulas galvene',
+ mergeCells: 'Apvienot šūnas',
+ splitCells: 'Sadalīt šūnas',
+ HorizontalSplit: 'Horizontāls sadalījums',
+ VerticalSplit: 'Vertikāls sadalījums'
+ },
+ menu: {
+ spaced: 'Ar atstarpi',
+ bordered: 'Robežojās',
+ neon: 'Neona',
+ translucent: 'Caurspīdīgs',
+ shadow: 'Ēna',
+ code: 'Kods'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'lv', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
\ No newline at end of file
--- /dev/null
+import { Lang } from './Lang';
+
+declare const pl: Lang;
+
+export default pl;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'pl',
+ toolbar: {
+ default: 'Domyślne',
+ save: 'Zapisz',
+ font: 'Czcionka',
+ formats: 'Formaty',
+ fontSize: 'Rozmiar',
+ bold: 'Pogrubienie',
+ underline: 'Podkreślenie',
+ italic: 'Kursywa',
+ strike: 'Przekreślenie',
+ subscript: 'Indeks dolny',
+ superscript: 'Indeks górny',
+ removeFormat: 'Wyczyść formatowanie',
+ fontColor: 'Kolor tekstu',
+ hiliteColor: 'Kolor tła tekstu',
+ indent: 'Zwiększ wcięcie',
+ outdent: 'Zmniejsz wcięcie',
+ align: 'Wyrównaj',
+ alignLeft: 'Do lewej',
+ alignRight: 'Do prawej',
+ alignCenter: 'Do środka',
+ alignJustify: 'Wyjustuj',
+ list: 'Lista',
+ orderList: 'Lista numerowana',
+ unorderList: 'Lista wypunktowana',
+ horizontalRule: 'Pozioma linia',
+ hr_solid: 'Ciągła',
+ hr_dotted: 'Kropkowana',
+ hr_dashed: 'Przerywana',
+ table: 'Tabela',
+ link: 'Odnośnik',
+ math: 'Matematyczne',
+ image: 'Obraz',
+ video: 'Wideo',
+ audio: 'Audio',
+ fullScreen: 'Pełny ekran',
+ showBlocks: 'Pokaż bloki',
+ codeView: 'Widok kodu',
+ undo: 'Cofnij',
+ redo: 'Ponów',
+ preview: 'Podgląd',
+ print: 'Drukuj',
+ tag_p: 'Akapit',
+ tag_div: 'Blok (DIV)',
+ tag_h: 'Nagłówek H',
+ tag_blockquote: 'Cytat',
+ tag_pre: 'Kod',
+ template: 'Szablon',
+ lineHeight: 'Odstęp między wierszami',
+ paragraphStyle: 'Styl akapitu',
+ textStyle: 'Styl tekstu',
+ imageGallery: 'Galeria obrazów',
+ mention: 'Wzmianka'
+ },
+ dialogBox: {
+ linkBox: {
+ title: 'Wstaw odnośnik',
+ url: 'Adres URL',
+ text: 'Tekst do wyświetlenia',
+ newWindowCheck: 'Otwórz w nowym oknie'
+ },
+ mathBox: {
+ title: 'Matematyczne',
+ inputLabel: 'Zapis matematyczny',
+ fontSizeLabel: 'Rozmiar czcionki',
+ previewLabel: 'Podgląd'
+ },
+ imageBox: {
+ title: 'Wstaw obraz',
+ file: 'Wybierz plik',
+ url: 'Adres URL obrazka',
+ altText: 'Tekst alternatywny'
+ },
+ videoBox: {
+ title: 'Wstaw wideo',
+ file: 'Wybierz plik',
+ url: 'Adres URL video, np. YouTube/Vimeo'
+ },
+ audioBox: {
+ title: 'Wstaw audio',
+ file: 'Wybierz plik',
+ url: 'Adres URL audio'
+ },
+ browser: {
+ tags: 'Tagi',
+ search: 'Szukaj',
+ },
+ caption: 'Wstaw opis',
+ close: 'Zamknij',
+ submitButton: 'Zatwierdź',
+ revertButton: 'Cofnij zmiany',
+ proportion: 'Ogranicz proporcje',
+ basic: 'Bez wyrównania',
+ left: 'Do lewej',
+ right: 'Do prawej',
+ center: 'Do środka',
+ width: 'Szerokość',
+ height: 'Wysokość',
+ size: 'Rozmiar',
+ ratio: 'Proporcje'
+ },
+ controller: {
+ edit: 'Edycja',
+ unlink: 'Usuń odnośnik',
+ remove: 'Usuń',
+ insertRowAbove: 'Wstaw wiersz powyżej',
+ insertRowBelow: 'Wstaw wiersz poniżej',
+ deleteRow: 'Usuń wiersz',
+ insertColumnBefore: 'Wstaw kolumnę z lewej',
+ insertColumnAfter: 'Wstaw kolumnę z prawej',
+ deleteColumn: 'Usuń kolumnę',
+ fixedColumnWidth: 'Stała szerokość kolumny',
+ resize100: 'Zmień rozmiar - 100%',
+ resize75: 'Zmień rozmiar - 75%',
+ resize50: 'Zmień rozmiar - 50%',
+ resize25: 'Zmień rozmiar - 25%',
+ autoSize: 'Rozmiar automatyczny',
+ mirrorHorizontal: 'Odbicie lustrzane w poziomie',
+ mirrorVertical: 'Odbicie lustrzane w pionie',
+ rotateLeft: 'Obróć w lewo',
+ rotateRight: 'Obróć w prawo',
+ maxSize: 'Maksymalny rozmiar',
+ minSize: 'Minimalny rozmiar',
+ tableHeader: 'Nagłówek tabeli',
+ mergeCells: 'Scal komórki',
+ splitCells: 'Podziel komórki',
+ HorizontalSplit: 'Podział poziomy',
+ VerticalSplit: 'Podział pionowy'
+ },
+ menu: {
+ spaced: 'Rozstawiony',
+ bordered: 'Z obwódką',
+ neon: 'Neon',
+ translucent: 'Półprzezroczysty',
+ shadow: 'Cień',
+ code: 'Kod'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'pl', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
\ No newline at end of file
--- /dev/null
+import { Lang } from './Lang';
+
+declare const ptBr: Lang;
+
+export default ptBr;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * Brazilian Portuguese translation by lpeil github
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'pt_br',
+ toolbar: {
+ default: 'Padrão',
+ save: 'Salvar',
+ font: 'Fonte',
+ formats: 'Formatos',
+ fontSize: 'Tamanho',
+ bold: 'Negrito',
+ underline: 'Sublinhado',
+ italic: 'Itálico',
+ strike: 'Riscado',
+ subscript: 'Subescrito',
+ superscript: 'Sobrescrito',
+ removeFormat: 'Remover Formatação',
+ fontColor: 'Cor da Fonte',
+ hiliteColor: 'Cor de destaque',
+ indent: 'Recuo',
+ outdent: 'Avançar',
+ align: 'Alinhar',
+ alignLeft: 'Alinhar à esquerda',
+ alignRight: 'Alinhar à direita',
+ alignCenter: 'Alinhar ao centro',
+ alignJustify: 'Alinhat justificado',
+ list: 'Lista',
+ orderList: 'Lista ordenada',
+ unorderList: 'Lista desordenada',
+ horizontalRule: 'Linha horizontal',
+ hr_solid: 'solida',
+ hr_dotted: 'pontilhada',
+ hr_dashed: 'tracejada',
+ table: 'Tabela',
+ link: 'Link',
+ math: 'Matemática',
+ image: 'Imagem',
+ video: 'Vídeo',
+ audio: 'Áudio',
+ fullScreen: 'Tela cheia',
+ showBlocks: 'Mostrar blocos',
+ codeView: 'Mostrar códigos',
+ undo: 'Voltar',
+ redo: 'Refazer',
+ preview: 'Prever',
+ print: 'imprimir',
+ tag_p: 'Paragráfo',
+ tag_div: '(DIV) Normal',
+ tag_h: 'Cabeçalho',
+ tag_blockquote: 'Citar',
+ tag_pre: 'Código',
+ template: 'Modelo',
+ lineHeight: 'Altura da linha',
+ paragraphStyle: 'Estilo do parágrafo',
+ textStyle: 'Estilo do texto',
+ imageGallery: 'Galeria de imagens',
+ mention: 'Menção'
+ },
+ dialogBox: {
+ linkBox: {
+ title: 'Inserir link',
+ url: 'URL para link',
+ text: 'Texto à mostrar',
+ newWindowCheck: 'Abrir em nova guia'
+ },
+ mathBox: {
+ title: 'Matemática',
+ inputLabel: 'Notação matemática',
+ fontSizeLabel: 'Tamanho',
+ previewLabel: 'Prever'
+ },
+ imageBox: {
+ title: 'Inserir imagens',
+ file: 'Selecionar arquivos',
+ url: 'URL da imagem',
+ altText: 'Texto alternativo'
+ },
+ videoBox: {
+ title: 'Inserir vídeo',
+ file: 'Selecionar arquivos',
+ url: 'URL do YouTube/Vimeo'
+ },
+ audioBox: {
+ title: 'Inserir audio',
+ file: 'Selecionar arquivos',
+ url: 'URL da audio'
+ },
+ browser: {
+ tags: 'Tag',
+ search: 'Procurar',
+ },
+ caption: 'Inserir descrição',
+ close: 'Fechar',
+ submitButton: 'Enviar',
+ revertButton: 'Reverter',
+ proportion: 'restringir proporções',
+ basic: 'Básico',
+ left: 'Esquerda',
+ right: 'Direita',
+ center: 'Centro',
+ width: 'Largura',
+ height: 'Altura',
+ size: 'Tamanho',
+ ratio: 'Proporções'
+ },
+ controller: {
+ edit: 'Editar',
+ unlink: 'Retirar link',
+ remove: 'Remover',
+ insertRowAbove: 'Inserir linha acima',
+ insertRowBelow: 'Inserir linha abaixo',
+ deleteRow: 'Deletar linha',
+ insertColumnBefore: 'Inserir coluna antes',
+ insertColumnAfter: 'Inserir coluna depois',
+ deleteColumn: 'Deletar coluna',
+ fixedColumnWidth: 'Largura fixa da coluna',
+ resize100: 'Redimensionar para 100%',
+ resize75: 'Redimensionar para 75%',
+ resize50: 'Redimensionar para 50%',
+ resize25: 'Redimensionar para 25%',
+ autoSize: 'Tamanho automático',
+ mirrorHorizontal: 'Espelho, Horizontal',
+ mirrorVertical: 'Espelho, Vertical',
+ rotateLeft: 'Girar para esquerda',
+ rotateRight: 'Girar para direita',
+ maxSize: 'Tam max',
+ minSize: 'Tam min',
+ tableHeader: 'Cabeçalho da tabela',
+ mergeCells: 'Mesclar células',
+ splitCells: 'Dividir células',
+ HorizontalSplit: 'Divisão horizontal',
+ VerticalSplit: 'Divisão vertical'
+ },
+ menu: {
+ spaced: 'Espaçado',
+ bordered: 'Com borda',
+ neon: 'Néon',
+ translucent: 'Translúcido',
+ shadow: 'Sombreado',
+ code: 'Código'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'pt_br', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
\ No newline at end of file
--- /dev/null
+import { Lang } from './Lang';
+
+declare const ro: Lang;
+
+export default ro;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'ro',
+ toolbar: {
+ default: 'Default',
+ save: 'Salvează',
+ font: 'Font',
+ formats: 'Format',
+ fontSize: 'Dimensiune',
+ bold: 'Îngroșat',
+ underline: 'Subliniat',
+ italic: 'Înclinat',
+ strike: 'Tăiat',
+ subscript: 'Subscript',
+ superscript: 'Superscript',
+ removeFormat: 'Șterge formatare',
+ fontColor: 'Culoare font',
+ hiliteColor: 'Culoare de evidențiere',
+ indent: 'Indentează',
+ outdent: 'Fără indentare',
+ align: 'Aliniere',
+ alignLeft: 'Aliniere la stânga',
+ alignRight: 'Aliniere la dreapta',
+ alignCenter: 'Aliniere la centru',
+ alignJustify: 'Aliniere stânga - dreapta',
+ list: 'Listă',
+ orderList: 'Listă ordonată',
+ unorderList: 'Listă neordonată',
+ horizontalRule: 'Linie orizontală',
+ hr_solid: 'Solid',
+ hr_dotted: 'Punctat',
+ hr_dashed: 'Punctate',
+ table: 'Tabel',
+ link: 'Link',
+ math: 'Matematică',
+ image: 'Imagine',
+ video: 'Video',
+ audio: 'Audio',
+ fullScreen: 'Tot ecranul',
+ showBlocks: 'Arată blocuri',
+ codeView: 'Vizualizare cod',
+ undo: 'Anulează',
+ redo: 'Refă',
+ preview: 'Previzualizare',
+ print: 'printează',
+ tag_p: 'Paragraf',
+ tag_div: 'Normal (DIV)',
+ tag_h: 'Antet',
+ tag_blockquote: 'Quote',
+ tag_pre: 'Citat',
+ template: 'Template',
+ lineHeight: 'Înălțime linie',
+ paragraphStyle: 'Stil paragraf',
+ textStyle: 'Stil text',
+ imageGallery: 'Galerie de imagini',
+ mention: 'Mentiune'
+ },
+ dialogBox: {
+ linkBox: {
+ title: 'Inserează Link',
+ url: 'Adresă link',
+ text: 'Text de afișat',
+ newWindowCheck: 'Deschide în fereastră nouă'
+ },
+ mathBox: {
+ title: 'Matematică',
+ inputLabel: 'Notație matematică',
+ fontSizeLabel: 'Dimensiune font',
+ previewLabel: 'Previzualizare'
+ },
+ imageBox: {
+ title: 'Inserează imagine',
+ file: 'Selectează',
+ url: 'URL imagine',
+ altText: 'text alternativ'
+ },
+ videoBox: {
+ title: 'Inserează video',
+ file: 'Selectează',
+ url: 'Include URL, youtube/vimeo'
+ },
+ audioBox: {
+ title: 'Inserează Audio',
+ file: 'Selectează',
+ url: 'URL Audio'
+ },
+ browser: {
+ tags: 'Etichete',
+ search: 'Căutareim',
+ },
+ caption: 'Inserează descriere',
+ close: 'Închide',
+ submitButton: 'Salvează',
+ revertButton: 'Revenire',
+ proportion: 'Constrânge proporțiile',
+ basic: 'De bază',
+ left: 'Stânga',
+ right: 'Dreapta',
+ center: 'Centru',
+ width: 'Lățime',
+ height: 'Înălțime',
+ size: 'Dimensiune',
+ ratio: 'Ratie'
+ },
+ controller: {
+ edit: 'Editează',
+ unlink: 'Scoate link',
+ remove: 'Elimină',
+ insertRowAbove: 'Inserează rând deasupra',
+ insertRowBelow: 'Inserează rând dedesupt',
+ deleteRow: 'Șterge linie',
+ insertColumnBefore: 'Inserează coloană înainte',
+ insertColumnAfter: 'Inserează coloană după',
+ deleteColumn: 'Șterge coloană',
+ fixedColumnWidth: 'Lățime fixă coloană',
+ resize100: 'Redimensionare 100%',
+ resize75: 'Redimensionare 75%',
+ resize50: 'Redimensionare 50%',
+ resize25: 'Redimensionare 25%',
+ autoSize: 'Dimensiune automată',
+ mirrorHorizontal: 'Oglindă, orizontal',
+ mirrorVertical: 'Oglindă, vertical',
+ rotateLeft: 'Rotește la stânga',
+ rotateRight: 'Rotește la dreapta',
+ maxSize: 'Dimensiune maximă',
+ minSize: 'Dimensiune minimă',
+ tableHeader: 'Antet tabel',
+ mergeCells: 'Îmbină celule',
+ splitCells: 'Divizează celule',
+ HorizontalSplit: 'Despicare orizontală',
+ VerticalSplit: 'Despicare verticală'
+ },
+ menu: {
+ spaced: 'Spațiat',
+ bordered: 'Mărginit',
+ neon: 'Neon',
+ translucent: 'Translucent',
+ shadow: 'Umbră',
+ code: 'Citat'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'ro', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
\ No newline at end of file
--- /dev/null
+import { Lang } from './Lang';
+
+declare const ru: Lang;
+
+export default ru;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'ru',
+ toolbar: {
+ default: 'По умолчанию',
+ save: 'Сохранить',
+ font: 'Шрифт',
+ formats: 'Стиль абзаца',
+ fontSize: 'Размер шрифта',
+ bold: 'Полужирный',
+ underline: 'Подчёркнутый',
+ italic: 'Курсив',
+ strike: 'Зачеркнутый',
+ subscript: 'Нижний индекс',
+ superscript: 'Верхний индекс',
+ removeFormat: 'Очистить форматирование',
+ fontColor: 'Цвет текста',
+ hiliteColor: 'Цвет фона',
+ indent: 'Увеличить отступ',
+ outdent: 'Уменьшить отступ',
+ align: 'Выравнивание',
+ alignLeft: 'Слева',
+ alignRight: 'Справа',
+ alignCenter: 'По центру',
+ alignJustify: 'По ширине',
+ list: 'Списки',
+ orderList: 'Нумерованный',
+ unorderList: 'Маркированный',
+ horizontalRule: 'Горизонтальная линия',
+ hr_solid: 'Сплошная',
+ hr_dotted: 'Пунктир',
+ hr_dashed: 'Штриховая',
+ table: 'Таблица',
+ link: 'Ссылка',
+ math: 'математический',
+ image: 'Изображение',
+ video: 'Видео',
+ audio: 'Аудио',
+ fullScreen: 'Полный экран',
+ showBlocks: 'Блочный вид',
+ codeView: 'Редактировать HTML',
+ undo: 'Отменить',
+ redo: 'Вернуть',
+ preview: 'Предварительный просмотр',
+ print: 'Печать',
+ tag_p: 'Текст',
+ tag_div: 'Базовый',
+ tag_h: 'Заголовок',
+ tag_blockquote: 'Цитата',
+ tag_pre: 'Код',
+ template: 'Шаблон',
+ lineHeight: 'Высота линии',
+ paragraphStyle: 'Стиль абзаца',
+ textStyle: 'Стиль текста',
+ imageGallery: 'Галерея',
+ mention: 'Упоминание'
+ },
+ dialogBox: {
+ linkBox: {
+ title: 'Вставить ссылку',
+ url: 'Ссылка',
+ text: 'Текст',
+ newWindowCheck: 'Открывать в новом окне'
+ },
+ mathBox: {
+ title: 'математический',
+ inputLabel: 'Математическая запись',
+ fontSizeLabel: 'Кегль',
+ previewLabel: 'Предварительный просмотр'
+ },
+ imageBox: {
+ title: 'Вставить изображение',
+ file: 'Выберите файл',
+ url: 'Адрес изображения',
+ altText: 'Текстовое описание изображения'
+ },
+ videoBox: {
+ title: 'Вставить видео',
+ file: 'Выберите файл',
+ url: 'Ссылка на видео, Youtube,Vimeo'
+ },
+ audioBox: {
+ title: 'Вставить аудио',
+ file: 'Выберите файл',
+ url: 'Адрес аудио'
+ },
+ browser: {
+ tags: 'Теги',
+ search: 'Поиск',
+ },
+ caption: 'Добавить подпись',
+ close: 'Закрыть',
+ submitButton: 'Подтвердить',
+ revertButton: 'Сбросить',
+ proportion: 'Сохранить пропорции',
+ basic: 'Без обтекания',
+ left: 'Слева',
+ right: 'Справа',
+ center: 'По центру',
+ width: 'Ширина',
+ height: 'Высота',
+ size: 'Размер',
+ ratio: 'Соотношение'
+ },
+ controller: {
+ edit: 'Изменить',
+ unlink: 'Убрать ссылку',
+ remove: 'Удалить',
+ insertRowAbove: 'Вставить строку выше',
+ insertRowBelow: 'Вставить строку ниже',
+ deleteRow: 'Удалить строку',
+ insertColumnBefore: 'Вставить столбец слева',
+ insertColumnAfter: 'Вставить столбец справа',
+ deleteColumn: 'Удалить столбец',
+ fixedColumnWidth: 'Фиксированная ширина столбца',
+ resize100: 'Размер 100%',
+ resize75: 'Размер 75%',
+ resize50: 'Размер 50%',
+ resize25: 'Размер 25%',
+ autoSize: 'Авто размер',
+ mirrorHorizontal: 'Отразить по горизонтали',
+ mirrorVertical: 'Отразить по вертикали',
+ rotateLeft: 'Повернуть против часовой стрелки',
+ rotateRight: 'Повернуть по часовой стрелке',
+ maxSize: 'Ширина по размеру страницы',
+ minSize: 'Ширина по содержимому',
+ tableHeader: 'Строка заголовков',
+ mergeCells: 'Объединить ячейки',
+ splitCells: 'Разделить ячейку',
+ HorizontalSplit: 'Разделить горизонтально',
+ VerticalSplit: 'Разделить вертикально'
+ },
+ menu: {
+ spaced: 'интервал',
+ bordered: 'Граничная Линия',
+ neon: 'неон',
+ translucent: 'полупрозрачный',
+ shadow: 'Тень',
+ code: 'Код'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'ru', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
\ No newline at end of file
--- /dev/null
+import { Lang } from './Lang';
+
+declare const zhCn: Lang;
+
+export default zhCn;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2019 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_LANG a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const lang = {
+ code: 'zh_cn',
+ toolbar: {
+ default: '默认',
+ save: '保存',
+ font: '字体',
+ formats: '格式',
+ fontSize: '字号',
+ bold: '粗体',
+ underline: '下划线',
+ italic: '斜体',
+ strike: '删除线',
+ subscript: '下标',
+ superscript: '上标',
+ removeFormat: '清除格式',
+ fontColor: '字体颜色',
+ hiliteColor: '背景颜色',
+ indent: '增加缩进',
+ outdent: '减少缩进',
+ align: '对齐方式',
+ alignLeft: '左对齐',
+ alignRight: '右对齐',
+ alignCenter: '居中',
+ alignJustify: '两端对齐',
+ list: '列表',
+ orderList: '有序列表',
+ unorderList: '无序列表',
+ horizontalRule: '水平线',
+ hr_solid: '实线',
+ hr_dotted: '点线',
+ hr_dashed: '虚线',
+ table: '表格',
+ link: '超链接',
+ math: '数学',
+ image: '图片',
+ video: '视频',
+ audio: '音讯',
+ fullScreen: '全屏',
+ showBlocks: '显示块区域',
+ codeView: '代码视图',
+ undo: '撤消',
+ redo: '恢复',
+ preview: '预览',
+ print: '打印',
+ tag_p: '段落',
+ tag_div: '正文 (DIV)',
+ tag_h: '标题',
+ tag_blockquote: '引用',
+ tag_pre: '代码',
+ template: '模板',
+ lineHeight: '行高',
+ paragraphStyle: '段落样式',
+ textStyle: '文字样式',
+ imageGallery: '图片库',
+ mention: '提到'
+ },
+ dialogBox: {
+ linkBox: {
+ title: '插入超链接',
+ url: '网址',
+ text: '字体',
+ newWindowCheck: '在新标签页中打开'
+ },
+ mathBox: {
+ title: '数学',
+ inputLabel: '数学符号',
+ fontSizeLabel: '字号',
+ previewLabel: '预览'
+ },
+ imageBox: {
+ title: '插入图片',
+ file: '上传图片',
+ url: '图片网址',
+ altText: '替换文字'
+ },
+ videoBox: {
+ title: '插入视频',
+ file: '上传图片',
+ url: '嵌入网址, Youtube,Vimeo'
+ },
+ audioBox: {
+ title: '插入音频',
+ file: '上传图片',
+ url: '音频网址'
+ },
+ browser: {
+ tags: '标签',
+ search: '搜索',
+ },
+ caption: '标题',
+ close: '取消',
+ submitButton: '确定',
+ revertButton: '恢复',
+ proportion: '比例',
+ basic: '基本',
+ left: '左',
+ right: '右',
+ center: '居中',
+ width: '宽度',
+ height: '高度',
+ size: '尺寸',
+ ratio: '比'
+ },
+ controller: {
+ edit: '编辑',
+ unlink: '去除链接',
+ remove: '删除',
+ insertRowAbove: '在上方插入',
+ insertRowBelow: '在下方插入',
+ deleteRow: '删除行',
+ insertColumnBefore: '在左侧插入',
+ insertColumnAfter: '在右侧插入',
+ deleteColumn: '删除列',
+ fixedColumnWidth: '固定列宽',
+ resize100: '放大 100%',
+ resize75: '放大 75%',
+ resize50: '放大 50%',
+ resize25: '放大 25%',
+ mirrorHorizontal: '翻转左右',
+ mirrorVertical: '翻转上下',
+ rotateLeft: '向左旋转',
+ rotateRight: '向右旋转',
+ maxSize: '最大尺寸',
+ minSize: '最小尺寸',
+ tableHeader: '表格标题',
+ mergeCells: '合并单元格',
+ splitCells: '分割单元格',
+ HorizontalSplit: '水平分割',
+ VerticalSplit: '垂直分割'
+ },
+ menu: {
+ spaced: '间隔开',
+ bordered: '边界线',
+ neon: '霓虹灯',
+ translucent: '半透明',
+ shadow: '阴影',
+ code: '代码'
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_LANG) {
+ Object.defineProperty(window, 'SUNEDITOR_LANG', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_LANG, 'zh_cn', {
+ enumerable: true,
+ writable: true,
+ configurable: true,
+ value: lang
+ });
+ }
+
+ return lang;
+}));
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+import _icons from '../assets/defaultIcons';
+import _defaultLang from '../lang/en';
+import util from './util';
+
+export default {
+ /**
+ * @description document create
+ * @param {Element} element Textarea
+ * @param {Object} options Options
+ * @returns {Object}
+ */
+ init: function (element, options) {
+ if (typeof options !== 'object') options = {};
+
+ const doc = document;
+
+ /** --- init options --- */
+ this._initOptions(element, options);
+
+ // suneditor div
+ const top_div = doc.createElement('DIV');
+ top_div.className = 'sun-editor' + (options.rtl ? ' se-rtl' : '');
+ if (element.id) top_div.id = 'suneditor_' + element.id;
+
+ // relative div
+ const relative = doc.createElement('DIV');
+ relative.className = 'se-container';
+
+ // toolbar
+ const tool_bar = this._createToolBar(doc, options.buttonList, options.plugins, options);
+ tool_bar.element.style.visibility = 'hidden';
+ if (tool_bar.pluginCallButtons.math) this._checkKatexMath(options.katex);
+ const arrow = doc.createElement('DIV');
+ arrow.className = 'se-arrow';
+
+ // sticky toolbar dummy
+ const sticky_dummy = doc.createElement('DIV');
+ sticky_dummy.className = 'se-toolbar-sticky-dummy';
+
+ // inner editor div
+ const editor_div = doc.createElement('DIV');
+ editor_div.className = 'se-wrapper';
+
+ /** --- init elements and create bottom bar --- */
+ const initElements = this._initElements(options, top_div, tool_bar.element, arrow);
+
+ const bottomBar = initElements.bottomBar;
+ const wysiwyg_div = initElements.wysiwygFrame;
+ const placeholder_span = initElements.placeholder;
+ let textarea = initElements.codeView;
+
+ // resizing bar
+ const resizing_bar = bottomBar.resizingBar;
+ const navigation = bottomBar.navigation;
+ const char_wrapper = bottomBar.charWrapper;
+ const char_counter = bottomBar.charCounter;
+
+ // loading box
+ const loading_box = doc.createElement('DIV');
+ loading_box.className = 'se-loading-box sun-editor-common';
+ loading_box.innerHTML = '<div class="se-loading-effect"></div>';
+
+ // enter line
+ const line_breaker = doc.createElement('DIV');
+ line_breaker.className = 'se-line-breaker';
+ line_breaker.innerHTML = '<button class="se-btn">' + options.icons.line_break + '</button>';
+ const line_breaker_t = doc.createElement('DIV');
+ line_breaker_t.className += 'se-line-breaker-component';
+ const line_breaker_b = line_breaker_t.cloneNode(true);
+ line_breaker_t.innerHTML = line_breaker_b.innerHTML = options.icons.line_break;
+
+ // resize operation background
+ const resize_back = doc.createElement('DIV');
+ resize_back.className = 'se-resizing-back';
+
+ // toolbar container
+ const toolbarContainer = options.toolbarContainer;
+ if (toolbarContainer) {
+ toolbarContainer.appendChild(tool_bar.element);
+ }
+
+ /** append html */
+ editor_div.appendChild(textarea);
+ if (placeholder_span) editor_div.appendChild(placeholder_span);
+ if (!toolbarContainer) relative.appendChild(tool_bar.element);
+ relative.appendChild(sticky_dummy);
+ relative.appendChild(editor_div);
+ relative.appendChild(resize_back);
+ relative.appendChild(loading_box);
+ relative.appendChild(line_breaker);
+ relative.appendChild(line_breaker_t);
+ relative.appendChild(line_breaker_b);
+ if (resizing_bar) relative.appendChild(resizing_bar);
+ top_div.appendChild(relative);
+
+ textarea = this._checkCodeMirror(options, textarea);
+
+ return {
+ constructed: {
+ _top: top_div,
+ _relative: relative,
+ _toolBar: tool_bar.element,
+ _menuTray: tool_bar._menuTray,
+ _editorArea: editor_div,
+ _wysiwygArea: wysiwyg_div,
+ _codeArea: textarea,
+ _placeholder: placeholder_span,
+ _resizingBar: resizing_bar,
+ _navigation: navigation,
+ _charWrapper: char_wrapper,
+ _charCounter: char_counter,
+ _loading: loading_box,
+ _lineBreaker: line_breaker,
+ _lineBreaker_t: line_breaker_t,
+ _lineBreaker_b: line_breaker_b,
+ _resizeBack: resize_back,
+ _stickyDummy: sticky_dummy,
+ _arrow: arrow
+ },
+ options: options,
+ plugins: tool_bar.plugins,
+ pluginCallButtons: tool_bar.pluginCallButtons,
+ _responsiveButtons: tool_bar.responsiveButtons
+ };
+ },
+
+ /**
+ * @description Check the CodeMirror option to apply the CodeMirror and return the CodeMirror element.
+ * @param {Object} options options
+ * @param {Element} textarea textarea element
+ * @private
+ */
+ _checkCodeMirror: function (options, textarea) {
+ if (options.codeMirror) {
+ const cmOptions = [{
+ mode: 'htmlmixed',
+ htmlMode: true,
+ lineNumbers: true,
+ lineWrapping: true
+ }, (options.codeMirror.options || {})].reduce(function (init, option) {
+ for (let key in option) {
+ if (util.hasOwn(option, key)) init[key] = option[key];
+ }
+ return init;
+ }, {});
+
+ if (options.height === 'auto') {
+ cmOptions.viewportMargin = Infinity;
+ cmOptions.height = 'auto';
+ }
+
+ const cm = options.codeMirror.src.fromTextArea(textarea, cmOptions);
+ cm.display.wrapper.style.cssText = textarea.style.cssText;
+
+ options.codeMirrorEditor = cm;
+ textarea = cm.display.wrapper;
+ textarea.className += ' se-wrapper-code-mirror';
+ }
+
+ return textarea;
+ },
+
+ /**
+ * @description Check for a katex object.
+ * @param {Object} katex katex object
+ * @private
+ */
+ _checkKatexMath: function (katex) {
+ if (!katex) throw Error('[SUNEDITOR.create.fail] To use the math button you need to add a "katex" object to the options.');
+
+ const katexOptions = [{
+ throwOnError: false,
+ }, (katex.options || {})].reduce(function (init, option) {
+ for (let key in option) {
+ if (util.hasOwn(option, key)) init[key] = option[key];
+ }
+ return init;
+ }, {});
+
+ katex.options = katexOptions;
+ },
+
+ /**
+ * @description Add or reset options
+ * @param {Object} mergeOptions New options property
+ * @param {Object} context Context object of core
+ * @param {Object} plugins Origin plugins
+ * @param {Object} originOptions Origin options
+ * @returns {Object} pluginCallButtons
+ * @private
+ */
+ _setOptions: function (mergeOptions, context, plugins, originOptions) {
+ this._initOptions(context.element.originElement, mergeOptions);
+
+ const el = context.element;
+ const relative = el.relative;
+ const editorArea = el.editorArea;
+ const isNewToolbarContainer = mergeOptions.toolbarContainer && mergeOptions.toolbarContainer !== originOptions.toolbarContainer;
+ const isNewToolbar = !!mergeOptions.buttonList || mergeOptions.mode !== originOptions.mode || isNewToolbarContainer;
+ const isNewPlugins = !!mergeOptions.plugins;
+
+ const tool_bar = this._createToolBar(document, (isNewToolbar ? mergeOptions.buttonList : originOptions.buttonList), (isNewPlugins ? mergeOptions.plugins : plugins), mergeOptions);
+ if (tool_bar.pluginCallButtons.math) this._checkKatexMath(mergeOptions.katex);
+ const arrow = document.createElement('DIV');
+ arrow.className = 'se-arrow';
+
+ if (isNewToolbar) {
+ tool_bar.element.style.visibility = 'hidden';
+ // toolbar container
+ if (isNewToolbarContainer) {
+ mergeOptions.toolbarContainer.appendChild(tool_bar.element);
+ el.toolbar.parentElement.removeChild(el.toolbar);
+ } else {
+ el.toolbar.parentElement.replaceChild(tool_bar.element, el.toolbar);
+ }
+
+ el.toolbar = tool_bar.element;
+ el._menuTray = tool_bar._menuTray;
+ el._arrow = arrow;
+ }
+
+ const initElements = this._initElements(mergeOptions, el.topArea, (isNewToolbar ? tool_bar.element : el.toolbar), arrow);
+
+ const bottomBar = initElements.bottomBar;
+ const wysiwygFrame = initElements.wysiwygFrame;
+ const placeholder_span = initElements.placeholder;
+ let code = initElements.codeView;
+
+ if (el.resizingBar) relative.removeChild(el.resizingBar);
+ if (bottomBar.resizingBar) relative.appendChild(bottomBar.resizingBar);
+
+ editorArea.innerHTML = '';
+ editorArea.appendChild(code);
+ if (placeholder_span) editorArea.appendChild(placeholder_span);
+
+ code = this._checkCodeMirror(mergeOptions, code);
+
+ el.resizingBar = bottomBar.resizingBar;
+ el.navigation = bottomBar.navigation;
+ el.charWrapper = bottomBar.charWrapper;
+ el.charCounter = bottomBar.charCounter;
+ el.wysiwygFrame = wysiwygFrame;
+ el.code = code;
+ el.placeholder = placeholder_span;
+
+ if (mergeOptions.rtl) util.addClass(el.topArea, 'se-rtl');
+ else util.removeClass(el.topArea, 'se-rtl');
+
+ return {
+ callButtons: isNewToolbar ? tool_bar.pluginCallButtons : null,
+ plugins: isNewToolbar || isNewPlugins ? tool_bar.plugins : null,
+ toolbar: tool_bar
+ };
+ },
+
+ /**
+ * @description Initialize property of suneditor elements
+ * @param {Object} options Options
+ * @param {Element} topDiv Suneditor top div
+ * @param {Element} toolBar Tool bar
+ * @param {Element} toolBarArrow Tool bar arrow (balloon editor)
+ * @returns {Object} Bottom bar elements (resizingBar, navigation, charWrapper, charCounter)
+ * @private
+ */
+ _initElements: function (options, topDiv, toolBar, toolBarArrow) {
+ /** top div */
+ topDiv.style.cssText = options._editorStyles.top;
+
+ /** toolbar */
+ if (/inline/i.test(options.mode)) {
+ toolBar.className += ' se-toolbar-inline';
+ toolBar.style.width = options.toolbarWidth;
+ } else if (/balloon/i.test(options.mode)) {
+ toolBar.className += ' se-toolbar-balloon';
+ toolBar.style.width = options.toolbarWidth;
+ toolBar.appendChild(toolBarArrow);
+ }
+
+ /** editor */
+ // wysiwyg div or iframe
+ const wysiwygDiv = document.createElement(!options.iframe ? 'DIV' : 'IFRAME');
+ wysiwygDiv.className = 'se-wrapper-inner se-wrapper-wysiwyg';
+
+ if (!options.iframe) {
+ wysiwygDiv.setAttribute('contenteditable', true);
+ wysiwygDiv.setAttribute('scrolling', 'auto');
+ wysiwygDiv.className += ' ' + options._editableClass;
+ wysiwygDiv.style.cssText = options._editorStyles.frame + options._editorStyles.editor;
+ } else {
+ wysiwygDiv.allowFullscreen = true;
+ wysiwygDiv.frameBorder = 0;
+ wysiwygDiv.style.cssText = options._editorStyles.frame;
+ }
+
+ // textarea for code view
+ const textarea = document.createElement('TEXTAREA');
+ textarea.className = 'se-wrapper-inner se-wrapper-code';
+ textarea.style.cssText = options._editorStyles.frame;
+ textarea.style.display = 'none';
+ if (options.height === 'auto') textarea.style.overflow = 'hidden';
+
+ /** resize bar */
+ let resizingBar = null;
+ let navigation = null;
+ let charWrapper = null;
+ let charCounter = null;
+ if (options.resizingBar) {
+ resizingBar = document.createElement('DIV');
+ resizingBar.className = 'se-resizing-bar sun-editor-common';
+
+ /** navigation */
+ navigation = document.createElement('DIV');
+ navigation.className = 'se-navigation sun-editor-common';
+ resizingBar.appendChild(navigation);
+
+ /** char counter */
+ if (options.charCounter) {
+ charWrapper = document.createElement('DIV');
+ charWrapper.className = 'se-char-counter-wrapper';
+
+ if (options.charCounterLabel) {
+ const charLabel = document.createElement('SPAN');
+ charLabel.className = 'se-char-label';
+ charLabel.textContent = options.charCounterLabel;
+ charWrapper.appendChild(charLabel);
+ }
+
+ charCounter = document.createElement('SPAN');
+ charCounter.className = 'se-char-counter';
+ charCounter.textContent = '0';
+ charWrapper.appendChild(charCounter);
+
+ if (options.maxCharCount > 0) {
+ const char_max = document.createElement('SPAN');
+ char_max.textContent = ' / ' + options.maxCharCount;
+ charWrapper.appendChild(char_max);
+ }
+
+ resizingBar.appendChild(charWrapper);
+ }
+ }
+
+ let placeholder = null;
+ if (options.placeholder) {
+ placeholder = document.createElement('SPAN');
+ placeholder.className = 'se-placeholder';
+ placeholder.innerText = options.placeholder;
+ }
+
+ return {
+ bottomBar: {
+ resizingBar: resizingBar,
+ navigation: navigation,
+ charWrapper: charWrapper,
+ charCounter: charCounter
+ },
+ wysiwygFrame: wysiwygDiv,
+ codeView: textarea,
+ placeholder: placeholder
+ };
+ },
+
+ /**
+ * @description Initialize options
+ * @param {Element} element Options object
+ * @param {Object} options Options object
+ * @private
+ */
+ _initOptions: function (element, options) {
+ /** Values */
+ options.lang = options.lang || _defaultLang;
+ options.defaultTag = typeof options.defaultTag === 'string' ? options.defaultTag : 'p';
+ options.value = typeof options.value === 'string' ? options.value : null;
+ options.historyStackDelayTime = typeof options.historyStackDelayTime === 'number' ? options.historyStackDelayTime : 400;
+ /** Whitelist */
+ options._defaultTagsWhitelist = typeof options._defaultTagsWhitelist === 'string' ? options._defaultTagsWhitelist : 'br|p|div|pre|blockquote|h[1-6]|ol|ul|li|hr|figure|figcaption|img|iframe|audio|video|source|table|thead|tbody|tr|th|td|a|b|strong|var|i|em|u|ins|s|span|strike|del|sub|sup|code';
+ options._editorTagsWhitelist = options._defaultTagsWhitelist + (typeof options.addTagsWhitelist === 'string' && options.addTagsWhitelist.length > 0 ? '|' + options.addTagsWhitelist : '');
+ options.pasteTagsWhitelist = typeof options.pasteTagsWhitelist === 'string' ? options.pasteTagsWhitelist : options._editorTagsWhitelist;
+ options.attributesWhitelist = (!options.attributesWhitelist || typeof options.attributesWhitelist !== 'object') ? null : options.attributesWhitelist;
+ /** Layout */
+ options.mode = options.mode || 'classic'; // classic, inline, balloon, balloon-always
+ options.rtl = !!options.rtl;
+ options._editableClass = 'sun-editor-editable' + (options.rtl ? ' se-rtl' : '');
+ options.toolbarWidth = options.toolbarWidth ? (util.isNumber(options.toolbarWidth) ? options.toolbarWidth + 'px' : options.toolbarWidth) : 'auto';
+ options.toolbarContainer = typeof options.toolbarContainer === 'string' ? document.querySelector(options.toolbarContainer) : options.toolbarContainer;
+ options.stickyToolbar = (/balloon/i.test(options.mode) || !!options.toolbarContainer) ? -1 : options.stickyToolbar === undefined ? 0 : (/^\d+/.test(options.stickyToolbar) ? util.getNumber(options.stickyToolbar, 0) : -1);
+ options.iframe = options.fullPage || options.iframe;
+ options.fullPage = !!options.fullPage;
+ options.iframeCSSFileName = options.iframe ? typeof options.iframeCSSFileName === 'string' ? [options.iframeCSSFileName] : (options.iframeCSSFileName || ['suneditor']) : null;
+ options.previewTemplate = typeof options.previewTemplate === 'string' ? options.previewTemplate : null;
+ /** CodeMirror object */
+ options.codeMirror = options.codeMirror ? options.codeMirror.src ? options.codeMirror : {src: options.codeMirror} : null;
+ /** katex object (Math plugin) */
+ options.katex = options.katex ? options.katex.src ? options.katex : {src: options.katex} : null;
+ /** Display */
+ options.position = typeof options.position === 'string' ? options.position : null;
+ options.display = options.display || (element.style.display === 'none' || !element.style.display ? 'block' : element.style.display);
+ options.popupDisplay = options.popupDisplay || 'full';
+ /** Bottom resizing bar */
+ options.resizingBar = options.resizingBar === undefined ? (/inline|balloon/i.test(options.mode) ? false : true) : options.resizingBar;
+ options.showPathLabel = !options.resizingBar ? false : typeof options.showPathLabel === 'boolean' ? options.showPathLabel : true;
+ /** Character count */
+ options.charCounter = options.maxCharCount > 0 ? true : typeof options.charCounter === 'boolean' ? options.charCounter : false;
+ options.charCounterType = typeof options.charCounterType === 'string' ? options.charCounterType : 'char';
+ options.charCounterLabel = typeof options.charCounterLabel === 'string' ? options.charCounterLabel.trim() : null;
+ options.maxCharCount = util.isNumber(options.maxCharCount) && options.maxCharCount > -1 ? options.maxCharCount * 1 : null;
+ /** Width size */
+ options.width = options.width ? (util.isNumber(options.width) ? options.width + 'px' : options.width) : (element.clientWidth ? element.clientWidth + 'px' : '100%');
+ options.minWidth = (util.isNumber(options.minWidth) ? options.minWidth + 'px' : options.minWidth) || '';
+ options.maxWidth = (util.isNumber(options.maxWidth) ? options.maxWidth + 'px' : options.maxWidth) || '';
+ /** Height size */
+ options.height = options.height ? (util.isNumber(options.height) ? options.height + 'px' : options.height) : (element.clientHeight ? element.clientHeight + 'px' : 'auto');
+ options.minHeight = (util.isNumber(options.minHeight) ? options.minHeight + 'px' : options.minHeight) || '';
+ options.maxHeight = (util.isNumber(options.maxHeight) ? options.maxHeight + 'px' : options.maxHeight) || '';
+ /** Editing area default style */
+ options.defaultStyle = typeof options.defaultStyle === 'string' ? options.defaultStyle : '';
+ /** Defining menu items */
+ options.font = !options.font ? null : options.font;
+ options.fontSize = !options.fontSize ? null : options.fontSize;
+ options.formats = !options.formats ? null : options.formats;
+ options.colorList = !options.colorList ? null : options.colorList;
+ options.lineHeights = !options.lineHeights ? null : options.lineHeights;
+ options.paragraphStyles = !options.paragraphStyles ? null : options.paragraphStyles;
+ options.textStyles = !options.textStyles ? null : options.textStyles;
+ options.fontSizeUnit = typeof options.fontSizeUnit === 'string' ? (options.fontSizeUnit.trim() || 'px') : 'px';
+ /** Image */
+ options.imageResizing = options.imageResizing === undefined ? true : options.imageResizing;
+ options.imageHeightShow = options.imageHeightShow === undefined ? true : !!options.imageHeightShow;
+ options.imageWidth = !options.imageWidth ? 'auto' : util.isNumber(options.imageWidth) ? options.imageWidth + 'px' : options.imageWidth;
+ options.imageHeight = !options.imageHeight ? 'auto' : util.isNumber(options.imageHeight) ? options.imageHeight + 'px' : options.imageHeight;
+ options.imageSizeOnlyPercentage = !!options.imageSizeOnlyPercentage;
+ options._imageSizeUnit = options.imageSizeOnlyPercentage ? '%' : 'px';
+ options.imageRotation = options.imageRotation !== undefined ? options.imageRotation : !(options.imageSizeOnlyPercentage || !options.imageHeightShow);
+ options.imageFileInput = options.imageFileInput === undefined ? true : options.imageFileInput;
+ options.imageUrlInput = (options.imageUrlInput === undefined || !options.imageFileInput) ? true : options.imageUrlInput;
+ options.imageUploadHeader = options.imageUploadHeader || null;
+ options.imageUploadUrl = typeof options.imageUploadUrl === 'string' ? options.imageUploadUrl : null;
+ options.imageUploadSizeLimit = /\d+/.test(options.imageUploadSizeLimit) ? util.getNumber(options.imageUploadSizeLimit, 0) : null;
+ options.imageMultipleFile = !!options.imageMultipleFile;
+ options.imageAccept = (typeof options.imageAccept !== 'string' || options.imageAccept.trim() === "*") ? 'image/*' : options.imageAccept.trim() || 'image/*';
+ /** Image - image gallery */
+ options.imageGalleryUrl = typeof options.imageGalleryUrl === 'string' ? options.imageGalleryUrl : null;
+ /** Video */
+ options.videoResizing = options.videoResizing === undefined ? true : options.videoResizing;
+ options.videoHeightShow = options.videoHeightShow === undefined ? true : !!options.videoHeightShow;
+ options.videoRatioShow = options.videoRatioShow === undefined ? true : !!options.videoRatioShow;
+ options.videoWidth = !options.videoWidth || !util.getNumber(options.videoWidth, 0) ? '' : util.isNumber(options.videoWidth) ? options.videoWidth + 'px' : options.videoWidth;
+ options.videoHeight = !options.videoHeight || !util.getNumber(options.videoHeight, 0) ? '' : util.isNumber(options.videoHeight) ? options.videoHeight + 'px' : options.videoHeight;
+ options.videoSizeOnlyPercentage = !!options.videoSizeOnlyPercentage;
+ options._videoSizeUnit = options.videoSizeOnlyPercentage ? '%' : 'px';
+ options.videoRotation = options.videoRotation !== undefined ? options.videoRotation : !(options.videoSizeOnlyPercentage || !options.videoHeightShow);
+ options.videoRatio = (util.getNumber(options.videoRatio, 4) || 0.5625);
+ options.videoRatioList = !options.videoRatioList ? null : options.videoRatioList;
+ options.youtubeQuery = (options.youtubeQuery || '').replace('?', '');
+ options.videoFileInput = !!options.videoFileInput;
+ options.videoUrlInput = (options.videoUrlInput === undefined || !options.videoFileInput) ? true : options.videoUrlInput;
+ options.videoUploadHeader = options.videoUploadHeader || null;
+ options.videoUploadUrl = typeof options.videoUploadUrl === 'string' ? options.videoUploadUrl : null;
+ options.videoUploadSizeLimit = /\d+/.test(options.videoUploadSizeLimit) ? util.getNumber(options.videoUploadSizeLimit, 0) : null;
+ options.videoMultipleFile = !!options.videoMultipleFile;
+ options.videoTagAttrs = options.videoTagAttrs || null;
+ options.videoIframeAttrs = options.videoIframeAttrs || null;
+ options.videoAccept = (typeof options.videoAccept !== 'string' || options.videoAccept.trim() === "*") ? 'video/*' : options.videoAccept.trim() || 'video/*';
+ /** Audio */
+ options.audioWidth = !options.audioWidth ? '' : util.isNumber(options.audioWidth) ? options.audioWidth + 'px' : options.audioWidth;
+ options.audioHeight = !options.audioHeight ? '' : util.isNumber(options.audioHeight) ? options.audioHeight + 'px' : options.audioHeight;
+ options.audioFileInput = !!options.audioFileInput;
+ options.audioUrlInput = (options.audioUrlInput === undefined || !options.audioFileInput) ? true : options.audioUrlInput;
+ options.audioUploadHeader = options.audioUploadHeader || null;
+ options.audioUploadUrl = typeof options.audioUploadUrl === 'string' ? options.audioUploadUrl : null;
+ options.audioUploadSizeLimit = /\d+/.test(options.audioUploadSizeLimit) ? util.getNumber(options.audioUploadSizeLimit, 0) : null;
+ options.audioMultipleFile = !!options.audioMultipleFile;
+ options.audioTagAttrs = options.audioTagAttrs || null;
+ options.audioAccept = (typeof options.audioAccept !== 'string' || options.audioAccept.trim() === "*") ? 'audio/*' : options.audioAccept.trim() || 'audio/*';
+ /** Table */
+ options.tableCellControllerPosition = typeof options.tableCellControllerPosition === 'string' ? options.tableCellControllerPosition.toLowerCase() : 'cell';
+ /** Key actions */
+ options.tabDisable = !!options.tabDisable;
+ options.shortcutsDisable = (Array.isArray(options.shortcutsDisable) && options.shortcutsDisable.length > 0) ? options.shortcutsDisable.map(function (v) { return v.toLowerCase(); }) : [];
+ options.shortcutsHint = options.shortcutsHint === undefined ? true : !!options.shortcutsHint;
+ /** Defining save button */
+ options.callBackSave = !options.callBackSave ? null : options.callBackSave;
+ /** Templates Array */
+ options.templates = !options.templates ? null : options.templates;
+ /** ETC */
+ options.placeholder = typeof options.placeholder === 'string' ? options.placeholder : null;
+ options.linkProtocol = typeof options.linkProtocol === 'string' ? options.linkProtocol : null;
+ /** Buttons */
+ options.buttonList = !!options.buttonList ? JSON.parse(JSON.stringify(options.buttonList)) : [
+ ['undo', 'redo'],
+ ['bold', 'underline', 'italic', 'strike', 'subscript', 'superscript'],
+ ['removeFormat'],
+ ['outdent', 'indent'],
+ ['fullScreen', 'showBlocks', 'codeView'],
+ ['preview', 'print']
+ ];
+
+ /** RTL - buttons */
+ if (options.rtl) {
+ options.buttonList = options.buttonList.reverse();
+ }
+
+ /** --- Define icons --- */
+ // custom icons
+ options.icons = (!options.icons || typeof options.icons !== 'object') ? _icons : [_icons, options.icons].reduce(function (_default, _new) {
+ for (let key in _new) {
+ if (util.hasOwn(_new, key)) _default[key] = _new[key];
+ }
+ return _default;
+ }, {});
+ // rtl icons
+ options.icons = !options.rtl ? options.icons : [options.icons, options.icons.rtl].reduce(function (_default, _new) {
+ for (let key in _new) {
+ if (util.hasOwn(_new, key)) _default[key] = _new[key];
+ }
+ return _default;
+ }, {});
+
+ /** _init options */
+ options._editorStyles = util._setDefaultOptionStyle(options, options.defaultStyle);
+ },
+
+ /**
+ * @description Suneditor's Default button list
+ * @param {Object} options options
+ * @private
+ */
+ _defaultButtons: function (options) {
+ const icons = options.icons;
+ const lang = options.lang;
+ const cmd = util.isOSX_IOS ? '⌘' : 'CTRL';
+ const addShift = util.isOSX_IOS ? '⇧' : '+SHIFT';
+ const shortcutsDisable = !options.shortcutsHint ? ['bold', 'strike', 'underline', 'italic', 'undo', 'indent'] : options.shortcutsDisable;
+ const indentKey = options.rtl ? ['[',']'] : [']','['];
+
+ return {
+ /** default command */
+ bold: ['_se_command_bold', lang.toolbar.bold + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('bold') > -1 ? '' : cmd + '+<span class="se-shortcut-key">B</span>') + '</span>', 'STRONG', '', icons.bold],
+ underline: ['_se_command_underline', lang.toolbar.underline + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('underline') > -1 ? '' : cmd + '+<span class="se-shortcut-key">U</span>') + '</span>', 'U', '', icons.underline],
+ italic: ['_se_command_italic', lang.toolbar.italic + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('italic') > -1 ? '' : cmd + '+<span class="se-shortcut-key">I</span>') + '</span>', 'EM', '', icons.italic],
+ strike: ['_se_command_strike', lang.toolbar.strike + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('strike') > -1 ? '' : cmd + addShift + '+<span class="se-shortcut-key">S</span>') + '</span>', 'DEL', '', icons.strike],
+ subscript: ['_se_command_subscript', lang.toolbar.subscript, 'SUB', '', icons.subscript],
+ superscript: ['_se_command_superscript', lang.toolbar.superscript, 'SUP', '', icons.superscript],
+ removeFormat: ['', lang.toolbar.removeFormat, 'removeFormat', '', icons.erase],
+ indent: ['_se_command_indent', lang.toolbar.indent + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('indent') > -1 ? '' : cmd + '+<span class="se-shortcut-key">' + indentKey[0] + '</span>') + '</span>', 'indent', '', icons.outdent],
+ outdent: ['_se_command_outdent', lang.toolbar.outdent + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('indent') > -1 ? '' : cmd + '+<span class="se-shortcut-key">' + indentKey[1] + '</span>') + '</span>', 'outdent', '', icons.indent],
+ fullScreen: ['se-code-view-enabled se-resizing-enabled _se_command_fullScreen', lang.toolbar.fullScreen, 'fullScreen', '', icons.expansion],
+ showBlocks: ['_se_command_showBlocks', lang.toolbar.showBlocks, 'showBlocks', '', icons.show_blocks],
+ codeView: ['se-code-view-enabled se-resizing-enabled _se_command_codeView', lang.toolbar.codeView, 'codeView', '', icons.code_view],
+ undo: ['_se_command_undo se-resizing-enabled', lang.toolbar.undo + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('undo') > -1 ? '' : cmd + '+<span class="se-shortcut-key">Z</span>') + '</span>', 'undo', '', icons.undo],
+ redo: ['_se_command_redo se-resizing-enabled', lang.toolbar.redo + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('undo') > -1 ? '' : cmd + '+<span class="se-shortcut-key">Y</span> / ' + cmd + addShift + '+<span class="se-shortcut-key">Z</span>') + '</span>', 'redo', '', icons.redo],
+ preview: ['se-resizing-enabled', lang.toolbar.preview, 'preview', '', icons.preview],
+ print: ['se-resizing-enabled', lang.toolbar.print, 'print', '', icons.print],
+ save: ['_se_command_save se-resizing-enabled', lang.toolbar.save, 'save', '', icons.save],
+ /** plugins - command */
+ blockquote: ['', lang.toolbar.tag_blockquote, 'blockquote', 'command', icons.blockquote],
+ /** plugins - submenu */
+ font: ['se-btn-select se-btn-tool-font', lang.toolbar.font, 'font', 'submenu', '<span class="txt">' + lang.toolbar.font + '</span>' + icons.arrow_down],
+ formatBlock: ['se-btn-select se-btn-tool-format', lang.toolbar.formats, 'formatBlock', 'submenu', '<span class="txt">' + lang.toolbar.formats + '</span>' + icons.arrow_down],
+ fontSize: ['se-btn-select se-btn-tool-size', lang.toolbar.fontSize, 'fontSize', 'submenu', '<span class="txt">' + lang.toolbar.fontSize + '</span>' + icons.arrow_down],
+ fontColor: ['', lang.toolbar.fontColor, 'fontColor', 'submenu', icons.font_color],
+ hiliteColor: ['', lang.toolbar.hiliteColor, 'hiliteColor', 'submenu', icons.highlight_color],
+ align: ['se-btn-align', lang.toolbar.align, 'align', 'submenu', (options.rtl ? icons.align_right : icons.align_left)],
+ list: ['', lang.toolbar.list, 'list', 'submenu', icons.list_number],
+ horizontalRule: ['btn_line', lang.toolbar.horizontalRule, 'horizontalRule', 'submenu', icons.horizontal_rule],
+ table: ['', lang.toolbar.table, 'table', 'submenu', icons.table],
+ lineHeight: ['', lang.toolbar.lineHeight, 'lineHeight', 'submenu', icons.line_height],
+ template: ['', lang.toolbar.template, 'template', 'submenu', icons.template],
+ paragraphStyle: ['', lang.toolbar.paragraphStyle, 'paragraphStyle', 'submenu', icons.paragraph_style],
+ textStyle: ['', lang.toolbar.textStyle, 'textStyle', 'submenu', icons.text_style],
+ /** plugins - dialog */
+ link: ['', lang.toolbar.link, 'link', 'dialog', icons.link],
+ image: ['', lang.toolbar.image, 'image', 'dialog', icons.image],
+ video: ['', lang.toolbar.video, 'video', 'dialog', icons.video],
+ audio: ['', lang.toolbar.audio, 'audio', 'dialog', icons.audio],
+ math: ['', lang.toolbar.math, 'math', 'dialog', icons.math],
+ /** plugins - fileBrowser */
+ imageGallery: ['', lang.toolbar.imageGallery, 'imageGallery', 'fileBrowser', icons.image_gallery]
+ };
+ },
+
+ /**
+ * @description Create a group div containing each module
+ * @returns {Object}
+ * @private
+ */
+ _createModuleGroup: function () {
+ const oDiv = util.createElement('DIV');
+ oDiv.className = 'se-btn-module se-btn-module-border';
+
+ const oUl = util.createElement('UL');
+ oUl.className = 'se-menu-list';
+ oDiv.appendChild(oUl);
+
+ return {
+ 'div': oDiv,
+ 'ul': oUl
+ };
+ },
+
+ /**
+ * @description Create a button element
+ * @param {string} buttonClass className in button
+ * @param {string} title Title in button
+ * @param {string} dataCommand The data-command property of the button
+ * @param {string} dataDisplay The data-display property of the button ('dialog', 'submenu', 'command')
+ * @param {string} innerHTML Html in button
+ * @param {string} _disabled Button disabled
+ * @param {Object} _icons Icons
+ * @returns {Object}
+ * @private
+ */
+ _createButton: function (buttonClass, title, dataCommand, dataDisplay, innerHTML, _disabled, _icons) {
+ const oLi = util.createElement('LI');
+ const oButton = util.createElement('BUTTON');
+
+ oButton.setAttribute('type', 'button');
+ oButton.setAttribute('class', 'se-btn' + (buttonClass ? ' ' + buttonClass : '') + ' se-tooltip');
+ oButton.setAttribute('data-command', dataCommand);
+ oButton.setAttribute('data-display', dataDisplay);
+ oButton.setAttribute('tabindex', '-1');
+
+ if (!innerHTML) innerHTML = '<span class="se-icon-text">!</span>';
+ if (/^default\./i.test(innerHTML)) {
+ innerHTML = _icons[innerHTML.replace(/^default\./i, '')];
+ }
+ if (/^text\./i.test(innerHTML)) {
+ innerHTML = innerHTML.replace(/^text\./i, '');
+ oButton.className += ' se-btn-more-text';
+ }
+
+ innerHTML += '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + (title || dataCommand) + '</span></span>';
+
+ if (_disabled) oButton.setAttribute('disabled', true);
+
+ oButton.innerHTML = innerHTML;
+ oLi.appendChild(oButton);
+
+ return {
+ 'li': oLi,
+ 'button': oButton
+ };
+ },
+
+ /**
+ * @description Create editor HTML
+ * @param {Array} doc document object
+ * @param {Array} buttonList option.buttonList
+ * @param {Array|Object|null} _plugins Plugins
+ * @param {Array} options options
+ * @returns {Object} { element: (Element) Toolbar element, plugins: (Array|null) Plugins Array, pluginCallButtons: (Object), responsiveButtons: (Array) }
+ * @private
+ */
+ _createToolBar: function (doc, buttonList, _plugins, options) {
+ const separator_vertical = doc.createElement('DIV');
+ separator_vertical.className = 'se-toolbar-separator-vertical';
+
+ const tool_bar = doc.createElement('DIV');
+ tool_bar.className = 'se-toolbar sun-editor-common';
+
+ const _buttonTray = doc.createElement('DIV');
+ _buttonTray.className = 'se-btn-tray';
+ tool_bar.appendChild(_buttonTray);
+
+ /** create button list */
+ const icons = options.icons;
+ const defaultButtonList = this._defaultButtons(options);
+ const pluginCallButtons = {};
+ const responsiveButtons = [];
+ const plugins = {};
+ if (_plugins) {
+ const pluginsValues = _plugins.length ? _plugins : Object.keys(_plugins).map(function(name) { return _plugins[name]; });
+ for (let i = 0, len = pluginsValues.length, p; i < len; i++) {
+ p = pluginsValues[i].default || pluginsValues[i];
+ plugins[p.name] = p;
+ }
+ }
+
+ let module = null;
+ let button = null;
+ let moduleElement = null;
+ let buttonElement = null;
+ let pluginName = '';
+ let vertical = false;
+ const moreLayer = util.createElement('DIV');
+ moreLayer.className = 'se-toolbar-more-layer';
+
+ buttonGroupLoop:
+ for (let i = 0, more, moreContainer, moreCommand, buttonGroup, align; i < buttonList.length; i++) {
+ more = false;
+ align = '';
+ buttonGroup = buttonList[i];
+ moduleElement = this._createModuleGroup();
+
+ // button object
+ if (typeof buttonGroup === 'object') {
+ // buttons loop
+ for (let j = 0, moreButton; j < buttonGroup.length; j++) {
+ button = buttonGroup[j];
+ moreButton = false;
+
+ if (/^\%\d+/.test(button) && j === 0) {
+ buttonGroup[0] = button.replace(/[^\d]/g, '');
+ responsiveButtons.push(buttonGroup);
+ buttonList.splice(i--, 1);
+ continue buttonGroupLoop;
+ }
+
+ if (typeof button === 'object') {
+ if (typeof button.add === 'function') {
+ pluginName = button.name;
+ module = defaultButtonList[pluginName];
+ plugins[pluginName] = button;
+ } else {
+ pluginName = button.name;
+ module = [button.buttonClass, button.title, button.name, button.dataDisplay, button.innerHTML, button._disabled];
+ }
+ } else {
+ // align
+ if (/^\-/.test(button)) {
+ align = button.substr(1);
+ moduleElement.div.style.float = align;
+ continue;
+ }
+
+ // more button
+ if (/^\:/.test(button)) {
+ moreButton = true;
+ const matched = button.match(/^\:([^\-]+)\-([^\-]+)\-([^\-]+)/);
+ moreCommand = '__se__' + matched[1].trim();
+ const title = matched[2].trim();
+ const innerHTML = matched[3].trim();
+ module = ['se-btn-more', title, moreCommand, 'MORE', innerHTML];
+ }
+ // buttons
+ else {
+ module = defaultButtonList[button];
+ }
+
+ pluginName = button;
+ if (!module) {
+ const custom = plugins[pluginName];
+ if (!custom) throw Error('[SUNEDITOR.create.toolbar.fail] The button name of a plugin that does not exist. [' + pluginName + ']');
+ module = [custom.buttonClass, custom.title, custom.name, custom.display, custom.innerHTML, custom._disabled];
+ }
+ }
+
+ buttonElement = this._createButton(module[0], module[1], module[2], module[3], module[4], module[5], icons);
+ (more ? moreContainer : moduleElement.ul).appendChild(buttonElement.li);
+
+ if (plugins[pluginName]) {
+ pluginCallButtons[pluginName] = buttonElement.button;
+ }
+
+ // more button
+ if (moreButton) {
+ more = true;
+ moreContainer = util.createElement('DIV');
+ moreContainer.className = 'se-more-layer ' + moreCommand;
+ moreContainer.innerHTML = '<div class="se-more-form"><ul class="se-menu-list"' + (align ? ' style="float: ' + align + ';"' : '') + '></ul></div>';
+ moreLayer.appendChild(moreContainer);
+ moreContainer = moreContainer.firstElementChild.firstElementChild;
+ }
+ }
+
+ if (vertical) {
+ const sv = separator_vertical.cloneNode(false);
+ if (align) sv.style.float = align;
+ _buttonTray.appendChild(sv);
+ }
+
+ _buttonTray.appendChild(moduleElement.div);
+ vertical = true;
+ }
+ /** line break */
+ else if (/^\/$/.test(buttonGroup)) {
+ const enterDiv = doc.createElement('DIV');
+ enterDiv.className = 'se-btn-module-enter';
+ _buttonTray.appendChild(enterDiv);
+ vertical = false;
+ }
+ }
+
+ const lastFloat = _buttonTray.lastElementChild.style.float;
+ if (!!lastFloat) {
+ const sv = separator_vertical.cloneNode(false);
+ sv.style.float = lastFloat;
+ _buttonTray.appendChild(sv);
+ }
+
+ if (_buttonTray.children.length === 1) util.removeClass(_buttonTray.firstElementChild, 'se-btn-module-border');
+ if (responsiveButtons.length > 0) responsiveButtons.unshift(buttonList);
+ if (moreLayer.children.length > 0) _buttonTray.appendChild(moreLayer);
+
+ // menu tray
+ const _menuTray = doc.createElement('DIV');
+ _menuTray.className = 'se-menu-tray';
+ tool_bar.appendChild(_menuTray);
+
+ // cover
+ const tool_cover = doc.createElement('DIV');
+ tool_cover.className = 'se-toolbar-cover';
+ tool_bar.appendChild(tool_cover);
+
+ return {
+ 'element': tool_bar,
+ 'plugins': plugins,
+ 'pluginCallButtons': pluginCallButtons,
+ 'responsiveButtons': responsiveButtons,
+ '_menuTray': _menuTray,
+ '_buttonTray': _buttonTray
+ };
+ }
+};
\ No newline at end of file
--- /dev/null
+import { SunEditorOptions } from './../options.d';
+import { Plugin } from '../plugins/Plugin';
+
+declare interface EditorElement {
+ originElement: Element;
+ topArea: Element;
+ relative: Element;
+ toolbar: Element;
+ resizingBar: Element;
+ navigation: Element;
+ charWrapper: Element;
+ charCounter: Element;
+ editorArea: Element;
+ wysiwygFrame: Element;
+ wysiwyg: Element;
+ code: Element;
+ placeholder: Element;
+ loading: Element;
+ lineBreaker: Element;
+ resizeBackground: Element;
+}
+
+export interface Context {
+ element: EditorElement;
+ tool: Record<string, Element>;
+ options: SunEditorOptions;
+ option: SunEditorOptions;
+}
+
+type Constructor = {
+ constructed: Record<string, Element|null>;
+ options: SunEditorOptions,
+ plugins: Plugin[],
+ pluginCallButtons: Record<string, Element>,
+ _icons: Record<string, string>
+};
+
+declare function _Context(element: Element, cons: Constructor, options: SunEditorOptions): Context;
+
+export default _Context;
+
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+/**
+ * @description Elements and variables you should have
+ * @param {Element} element textarea element
+ * @param {object} cons Toolbar element you created
+ * @param {JSON|Object} options Inserted options
+ * @returns {Object} {Elements, variables of the editor, option}
+ * @private
+ */
+const _Context = function (element, cons, options) {
+ return {
+ element: {
+ originElement: element,
+ topArea: cons._top,
+ relative: cons._relative,
+ toolbar: cons._toolBar,
+ _buttonTray: cons._toolBar.querySelector('.se-btn-tray'),
+ _menuTray: cons._menuTray,
+ resizingBar: cons._resizingBar,
+ navigation: cons._navigation,
+ charWrapper: cons._charWrapper,
+ charCounter: cons._charCounter,
+ editorArea: cons._editorArea,
+ wysiwygFrame: cons._wysiwygArea,
+ wysiwyg: cons._wysiwygArea, // if (options.iframe) cons._wysiwygArea.contentDocument.body
+ code: cons._codeArea,
+ placeholder: cons._placeholder,
+ loading: cons._loading,
+ lineBreaker: cons._lineBreaker,
+ lineBreaker_t: cons._lineBreaker_t,
+ lineBreaker_b: cons._lineBreaker_b,
+ resizeBackground: cons._resizeBack,
+ _stickyDummy: cons._stickyDummy,
+ _arrow: cons._arrow
+ },
+ tool: {
+ cover: cons._toolBar.querySelector('.se-toolbar-cover'),
+ bold: cons._toolBar.querySelector('._se_command_bold'),
+ underline: cons._toolBar.querySelector('._se_command_underline'),
+ italic: cons._toolBar.querySelector('._se_command_italic'),
+ strike: cons._toolBar.querySelector('._se_command_strike'),
+ subscript: cons._toolBar.querySelector('._se_command_subscript'),
+ superscript: cons._toolBar.querySelector('._se_command_superscript'),
+ undo: cons._toolBar.querySelector('._se_command_undo'),
+ redo: cons._toolBar.querySelector('._se_command_redo'),
+ save: cons._toolBar.querySelector('._se_command_save'),
+ outdent: cons._toolBar.querySelector('._se_command_outdent'),
+ indent: cons._toolBar.querySelector('._se_command_indent'),
+ fullScreen: cons._toolBar.querySelector('._se_command_fullScreen'),
+ showBlocks: cons._toolBar.querySelector('._se_command_showBlocks'),
+ codeView: cons._toolBar.querySelector('._se_command_codeView')
+ },
+ options: options,
+ option: options
+ };
+};
+
+export default _Context;
\ No newline at end of file
--- /dev/null
+import { History } from './history.d';
+import { Plugin } from './../plugins/Plugin.d';
+import { Lang } from './../lang/Lang.d';
+import { SunEditorOptions } from './../options.d';
+import { Context } from './context';
+import Util from './util';
+import { Module } from '../plugins/Module';
+import _Notice from '../plugins/modules/_notice';
+
+type Controllers = Array<string | Function | Element>;
+type fileInfo = {
+ index: number;
+ name: string;
+ size: string | number;
+ select: Function;
+ delete: Function;
+ element: Element;
+ src: string;
+};
+type seledtedFileInfo = Record<string, string | Element>;
+type commands = 'selectAll' | 'codeView' | 'fullScreen' | 'indent' | 'outdent' | 'undo' | 'redo' | 'removeFormat' | 'print' | 'preview' | 'showBlocks' | 'save' | 'bold' | 'underline' | 'italic' | 'strike' | 'subscript' | 'superscript';
+
+interface Core {
+ /**
+ * @description Util object
+ */
+ util: Util;
+
+ /**
+ * @description Functions object
+ */
+ functions: SunEditor;
+
+ /**
+ * @description Notice object
+ */
+ notice: _Notice;
+
+ /**
+ * @description Default icons object
+ */
+ icons: Record<string, string>;
+
+ /**
+ * @description History object for undo, redo
+ */
+ history: History;
+
+ /**
+ * @description Elements and user options parameters of the suneditor
+ */
+ context: Context;
+
+ /**
+ * @description Plugin buttons
+ */
+ pluginCallButtons: Record<string, Element>;
+
+ /**
+ * @description Loaded plugins
+ */
+ plugins: Record<string, Plugin>;
+
+ /**
+ * @description Whether the plugin is initialized
+ */
+ initPlugins: Record<string, boolean>;
+
+ /**
+ * @description loaded language
+ */
+ lang: Lang;
+
+ /**
+ * @description The selection node (core.getSelectionNode()) to which the effect was last applied
+ */
+ effectNode: Node;
+
+ /**
+ * @description submenu element
+ */
+ submenu: Element;
+
+ /**
+ * @description container element
+ */
+ container: Element;
+
+ /**
+ * @description active button element in submenu
+ */
+ submenuActiveButton: Element;
+
+ /**
+ * @description active button element in container
+ */
+ containerActiveButton: Element;
+
+ /**
+ * @description The elements array to be processed unvisible when the controllersOff function is executed (resizing, link modified button, table controller)
+ */
+ controllerArray: Controllers;
+
+ /**
+ * @description The name of the plugin that called the currently active controller
+ */
+ currentControllerName: string;
+
+ /**
+ * @description The target element of current controller
+ */
+ currentControllerTarget: Element;
+
+ /**
+ * @description The file component object of current selected file tag (getFileComponent(): {target, component, pluginName})
+ */
+ currentFileComponentInfo: seledtedFileInfo;
+
+ /**
+ * @description An array of buttons whose class name is not "se-code-view-enabled"
+ */
+ codeViewDisabledButtons: Element[];
+
+ /**
+ * @description An array of buttons whose class name is not "se-resizing-enabled"
+ */
+ resizingDisabledButtons: Element[],
+
+ /**
+ * @description Editor tags whitelist (RegExp object)
+ * util.createTagsWhitelist(options._editorTagsWhitelist)
+ */
+ editorTagsWhitelistRegExp: RegExp;
+
+ /**
+ * @description Tag whitelist when pasting (RegExp object)
+ * util.createTagsWhitelist(options.pasteTagsWhitelist)
+ */
+ pasteTagsWhitelistRegExp: RegExp;
+
+ /**
+ * @description Boolean value of whether the editor has focus
+ */
+ hasFocus: boolean;
+
+ /**
+ * @description Plugins array with "active" method.
+ * "activePlugins" runs the "add" method when creating the editor.
+ */
+ activePlugins: Plugin[];
+
+ /**
+ * @description Plugins array with "checkFiletInfo" and "resetFileInfo" methods.
+ * "fileInfoPlugins" runs the "add" method when creating the editor.
+ * "checkFileInfo" method is always call just before the "change" event.
+ */
+ fileInfoPlugins: Function[],
+
+ /**
+ * @description Elements that need to change text or className for each selection change
+ * After creating the editor, "activePlugins" are added.
+ * @property STRONG bold button
+ * @property U underline button
+ * @property EM italic button
+ * @property DEL strike button
+ * @property SUB subscript button
+ * @property SUP superscript button
+ * @property OUTDENT outdent button
+ * @property INDENT indent button
+ */
+ commandMap: Record<string, Element>;
+
+ /**
+ * @description If the plugin is not added, add the plugin and call the 'add' function.
+ * If the plugin is added call callBack function.
+ * @param pluginName The name of the plugin to call
+ * @param callBackFunction Function to be executed immediately after module call
+ * @param _target Plugin target button (This is not necessary if you have a button list when creating the editor)
+ */
+ callPlugin(pluginName: string, callBackFunction: Function, _target?: Element): void;
+
+ /**
+ * @description If the module is not added, add the module and call the 'add' function
+ * @param moduleArray module object's Array [dialog, resizing]
+ */
+ addModule(moduleArray: Module[]): void;
+
+ /**
+ * @description Method for managing submenu element.
+ * You must add the "submenu" element using the this method at custom plugin.
+ * @param pluginName Plugin name
+ * @param target Target button
+ * @param menu Submenu element
+ */
+ initMenuTarget(pluginName: string, target: Element | null, menu: Element): void;
+
+ /**
+ * @description Enabled submenu
+ * @param element Submenu's button element to call
+ */
+ submenuOn(element: Element): void;
+
+ /**
+ * @description Disable submenu
+ */
+ submenuOff(): void;
+
+ /**
+ * @description Enabled container
+ * @param element Container's button element to call
+ */
+ containerOn(element: Element): void;
+
+ /**
+ * @description Disable container
+ */
+ containerOff(): void;
+
+ /**
+ * @description Show controller at editor area (controller elements, function, "controller target element(@Required)", "controller name(@Required)", etc..)
+ * @param arguments controller elements, functions..
+ */
+ controllersOn(...arguments: Controllers): void;
+
+ /**
+ * @description Hide controller at editor area (link button, image resize button..)
+ * @param e Event object when called from mousedown and keydown events registered in "core.controllersOn"
+ */
+ controllersOff(e?: KeyboardEvent | MouseEvent): void;
+
+ /**
+ * @description Specify the position of the controller.
+ * @param controller Controller element.
+ * @param referEl Element that is the basis of the controller's position.
+ * @param position Type of position ("top" | "bottom")
+ * When using the "top" position, there should not be an arrow on the controller.
+ * When using the "bottom" position there should be an arrow on the controller.
+ * @param addOffset These are the left and top values that need to be added specially.
+ * This argument is required. - {left: 0, top: 0}
+ * Please enter the value based on ltr mode.
+ * Calculated automatically in rtl mode.
+ */
+ setControllerPosition(controller: Element, referEl: Element, position: 'top' | 'bottom', addOffset: {left: number, top: number}): void;
+
+ /**
+ * @description Run event.stopPropagation and event.preventDefault.
+ * @param e Event Object
+ */
+ eventStop(e: Event): void;
+
+ /**
+ * @description javascript execCommand
+ * @param command javascript execCommand function property
+ * @param showDefaultUI javascript execCommand function property
+ * @param value javascript execCommand function property
+ */
+ execCommand(command: string, showDefaultUI?: boolean, value?: string): void;
+
+ /**
+ * @description Focus to wysiwyg area using "native focus function"
+ */
+ nativeFocus(): void;
+
+ /**
+ * @description Focus to wysiwyg area
+ */
+ focus(): void;
+
+ /**
+ * @description If "focusEl" is a component, then that component is selected; if it is a format element, the last text is selected
+ * If "focusEdge" is null, then selected last element
+ * @param focusEl Focus element
+ */
+ focusEdge(focusEl: Element | null): void;
+
+ /**
+ * @description Set current editor's range object and return.
+ * @param startCon The startContainer property of the selection object.
+ * @param startOff The startOffset property of the selection object.
+ * @param endCon The endContainer property of the selection object.
+ * @param endOff The endOffset property of the selection object.
+ * @returns
+ */
+ setRange(startCon: Node, startOff: number, endCon: Node, endOff: number): Range;
+
+ /**
+ * @description Remove range object and button effect
+ */
+ removeRange(): void;
+
+ /**
+ * @description Get current editor's range object
+ * @returns
+ */
+ getRange(): Range;
+
+ /**
+ * @description If the "range" object is a non-editable area, add a line at the top of the editor and update the "range" object.
+ * Returns a new "range" or argument "range".
+ * @param range core.getRange()
+ * @param container If there is "container" argument, it creates a line in front of the container.
+ */
+ getRange_addLine(range: Range, container?: Element): Range;
+
+ /**
+ * @description Get window selection obejct
+ * @returns
+ */
+ getSelection(): Selection;
+
+ /**
+ * @description Get current select node
+ * @returns
+ */
+ getSelectionNode(): Node;
+
+ /**
+ * @description Returns a "formatElement"(util.isFormatElement) array from the currently selected range.
+ * @param validation The validation function. (Replaces the default validation function-util.isFormatElement(current))
+ * @returns
+ */
+ getSelectedElements(validation?: Function): Node[];
+
+ /**
+ * @description Get format elements and components from the selected area. (P, DIV, H[1-6], OL, UL, TABLE..)
+ * If some of the component are included in the selection, get the entire that component.
+ * @param removeDuplicate If true, if there is a parent and child tag among the selected elements, the child tag is excluded.
+ * @returns
+ */
+ getSelectedElementsAndComponents(removeDuplicate: boolean): Node[];
+
+ /**
+ * @description Determine if this offset is the edge offset of container
+ * @param container The container property of the selection object.
+ * @param offset The offset property of the selection object.
+ * @returns
+ */
+ isEdgePoint(container: Node, offset: number): boolean;
+
+ /**
+ * @description Show loading box
+ */
+ showLoading(): void;
+
+ /**
+ * @description Close loading box
+ */
+ closeLoading(): void;
+
+ /**
+ * @description Append format element to sibling node of argument element.
+ * If the "formatNodeName" argument value is present, the tag of that argument value is inserted,
+ * If not, the currently selected format tag is inserted.
+ * @param element Insert as siblings of that element
+ * @param formatNode Node name or node obejct to be inserted
+ * @returns
+ */
+ appendFormatTag(element: Element, formatNode?: string | Element): Element;
+
+ /**
+ * @description The method to insert a element and return. (used elements : table, hr, image, video)
+ * If "element" is "HR", insert and return the new line.
+ * @param element Element to be inserted
+ * @param notHistoryPush When true, it does not update the history stack and the selection object and return EdgeNodes (util.getEdgeChildNodes)
+ * @param checkCharCount If true, if "options.maxCharCount" is exceeded when "element" is added, null is returned without addition.
+ * @param notSelect If true, Do not automatically select the inserted component.
+ * @returns
+ */
+ insertComponent(element: Element, notHistoryPush?: boolean, checkCharCount?: boolean, notSelect?:boolean): Element;
+
+ /**
+ * @description Gets the file component and that plugin name
+ * return: {target, component, pluginName} | null
+ * @param element Target element (figure tag, component div, file tag)
+ * @returns
+ */
+ getFileComponent(element: Element): seledtedFileInfo | null;
+
+ /**
+ * @description The component(image, video) is selected and the resizing module is called.
+ * @param element Element tag (img, iframe, video)
+ * @param pluginName Plugin name (image, video)
+ */
+ selectComponent(element: Element, pluginName: string): void;
+
+ /**
+ * @description Delete selected node and insert argument value node and return.
+ * If the "afterNode" exists, it is inserted after the "afterNode"
+ * Inserting a text node merges with both text nodes on both sides and returns a new "{ container, startOffset, endOffset }".
+ * @param oNode Element to be inserted
+ * @param afterNode If the node exists, it is inserted after the node
+ * @returns
+ */
+ insertNode(oNode: Node, afterNode?: Node, checkCharCount?: boolean): { startOffset: Node, endOffset: number } | Node | null;
+
+ /**
+ * @description Delete the currently selected nodes and reset selection range
+ * Returns {container: "the last element after deletion", offset: "offset", prevContainer: "previousElementSibling Of the deleted area"}
+ * @returns
+ */
+ removeNode(): { container: Node; offset: number; prevContainer?: Node };
+
+ /**
+ * @description Appended all selected format Element to the argument element and insert
+ * @param rangeElement Element of wrap the arguments (BLOCKQUOTE...)
+ */
+ applyRangeFormatElement(rangeElement: Element): void;
+
+ /**
+ * @description The elements of the "selectedFormats" array are detached from the "rangeElement" element. ("LI" tags are converted to "P" tags)
+ * When "selectedFormats" is null, all elements are detached and return {cc: parentNode, sc: nextSibling, ec: previousSibling, removeArray: [Array of removed elements]}.
+ * @param rangeElement Range format element (PRE, BLOCKQUOTE, OL, UL...)
+ * @param selectedFormats Array of format elements (P, DIV, LI...) to remove.
+ * If null, Applies to all elements and return {cc: parentNode, sc: nextSibling, ec: previousSibling}
+ * @param newRangeElement The node(rangeElement) to replace the currently wrapped node.
+ * @param remove If true, deleted without detached.
+ * @param notHistoryPush When true, it does not update the history stack and the selection object and return EdgeNodes (util.getEdgeChildNodes)
+ * @returns
+ */
+ detachRangeFormatElement(rangeElement: Element, selectedFormats: Element[] | null, newRangeElement: Element | null, remove: boolean, notHistoryPush: boolean): {cc: Node, sc: Node, ec: Node, removeArray: Element[]}
+
+ /**
+ * @description "selectedFormats" array are detached from the list element.
+ * The return value is applied when the first and last lines of "selectedFormats" are "LI" respectively.
+ * @param selectedFormats Array of format elements (LI, P...) to remove.
+ * @param remove If true, deleted without detached.
+ * @returns {sc: <LI>, ec: <LI>}.
+ */
+ detachList(selectedFormats: Element[], remove: boolean): {sc: Element, ec: Element};
+
+ /**
+ * @description Add, update, and delete nodes from selected text.
+ * 1. If there is a node in the "appendNode" argument, a node with the same tags and attributes as "appendNode" is added to the selection text.
+ * 2. If it is in the same tag, only the tag's attributes are changed without adding a tag.
+ * 3. If the "appendNode" argument is null, the node of the selection is update or remove without adding a new node.
+ * 4. The same style as the style attribute of the "styleArray" argument is deleted.
+ * (Styles should be put with attribute names from css. ["background-color"])
+ * 5. The same class name as the class attribute of the "styleArray" argument is deleted.
+ * (The class name is preceded by "." [".className"])
+ * 6. Use a list of styles and classes of "appendNode" in "styleArray" to avoid duplicate property values.
+ * 7. If a node with all styles and classes removed has the same tag name as "appendNode" or "removeNodeArray", or "appendNode" is null, that node is deleted.
+ * 8. Regardless of the style and class of the node, the tag with the same name as the "removeNodeArray" argument value is deleted.
+ * 9. If the "strictRemove" argument is true, only nodes with all styles and classes removed from the nodes of "removeNodeArray" are removed.
+ * 10. It won't work if the parent node has the same class and same value style.
+ * However, if there is a value in "removeNodeArray", it works and the text node is separated even if there is no node to replace.
+ * @param appendNode The element to be added to the selection. If it is null, only delete the node.
+ * @param styleArray The style or className attribute name Array to check (['font-size'], ['.className'], ['font-family', 'color', '.className']...])
+ * @param removeNodeArray An array of node names to remove types from, remove all formats when "appendNode" is null and there is an empty array or null value. (['span'], ['strong', 'em'] ...])
+ * @param strictRemove If true, only nodes with all styles and classes removed from the nodes of "removeNodeArray" are removed.
+ */
+ nodeChange(appendNode?: Element, styleArray?: string[], removeNodeArray?: string[], strictRemove?: boolean): void;
+
+ /**
+ * @description Run plugin calls and basic commands.
+ * @param command Command string
+ * @param display Display type string ('command', 'submenu', 'dialog', 'container')
+ * @param target The element of command button
+ */
+ actionCall(command: string, display: 'command' | 'submenu' | 'dialog' | 'container', target: Element): void;
+
+ /**
+ * @description Execute command of command button(All Buttons except submenu and dialog)
+ * (undo, redo, bold, underline, italic, strikethrough, subscript, superscript, removeFormat, indent, outdent, fullscreen, showBlocks, codeview, preview, print)
+ * @param target The element of command button
+ * @param command Property of command button (data-value)
+ */
+ commandHandler(target: Element | null, command: commands): void;
+
+ /**
+ * @description Remove format of the currently selected range
+ */
+ removeFormat(): void;
+
+ /**
+ * @description This method implements indentation to selected range.
+ * Setted "margin-left" to "25px" in the top "P" tag of the parameter node.
+ * @param command Separator ("indent" or "outdent")
+ */
+ indent(command: 'indent' | 'outdent'): void;
+
+ /**
+ * @description Add or remove the class name of "body" so that the code block is visible
+ */
+ toggleDisplayBlocks(): void;
+
+ /**
+ * @description Changes to code view or wysiwyg view
+ */
+ toggleCodeView(): void;
+
+ /**
+ * @description Changes to full screen or default screen
+ * @param element full screen button
+ */
+ toggleFullScreen(element: Element): void;
+
+ /**
+ * @description Prints the current contents of the editor.
+ */
+ print(): void;
+
+ /**
+ * @description Open the preview window.
+ */
+ preview(): void;
+
+ /**
+ * @description Sets the HTML string
+ * @param html HTML string
+ */
+ setContents(html: string): void;
+
+ /**
+ * @description Sets the contents of the iframe's head tag and body tag when using the "iframe" or "fullPage" option.
+ * @param ctx { head: HTML string, body: HTML string}
+ */
+ setIframeContents(ctx: { head?: string, body?: string }): void;
+
+ /**
+ * @description Gets the current contents
+ * @param onlyContents Return only the contents of the body without headers when the "fullPage" option is true
+ * @returns
+ */
+ getContents(onlyContents: boolean): string;
+
+ /**
+ * @description Gets the clean HTML code for editor
+ * @param html HTML string
+ * @param whitelist Regular expression of allowed tags.
+ * RegExp object is create by util.createTagsWhitelist method. (core.pasteTagsWhitelistRegExp)
+ * @returns
+ */
+ cleanHTML(html: string, whitelist?: string | RegExp): string;
+
+ /**
+ * @description Converts contents into a format that can be placed in an editor
+ * @param contents contents
+ * @returns
+ */
+ convertContentsForEditor(contents: string): string;
+
+ /**
+ * @description Converts wysiwyg area element into a format that can be placed in an editor of code view mode
+ * @param html WYSIWYG element (context.element.wysiwyg) or HTML string.
+ * @returns
+ */
+ convertHTMLForCodeView(html: Element | string): string;
+
+ /**
+ * @description Add an event to document.
+ * When created as an Iframe, the same event is added to the document in the Iframe.
+ * @param type Event type
+ * @param listener Event listener
+ * @param useCapture Use event capture
+ */
+ addDocEvent(type: string, listener: EventListener, useCapture: boolean): void;
+
+ /**
+ * @description Remove events from document.
+ * When created as an Iframe, the event of the document inside the Iframe is also removed.
+ * @param type Event type
+ * @param listener Event listener
+ */
+ removeDocEvent(type: string, listener: EventListener): void;
+
+ /**
+ * @description When "element" is added, if it is greater than "options.maxCharCount", false is returned.
+ * @param element Element node or String.
+ * @param charCounterType charCounterType. If it is null, the options.charCounterType
+ */
+ checkCharCount(element: Node | string, charCounterType?: string): boolean;
+
+ /**
+ * @description Get the length of the content.
+ * Depending on the option, the length of the character is taken. (charCounterType)
+ * @param content Content to count
+ * @param charCounterType options.charCounterType
+ */
+ getCharLength(content: string, charCounterType: string): number;
+}
+
+interface Toolbar {
+ /**
+ * @description Disable the toolbar
+ */
+ disabled(): void;
+
+ /**
+ * @description Enable the toolbar
+ */
+ enabled(): void;
+
+ /**
+ * @description Show the toolbar
+ */
+ show(): void;
+
+ /**
+ * @description Hide the toolbar
+ */
+ hide(): void;
+}
+
+type EventFn = (e: Event, core: Core) => void;
+
+type imageInputInformation = { linkValue: string, linkNewWindow: Window, inputWidth: number, inputHeight: number, align: string, isUpdate: boolean, element: any };
+type videoInputInformation = { inputWidth: number, inputHeight: number, align: string, isUpdate: boolean, element: any };
+type audioInputInformation = { isUpdate: boolean, element: any };
+
+export default class SunEditor {
+ constructor(context: Context,
+ pluginCallButtons: Record<string, Element>,
+ plugins: Record<string, Plugin>,
+ lang: Lang,
+ options: SunEditorOptions,
+ _icons: Record<string, string>)
+
+ core: Core;
+ util: Util;
+
+ onload: (core: Core, reload: boolean) => void;
+ onScroll: EventFn;
+ onMouseDown: EventFn;
+ onClick: EventFn;
+ onInput: EventFn;
+ onKeyDown: EventFn;
+ onKeyUp: EventFn;
+ onChange: (contents: string, core: Core) => void;
+ onBlur: (e: FocusEvent, core: Core) => void;
+ onDrop: (e: Event, cleanData: string, maxCharCount: number, core: Core) => boolean | string;
+ onPaste: (e: Event, cleanData: string, maxCharCount: number, core: Core) => boolean | string;
+ onCopy: (e: Event, clipboardData: any, core: Core) => void;
+ onCut: (e: Event, clipboardData: any, core: Core) => void;
+
+ /**
+ * @description Called just before the inline toolbar is positioned and displayed on the screen.
+ * @param toolbar Toolbar Element
+ * @param context The editor's context object (editor.getContext())
+ * @param core Core object
+ */
+ showInline: (toolbar: Element, context: Context, core: Core) => void;
+
+ /**
+ * @description Called just after the controller is positioned and displayed on the screen.
+ * controller - editing elements displayed on the screen [image resizing, table editor, link editor..]]
+ * @param name The name of the plugin that called the controller
+ * @param controllers Array of Controller elements
+ * @param core Core object
+ */
+ showController: (name: String, controllers: Controllers, core: Core) => void;
+
+ /**
+ * @description It replaces the default callback function of the image upload
+ * @param xmlHttp xmlHttpRequest object
+ * @param info Input information
+ * - linkValue: Link url value
+ * - linkNewWindow: Open in new window Check Value
+ * - inputWidth: Value of width input
+ * - inputHeight: Value of height input
+ * - align: Align Check Value
+ * - isUpdate: Update image if true, create image if false
+ * - element: If isUpdate is true, the currently selected image.
+ * @param core Core object
+ */
+ imageUploadHandler: (xmlHttp: XMLHttpRequest, info: imageInputInformation, core: Core) => void;
+
+ /**
+ * @description It replaces the default callback function of the video upload
+ * @param xmlHttp xmlHttpRequest object
+ * @param info Input information
+ * - inputWidth: Value of width input
+ * - inputHeight: Value of height input
+ * - align: Align Check Value
+ * - isUpdate: Update video if true, create video if false
+ * - element: If isUpdate is true, the currently selected video.
+ * @param core Core object
+ */
+ videoUploadHandler: (xmlHttp: XMLHttpRequest, info: videoInputInformation, core: Core) => void;
+
+ /**
+ * @description It replaces the default callback function of the audio upload
+ * @param xmlHttp xmlHttpRequest object
+ * @param info Input information
+ * - isUpdate: Update audio if true, create audio if false
+ * - element: If isUpdate is true, the currently selected audio.
+ * @param core Core object
+ */
+ audioUploadHandler: (xmlHttp: XMLHttpRequest, info: audioInputInformation, core: Core) => void;
+
+ /**
+ * @description Called before the image is uploaded
+ * If true is returned, the internal upload process runs normally.
+ * If false is returned, no image upload is performed.
+ * If new fileList are returned, replaced the previous fileList
+ * If undefined is returned, it waits until "uploadHandler" is executed.
+ * @param files Files array
+ * @param info Input information
+ * @param core Core object
+ * @param uploadHandler If undefined is returned, it waits until "uploadHandler" is executed.
+ * "uploadHandler" is an upload function with "core" and "info" bound.
+ * [upload files] : uploadHandler(files or [new File(...),])
+ * [error] : uploadHandler("Error message")
+ * [Just finish] : uploadHandler()
+ * [directly register] : uploadHandler(response) // Same format as "imageUploadUrl" response
+ * ex) {
+ * // "errorMessage": "insert error message",
+ * "result": [ { "url": "...", "name": "...", "size": "999" }, ]
+ * }
+ * @returns
+ */
+ onImageUploadBefore: (files: any[], info: imageInputInformation, core: Core, uploadHandler: Function) => boolean | any[] | undefined;
+
+ /**
+ * @description Called before the video is uploaded
+ * If true is returned, the internal upload process runs normally.
+ * If false is returned, no video upload is performed.
+ * If new fileList are returned, replaced the previous fileList
+ * If undefined is returned, it waits until "uploadHandler" is executed.
+ * @param files Files array
+ * @param info Input information
+ * @param core Core object
+ * @param uploadHandler If undefined is returned, it waits until "uploadHandler" is executed.
+ * "uploadHandler" is an upload function with "core" and "info" bound.
+ * [upload files] : uploadHandler(files or [new File(...),])
+ * [error] : uploadHandler("Error message")
+ * [Just finish] : uploadHandler()
+ * [directly register] : uploadHandler(response) // Same format as "videoUploadUrl" response
+ * ex) {
+ * // "errorMessage": "insert error message",
+ * "result": [ { "url": "...", "name": "...", "size": "999" }, ]
+ * }
+ * @returns
+ */
+ onVideoUploadBefore: (files: any[], info: videoInputInformation, core: Core, uploadHandler: Function) => boolean | any[] | undefined;
+
+ /**
+ * @description Called before the audio is uploaded
+ * If true is returned, the internal upload process runs normally.
+ * If false is returned, no audio upload is performed.
+ * If new fileList are returned, replaced the previous fileList
+ * If undefined is returned, it waits until "uploadHandler" is executed.
+ * @param files Files array
+ * @param info Input information
+ * @param core Core object
+ * @param uploadHandler If undefined is returned, it waits until "uploadHandler" is executed.
+ * "uploadHandler" is an upload function with "core" and "info" bound.
+ * [upload files] : uploadHandler(files or [new File(...),])
+ * [error] : uploadHandler("Error message")
+ * [Just finish] : uploadHandler()
+ * [directly register] : uploadHandler(response) // Same format as "audioUploadUrl" response
+ * ex) {
+ * // "errorMessage": "insert error message",
+ * "result": [ { "url": "...", "name": "...", "size": "999" }, ]
+ * }
+ * @returns
+ */
+ onAudioUploadBefore: (files: any[], info: audioInputInformation, core: Core, uploadHandler: Function) => boolean | any[] | undefined;
+
+ /**
+ * @description Called when the image is uploaded, updated, deleted
+ * @param targetElement Target element
+ * @param index Uploaded index
+ * @param state Upload status ('create', 'update', 'delete')
+ * @param info Info object
+ * - index: data index
+ * - name: file name
+ * - size: file size
+ * - select: select function
+ * - delete: delete function
+ * - element: target element
+ * - src: src attribute of tag
+ * @param remainingFilesCount Count of remaining files to upload (0 when added as a url)
+ * @param core Core object
+ */
+ onImageUpload: (targetElement: HTMLImageElement, index: number, state: 'create' | 'update' | 'delete', info: fileInfo, remainingFilesCount: number, core: Core) => void;
+
+ /**
+ * @description Called when the video(iframe, video) is uploaded, updated, deleted
+ * @param targetElement Target element
+ * @param index Uploaded index
+ * @param state Upload status ('create', 'update', 'delete')
+ * @param info Info object
+ * - index: data index
+ * - name: file name
+ * - size: file size
+ * - select: select function
+ * - delete: delete function
+ * - element: target element
+ * - src: src attribute of tag
+ * @param remainingFilesCount Count of remaining files to upload (0 when added as a url)
+ * @param core Core object
+ */
+ onVideoUpload: (targetElement: HTMLIFrameElement | HTMLVideoElement, index: number, state: 'create' | 'update' | 'delete', info: fileInfo, remainingFilesCount: number, core: Core) => void;
+
+ /**
+ * @description Called when the audio is uploaded, updated, deleted
+ * @param targetElement Target element
+ * @param index Uploaded index
+ * @param state Upload status ('create', 'update', 'delete')
+ * @param info Info object
+ * - index: data index
+ * - name: file name
+ * - size: file size
+ * - select: select function
+ * - delete: delete function
+ * - element: target element
+ * - src: src attribute of tag
+ * @param remainingFilesCount Count of remaining files to upload (0 when added as a url)
+ * @param core Core object
+ */
+ onAudioUpload: (targetElement: HTMLAudioElement, index: number, state: 'create' | 'update' | 'delete', info: fileInfo, remainingFilesCount: number, core: Core) => void;
+
+ /**
+ * @description Called when the image is upload failed
+ * @param errorMessage Error message
+ * @param result Response Object
+ * @param core Core object
+ * @returns
+ */
+ onImageUploadError: (errorMessage: string, result: any, core: Core) => boolean;
+
+ /**
+ * @description Called when the video(iframe, video) upload failed
+ * @param errorMessage Error message
+ * @param result Response Object
+ * @param core Core object
+ * @returns
+ */
+ onVideoUploadError: (errorMessage: string, result: any, core: Core) => boolean;
+
+ /**
+ * @description Called when the audio upload failed
+ * @param errorMessage Error message
+ * @param result Response Object
+ * @param core Core object
+ * @returns
+ */
+ onAudioUploadError: (errorMessage: string, result: any, core: Core) => boolean;
+
+ /**
+ * @description Reset the buttons on the toolbar. (Editor is not reloaded)
+ * You cannot set a new plugin for the button.
+ * @param buttonList Button list
+ */
+ setToolbarButtons(buttonList: any[]): void;
+
+ /**
+ * @description Add or reset option property
+ * @param options Options
+ */
+ setOptions(options: SunEditorOptions): void;
+
+ /**
+ * @description Set "options.defaultStyle" style.
+ * Define the style of the edit area
+ * It can also be defined with the "setOptions" method, but the "setDefaultStyle" method does not render the editor again.
+ * @param style Style string
+ */
+ setDefaultStyle(style: string): void;
+
+ /**
+ * @description Open a notice area
+ * @param message Notice message
+ */
+ noticeOpen(message: string): void;
+
+ /**
+ * @description Close a notice area
+ */
+ noticeClose(): void;
+
+ /**
+ * @description Copying the contents of the editor to the original textarea
+ */
+ save(): void;
+
+ /**
+ * @description Gets the suneditor's context object. Contains settings, plugins, and cached element objects
+ * @returns
+ */
+ getContext(): Context;
+
+ /**
+ * @description Gets the contents of the suneditor
+ * @param onlyContents - Return only the contents of the body without headers when the "fullPage" option is true
+ * @returns
+ */
+ getContents(onlyContents: boolean): string;
+
+ /**
+ * @description Gets only the text of the suneditor contents
+ * @returns
+ */
+ getText(): string;
+
+ /**
+ * @description Get the editor's number of characters or binary data size.
+ * You can use the "charCounterType" option format.
+ * @param charCounterType options - charCounterType ('char', 'byte', 'byte-html')
+ * If argument is no value, the currently set "charCounterType" option is used.
+ * @returns
+ */
+ getCharCount(charCounterType?: string): number;
+
+ /**
+ * @description Gets uploaded images informations
+ * - index: data index
+ * - name: file name
+ * - size: file size
+ * - select: select function
+ * - delete: delete function
+ * - element: img element
+ * - src: src attribute of img tag
+ * @returns
+ */
+ getImagesInfo(): fileInfo[];
+
+ /**
+ * @description Gets uploaded files(plugin using fileManager) information list.
+ * image: [img], video: [video, iframe], audio: [audio]
+ * When the argument value is 'image', it is the same function as "getImagesInfo".
+ * - index: data index
+ * - name: file name
+ * - size: file size
+ * - select: select function
+ * - delete: delete function
+ * - element: img element
+ * - src: src attribute of img tag
+ * @param pluginName Plugin name (image, video, audio)
+ * @returns
+ */
+ getFilesInfo(pluginName: string): fileInfo[];
+
+ /**
+ * @description Upload images using image plugin
+ * @param files FileList
+ */
+ insertImage(files: FileList): void;
+
+ /**
+ * @description Inserts an HTML element or HTML string or plain string at the current cursor position
+ * @param html HTML Element or HTML string or plain string
+ * @param notCleaningData If true, inserts the HTML string without refining it with core.cleanHTML.
+ * @param checkCharCount If true, if "options.maxCharCount" is exceeded when "element" is added, null is returned without addition.
+ * @param rangeSelection If true, range select the inserted node.
+ */
+ insertHTML(html: Element | string, notCleaningData?: boolean, checkCharCount?: boolean, rangeSelection?: boolean): void;
+
+ /**
+ * @description Change the contents of the suneditor
+ * @param contents Contents to Input
+ */
+ setContents(contents: string): void;
+
+ /**
+ * @description Add contents to the suneditor
+ * @param contents Contents to Input
+ */
+ appendContents(contents: string): void;
+
+ /**
+ * @description Disable the suneditor
+ */
+ disabled(): void;
+
+ /**
+ * @description Enable the suneditor
+ */
+ enabled(): void;
+
+ /**
+ * @description Show the suneditor
+ */
+ show(): void;
+
+ /**
+ * @description Hide the suneditor
+ */
+ hide(): void;
+
+ /**
+ * @description Destroy the suneditor
+ */
+ destroy(): void;
+
+ /**
+ * @description Toolbar methods
+ */
+ toolbar: Toolbar;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+import _Constructor from './constructor';
+import _Context from './context';
+import _history from './history';
+import _util from './util';
+import _notice from '../plugins/modules/_notice';
+
+/**
+ * @description SunEditor constuctor function.
+ * create core object and event registration.
+ * core, event, functions
+ * @param {Object} context
+ * @param {Object} pluginCallButtons
+ * @param {Object} plugins
+ * @param {Object} lang
+ * @param {Object} options
+ * @param {Object} _responsiveButtons
+ * @returns {Object} functions Object
+ */
+export default function (context, pluginCallButtons, plugins, lang, options, _responsiveButtons) {
+ const _d = context.element.originElement.ownerDocument || document;
+ const _w = _d.defaultView || window;
+ const util = _util;
+ const icons = options.icons;
+
+ /**
+ * @description editor core object
+ * should always bind this object when registering an event in the plug-in.
+ */
+ const core = {
+ _d: _d,
+ _w: _w,
+ _parser: new _w.DOMParser(),
+
+ /**
+ * @description Document object of the iframe if created as an iframe || _d
+ * @private
+ */
+ _wd: null,
+
+ /**
+ * @description Window object of the iframe if created as an iframe || _w
+ * @private
+ */
+ _ww: null,
+
+ /**
+ * @description Closest ShadowRoot to editor if found
+ * @private
+ */
+ _shadowRoot: null,
+
+ /**
+ * @description Util object
+ */
+ util: util,
+
+ /**
+ * @description Functions object
+ */
+ functions: null,
+
+ /**
+ * @description Notice object
+ */
+ notice: _notice,
+
+ /**
+ * @description Default icons object
+ */
+ icons: icons,
+
+ /**
+ * @description History object for undo, redo
+ */
+ history: null,
+
+ /**
+ * @description Elements and user options parameters of the suneditor
+ */
+ context: context,
+
+ /**
+ * @description Plugin buttons
+ */
+ pluginCallButtons: pluginCallButtons,
+
+ /**
+ * @description Loaded plugins
+ */
+ plugins: plugins || {},
+
+ /**
+ * @description Whether the plugin is initialized
+ */
+ initPlugins: {},
+
+ /**
+ * @description Object for managing submenu elements
+ * @private
+ */
+ _targetPlugins: {},
+
+ /**
+ * @description Save rendered submenus and containers
+ * @private
+ */
+ _menuTray: {},
+
+ /**
+ * @description loaded language
+ */
+ lang: lang,
+
+ /**
+ * @description The selection node (core.getSelectionNode()) to which the effect was last applied
+ */
+ effectNode: null,
+
+ /**
+ * @description submenu element
+ */
+ submenu: null,
+
+ /**
+ * @description container element
+ */
+ container: null,
+
+ /**
+ * @description current subment name
+ * @private
+ */
+ _submenuName: '',
+
+ /**
+ * @description binded submenuOff method
+ * @private
+ */
+ _bindedSubmenuOff: null,
+
+ /**
+ * @description binded containerOff method
+ * @private
+ */
+ _bindedContainerOff: null,
+
+ /**
+ * @description active button element in submenu
+ */
+ submenuActiveButton: null,
+
+ /**
+ * @description active button element in container
+ */
+ containerActiveButton: null,
+
+ /**
+ * @description The elements array to be processed unvisible when the controllersOff function is executed (resizing, link modified button, table controller)
+ */
+ controllerArray: [],
+
+ /**
+ * @description The name of the plugin that called the currently active controller
+ */
+ currentControllerName: '',
+
+ /**
+ * @description The target element of current controller
+ */
+ currentControllerTarget: null,
+
+ /**
+ * @description The file component object of current selected file tag (getFileComponent)
+ */
+ currentFileComponentInfo: null,
+
+ /**
+ * @description An array of buttons whose class name is not "se-code-view-enabled"
+ */
+ codeViewDisabledButtons: null,
+
+ /**
+ * @description An array of buttons whose class name is not "se-resizing-enabled"
+ */
+ resizingDisabledButtons: null,
+
+ /**
+ * @description active more layer element in submenu
+ * @private
+ */
+ _moreLayerActiveButton: null,
+
+ /**
+ * @description Tag whitelist RegExp object used in "_consistencyCheckOfHTML" method
+ * ^(options._editorTagsWhitelist)$
+ * @private
+ */
+ _htmlCheckWhitelistRegExp: null,
+
+ /**
+ * @description RegExp when using check disallowd tags. (b, i, ins, strike, s)
+ * @private
+ */
+ _disallowedTextTagsRegExp: null,
+
+ /**
+ * @description Editor tags whitelist (RegExp object)
+ * util.createTagsWhitelist(options._editorTagsWhitelist)
+ */
+ editorTagsWhitelistRegExp: null,
+
+ /**
+ * @description Tag whitelist when pasting (RegExp object)
+ * util.createTagsWhitelist(options.pasteTagsWhitelist)
+ */
+ pasteTagsWhitelistRegExp: null,
+
+ /**
+ * @description Boolean value of whether the editor has focus
+ */
+ hasFocus: false,
+
+ /**
+ * @description Boolean value of whether the editor is disabled
+ */
+ isDisabled: false,
+
+ /**
+ * @description Attributes whitelist used by the cleanHTML method
+ * @private
+ */
+ _attributesWhitelistRegExp: null,
+
+ /**
+ * @description Attributes of tags whitelist used by the cleanHTML method
+ * @private
+ */
+ _attributesTagsWhitelist: null,
+
+ /**
+ * @description binded controllersOff method
+ * @private
+ */
+ _bindControllersOff: null,
+
+ /**
+ * @description Is inline mode?
+ * @private
+ */
+ _isInline: null,
+
+ /**
+ * @description Is balloon|balloon-always mode?
+ * @private
+ */
+ _isBalloon: null,
+
+ /**
+ * @description Is balloon-always mode?
+ * @private
+ */
+ _isBalloonAlways: null,
+
+ /**
+ * @description Required value when using inline mode to sticky toolbar
+ * @private
+ */
+ _inlineToolbarAttr: {top: '', width: '', isShow: false},
+
+ /**
+ * @description Variable that controls the "blur" event in the editor of inline or balloon mode when the focus is moved to submenu
+ * @private
+ */
+ _notHideToolbar: false,
+
+ /**
+ * @description Variable value that sticky toolbar mode
+ * @private
+ */
+ _sticky: false,
+
+ /**
+ * @description Variables for controlling focus and blur events
+ * @private
+ */
+ _antiBlur: false,
+
+ /**
+ * @description Component line breaker element
+ * @private
+ */
+ _lineBreaker: null,
+ _lineBreakerButton: null,
+
+ /**
+ * @description If true, (initialize, reset) all indexes of image, video information
+ * @private
+ */
+ _componentsInfoInit: true,
+ _componentsInfoReset: false,
+
+ /**
+ * @description Plugins array with "active" method.
+ * "activePlugins" runs the "add" method when creating the editor.
+ */
+ activePlugins: null,
+
+ /**
+ * @description Information of tags that should maintain HTML structure, style, class name, etc. (In use by "math" plugin)
+ * When inserting "html" such as paste, it is executed on the "html" to be inserted. (core.cleanHTML)
+ * Basic Editor Actions:
+ * 1. All classes not starting with "__se__" or "se-" in the editor are removed.
+ * 2. The style of all tags except the "span" tag is removed from the editor.
+ * "managedTagsInfo" structure ex:
+ * managedTagsInfo: {
+ * query: '.__se__xxx, se-xxx'
+ * map: {
+ * '__se__xxx': method.bind(core),
+ * 'se-xxx': method.bind(core),
+ * }
+ * }
+ * @example
+ * Define in the following return format in the "managedTagInfo" function of the plugin.
+ * managedTagInfo() => {
+ * return {
+ * className: 'string', // Class name to identify the tag. ("__se__xxx", "se-xxx")
+ * // Change the html of the "element". ("element" is the element found with "className".)
+ * // "method" is executed by binding "core".
+ * method: function (element) {
+ * // this === core
+ * element.innerHTML = // (rendered html);
+ * }
+ * }
+ * }
+ */
+ managedTagsInfo: null,
+
+ /**
+ * @description cashing: options.charCounterType === 'byte-html'
+ * @private
+ */
+ _charTypeHTML: false,
+
+ /**
+ * @description Array of "checkFileInfo" functions with the core bound
+ * (Plugins with "checkFileInfo" and "resetFileInfo" methods)
+ * "fileInfoPlugins" runs the "add" method when creating the editor.
+ * "checkFileInfo" method is always call just before the "change" event.
+ * @private
+ */
+ _fileInfoPluginsCheck: null,
+
+ /**
+ * @description Array of "resetFileInfo" functions with the core bound
+ * (Plugins with "checkFileInfo" and "resetFileInfo" methods)
+ * "checkFileInfo" method is always call just before the "functions.setOptions" method.
+ * @private
+ */
+ _fileInfoPluginsReset: null,
+
+ /**
+ * @description Variables for file component management
+ * @private
+ */
+ _fileManager: {
+ tags: null,
+ regExp: null,
+ queryString: null,
+ pluginRegExp: null,
+ pluginMap: null
+ },
+
+ /**
+ * @description Elements that need to change text or className for each selection change
+ * After creating the editor, "activePlugins" are added.
+ * @property {Element} STRONG bold button
+ * @property {Element} U underline button
+ * @property {Element} EM italic button
+ * @property {Element} DEL strike button
+ * @property {Element} SUB subscript button
+ * @property {Element} SUP superscript button
+ * @property {Element} OUTDENT outdent button
+ * @property {Element} INDENT indent button
+ */
+ commandMap: null,
+
+ /**
+ * @description Style button related to edit area
+ * @property {Element} fullScreen fullScreen button element
+ * @property {Element} showBlocks showBlocks button element
+ * @property {Element} codeView codeView button element
+ * @private
+ */
+ _styleCommandMap: null,
+
+ /**
+ * @description Map of default command
+ * @private
+ */
+ _defaultCommand: {
+ bold: 'STRONG',
+ underline: 'U',
+ italic: 'EM',
+ strike: 'DEL',
+ subscript: 'SUB',
+ superscript: 'SUP'
+ },
+
+ /**
+ * @description Variables used internally in editor operation
+ * @property {Boolean} isCodeView State of code view
+ * @property {Boolean} isFullScreen State of full screen
+ * @property {Number} innerHeight_fullScreen InnerHeight in editor when in full screen
+ * @property {Number} resizeClientY Remember the vertical size of the editor before resizing the editor (Used when calculating during resize operation)
+ * @property {Number} tabSize Indent size of tab (4)
+ * @property {Number} codeIndent Indent size of Code view mode (4)
+ * @property {Number} minResizingSize Minimum size of editing area when resized {Number} (.se-wrapper-inner {min-height: 65px;} || 65)
+ * @property {Array} currentNodes An array of the current cursor's node structure
+ * @private
+ */
+ _variable: {
+ isCodeView: false,
+ isFullScreen: false,
+ innerHeight_fullScreen: 0,
+ resizeClientY: 0,
+ tabSize: 4,
+ codeIndent: 4,
+ minResizingSize: util.getNumber((context.element.wysiwygFrame.style.minHeight || '65'), 0),
+ currentNodes: [],
+ currentNodesMap: [],
+ _range: null,
+ _selectionNode: null,
+ _originCssText: context.element.topArea.style.cssText,
+ _bodyOverflow: '',
+ _editorAreaOriginCssText: '',
+ _wysiwygOriginCssText: '',
+ _codeOriginCssText: '',
+ _fullScreenAttrs: {sticky: false, balloon: false, inline: false},
+ _lineBreakComp: null,
+ _lineBreakDir: ''
+ },
+
+ /**
+ * @description If the plugin is not added, add the plugin and call the 'add' function.
+ * If the plugin is added call callBack function.
+ * @param {String} pluginName The name of the plugin to call
+ * @param {function} callBackFunction Function to be executed immediately after module call
+ * @param {Element|null} _target Plugin target button (This is not necessary if you have a button list when creating the editor)
+ */
+ callPlugin: function (pluginName, callBackFunction, _target) {
+ _target = _target || pluginCallButtons[pluginName];
+
+ if (!this.plugins[pluginName]) {
+ throw Error('[SUNEDITOR.core.callPlugin.fail] The called plugin does not exist or is in an invalid format. (pluginName:"' + pluginName + '")');
+ } else if (!this.initPlugins[pluginName]) {
+ this.plugins[pluginName].add(this, _target);
+ this.initPlugins[pluginName] = true;
+ } else if (typeof this._targetPlugins[pluginName] === 'object' && !!_target) {
+ this.initMenuTarget(pluginName, _target, this._targetPlugins[pluginName]);
+ }
+
+ if (this.plugins[pluginName].active && !this.commandMap[pluginName] && !!_target) {
+ this.commandMap[pluginName] = _target;
+ this.activePlugins.push(pluginName);
+ }
+
+ if (typeof callBackFunction === 'function') callBackFunction();
+ },
+
+ /**
+ * @description If the module is not added, add the module and call the 'add' function
+ * @param {Array} moduleArray module object's Array [dialog, resizing]
+ */
+ addModule: function (moduleArray) {
+ for (let i = 0, len = moduleArray.length, moduleName; i < len; i++) {
+ moduleName = moduleArray[i].name;
+ if (!this.plugins[moduleName]) {
+ this.plugins[moduleName] = moduleArray[i];
+ }
+ if (!this.initPlugins[moduleName]) {
+ this.initPlugins[moduleName] = true;
+ if (typeof this.plugins[moduleName].add === 'function') this.plugins[moduleName].add(this);
+ }
+ }
+ },
+
+ /**
+ * @description Method for managing submenu element.
+ * You must add the "submenu" element using the this method at custom plugin.
+ * @param {String} pluginName Plugin name
+ * @param {Element|null} target Target button
+ * @param {Element} menu Submenu element
+ */
+ initMenuTarget: function (pluginName, target, menu) {
+ if (!target) {
+ this._targetPlugins[pluginName] = menu;
+ } else {
+ context.element._menuTray.appendChild(menu);
+ this._targetPlugins[pluginName] = true;
+ this._menuTray[target.getAttribute('data-command')] = menu;
+ }
+ },
+
+ /**
+ * @description Enabled submenu
+ * @param {Element} element Submenu's button element to call
+ */
+ submenuOn: function (element) {
+ if (this._bindedSubmenuOff) this._bindedSubmenuOff();
+ if (this._bindControllersOff) this.controllersOff();
+
+ const submenuName = this._submenuName = element.getAttribute('data-command');
+ const menu = this.submenu = this._menuTray[submenuName];
+ this.submenuActiveButton = element;
+ this._setMenuPosition(element, menu);
+
+ this._bindedSubmenuOff = this.submenuOff.bind(this);
+ this.addDocEvent('mousedown', this._bindedSubmenuOff, false);
+
+ if (this.plugins[submenuName].on) this.plugins[submenuName].on.call(this);
+ this._antiBlur = true;
+ },
+
+ /**
+ * @description Disable submenu
+ */
+ submenuOff: function () {
+ this.removeDocEvent('mousedown', this._bindedSubmenuOff);
+ this._bindedSubmenuOff = null;
+
+ if (this.submenu) {
+ this._submenuName = '';
+ this.submenu.style.display = 'none';
+ this.submenu = null;
+ util.removeClass(this.submenuActiveButton, 'on');
+ this.submenuActiveButton = null;
+ this._notHideToolbar = false;
+ }
+
+ this._antiBlur = false;
+ },
+
+ /**
+ * @description Enabled container
+ * @param {Element} element Container's button element to call
+ */
+ containerOn: function (element) {
+ if (this._bindedContainerOff) this._bindedContainerOff();
+
+ const containerName = this._containerName = element.getAttribute('data-command');
+ const menu = this.container = this._menuTray[containerName];
+ this.containerActiveButton = element;
+ this._setMenuPosition(element, menu);
+
+ this._bindedContainerOff = this.containerOff.bind(this);
+ this.addDocEvent('mousedown', this._bindedContainerOff, false);
+
+ if (this.plugins[containerName].on) this.plugins[containerName].on.call(this);
+ this._antiBlur = true;
+ },
+
+ /**
+ * @description Disable container
+ */
+ containerOff: function () {
+ this.removeDocEvent('mousedown', this._bindedContainerOff);
+ this._bindedContainerOff = null;
+
+ if (this.container) {
+ this._containerName = '';
+ this.container.style.display = 'none';
+ this.container = null;
+ util.removeClass(this.containerActiveButton, 'on');
+ this.containerActiveButton = null;
+ this._notHideToolbar = false;
+ }
+
+ this._antiBlur = false;
+ },
+
+ /**
+ * @description Set the menu position. (submenu, container)
+ * @param {*} element Button element
+ * @param {*} menu Menu element
+ * @private
+ */
+ _setMenuPosition: function (element, menu) {
+ menu.style.visibility = 'hidden';
+ menu.style.display = 'block';
+ menu.style.height = '';
+ util.addClass(element, 'on');
+
+ const toolbar = this.context.element.toolbar;
+ const toolbarW = toolbar.offsetWidth;
+ const toolbarOffset = event._getEditorOffsets(context.element.toolbar);
+ const menuW = menu.offsetWidth;
+ const l = element.parentElement.offsetLeft + 3;
+
+ // rtl
+ if (options.rtl) {
+ const elementW = element.offsetWidth;
+ const rtlW = menuW > elementW ? menuW - elementW : 0;
+ const rtlL = rtlW > 0 ? 0 : elementW - menuW;
+ menu.style.left = (l - rtlW + rtlL) + 'px';
+ if (toolbarOffset.left > event._getEditorOffsets(menu).left) {
+ menu.style.left = '0px';
+ }
+ } else {
+ const overLeft = toolbarW <= menuW ? 0 : toolbarW - (l + menuW);
+ if (overLeft < 0) menu.style.left = (l + overLeft) + 'px';
+ else menu.style.left = l + 'px';
+ }
+
+ // get element top
+ let t = 0;
+ let offsetEl = element;
+ while (offsetEl && offsetEl !== toolbar) {
+ t += offsetEl.offsetTop;
+ offsetEl = offsetEl.offsetParent;
+ }
+
+ const bt = t;
+ if (this._isBalloon) {
+ t += toolbar.offsetTop + element.offsetHeight;
+ } else {
+ t -= element.offsetHeight;
+ }
+
+ // set menu position
+ const toolbarTop = toolbarOffset.top;
+ let menuHeight = menu.offsetHeight;
+ let el = context.element.topArea;
+ let scrollTop = 0;
+ while (!!el) {
+ scrollTop += el.scrollTop;
+ el = el.parentElement;
+ }
+
+ const menuHeight_bottom = _w.innerHeight - (toolbarTop - scrollTop + bt + element.parentElement.offsetHeight);
+ if (menuHeight_bottom < menuHeight) {
+ let menuTop = -1 * (menuHeight - bt + 3);
+ const insTop = toolbarTop - scrollTop + menuTop;
+ const menuHeight_top = menuHeight + (insTop < 0 ? insTop : 0);
+
+ if (menuHeight_top > menuHeight_bottom) {
+ menu.style.height = menuHeight_top + 'px';
+ menuTop = -1 * (menuHeight_top - bt + 3);
+ } else {
+ menu.style.height = menuHeight_bottom + 'px';
+ menuTop = bt + element.parentElement.offsetHeight;
+ }
+
+ menu.style.top = menuTop + 'px';
+ } else {
+ menu.style.top = (bt + element.parentElement.offsetHeight) + 'px';
+ }
+
+ menu.style.visibility = '';
+ },
+
+ /**
+ * @description Show controller at editor area (controller elements, function, "controller target element(@Required)", "controller name(@Required)", etc..)
+ * @param {*} arguments controller elements, functions..
+ */
+ controllersOn: function () {
+ if (this._bindControllersOff) this._bindControllersOff();
+ this.controllerArray = [];
+
+ for (let i = 0, arg; i < arguments.length; i++) {
+ arg = arguments[i];
+ if (!arg) continue;
+
+ if (typeof arg === 'string') {
+ this.currentControllerName = arg;
+ continue;
+ }
+ if (typeof arg === 'function') {
+ this.controllerArray.push(arg);
+ continue;
+ }
+ if (!util.hasClass(arg, 'se-controller')) {
+ this.currentControllerTarget = arg;
+ this.currentFileComponentInfo = this.getFileComponent(arg);
+ continue;
+ }
+ if (arg.style) arg.style.display = 'block';
+ this.controllerArray.push(arg);
+ }
+
+ this._bindControllersOff = this.controllersOff.bind(this);
+ this.addDocEvent('mousedown', this._bindControllersOff, false);
+ this.addDocEvent('keydown', this._bindControllersOff, false);
+ this._antiBlur = true;
+
+ if (typeof functions.showController === 'function') functions.showController(this.currentControllerName, this.controllerArray, this);
+ },
+
+ /**
+ * @description Hide controller at editor area (link button, image resize button..)
+ * @param {KeyboardEvent|MouseEvent|null} e Event object when called from mousedown and keydown events registered in "core.controllersOn"
+ */
+ controllersOff: function (e) {
+ if (this._fileManager.pluginRegExp.test(this.currentControllerName) && e && e.type === 'keydown' && e.keyCode !== 27) return;
+ context.element.lineBreaker_t.style.display = context.element.lineBreaker_b.style.display = 'none';
+ this._variable._lineBreakComp = null;
+
+ this.currentControllerName = '';
+ this.currentControllerTarget = null;
+ this.currentFileComponentInfo = null;
+ this.effectNode = null;
+ if (!this._bindControllersOff) return;
+
+ this.removeDocEvent('mousedown', this._bindControllersOff);
+ this.removeDocEvent('keydown', this._bindControllersOff);
+ this._bindControllersOff = null;
+
+ const len = this.controllerArray.length;
+ if (len > 0) {
+ for (let i = 0; i < len; i++) {
+ if (typeof this.controllerArray[i] === 'function') this.controllerArray[i]();
+ else this.controllerArray[i].style.display = 'none';
+ }
+
+ this.controllerArray = [];
+ }
+
+ this._antiBlur = false;
+ },
+
+ /**
+ * @description Specify the position of the controller.
+ * @param {Element} controller Controller element.
+ * @param {Element} referEl Element that is the basis of the controller's position.
+ * @param {String} position Type of position ("top" | "bottom")
+ * When using the "top" position, there should not be an arrow on the controller.
+ * When using the "bottom" position there should be an arrow on the controller.
+ * @param {Object} addOffset These are the left and top values that need to be added specially.
+ * This argument is required. - {left: 0, top: 0}
+ * Please enter the value based on ltr mode.
+ * Calculated automatically in rtl mode.
+ */
+ setControllerPosition: function (controller, referEl, position, addOffset) {
+ if (options.rtl) addOffset.left *= -1;
+
+ const offset = util.getOffset(referEl, context.element.wysiwygFrame);
+ controller.style.visibility = 'hidden';
+ controller.style.display = 'block';
+
+ // Height value of the arrow element is 11px
+ const topMargin = position === 'top' ? -(controller.offsetHeight + 2) : (referEl.offsetHeight + 12);
+ controller.style.top = (offset.top + topMargin + addOffset.top) + 'px';
+
+ const l = offset.left - context.element.wysiwygFrame.scrollLeft + addOffset.left;
+ const controllerW = controller.offsetWidth;
+ const referElW = referEl.offsetWidth;
+
+ // rtl (Width value of the arrow element is 22px)
+ if (options.rtl) {
+ const rtlW = (controllerW > referElW) ? controllerW - referElW : 0;
+ const rtlL = rtlW > 0 ? 0 : referElW - controllerW;
+ controller.style.left = (l - rtlW + rtlL) + 'px';
+
+ if (rtlW > 0) {
+ controller.firstElementChild.style.left = ((controllerW - 14 < 10 + rtlW) ? (controllerW - 14) : (10 + rtlW)) + 'px';
+ }
+
+ const overSize = context.element.wysiwygFrame.offsetLeft - controller.offsetLeft;
+ if (overSize > 0) {
+ controller.style.left = '0px';
+ controller.firstElementChild.style.left = overSize + 'px';
+ }
+ } else {
+ controller.style.left = l + 'px';
+
+ const overSize = context.element.wysiwygFrame.offsetWidth - (controller.offsetLeft + controllerW);
+ if (overSize < 0) {
+ controller.style.left = (controller.offsetLeft + overSize) + 'px';
+ controller.firstElementChild.style.left = (20 - overSize) + 'px';
+ } else {
+ controller.firstElementChild.style.left = '20px';
+ }
+ }
+
+ controller.style.visibility = '';
+ },
+
+ /**
+ * @description Run event.stopPropagation and event.preventDefault.
+ * @param {Object} e Event Object
+ */
+ eventStop: function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ },
+
+ /**
+ * @description javascript execCommand
+ * @param {String} command javascript execCommand function property
+ * @param {Boolean|undefined} showDefaultUI javascript execCommand function property
+ * @param {String|undefined} value javascript execCommand function property
+ */
+ execCommand: function (command, showDefaultUI, value) {
+ this._wd.execCommand(command, showDefaultUI, (command === 'formatBlock' ? '<' + value + '>' : value));
+ // history stack
+ this.history.push(true);
+ },
+
+ /**
+ * @description Focus to wysiwyg area using "native focus function"
+ */
+ nativeFocus: function () {
+ const caption = util.getParentElement(this.getSelectionNode(), 'figcaption');
+ if (caption) {
+ caption.focus();
+ } else {
+ context.element.wysiwyg.focus();
+ }
+
+ this._editorRange();
+ },
+
+ /**
+ * @description Focus to wysiwyg area
+ */
+ focus: function () {
+ if (context.element.wysiwygFrame.style.display === 'none') return;
+
+ if (options.iframe) {
+ this.nativeFocus();
+ } else {
+ try {
+ const range = this.getRange();
+
+ if (range.startContainer === range.endContainer && util.isWysiwygDiv(range.startContainer)) {
+ const format = util.createElement(options.defaultTag);
+ const br = util.createElement('BR');
+ format.appendChild(br);
+ context.element.wysiwyg.appendChild(format);
+ this.setRange(br, 0, br, 0);
+ } else {
+ this.setRange(range.startContainer, range.startOffset, range.endContainer, range.endOffset);
+ }
+ } catch (e) {
+ this.nativeFocus();
+ }
+ }
+
+ event._applyTagEffects();
+ if (this._isBalloon) event._toggleToolbarBalloon();
+ },
+
+ /**
+ * @description If "focusEl" is a component, then that component is selected; if it is a format element, the last text is selected
+ * If "focusEdge" is null, then selected last element
+ * @param {Element|null} focusEl Focus element
+ */
+ focusEdge: function (focusEl) {
+ if (!focusEl) focusEl = context.element.wysiwyg.lastElementChild;
+
+ const fileComponentInfo = this.getFileComponent(focusEl);
+ if (fileComponentInfo) {
+ this.selectComponent(fileComponentInfo.target, fileComponentInfo.pluginName);
+ } else if (focusEl) {
+ focusEl = util.getChildElement(focusEl, function (current) { return current.childNodes.length === 0 || current.nodeType === 3; }, true);
+ if (!focusEl) this.nativeFocus();
+ else this.setRange(focusEl, focusEl.textContent.length, focusEl, focusEl.textContent.length);
+ } else {
+ this.focus();
+ }
+ },
+
+ /**
+ * @description Set current editor's range object and return.
+ * @param {Node} startCon The startContainer property of the selection object.
+ * @param {Number} startOff The startOffset property of the selection object.
+ * @param {Node} endCon The endContainer property of the selection object.
+ * @param {Number} endOff The endOffset property of the selection object.
+ * @returns {Object} Range object.
+ */
+ setRange: function (startCon, startOff, endCon, endOff) {
+ if (!startCon || !endCon) return;
+ if (startOff > startCon.textContent.length) startOff = startCon.textContent.length;
+ if (endOff > endCon.textContent.length) endOff = endCon.textContent.length;
+
+ const range = this._wd.createRange();
+
+ try {
+ range.setStart(startCon, startOff);
+ range.setEnd(endCon, endOff);
+ } catch (error) {
+ console.warn('[SUNEDITOR.core.focus.error] ' + error);
+ this.nativeFocus();
+ return;
+ }
+
+ const selection = this.getSelection();
+
+ if (selection.removeAllRanges) {
+ selection.removeAllRanges();
+ }
+
+ selection.addRange(range);
+ this._editorRange();
+ if (options.iframe) this.nativeFocus();
+
+ return range;
+ },
+
+ /**
+ * @description Remove range object and button effect
+ */
+ removeRange: function () {
+ this._variable._range = null;
+ this._variable._selectionNode = null;
+ this.getSelection().removeAllRanges();
+
+ const commandMap = this.commandMap;
+ const activePlugins = this.activePlugins;
+ for (let key in commandMap) {
+ if (!util.hasOwn(commandMap, key)) continue;
+ if (activePlugins.indexOf(key) > -1) {
+ plugins[key].active.call(this, null);
+ } else if (commandMap.OUTDENT && /^OUTDENT$/i.test(key)) {
+ commandMap.OUTDENT.setAttribute('disabled', true);
+ } else if (commandMap.INDENT && /^INDENT$/i.test(key)) {
+ commandMap.INDENT.removeAttribute('disabled');
+ } else {
+ util.removeClass(commandMap[key], 'active');
+ }
+ }
+ },
+
+ /**
+ * @description Get current editor's range object
+ * @returns {Object}
+ */
+ getRange: function () {
+ const range = this._variable._range || this._createDefaultRange();
+ const selection = this.getSelection();
+ if (range.collapsed === selection.isCollapsed || !context.element.wysiwyg.contains(selection.focusNode)) return range;
+
+ if (selection.rangeCount > 0) {
+ this._variable._range = selection.getRangeAt(0);
+ return this._variable._range;
+ } else {
+ const sc = selection.anchorNode, ec = selection.focusNode, so = selection.anchorOffset, eo = selection.focusOffset;
+ const compareValue = util.compareElements(sc, ec);
+ const rightDir = compareValue.ancestor && (compareValue.result === 0 ? so <= eo : compareValue.result > 1 ? true : false);
+ return this.setRange(
+ rightDir ? sc : ec,
+ rightDir ? so : eo,
+ rightDir ? ec : sc,
+ rightDir ? eo : so
+ );
+ }
+ },
+
+ /**
+ * @description If the "range" object is a non-editable area, add a line at the top of the editor and update the "range" object.
+ * Returns a new "range" or argument "range".
+ * @param {Object} range core.getRange()
+ * @param {Element|null} container If there is "container" argument, it creates a line in front of the container.
+ * @returns {Object} range
+ */
+ getRange_addLine: function (range, container) {
+ if (this._selectionVoid(range)) {
+ const wysiwyg = context.element.wysiwyg;
+ const op = util.createElement(options.defaultTag);
+ op.innerHTML = '<br>';
+ wysiwyg.insertBefore(op, container && container !== wysiwyg ? container.nextElementSibling : wysiwyg.firstElementChild);
+ this.setRange(op.firstElementChild, 0, op.firstElementChild, 1);
+ range = this._variable._range;
+ }
+ return range;
+ },
+
+ /**
+ * @description Get window selection obejct
+ * @returns {Object}
+ */
+ getSelection: function () {
+ return this._shadowRoot && this._shadowRoot.getSelection ? this._shadowRoot.getSelection() : this._ww.getSelection();
+ },
+
+ /**
+ * @description Get current select node
+ * @returns {Node}
+ */
+ getSelectionNode: function () {
+ if (util.isWysiwygDiv(this._variable._selectionNode)) this._editorRange();
+ if (!this._variable._selectionNode) {
+ const selectionNode = util.getChildElement(context.element.wysiwyg.firstChild, function (current) { return current.childNodes.length === 0 || current.nodeType === 3; }, false);
+ if (!selectionNode) {
+ this._editorRange();
+ } else {
+ this._variable._selectionNode = selectionNode;
+ return selectionNode;
+ }
+ }
+ return this._variable._selectionNode;
+ },
+
+ /**
+ * @description Saving the range object and the currently selected node of editor
+ * @private
+ */
+ _editorRange: function () {
+ const selection = this.getSelection();
+ if (!selection) return null;
+ let range = null;
+ let selectionNode = null;
+
+ if (selection.rangeCount > 0) {
+ range = selection.getRangeAt(0);
+ } else {
+ range = this._createDefaultRange();
+ }
+
+ this._variable._range = range;
+
+ if (range.collapsed) {
+ selectionNode = range.commonAncestorContainer;
+ } else {
+ selectionNode = selection.extentNode || selection.anchorNode;
+ }
+
+ this._variable._selectionNode = selectionNode;
+ },
+
+ /**
+ * @description Return the range object of editor's first child node
+ * @returns {Object}
+ * @private
+ */
+ _createDefaultRange: function () {
+ const wysiwyg = context.element.wysiwyg;
+ wysiwyg.focus();
+ const range = this._wd.createRange();
+
+ let focusEl = wysiwyg.firstElementChild;
+ if (!focusEl) {
+ focusEl = util.createElement(options.defaultTag);
+ focusEl.innerHTML = '<br>';
+ wysiwyg.appendChild(focusEl);
+ }
+
+ range.setStart(focusEl, 0);
+ range.setEnd(focusEl, 0);
+
+ return range;
+ },
+
+ /**
+ * @description Returns true if there is no valid "selection".
+ * @param {Object} range core.getRange()
+ * @returns {Object} range
+ * @private
+ */
+ _selectionVoid: function (range) {
+ const comm = range.commonAncestorContainer;
+ return (util.isWysiwygDiv(range.startContainer) && util.isWysiwygDiv(range.endContainer)) || /FIGURE/i.test(comm.nodeName) || this._fileManager.regExp.test(comm.nodeName) || util.isMediaComponent(comm);
+ },
+
+ /**
+ * @description Reset range object to text node selected status.
+ * @returns {Boolean} Returns false if there is no valid selection.
+ * @private
+ */
+ _resetRangeToTextNode: function () {
+ const range = this.getRange();
+ if (this._selectionVoid(range)) return false;
+
+ let startCon = range.startContainer;
+ let startOff = range.startOffset;
+ let endCon = range.endContainer;
+ let endOff = range.endOffset;
+ let tempCon, tempOffset, tempChild;
+
+ if (util.isFormatElement(startCon)) {
+ startCon = startCon.childNodes[startOff] || startCon.lastChild;
+ startOff = startCon.textContent.length;
+ }
+ if (util.isFormatElement(endCon)) {
+ endCon = endCon.childNodes[endOff] || endCon.lastChild;
+ endOff = endCon.textContent.length;
+ }
+
+ // startContainer
+ tempCon = util.isWysiwygDiv(startCon) ? context.element.wysiwyg.firstChild : startCon;
+ tempOffset = startOff;
+
+ if (util.isBreak(tempCon) || (tempCon.nodeType === 1 && tempCon.childNodes.length > 0)) {
+ const onlyBreak = util.isBreak(tempCon);
+ if (!onlyBreak) {
+ while (tempCon && !util.isBreak(tempCon) && tempCon.nodeType === 1) {
+ tempCon = tempCon.childNodes[tempOffset] || tempCon.nextElementSibling || tempCon.nextSibling;
+ tempOffset = 0;
+ }
+
+ let format = util.getFormatElement(tempCon, null);
+ if (format === util.getRangeFormatElement(format, null)) {
+ format = util.createElement(util.getParentElement(tempCon, util.isCell) ? 'DIV' : options.defaultTag);
+ tempCon.parentNode.insertBefore(format, tempCon);
+ format.appendChild(tempCon);
+ }
+ }
+
+ if (util.isBreak(tempCon)) {
+ const emptyText = util.createTextNode(util.zeroWidthSpace);
+ tempCon.parentNode.insertBefore(emptyText, tempCon);
+ tempCon = emptyText;
+ if (onlyBreak) {
+ if (startCon === endCon) {
+ endCon = tempCon;
+ endOff = 1;
+ }
+ }
+ }
+ }
+
+ // set startContainer
+ startCon = tempCon;
+ startOff = tempOffset;
+
+ // endContainer
+ tempCon = util.isWysiwygDiv(endCon) ? context.element.wysiwyg.lastChild : endCon;
+ tempOffset = endOff;
+
+ if (util.isBreak(tempCon) || (tempCon.nodeType === 1 && tempCon.childNodes.length > 0)) {
+ const onlyBreak = util.isBreak(tempCon);
+ if (!onlyBreak) {
+ while (tempCon && !util.isBreak(tempCon) && tempCon.nodeType === 1) {
+ tempChild = tempCon.childNodes;
+ if (tempChild.length === 0) break;
+ tempCon = tempChild[tempOffset > 0 ? tempOffset - 1 : tempOffset] || !/FIGURE/i.test(tempChild[0].nodeName) ? tempChild[0] : (tempCon.previousElementSibling || tempCon.previousSibling || startCon);
+ tempOffset = tempOffset > 0 ? tempCon.textContent.length : tempOffset;
+ }
+
+ let format = util.getFormatElement(tempCon, null);
+ if (format === util.getRangeFormatElement(format, null)) {
+ format = util.createElement(util.isCell(format) ? 'DIV' : options.defaultTag);
+ tempCon.parentNode.insertBefore(format, tempCon);
+ format.appendChild(tempCon);
+ }
+ }
+
+ if (util.isBreak(tempCon)) {
+ const emptyText = util.createTextNode(util.zeroWidthSpace);
+ tempCon.parentNode.insertBefore(emptyText, tempCon);
+ tempCon = emptyText;
+ tempOffset = 1;
+ if (onlyBreak && !tempCon.previousSibling) {
+ util.removeItem(endCon);
+ }
+ }
+ }
+
+ // set endContainer
+ endCon = tempCon;
+ endOff = tempOffset;
+
+ // set Range
+ this.setRange(startCon, startOff, endCon, endOff);
+ return true;
+ },
+
+ /**
+ * @description Returns a "formatElement"(util.isFormatElement) array from the currently selected range.
+ * @param {Function|null} validation The validation function. (Replaces the default validation function-util.isFormatElement(current))
+ * @returns {Array}
+ */
+ getSelectedElements: function (validation) {
+ if (!this._resetRangeToTextNode()) return [];
+ let range = this.getRange();
+
+ if (util.isWysiwygDiv(range.startContainer)) {
+ const children = context.element.wysiwyg.children;
+ if (children.length === 0) return [];
+
+ this.setRange(children[0], 0, children[children.length - 1], children[children.length - 1].textContent.trim().length);
+ range = this.getRange();
+ }
+
+ const startCon = range.startContainer;
+ const endCon = range.endContainer;
+ const commonCon = range.commonAncestorContainer;
+
+ // get line nodes
+ const lineNodes = util.getListChildren(commonCon, function (current) {
+ return validation ? validation(current) : util.isFormatElement(current);
+ });
+
+ if (!util.isWysiwygDiv(commonCon) && !util.isRangeFormatElement(commonCon)) lineNodes.unshift(util.getFormatElement(commonCon, null));
+ if (startCon === endCon || lineNodes.length === 1) return lineNodes;
+
+ let startLine = util.getFormatElement(startCon, null);
+ let endLine = util.getFormatElement(endCon, null);
+ let startIdx = null;
+ let endIdx = null;
+
+ const onlyTable = function (current) {
+ return util.isTable(current) ? /^TABLE$/i.test(current.nodeName) : true;
+ };
+
+ let startRangeEl = util.getRangeFormatElement(startLine, onlyTable);
+ let endRangeEl = util.getRangeFormatElement(endLine, onlyTable);
+ if (util.isTable(startRangeEl) && util.isListCell(startRangeEl.parentNode)) startRangeEl = startRangeEl.parentNode;
+ if (util.isTable(endRangeEl) && util.isListCell(endRangeEl.parentNode)) endRangeEl = endRangeEl.parentNode;
+
+ const sameRange = startRangeEl === endRangeEl;
+ for (let i = 0, len = lineNodes.length, line; i < len; i++) {
+ line = lineNodes[i];
+
+ if (startLine === line || (!sameRange && line === startRangeEl)) {
+ startIdx = i;
+ continue;
+ }
+
+ if (endLine === line || (!sameRange && line === endRangeEl)) {
+ endIdx = i;
+ break;
+ }
+ }
+
+ if (startIdx === null) startIdx = 0;
+ if (endIdx === null) endIdx = lineNodes.length - 1;
+
+ return lineNodes.slice(startIdx, endIdx + 1);
+ },
+
+ /**
+ * @description Get format elements and components from the selected area. (P, DIV, H[1-6], OL, UL, TABLE..)
+ * If some of the component are included in the selection, get the entire that component.
+ * @param {Boolean} removeDuplicate If true, if there is a parent and child tag among the selected elements, the child tag is excluded.
+ * @returns {Array}
+ */
+ getSelectedElementsAndComponents: function (removeDuplicate) {
+ const commonCon = this.getRange().commonAncestorContainer;
+ const myComponent = util.getParentElement(commonCon, util.isComponent);
+ const selectedLines = util.isTable(commonCon) ?
+ this.getSelectedElements(null) :
+ this.getSelectedElements(function (current) {
+ const component = this.getParentElement(current, this.isComponent);
+ return (this.isFormatElement(current) && (!component || component === myComponent)) || (this.isComponent(current) && !this.getFormatElement(current));
+ }.bind(util));
+
+ if (removeDuplicate) {
+ for (let i = 0, len = selectedLines.length; i < len; i++) {
+ for (let j = i - 1; j >= 0; j--) {
+ if (selectedLines[j].contains(selectedLines[i])) {
+ selectedLines.splice(i, 1);
+ i--; len--;
+ break;
+ }
+ }
+ }
+ }
+
+ return selectedLines;
+ },
+
+ /**
+ * @description Determine if this offset is the edge offset of container
+ * @param {Node} container The node of the selection object. (range.startContainer..)
+ * @param {Number} offset The offset of the selection object. (core.getRange().startOffset...)
+ * @returns {Boolean}
+ */
+ isEdgePoint: function (container, offset) {
+ return (offset === 0) || (!container.nodeValue && offset === 1) || (offset === container.nodeValue.length);
+ },
+
+ /**
+ * @description Show loading box
+ */
+ showLoading: function () {
+ context.element.loading.style.display = 'block';
+ },
+
+ /**
+ * @description Close loading box
+ */
+ closeLoading: function () {
+ context.element.loading.style.display = 'none';
+ },
+
+ /**
+ * @description Append format element to sibling node of argument element.
+ * If the "formatNodeName" argument value is present, the tag of that argument value is inserted,
+ * If not, the currently selected format tag is inserted.
+ * @param {Element} element Insert as siblings of that element
+ * @param {String|Element|null} formatNode Node name or node obejct to be inserted
+ * @returns {Element}
+ */
+ appendFormatTag: function (element, formatNode) {
+ const currentFormatEl = util.getFormatElement(this.getSelectionNode(), null);
+ const oFormatName = formatNode ? (typeof formatNode === 'string' ? formatNode : formatNode.nodeName) : (util.isFormatElement(currentFormatEl) && !util.isFreeFormatElement(currentFormatEl)) ? currentFormatEl.nodeName : options.defaultTag;
+ const oFormat = util.createElement(oFormatName);
+ oFormat.innerHTML = '<br>';
+
+ if ((formatNode && typeof formatNode !== 'string') || (!formatNode && util.isFormatElement(currentFormatEl))) {
+ util.copyTagAttributes(oFormat, formatNode || currentFormatEl);
+ }
+
+ if (util.isCell(element)) element.insertBefore(oFormat, element.nextElementSibling);
+ else element.parentNode.insertBefore(oFormat, element.nextElementSibling);
+
+ return oFormat;
+ },
+
+ /**
+ * @description The method to insert a element and return. (used elements : table, hr, image, video)
+ * If "element" is "HR", insert and return the new line.
+ * @param {Element} element Element to be inserted
+ * @param {Boolean} notHistoryPush When true, it does not update the history stack and the selection object and return EdgeNodes (util.getEdgeChildNodes)
+ * @param {Boolean} checkCharCount If true, if "options.maxCharCount" is exceeded when "element" is added, null is returned without addition.
+ * @param {Boolean} notSelect If true, Do not automatically select the inserted component.
+ * @returns {Element}
+ */
+ insertComponent: function (element, notHistoryPush, checkCharCount, notSelect) {
+ if (checkCharCount && !this.checkCharCount(element, null)) {
+ return null;
+ }
+
+ const r = this.removeNode();
+ this.getRange_addLine(this.getRange(), r.container);
+ let oNode = null;
+ let selectionNode = this.getSelectionNode();
+ let formatEl = util.getFormatElement(selectionNode, null);
+
+ if (util.isListCell(formatEl)) {
+ this.insertNode(element, selectionNode === formatEl ? null : r.container.nextSibling, false);
+ if (!element.nextSibling) element.parentNode.appendChild(util.createElement('BR'));
+ } else {
+ if (this.getRange().collapsed && (r.container.nodeType === 3 || util.isBreak(r.container))) {
+ const depthFormat = util.getParentElement(r.container, function (current) { return this.isRangeFormatElement(current); }.bind(util));
+ oNode = util.splitElement(r.container, r.offset, !depthFormat ? 0 : util.getElementDepth(depthFormat) + 1);
+ if (oNode) formatEl = oNode.previousSibling;
+ }
+ this.insertNode(element, formatEl, false);
+ if (formatEl && util.onlyZeroWidthSpace(formatEl)) util.removeItem(formatEl);
+ }
+
+ this.setRange(element, 0, element, 0);
+
+ if (!notSelect) {
+ const fileComponentInfo = this.getFileComponent(element);
+ if (fileComponentInfo) {
+ this.selectComponent(fileComponentInfo.target, fileComponentInfo.pluginName);
+ } else if (oNode) {
+ oNode = util.getEdgeChildNodes(oNode, null).sc || oNode;
+ this.setRange(oNode, 0, oNode, 0);
+ }
+ }
+
+ // history stack
+ if (!notHistoryPush) this.history.push(1);
+
+ return oNode || element;
+ },
+
+ /**
+ * @description Gets the file component and that plugin name
+ * return: {target, component, pluginName} | null
+ * @param {Element} element Target element (figure tag, component div, file tag)
+ * @returns {Object|null}
+ */
+ getFileComponent: function (element) {
+ if (!this._fileManager.queryString || !element) return null;
+
+ let target, pluginName;
+ if (/^FIGURE$/i.test(element.nodeName) || /se-component/.test(element.className)) {
+ target = element.querySelector(this._fileManager.queryString);
+ }
+ if (!target && element.nodeName && this._fileManager.regExp.test(element.nodeName)) {
+ target = element;
+ }
+
+ if (target) {
+ pluginName = this._fileManager.pluginMap[target.nodeName.toLowerCase()];
+ if (pluginName) {
+ return {
+ target: target,
+ component: util.getParentElement(target, util.isComponent),
+ pluginName: pluginName
+ };
+ }
+ }
+
+ return null;
+ },
+
+ /**
+ * @description The component(image, video) is selected and the resizing module is called.
+ * @param {Element} element Element tag (img, iframe, video)
+ * @param {String} pluginName Plugin name (image, video)
+ */
+ selectComponent: function (element, pluginName) {
+ if (!this.hasFocus) this.focus();
+ const plugin = this.plugins[pluginName];
+ if (!plugin) return;
+ _w.setTimeout(function () {
+ if (typeof plugin.select === 'function') this.callPlugin(pluginName, plugin.select.bind(this, element), null);
+ this._setComponentLineBreaker(element);
+ }.bind(this));
+ },
+
+ /**
+ * @description Set line breaker of component
+ * @param {Element} element Element tag (img, iframe, video)
+ * @private
+ */
+ _setComponentLineBreaker: function (element) {
+ // line breaker
+ this._lineBreaker.style.display = 'none';
+ const container = util.getParentElement(element, util.isComponent);
+ const t_style = context.element.lineBreaker_t.style;
+ const b_style = context.element.lineBreaker_b.style;
+ const target = this.context.resizing.resizeContainer.style.display === 'block' ? this.context.resizing.resizeContainer : element;
+
+ const isList = util.isListCell(container.parentNode);
+ let componentTop, wScroll, w;
+ // top
+ if (isList ? !container.previousSibling : !util.isFormatElement(container.previousElementSibling)) {
+ this._variable._lineBreakComp = container;
+ wScroll = context.element.wysiwyg.scrollTop;
+ componentTop = util.getOffset(element, context.element.wysiwygFrame).top + wScroll;
+ w = (target.offsetWidth / 2) / 2;
+
+ t_style.top = (componentTop - wScroll - 12) + 'px';
+ t_style.left = (util.getOffset(target).left + w) + 'px';
+ t_style.display = 'block';
+ } else {
+ t_style.display = 'none';
+ }
+ // bottom
+ if (isList ? !container.nextSibling : !util.isFormatElement(container.nextElementSibling)) {
+ if (!componentTop) {
+ this._variable._lineBreakComp = container;
+ wScroll = context.element.wysiwyg.scrollTop;
+ componentTop = util.getOffset(element, context.element.wysiwygFrame).top + wScroll;
+ w = (target.offsetWidth / 2) / 2;
+ }
+
+ b_style.top = (componentTop + target.offsetHeight - wScroll - 12) + 'px';
+ b_style.left = (util.getOffset(target).left + target.offsetWidth - w - 24) + 'px';
+ b_style.display = 'block';
+ } else {
+ b_style.display = 'none';
+ }
+ },
+
+ /**
+ * @description Delete selected node and insert argument value node and return.
+ * If the "afterNode" exists, it is inserted after the "afterNode"
+ * Inserting a text node merges with both text nodes on both sides and returns a new "{ container, startOffset, endOffset }".
+ * @param {Node} oNode Element to be inserted
+ * @param {Node|null} afterNode If the node exists, it is inserted after the node
+ * @param {Boolean} checkCharCount If true, if "options.maxCharCount" is exceeded when "element" is added, null is returned without addition.
+ * @returns {Object|Node|null}
+ */
+ insertNode: function (oNode, afterNode, checkCharCount) {
+ if (checkCharCount && !this.checkCharCount(oNode, null)) {
+ return null;
+ }
+
+ const freeFormat = util.getFreeFormatElement(this.getSelectionNode(), null);
+ const isFormats = (!freeFormat && (util.isFormatElement(oNode) || util.isRangeFormatElement(oNode))) || util.isComponent(oNode);
+
+ if (!afterNode && isFormats) {
+ const range = this.getRange();
+ if (range.startOffset !== range.endOffset || range.startContainer !== range.endContainer) {
+ const r = this.removeNode();
+ if (r.container.nodeType === 3 || util.isBreak(r.container)) {
+ const depthFormat = util.getParentElement(r.container, function (current) { return this.isRangeFormatElement(current) || this.isListCell(current); }.bind(util));
+ afterNode = util.splitElement(r.container, r.offset, !depthFormat ? 0 : util.getElementDepth(depthFormat) + 1);
+ if (afterNode) afterNode = afterNode.previousSibling;
+ }
+ }
+ }
+
+ const range = (!afterNode && !isFormats) ? this.getRange_addLine(this.getRange(), null) : this.getRange();
+ const commonCon = range.commonAncestorContainer;
+ const startOff = range.startOffset;
+ const endOff = range.endOffset;
+ const formatRange = range.startContainer === commonCon && util.isFormatElement(commonCon);
+ const startCon = formatRange ? commonCon.childNodes[startOff] : range.startContainer;
+ const endCon = formatRange ? commonCon.childNodes[endOff] : range.endContainer;
+ let parentNode, originAfter = null;
+
+ if (!afterNode) {
+ parentNode = startCon;
+ if (startCon.nodeType === 3) {
+ parentNode = startCon.parentNode;
+ }
+
+ /** No Select range node */
+ if (range.collapsed) {
+ if (commonCon.nodeType === 3) {
+ if (commonCon.textContent.length > endOff) afterNode = commonCon.splitText(endOff);
+ else afterNode = commonCon.nextSibling;
+ } else {
+ if (!util.isBreak(parentNode)) {
+ let c = parentNode.childNodes[startOff];
+ const focusNode = (c && c.nodeType === 3 && util.onlyZeroWidthSpace(c) && util.isBreak(c.nextSibling)) ? c.nextSibling : c;
+ if (focusNode) {
+ if (!focusNode.nextSibling) {
+ parentNode.removeChild(focusNode);
+ afterNode = null;
+ } else {
+ afterNode = (util.isBreak(focusNode) && !util.isBreak(oNode)) ? focusNode : focusNode.nextSibling;
+ }
+ } else {
+ afterNode = null;
+ }
+ } else {
+ afterNode = parentNode;
+ parentNode = parentNode.parentNode;
+ }
+ }
+ } else { /** Select range nodes */
+ const isSameContainer = startCon === endCon;
+
+ if (isSameContainer) {
+ if (this.isEdgePoint(endCon, endOff)) afterNode = endCon.nextSibling;
+ else afterNode = endCon.splitText(endOff);
+
+ let removeNode = startCon;
+ if (!this.isEdgePoint(startCon, startOff)) removeNode = startCon.splitText(startOff);
+
+ parentNode.removeChild(removeNode);
+ if (parentNode.childNodes.length === 0 && isFormats) {
+ parentNode.innerHTML = '<br>';
+ }
+ }
+ else {
+ const removedTag = this.removeNode();
+ const container = removedTag.container;
+ const prevContainer = removedTag.prevContainer;
+ if (container && container.childNodes.length === 0 && isFormats) {
+ if (util.isFormatElement(container)) {
+ container.innerHTML = '<br>';
+ } else if (util.isRangeFormatElement(container)) {
+ container.innerHTML = '<' + options.defaultTag + '><br></' + options.defaultTag + '>';
+ }
+ }
+
+ if (!isFormats && prevContainer) {
+ parentNode = prevContainer.nodeType === 3 ? prevContainer.parentNode : prevContainer;
+ if (parentNode.contains(container)) {
+ afterNode = container;
+ while (afterNode.parentNode === parentNode) {
+ afterNode = afterNode.parentNode;
+ }
+ } else {
+ afterNode = null;
+ }
+ } else {
+ parentNode = isFormats ? commonCon : container;
+ afterNode = isFormats ? endCon : null;
+ }
+
+ while (afterNode && !util.isFormatElement(afterNode) && afterNode.parentNode !== commonCon) {
+ afterNode = afterNode.parentNode;
+ }
+ }
+ }
+ }
+ // has afterNode
+ else {
+ parentNode = afterNode.parentNode;
+ afterNode = afterNode.nextSibling;
+ originAfter = true;
+ }
+
+ // --- insert node ---
+ try {
+ if (util.isFormatElement(oNode) || util.isRangeFormatElement(oNode) || (!util.isListCell(parentNode) && util.isComponent(oNode))) {
+ const oldParent = parentNode;
+ if (util.isList(afterNode)) {
+ parentNode = afterNode;
+ afterNode = null;
+ } else if (util.isListCell(afterNode)) {
+ parentNode = afterNode.previousElementSibling || afterNode;
+ } else if (!originAfter && !afterNode) {
+ const r = this.removeNode();
+ const container = r.container.nodeType === 3 ? (util.isListCell(util.getFormatElement(r.container, null)) ? r.container : (util.getFormatElement(r.container, null) || r.container.parentNode)) : r.container;
+ const rangeCon = util.isWysiwygDiv(container) || util.isRangeFormatElement(container);
+ parentNode = rangeCon ? container : container.parentNode;
+ afterNode = rangeCon ? null : container.nextSibling;
+ }
+
+ if (oldParent.childNodes.length === 0 && parentNode !== oldParent) util.removeItem(oldParent);
+ }
+
+ if (isFormats && !freeFormat && !util.isRangeFormatElement(parentNode) && !util.isListCell(parentNode) && !util.isWysiwygDiv(parentNode)) {
+ afterNode = parentNode.nextElementSibling;
+ parentNode = parentNode.parentNode;
+ }
+ parentNode.insertBefore(oNode, parentNode === afterNode ? parentNode.lastChild : afterNode);
+ } catch (e) {
+ parentNode.appendChild(oNode);
+ } finally {
+ if (freeFormat && (util.isFormatElement(oNode) || util.isRangeFormatElement(oNode))) {
+ oNode = this._setIntoFreeFormat(oNode);
+ }
+
+ if (!util.isComponent(oNode)) {
+ let offset = 1;
+ if (oNode.nodeType === 3) {
+ const previous = oNode.previousSibling;
+ const next = oNode.nextSibling;
+ const previousText = (!previous || previous.nodeType === 1 || util.onlyZeroWidthSpace(previous)) ? '' : previous.textContent;
+ const nextText = (!next || next.nodeType === 1 || util.onlyZeroWidthSpace(next)) ? '' : next.textContent;
+
+ if (previous && previousText.length > 0) {
+ oNode.textContent = previousText + oNode.textContent;
+ util.removeItem(previous);
+ }
+
+ if (next && next.length > 0) {
+ oNode.textContent += nextText;
+ util.removeItem(next);
+ }
+
+ const newRange = {
+ container: oNode,
+ startOffset: previousText.length,
+ endOffset: oNode.textContent.length - nextText.length
+ };
+
+ this.setRange(oNode, newRange.startOffset, oNode, newRange.endOffset);
+
+ return newRange;
+ } else if (!util.isBreak(oNode) && util.isFormatElement(parentNode)) {
+ let zeroWidth = null;
+ if (!oNode.previousSibling || util.isBreak(oNode.previousSibling)) {
+ zeroWidth = util.createTextNode(util.zeroWidthSpace);
+ oNode.parentNode.insertBefore(zeroWidth, oNode);
+ }
+
+ if (!oNode.nextSibling || util.isBreak(oNode.nextSibling)) {
+ zeroWidth = util.createTextNode(util.zeroWidthSpace);
+ oNode.parentNode.insertBefore(zeroWidth, oNode.nextSibling);
+ }
+
+ if (util._isIgnoreNodeChange(oNode)) {
+ oNode = oNode.nextSibling;
+ offset = 0;
+ }
+ }
+
+ this.setRange(oNode, offset, oNode, offset);
+ }
+
+ // history stack
+ this.history.push(true);
+
+ return oNode;
+ }
+ },
+
+ _setIntoFreeFormat: function (oNode) {
+ const parentNode = oNode.parentNode;
+ let oNodeChildren, lastONode;
+
+ while (util.isFormatElement(oNode) || util.isRangeFormatElement(oNode)) {
+ oNodeChildren = oNode.childNodes;
+ lastONode = null;
+
+ while (oNodeChildren[0]) {
+ lastONode = oNodeChildren[0];
+ if (util.isFormatElement(lastONode) || util.isRangeFormatElement(lastONode)) {
+ this._setIntoFreeFormat(lastONode);
+ if (!oNode.parentNode) break;
+ oNodeChildren = oNode.childNodes;
+ continue;
+ }
+
+ parentNode.insertBefore(lastONode, oNode);
+ }
+
+ if (oNode.childNodes.length === 0) util.removeItem(oNode);
+ oNode = util.createElement('BR');
+ parentNode.insertBefore(oNode, lastONode.nextSibling);
+ }
+
+ return oNode;
+ },
+
+ /**
+ * @description Delete the currently selected nodes and reset selection range
+ * Returns {container: "the last element after deletion", offset: "offset", prevContainer: "previousElementSibling Of the deleted area"}
+ * @returns {Object}
+ */
+ removeNode: function () {
+ this._resetRangeToTextNode();
+
+ const range = this.getRange();
+ let container, offset = 0;
+ let startCon = range.startContainer;
+ let endCon = range.endContainer;
+ const startOff = range.startOffset;
+ const endOff = range.endOffset;
+ const commonCon = (range.commonAncestorContainer.nodeType === 3 && range.commonAncestorContainer.parentNode === startCon.parentNode) ? startCon.parentNode : range.commonAncestorContainer;
+
+ let beforeNode = null;
+ let afterNode = null;
+
+ const childNodes = util.getListChildNodes(commonCon, null);
+ let startIndex = util.getArrayIndex(childNodes, startCon);
+ let endIndex = util.getArrayIndex(childNodes, endCon);
+
+ if (childNodes.length > 0 && startIndex > -1 && endIndex > -1) {
+ for (let i = startIndex + 1, startNode = startCon; i >= 0; i--) {
+ if (childNodes[i] === startNode.parentNode && childNodes[i].firstChild === startNode && startOff === 0) {
+ startIndex = i;
+ startNode = startNode.parentNode;
+ }
+ }
+
+ for (let i = endIndex - 1, endNode = endCon; i > startIndex; i--) {
+ if (childNodes[i] === endNode.parentNode && childNodes[i].nodeType === 1) {
+ childNodes.splice(i, 1);
+ endNode = endNode.parentNode;
+ --endIndex;
+ }
+ }
+ } else {
+ if (childNodes.length === 0) {
+ if (util.isFormatElement(commonCon) || util.isRangeFormatElement(commonCon) || util.isWysiwygDiv(commonCon) || util.isBreak(commonCon) || util.isMedia(commonCon)) {
+ return {
+ container: commonCon,
+ offset: 0
+ };
+ } else if (commonCon.nodeType === 3) {
+ return {
+ container: commonCon,
+ offset: endOff
+ };
+ }
+ childNodes.push(commonCon);
+ startCon = endCon = commonCon;
+ } else {
+ startCon = endCon = childNodes[0];
+ if (util.isBreak(startCon) || util.onlyZeroWidthSpace(startCon)) {
+ return {
+ container: util.isMedia(commonCon) ? commonCon : startCon,
+ offset: 0
+ };
+ }
+ }
+
+ startIndex = endIndex = 0;
+ }
+
+ function remove (item) {
+ const format = util.getFormatElement(item, null);
+ util.removeItem(item);
+
+ if(util.isListCell(format)) {
+ const list = util.getArrayItem(format.children, util.isList, false);
+ if (list) {
+ const child = list.firstElementChild;
+ const children = child.childNodes;
+ while (children[0]) {
+ format.insertBefore(children[0], list);
+ }
+ util.removeItemAllParents(child, null, null);
+ }
+ }
+ }
+
+ for (let i = startIndex; i <= endIndex; i++) {
+ const item = childNodes[i];
+
+ if (item.length === 0 || (item.nodeType === 3 && item.data === undefined)) {
+ remove(item);
+ continue;
+ }
+
+ if (item === startCon) {
+ if (startCon.nodeType === 1) {
+ beforeNode = util.createTextNode(startCon.textContent);
+ } else {
+ if (item === endCon) {
+ beforeNode = util.createTextNode(startCon.substringData(0, startOff) + endCon.substringData(endOff, (endCon.length - endOff)));
+ offset = startOff;
+ } else {
+ beforeNode = util.createTextNode(startCon.substringData(0, startOff));
+ }
+ }
+
+ if (beforeNode.length > 0) {
+ startCon.data = beforeNode.data;
+ } else {
+ remove(startCon);
+ }
+
+ if (item === endCon) break;
+ continue;
+ }
+
+ if (item === endCon) {
+ if (endCon.nodeType === 1) {
+ afterNode = util.createTextNode(endCon.textContent);
+ } else {
+ afterNode = util.createTextNode(endCon.substringData(endOff, (endCon.length - endOff)));
+ }
+
+ if (afterNode.length > 0) {
+ endCon.data = afterNode.data;
+ } else {
+ remove(endCon);
+ }
+
+ continue;
+ }
+
+ remove(item);
+ }
+
+ container = endCon && endCon.parentNode ? endCon : startCon && startCon.parentNode ? startCon : (range.endContainer || range.startContainer);
+
+ if (!util.isWysiwygDiv(container)) {
+ const rc = util.removeItemAllParents(container, function (current) {
+ if (this.isComponent(current)) return false;
+ const text = current.textContent;
+ return text.length === 0 || /^(\n|\u200B)+$/.test(text);
+ }.bind(util), null);
+
+ if (rc) container = rc.sc || rc.ec || context.element.wysiwyg;
+ }
+
+ // set range
+ this.setRange(container, offset, container, offset);
+ // history stack
+ this.history.push(true);
+
+ return {
+ container: container,
+ offset: offset,
+ prevContainer: startCon && startCon.parentNode ? startCon : null
+ };
+ },
+
+ /**
+ * @description Appended all selected format Element to the argument element and insert
+ * @param {Element} rangeElement Element of wrap the arguments (BLOCKQUOTE...)
+ */
+ applyRangeFormatElement: function (rangeElement) {
+ this.getRange_addLine(this.getRange(), null);
+ const rangeLines = this.getSelectedElementsAndComponents(false);
+ if (!rangeLines || rangeLines.length === 0) return;
+
+ linesLoop:
+ for (let i = 0, len = rangeLines.length, line, nested, fEl, lEl, f, l; i < len; i++) {
+ line = rangeLines[i];
+ if (!util.isListCell(line)) continue;
+
+ nested = line.lastElementChild;
+ if (nested && util.isListCell(line.nextElementSibling) && rangeLines.indexOf(line.nextElementSibling) > -1) {
+ lEl = nested.lastElementChild;
+ if (rangeLines.indexOf(lEl) > -1) {
+ let list = null;
+ while ((list = lEl.lastElementChild)) {
+ if (util.isList(list)) {
+ if (rangeLines.indexOf(list.lastElementChild) > -1) {
+ lEl = list.lastElementChild;
+ } else {
+ continue linesLoop;
+ }
+ }
+ }
+
+ fEl = nested.firstElementChild;
+ f = rangeLines.indexOf(fEl);
+ l = rangeLines.indexOf(lEl);
+ rangeLines.splice(f, (l - f) + 1);
+ len = rangeLines.length;
+ continue;
+ }
+ }
+ }
+
+ let last = rangeLines[rangeLines.length - 1];
+ let standTag, beforeTag, pElement;
+
+ if (util.isRangeFormatElement(last) || util.isFormatElement(last)) {
+ standTag = last;
+ } else {
+ standTag = util.getRangeFormatElement(last, null) || util.getFormatElement(last, null);
+ }
+
+ if (util.isCell(standTag)) {
+ beforeTag = null;
+ pElement = standTag;
+ } else {
+ beforeTag = standTag.nextSibling;
+ pElement = standTag.parentNode;
+ }
+
+ let parentDepth = util.getElementDepth(standTag);
+ let listParent = null;
+ const lineArr = [];
+ const removeItems = function (parent, origin, before) {
+ let cc = null;
+ if (parent !== origin && !util.isTable(origin)) {
+ if (origin && util.getElementDepth(parent) === util.getElementDepth(origin)) return before;
+ cc = util.removeItemAllParents(origin, null, parent);
+ }
+
+ return cc ? cc.ec : before;
+ };
+
+ for (let i = 0, len = rangeLines.length, line, originParent, depth, before, nextLine, nextList, nested; i < len; i++) {
+ line = rangeLines[i];
+ originParent = line.parentNode;
+ if (!originParent || rangeElement.contains(originParent)) continue;
+
+ depth = util.getElementDepth(line);
+
+ if (util.isList(originParent)) {
+ if (listParent === null) {
+ if (nextList) {
+ listParent = nextList;
+ nested = true;
+ nextList = null;
+ } else {
+ listParent = originParent.cloneNode(false);
+ }
+ }
+
+ lineArr.push(line);
+ nextLine = rangeLines[i + 1];
+
+ if (i === len - 1 || (nextLine && nextLine.parentNode !== originParent)) {
+ // nested list
+ if (nextLine && line.contains(nextLine.parentNode)) {
+ nextList = nextLine.parentNode.cloneNode(false);
+ }
+
+ let list = originParent.parentNode, p;
+ while (util.isList(list)) {
+ p = util.createElement(list.nodeName);
+ p.appendChild(listParent);
+ listParent = p;
+ list = list.parentNode;
+ }
+
+ const edge = this.detachRangeFormatElement(originParent, lineArr, null, true, true);
+
+ if (parentDepth >= depth) {
+ parentDepth = depth;
+ pElement = edge.cc;
+ beforeTag = removeItems(pElement, originParent, edge.ec);
+ if (beforeTag) pElement = beforeTag.parentNode;
+ } else if (pElement === edge.cc) {
+ beforeTag = edge.ec;
+ }
+
+ if (pElement !== edge.cc) {
+ before = removeItems(pElement, edge.cc, before);
+ if (before !== undefined) beforeTag = before;
+ else beforeTag = edge.cc;
+ }
+
+ for (let c = 0, cLen = edge.removeArray.length; c < cLen; c++) {
+ listParent.appendChild(edge.removeArray[c]);
+ }
+
+ if (!nested) rangeElement.appendChild(listParent);
+ if (nextList) edge.removeArray[edge.removeArray.length - 1].appendChild(nextList);
+ listParent = null;
+ nested = false;
+ }
+ } else {
+ if (parentDepth >= depth) {
+ parentDepth = depth;
+ pElement = originParent;
+ beforeTag = line.nextSibling;
+ }
+
+ rangeElement.appendChild(line);
+
+ if (pElement !== originParent) {
+ before = removeItems(pElement, originParent);
+ if (before !== undefined) beforeTag = before;
+ }
+ }
+ }
+
+ this.effectNode = null;
+ util.mergeSameTags(rangeElement, null, false);
+ util.mergeNestedTags(rangeElement, function (current) { return this.isList(current); }.bind(util));
+
+ // Nested list
+ if (beforeTag && util.getElementDepth(beforeTag) > 0 && (util.isList(beforeTag.parentNode) || util.isList(beforeTag.parentNode.parentNode))) {
+ const depthFormat = util.getParentElement(beforeTag, function (current) { return this.isRangeFormatElement(current) && !this.isList(current); }.bind(util));
+ const splitRange = util.splitElement(beforeTag, null, !depthFormat ? 0 : util.getElementDepth(depthFormat) + 1);
+ splitRange.parentNode.insertBefore(rangeElement, splitRange);
+ } else { // basic
+ pElement.insertBefore(rangeElement, beforeTag);
+ removeItems(rangeElement, beforeTag);
+ }
+
+ const edge = util.getEdgeChildNodes(rangeElement.firstElementChild, rangeElement.lastElementChild);
+ if (rangeLines.length > 1) {
+ this.setRange(edge.sc, 0, edge.ec, edge.ec.textContent.length);
+ } else {
+ this.setRange(edge.ec, edge.ec.textContent.length, edge.ec, edge.ec.textContent.length);
+ }
+
+ // history stack
+ this.history.push(false);
+ },
+
+ /**
+ * @description The elements of the "selectedFormats" array are detached from the "rangeElement" element. ("LI" tags are converted to "P" tags)
+ * When "selectedFormats" is null, all elements are detached and return {cc: parentNode, sc: nextSibling, ec: previousSibling, removeArray: [Array of removed elements]}.
+ * @param {Element} rangeElement Range format element (PRE, BLOCKQUOTE, OL, UL...)
+ * @param {Array|null} selectedFormats Array of format elements (P, DIV, LI...) to remove.
+ * If null, Applies to all elements and return {cc: parentNode, sc: nextSibling, ec: previousSibling}
+ * @param {Element|null} newRangeElement The node(rangeElement) to replace the currently wrapped node.
+ * @param {Boolean} remove If true, deleted without detached.
+ * @param {Boolean} notHistoryPush When true, it does not update the history stack and the selection object and return EdgeNodes (util.getEdgeChildNodes)
+ * @returns {Object}
+ */
+ detachRangeFormatElement: function (rangeElement, selectedFormats, newRangeElement, remove, notHistoryPush) {
+ const range = this.getRange();
+ const so = range.startOffset;
+ const eo = range.endOffset;
+
+ let children = util.getListChildNodes(rangeElement, function (current) { return current.parentNode === rangeElement; });
+ let parent = rangeElement.parentNode;
+ let firstNode = null;
+ let lastNode = null;
+ let rangeEl = rangeElement.cloneNode(false);
+
+ const removeArray = [];
+ const newList = util.isList(newRangeElement);
+ let insertedNew = false;
+ let reset = false;
+ let moveComplete = false;
+
+ function appendNode (parent, insNode, sibling, originNode) {
+ if (util.onlyZeroWidthSpace(insNode)) insNode.innerHTML = util.zeroWidthSpace;
+
+ if (insNode.nodeType === 3) {
+ parent.insertBefore(insNode, sibling);
+ return insNode;
+ }
+
+ const insChildren = (moveComplete ? insNode : originNode).childNodes;
+ let format = insNode.cloneNode(false);
+ let first = null;
+ let c = null;
+
+ while (insChildren[0]) {
+ c = insChildren[0];
+ if (util._notTextNode(c) && !util.isBreak(c) && !util.isListCell(format)) {
+ if (format.childNodes.length > 0) {
+ if (!first) first = format;
+ parent.insertBefore(format, sibling);
+ format = insNode.cloneNode(false);
+ }
+ parent.insertBefore(c, sibling);
+ if (!first) first = c;
+ } else {
+ format.appendChild(c);
+ }
+ }
+
+ if (format.childNodes.length > 0) {
+ if (util.isListCell(parent) && util.isListCell(format) && util.isList(sibling)) {
+ if (newList) {
+ first = sibling;
+ while(sibling) {
+ format.appendChild(sibling);
+ sibling = sibling.nextSibling;
+ }
+ parent.parentNode.insertBefore(format, parent.nextElementSibling);
+ } else {
+ const originNext = originNode.nextElementSibling;
+ const detachRange = util.detachNestedList(originNode, false);
+ if ((rangeElement !== detachRange) || (originNext !== originNode.nextElementSibling)) {
+ const fChildren = format.childNodes;
+ while (fChildren[0]) {
+ originNode.appendChild(fChildren[0]);
+ }
+
+ rangeElement = detachRange;
+ reset = true;
+ }
+ }
+ } else {
+ parent.insertBefore(format, sibling);
+ }
+
+ if (!first) first = format;
+ }
+
+ return first;
+ }
+
+ // detach loop
+ for (let i = 0, len = children.length, insNode, lineIndex, next; i < len; i++) {
+ insNode = children[i];
+ if (insNode.nodeType === 3 && util.isList(rangeEl)) continue;
+
+ moveComplete = false;
+ if (remove && i === 0) {
+ if (!selectedFormats || selectedFormats.length === len || selectedFormats[0] === insNode) {
+ firstNode = rangeElement.previousSibling;
+ } else {
+ firstNode = rangeEl;
+ }
+ }
+
+ if (selectedFormats) lineIndex = selectedFormats.indexOf(insNode);
+ if (selectedFormats && lineIndex === -1) {
+ if (!rangeEl) rangeEl = rangeElement.cloneNode(false);
+ rangeEl.appendChild(insNode);
+ } else {
+ if (selectedFormats) next = selectedFormats[lineIndex + 1];
+ if (rangeEl && rangeEl.children.length > 0) {
+ parent.insertBefore(rangeEl, rangeElement);
+ rangeEl = null;
+ }
+
+ if (!newList && util.isListCell(insNode)) {
+ if (next && util.getElementDepth(insNode) !== util.getElementDepth(next) && (util.isListCell(parent) || util.getArrayItem(insNode.children, util.isList, false))) {
+ const insNext = insNode.nextElementSibling;
+ const detachRange = util.detachNestedList(insNode, false);
+ if ((rangeElement !== detachRange) || insNext !== insNode.nextElementSibling) {
+ rangeElement = detachRange;
+ reset = true;
+ }
+ } else {
+ const inner = insNode;
+ insNode = util.createElement(remove ? inner.nodeName : (util.isList(rangeElement.parentNode) || util.isListCell(rangeElement.parentNode)) ? 'LI' : util.isCell(rangeElement.parentNode) ? 'DIV' : options.defaultTag);
+ const isCell = util.isListCell(insNode);
+ const innerChildren = inner.childNodes;
+ while (innerChildren[0]) {
+ if (util.isList(innerChildren[0]) && !isCell) break;
+ insNode.appendChild(innerChildren[0]);
+ }
+ util.copyFormatAttributes(insNode, inner);
+ moveComplete = true;
+ }
+ } else {
+ insNode = insNode.cloneNode(false);
+ }
+
+ if (!reset) {
+ if (!remove) {
+ if (newRangeElement) {
+ if (!insertedNew) {
+ parent.insertBefore(newRangeElement, rangeElement);
+ insertedNew = true;
+ }
+ insNode = appendNode(newRangeElement, insNode, null, children[i]);
+ } else {
+ insNode = appendNode(parent, insNode, rangeElement, children[i]);
+ }
+
+ if (!reset) {
+ if (selectedFormats) {
+ lastNode = insNode;
+ if (!firstNode) {
+ firstNode = insNode;
+ }
+ } else if (!firstNode) {
+ firstNode = lastNode = insNode;
+ }
+ }
+ } else {
+ removeArray.push(insNode);
+ util.removeItem(children[i]);
+ }
+
+ if (reset) {
+ reset = moveComplete = false;
+ children = util.getListChildNodes(rangeElement, function (current) { return current.parentNode === rangeElement; });
+ rangeEl = rangeElement.cloneNode(false);
+ parent = rangeElement.parentNode;
+ i = -1;
+ len = children.length;
+ continue;
+ }
+ }
+ }
+ }
+
+ const rangeParent = rangeElement.parentNode;
+ let rangeRight = rangeElement.nextSibling;
+ if (rangeEl && rangeEl.children.length > 0) {
+ rangeParent.insertBefore(rangeEl, rangeRight);
+ }
+
+ if (newRangeElement) firstNode = newRangeElement.previousSibling;
+ else if (!firstNode) firstNode = rangeElement.previousSibling;
+ rangeRight = rangeElement.nextSibling;
+
+ if (rangeElement.children.length === 0 || rangeElement.textContent.length === 0) {
+ util.removeItem(rangeElement);
+ } else {
+ util.removeEmptyNode(rangeElement, null);
+ }
+
+ let edge = null;
+ if (remove) {
+ edge = {
+ cc: rangeParent,
+ sc: firstNode,
+ ec: rangeRight,
+ removeArray: removeArray
+ };
+ } else {
+ if (!firstNode) firstNode = lastNode;
+ if (!lastNode) lastNode = firstNode;
+ const childEdge = util.getEdgeChildNodes(firstNode, (lastNode.parentNode ? firstNode : lastNode));
+ edge = {
+ cc: (childEdge.sc || childEdge.ec).parentNode,
+ sc: childEdge.sc,
+ ec: childEdge.ec
+ };
+ }
+
+ this.effectNode = null;
+ if (notHistoryPush) return edge;
+
+ if (!remove && edge) {
+ if (!selectedFormats) {
+ this.setRange(edge.sc, 0, edge.sc, 0);
+ } else {
+ this.setRange(edge.sc, so, edge.ec, eo);
+ }
+ }
+
+ // history stack
+ this.history.push(false);
+ },
+
+ /**
+ * @description "selectedFormats" array are detached from the list element.
+ * The return value is applied when the first and last lines of "selectedFormats" are "LI" respectively.
+ * @param {Array} selectedFormats Array of format elements (LI, P...) to remove.
+ * @param {Boolean} remove If true, deleted without detached.
+ * @returns {Object} {sc: <LI>, ec: <LI>}.
+ */
+ detachList: function (selectedFormats, remove) {
+ let rangeArr = {};
+ let listFirst = false;
+ let listLast = false;
+ let first = null;
+ let last = null;
+ const passComponent = function (current) { return !this.isComponent(current); }.bind(util);
+
+ for (let i = 0, len = selectedFormats.length, r, o, lastIndex, isList; i < len; i++) {
+ lastIndex = i === len - 1;
+ o = util.getRangeFormatElement(selectedFormats[i], passComponent);
+ isList = util.isList(o);
+ if (!r && isList) {
+ r = o;
+ rangeArr = {r: r, f: [util.getParentElement(selectedFormats[i], 'LI')]};
+ if (i === 0) listFirst = true;
+ } else if (r && isList) {
+ if (r !== o) {
+ const edge = this.detachRangeFormatElement(rangeArr.f[0].parentNode, rangeArr.f, null, remove, true);
+ o = selectedFormats[i].parentNode;
+ if (listFirst) {
+ first = edge.sc;
+ listFirst = false;
+ }
+ if (lastIndex) last = edge.ec;
+
+ if (isList) {
+ r = o;
+ rangeArr = {r: r, f: [util.getParentElement(selectedFormats[i], 'LI')]};
+ if (lastIndex) listLast = true;
+ } else {
+ r = null;
+ }
+ } else {
+ rangeArr.f.push(util.getParentElement(selectedFormats[i], 'LI'));
+ if (lastIndex) listLast = true;
+ }
+ }
+
+ if (lastIndex && util.isList(r)) {
+ const edge = this.detachRangeFormatElement(rangeArr.f[0].parentNode, rangeArr.f, null, remove, true);
+ if (listLast || len === 1) last = edge.ec;
+ if (listFirst) first = edge.sc || last;
+ }
+ }
+
+ return {
+ sc: first,
+ ec: last
+ };
+ },
+
+ /**
+ * @description Add, update, and delete nodes from selected text.
+ * 1. If there is a node in the "appendNode" argument, a node with the same tags and attributes as "appendNode" is added to the selection text.
+ * 2. If it is in the same tag, only the tag's attributes are changed without adding a tag.
+ * 3. If the "appendNode" argument is null, the node of the selection is update or remove without adding a new node.
+ * 4. The same style as the style attribute of the "styleArray" argument is deleted.
+ * (Styles should be put with attribute names from css. ["background-color"])
+ * 5. The same class name as the class attribute of the "styleArray" argument is deleted.
+ * (The class name is preceded by "." [".className"])
+ * 6. Use a list of styles and classes of "appendNode" in "styleArray" to avoid duplicate property values.
+ * 7. If a node with all styles and classes removed has the same tag name as "appendNode" or "removeNodeArray", or "appendNode" is null, that node is deleted.
+ * 8. Regardless of the style and class of the node, the tag with the same name as the "removeNodeArray" argument value is deleted.
+ * 9. If the "strictRemove" argument is true, only nodes with all styles and classes removed from the nodes of "removeNodeArray" are removed.
+ *10. It won't work if the parent node has the same class and same value style.
+ * However, if there is a value in "removeNodeArray", it works and the text node is separated even if there is no node to replace.
+ * @param {Element|null} appendNode The element to be added to the selection. If it is null, only delete the node.
+ * @param {Array|null} styleArray The style or className attribute name Array to check (['font-size'], ['.className'], ['font-family', 'color', '.className']...])
+ * @param {Array|null} removeNodeArray An array of node names to remove types from, remove all formats when "appendNode" is null and there is an empty array or null value. (['span'], ['strong', 'em'] ...])
+ * @param {Boolean|null} strictRemove If true, only nodes with all styles and classes removed from the nodes of "removeNodeArray" are removed.
+ */
+ nodeChange: function (appendNode, styleArray, removeNodeArray, strictRemove) {
+ this._resetRangeToTextNode();
+ let range = this.getRange_addLine(this.getRange(), null);
+ styleArray = styleArray && styleArray.length > 0 ? styleArray : false;
+ removeNodeArray = removeNodeArray && removeNodeArray.length > 0 ? removeNodeArray : false;
+
+ const isRemoveNode = !appendNode;
+ const isRemoveFormat = isRemoveNode && !removeNodeArray && !styleArray;
+ let startCon = range.startContainer;
+ let startOff = range.startOffset;
+ let endCon = range.endContainer;
+ let endOff = range.endOffset;
+
+ if ((isRemoveFormat && range.collapsed && util.isFormatElement(startCon.parentNode) && util.isFormatElement(endCon.parentNode)) || (startCon === endCon && startCon.nodeType === 1 && util.isNonEditable(startCon))) {
+ return;
+ }
+
+ if (range.collapsed && !isRemoveFormat) {
+ if (startCon.nodeType === 1 && !util.isBreak(startCon) && !util.isComponent(startCon)) {
+ let afterNode = null;
+ const focusNode = startCon.childNodes[startOff];
+
+ if (focusNode) {
+ if (!focusNode.nextSibling) {
+ afterNode = null;
+ } else {
+ afterNode = util.isBreak(focusNode) ? focusNode : focusNode.nextSibling;
+ }
+ }
+
+ const zeroWidth = util.createTextNode(util.zeroWidthSpace);
+ startCon.insertBefore(zeroWidth, afterNode);
+ this.setRange(zeroWidth, 1, zeroWidth, 1);
+
+ range = this.getRange();
+ startCon = range.startContainer;
+ startOff = range.startOffset;
+ endCon = range.endContainer;
+ endOff = range.endOffset;
+ }
+ }
+
+ if (util.isFormatElement(startCon)) {
+ startCon = startCon.childNodes[startOff] || startCon.firstChild;
+ startOff = 0;
+ }
+ if (util.isFormatElement(endCon)) {
+ endCon = endCon.childNodes[endOff] || endCon.lastChild;
+ endOff = endCon.textContent.length;
+ }
+
+ if (isRemoveNode) {
+ appendNode = util.createElement('DIV');
+ }
+
+ const wRegExp = _w.RegExp;
+ const newNodeName = appendNode.nodeName;
+
+ /* checked same style property */
+ if (!isRemoveFormat && startCon === endCon && !removeNodeArray && appendNode) {
+ let sNode = startCon;
+ let checkCnt = 0;
+ const checkAttrs = [];
+
+ const checkStyles = appendNode.style;
+ for (let i = 0, len = checkStyles.length; i < len; i++) {
+ checkAttrs.push(checkStyles[i]);
+ }
+
+ const ckeckClasses = appendNode.classList;
+ for (let i = 0, len = ckeckClasses.length; i < len; i++) {
+ checkAttrs.push('.' + ckeckClasses[i]);
+ }
+
+ if (checkAttrs.length > 0) {
+ while(!util.isFormatElement(sNode) && !util.isWysiwygDiv(sNode)) {
+ for (let i = 0; i < checkAttrs.length; i++) {
+ if (sNode.nodeType === 1) {
+ const s = checkAttrs[i];
+ const classReg = /^\./.test(s) ? new wRegExp('\\s*' + s.replace(/^\./, '') + '(\\s+|$)', 'ig') : false;
+
+ const styleCheck = isRemoveNode ? !!sNode.style[s] : (!!sNode.style[s] && !!appendNode.style[s] && sNode.style[s] === appendNode.style[s]);
+ const classCheck = classReg === false ? false : isRemoveNode ? !!sNode.className.match(classReg) : !!sNode.className.match(classReg) && !!appendNode.className.match(classReg);
+ if (styleCheck || classCheck) {
+ checkCnt++;
+ }
+ }
+ }
+ sNode = sNode.parentNode;
+ }
+
+ if (checkCnt >= checkAttrs.length) return;
+ }
+ }
+
+ let start = {}, end = {};
+ let newNode, styleRegExp = '', classRegExp = '', removeNodeRegExp = '';
+
+ if (styleArray) {
+ for (let i = 0, len = styleArray.length, s; i < len; i++) {
+ s = styleArray[i];
+ if (/^\./.test(s)) {
+ classRegExp += (classRegExp ? '|' : '\\s*(?:') + s.replace(/^\./, '');
+ } else {
+ styleRegExp += (styleRegExp ? '|' : '(?:;|^|\\s)(?:') + s;
+ }
+ }
+
+ if (styleRegExp) {
+ styleRegExp += ')\\s*:[^;]*\\s*(?:;|$)';
+ styleRegExp = new wRegExp(styleRegExp, 'ig');
+ }
+
+ if (classRegExp) {
+ classRegExp += ')(?=\\s+|$)';
+ classRegExp = new wRegExp(classRegExp, 'ig');
+ }
+ }
+
+ if (removeNodeArray) {
+ removeNodeRegExp = '^(?:' + removeNodeArray[0];
+ for (let i = 1; i < removeNodeArray.length; i++) {
+ removeNodeRegExp += '|' + removeNodeArray[i];
+ }
+ removeNodeRegExp += ')$';
+ removeNodeRegExp = new wRegExp(removeNodeRegExp, 'i');
+ }
+
+ /** validation check function*/
+ const wBoolean = _w.Boolean;
+ const _removeCheck = {v: false};
+ const validation = function (checkNode) {
+ const vNode = checkNode.cloneNode(false);
+
+ // all path
+ if (vNode.nodeType === 3 || util.isBreak(vNode)) return vNode;
+ // all remove
+ if (isRemoveFormat) return null;
+
+ // remove node check
+ const tagRemove = (!removeNodeRegExp && isRemoveNode) || (removeNodeRegExp && removeNodeRegExp.test(vNode.nodeName));
+
+ // tag remove
+ if (tagRemove && !strictRemove) {
+ _removeCheck.v = true;
+ return null;
+ }
+
+ // style regexp
+ const originStyle = vNode.style.cssText;
+ let style = '';
+ if (styleRegExp && originStyle.length > 0) {
+ style = originStyle.replace(styleRegExp, '').trim();
+ if (style !== originStyle) _removeCheck.v = true;
+ }
+
+ // class check
+ const originClasses = vNode.className;
+ let classes = '';
+ if (classRegExp && originClasses.length > 0) {
+ classes = originClasses.replace(classRegExp, '').trim();
+ if (classes !== originClasses) _removeCheck.v = true;
+ }
+
+ // remove only
+ if (isRemoveNode) {
+ if ((classRegExp || !originClasses) && (styleRegExp || !originStyle) && !style && !classes && tagRemove) {
+ _removeCheck.v = true;
+ return null;
+ }
+ }
+
+ // change
+ if (style || classes || vNode.nodeName !== newNodeName || (wBoolean(styleRegExp) !== wBoolean(originStyle)) || (wBoolean(classRegExp) !== wBoolean(originClasses))) {
+ if (styleRegExp && originStyle.length > 0) vNode.style.cssText = style;
+ if (!vNode.style.cssText) {
+ vNode.removeAttribute('style');
+ }
+
+ if (classRegExp && originClasses.length > 0) vNode.className = classes.trim();
+ if (!vNode.className.trim()) {
+ vNode.removeAttribute('class');
+ }
+
+ if (!vNode.style.cssText && !vNode.className && (vNode.nodeName === newNodeName || tagRemove)) {
+ _removeCheck.v = true;
+ return null;
+ }
+
+ return vNode;
+ }
+
+ _removeCheck.v = true;
+ return null;
+ };
+
+ // get line nodes
+ const lineNodes = this.getSelectedElements(null);
+ range = this.getRange();
+ startCon = range.startContainer;
+ startOff = range.startOffset;
+ endCon = range.endContainer;
+ endOff = range.endOffset;
+
+ if (!util.getFormatElement(startCon, null)) {
+ startCon = util.getChildElement(lineNodes[0], function (current) { return current.nodeType === 3; }, false);
+ startOff = 0;
+ }
+
+ if (!util.getFormatElement(endCon, null)) {
+ endCon = util.getChildElement(lineNodes[lineNodes.length - 1], function (current) { return current.nodeType === 3; }, false);
+ endOff = endCon.textContent.length;
+ }
+
+
+ const oneLine = util.getFormatElement(startCon, null) === util.getFormatElement(endCon, null);
+ const endLength = lineNodes.length - (oneLine ? 0 : 1);
+
+ // node Changes
+ newNode = appendNode.cloneNode(false);
+
+ const isRemoveAnchor = isRemoveFormat || (isRemoveNode && (function (arr) {
+ for (let n = 0, len = arr.length; n < len; n++) {
+ if (util._isMaintainedNode(arr[n]) || util._isSizeNode(arr[n])) return true;
+ }
+ return false;
+ })(removeNodeArray));
+
+ const isSizeNode = util._isSizeNode(newNode);
+ const _getMaintainedNode = this._util_getMaintainedNode.bind(util, isRemoveAnchor, isSizeNode);
+ const _isMaintainedNode = this._util_isMaintainedNode.bind(util, isRemoveAnchor, isSizeNode);
+
+ // one line
+ if (oneLine) {
+ const newRange = this._nodeChange_oneLine(lineNodes[0], newNode, validation, startCon, startOff, endCon, endOff, isRemoveFormat, isRemoveNode, range.collapsed, _removeCheck, _getMaintainedNode, _isMaintainedNode);
+ start.container = newRange.startContainer;
+ start.offset = newRange.startOffset;
+ end.container = newRange.endContainer;
+ end.offset = newRange.endOffset;
+ if (start.container === end.container && util.onlyZeroWidthSpace(start.container)) {
+ start.offset = end.offset = 1;
+ }
+ this._setCommonListStyle(newRange.ancestor, null);
+ } else { // multi line
+ // end
+ if (endLength > 0) {
+ newNode = appendNode.cloneNode(false);
+ end = this._nodeChange_endLine(lineNodes[endLength], newNode, validation, endCon, endOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode);
+ }
+
+ // mid
+ for (let i = endLength - 1, newRange; i > 0; i--) {
+ newNode = appendNode.cloneNode(false);
+ newRange = this._nodeChange_middleLine(lineNodes[i], newNode, validation, isRemoveFormat, isRemoveNode, _removeCheck, end.container);
+ if (newRange.endContainer) {
+ end.ancestor = null;
+ end.container = newRange.endContainer;
+ }
+ this._setCommonListStyle(newRange.ancestor, null);
+ }
+
+ // start
+ newNode = appendNode.cloneNode(false);
+ start = this._nodeChange_startLine(lineNodes[0], newNode, validation, startCon, startOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode, end.container);
+
+ if (start.endContainer) {
+ end.ancestor = null;
+ end.container = start.endContainer;
+ }
+
+ if (endLength <= 0) {
+ end = start;
+ } else if (!end.container) {
+ end.ancestor = null;
+ end.container = start.container;
+ end.offset = start.container.textContent.length;
+ }
+
+ this._setCommonListStyle(start.ancestor, null);
+ this._setCommonListStyle(end.ancestor || util.getFormatElement(end.container), null);
+ }
+
+ // set range
+ this.controllersOff();
+ this.setRange(start.container, start.offset, end.container, end.offset);
+
+ // history stack
+ this.history.push(false);
+ },
+
+ /**
+ * @description If certain styles are applied to all child nodes of the list cell, the style of the list cell is also changed. (bold, color, size)
+ * @param {Element} el List cell element. <li>
+ * @param {Element|null} child Variable for recursive call. ("null" on the first call)
+ * @private
+ */
+ _setCommonListStyle: function (el, child) {
+ if (!util.isListCell(el)) return;
+ if (!child) el.removeAttribute('style');
+
+ const children = util.getArrayItem((child || el).childNodes, function (current) { return !util.isBreak(current) && !util.onlyZeroWidthSpace(current.textContent.trim()); }, true);
+ if (children[0] && children.length === 1){
+ child = children[0];
+ if (!child || child.nodeType !== 1) return;
+
+ const childStyle = child.style;
+ const elStyle = el.style;
+
+ // bold
+ if (/STRONG/i.test(child.nodeName)) elStyle.fontWeight = 'bold'; // bold
+ else if (childStyle.fontWeight) elStyle.fontWeight = childStyle.fontWeight;
+
+ // styles
+ if (childStyle.color) elStyle.color = childStyle.color; // color
+ if (childStyle.fontSize) elStyle.fontSize = childStyle.fontSize; // size
+
+ this._setCommonListStyle(el, child);
+ }
+ },
+
+ /**
+ * @description Strip remove node
+ * @param {Node} removeNode The remove node
+ * @private
+ */
+ _stripRemoveNode: function (removeNode) {
+ const element = removeNode.parentNode;
+ if (!removeNode || removeNode.nodeType === 3 || !element) return;
+
+ const children = removeNode.childNodes;
+ while (children[0]) {
+ element.insertBefore(children[0], removeNode);
+ }
+
+ element.removeChild(removeNode);
+ },
+
+ /**
+ * @description Return the parent maintained tag. (bind and use a util object)
+ * @param {Element} element Element
+ * @returns {Element}
+ * @private
+ */
+ _util_getMaintainedNode: function (_isRemove, _isSizeNode, element) {
+ if (!element || _isRemove) return null;
+ return this.getParentElement(element, this._isMaintainedNode.bind(this)) || (!_isSizeNode ? this.getParentElement(element, this._isSizeNode.bind(this)) : null);
+ },
+
+ /**
+ * @description Check if element is a tag that should be persisted. (bind and use a util object)
+ * @param {Element} element Element
+ * @returns {Element}
+ * @private
+ */
+ _util_isMaintainedNode: function (_isRemove, _isSizeNode, element) {
+ if (!element || _isRemove || element.nodeType !== 1) return false;
+ const anchor = this._isMaintainedNode(element);
+ return this.getParentElement(element, this._isMaintainedNode.bind(this)) ? anchor : (anchor || (!_isSizeNode ? this._isSizeNode(element) : false));
+ },
+
+ /**
+ * @description wraps text nodes of line selected text.
+ * @param {Element} element The node of the line that contains the selected text node.
+ * @param {Element} newInnerNode The dom that will wrap the selected text area
+ * @param {Function} validation Check if the node should be stripped.
+ * @param {Node} startCon The startContainer property of the selection object.
+ * @param {Number} startOff The startOffset property of the selection object.
+ * @param {Node} endCon The endContainer property of the selection object.
+ * @param {Number} endOff The endOffset property of the selection object.
+ * @param {Boolean} isRemoveFormat Is the remove all formats command?
+ * @param {Boolean} isRemoveNode "newInnerNode" is remove node?
+ * @param {Boolean} collapsed range.collapsed
+ * @returns {{ancestor: *, startContainer: *, startOffset: *, endContainer: *, endOffset: *}}
+ * @private
+ */
+ _nodeChange_oneLine: function (element, newInnerNode, validation, startCon, startOff, endCon, endOff, isRemoveFormat, isRemoveNode, collapsed, _removeCheck, _getMaintainedNode, _isMaintainedNode) {
+ // not add tag
+ let parentCon = startCon.parentNode;
+ while (!parentCon.nextSibling && !parentCon.previousSibling && !util.isFormatElement(parentCon.parentNode) && !util.isWysiwygDiv(parentCon.parentNode)) {
+ if (parentCon.nodeName === newInnerNode.nodeName) break;
+ parentCon = parentCon.parentNode;
+ }
+
+ if (!isRemoveNode && parentCon === endCon.parentNode && parentCon.nodeName === newInnerNode.nodeName) {
+ if (util.onlyZeroWidthSpace(startCon.textContent.slice(0, startOff)) && util.onlyZeroWidthSpace(endCon.textContent.slice(endOff))) {
+ const children = parentCon.childNodes;
+ let sameTag = true;
+
+ for (let i = 0, len = children.length, c, s, e, z; i < len; i++) {
+ c = children[i];
+ z = !util.onlyZeroWidthSpace(c);
+ if (c === startCon) {
+ s = true;
+ continue;
+ }
+ if (c === endCon) {
+ e = true;
+ continue;
+ }
+ if ((!s && z) || (s && e && z)) {
+ sameTag = false;
+ break;
+ }
+ }
+
+ if (sameTag) {
+ util.copyTagAttributes(parentCon, newInnerNode);
+
+ return {
+ startContainer: startCon,
+ startOffset: startOff,
+ endContainer: endCon,
+ endOffset: endOff
+ };
+ }
+ }
+ }
+
+ // add tag
+ _removeCheck.v = false;
+ const el = element;
+ const nNodeArray = [newInnerNode];
+ const pNode = element.cloneNode(false);
+ const isSameNode = startCon === endCon;
+ let startContainer = startCon;
+ let startOffset = startOff;
+ let endContainer = endCon;
+ let endOffset = endOff;
+ let startPass = false;
+ let endPass = false;
+ let pCurrent, newNode, appendNode, cssText, anchorNode;
+
+ const wRegExp = _w.RegExp;
+ function checkCss (vNode) {
+ const regExp = new wRegExp('(?:;|^|\\s)(?:' + cssText + 'null)\\s*:[^;]*\\s*(?:;|$)', 'ig');
+ let style = '';
+
+ if (regExp && vNode.style.cssText.length > 0) {
+ style = regExp.test(vNode.style.cssText);
+ }
+
+ return !style;
+ }
+
+ (function recursionFunc(current, ancestor) {
+ const childNodes = current.childNodes;
+
+ for (let i = 0, len = childNodes.length, vNode; i < len; i++) {
+ let child = childNodes[i];
+ if (!child) continue;
+ let coverNode = ancestor;
+ let cloneNode;
+
+ // startContainer
+ if (!startPass && child === startContainer) {
+ let line = pNode;
+ anchorNode = _getMaintainedNode(child);
+ const prevNode = util.createTextNode(startContainer.nodeType === 1 ? '' : startContainer.substringData(0, startOffset));
+ const textNode = util.createTextNode(startContainer.nodeType === 1 ? '' : startContainer.substringData(startOffset,
+ isSameNode ?
+ (endOffset >= startOffset ? endOffset - startOffset : startContainer.data.length - startOffset) :
+ startContainer.data.length - startOffset)
+ );
+
+ if (anchorNode) {
+ const a = _getMaintainedNode(ancestor);
+ if (a && a.parentNode !== line) {
+ let m = a;
+ let p = null;
+ while (m.parentNode !== line) {
+ ancestor = p = m.parentNode.cloneNode(false);
+ while(m.childNodes[0]) {
+ p.appendChild(m.childNodes[0]);
+ }
+ m.appendChild(p);
+ m = m.parentNode;
+ }
+ m.parentNode.appendChild(a);
+ }
+ anchorNode = anchorNode.cloneNode(false);
+ }
+
+ if (!util.onlyZeroWidthSpace(prevNode)) {
+ ancestor.appendChild(prevNode);
+ }
+
+ const prevAnchorNode = _getMaintainedNode(ancestor);
+ if (!!prevAnchorNode) anchorNode = prevAnchorNode;
+ if (anchorNode) line = anchorNode;
+
+ newNode = child;
+ pCurrent = [];
+ cssText = '';
+ while (newNode !== line && newNode !== el && newNode !== null) {
+ vNode = _isMaintainedNode(newNode) ? null : validation(newNode);
+ if (vNode && newNode.nodeType === 1 && checkCss(newNode)) {
+ pCurrent.push(vNode);
+ cssText += newNode.style.cssText.substr(0, newNode.style.cssText.indexOf(':')) + '|';
+ }
+ newNode = newNode.parentNode;
+ }
+
+ const childNode = pCurrent.pop() || textNode;
+ appendNode = newNode = childNode;
+ while (pCurrent.length > 0) {
+ newNode = pCurrent.pop();
+ appendNode.appendChild(newNode);
+ appendNode = newNode;
+ }
+
+ newInnerNode.appendChild(childNode);
+ line.appendChild(newInnerNode);
+
+ if (anchorNode && !_getMaintainedNode(endContainer)) {
+ newInnerNode = newInnerNode.cloneNode(false);
+ pNode.appendChild(newInnerNode);
+ nNodeArray.push(newInnerNode);
+ }
+
+ startContainer = textNode;
+ startOffset = 0;
+ startPass = true;
+
+ if (newNode !== textNode) newNode.appendChild(startContainer);
+ if (!isSameNode) continue;
+ }
+
+ // endContainer
+ if (!endPass && child === endContainer) {
+ anchorNode = _getMaintainedNode(child);
+ const afterNode = util.createTextNode(endContainer.nodeType === 1 ? '' : endContainer.substringData(endOffset, (endContainer.length - endOffset)));
+ const textNode = util.createTextNode(isSameNode || endContainer.nodeType === 1 ? '' : endContainer.substringData(0, endOffset));
+
+ if (anchorNode) {
+ anchorNode = anchorNode.cloneNode(false);
+ } else if (_isMaintainedNode(newInnerNode.parentNode) && !anchorNode) {
+ newInnerNode = newInnerNode.cloneNode(false);
+ pNode.appendChild(newInnerNode);
+ nNodeArray.push(newInnerNode);
+ }
+
+ if (!util.onlyZeroWidthSpace(afterNode)) {
+ newNode = child;
+ cssText = '';
+ pCurrent = [];
+ const anchors = [];
+ while (newNode !== pNode && newNode !== el && newNode !== null) {
+ if (newNode.nodeType === 1 && checkCss(newNode)) {
+ if (_isMaintainedNode(newNode)) anchors.push(newNode.cloneNode(false));
+ else pCurrent.push(newNode.cloneNode(false));
+ cssText += newNode.style.cssText.substr(0, newNode.style.cssText.indexOf(':')) + '|';
+ }
+ newNode = newNode.parentNode;
+ }
+ pCurrent = pCurrent.concat(anchors);
+
+ cloneNode = appendNode = newNode = pCurrent.pop() || afterNode;
+ while (pCurrent.length > 0) {
+ newNode = pCurrent.pop();
+ appendNode.appendChild(newNode);
+ appendNode = newNode;
+ }
+
+ pNode.appendChild(cloneNode);
+ newNode.textContent = afterNode.data;
+ }
+
+ if (anchorNode && cloneNode) {
+ const afterAnchorNode = _getMaintainedNode(cloneNode);
+ if (afterAnchorNode) {
+ anchorNode = afterAnchorNode;
+ }
+ }
+
+ newNode = child;
+ pCurrent = [];
+ cssText = '';
+ while (newNode !== pNode && newNode !== el && newNode !== null) {
+ vNode = _isMaintainedNode(newNode) ? null : validation(newNode);
+ if (vNode && newNode.nodeType === 1 && checkCss(newNode)) {
+ pCurrent.push(vNode);
+ cssText += newNode.style.cssText.substr(0, newNode.style.cssText.indexOf(':')) + '|';
+ }
+ newNode = newNode.parentNode;
+ }
+
+ const childNode = pCurrent.pop() || textNode;
+ appendNode = newNode = childNode;
+ while (pCurrent.length > 0) {
+ newNode = pCurrent.pop();
+ appendNode.appendChild(newNode);
+ appendNode = newNode;
+ }
+
+ if (anchorNode) {
+ newInnerNode = newInnerNode.cloneNode(false);
+ newInnerNode.appendChild(childNode);
+ anchorNode.insertBefore(newInnerNode, anchorNode.firstChild);
+ pNode.appendChild(anchorNode);
+ nNodeArray.push(newInnerNode);
+ anchorNode = null;
+ } else {
+ newInnerNode.appendChild(childNode);
+ }
+
+ endContainer = textNode;
+ endOffset = textNode.data.length;
+ endPass = true;
+
+ if (!isRemoveFormat && collapsed) {
+ newInnerNode = textNode;
+ textNode.textContent = util.zeroWidthSpace;
+ }
+
+ if (newNode !== textNode) newNode.appendChild(endContainer);
+ continue;
+ }
+
+ // other
+ if (startPass) {
+ if (child.nodeType === 1 && !util.isBreak(child)) {
+ if (util._isIgnoreNodeChange(child)) {
+ pNode.appendChild(child.cloneNode(true));
+ if (!collapsed) {
+ newInnerNode = newInnerNode.cloneNode(false);
+ pNode.appendChild(newInnerNode);
+ nNodeArray.push(newInnerNode);
+ }
+ } else {
+ recursionFunc(child, child);
+ }
+ continue;
+ }
+
+ newNode = child;
+ pCurrent = [];
+ cssText = '';
+ const anchors = [];
+ while (newNode.parentNode !== null && newNode !== el && newNode !== newInnerNode) {
+ vNode = endPass ? newNode.cloneNode(false) : validation(newNode);
+ if (newNode.nodeType === 1 && !util.isBreak(child) && vNode && checkCss(newNode)) {
+ if (_isMaintainedNode(newNode)) {
+ if (!anchorNode) anchors.push(vNode);
+ } else {
+ pCurrent.push(vNode);
+ }
+ cssText += newNode.style.cssText.substr(0, newNode.style.cssText.indexOf(':')) + '|';
+ }
+ newNode = newNode.parentNode;
+ }
+ pCurrent = pCurrent.concat(anchors);
+
+ const childNode = pCurrent.pop() || child;
+ appendNode = newNode = childNode;
+ while (pCurrent.length > 0) {
+ newNode = pCurrent.pop();
+ appendNode.appendChild(newNode);
+ appendNode = newNode;
+ }
+
+ if (_isMaintainedNode(newInnerNode.parentNode) && !_isMaintainedNode(childNode)) {
+ newInnerNode = newInnerNode.cloneNode(false);
+ pNode.appendChild(newInnerNode);
+ nNodeArray.push(newInnerNode);
+ }
+
+ if (!endPass && !anchorNode && _isMaintainedNode(childNode)) {
+ newInnerNode = newInnerNode.cloneNode(false);
+ const aChildren = childNode.childNodes;
+ for (let a = 0, aLen = aChildren.length; a < aLen; a++) {
+ newInnerNode.appendChild(aChildren[a]);
+ }
+ childNode.appendChild(newInnerNode);
+ pNode.appendChild(childNode);
+ nNodeArray.push(newInnerNode);
+ if (newInnerNode.children.length > 0) ancestor = newNode;
+ else ancestor = newInnerNode;
+ } else if (childNode === child) {
+ if (!endPass) ancestor = newInnerNode;
+ else ancestor = pNode;
+ } else if (endPass) {
+ pNode.appendChild(childNode);
+ ancestor = newNode;
+ } else {
+ newInnerNode.appendChild(childNode);
+ ancestor = newNode;
+ }
+
+ if (anchorNode && child.nodeType === 3) {
+ if (_getMaintainedNode(child)) {
+ const ancestorAnchorNode = util.getParentElement(ancestor, function (current) {return this._isMaintainedNode(current.parentNode) || current.parentNode === pNode;}.bind(util));
+ anchorNode.appendChild(ancestorAnchorNode);
+ newInnerNode = ancestorAnchorNode.cloneNode(false);
+ nNodeArray.push(newInnerNode);
+ pNode.appendChild(newInnerNode);
+ } else {
+ anchorNode = null;
+ }
+ }
+ }
+
+ cloneNode = child.cloneNode(false);
+ ancestor.appendChild(cloneNode);
+ if (child.nodeType === 1 && !util.isBreak(child)) coverNode = cloneNode;
+
+ recursionFunc(child, coverNode);
+ }
+ })(element, pNode);
+
+ // not remove tag
+ if (isRemoveNode && !isRemoveFormat && !_removeCheck.v) {
+ return {
+ ancestor: element,
+ startContainer: startCon,
+ startOffset: startOff,
+ endContainer: endCon,
+ endOffset: endOff
+ };
+ }
+
+ isRemoveFormat = isRemoveFormat && isRemoveNode;
+
+ if (isRemoveFormat) {
+ for (let i = 0; i < nNodeArray.length; i++) {
+ let removeNode = nNodeArray[i];
+ let textNode, textNode_s, textNode_e;
+
+ if (collapsed) {
+ textNode = util.createTextNode(util.zeroWidthSpace);
+ pNode.replaceChild(textNode, removeNode);
+ } else {
+ const rChildren = removeNode.childNodes;
+ textNode_s = rChildren[0];
+ while (rChildren[0]) {
+ textNode_e = rChildren[0];
+ pNode.insertBefore(textNode_e, removeNode);
+ }
+ util.removeItem(removeNode);
+ }
+
+ if (i === 0) {
+ if (collapsed) {
+ startContainer = endContainer = textNode;
+ } else {
+ startContainer = textNode_s;
+ endContainer = textNode_e;
+ }
+ }
+ }
+ } else {
+ if (isRemoveNode) {
+ for (let i = 0; i < nNodeArray.length; i++) {
+ this._stripRemoveNode(nNodeArray[i]);
+ }
+ }
+
+ if (collapsed) {
+ startContainer = endContainer = newInnerNode;
+ }
+ }
+
+ util.removeEmptyNode(pNode, newInnerNode);
+
+ if (collapsed) {
+ startOffset = startContainer.textContent.length;
+ endOffset = endContainer.textContent.length;
+ }
+
+ // endContainer reset
+ const endConReset = isRemoveFormat || endContainer.textContent.length === 0;
+
+ if (!util.isBreak(endContainer) && endContainer.textContent.length === 0) {
+ util.removeItem(endContainer);
+ endContainer = startContainer;
+ }
+ endOffset = endConReset ? endContainer.textContent.length : endOffset;
+
+ // node change
+ const newStartOffset = {s: 0, e: 0};
+ const startPath = util.getNodePath(startContainer, pNode, newStartOffset);
+
+ const mergeEndCon = !endContainer.parentNode;
+ if (mergeEndCon) endContainer = startContainer;
+ const newEndOffset = {s: 0, e: 0};
+ const endPath = util.getNodePath(endContainer , pNode, (!mergeEndCon && !endConReset) ? newEndOffset : null);
+
+ startOffset += newStartOffset.s;
+ endOffset = (collapsed ? startOffset : mergeEndCon ? startContainer.textContent.length : endConReset ? endOffset + newStartOffset.s : endOffset + newEndOffset.s);
+
+ // tag merge
+ const newOffsets = util.mergeSameTags(pNode, [startPath, endPath], true);
+
+ element.parentNode.replaceChild(pNode, element);
+
+ startContainer = util.getNodeFromPath(startPath, pNode);
+ endContainer = util.getNodeFromPath(endPath, pNode);
+
+ return {
+ ancestor: pNode,
+ startContainer: startContainer,
+ startOffset: startOffset + newOffsets[0],
+ endContainer: endContainer,
+ endOffset: endOffset + newOffsets[1]
+ };
+ },
+
+ /**
+ * @description wraps first line selected text.
+ * @param {Element} element The node of the line that contains the selected text node.
+ * @param {Element} newInnerNode The dom that will wrap the selected text area
+ * @param {Function} validation Check if the node should be stripped.
+ * @param {Node} startCon The startContainer property of the selection object.
+ * @param {Number} startOff The startOffset property of the selection object.
+ * @param {Boolean} isRemoveFormat Is the remove all formats command?
+ * @param {Boolean} isRemoveNode "newInnerNode" is remove node?
+ * @returns {null|Node} If end container is renewed, returned renewed node
+ * @returns {Object} { ancestor, container, offset, endContainer }
+ * @private
+ */
+ _nodeChange_startLine: function (element, newInnerNode, validation, startCon, startOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode, _endContainer) {
+ // not add tag
+ let parentCon = startCon.parentNode;
+ while (!parentCon.nextSibling && !parentCon.previousSibling && !util.isFormatElement(parentCon.parentNode) && !util.isWysiwygDiv(parentCon.parentNode)) {
+ if (parentCon.nodeName === newInnerNode.nodeName) break;
+ parentCon = parentCon.parentNode;
+ }
+
+ if (!isRemoveNode && parentCon.nodeName === newInnerNode.nodeName && !util.isFormatElement(parentCon) && !parentCon.nextSibling && util.onlyZeroWidthSpace(startCon.textContent.slice(0, startOff))) {
+ let sameTag = true;
+ let s = startCon.previousSibling;
+ while (s) {
+ if (!util.onlyZeroWidthSpace(s)) {
+ sameTag = false;
+ break;
+ }
+ s = s.previousSibling;
+ }
+
+ if (sameTag) {
+ util.copyTagAttributes(parentCon, newInnerNode);
+
+ return {
+ ancestor: element,
+ container: startCon,
+ offset: startOff
+ };
+ }
+ }
+
+ // add tag
+ _removeCheck.v = false;
+ const el = element;
+ const nNodeArray = [newInnerNode];
+ const pNode = element.cloneNode(false);
+
+ let container = startCon;
+ let offset = startOff;
+ let passNode = false;
+ let pCurrent, newNode, appendNode, anchorNode;
+
+ (function recursionFunc(current, ancestor) {
+ const childNodes = current.childNodes;
+
+ for (let i = 0, len = childNodes.length, vNode, cloneChild; i < len; i++) {
+ const child = childNodes[i];
+ if (!child) continue;
+ let coverNode = ancestor;
+
+ if (passNode && !util.isBreak(child)) {
+ if (child.nodeType === 1) {
+ if (util._isIgnoreNodeChange(child)) {
+ newInnerNode = newInnerNode.cloneNode(false);
+ cloneChild = child.cloneNode(true);
+ pNode.appendChild(cloneChild);
+ pNode.appendChild(newInnerNode);
+ nNodeArray.push(newInnerNode);
+
+ // end container
+ if (_endContainer && child.contains(_endContainer)) {
+ const endPath = util.getNodePath(_endContainer, child);
+ _endContainer = util.getNodeFromPath(endPath, cloneChild);
+ }
+ } else {
+ recursionFunc(child, child);
+ }
+ continue;
+ }
+
+ newNode = child;
+ pCurrent = [];
+ const anchors = [];
+ while (newNode.parentNode !== null && newNode !== el && newNode !== newInnerNode) {
+ vNode = validation(newNode);
+ if (newNode.nodeType === 1 && vNode) {
+ if (_isMaintainedNode(newNode)) {
+ if (!anchorNode) anchors.push(vNode);
+ } else {
+ pCurrent.push(vNode);
+ }
+ }
+ newNode = newNode.parentNode;
+ }
+ pCurrent = pCurrent.concat(anchors);
+
+ const isTopNode = pCurrent.length > 0;
+ const childNode = pCurrent.pop() || child;
+ appendNode = newNode = childNode;
+ while (pCurrent.length > 0) {
+ newNode = pCurrent.pop();
+ appendNode.appendChild(newNode);
+ appendNode = newNode;
+ }
+
+ if (_isMaintainedNode(newInnerNode.parentNode) && !_isMaintainedNode(childNode)) {
+ newInnerNode = newInnerNode.cloneNode(false);
+ pNode.appendChild(newInnerNode);
+ nNodeArray.push(newInnerNode);
+ }
+
+ if (!anchorNode && _isMaintainedNode(childNode)) {
+ newInnerNode = newInnerNode.cloneNode(false);
+ const aChildren = childNode.childNodes;
+ for (let a = 0, aLen = aChildren.length; a < aLen; a++) {
+ newInnerNode.appendChild(aChildren[a]);
+ }
+ childNode.appendChild(newInnerNode);
+ pNode.appendChild(childNode);
+ ancestor = !_isMaintainedNode(newNode) ? newNode : newInnerNode;
+ nNodeArray.push(newInnerNode);
+ } else if (isTopNode) {
+ newInnerNode.appendChild(childNode);
+ ancestor = newNode;
+ } else {
+ ancestor = newInnerNode;
+ }
+
+ if (anchorNode && child.nodeType === 3) {
+ if (_getMaintainedNode(child)) {
+ const ancestorAnchorNode = util.getParentElement(ancestor, function (current) {return this._isMaintainedNode(current.parentNode) || current.parentNode === pNode;}.bind(util));
+ anchorNode.appendChild(ancestorAnchorNode);
+ newInnerNode = ancestorAnchorNode.cloneNode(false);
+ nNodeArray.push(newInnerNode);
+ pNode.appendChild(newInnerNode);
+ } else {
+ anchorNode = null;
+ }
+ }
+ }
+
+ // startContainer
+ if (!passNode && child === container) {
+ let line = pNode;
+ anchorNode = _getMaintainedNode(child);
+ const prevNode = util.createTextNode(container.nodeType === 1 ? '' : container.substringData(0, offset));
+ const textNode = util.createTextNode(container.nodeType === 1 ? '' : container.substringData(offset, (container.length - offset)));
+
+ if (anchorNode) {
+ const a = _getMaintainedNode(ancestor);
+ if (a && a.parentNode !== line) {
+ let m = a;
+ let p = null;
+ while (m.parentNode !== line) {
+ ancestor = p = m.parentNode.cloneNode(false);
+ while(m.childNodes[0]) {
+ p.appendChild(m.childNodes[0]);
+ }
+ m.appendChild(p);
+ m = m.parentNode;
+ }
+ m.parentNode.appendChild(a);
+ }
+ anchorNode = anchorNode.cloneNode(false);
+ }
+
+ if (!util.onlyZeroWidthSpace(prevNode)) {
+ ancestor.appendChild(prevNode);
+ }
+
+ const prevAnchorNode = _getMaintainedNode(ancestor);
+ if (!!prevAnchorNode) anchorNode = prevAnchorNode;
+ if (anchorNode) line = anchorNode;
+
+ newNode = ancestor;
+ pCurrent = [];
+ while (newNode !== line && newNode !== null) {
+ vNode = validation(newNode);
+ if (newNode.nodeType === 1 && vNode) {
+ pCurrent.push(vNode);
+ }
+ newNode = newNode.parentNode;
+ }
+
+ const childNode = pCurrent.pop() || ancestor;
+ appendNode = newNode = childNode;
+ while (pCurrent.length > 0) {
+ newNode = pCurrent.pop();
+ appendNode.appendChild(newNode);
+ appendNode = newNode;
+ }
+
+ if (childNode !== ancestor) {
+ newInnerNode.appendChild(childNode);
+ ancestor = newNode;
+ } else {
+ ancestor = newInnerNode;
+ }
+
+ if (util.isBreak(child)) newInnerNode.appendChild(child.cloneNode(false));
+ line.appendChild(newInnerNode);
+
+ container = textNode;
+ offset = 0;
+ passNode = true;
+
+ ancestor.appendChild(container);
+ continue;
+ }
+
+ vNode = !passNode ? child.cloneNode(false) : validation(child);
+ if (vNode) {
+ ancestor.appendChild(vNode);
+ if (child.nodeType === 1 && !util.isBreak(child)) coverNode = vNode;
+ }
+
+ recursionFunc(child, coverNode);
+ }
+ })(element, pNode);
+
+ // not remove tag
+ if (isRemoveNode && !isRemoveFormat && !_removeCheck.v) {
+ return {
+ ancestor: element,
+ container: startCon,
+ offset: startOff,
+ endContainer: _endContainer
+ };
+ }
+
+ isRemoveFormat = isRemoveFormat && isRemoveNode;
+
+ if (isRemoveFormat) {
+ for (let i = 0; i < nNodeArray.length; i++) {
+ let removeNode = nNodeArray[i];
+
+ const rChildren = removeNode.childNodes;
+ const textNode = rChildren[0];
+ while (rChildren[0]) {
+ pNode.insertBefore(rChildren[0], removeNode);
+ }
+ util.removeItem(removeNode);
+
+ if (i === 0) container = textNode;
+ }
+ } else if (isRemoveNode) {
+ newInnerNode = newInnerNode.firstChild;
+ for (let i = 0; i < nNodeArray.length; i++) {
+ this._stripRemoveNode(nNodeArray[i]);
+ }
+ }
+
+ if (!isRemoveFormat && pNode.childNodes.length === 0) {
+ if (element.childNodes) {
+ container = element.childNodes[0];
+ } else {
+ container = util.createTextNode(util.zeroWidthSpace);
+ element.appendChild(container);
+ }
+ } else {
+ util.removeEmptyNode(pNode, newInnerNode);
+
+ if (util.onlyZeroWidthSpace(pNode.textContent)) {
+ container = pNode.firstChild;
+ offset = 0;
+ }
+
+ // node change
+ const offsets = {s: 0, e: 0};
+ const path = util.getNodePath(container, pNode, offsets);
+ offset += offsets.s;
+
+ // tag merge
+ const newOffsets = util.mergeSameTags(pNode, [path], true);
+
+ element.parentNode.replaceChild(pNode, element);
+
+ container = util.getNodeFromPath(path, pNode);
+ offset += newOffsets[0];
+ }
+
+ return {
+ ancestor: pNode,
+ container: container,
+ offset: offset,
+ endContainer: _endContainer
+ };
+ },
+
+ /**
+ * @description wraps mid lines selected text.
+ * @param {Element} element The node of the line that contains the selected text node.
+ * @param {Element} newInnerNode The dom that will wrap the selected text area
+ * @param {Function} validation Check if the node should be stripped.
+ * @param {Boolean} isRemoveFormat Is the remove all formats command?
+ * @param {Boolean} isRemoveNode "newInnerNode" is remove node?
+ * @param {Node} _endContainer Offset node of last line already modified (end.container)
+ * @returns {Object} { ancestor, endContainer: "If end container is renewed, returned renewed node" }
+ * @private
+ */
+ _nodeChange_middleLine: function (element, newInnerNode, validation, isRemoveFormat, isRemoveNode, _removeCheck, _endContainer) {
+ // not add tag
+ if (!isRemoveNode) {
+ // end container path
+ let endPath = null;
+ if (_endContainer && element.contains(_endContainer)) endPath = util.getNodePath(_endContainer, element);
+
+ const tempNode = element.cloneNode(true);
+ const newNodeName = newInnerNode.nodeName;
+ const newCssText = newInnerNode.style.cssText;
+ const newClass = newInnerNode.className;
+
+ let children = tempNode.childNodes;
+ let i = 0, len = children.length;
+ for (let child; i < len; i++) {
+ child = children[i];
+ if (child.nodeType === 3) break;
+ if (child.nodeName === newNodeName) {
+ child.style.cssText += newCssText;
+ util.addClass(child, newClass);
+ } else if (!util.isBreak(child) && util._isIgnoreNodeChange(child)) {
+ continue;
+ } else if (len === 1) {
+ children = child.childNodes;
+ len = children.length;
+ i = -1;
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ if (len > 0 && i === len) {
+ element.innerHTML = tempNode.innerHTML;
+ return {
+ ancestor: element,
+ endContainer: endPath ? util.getNodeFromPath(endPath, element) : null
+ };
+ }
+ }
+
+ // add tag
+ _removeCheck.v = false;
+ const pNode = element.cloneNode(false);
+ const nNodeArray = [newInnerNode];
+ let noneChange = true;
+
+ (function recursionFunc(current, ancestor) {
+ const childNodes = current.childNodes;
+
+ for (let i = 0, len = childNodes.length, vNode, cloneChild; i < len; i++) {
+ let child = childNodes[i];
+ if (!child) continue;
+ let coverNode = ancestor;
+
+ if (!util.isBreak(child) && util._isIgnoreNodeChange(child)) {
+ if (newInnerNode.childNodes.length > 0) {
+ pNode.appendChild(newInnerNode);
+ newInnerNode = newInnerNode.cloneNode(false);
+ }
+
+ cloneChild = child.cloneNode(true);
+ pNode.appendChild(cloneChild);
+ pNode.appendChild(newInnerNode);
+ nNodeArray.push(newInnerNode);
+ ancestor = newInnerNode;
+
+ // end container
+ if (_endContainer && child.contains(_endContainer)) {
+ const endPath = util.getNodePath(_endContainer, child);
+ _endContainer = util.getNodeFromPath(endPath, cloneChild);
+ }
+
+ continue;
+ } else {
+ vNode = validation(child);
+ if (vNode) {
+ noneChange = false;
+ ancestor.appendChild(vNode);
+ if (child.nodeType === 1) coverNode = vNode;
+ }
+ }
+
+ if (!util.isBreak(child)) recursionFunc(child, coverNode);
+ }
+ })(element, newInnerNode);
+
+ // not remove tag
+ if (noneChange || (isRemoveNode && !isRemoveFormat && !_removeCheck.v)) return { ancestor: element, endContainer: _endContainer };
+
+ pNode.appendChild(newInnerNode);
+
+ if (isRemoveFormat && isRemoveNode) {
+ for (let i = 0; i < nNodeArray.length; i++) {
+ let removeNode = nNodeArray[i];
+
+ const rChildren = removeNode.childNodes;
+ while (rChildren[0]) {
+ pNode.insertBefore(rChildren[0], removeNode);
+ }
+ util.removeItem(removeNode);
+ }
+ } else if (isRemoveNode) {
+ newInnerNode = newInnerNode.firstChild;
+ for (let i = 0; i < nNodeArray.length; i++) {
+ this._stripRemoveNode(nNodeArray[i]);
+ }
+ }
+
+ util.removeEmptyNode(pNode, newInnerNode);
+ util.mergeSameTags(pNode, null, true);
+
+ // node change
+ element.parentNode.replaceChild(pNode, element);
+ return { ancestor: pNode, endContainer: _endContainer };
+ },
+
+ /**
+ * @description wraps last line selected text.
+ * @param {Element} element The node of the line that contains the selected text node.
+ * @param {Element} newInnerNode The dom that will wrap the selected text area
+ * @param {Function} validation Check if the node should be stripped.
+ * @param {Node} endCon The endContainer property of the selection object.
+ * @param {Number} endOff The endOffset property of the selection object.
+ * @param {Boolean} isRemoveFormat Is the remove all formats command?
+ * @param {Boolean} isRemoveNode "newInnerNode" is remove node?
+ * @returns {Object} { ancestor, container, offset }
+ * @private
+ */
+ _nodeChange_endLine: function (element, newInnerNode, validation, endCon, endOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode) {
+ // not add tag
+ let parentCon = endCon.parentNode;
+ while (!parentCon.nextSibling && !parentCon.previousSibling && !util.isFormatElement(parentCon.parentNode) && !util.isWysiwygDiv(parentCon.parentNode)) {
+ if (parentCon.nodeName === newInnerNode.nodeName) break;
+ parentCon = parentCon.parentNode;
+ }
+
+ if (!isRemoveNode && parentCon.nodeName === newInnerNode.nodeName && !util.isFormatElement(parentCon) && !parentCon.previousSibling && util.onlyZeroWidthSpace(endCon.textContent.slice(endOff))) {
+ let sameTag = true;
+ let e = endCon.nextSibling;
+ while (e) {
+ if (!util.onlyZeroWidthSpace(e)) {
+ sameTag = false;
+ break;
+ }
+ e = e.nextSibling;
+ }
+
+ if (sameTag) {
+ util.copyTagAttributes(parentCon, newInnerNode);
+
+ return {
+ ancestor: element,
+ container: endCon,
+ offset: endOff
+ };
+ }
+ }
+
+ // add tag
+ _removeCheck.v = false;
+ const el = element;
+ const nNodeArray = [newInnerNode];
+ const pNode = element.cloneNode(false);
+
+ let container = endCon;
+ let offset = endOff;
+ let passNode = false;
+ let pCurrent, newNode, appendNode, anchorNode;
+
+ (function recursionFunc(current, ancestor) {
+ const childNodes = current.childNodes;
+
+ for (let i = childNodes.length - 1, vNode; 0 <= i; i--) {
+ const child = childNodes[i];
+ if (!child) continue;
+ let coverNode = ancestor;
+
+ if (passNode && !util.isBreak(child)) {
+ if (child.nodeType === 1) {
+ if (util._isIgnoreNodeChange(child)) {
+ newInnerNode = newInnerNode.cloneNode(false);
+ const cloneChild = child.cloneNode(true);
+ pNode.insertBefore(cloneChild, ancestor);
+ pNode.insertBefore(newInnerNode, cloneChild);
+ nNodeArray.push(newInnerNode);
+ } else {
+ recursionFunc(child, child);
+ }
+ continue;
+ }
+
+ newNode = child;
+ pCurrent = [];
+ const anchors = [];
+ while (newNode.parentNode !== null && newNode !== el && newNode !== newInnerNode) {
+ vNode = validation(newNode);
+ if (vNode && newNode.nodeType === 1) {
+ if (_isMaintainedNode(newNode)) {
+ if (!anchorNode) anchors.push(vNode);
+ } else {
+ pCurrent.push(vNode);
+ }
+ }
+ newNode = newNode.parentNode;
+ }
+ pCurrent = pCurrent.concat(anchors);
+
+ const isTopNode = pCurrent.length > 0;
+ const childNode = pCurrent.pop() || child;
+ appendNode = newNode = childNode;
+ while (pCurrent.length > 0) {
+ newNode = pCurrent.pop();
+ appendNode.appendChild(newNode);
+ appendNode = newNode;
+ }
+
+ if (_isMaintainedNode(newInnerNode.parentNode) && !_isMaintainedNode(childNode)) {
+ newInnerNode = newInnerNode.cloneNode(false);
+ pNode.insertBefore(newInnerNode, pNode.firstChild);
+ nNodeArray.push(newInnerNode);
+ }
+
+ if (!anchorNode && _isMaintainedNode(childNode)) {
+ newInnerNode = newInnerNode.cloneNode(false);
+ const aChildren = childNode.childNodes;
+ for (let a = 0, aLen = aChildren.length; a < aLen; a++) {
+ newInnerNode.appendChild(aChildren[a]);
+ }
+ childNode.appendChild(newInnerNode);
+ pNode.insertBefore(childNode, pNode.firstChild);
+ nNodeArray.push(newInnerNode);
+ if (newInnerNode.children.length > 0) ancestor = newNode;
+ else ancestor = newInnerNode;
+ } else if (isTopNode) {
+ newInnerNode.insertBefore(childNode, newInnerNode.firstChild);
+ ancestor = newNode;
+ } else {
+ ancestor = newInnerNode;
+ }
+
+ if (anchorNode && child.nodeType === 3) {
+ if (_getMaintainedNode(child)) {
+ const ancestorAnchorNode = util.getParentElement(ancestor, function (current) {return this._isMaintainedNode(current.parentNode) || current.parentNode === pNode;}.bind(util));
+ anchorNode.appendChild(ancestorAnchorNode);
+ newInnerNode = ancestorAnchorNode.cloneNode(false);
+ nNodeArray.push(newInnerNode);
+ pNode.insertBefore(newInnerNode, pNode.firstChild);
+ } else {
+ anchorNode = null;
+ }
+ }
+ }
+
+ // endContainer
+ if (!passNode && child === container) {
+ anchorNode = _getMaintainedNode(child);
+ const afterNode = util.createTextNode(container.nodeType === 1 ? '' : container.substringData(offset, (container.length - offset)));
+ const textNode = util.createTextNode(container.nodeType === 1 ? '' : container.substringData(0, offset));
+
+ if (anchorNode) {
+ anchorNode = anchorNode.cloneNode(false);
+ const a = _getMaintainedNode(ancestor);
+ if (a && a.parentNode !== pNode) {
+ let m = a;
+ let p = null;
+ while (m.parentNode !== pNode) {
+ ancestor = p = m.parentNode.cloneNode(false);
+ while(m.childNodes[0]) {
+ p.appendChild(m.childNodes[0]);
+ }
+ m.appendChild(p);
+ m = m.parentNode;
+ }
+ m.parentNode.insertBefore(a, m.parentNode.firstChild);
+ }
+ anchorNode = anchorNode.cloneNode(false);
+ } else if (_isMaintainedNode(newInnerNode.parentNode) && !anchorNode) {
+ newInnerNode = newInnerNode.cloneNode(false);
+ pNode.appendChild(newInnerNode);
+ nNodeArray.push(newInnerNode);
+ }
+
+ if (!util.onlyZeroWidthSpace(afterNode)) {
+ ancestor.insertBefore(afterNode, ancestor.firstChild);
+ }
+
+ newNode = ancestor;
+ pCurrent = [];
+ while (newNode !== pNode && newNode !== null) {
+ vNode = _isMaintainedNode(newNode) ? null : validation(newNode);
+ if (vNode && newNode.nodeType === 1) {
+ pCurrent.push(vNode);
+ }
+ newNode = newNode.parentNode;
+ }
+
+ const childNode = pCurrent.pop() || ancestor;
+ appendNode = newNode = childNode;
+ while (pCurrent.length > 0) {
+ newNode = pCurrent.pop();
+ appendNode.appendChild(newNode);
+ appendNode = newNode;
+ }
+
+ if (childNode !== ancestor) {
+ newInnerNode.insertBefore(childNode, newInnerNode.firstChild);
+ ancestor = newNode;
+ } else {
+ ancestor = newInnerNode;
+ }
+
+ if (util.isBreak(child)) newInnerNode.appendChild(child.cloneNode(false));
+
+ if (anchorNode) {
+ anchorNode.insertBefore(newInnerNode, anchorNode.firstChild);
+ pNode.insertBefore(anchorNode, pNode.firstChild);
+ anchorNode = null;
+ } else {
+ pNode.insertBefore(newInnerNode, pNode.firstChild);
+ }
+
+ container = textNode;
+ offset = textNode.data.length;
+ passNode = true;
+
+ ancestor.insertBefore(container, ancestor.firstChild);
+ continue;
+ }
+
+ vNode = !passNode ? child.cloneNode(false) : validation(child);
+ if (vNode) {
+ ancestor.insertBefore(vNode, ancestor.firstChild);
+ if (child.nodeType === 1 && !util.isBreak(child)) coverNode = vNode;
+ }
+
+ recursionFunc(child, coverNode);
+ }
+ })(element, pNode);
+
+ // not remove tag
+ if (isRemoveNode && !isRemoveFormat && !_removeCheck.v) {
+ return {
+ ancestor: element,
+ container: endCon,
+ offset: endOff
+ };
+ }
+
+ isRemoveFormat = isRemoveFormat && isRemoveNode;
+
+ if (isRemoveFormat) {
+ for (let i = 0; i < nNodeArray.length; i++) {
+ let removeNode = nNodeArray[i];
+
+ const rChildren = removeNode.childNodes;
+ let textNode = null;
+ while (rChildren[0]) {
+ textNode = rChildren[0];
+ pNode.insertBefore(textNode, removeNode);
+ }
+ util.removeItem(removeNode);
+
+ if (i === nNodeArray.length - 1) {
+ container = textNode;
+ offset = textNode.textContent.length;
+ }
+ }
+ } else if (isRemoveNode) {
+ newInnerNode = newInnerNode.firstChild;
+ for (let i = 0; i < nNodeArray.length; i++) {
+ this._stripRemoveNode(nNodeArray[i]);
+ }
+ }
+
+ if (!isRemoveFormat && pNode.childNodes.length === 0) {
+ if (element.childNodes) {
+ container = element.childNodes[0];
+ } else {
+ container = util.createTextNode(util.zeroWidthSpace);
+ element.appendChild(container);
+ }
+ } else {
+ if (!isRemoveNode && newInnerNode.textContent.length === 0) {
+ util.removeEmptyNode(pNode, null);
+ return {
+ ancestor: null,
+ container: null,
+ offset: 0
+ };
+ }
+
+ util.removeEmptyNode(pNode, newInnerNode);
+
+ if (util.onlyZeroWidthSpace(pNode.textContent)) {
+ container = pNode.firstChild;
+ offset = container.textContent.length;
+ } else if (util.onlyZeroWidthSpace(container)) {
+ container = newInnerNode;
+ offset = 1;
+ }
+
+ // node change
+ const offsets = {s: 0, e: 0};
+ const path = util.getNodePath(container, pNode, offsets);
+ offset += offsets.s;
+
+ // tag merge
+ const newOffsets = util.mergeSameTags(pNode, [path], true);
+
+ element.parentNode.replaceChild(pNode, element);
+
+ container = util.getNodeFromPath(path, pNode);
+ offset += newOffsets[0];
+ }
+
+ return {
+ ancestor: pNode,
+ container: container,
+ offset: offset
+ };
+ },
+
+ /**
+ * @description Run plugin calls and basic commands.
+ * @param {String} command Command string
+ * @param {String} display Display type string ('command', 'submenu', 'dialog', 'container')
+ * @param {Element} target The element of command button
+ */
+ actionCall: function (command, display, target) {
+ // call plugins
+ if (display) {
+ if (/more/i.test(display) && target !== this._moreLayerActiveButton) {
+ const layer = context.element.toolbar.querySelector('.' + command);
+ if (layer) {
+ if (this._moreLayerActiveButton) {
+ (context.element.toolbar.querySelector('.' + this._moreLayerActiveButton.getAttribute('data-command'))).style.display = 'none';
+ util.removeClass(this._moreLayerActiveButton, 'on');
+ }
+ util.addClass(target, 'on');
+ this._moreLayerActiveButton = target;
+ layer.style.display = 'block';
+
+ event._showToolbarBalloon();
+ event._showToolbarInline();
+ }
+ return;
+ } else if (/submenu/.test(display) && (this._menuTray[command] === null || target !== this.submenuActiveButton)) {
+ this.callPlugin(command, this.submenuOn.bind(this, target), target);
+ return;
+ } else if (/dialog/.test(display)) {
+ this.callPlugin(command, this.plugins[command].open.bind(this), target);
+ return;
+ } else if (/command/.test(display)) {
+ this.callPlugin(command, this.plugins[command].action.bind(this), target);
+ } else if (/container/.test(display) && (this._menuTray[command] === null || target !== this.containerActiveButton)) {
+ this.callPlugin(command, this.containerOn.bind(this, target), target);
+ return;
+ } else if (/fileBrowser/.test(display)) {
+ this.callPlugin(command, this.plugins[command].open.bind(this, null), target);
+ }
+ } // default command
+ else if (command) {
+ this.commandHandler(target, command);
+ }
+
+ if (/more/i.test(display)) {
+ const layer = context.element.toolbar.querySelector('.' + this._moreLayerActiveButton.getAttribute('data-command'));
+ if (layer) {
+ util.removeClass(this._moreLayerActiveButton, 'on');
+ this._moreLayerActiveButton = null;
+ layer.style.display = 'none';
+
+ event._showToolbarBalloon();
+ event._showToolbarInline();
+ }
+ } else if (/submenu/.test(display)) {
+ this.submenuOff();
+ } else {
+ this.submenuOff();
+ this.containerOff();
+ }
+ },
+
+ /**
+ * @description Execute command of command button(All Buttons except submenu and dialog)
+ * (selectAll, codeView, fullScreen, indent, outdent, undo, redo, removeFormat, print, preview, showBlocks, save, bold, underline, italic, strike, subscript, superscript)
+ * @param {Element|null} target The element of command button
+ * @param {String} command Property of command button (data-value)
+ */
+ commandHandler: function (target, command) {
+ switch (command) {
+ case 'selectAll':
+ const wysiwyg = context.element.wysiwyg;
+ const first = util.getChildElement(wysiwyg.firstChild, function (current) { return current.childNodes.length === 0 || current.nodeType === 3; }, false) || wysiwyg.firstChild;
+ const last = util.getChildElement(wysiwyg.lastChild, function (current) { return current.childNodes.length === 0 || current.nodeType === 3; }, true) || wysiwyg.lastChild;
+ if (!first || !last) return;
+ this.setRange(first, 0, last, last.textContent.length);
+ break;
+ case 'codeView':
+ this.toggleCodeView();
+ break;
+ case 'fullScreen':
+ this.toggleFullScreen(target);
+ break;
+ case 'indent':
+ case 'outdent':
+ this.indent(command);
+ break;
+ case 'undo':
+ this.history.undo();
+ break;
+ case 'redo':
+ this.history.redo();
+ break;
+ case 'removeFormat':
+ this.removeFormat();
+ this.focus();
+ break;
+ case 'print':
+ this.print();
+ break;
+ case 'preview':
+ this.preview();
+ break;
+ case 'showBlocks':
+ this.toggleDisplayBlocks();
+ break;
+ case 'save':
+ if (typeof options.callBackSave === 'function') {
+ options.callBackSave(this.getContents(false));
+ } else if (typeof functions.save === 'function') {
+ functions.save();
+ } else {
+ throw Error('[SUNEDITOR.core.commandHandler.fail] Please register call back function in creation option. (callBackSave : Function)');
+ }
+
+ if (context.tool.save) context.tool.save.setAttribute('disabled', true);
+ break;
+ default : // 'STRONG', 'U', 'EM', 'DEL', 'SUB', 'SUP'..
+ command = this._defaultCommand[command.toLowerCase()] || command;
+ if (!this.commandMap[command]) this.commandMap[command] = target;
+
+ const nodesMap = this._variable.currentNodesMap;
+ const cmd = nodesMap.indexOf(command) > -1 ? null : util.createElement(command);
+ let removeNode = command;
+
+ if (/^SUB$/i.test(command) && nodesMap.indexOf('SUP') > -1) {
+ removeNode = 'SUP';
+ } else if (/^SUP$/i.test(command) && nodesMap.indexOf('SUB') > -1) {
+ removeNode = 'SUB';
+ }
+
+ this.nodeChange(cmd, null, [removeNode], false);
+ this.focus();
+ }
+ },
+
+ /**
+ * @description Remove format of the currently selected range
+ */
+ removeFormat: function () {
+ this.nodeChange(null, null, null, null);
+ },
+
+ /**
+ * @description This method implements indentation to selected range.
+ * Setted "margin-left" to "25px" in the top "P" tag of the parameter node.
+ * @param {String} command Separator ("indent" or "outdent")
+ */
+ indent: function (command) {
+ const range = this.getRange();
+ const rangeLines = this.getSelectedElements(null);
+ const cells = [];
+ const shift = 'indent' !== command;
+ const marginDir = options.rtl ? 'marginRight' : 'marginLeft';
+ let sc = range.startContainer;
+ let ec = range.endContainer;
+ let so = range.startOffset;
+ let eo = range.endOffset;
+
+ for (let i = 0, len = rangeLines.length, f, margin; i < len; i++) {
+ f = rangeLines[i];
+
+ if (!util.isListCell(f) || !this.plugins.list) {
+ margin = /\d+/.test(f.style[marginDir]) ? util.getNumber(f.style[marginDir], 0) : 0;
+ if (shift) {
+ margin -= 25;
+ } else {
+ margin += 25;
+ }
+ util.setStyle(f, marginDir, (margin <= 0 ? '' : margin + 'px'));
+ } else {
+ if (shift || f.previousElementSibling) {
+ cells.push(f);
+ }
+ }
+ }
+
+ // list cells
+ if (cells.length > 0) {
+ this.plugins.list.editInsideList.call(this, shift, cells);
+ }
+
+ this.effectNode = null;
+ this.setRange(sc, so, ec, eo);
+
+ // history stack
+ this.history.push(false);
+ },
+
+ /**
+ * @description Add or remove the class name of "body" so that the code block is visible
+ */
+ toggleDisplayBlocks: function () {
+ const wysiwyg = context.element.wysiwyg;
+ util.toggleClass(wysiwyg, 'se-show-block');
+ if (util.hasClass(wysiwyg, 'se-show-block')) {
+ util.addClass(this._styleCommandMap.showBlocks, 'active');
+ } else {
+ util.removeClass(this._styleCommandMap.showBlocks, 'active');
+ }
+ this._resourcesStateChange();
+ },
+
+ /**
+ * @description Changes to code view or wysiwyg view
+ */
+ toggleCodeView: function () {
+ const isCodeView = this._variable.isCodeView;
+ this.controllersOff();
+ util.setDisabledButtons(!isCodeView, this.codeViewDisabledButtons);
+
+ if (isCodeView) {
+ this._setCodeDataToEditor();
+ context.element.wysiwygFrame.scrollTop = 0;
+ context.element.code.style.display = 'none';
+ context.element.wysiwygFrame.style.display = 'block';
+
+ this._variable._codeOriginCssText = this._variable._codeOriginCssText.replace(/(\s?display(\s+)?:(\s+)?)[a-zA-Z]+(?=;)/, 'display: none');
+ this._variable._wysiwygOriginCssText = this._variable._wysiwygOriginCssText.replace(/(\s?display(\s+)?:(\s+)?)[a-zA-Z]+(?=;)/, 'display: block');
+
+ if (options.height === 'auto' && !options.codeMirrorEditor) context.element.code.style.height = '0px';
+
+ this._variable.isCodeView = false;
+
+ if (!this._variable.isFullScreen) {
+ this._notHideToolbar = false;
+ if (/balloon|balloon-always/i.test(options.mode)) {
+ context.element._arrow.style.display = '';
+ this._isInline = false;
+ this._isBalloon = true;
+ event._hideToolbar();
+ }
+ }
+
+ this.nativeFocus();
+ util.removeClass(this._styleCommandMap.codeView, 'active');
+
+ // history stack
+ this.history.push(false);
+ } else {
+ this._setEditorDataToCodeView();
+ this._variable._codeOriginCssText = this._variable._codeOriginCssText.replace(/(\s?display(\s+)?:(\s+)?)[a-zA-Z]+(?=;)/, 'display: block');
+ this._variable._wysiwygOriginCssText = this._variable._wysiwygOriginCssText.replace(/(\s?display(\s+)?:(\s+)?)[a-zA-Z]+(?=;)/, 'display: none');
+
+ if (options.height === 'auto' && !options.codeMirrorEditor) context.element.code.style.height = context.element.code.scrollHeight > 0 ? (context.element.code.scrollHeight + 'px') : 'auto';
+ if (options.codeMirrorEditor) options.codeMirrorEditor.refresh();
+
+ this._variable.isCodeView = true;
+
+ if (!this._variable.isFullScreen) {
+ this._notHideToolbar = true;
+ if (this._isBalloon) {
+ context.element._arrow.style.display = 'none';
+ context.element.toolbar.style.left = '';
+ this._isInline = true;
+ this._isBalloon = false;
+ event._showToolbarInline();
+ }
+ }
+
+ this._variable._range = null;
+ context.element.code.focus();
+ util.addClass(this._styleCommandMap.codeView, 'active');
+ }
+
+ this._checkPlaceholder();
+
+ if (typeof functions.toggleCodeView === 'function') functions.toggleCodeView(this._variable.isCodeView, this);
+ },
+
+ /**
+ * @description Convert the data of the code view and put it in the WYSIWYG area.
+ * @private
+ */
+ _setCodeDataToEditor: function () {
+ const code_html = this._getCodeView();
+
+ if (options.fullPage) {
+ const parseDocument = this._parser.parseFromString(code_html, 'text/html');
+ const headChildren = parseDocument.head.children;
+
+ for (let i = 0, len = headChildren.length; i < len; i++) {
+ if (/^script$/i.test(headChildren[i].tagName)) {
+ parseDocument.head.removeChild(headChildren[i]);
+ i--, len--;
+ }
+ }
+
+ this._wd.head.innerHTML = parseDocument.head.innerHTML;
+ this._wd.body.innerHTML = this.convertContentsForEditor(parseDocument.body.innerHTML);
+
+ const attrs = parseDocument.body.attributes;
+ for (let i = 0, len = attrs.length; i < len; i++) {
+ if (attrs[i].name === 'contenteditable') continue;
+ this._wd.body.setAttribute(attrs[i].name, attrs[i].value);
+ }
+ if (!util.hasClass(this._wd.body, 'sun-editor-editable')) {
+ const editableClasses = options._editableClass.split(' ');
+ for (let i = 0; i < editableClasses.length; i++) {
+ util.addClass(this._wd.body, options._editableClass[i]);
+ }
+ }
+ } else {
+ context.element.wysiwyg.innerHTML = code_html.length > 0 ? this.convertContentsForEditor(code_html) : '<' + options.defaultTag + '><br></' + options.defaultTag + '>';
+ }
+ },
+
+ /**
+ * @description Convert the data of the WYSIWYG area and put it in the code view area.
+ * @private
+ */
+ _setEditorDataToCodeView: function () {
+ const codeContents = this.convertHTMLForCodeView(context.element.wysiwyg);
+ let codeValue = '';
+
+ if (options.fullPage) {
+ const attrs = util.getAttributesToString(this._wd.body, null);
+ codeValue = '<!DOCTYPE html>\n<html>\n' + this._wd.head.outerHTML.replace(/>(?!\n)/g, '>\n') + '<body ' + attrs + '>\n' + codeContents + '</body>\n</html>';
+ } else {
+ codeValue = codeContents;
+ }
+
+ context.element.code.style.display = 'block';
+ context.element.wysiwygFrame.style.display = 'none';
+
+ this._setCodeView(codeValue);
+ },
+
+ /**
+ * @description Changes to full screen or default screen
+ * @param {Element} element full screen button
+ */
+ toggleFullScreen: function (element) {
+ const topArea = context.element.topArea;
+ const toolbar = context.element.toolbar;
+ const editorArea = context.element.editorArea;
+ const wysiwygFrame = context.element.wysiwygFrame;
+ const code = context.element.code;
+ const _var = this._variable;
+ this.controllersOff();
+
+ if (!_var.isFullScreen) {
+ _var.isFullScreen = true;
+
+ _var._fullScreenAttrs.inline = this._isInline;
+ _var._fullScreenAttrs.balloon = this._isBalloon;
+
+ if (this._isInline || this._isBalloon) {
+ this._isInline = false;
+ this._isBalloon = false;
+ }
+
+ if (!!options.toolbarContainer) context.element.relative.insertBefore(toolbar, editorArea);
+
+ topArea.style.position = 'fixed';
+ topArea.style.top = '0';
+ topArea.style.left = '0';
+ topArea.style.width = '100%';
+ topArea.style.maxWidth = '100%';
+ topArea.style.height = '100%';
+ topArea.style.zIndex = '2147483647';
+
+ if (context.element._stickyDummy.style.display !== ('none' && '')) {
+ _var._fullScreenAttrs.sticky = true;
+ context.element._stickyDummy.style.display = 'none';
+ util.removeClass(toolbar, 'se-toolbar-sticky');
+ }
+
+ _var._bodyOverflow = _d.body.style.overflow;
+ _d.body.style.overflow = 'hidden';
+
+ _var._editorAreaOriginCssText = editorArea.style.cssText;
+ _var._wysiwygOriginCssText = wysiwygFrame.style.cssText;
+ _var._codeOriginCssText = code.style.cssText;
+
+ editorArea.style.cssText = toolbar.style.cssText = '';
+ wysiwygFrame.style.cssText = (wysiwygFrame.style.cssText.match(/\s?display(\s+)?:(\s+)?[a-zA-Z]+;/) || [''])[0];
+ code.style.cssText = (code.style.cssText.match(/\s?display(\s+)?:(\s+)?[a-zA-Z]+;/) || [''])[0];
+ toolbar.style.width = wysiwygFrame.style.height = code.style.height = '100%';
+ toolbar.style.position = 'relative';
+ toolbar.style.display = 'block';
+
+ _var.innerHeight_fullScreen = (_w.innerHeight - toolbar.offsetHeight);
+ editorArea.style.height = _var.innerHeight_fullScreen + 'px';
+
+ util.changeElement(element.firstElementChild, icons.reduction);
+
+ if (options.iframe && options.height === 'auto') {
+ editorArea.style.overflow = 'auto';
+ this._iframeAutoHeight();
+ }
+
+ util.addClass(this._styleCommandMap.fullScreen, 'active');
+ } else {
+ _var.isFullScreen = false;
+
+ wysiwygFrame.style.cssText = _var._wysiwygOriginCssText;
+ code.style.cssText = _var._codeOriginCssText;
+ toolbar.style.cssText = '';
+ editorArea.style.cssText = _var._editorAreaOriginCssText;
+ topArea.style.cssText = _var._originCssText;
+ _d.body.style.overflow = _var._bodyOverflow;
+
+ if (!!options.toolbarContainer) options.toolbarContainer.appendChild(toolbar);
+
+ if (options.stickyToolbar > -1) {
+ util.removeClass(toolbar, 'se-toolbar-sticky');
+ }
+
+ if (_var._fullScreenAttrs.sticky && !options.toolbarContainer) {
+ _var._fullScreenAttrs.sticky = false;
+ context.element._stickyDummy.style.display = 'block';
+ util.addClass(toolbar, "se-toolbar-sticky");
+ }
+
+ this._isInline = _var._fullScreenAttrs.inline;
+ this._isBalloon = _var._fullScreenAttrs.balloon;
+ if (this._isInline) event._showToolbarInline();
+ if (!!options.toolbarContainer) util.removeClass(toolbar, 'se-toolbar-balloon');
+
+ event.onScroll_window();
+ util.changeElement(element.firstElementChild, icons.expansion);
+
+ util.removeClass(this._styleCommandMap.fullScreen, 'active');
+ }
+
+ if (typeof functions.toggleFullScreen === 'function') functions.toggleFullScreen(this._variable.isFullScreen, this);
+ },
+
+ /**
+ * @description Prints the current contents of the editor.
+ */
+ print: function () {
+ const iframe = util.createElement('IFRAME');
+ iframe.style.display = 'none';
+ _d.body.appendChild(iframe);
+
+ const printDocument = util.getIframeDocument(iframe);
+ const contentsHTML = this.getContents(true);
+ const wDoc = this._wd;
+
+ if (options.iframe) {
+ const arrts = options.fullPage ? util.getAttributesToString(wDoc.body, ['contenteditable']) : 'class="' + options._editableClass + '"';
+
+ printDocument.write('' +
+ '<!DOCTYPE html><html>' +
+ '<head>' +
+ wDoc.head.innerHTML +
+ '</head>' +
+ '<body ' + arrts + '>' + contentsHTML + '</body>' +
+ '</html>'
+ );
+ } else {
+ const links = _d.head.getElementsByTagName('link');
+ const styles = _d.head.getElementsByTagName('style');
+ let linkHTML = '';
+ for (let i = 0, len = links.length; i < len; i++) {
+ linkHTML += links[i].outerHTML;
+ }
+ for (let i = 0, len = styles.length; i < len; i++) {
+ linkHTML += styles[i].outerHTML;
+ }
+
+ printDocument.write('' +
+ '<!DOCTYPE html><html>' +
+ '<head>' +
+ linkHTML +
+ '</head>' +
+ '<body class="' + options._editableClass + '">' + contentsHTML + '</body>' +
+ '</html>'
+ );
+ }
+
+ this.showLoading();
+ _w.setTimeout(function () {
+ try {
+ iframe.focus();
+ // IE or Edge
+ if (util.isIE_Edge || !!_d.documentMode || !!_w.StyleMedia) {
+ try {
+ iframe.contentWindow.document.execCommand('print', false, null);
+ } catch (e) {
+ iframe.contentWindow.print();
+ }
+ } else {
+ // Other browsers
+ iframe.contentWindow.print();
+ }
+ } catch (error) {
+ throw Error('[SUNEDITOR.core.print.fail] error: ' + error);
+ } finally {
+ core.closeLoading();
+ util.removeItem(iframe);
+ }
+ }, 1000);
+ },
+
+ /**
+ * @description Open the preview window.
+ */
+ preview: function () {
+ core.submenuOff();
+ core.containerOff();
+ core.controllersOff();
+
+ const contentsHTML = options.previewTemplate ? options.previewTemplate.replace(/\{\{\s*contents\s*\}\}/i, this.getContents(true)) : this.getContents(true);
+ const windowObject = _w.open('', '_blank');
+ windowObject.mimeType = 'text/html';
+ const w = context.element.wysiwygFrame.offsetWidth + 'px !important';
+ const wDoc = this._wd;
+
+ if (options.iframe) {
+ const arrts = options.fullPage ? util.getAttributesToString(wDoc.body, ['contenteditable']) : 'class="' + options._editableClass + '"';
+
+ windowObject.document.write('' +
+ '<!DOCTYPE html><html>' +
+ '<head>' +
+ wDoc.head.innerHTML +
+ '<style>body {overflow:auto !important; width:' + w + '; border:1px solid #ccc; margin: 10px auto !important; height:auto !important;}</style>' +
+ '</head>' +
+ '<body ' + arrts + '>' + contentsHTML + '</body>' +
+ '</html>'
+ );
+ } else {
+ const links = _d.head.getElementsByTagName('link');
+ const styles = _d.head.getElementsByTagName('style');
+ let linkHTML = '';
+ for (let i = 0, len = links.length; i < len; i++) {
+ linkHTML += links[i].outerHTML;
+ }
+ for (let i = 0, len = styles.length; i < len; i++) {
+ linkHTML += styles[i].outerHTML;
+ }
+
+ windowObject.document.write('' +
+ '<!DOCTYPE html><html>' +
+ '<head>' +
+ '<meta charset="utf-8" />' +
+ '<meta name="viewport" content="width=device-width, initial-scale=1">' +
+ '<title>' + lang.toolbar.preview + '</title>' +
+ linkHTML +
+ '</head>' +
+ '<body class="' + options._editableClass + '" style="width:' + w + '; border:1px solid #ccc; margin:10px auto !important; height:auto !important;">' + contentsHTML + '</body>' +
+ '</html>'
+ );
+ }
+ },
+
+ /**
+ * @description Sets the HTML string
+ * @param {String|undefined} html HTML string
+ */
+ setContents: function (html) {
+ this.removeRange();
+
+ const convertValue = (html === null || html === undefined) ? '' : this.convertContentsForEditor(html);
+ this._resetComponents();
+
+ if (!this._variable.isCodeView) {
+ context.element.wysiwyg.innerHTML = convertValue;
+ // history stack
+ this.history.push(false);
+ } else {
+ const value = this.convertHTMLForCodeView(convertValue);
+ this._setCodeView(value);
+ }
+ },
+
+ /**
+ * @description Sets the contents of the iframe's head tag and body tag when using the "iframe" or "fullPage" option.
+ * @param {Object} ctx { head: HTML string, body: HTML string}
+ */
+ setIframeContents: function (ctx) {
+ if (!options.iframe) return false;
+ if (ctx.head) this._wd.head.innerHTML = ctx.head.replace(/<script\s*.*>.*<\/script>/g, '');
+ if (ctx.body) this._wd.body.innerHTML = this.convertContentsForEditor(ctx.body);
+ },
+
+ /**
+ * @description Gets the current contents
+ * @param {Boolean} onlyContents Return only the contents of the body without headers when the "fullPage" option is true
+ * @returns {Object}
+ */
+ getContents: function (onlyContents) {
+ const contents = context.element.wysiwyg.innerHTML;
+ const renderHTML = util.createElement('DIV');
+ renderHTML.innerHTML = contents;
+
+ const figcaptions = util.getListChildren(renderHTML, function (current) {
+ return /FIGCAPTION/i.test(current.nodeName);
+ });
+
+ for (let i = 0, len = figcaptions.length; i < len; i++) {
+ figcaptions[i].removeAttribute('contenteditable');
+ }
+
+ if (options.fullPage && !onlyContents) {
+ const attrs = util.getAttributesToString(this._wd.body, ['contenteditable']);
+ return '<!DOCTYPE html><html>' + this._wd.head.outerHTML + '<body ' + attrs + '>' + renderHTML.innerHTML + '</body></html>';
+ } else {
+ return renderHTML.innerHTML;
+ }
+ },
+
+ /**
+ * @description Returns HTML string according to tag type and configuration.
+ * Use only "cleanHTML"
+ * @param {Node} node Node
+ * @param {Boolean} requireFormat If true, text nodes that do not have a format node is wrapped with the format tag.
+ * @private
+ */
+ _makeLine: function (node, requireFormat) {
+ const defaultTag = options.defaultTag;
+ // element
+ if (node.nodeType === 1) {
+ if (util._disallowedTags(node)) return '';
+ if (!requireFormat || (util.isFormatElement(node) || util.isRangeFormatElement(node) || util.isComponent(node) || util.isMedia(node) || (util.isAnchor(node) && util.isMedia(node.firstElementChild)))) {
+ return node.outerHTML;
+ } else {
+ return '<' + defaultTag + '>' + node.outerHTML + '</' + defaultTag + '>';
+ }
+ }
+ // text
+ if (node.nodeType === 3) {
+ if (!requireFormat) return node.textContent;
+ const textArray = node.textContent.split(/\n/g);
+ let html = '';
+ for (let i = 0, tLen = textArray.length, text; i < tLen; i++) {
+ text = textArray[i].trim();
+ if (text.length > 0) html += '<' + defaultTag + '>' + text + '</' + defaultTag + '>';
+ }
+ return html;
+ }
+ // comments
+ if (node.nodeType === 8 && this._allowHTMLComments) {
+ return '<!--' + node.textContent.trim() + '-->';
+ }
+
+ return '';
+ },
+
+ /**
+ * @description Removes attribute values such as style and converts tags that do not conform to the "html5" standard.
+ * @param {String} text
+ * @returns {String} HTML string
+ * @private
+ */
+ _tagConvertor: function (text) {
+ if (!this._disallowedTextTagsRegExp) return text;
+
+ const ec = {'b': 'strong', 'i': 'em', 'ins': 'u', 'strike': 'del', 's': 'del'};
+ return text.replace(this._disallowedTextTagsRegExp, function (m, t, n) {
+ return t + (typeof ec[n] === 'string' ? ec[n] : n);
+ });
+ },
+
+ /**
+ * @description Delete disallowed tags
+ * @param {String} html HTML string
+ * @returns {String}
+ * @private
+ */
+ _deleteDisallowedTags: function (html) {
+ return html
+ .replace(/\n/g, '')
+ .replace(/<(script|style).*>(\n|.)*<\/(script|style)>/gi, '')
+ .replace(/<[a-z0-9]+\:[a-z0-9]+[^>^\/]*>[^>]*<\/[a-z0-9]+\:[a-z0-9]+>/gi, '')
+ .replace(this.editorTagsWhitelistRegExp, '');
+ },
+
+ /**
+ * @description Gets the clean HTML code for editor
+ * @param {String} html HTML string
+ * @param {String|RegExp|null} whitelist Regular expression of allowed tags.
+ * RegExp object is create by util.createTagsWhitelist method. (core.pasteTagsWhitelistRegExp)
+ * @returns {String}
+ */
+ cleanHTML: function (html, whitelist) {
+ html = this._deleteDisallowedTags(html)
+ .replace(/(<[a-zA-Z0-9]+)[^>]*(?=>)/g, function (m, t) {
+ if (/^<[a-z0-9]+\:[a-z0-9]+/i.test(m)) return m;
+
+ let v = null;
+ const tAttr = this._attributesTagsWhitelist[t.match(/(?!<)[a-zA-Z0-9]+/)[0].toLowerCase()];
+ if (tAttr) v = m.match(tAttr);
+ else v = m.match(this._attributesWhitelistRegExp);
+
+ if (/<span/i.test(t) && (!v || !/style=/i.test(v.toString()))) {
+ const sv = m.match(/style\s*=\s*"[^"]*"/);
+ if (sv) {
+ if (!v) v = [];
+ v.push(sv[0]);
+ }
+ }
+
+ if (v) {
+ for (let i = 0, len = v.length; i < len; i++) {
+ if (/^class="(?!(__se__|se-|katex))/.test(v[i])) continue;
+ t += ' ' + v[i];
+ }
+ }
+
+ return t;
+ }.bind(this));
+
+ const dom = _d.createRange().createContextualFragment(html);
+ try {
+ util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp);
+ } catch (error) {
+ console.warn('[SUNEDITOR.cleanHTML.consistencyCheck.fail] ' + error);
+ }
+
+ if (this.managedTagsInfo && this.managedTagsInfo.query) {
+ const textCompList = dom.querySelectorAll(this.managedTagsInfo.query);
+ for (let i = 0, len = textCompList.length, initMethod, classList; i < len; i++) {
+ classList = [].slice.call(textCompList[i].classList);
+ for (let c = 0, cLen = classList.length; c < cLen; c++) {
+ initMethod = this.managedTagsInfo.map[classList[c]];
+ if (initMethod) {
+ initMethod(textCompList[i]);
+ break;
+ }
+ }
+ }
+ }
+
+ const domTree = dom.childNodes;
+ let cleanHTML = '';
+ let requireFormat = false;
+
+ for (let i = 0, len = domTree.length, t; i < len; i++) {
+ t = domTree[i];
+ if (t.nodeType === 1 && !util.isTextStyleElement(t) && !util.isBreak(t) && !util._disallowedTags(t)) {
+ requireFormat = true;
+ break;
+ }
+ }
+
+ for (let i = 0, len = domTree.length; i < len; i++) {
+ cleanHTML += this._makeLine(domTree[i], requireFormat);
+ }
+
+ cleanHTML = util.htmlRemoveWhiteSpace(cleanHTML);
+ return this._tagConvertor(!cleanHTML ? html : !whitelist ? cleanHTML : cleanHTML.replace(typeof whitelist === 'string' ? util.createTagsWhitelist(whitelist) : whitelist, ''));
+ },
+
+ /**
+ * @description Converts contents into a format that can be placed in an editor
+ * @param {String} contents contents
+ * @returns {String}
+ */
+ convertContentsForEditor: function (contents) {
+ contents = this._deleteDisallowedTags(contents)
+ .replace(/(<[a-zA-Z0-9]+)[^>]*(?=>)/g, function (m, t) {
+ if (/^<[a-z0-9]+\:[a-z0-9]+/i.test(m)) return m;
+
+ let v = null;
+ const tAttr = this._attributesTagsWhitelist[t.match(/(?!<)[a-zA-Z0-9]+/)[0].toLowerCase()];
+ if (tAttr) v = m.match(tAttr);
+ else v = m.match(this._attributesWhitelistRegExp);
+
+ if (/<span/i.test(t) && (!v || !/style=/i.test(v.toString()))) {
+ const sv = m.match(/style\s*=\s*"[^"]*"/);
+ if (sv) {
+ if (!v) v = [];
+ v.push(sv[0]);
+ }
+ }
+
+ if (v) {
+ for (let i = 0, len = v.length; i < len; i++) {
+ t += ' ' + v[i];
+ }
+ }
+
+ return t;
+ }.bind(this));
+
+ const dom = _d.createRange().createContextualFragment(this._deleteDisallowedTags(contents));
+
+ try {
+ util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp);
+ } catch (error) {
+ console.warn('[SUNEDITOR.convertContentsForEditor.consistencyCheck.fail] ' + error);
+ }
+
+ const domTree = dom.childNodes;
+ let cleanHTML = '';
+ for (let i = 0, len = domTree.length; i < len; i++) {
+ cleanHTML += this._makeLine(domTree[i], true);
+ }
+
+ if (cleanHTML.length === 0) return '<' + options.defaultTag + '><br></' + options.defaultTag + '>';
+
+ cleanHTML = util.htmlRemoveWhiteSpace(cleanHTML);
+ return this._tagConvertor(cleanHTML);
+ },
+
+ /**
+ * @description Converts wysiwyg area element into a format that can be placed in an editor of code view mode
+ * @param {Element|String} html WYSIWYG element (context.element.wysiwyg) or HTML string.
+ * @returns {String}
+ */
+ convertHTMLForCodeView: function (html) {
+ let returnHTML = '';
+ const wRegExp = _w.RegExp;
+ const brReg = new wRegExp('^(BLOCKQUOTE|PRE|TABLE|THEAD|TBODY|TR|TH|TD|OL|UL|IMG|IFRAME|VIDEO|AUDIO|FIGURE|FIGCAPTION|HR|BR|CANVAS|SELECT)$', 'i');
+ const isFormatElement = util.isFormatElement.bind(util);
+ const wDoc = typeof html === 'string' ? _d.createRange().createContextualFragment(html) : html;
+
+ let indentSize = this._variable.codeIndent * 1;
+ indentSize = indentSize > 0 ? new _w.Array(indentSize + 1).join(' ') : '';
+
+ (function recursionFunc (element, indent, lineBR) {
+ const children = element.childNodes;
+ const elementRegTest = brReg.test(element.nodeName);
+ const elementIndent = (elementRegTest ? indent : '');
+
+ for (let i = 0, len = children.length, node, br, nodeRegTest; i < len; i++) {
+ node = children[i];
+ nodeRegTest = brReg.test(node.nodeName);
+ br = nodeRegTest ? '\n' : '';
+ lineBR = isFormatElement(node) && !elementRegTest && !/^(TH|TD)$/i.test(element.nodeName) ? '\n' : '';
+
+ if (node.nodeType === 8) {
+ returnHTML += '\n<!-- ' + node.textContent.trim() + ' -->' + br;
+ continue;
+ }
+ if (node.nodeType === 3) {
+ returnHTML += util._HTMLConvertor((/^\n+$/.test(node.data) ? '' : node.data));
+ continue;
+ }
+ if (node.childNodes.length === 0) {
+ returnHTML += (/^HR$/i.test(node.nodeName) ? '\n' : '') + elementIndent + node.outerHTML + br;
+ continue;
+ }
+
+ node.innerHTML = node.innerHTML;
+ const tag = node.nodeName.toLowerCase();
+ returnHTML += (lineBR || (elementRegTest ? '' : br)) + (elementIndent || nodeRegTest ? indent : '') + node.outerHTML.match(wRegExp('<' + tag + '[^>]*>', 'i'))[0] + br;
+ recursionFunc(node, indent + indentSize, '');
+ returnHTML += (nodeRegTest ? indent : '') + '</' + tag + '>' + (lineBR || br || elementRegTest ? '\n' : '' || /^(TH|TD)$/i.test(node.nodeName) ? '\n' : '');
+ }
+ }(wDoc, '', '\n'));
+
+ return returnHTML.trim() + '\n';
+ },
+
+ /**
+ * @description Add an event to document.
+ * When created as an Iframe, the same event is added to the document in the Iframe.
+ * @param {String} type Event type
+ * @param {Function} listener Event listener
+ * @param {Boolean} useCapture Use event capture
+ */
+ addDocEvent: function (type, listener, useCapture) {
+ _d.addEventListener(type, listener, useCapture);
+ if (options.iframe) {
+ this._wd.addEventListener(type, listener);
+ }
+ },
+
+ /**
+ * @description Remove events from document.
+ * When created as an Iframe, the event of the document inside the Iframe is also removed.
+ * @param {String} type Event type
+ * @param {Function} listener Event listener
+ */
+ removeDocEvent: function (type, listener) {
+ _d.removeEventListener(type, listener);
+ if (options.iframe) {
+ this._wd.removeEventListener(type, listener);
+ }
+ },
+
+ /**
+ * @description The current number of characters is counted and displayed.
+ * @param {String} inputText Text added.
+ * @returns {Boolean}
+ * @private
+ */
+ _charCount: function (inputText) {
+ const maxCharCount = options.maxCharCount;
+ const countType = options.charCounterType;
+ let nextCharCount = 0;
+ if (!!inputText) nextCharCount = this.getCharLength(inputText, countType);
+
+ this._setCharCount();
+
+ if (maxCharCount > 0) {
+ let over = false;
+ const count = functions.getCharCount(countType);
+
+ if (count > maxCharCount) {
+ over = true;
+ if (nextCharCount > 0) {
+ this._editorRange();
+ const range = this.getRange();
+ const endOff = range.endOffset - 1;
+ const text = this.getSelectionNode().textContent;
+ const slicePosition = range.endOffset - (count - maxCharCount);
+
+ this.getSelectionNode().textContent = text.slice(0, slicePosition < 0 ? 0 : slicePosition) + text.slice(range.endOffset, text.length);
+ this.setRange(range.endContainer, endOff, range.endContainer, endOff);
+ }
+ } else if ((count + nextCharCount) > maxCharCount) {
+ over = true;
+ }
+
+ if (over) {
+ this._callCounterBlink();
+ if (nextCharCount > 0) return false;
+ }
+ }
+
+ return true;
+ },
+
+ /**
+ * @description When "element" is added, if it is greater than "options.maxCharCount", false is returned.
+ * @param {Node|String} element Element node or String.
+ * @param {String|null} charCounterType charCounterType. If it is null, the options.charCounterType
+ * @returns {Boolean}
+ */
+ checkCharCount: function (element, charCounterType) {
+ if (options.maxCharCount) {
+ const countType = charCounterType || options.charCounterType;
+ const length = this.getCharLength((typeof element === 'string' ? element : this._charTypeHTML ? element.outerHTML : element.textContent), countType);
+ if (length > 0 && length + functions.getCharCount(countType) > options.maxCharCount) {
+ this._callCounterBlink();
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /**
+ * @description Get the length of the content.
+ * Depending on the option, the length of the character is taken. (charCounterType)
+ * @param {String} content Content to count
+ * @param {String} charCounterType options.charCounterType
+ * @returns {Number}
+ */
+ getCharLength: function (content, charCounterType) {
+ return /byte/.test(charCounterType) ? util.getByteLength(content) : content.length;
+ },
+
+ /**
+ * @description Set the char count to charCounter element textContent.
+ * @private
+ */
+ _setCharCount: function () {
+ if (context.element.charCounter) {
+ _w.setTimeout(function () { context.element.charCounter.textContent = functions.getCharCount(options.charCounterType); });
+ }
+ },
+
+ /**
+ * @description The character counter blinks.
+ * @private
+ */
+ _callCounterBlink: function () {
+ const charWrapper = context.element.charWrapper;
+ if (charWrapper && !util.hasClass(charWrapper, 'se-blink')) {
+ util.addClass(charWrapper, 'se-blink');
+ _w.setTimeout(function () {
+ util.removeClass(charWrapper, 'se-blink');
+ }, 600);
+ }
+ },
+
+ /**
+ * @description Check the components such as image and video and modify them according to the format.
+ * @private
+ */
+ _checkComponents: function () {
+ for (let i = 0, len = this._fileInfoPluginsCheck.length; i < len; i++) {
+ this._fileInfoPluginsCheck[i]();
+ }
+ },
+
+ /**
+ * @description Initialize the information of the components.
+ * @private
+ */
+ _resetComponents: function () {
+ for (let i = 0, len = this._fileInfoPluginsReset.length; i < len; i++) {
+ this._fileInfoPluginsReset[i]();
+ }
+ },
+
+ /**
+ * @description Set method in the code view area
+ * @param {String} value HTML string
+ * @private
+ */
+ _setCodeView: function (value) {
+ if (options.codeMirrorEditor) {
+ options.codeMirrorEditor.getDoc().setValue(value);
+ } else {
+ context.element.code.value = value;
+ }
+ },
+
+ /**
+ * @description Get method in the code view area
+ * @private
+ */
+ _getCodeView: function () {
+ return options.codeMirrorEditor ? options.codeMirrorEditor.getDoc().getValue() : context.element.code.value;
+ },
+
+ /**
+ * @description Initializ core variable
+ * @param {Boolean} reload Is relooad?
+ * @param {String} _initHTML initial html string
+ * @private
+ */
+ _init: function (reload, _initHTML) {
+ const wRegExp = _w.RegExp;
+ this._ww = options.iframe ? context.element.wysiwygFrame.contentWindow : _w;
+ this._wd = _d;
+ this._charTypeHTML = options.charCounterType === 'byte-html';
+
+ if (!options.iframe && typeof _w.ShadowRoot === 'function') {
+ let child = context.element.wysiwygFrame;
+ while (child) {
+ if (child.shadowRoot) {
+ this._shadowRoot = child.shadowRoot;
+ break;
+ } else if (child instanceof _w.ShadowRoot) {
+ this._shadowRoot = child;
+ break;
+ }
+ child = child.parentNode;
+ }
+ }
+
+ // set disallow text nodes
+ const disallowTextTags = ['b', 'i', 'ins', 's', 'strike'];
+ const allowTextTags = !options.addTagsWhitelist ? [] : options.addTagsWhitelist.split('|').filter(function (v) { return /b|i|ins|s|strike/i.test(v); });
+ for (let i = 0; i < allowTextTags.length; i++) {
+ disallowTextTags.splice(disallowTextTags.indexOf(allowTextTags[i].toLowerCase()), 1);
+ }
+ this._disallowedTextTagsRegExp = disallowTextTags.length === 0 ? null : new wRegExp('(<\\/?)(' + disallowTextTags.join('|') + ')\\b\\s*(?:[^>^<]+)?\\s*(?=>)', 'gi');
+
+ // set whitelist
+ const defaultAttr = 'contenteditable|colspan|rowspan|target|href|src|class|type|controls|data-format|data-size|data-file-size|data-file-name|data-origin|data-align|data-image-link|data-rotate|data-proportion|data-percentage|origin-size|data-exp|data-font-size';
+ this._allowHTMLComments = options._editorTagsWhitelist.indexOf('//') > -1;
+ this._htmlCheckWhitelistRegExp = new wRegExp('^(' + options._editorTagsWhitelist.replace('|//', '') + ')$', 'i');
+ this.editorTagsWhitelistRegExp = util.createTagsWhitelist(options._editorTagsWhitelist.replace('|//', '|<!--|-->'));
+ this.pasteTagsWhitelistRegExp = util.createTagsWhitelist(options.pasteTagsWhitelist);
+
+ const _attr = options.attributesWhitelist;
+ const tagsAttr = {};
+ let allAttr = '';
+ if (!!_attr) {
+ for (let k in _attr) {
+ if (!util.hasOwn(_attr, k)) continue;
+ if (k === 'all') {
+ allAttr = _attr[k] + '|';
+ } else {
+ tagsAttr[k] = new wRegExp('((?:' + _attr[k] + '|' + defaultAttr + ')\s*=\s*"[^"]*")', 'ig');
+ }
+ }
+ }
+
+ this._attributesWhitelistRegExp = new wRegExp('((?:' + allAttr + defaultAttr + ')\s*=\s*"[^"]*")', 'ig');
+ this._attributesTagsWhitelist = tagsAttr;
+
+ // set modes
+ this._isInline = /inline/i.test(options.mode);
+ this._isBalloon = /balloon|balloon-always/i.test(options.mode);
+ this._isBalloonAlways = /balloon-always/i.test(options.mode);
+
+ // caching buttons
+ this._cachingButtons();
+
+ // file components
+ this._fileInfoPluginsCheck = [];
+ this._fileInfoPluginsReset = [];
+
+ // text components
+ this.managedTagsInfo = { query: '', map: {} };
+ const managedClass = [];
+
+ // Command and file plugins registration
+ this.activePlugins = [];
+ this._fileManager.tags = [];
+ this._fileManager.pluginMap = {};
+
+ let filePluginRegExp = [];
+ let plugin, button;
+ for (let key in plugins) {
+ if (!util.hasOwn(plugins, key)) continue;
+ plugin = plugins[key];
+ button = pluginCallButtons[key];
+ if (plugin.active && button) {
+ this.callPlugin(key, null, button);
+ }
+ if (typeof plugin.checkFileInfo === 'function' && typeof plugin.resetFileInfo === 'function') {
+ this.callPlugin(key, null, button);
+ this._fileInfoPluginsCheck.push(plugin.checkFileInfo.bind(this));
+ this._fileInfoPluginsReset.push(plugin.resetFileInfo.bind(this));
+ }
+ if (_w.Array.isArray(plugin.fileTags)) {
+ const fileTags = plugin.fileTags;
+ this.callPlugin(key, null, button);
+ this._fileManager.tags = this._fileManager.tags.concat(fileTags);
+ filePluginRegExp.push(key);
+ for (let tag = 0, tLen = fileTags.length; tag < tLen; tag++) {
+ this._fileManager.pluginMap[fileTags[tag].toLowerCase()] = key;
+ }
+ }
+ if (plugin.managedTags) {
+ const info = plugin.managedTags();
+ managedClass.push('.' + info.className);
+ this.managedTagsInfo.map[info.className] = info.method.bind(this);
+ }
+ }
+
+ this.managedTagsInfo.query = managedClass.toString();
+ this._fileManager.queryString = this._fileManager.tags.join(',');
+ this._fileManager.regExp = new wRegExp('^(' + this._fileManager.tags.join('|') + ')$', 'i');
+ this._fileManager.pluginRegExp = new wRegExp('^(' + (filePluginRegExp.length === 0 ? 'undefined' : filePluginRegExp.join('|')) + ')$', 'i');
+
+ // cache editor's element
+ this._variable._originCssText = context.element.topArea.style.cssText;
+ this._placeholder = context.element.placeholder;
+ this._lineBreaker = context.element.lineBreaker;
+ this._lineBreakerButton = this._lineBreaker.querySelector('button');
+
+ // Excute history function
+ this.history = _history(this, this._onChange_historyStack.bind(this));
+
+ // register notice module
+ this.addModule([_notice]);
+
+ // Init, validate
+ if (options.iframe) {
+ this._wd = context.element.wysiwygFrame.contentDocument;
+ context.element.wysiwyg = this._wd.body;
+ if (options._editorStyles.editor) context.element.wysiwyg.style.cssText = options._editorStyles.editor;
+ if (options.height === 'auto') this._iframeAuto = this._wd.body;
+ }
+
+ this._initWysiwygArea(reload, _initHTML);
+ },
+
+ /**
+ * @description Caching basic buttons to use
+ * @private
+ */
+ _cachingButtons: function () {
+ this.codeViewDisabledButtons = context.element.toolbar.querySelectorAll('.se-toolbar button:not([class~="se-code-view-enabled"])');
+ this.resizingDisabledButtons = context.element.toolbar.querySelectorAll('.se-toolbar button:not([class~="se-resizing-enabled"])');
+ const tool = context.tool;
+ this.commandMap = {
+ STRONG: tool.bold,
+ U: tool.underline,
+ EM: tool.italic,
+ DEL: tool.strike,
+ SUB: tool.subscript,
+ SUP: tool.superscript,
+ OUTDENT: tool.outdent,
+ INDENT: tool.indent
+ };
+ this._styleCommandMap = {
+ fullScreen: tool.fullScreen,
+ showBlocks: tool.showBlocks,
+ codeView: tool.codeView
+ };
+ },
+
+ /**
+ * @description Initializ wysiwyg area (Only called from core._init)
+ * @param {Boolean} reload Is relooad?
+ * @param {String} _initHTML initial html string
+ * @private
+ */
+ _initWysiwygArea: function (reload, _initHTML) {
+ context.element.wysiwyg.innerHTML = reload ? _initHTML : this.convertContentsForEditor(typeof _initHTML === 'string' ? _initHTML : context.element.originElement.value);
+ },
+
+ /**
+ * @description Called when there are changes to tags in the wysiwyg region.
+ * @private
+ */
+ _resourcesStateChange: function () {
+ this._iframeAutoHeight();
+ this._checkPlaceholder();
+ },
+
+ /**
+ * @description Called when after execute "history.push"
+ * @private
+ */
+ _onChange_historyStack: function () {
+ event._applyTagEffects();
+ if (context.tool.save) context.tool.save.removeAttribute('disabled');
+ if (functions.onChange) functions.onChange(this.getContents(true), this);
+ },
+
+ /**
+ * @description Modify the height value of the iframe when the height of the iframe is automatic.
+ * @private
+ */
+ _iframeAutoHeight: function () {
+ if (this._iframeAuto) {
+ _w.setTimeout(function () { context.element.wysiwygFrame.style.height = core._iframeAuto.offsetHeight + 'px'; });
+ }
+ },
+
+ /**
+ * @description Set display property when there is placeholder.
+ * @private
+ */
+ _checkPlaceholder: function () {
+ if (this._placeholder) {
+ if (this._variable.isCodeView) {
+ this._placeholder.style.display = 'none';
+ return;
+ }
+
+ const wysiwyg = context.element.wysiwyg;
+ if (!util.onlyZeroWidthSpace(wysiwyg.textContent) || wysiwyg.querySelector('.se-component, pre, blockquote, hr, li, table, img, iframe, video') || (wysiwyg.innerText.match(/\n/g) || '').length > 1) {
+ this._placeholder.style.display = 'none';
+ } else {
+ this._placeholder.style.display = 'block';
+ }
+ }
+ },
+
+ /**
+ * @description If there is no default format, add a format and move "selection".
+ * @param {String|null} formatName Format tag name (default: 'P')
+ * @private
+ */
+ _setDefaultFormat: function (formatName) {
+ if (this._fileManager.pluginRegExp.test(this.currentControllerName)) return;
+
+ const range = this.getRange();
+ const commonCon = range.commonAncestorContainer;
+ const startCon = range.startContainer;
+ const rangeEl = util.getRangeFormatElement(commonCon, null);
+ let focusNode, offset, format;
+
+ const fileComponent = util.getParentElement(commonCon, util.isComponent);
+ if (fileComponent && !util.isTable(fileComponent)) return;
+ if((util.isRangeFormatElement(startCon) || util.isWysiwygDiv(startCon)) && util.isComponent(startCon.childNodes[range.startOffset])) return;
+
+ if (rangeEl) {
+ format = util.createElement(formatName || options.defaultTag);
+ format.innerHTML = rangeEl.innerHTML;
+ if (format.childNodes.length === 0) format.innerHTML = util.zeroWidthSpace;
+
+ rangeEl.innerHTML = format.outerHTML;
+ format = rangeEl.firstChild;
+ focusNode = util.getEdgeChildNodes(format, null).sc;
+
+ if (!focusNode) {
+ focusNode = util.createTextNode(util.zeroWidthSpace);
+ format.insertBefore(focusNode, format.firstChild);
+ }
+
+ offset = focusNode.textContent.length;
+ this.setRange(focusNode, offset, focusNode, offset);
+ return;
+ }
+
+ if(util.isRangeFormatElement(commonCon) && (commonCon.childNodes.length <= 1)) {
+ let br = null;
+ if (commonCon.childNodes.length === 1 && util.isBreak(commonCon.firstChild)) {
+ br = commonCon.firstChild;
+ } else {
+ br = util.createTextNode(util.zeroWidthSpace);
+ commonCon.appendChild(br);
+ }
+
+ this.setRange(br, 1, br, 1);
+ return;
+ }
+
+ this.execCommand('formatBlock', false, (formatName || options.defaultTag));
+ focusNode = util.getEdgeChildNodes(commonCon, commonCon);
+ focusNode = focusNode ? focusNode.ec : commonCon;
+
+ format = util.getFormatElement(focusNode, null);
+ if (!format) {
+ this.removeRange();
+ this._editorRange();
+ return;
+ }
+
+ if (util.isBreak(format.nextSibling)) util.removeItem(format.nextSibling);
+ if (util.isBreak(format.previousSibling)) util.removeItem(format.previousSibling);
+ if (util.isBreak(focusNode)) {
+ const zeroWidth = util.createTextNode(util.zeroWidthSpace);
+ focusNode.parentNode.insertBefore(zeroWidth, focusNode);
+ focusNode = zeroWidth;
+ }
+
+ this.effectNode = null;
+ this.nativeFocus();
+ },
+
+ /**
+ * @description Initialization after "setOptions"
+ * @param {Object} el context.element
+ * @param {String} _initHTML Initial html string
+ * @private
+ */
+ _setOptionsInit: function (el, _initHTML) {
+ this.context = context = _Context(el.originElement, this._getConstructed(el), options);
+ this._componentsInfoReset = true;
+ this._editorInit(true, _initHTML);
+ },
+
+ /**
+ * @description Initializ editor
+ * @param {Boolean} reload Is relooad?
+ * @param {String} _initHTML initial html string
+ * @private
+ */
+ _editorInit: function (reload, _initHTML) {
+ // initialize core and add event listeners
+ this._init(reload, _initHTML);
+ event._addEvent();
+ this._setCharCount();
+ event._offStickyToolbar();
+ event.onResize_window();
+
+ // toolbar visibility
+ context.element.toolbar.style.visibility = '';
+
+ this._checkComponents();
+ this._componentsInfoInit = false;
+ this._componentsInfoReset = false;
+
+ this.history.reset(true);
+ this._resourcesStateChange();
+
+ _w.setTimeout(function () {
+ if (typeof functions.onload === 'function') functions.onload(core, reload);
+ });
+ },
+
+ /**
+ * @description Create and return an object to cache the new context.
+ * @param {Element} contextEl context.element
+ * @returns {Object}
+ * @private
+ */
+ _getConstructed: function (contextEl) {
+ return {
+ _top: contextEl.topArea,
+ _relative: contextEl.relative,
+ _toolBar: contextEl.toolbar,
+ _menuTray: contextEl._menuTray,
+ _editorArea: contextEl.editorArea,
+ _wysiwygArea: contextEl.wysiwygFrame,
+ _codeArea: contextEl.code,
+ _placeholder: contextEl.placeholder,
+ _resizingBar: contextEl.resizingBar,
+ _navigation: contextEl.navigation,
+ _charCounter: contextEl.charCounter,
+ _charWrapper: contextEl.charWrapper,
+ _loading: contextEl.loading,
+ _lineBreaker: contextEl.lineBreaker,
+ _lineBreaker_t: contextEl.lineBreaker_t,
+ _lineBreaker_b: contextEl.lineBreaker_b,
+ _resizeBack: contextEl.resizeBackground,
+ _stickyDummy: contextEl._stickyDummy,
+ _arrow: contextEl._arrow
+ };
+ }
+ };
+
+ /**
+ * @description event function
+ */
+ const event = {
+ _IEisComposing: false, // In IE, there is no "e.isComposing" in the key-up event.
+ _lineBreakerBind: null,
+ _responsiveCurrentSize: 'default',
+ _responsiveButtonSize: null,
+ _responsiveButtons: null,
+ _directionKeyCode: new _w.RegExp('^(8|13|3[2-9]|40|46)$'),
+ _nonTextKeyCode: new _w.RegExp('^(8|13|1[6-9]|20|27|3[3-9]|40|45|46|11[2-9]|12[0-3]|144|145)$'),
+ _historyIgnoreKeyCode: new _w.RegExp('^(1[6-9]|20|27|3[3-9]|40|45|11[2-9]|12[0-3]|144|145)$'),
+ _onButtonsCheck: new _w.RegExp('^(STRONG|U|EM|DEL|SUB|SUP)$'),
+ _frontZeroWidthReg: new _w.RegExp(util.zeroWidthSpace + '+', ''),
+ _keyCodeShortcut: {
+ 65: 'A',
+ 66: 'B',
+ 83: 'S',
+ 85: 'U',
+ 73: 'I',
+ 89: 'Y',
+ 90: 'Z',
+ 219: '[',
+ 221: ']'
+ },
+
+ _shortcutCommand: function (keyCode, shift) {
+ let command = null;
+ const keyStr = event._keyCodeShortcut[keyCode];
+
+ switch (keyStr) {
+ case 'A':
+ command = 'selectAll';
+ break;
+ case 'B':
+ if (options.shortcutsDisable.indexOf('bold') === -1) {
+ command = 'STRONG';
+ }
+ break;
+ case 'S':
+ if (shift && options.shortcutsDisable.indexOf('strike') === -1) {
+ command = 'DEL';
+ }
+ break;
+ case 'U':
+ if (options.shortcutsDisable.indexOf('underline') === -1) {
+ command = 'U';
+ }
+ break;
+ case 'I':
+ if (options.shortcutsDisable.indexOf('italic') === -1) {
+ command = 'EM';
+ }
+ break;
+ case 'Z':
+ if (options.shortcutsDisable.indexOf('undo') === -1) {
+ if (shift) {
+ command = 'redo';
+ } else {
+ command = 'undo';
+ }
+ }
+ break;
+ case 'Y':
+ if (options.shortcutsDisable.indexOf('undo') === -1) {
+ command = 'redo';
+ }
+ break;
+ case '[':
+ if (options.shortcutsDisable.indexOf('indent') === -1) {
+ command = options.rtl ? 'indent' : 'outdent';
+ }
+ break;
+ case ']':
+ if (options.shortcutsDisable.indexOf('indent') === -1) {
+ command = options.rtl ? 'outdent' : 'indent';
+ }
+ break;
+ }
+
+ if (!command) return false;
+
+ core.commandHandler(core.commandMap[command], command);
+ return true;
+ },
+
+ _applyTagEffects: function () {
+ let selectionNode = core.getSelectionNode();
+ if (selectionNode === core.effectNode) return;
+ core.effectNode = selectionNode;
+
+ const marginDir = options.rtl ? 'marginRight' : 'marginLeft';
+ const commandMap = core.commandMap;
+ const classOnCheck = this._onButtonsCheck;
+ const commandMapNodes = [];
+ const currentNodes = [];
+
+ const activePlugins = core.activePlugins;
+ const cLen = activePlugins.length;
+ let nodeName = '';
+
+ while (selectionNode.firstChild) {
+ selectionNode = selectionNode.firstChild;
+ }
+
+ for (let element = selectionNode; !util.isWysiwygDiv(element); element = element.parentNode) {
+ if (!element) break;
+ if (element.nodeType !== 1 || util.isBreak(element)) continue;
+ nodeName = element.nodeName.toUpperCase();
+ currentNodes.push(nodeName);
+
+ /* Active plugins */
+ for (let c = 0, name; c < cLen; c++) {
+ name = activePlugins[c];
+ if (commandMapNodes.indexOf(name) === -1 && plugins[name].active.call(core, element)) {
+ commandMapNodes.push(name);
+ }
+ }
+
+ if (util.isFormatElement(element)) {
+ /* Outdent */
+ if (commandMapNodes.indexOf('OUTDENT') === -1 && commandMap.OUTDENT) {
+ if (util.isListCell(element) || (element.style[marginDir] && util.getNumber(element.style[marginDir], 0) > 0)) {
+ commandMapNodes.push('OUTDENT');
+ commandMap.OUTDENT.removeAttribute('disabled');
+ }
+ }
+
+ /* Indent */
+ if (commandMapNodes.indexOf('INDENT') === -1 && commandMap.INDENT && util.isListCell(element) && !element.previousElementSibling) {
+ commandMapNodes.push('INDENT');
+ commandMap.INDENT.setAttribute('disabled', true);
+ }
+
+ continue;
+ }
+
+ /** default active buttons [strong, ins, em, del, sub, sup] */
+ if (classOnCheck.test(nodeName)) {
+ commandMapNodes.push(nodeName);
+ util.addClass(commandMap[nodeName], 'active');
+ }
+ }
+
+ /** remove class, display text */
+ for (let key in commandMap) {
+ if (commandMapNodes.indexOf(key) > -1 || !util.hasOwn(commandMap, key)) continue;
+ if (activePlugins.indexOf(key) > -1) {
+ plugins[key].active.call(core, null);
+ } else if (commandMap.OUTDENT && /^OUTDENT$/i.test(key)) {
+ commandMap.OUTDENT.setAttribute('disabled', true);
+ } else if (commandMap.INDENT && /^INDENT$/i.test(key)) {
+ commandMap.INDENT.removeAttribute('disabled');
+ } else {
+ util.removeClass(commandMap[key], 'active');
+ }
+ }
+
+ /** save current nodes */
+ core._variable.currentNodes = currentNodes.reverse();
+ core._variable.currentNodesMap = commandMapNodes;
+
+ /** Displays the current node structure to resizingBar */
+ if (options.showPathLabel) context.element.navigation.textContent = core._variable.currentNodes.join(' > ');
+ },
+
+ _cancelCaptionEdit: function () {
+ this.setAttribute('contenteditable', false);
+ this.removeEventListener('blur', event._cancelCaptionEdit);
+ },
+
+ _buttonsEventHandler: function (e) {
+ let target = e.target;
+ if (core._bindControllersOff) e.stopPropagation();
+
+ if (/^(input|textarea|select|option)$/i.test(target.nodeName)) {
+ core._antiBlur = false;
+ } else {
+ e.preventDefault();
+ }
+
+ if (util.getParentElement(target, '.se-submenu')) {
+ e.stopPropagation();
+ core._notHideToolbar = true;
+ } else {
+ let command = target.getAttribute('data-command');
+ let className = target.className;
+
+ while (!command && !/se-menu-list/.test(className) && !/sun-editor-common/.test(className)) {
+ target = target.parentNode;
+ command = target.getAttribute('data-command');
+ className = target.className;
+ }
+
+ if (command === core._submenuName || command === core._containerName) {
+ e.stopPropagation();
+ }
+ }
+ },
+
+ onClick_toolbar: function (e) {
+ let target = e.target;
+ let display = target.getAttribute('data-display');
+ let command = target.getAttribute('data-command');
+ let className = target.className;
+
+ while (target.parentNode && !command && !/se-menu-list/.test(className) && !/se-toolbar/.test(className)) {
+ target = target.parentNode;
+ command = target.getAttribute('data-command');
+ display = target.getAttribute('data-display');
+ className = target.className;
+ }
+
+ if (!command && !display) return;
+ if (target.disabled) return;
+ if (!core.hasFocus) core.nativeFocus();
+ if (!core._variable.isCodeView) core._editorRange();
+
+ core.actionCall(command, display, target);
+ },
+
+ onMouseDown_wysiwyg: function (e) {
+ if (util.isNonEditable(context.element.wysiwyg)) return;
+
+ const tableCell = util.getParentElement(e.target, util.isCell);
+ if (tableCell) {
+ const tablePlugin = core.plugins.table;
+ if (tablePlugin && tableCell !== tablePlugin._fixedCell && !tablePlugin._shift) {
+ core.callPlugin('table', function () {
+ tablePlugin.onTableCellMultiSelect.call(core, tableCell, false);
+ }, null);
+ }
+ }
+
+ if (core._isBalloon) {
+ event._hideToolbar();
+ }
+
+ if (/FIGURE/i.test(e.target.nodeName)) e.preventDefault();
+ if (typeof functions.onMouseDown === 'function') functions.onMouseDown(e, core);
+ },
+
+ onClick_wysiwyg: function (e) {
+ const targetElement = e.target;
+ if (util.isNonEditable(context.element.wysiwyg)) return;
+
+ const fileComponentInfo = core.getFileComponent(targetElement);
+ if (fileComponentInfo) {
+ e.preventDefault();
+ core.selectComponent(fileComponentInfo.target, fileComponentInfo.pluginName);
+ return;
+ }
+
+ const figcaption = util.getParentElement(targetElement, 'FIGCAPTION');
+ if (util.isNonEditable(figcaption)) {
+ e.preventDefault();
+ figcaption.setAttribute('contenteditable', true);
+ figcaption.focus();
+
+ if (core._isInline && !core._inlineToolbarAttr.isShow) {
+ event._showToolbarInline();
+
+ const hideToolbar = function () {
+ event._hideToolbar();
+ figcaption.removeEventListener('blur', hideToolbar);
+ };
+
+ figcaption.addEventListener('blur', hideToolbar);
+ }
+ }
+
+ _w.setTimeout(core._editorRange.bind(core));
+ core._editorRange();
+
+ const selectionNode = core.getSelectionNode();
+ const formatEl = util.getFormatElement(selectionNode, null);
+ const rangeEl = util.getRangeFormatElement(selectionNode, null);
+ if ((!formatEl || formatEl === rangeEl) && !util.isNonEditable(targetElement) && !util.isList(rangeEl)) {
+ const range = core.getRange();
+ if (util.getFormatElement(range.startContainer) === util.getFormatElement(range.endContainer)) {
+ if (util.isList(rangeEl)) {
+ const oLi = util.createElement('LI');
+ const prevLi = selectionNode.nextElementSibling;
+ oLi.appendChild(selectionNode);
+ rangeEl.insertBefore(oLi, prevLi);
+ } else if (!util.isWysiwygDiv(selectionNode) && !util.isComponent(selectionNode) && (!util.isTable(selectionNode) || util.isCell(selectionNode))) {
+ core._setDefaultFormat(util.isRangeFormatElement(rangeEl) ? 'DIV' : options.defaultTag);
+ }
+
+ e.preventDefault();
+ core.focus();
+ }
+ } else {
+ event._applyTagEffects();
+ }
+
+ if (core._isBalloon) _w.setTimeout(event._toggleToolbarBalloon);
+ if (typeof functions.onClick === 'function') functions.onClick(e, core);
+ },
+
+ _balloonDelay: null,
+ _showToolbarBalloonDelay: function () {
+ if (event._balloonDelay) {
+ _w.clearTimeout(event._balloonDelay);
+ }
+
+ event._balloonDelay = _w.setTimeout(function () {
+ _w.clearTimeout(this._balloonDelay);
+ this._balloonDelay = null;
+ this._showToolbarBalloon();
+ }.bind(event), 350);
+ },
+
+ _toggleToolbarBalloon: function () {
+ core._editorRange();
+ const range = core.getRange();
+ if (core._bindControllersOff || (!core._isBalloonAlways && range.collapsed)) event._hideToolbar();
+ else event._showToolbarBalloon(range);
+ },
+
+ _showToolbarBalloon: function (rangeObj) {
+ if (!core._isBalloon) return;
+
+ const range = rangeObj || core.getRange();
+ const toolbar = context.element.toolbar;
+ const topArea = context.element.topArea;
+ const selection = core.getSelection();
+
+ let isDirTop;
+ if (core._isBalloonAlways && range.collapsed) {
+ isDirTop = true;
+ } else if (selection.focusNode === selection.anchorNode) {
+ isDirTop = selection.focusOffset < selection.anchorOffset;
+ } else {
+ const childNodes = util.getListChildNodes(range.commonAncestorContainer, null);
+ isDirTop = util.getArrayIndex(childNodes, selection.focusNode) < util.getArrayIndex(childNodes, selection.anchorNode);
+ }
+
+ let rects = range.getClientRects();
+ rects = rects[isDirTop ? 0 : rects.length - 1];
+
+ let scrollLeft = 0;
+ let scrollTop = 0;
+ let el = topArea;
+ while (!!el) {
+ scrollLeft += el.scrollLeft;
+ scrollTop += el.scrollTop;
+ el = el.parentElement;
+ }
+
+ const editorWidth = topArea.offsetWidth;
+ const offsets = event._getEditorOffsets(null);
+ const stickyTop = offsets.top;
+ const editorLeft = offsets.left;
+
+ toolbar.style.top = '-10000px';
+ toolbar.style.visibility = 'hidden';
+ toolbar.style.display = 'block';
+
+ if (!rects) {
+ const node = core.getSelectionNode();
+ if (util.isFormatElement(node)) {
+ const zeroWidth = util.createTextNode(util.zeroWidthSpace);
+ core.insertNode(zeroWidth, null, false);
+ core.setRange(zeroWidth, 1, zeroWidth, 1);
+ core._editorRange();
+ rects = core.getRange().getClientRects();
+ rects = rects[isDirTop ? 0 : rects.length - 1];
+ }
+
+ if (!rects) {
+ const nodeOffset = util.getOffset(node, context.element.wysiwygFrame);
+ rects = {
+ left: nodeOffset.left,
+ top: nodeOffset.top,
+ right: nodeOffset.left,
+ bottom: nodeOffset.top + node.offsetHeight,
+ noText: true
+ };
+ scrollLeft = 0;
+ scrollTop = 0;
+ }
+
+ isDirTop = true;
+ }
+
+ const arrowMargin = _w.Math.round(context.element._arrow.offsetWidth / 2);
+ const toolbarWidth = toolbar.offsetWidth;
+ const toolbarHeight = toolbar.offsetHeight;
+ const iframeRects = /iframe/i.test(context.element.wysiwygFrame.nodeName) ? context.element.wysiwygFrame.getClientRects()[0] : null;
+ if (iframeRects) {
+ rects = {
+ left: rects.left + iframeRects.left,
+ top: rects.top + iframeRects.top,
+ right: rects.right + iframeRects.right - iframeRects.width,
+ bottom: rects.bottom + iframeRects.bottom - iframeRects.height
+ };
+ }
+
+ event._setToolbarOffset(isDirTop, rects, toolbar, editorLeft, editorWidth, scrollLeft, scrollTop, stickyTop, arrowMargin);
+ if (toolbarWidth !== toolbar.offsetWidth || toolbarHeight !== toolbar.offsetHeight) {
+ event._setToolbarOffset(isDirTop, rects, toolbar, editorLeft, editorWidth, scrollLeft, scrollTop, stickyTop, arrowMargin);
+ }
+
+ if (options.toolbarContainer) {
+ const editorParent = topArea.parentElement;
+
+ let container = options.toolbarContainer;
+ let left = container.offsetLeft;
+ let top = container.offsetTop;
+
+ while(!container.parentElement.contains(editorParent) || !/^(BODY|HTML)$/i.test(container.parentElement.nodeName)) {
+ container = container.offsetParent;
+ left += container.offsetLeft;
+ top += container.offsetTop;
+ }
+
+ toolbar.style.left = (toolbar.offsetLeft - left + topArea.offsetLeft) + 'px';
+ toolbar.style.top = (toolbar.offsetTop - top + topArea.offsetTop) + 'px';
+ }
+
+ toolbar.style.visibility = '';
+ },
+
+ _setToolbarOffset: function (isDirTop, rects, toolbar, editorLeft, editorWidth, scrollLeft, scrollTop, stickyTop, arrowMargin) {
+ const padding = 1;
+ const toolbarWidth = toolbar.offsetWidth;
+ const toolbarHeight = rects.noText && !isDirTop ? 0 : toolbar.offsetHeight;
+
+ const absoluteLeft = (isDirTop ? rects.left : rects.right) - editorLeft - (toolbarWidth / 2) + scrollLeft;
+ const overRight = absoluteLeft + toolbarWidth - editorWidth;
+
+ let t = (isDirTop ? rects.top - toolbarHeight - arrowMargin : rects.bottom + arrowMargin) - (rects.noText ? 0 : stickyTop) + scrollTop;
+ let l = absoluteLeft < 0 ? padding : overRight < 0 ? absoluteLeft : absoluteLeft - overRight - padding - 1;
+
+ let resetTop = false;
+ const space = t + (isDirTop ? (event._getEditorOffsets(null).top) : (toolbar.offsetHeight - context.element.wysiwyg.offsetHeight));
+ if (!isDirTop && space > 0 && event._getPageBottomSpace() < space) {
+ isDirTop = true;
+ resetTop = true;
+ } else if (isDirTop && _d.documentElement.offsetTop > space) {
+ isDirTop = false;
+ resetTop = true;
+ }
+
+ if (resetTop) t = (isDirTop ? rects.top - toolbarHeight - arrowMargin : rects.bottom + arrowMargin) - (rects.noText ? 0 : stickyTop) + scrollTop;
+
+ toolbar.style.left = _w.Math.floor(l) + 'px';
+ toolbar.style.top = _w.Math.floor(t) + 'px';
+
+ if (isDirTop) {
+ util.removeClass(context.element._arrow, 'se-arrow-up');
+ util.addClass(context.element._arrow, 'se-arrow-down');
+ context.element._arrow.style.top = toolbarHeight + 'px';
+ } else {
+ util.removeClass(context.element._arrow, 'se-arrow-down');
+ util.addClass(context.element._arrow, 'se-arrow-up');
+ context.element._arrow.style.top = -arrowMargin + 'px';
+ }
+
+ const arrow_left = _w.Math.floor((toolbarWidth / 2) + (absoluteLeft - l));
+ context.element._arrow.style.left = (arrow_left + arrowMargin > toolbar.offsetWidth ? toolbar.offsetWidth - arrowMargin : arrow_left < arrowMargin ? arrowMargin : arrow_left) + 'px';
+ },
+
+ _showToolbarInline: function () {
+ if (!core._isInline) return;
+
+ const toolbar = context.element.toolbar;
+ if (options.toolbarContainer) toolbar.style.position = 'relative';
+ else toolbar.style.position = 'absolute';
+
+ toolbar.style.visibility = 'hidden';
+ toolbar.style.display = 'block';
+ core._inlineToolbarAttr.width = toolbar.style.width = options.toolbarWidth;
+ core._inlineToolbarAttr.top = toolbar.style.top = (options.toolbarContainer ? 0 : (-1 - toolbar.offsetHeight)) + 'px';
+
+ if (typeof functions.showInline === 'function') functions.showInline(toolbar, context, core);
+
+ event.onScroll_window();
+ core._inlineToolbarAttr.isShow = true;
+ toolbar.style.visibility = '';
+ },
+
+ _hideToolbar: function () {
+ if (!core._notHideToolbar && !core._variable.isFullScreen) {
+ context.element.toolbar.style.display = 'none';
+ core._inlineToolbarAttr.isShow = false;
+ }
+ },
+
+ onInput_wysiwyg: function (e) {
+ core._editorRange();
+
+ const data = (e.data === null ? '' : e.data === undefined ? ' ' : e.data) || '';
+ if (!core._charCount(data)) {
+ e.preventDefault();
+ e.stopPropagation();
+ }
+
+ // history stack
+ core.history.push(true);
+
+ if (typeof functions.onInput === 'function') functions.onInput(e, core);
+ },
+
+ _onShortcutKey: false,
+ onKeyDown_wysiwyg: function (e) {
+ const keyCode = e.keyCode;
+ const shift = e.shiftKey;
+ const ctrl = e.ctrlKey || e.metaKey || keyCode === 91 || keyCode === 92 || keyCode === 224;
+ const alt = e.altKey;
+ event._IEisComposing = keyCode === 229;
+
+ core.submenuOff();
+
+ if (core._isBalloon) {
+ event._hideToolbar();
+ }
+
+ /** Shortcuts */
+ if (ctrl && event._shortcutCommand(keyCode, shift)) {
+ event._onShortcutKey = true;
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ } else if (event._onShortcutKey) {
+ event._onShortcutKey = false;
+ }
+
+ /** default key action */
+ let selectionNode = core.getSelectionNode();
+ const range = core.getRange();
+ const selectRange = !range.collapsed || range.startContainer !== range.endContainer;
+ const fileComponentName = core._fileManager.pluginRegExp.test(core.currentControllerName) ? core.currentControllerName : '';
+ let formatEl = util.getFormatElement(selectionNode, null) || selectionNode;
+ let rangeEl = util.getRangeFormatElement(formatEl, null);
+
+ switch (keyCode) {
+ case 8: /** backspace key */
+ if (!selectRange) {
+ if (fileComponentName) {
+ e.preventDefault();
+ e.stopPropagation();
+ core.plugins[fileComponentName].destroy.call(core);
+ break;
+ }
+ }
+
+ if (selectRange && event._hardDelete()) {
+ e.preventDefault();
+ e.stopPropagation();
+ break;
+ }
+
+ if (!util.isFormatElement(formatEl) && !context.element.wysiwyg.firstElementChild && !util.isComponent(selectionNode)) {
+ e.preventDefault();
+ e.stopPropagation();
+ core._setDefaultFormat(options.defaultTag);
+ return false;
+ }
+
+ if (!selectRange && !formatEl.previousElementSibling && (range.startOffset === 0 && !selectionNode.previousSibling && !util.isListCell(formatEl) &&
+ (util.isFormatElement(formatEl) && (!util.isFreeFormatElement(formatEl) || util.isClosureFreeFormatElement(formatEl))))) {
+ // closure range
+ if (util.isClosureRangeFormatElement(formatEl.parentNode)) {
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ // maintain default format
+ if (util.isWysiwygDiv(formatEl.parentNode) && formatEl.childNodes.length <= 1 && (!formatEl.firstChild || util.onlyZeroWidthSpace(formatEl.textContent))) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ formatEl.innerHTML = '<br>';
+ const attrs = formatEl.attributes;
+ while (attrs[0]) {
+ formatEl.removeAttribute(attrs[0].name);
+ }
+ core.nativeFocus();
+
+ return false;
+ }
+ }
+
+ // clean remove tag
+ if (formatEl && range.startContainer === range.endContainer && selectionNode.nodeType === 3 && !util.isFormatElement(selectionNode.parentNode)) {
+ if (range.collapsed ? selectionNode.textContent.length === 1 : (range.endOffset - range.startOffset) === selectionNode.textContent.length) {
+ e.preventDefault();
+
+ let offset = null;
+ let prev = selectionNode.parentNode.previousSibling;
+ const next = selectionNode.parentNode.nextSibling;
+ if (!prev) {
+ if (!next) {
+ prev = util.createElement('BR');
+ formatEl.appendChild(prev);
+ } else {
+ prev = next;
+ offset = 0;
+ }
+ }
+
+ selectionNode.textContent = '';
+ util.removeItemAllParents(selectionNode, null, formatEl);
+ offset = typeof offset === 'number' ? offset : prev.nodeType === 3 ? prev.textContent.length : 1;
+ core.setRange(prev, offset, prev, offset);
+ break;
+ }
+ }
+
+ // nested list
+ const commonCon = range.commonAncestorContainer;
+ formatEl = util.getFormatElement(range.startContainer, null);
+ rangeEl = util.getRangeFormatElement(formatEl, null);
+ if (rangeEl && formatEl && !util.isCell(rangeEl) && !/^FIGCAPTION$/i.test(rangeEl.nodeName)) {
+ if (util.isListCell(formatEl) && util.isList(rangeEl) && (util.isListCell(rangeEl.parentNode) || formatEl.previousElementSibling) && (selectionNode === formatEl || (selectionNode.nodeType === 3 && (!selectionNode.previousSibling || util.isList(selectionNode.previousSibling)))) &&
+ (util.getFormatElement(range.startContainer, null) !== util.getFormatElement(range.endContainer, null) ? rangeEl.contains(range.startContainer) : (range.startOffset === 0 && range.collapsed))) {
+ if (range.startContainer !== range.endContainer) {
+ e.preventDefault();
+
+ core.removeNode();
+ if (range.startContainer.nodeType === 3) {
+ core.setRange(range.startContainer, range.startContainer.textContent.length, range.startContainer, range.startContainer.textContent.length);
+ }
+ // history stack
+ core.history.push(true);
+ } else {
+ let prev = formatEl.previousElementSibling || rangeEl.parentNode;
+ if (util.isListCell(prev)) {
+ e.preventDefault();
+
+ let prevLast = prev;
+ if (!prev.contains(formatEl) && util.isListCell(prevLast) && util.isList(prevLast.lastElementChild)) {
+ prevLast = prevLast.lastElementChild.lastElementChild;
+ while (util.isListCell(prevLast) && util.isList(prevLast.lastElementChild)) {
+ prevLast = prevLast.lastElementChild && prevLast.lastElementChild.lastElementChild;
+ }
+ prev = prevLast;
+ }
+
+ let con = prev === rangeEl.parentNode ? rangeEl.previousSibling : prev.lastChild;
+ if (!con) {
+ con = util.createTextNode(util.zeroWidthSpace);
+ rangeEl.parentNode.insertBefore(con, rangeEl.parentNode.firstChild);
+ }
+ const offset = con.nodeType === 3 ? con.textContent.length : 1;
+ const children = formatEl.childNodes;
+ let after = con;
+ let child = children[0];
+ while ((child = children[0])) {
+ prev.insertBefore(child, after.nextSibling);
+ after = child;
+ }
+
+ util.removeItem(formatEl);
+ if (rangeEl.children.length === 0) util.removeItem(rangeEl);
+
+ core.setRange(con, offset, con, offset);
+ // history stack
+ core.history.push(true);
+ }
+ }
+
+ break;
+ }
+
+ // detach range
+ if (!selectRange && range.startOffset === 0) {
+ let detach = true;
+ let comm = commonCon;
+ while (comm && comm !== rangeEl && !util.isWysiwygDiv(comm)) {
+ if (comm.previousSibling) {
+ if (comm.previousSibling.nodeType === 1 || !util.onlyZeroWidthSpace(comm.previousSibling.textContent.trim())) {
+ detach = false;
+ break;
+ }
+ }
+ comm = comm.parentNode;
+ }
+
+ if (detach && rangeEl.parentNode) {
+ e.preventDefault();
+ core.detachRangeFormatElement(rangeEl, (util.isListCell(formatEl) ? [formatEl] : null), null, false, false);
+ // history stack
+ core.history.push(true);
+ break;
+ }
+ }
+ }
+
+ // component
+ if (!selectRange && (range.startOffset === 0 || (selectionNode === formatEl ? !!formatEl.childNodes[range.startOffset] : false))) {
+ const sel = selectionNode === formatEl ? formatEl.childNodes[range.startOffset] : selectionNode;
+ // select file component
+ const ignoreZWS = (commonCon.nodeType === 3 || util.isBreak(commonCon)) && !commonCon.previousSibling && range.startOffset === 0;
+ if (!sel.previousSibling && (util.isComponent(commonCon.previousSibling) || (ignoreZWS && util.isComponent(formatEl.previousSibling)))) {
+ const fileComponentInfo = core.getFileComponent(formatEl.previousSibling);
+ if (fileComponentInfo) {
+ e.preventDefault();
+ e.stopPropagation();
+ if (formatEl.textContent.length === 0) util.removeItem(formatEl);
+ core.selectComponent(fileComponentInfo.target, fileComponentInfo.pluginName);
+ }
+ break;
+ }
+ // delete nonEditable
+ if (util.isNonEditable(sel.previousSibling)) {
+ e.preventDefault();
+ e.stopPropagation();
+ util.removeItem(sel.previousSibling);
+ break;
+ }
+ }
+
+ break;
+ case 46: /** delete key */
+ if (fileComponentName) {
+ e.preventDefault();
+ e.stopPropagation();
+ core.plugins[fileComponentName].destroy.call(core);
+ break;
+ }
+
+ if (selectRange && event._hardDelete()) {
+ e.preventDefault();
+ e.stopPropagation();
+ break;
+ }
+
+ // component
+ if ((util.isFormatElement(selectionNode) || selectionNode.nextSibling === null || (util.onlyZeroWidthSpace(selectionNode.nextSibling) && selectionNode.nextSibling.nextSibling === null)) && range.startOffset === selectionNode.textContent.length) {
+ let nextEl = formatEl.nextElementSibling;
+ if (!nextEl) {
+ e.preventDefault();
+ break;
+ }
+
+ if (util.isComponent(nextEl)) {
+ e.preventDefault();
+
+ if (util.onlyZeroWidthSpace(formatEl)) {
+ util.removeItem(formatEl);
+ // table component
+ if (util.isTable(nextEl)) {
+ let cell = util.getChildElement(nextEl, util.isCell, false);
+ cell = cell.firstElementChild || cell;
+ core.setRange(cell, 0, cell, 0);
+ break;
+ }
+ }
+
+ // select file component
+ const fileComponentInfo = core.getFileComponent(nextEl);
+ if (fileComponentInfo) {
+ e.stopPropagation();
+ core.selectComponent(fileComponentInfo.target, fileComponentInfo.pluginName);
+ }
+
+ break;
+ }
+ }
+
+ if (!selectRange && (core.isEdgePoint(range.endContainer, range.endOffset) || (selectionNode === formatEl ? !!formatEl.childNodes[range.startOffset] : false))) {
+ const sel = selectionNode === formatEl ? formatEl.childNodes[range.startOffset] : selectionNode;
+ // delete nonEditable
+ if (util.isNonEditable(sel.nextSibling)) {
+ e.preventDefault();
+ e.stopPropagation();
+ util.removeItem(sel.nextSibling);
+ break;
+ }
+ }
+
+ // nested list
+ formatEl = util.getFormatElement(range.startContainer, null);
+ rangeEl = util.getRangeFormatElement(formatEl, null);
+ if (util.isListCell(formatEl) && util.isList(rangeEl) && (selectionNode === formatEl || (selectionNode.nodeType === 3 && (!selectionNode.nextSibling || util.isList(selectionNode.nextSibling)) &&
+ (util.getFormatElement(range.startContainer, null) !== util.getFormatElement(range.endContainer, null) ? rangeEl.contains(range.endContainer) : (range.endOffset === selectionNode.textContent.length && range.collapsed))))) {
+ if (range.startContainer !== range.endContainer) core.removeNode();
+
+ let next = util.getArrayItem(formatEl.children, util.isList, false);
+ next = next || formatEl.nextElementSibling || rangeEl.parentNode.nextElementSibling;
+ if (next && (util.isList(next) || util.getArrayItem(next.children, util.isList, false))) {
+ e.preventDefault();
+
+ let con, children;
+ if (util.isList(next)) {
+ const child = next.firstElementChild;
+ children = child.childNodes;
+ con = children[0];
+ while (children[0]) {
+ formatEl.insertBefore(children[0], next);
+ }
+ util.removeItem(child);
+ } else {
+ con = next.firstChild;
+ children = next.childNodes;
+ while (children[0]) {
+ formatEl.appendChild(children[0]);
+ }
+ util.removeItem(next);
+ }
+ core.setRange(con, 0, con, 0);
+ // history stack
+ core.history.push(true);
+ }
+ break;
+ }
+
+ break;
+ case 9: /** tab key */
+ if (fileComponentName || options.tabDisable) break;
+ e.preventDefault();
+ if (ctrl || alt || util.isWysiwygDiv(selectionNode)) break;
+
+ const isEdge = (!range.collapsed || core.isEdgePoint(range.startContainer, range.startOffset));
+ const selectedFormats = core.getSelectedElements(null);
+ selectionNode = core.getSelectionNode();
+ const cells = [];
+ let lines = [];
+ let fc = util.isListCell(selectedFormats[0]), lc = util.isListCell(selectedFormats[selectedFormats.length - 1]);
+ let r = {sc: range.startContainer, so: range.startOffset, ec: range.endContainer, eo: range.endOffset};
+ for (let i = 0, len = selectedFormats.length, f; i < len; i++) {
+ f = selectedFormats[i];
+ if (util.isListCell(f)) {
+ if (!f.previousElementSibling && !shift) {
+ continue;
+ } else {
+ cells.push(f);
+ }
+ } else {
+ lines.push(f);
+ }
+ }
+
+ // Nested list
+ if (cells.length > 0 && isEdge && core.plugins.list) {
+ r = core.plugins.list.editInsideList.call(core, shift, cells);
+ } else {
+ // table
+ const tableCell = util.getParentElement(selectionNode, util.isCell);
+ if (tableCell && isEdge) {
+ const table = util.getParentElement(tableCell, 'table');
+ const cells = util.getListChildren(table, util.isCell);
+ let idx = shift ? util.prevIdx(cells, tableCell) : util.nextIdx(cells, tableCell);
+
+ if (idx === cells.length && !shift) idx = 0;
+ if (idx === -1 && shift) idx = cells.length - 1;
+
+ let moveCell = cells[idx];
+ if (!moveCell) break;
+ moveCell = moveCell.firstElementChild || moveCell;
+ core.setRange(moveCell, 0, moveCell, 0);
+ break;
+ }
+
+ lines = lines.concat(cells);
+ fc = lc = null;
+ }
+
+ // Lines tab(4)
+ if (lines.length > 0) {
+ if (!shift) {
+ const tabText = util.createTextNode(new _w.Array(core._variable.tabSize + 1).join('\u00A0'));
+ if (lines.length === 1) {
+ const textRange = core.insertNode(tabText, null, true);
+ if (!textRange) return false;
+ if (!fc) {
+ r.sc = tabText;
+ r.so = textRange.endOffset;
+ }
+ if (!lc) {
+ r.ec = tabText;
+ r.eo = textRange.endOffset;
+ }
+ } else {
+ const len = lines.length - 1;
+ for (let i = 0, child; i <= len; i++) {
+ child = lines[i].firstChild;
+ if (!child) continue;
+
+ if (util.isBreak(child)) {
+ lines[i].insertBefore(tabText.cloneNode(false), child);
+ } else {
+ child.textContent = tabText.textContent + child.textContent;
+ }
+ }
+
+ const firstChild = util.getChildElement(lines[0], 'text', false);
+ const endChild = util.getChildElement(lines[len], 'text', true);
+ if (!fc && firstChild) {
+ r.sc = firstChild;
+ r.so = 0;
+ }
+ if (!lc && endChild) {
+ r.ec = endChild;
+ r.eo = endChild.textContent.length;
+ }
+ }
+ } else {
+ const len = lines.length - 1;
+ for (let i = 0, line; i <= len; i++) {
+ line = lines[i].childNodes;
+ for (let c = 0, cLen = line.length, child; c < cLen; c++) {
+ child = line[c];
+ if (!child) break;
+ if (util.onlyZeroWidthSpace(child)) continue;
+
+ if (/^\s{1,4}$/.test(child.textContent)) {
+ util.removeItem(child);
+ } else if (/^\s{1,4}/.test(child.textContent)) {
+ child.textContent = child.textContent.replace(/^\s{1,4}/, '');
+ }
+
+ break;
+ }
+ }
+
+ const firstChild = util.getChildElement(lines[0], 'text', false);
+ const endChild = util.getChildElement(lines[len], 'text', true);
+ if (!fc && firstChild) {
+ r.sc = firstChild;
+ r.so = 0;
+ }
+ if (!lc && endChild) {
+ r.ec = endChild;
+ r.eo = endChild.textContent.length;
+ }
+ }
+ }
+
+ core.setRange(r.sc, r.so, r.ec, r.eo);
+ // history stack
+ core.history.push(false);
+
+ break;
+ case 13: /** enter key */
+ const freeFormatEl = util.getFreeFormatElement(selectionNode, null);
+
+ if (core._charTypeHTML) {
+ let enterHTML = '';
+ if ((!shift && freeFormatEl) || shift) {
+ enterHTML = '<br>';
+ } else {
+ enterHTML = '<' + formatEl.nodeName + '><br></' + formatEl.nodeName + '>';
+ }
+
+ if (!core.checkCharCount(enterHTML, 'byte-html')) {
+ e.preventDefault();
+ return false;
+ }
+ }
+
+ if (!shift && freeFormatEl) {
+ e.preventDefault();
+ const selectionFormat = selectionNode === freeFormatEl;
+ const wSelection = core.getSelection();
+ const children = selectionNode.childNodes, offset = wSelection.focusOffset, prev = selectionNode.previousElementSibling, next = selectionNode.nextSibling;
+
+ if (!util.isClosureFreeFormatElement(freeFormatEl) && !!children && ((selectionFormat && range.collapsed && children.length - 1 <= offset + 1 && util.isBreak(children[offset]) && (!children[offset + 1] || ((!children[offset + 2] || util.onlyZeroWidthSpace(children[offset + 2].textContent)) && children[offset + 1].nodeType === 3 && util.onlyZeroWidthSpace(children[offset + 1].textContent))) && offset > 0 && util.isBreak(children[offset - 1])) ||
+ (!selectionFormat && util.onlyZeroWidthSpace(selectionNode.textContent) && util.isBreak(prev) && (util.isBreak(prev.previousSibling) || !util.onlyZeroWidthSpace(prev.previousSibling.textContent)) && (!next || (!util.isBreak(next) && util.onlyZeroWidthSpace(next.textContent)))))) {
+ if (selectionFormat) util.removeItem(children[offset - 1]);
+ else util.removeItem(selectionNode);
+ const newEl = core.appendFormatTag(freeFormatEl, util.isFormatElement(freeFormatEl.nextElementSibling) ? freeFormatEl.nextElementSibling : null);
+ util.copyFormatAttributes(newEl, freeFormatEl);
+ core.setRange(newEl, 1, newEl, 1);
+ break;
+ }
+
+ if (selectionFormat) {
+ functions.insertHTML(((range.collapsed && util.isBreak(range.startContainer.childNodes[range.startOffset - 1])) ? '<br>' : '<br><br>'), true, false);
+
+ let focusNode = wSelection.focusNode;
+ const wOffset = wSelection.focusOffset;
+ if (freeFormatEl === focusNode) {
+ focusNode = focusNode.childNodes[wOffset - offset > 1 ? wOffset - 1 : wOffset];
+ }
+
+ core.setRange(focusNode, 1, focusNode, 1);
+ } else {
+ const focusNext = wSelection.focusNode.nextSibling;
+ const br = util.createElement('BR');
+ core.insertNode(br, null, false);
+
+ const brPrev = br.previousSibling, brNext = br.nextSibling;
+ if (!util.isBreak(focusNext) && !util.isBreak(brPrev) && (!brNext || util.onlyZeroWidthSpace(brNext))) {
+ br.parentNode.insertBefore(br.cloneNode(false), br);
+ core.setRange(br, 1, br, 1);
+ } else {
+ core.setRange(brNext, 0, brNext, 0);
+ }
+ }
+
+ event._onShortcutKey = true;
+ break;
+ }
+
+ if (selectRange) break;
+
+ if (rangeEl && formatEl && !util.isCell(rangeEl) && !/^FIGCAPTION$/i.test(rangeEl.nodeName)) {
+ const range = core.getRange();
+ if(core.isEdgePoint(range.endContainer, range.endOffset) && util.isList(selectionNode.nextSibling)) {
+ e.preventDefault();
+ const newEl = util.createElement('LI');
+ const br = util.createElement('BR');
+ newEl.appendChild(br);
+
+ formatEl.parentNode.insertBefore(newEl, formatEl.nextElementSibling);
+ newEl.appendChild(selectionNode.nextSibling);
+
+ core.setRange(br, 1, br, 1);
+ break;
+ }
+
+ if ((range.commonAncestorContainer.nodeType === 3 ? !range.commonAncestorContainer.nextElementSibling : true) && util.onlyZeroWidthSpace(formatEl.innerText.trim())) {
+ e.preventDefault();
+ let newEl = null;
+
+ if (util.isListCell(rangeEl.parentNode)) {
+ rangeEl = formatEl.parentNode.parentNode.parentNode;
+ newEl = util.splitElement(formatEl, null, util.getElementDepth(formatEl) - 2);
+ if (!newEl) {
+ const newListCell = util.createElement('LI');
+ newListCell.innerHTML = '<br>';
+ rangeEl.insertBefore(newListCell, newEl);
+ newEl = newListCell;
+ }
+ } else {
+ const newFormat = util.isCell(rangeEl.parentNode) ? 'DIV' : util.isList(rangeEl.parentNode) ? 'LI' : util.isFormatElement(rangeEl.nextElementSibling) ? rangeEl.nextElementSibling.nodeName : util.isFormatElement(rangeEl.previousElementSibling) ? rangeEl.previousElementSibling.nodeName : options.defaultTag;
+ newEl = util.createElement(newFormat);
+ const edge = core.detachRangeFormatElement(rangeEl, [formatEl], null, true, true);
+ edge.cc.insertBefore(newEl, edge.ec);
+ }
+
+ newEl.innerHTML = '<br>';
+ util.copyFormatAttributes(newEl, formatEl);
+ util.removeItemAllParents(formatEl, null, null);
+ core.setRange(newEl, 1, newEl, 1);
+ break;
+ }
+ }
+
+ if (rangeEl && util.getParentElement(rangeEl, 'FIGCAPTION') && util.getParentElement(rangeEl, util.isList)) {
+ e.preventDefault();
+ formatEl = core.appendFormatTag(formatEl, null);
+ core.setRange(formatEl, 0, formatEl, 0);
+ }
+
+ if (fileComponentName) {
+ e.preventDefault();
+ e.stopPropagation();
+ const compContext = context[fileComponentName];
+ const container = compContext._container;
+ const sibling = container.previousElementSibling || container.nextElementSibling;
+
+ let newEl = null;
+ if (util.isListCell(container.parentNode)) {
+ newEl = util.createElement('BR');
+ } else {
+ newEl = util.createElement(util.isFormatElement(sibling) ? sibling.nodeName : options.defaultTag);
+ newEl.innerHTML = '<br>';
+ }
+
+ container.parentNode.insertBefore(newEl, container);
+
+ core.callPlugin(fileComponentName, function () {
+ core.selectComponent(compContext._element, fileComponentName);
+ }, null);
+ }
+
+ break;
+ case 27:
+ if (fileComponentName) {
+ e.preventDefault();
+ e.stopPropagation();
+ core.controllersOff();
+ return false;
+ }
+ break;
+ }
+
+ if (shift && keyCode === 16) {
+ e.preventDefault();
+ e.stopPropagation();
+ const tablePlugin = core.plugins.table;
+ if (tablePlugin && !tablePlugin._shift && !tablePlugin._ref) {
+ const cell = util.getParentElement(formatEl, util.isCell);
+ if (cell) {
+ tablePlugin.onTableCellMultiSelect.call(core, cell, true);
+ return;
+ }
+ }
+ }
+
+ const textKey = !ctrl && !alt && !selectRange && !event._nonTextKeyCode.test(keyCode);
+ if (textKey && range.collapsed && range.startContainer === range.endContainer && util.isBreak(range.commonAncestorContainer)) {
+ const zeroWidth = util.createTextNode(util.zeroWidthSpace);
+ core.insertNode(zeroWidth, null, false);
+ core.setRange(zeroWidth, 1, zeroWidth, 1);
+ }
+
+ if (typeof functions.onKeyDown === 'function') functions.onKeyDown(e, core);
+ },
+
+ onKeyUp_wysiwyg: function (e) {
+ if (event._onShortcutKey) return;
+ core._editorRange();
+
+ const range = core.getRange();
+ const keyCode = e.keyCode;
+ const ctrl = e.ctrlKey || e.metaKey || keyCode === 91 || keyCode === 92 || keyCode === 224;
+ const alt = e.altKey;
+ let selectionNode = core.getSelectionNode();
+
+ if (core._isBalloon && ((core._isBalloonAlways && keyCode !== 27) || !range.collapsed)) {
+ if (core._isBalloonAlways) {
+ if (keyCode !== 27) event._showToolbarBalloonDelay();
+ } else {
+ event._showToolbarBalloon();
+ return;
+ }
+ }
+
+ /** when format tag deleted */
+ if (keyCode === 8 && util.isWysiwygDiv(selectionNode) && selectionNode.textContent === '' && selectionNode.children.length === 0) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ selectionNode.innerHTML = '';
+
+ const oFormatTag = util.createElement(util.isFormatElement(core._variable.currentNodes[0]) ? core._variable.currentNodes[0] : options.defaultTag);
+ oFormatTag.innerHTML = '<br>';
+
+ selectionNode.appendChild(oFormatTag);
+ core.setRange(oFormatTag, 0, oFormatTag, 0);
+ event._applyTagEffects();
+
+ core.history.push(false);
+ return;
+ }
+
+ const formatEl = util.getFormatElement(selectionNode, null);
+ const rangeEl = util.getRangeFormatElement(selectionNode, null);
+ if (((!formatEl && range.collapsed) || formatEl === rangeEl) && !util.isComponent(selectionNode) && !util.isList(selectionNode)) {
+ core._setDefaultFormat(util.isRangeFormatElement(rangeEl) ? 'DIV' : options.defaultTag);
+ selectionNode = core.getSelectionNode();
+ }
+
+ if (event._directionKeyCode.test(keyCode)) {
+ event._applyTagEffects();
+ }
+
+ const textKey = !ctrl && !alt && !event._nonTextKeyCode.test(keyCode);
+ if (textKey && selectionNode.nodeType === 3 && util.zeroWidthRegExp.test(selectionNode.textContent) && !(e.isComposing !== undefined ? e.isComposing : event._IEisComposing)) {
+ let so = range.startOffset, eo = range.endOffset;
+ const frontZeroWidthCnt = (selectionNode.textContent.substring(0, eo).match(event._frontZeroWidthReg) || '').length;
+ so = range.startOffset - frontZeroWidthCnt;
+ eo = range.endOffset - frontZeroWidthCnt;
+ selectionNode.textContent = selectionNode.textContent.replace(util.zeroWidthRegExp, '');
+ core.setRange(selectionNode, so < 0 ? 0 : so, selectionNode, eo < 0 ? 0 : eo);
+ }
+
+ core._charCount('');
+
+ // history stack
+ core.history.push(true);
+
+ if (typeof functions.onKeyUp === 'function') functions.onKeyUp(e, core);
+ },
+
+ onScroll_wysiwyg: function (e) {
+ core.controllersOff();
+ core._lineBreaker.style.display = 'none';
+ if (core._isBalloon) event._hideToolbar();
+ if (typeof functions.onScroll === 'function') functions.onScroll(e, core);
+ },
+
+ onFocus_wysiwyg: function (e) {
+ if (core._antiBlur) return;
+ core.hasFocus = true;
+ if (core._isInline) event._showToolbarInline();
+ if (typeof functions.onFocus === 'function') functions.onFocus(e, core);
+ },
+
+ onBlur_wysiwyg: function (e) {
+ if (core._antiBlur || core._variable.isCodeView) return;
+ core.hasFocus = false;
+ core.controllersOff();
+ if (core._isInline || core._isBalloon) event._hideToolbar();
+ if (typeof functions.onBlur === 'function') functions.onBlur(e, core);
+
+ // active class reset of buttons
+ const commandMap = core.commandMap;
+ const activePlugins = core.activePlugins;
+ for (let key in commandMap) {
+ if (!util.hasOwn(commandMap, key)) continue;
+ if (activePlugins.indexOf(key) > -1) {
+ plugins[key].active.call(core, null);
+ } else if (commandMap.OUTDENT && /^OUTDENT$/i.test(key)) {
+ commandMap.OUTDENT.setAttribute('disabled', true);
+ } else if (commandMap.INDENT && /^INDENT$/i.test(key)) {
+ commandMap.INDENT.removeAttribute('disabled');
+ } else {
+ util.removeClass(commandMap[key], 'active');
+ }
+ }
+
+ core._variable.currentNodes = [];
+ core._variable.currentNodesMap = [];
+ if (options.showPathLabel) context.element.navigation.textContent = '';
+ },
+
+ onMouseDown_resizingBar: function (e) {
+ e.stopPropagation();
+
+ core._variable.resizeClientY = e.clientY;
+ context.element.resizeBackground.style.display = 'block';
+
+ function closureFunc() {
+ context.element.resizeBackground.style.display = 'none';
+ _d.removeEventListener('mousemove', event._resize_editor);
+ _d.removeEventListener('mouseup', closureFunc);
+ }
+
+ _d.addEventListener('mousemove', event._resize_editor);
+ _d.addEventListener('mouseup', closureFunc);
+ },
+
+ _resize_editor: function (e) {
+ const resizeInterval = context.element.editorArea.offsetHeight + (e.clientY - core._variable.resizeClientY);
+ context.element.wysiwygFrame.style.height = context.element.code.style.height = (resizeInterval < core._variable.minResizingSize ? core._variable.minResizingSize : resizeInterval) + 'px';
+ core._variable.resizeClientY = e.clientY;
+ },
+
+ onResize_window: function () {
+ core.controllersOff();
+
+ const responsiveSize = event._responsiveButtonSize;
+ if (responsiveSize) {
+ const windowWidth = _w.innerWidth;
+ let responsiveWidth = 'default';
+ for (let i = 1, len = responsiveSize.length; i < len; i++) {
+ if (windowWidth < responsiveSize[i]) {
+ responsiveWidth = responsiveSize[i] + '';
+ break;
+ }
+ }
+
+ if (event._responsiveCurrentSize !== responsiveWidth) {
+ event._responsiveCurrentSize = responsiveWidth;
+ functions.setToolbarButtons(event._responsiveButtons[responsiveWidth]);
+ }
+ }
+
+ if (context.element.toolbar.offsetWidth === 0) return;
+
+ if (context.fileBrowser && context.fileBrowser.area.style.display === 'block') {
+ context.fileBrowser.body.style.maxHeight = (_w.innerHeight - context.fileBrowser.header.offsetHeight - 50) + 'px';
+ }
+
+ if (core.submenuActiveButton && core.submenu) {
+ core._setMenuPosition(core.submenuActiveButton, core.submenu);
+ }
+
+ if (core._variable.isFullScreen) {
+ core._variable.innerHeight_fullScreen += (_w.innerHeight - context.element.toolbar.offsetHeight) - core._variable.innerHeight_fullScreen;
+ context.element.editorArea.style.height = core._variable.innerHeight_fullScreen + 'px';
+ return;
+ }
+
+ if (core._variable.isCodeView && core._isInline) {
+ event._showToolbarInline();
+ return;
+ }
+
+ core._iframeAutoHeight();
+
+ if (core._sticky) {
+ context.element.toolbar.style.width = (context.element.topArea.offsetWidth - 2) + 'px';
+ event.onScroll_window();
+ }
+ },
+
+ onScroll_window: function () {
+ if (core._variable.isFullScreen || context.element.toolbar.offsetWidth === 0 || options.stickyToolbar < 0) return;
+
+ const element = context.element;
+ const editorHeight = element.editorArea.offsetHeight;
+ const y = (this.scrollY || _d.documentElement.scrollTop) + options.stickyToolbar;
+ const editorTop = event._getEditorOffsets(options.toolbarContainer).top - (core._isInline ? element.toolbar.offsetHeight : 0);
+
+ if (y < editorTop) {
+ event._offStickyToolbar();
+ }
+ else if (y + core._variable.minResizingSize >= editorHeight + editorTop) {
+ if (!core._sticky) event._onStickyToolbar();
+ element.toolbar.style.top = (editorHeight + editorTop + options.stickyToolbar -y - core._variable.minResizingSize) + 'px';
+ }
+ else if (y >= editorTop) {
+ event._onStickyToolbar();
+ }
+ },
+
+ _getEditorOffsets: function (container) {
+ let offsetEl = container || context.element.topArea;
+ let t = 0, l = 0, s = 0;
+
+ while (offsetEl) {
+ t += offsetEl.offsetTop;
+ l += offsetEl.offsetLeft;
+ s += offsetEl.scrollTop;
+ offsetEl = offsetEl.offsetParent;
+ }
+
+ return {
+ top: t,
+ left: l,
+ scroll: s
+ };
+ },
+
+ _getPageBottomSpace: function () {
+ return _d.documentElement.scrollHeight - (event._getEditorOffsets(null).top + context.element.topArea.offsetHeight);
+ },
+
+ _onStickyToolbar: function () {
+ const element = context.element;
+
+ if (!core._isInline && !options.toolbarContainer) {
+ element._stickyDummy.style.height = element.toolbar.offsetHeight + 'px';
+ element._stickyDummy.style.display = 'block';
+ }
+
+ element.toolbar.style.top = options.stickyToolbar + 'px';
+ element.toolbar.style.width = core._isInline ? core._inlineToolbarAttr.width : element.toolbar.offsetWidth + 'px';
+ util.addClass(element.toolbar, 'se-toolbar-sticky');
+ core._sticky = true;
+ },
+
+ _offStickyToolbar: function () {
+ const element = context.element;
+
+ element._stickyDummy.style.display = 'none';
+ element.toolbar.style.top = core._isInline ? core._inlineToolbarAttr.top : '';
+ element.toolbar.style.width = core._isInline ? core._inlineToolbarAttr.width : '';
+ element.editorArea.style.marginTop = '';
+
+ util.removeClass(element.toolbar, 'se-toolbar-sticky');
+ core._sticky = false;
+ },
+
+ _codeViewAutoHeight: function () {
+ context.element.code.style.height = context.element.code.scrollHeight + 'px';
+ },
+
+ // FireFox - table delete, Chrome - image, video, audio
+ _hardDelete: function () {
+ const range = core.getRange();
+ const sc = range.startContainer;
+ const ec = range.endContainer;
+
+ // table
+ const sCell = util.getRangeFormatElement(sc);
+ const eCell = util.getRangeFormatElement(ec);
+ const sIsCell = util.isCell(sCell);
+ const eIsCell = util.isCell(eCell);
+ if (((sIsCell && !sCell.previousElementSibling && !sCell.parentElement.previousElementSibling) || (eIsCell && !eCell.nextElementSibling && !eCell.parentElement.nextElementSibling)) && sCell !== eCell) {
+ if (!sIsCell) {
+ util.removeItem(util.getParentElement(eCell, util.isComponent));
+ } else if (!eIsCell) {
+ util.removeItem(util.getParentElement(sCell, util.isComponent));
+ } else {
+ util.removeItem(util.getParentElement(sCell, util.isComponent));
+ core.nativeFocus();
+ return true;
+ }
+ }
+
+ // component
+ const sComp = sc.nodeType === 1 ? util.getParentElement(sc, '.se-component') : null;
+ const eComp = ec.nodeType === 1 ? util.getParentElement(ec, '.se-component') : null;
+ if (sComp) util.removeItem(sComp);
+ if (eComp) util.removeItem(eComp);
+
+ return false;
+ },
+
+ onPaste_wysiwyg: function (e) {
+ const clipboardData = util.isIE ? _w.clipboardData : e.clipboardData;
+ if (!clipboardData) return true;
+ return event._dataTransferAction('paste', e, clipboardData);
+ },
+
+ _setClipboardComponent: function (e, info, clipboardData) {
+ e.preventDefault();
+ e.stopPropagation();
+ clipboardData.setData('text/html', info.component.outerHTML);
+ },
+
+ onCopy_wysiwyg: function (e) {
+ const clipboardData = util.isIE ? _w.clipboardData : e.clipboardData;
+ if (typeof functions.onCopy === 'function' && !functions.onCopy(e, clipboardData, core)) {
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+
+ const info = core.currentFileComponentInfo;
+ if (info && !util.isIE) {
+ event._setClipboardComponent(e, info, clipboardData);
+ util.addClass(info.component, 'se-component-copy');
+ // copy effect
+ _w.setTimeout(function () {
+ util.removeClass(info.component, 'se-component-copy');
+ }, 150);
+ }
+ },
+
+ onCut_wysiwyg: function (e) {
+ const clipboardData = util.isIE ? _w.clipboardData : e.clipboardData;
+ if (typeof functions.onCut === 'function' && !functions.onCut(e, clipboardData, core)) {
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+
+ const info = core.currentFileComponentInfo;
+ if (info && !util.isIE) {
+ event._setClipboardComponent(e, info, clipboardData);
+ util.removeItem(info.component);
+ core.controllersOff();
+ }
+
+ _w.setTimeout(function () {
+ // history stack
+ core.history.push(false);
+ });
+ },
+
+ onDrop_wysiwyg: function (e) {
+ const dataTransfer = e.dataTransfer;
+ if (!dataTransfer) return true;
+ if (util.isIE) {
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+
+ core.removeNode();
+ event._setDropLocationSelection(e);
+ return event._dataTransferAction('drop', e, dataTransfer);
+ },
+
+ _setDropLocationSelection: function (e) {
+ if (e.rangeParent) {
+ core.setRange(e.rangeParent, e.rangeOffset, e.rangeParent, e.rangeOffset);
+ } else if (core._wd.caretRangeFromPoint) {
+ const r = core._wd.caretRangeFromPoint(e.clientX, e.clientY);
+ core.setRange(r.startContainer, r.startOffset, r.endContainer, r.endOffset);
+ } else {
+ const r = core.getRange();
+ core.setRange(r.startContainer, r.startOffset, r.endContainer, r.endOffset);
+ }
+ },
+
+ _dataTransferAction: function (type, e, data) {
+ let plainText, cleanData;
+ if (util.isIE) {
+ plainText = data.getData('Text');
+
+ const range = core.getRange();
+ const tempDiv = util.createElement('DIV');
+ const tempRange = {
+ sc: range.startContainer,
+ so: range.startOffset,
+ ec: range.endContainer,
+ eo: range.endOffset
+ };
+
+ tempDiv.setAttribute('contenteditable', true);
+ tempDiv.style.cssText = 'position:absolute; top:0; left:0; width:1px; height:1px; overflow:hidden;';
+
+ context.element.relative.appendChild(tempDiv);
+ tempDiv.focus();
+
+ _w.setTimeout(function () {
+ cleanData = tempDiv.innerHTML;
+ util.removeItem(tempDiv);
+ core.setRange(tempRange.sc, tempRange.so, tempRange.ec, tempRange.eo);
+ event._setClipboardData(type, e, plainText, cleanData, data);
+ });
+
+ return true;
+ } else {
+ plainText = data.getData('text/plain');
+ cleanData = data.getData('text/html') || plainText;
+ if (event._setClipboardData(type, e, plainText, cleanData, data) === false) {
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ }
+ },
+
+ _setClipboardData: function (type, e, plainText, cleanData, data) {
+ // MS word
+ if (/class=["']*Mso(Normal|List)/i.test(cleanData) || /content=["']*Word.Document/i.test(cleanData) || /content=["']*OneNote.File/i.test(cleanData)) {
+ cleanData = cleanData.replace(/\n/g, ' ');
+ plainText = plainText.replace(/\n/g, ' ');
+ } else {
+ plainText = plainText.replace(/\n/g, '');
+ }
+
+ cleanData = core.cleanHTML(cleanData, core.pasteTagsWhitelistRegExp);
+ const maxCharCount = core._charCount(core._charTypeHTML ? cleanData : plainText);
+
+ // paste event
+ if (type === 'paste' && typeof functions.onPaste === 'function') {
+ const value = functions.onPaste(e, cleanData, maxCharCount, core);
+ if (!value) return false;
+ if (typeof value === 'string') cleanData = value;
+ }
+ // drop event
+ if (type === 'drop' && typeof functions.onDrop === 'function') {
+ const value = functions.onDrop(e, cleanData, maxCharCount, core);
+ if (!value) return false;
+ if (typeof value === 'string') cleanData = value;
+ }
+
+ // files
+ const files = data.files;
+ if (files.length > 0) {
+ if (/^image/.test(files[0].type) && core.plugins.image) {
+ functions.insertImage(files);
+ }
+ return false;
+ }
+
+ if (!maxCharCount) {
+ return false;
+ }
+
+ if (cleanData) {
+ functions.insertHTML(cleanData, true, false);
+ return false;
+ }
+ },
+
+ onMouseMove_wysiwyg: function (e) {
+ if (core.isDisabled) return;
+ const component = util.getParentElement(e.target, util.isComponent);
+ const lineBreakerStyle = core._lineBreaker.style;
+
+ if (component && !core.currentControllerName) {
+ let scrollTop = 0;
+ let el = context.element.wysiwyg;
+ do {
+ scrollTop += el.scrollTop;
+ el = el.parentElement;
+ } while (el && !/^(BODY|HTML)$/i.test(el.nodeName));
+
+ const wScroll = context.element.wysiwyg.scrollTop;
+ const offsets = event._getEditorOffsets(null);
+ const componentTop = util.getOffset(component, context.element.wysiwygFrame).top + wScroll;
+ const y = e.pageY + scrollTop + (options.iframe && !options.toolbarContainer ? context.element.toolbar.offsetHeight : 0);
+ const c = componentTop + (options.iframe ? scrollTop : offsets.top);
+
+ const isList = util.isListCell(component.parentNode);
+ let dir = '', top = '';
+ if ((isList ? !component.previousSibling : !util.isFormatElement(component.previousElementSibling)) && y < (c + 20)) {
+ top = componentTop;
+ dir = 't';
+ } else if ((isList ? !component.nextSibling : !util.isFormatElement(component.nextElementSibling)) && y > (c + component.offsetHeight - 20)) {
+ top = componentTop + component.offsetHeight;
+ dir = 'b';
+ } else {
+ lineBreakerStyle.display = 'none';
+ return;
+ }
+
+ core._variable._lineBreakComp = component;
+ core._variable._lineBreakDir = dir;
+ lineBreakerStyle.top = (top - wScroll) + 'px';
+ core._lineBreakerButton.style.left = (util.getOffset(component).left + (component.offsetWidth / 2) - 15) + 'px';
+ lineBreakerStyle.display = 'block';
+ } // off line breaker
+ else if (lineBreakerStyle.display !== 'none') {
+ lineBreakerStyle.display = 'none';
+ }
+ },
+
+ _onMouseDown_lineBreak: function (e) {
+ e.preventDefault();
+ },
+
+ _onLineBreak: function (e) {
+ e.preventDefault();
+
+ const component = core._variable._lineBreakComp;
+ const dir = !this ? core._variable._lineBreakDir : this;
+ const isList = util.isListCell(component.parentNode);
+
+ const format = util.createElement(isList ? 'BR' : util.isCell(component.parentNode) ? 'DIV' : options.defaultTag);
+ if (!isList) format.innerHTML = '<br>';
+
+ if (core._charTypeHTML && !core.checkCharCount(format.outerHTML, 'byte-html')) return;
+
+ component.parentNode.insertBefore(format, dir === 't' ? component : component.nextSibling);
+ core._lineBreaker.style.display = 'none';
+ core._variable._lineBreakComp = null;
+
+ const focusEl = isList ? format : format.firstChild;
+ core.setRange(focusEl, 1, focusEl, 1);
+ // history stack
+ core.history.push(false);
+ },
+
+ _addEvent: function () {
+ const eventWysiwyg = options.iframe ? core._ww : context.element.wysiwyg;
+
+ /** toolbar event */
+ context.element.toolbar.addEventListener('mousedown', event._buttonsEventHandler, false);
+ context.element._menuTray.addEventListener('mousedown', event._buttonsEventHandler, false);
+ context.element.toolbar.addEventListener('click', event.onClick_toolbar, false);
+ /** editor area */
+ eventWysiwyg.addEventListener('mousedown', event.onMouseDown_wysiwyg, false);
+ eventWysiwyg.addEventListener('click', event.onClick_wysiwyg, false);
+ eventWysiwyg.addEventListener(util.isIE ? 'textinput' : 'input', event.onInput_wysiwyg, false);
+ eventWysiwyg.addEventListener('keydown', event.onKeyDown_wysiwyg, false);
+ eventWysiwyg.addEventListener('keyup', event.onKeyUp_wysiwyg, false);
+ eventWysiwyg.addEventListener('paste', event.onPaste_wysiwyg, false);
+ eventWysiwyg.addEventListener('copy', event.onCopy_wysiwyg, false);
+ eventWysiwyg.addEventListener('cut', event.onCut_wysiwyg, false);
+ eventWysiwyg.addEventListener('drop', event.onDrop_wysiwyg, false);
+ eventWysiwyg.addEventListener('scroll', event.onScroll_wysiwyg, false);
+ eventWysiwyg.addEventListener('focus', event.onFocus_wysiwyg, false);
+ eventWysiwyg.addEventListener('blur', event.onBlur_wysiwyg, false);
+
+ /** line breaker */
+ event._lineBreakerBind = { a: event._onLineBreak.bind(''), t: event._onLineBreak.bind('t'), b: event._onLineBreak.bind('b') };
+ eventWysiwyg.addEventListener('mousemove', event.onMouseMove_wysiwyg, false);
+ core._lineBreakerButton.addEventListener('mousedown', event._onMouseDown_lineBreak, false);
+ core._lineBreakerButton.addEventListener('click', event._lineBreakerBind.a, false);
+ context.element.lineBreaker_t.addEventListener('mousedown', event._lineBreakerBind.t, false);
+ context.element.lineBreaker_b.addEventListener('mousedown', event._lineBreakerBind.b, false);
+
+ /** Events are registered only when there is a table plugin. */
+ if (core.plugins.table) {
+ eventWysiwyg.addEventListener('touchstart', event.onMouseDown_wysiwyg, {passive: true, useCapture: false});
+ }
+
+ /** code view area auto line */
+ if (options.height === 'auto' && !options.codeMirrorEditor) {
+ context.element.code.addEventListener('keydown', event._codeViewAutoHeight, false);
+ context.element.code.addEventListener('keyup', event._codeViewAutoHeight, false);
+ context.element.code.addEventListener('paste', event._codeViewAutoHeight, false);
+ }
+
+ /** resizingBar */
+ if (context.element.resizingBar) {
+ if (/\d+/.test(options.height)) {
+ context.element.resizingBar.addEventListener('mousedown', event.onMouseDown_resizingBar, false);
+ } else {
+ util.addClass(context.element.resizingBar, 'se-resizing-none');
+ }
+ }
+
+ /** window event */
+ event._setResponsiveToolbar();
+ _w.removeEventListener('resize', event.onResize_window);
+ _w.removeEventListener('scroll', event.onScroll_window);
+
+ _w.addEventListener('resize', event.onResize_window, false);
+ if (options.stickyToolbar > -1) {
+ _w.addEventListener('scroll', event.onScroll_window, false);
+ }
+ },
+
+ _removeEvent: function () {
+ const eventWysiwyg = options.iframe ? core._ww : context.element.wysiwyg;
+
+ context.element.toolbar.removeEventListener('mousedown', event._buttonsEventHandler);
+ context.element._menuTray.removeEventListener('mousedown', event._buttonsEventHandler);
+ context.element.toolbar.removeEventListener('click', event.onClick_toolbar);
+
+ eventWysiwyg.removeEventListener('mousedown', event.onMouseDown_wysiwyg);
+ eventWysiwyg.removeEventListener('click', event.onClick_wysiwyg);
+ eventWysiwyg.removeEventListener(util.isIE ? 'textinput' : 'input', event.onInput_wysiwyg);
+ eventWysiwyg.removeEventListener('keydown', event.onKeyDown_wysiwyg);
+ eventWysiwyg.removeEventListener('keyup', event.onKeyUp_wysiwyg);
+ eventWysiwyg.removeEventListener('paste', event.onPaste_wysiwyg);
+ eventWysiwyg.removeEventListener('copy', event.onCopy_wysiwyg);
+ eventWysiwyg.removeEventListener('cut', event.onCut_wysiwyg);
+ eventWysiwyg.removeEventListener('drop', event.onDrop_wysiwyg);
+ eventWysiwyg.removeEventListener('scroll', event.onScroll_wysiwyg);
+
+ eventWysiwyg.removeEventListener('mousemove', event.onMouseMove_wysiwyg);
+ core._lineBreakerButton.removeEventListener('mousedown', event._onMouseDown_lineBreak);
+ core._lineBreakerButton.removeEventListener('click', event._lineBreakerBind.a);
+ context.element.lineBreaker_t.removeEventListener('mousedown', event._lineBreakerBind.t);
+ context.element.lineBreaker_b.removeEventListener('mousedown', event._lineBreakerBind.b);
+ event._lineBreakerBind = null;
+
+ eventWysiwyg.removeEventListener('touchstart', event.onMouseDown_wysiwyg, {passive: true, useCapture: false});
+
+ eventWysiwyg.removeEventListener('focus', event.onFocus_wysiwyg);
+ eventWysiwyg.removeEventListener('blur', event.onBlur_wysiwyg);
+
+ context.element.code.removeEventListener('keydown', event._codeViewAutoHeight);
+ context.element.code.removeEventListener('keyup', event._codeViewAutoHeight);
+ context.element.code.removeEventListener('paste', event._codeViewAutoHeight);
+
+ if (context.element.resizingBar) {
+ context.element.resizingBar.removeEventListener('mousedown', event.onMouseDown_resizingBar);
+ }
+
+ _w.removeEventListener('resize', event.onResize_window);
+ _w.removeEventListener('scroll', event.onScroll_window);
+ },
+
+ _setResponsiveToolbar: function () {
+ if (_responsiveButtons.length === 0) {
+ _responsiveButtons = null;
+ return;
+ }
+
+ const sizeArray = event._responsiveButtonSize = [];
+ const buttonsObj = event._responsiveButtons = {default: _responsiveButtons[0]};
+ for (let i = 1, len = _responsiveButtons.length, size, buttonGroup; i < len; i++) {
+ buttonGroup = _responsiveButtons[i];
+ size = buttonGroup[0] * 1;
+ sizeArray.push(size);
+ buttonsObj[size] = buttonGroup[1];
+ }
+
+ sizeArray.sort(function (a, b) { return a - b; }).unshift('default');
+ }
+ };
+
+ /** functions */
+ const functions = {
+ /**
+ * @description Core, Util object
+ */
+ core: core,
+ util: util,
+
+ /**
+ * @description Event functions
+ * @param {Object} e Event Object
+ * @param {Object} core Core object
+ */
+ onload: null,
+ onScroll: null,
+ onMouseDown: null,
+ onClick: null,
+ onInput: null,
+ onKeyDown: null,
+ onKeyUp: null,
+ onChange: null,
+ onCopy: null,
+ onCut: null,
+ onFocus: null,
+ onBlur: null,
+
+ /**
+ * @description Event functions (drop, paste)
+ * When false is returned, the default behavior is stopped.
+ * If the string is returned, the cleanData value is modified to the return value.
+ * @param {Object} e Event object.
+ * @param {String} cleanData HTML string modified for editor format.
+ * @param {Boolean} maxChartCount option (true if max character is exceeded)
+ * @param {Object} core Core object
+ * @returns {Boolean|String}
+ */
+ onDrop: null,
+ onPaste: null,
+
+ /**
+ * @description Called just before the inline toolbar is positioned and displayed on the screen.
+ * @param {Element} toolbar Toolbar Element
+ * @param {Object} context The editor's context object (editor.getContext())
+ * @param {Object} core Core object
+ */
+ showInline: null,
+
+ /**
+ * @description Called just after the controller is positioned and displayed on the screen.
+ * controller - editing elements displayed on the screen [image resizing, table editor, link editor..]]
+ * @param {String} name The name of the plugin that called the controller
+ * @param {Array} controllers Array of Controller elements
+ * @param {Object} core Core object
+ */
+ showController: null,
+
+ /**
+ * @description An event when toggling between code view and wysiwyg view.
+ * @param {Boolean} isCodeView Whether the current code view mode
+ * @param {Object} core Core object
+ */
+ toggleCodeView: null,
+
+ /**
+ * @description An event when toggling full screen.
+ * @param {Boolean} isFullScreen Whether the current full screen mode
+ * @param {Object} core Core object
+ */
+ toggleFullScreen: null,
+
+ /**
+ * @description It replaces the default callback function of the image upload
+ * @param {Object} response Response object
+ * @param {Object} info Input information
+ * - linkValue: Link url value
+ * - linkNewWindow: Open in new window Check Value
+ * - inputWidth: Value of width input
+ * - inputHeight: Value of height input
+ * - align: Align Check Value
+ * - isUpdate: Update image if true, create image if false
+ * - element: If isUpdate is true, the currently selected image.
+ * @param {Object} core Core object
+ */
+ imageUploadHandler: null,
+
+ /**
+ * @description It replaces the default callback function of the video upload
+ * @param xmlHttp xmlHttpRequest object
+ * @param info Input information
+ * - inputWidth: Value of width input
+ * - inputHeight: Value of height input
+ * - align: Align Check Value
+ * - isUpdate: Update video if true, create video if false
+ * - element: If isUpdate is true, the currently selected video.
+ * @param core Core object
+ */
+ videoUploadHandler: null,
+
+ /**
+ * @description It replaces the default callback function of the audio upload
+ * @param xmlHttp xmlHttpRequest object
+ * @param info Input information
+ * - isUpdate: Update audio if true, create audio if false
+ * - element: If isUpdate is true, the currently selected audio.
+ * @param core Core object
+ */
+ audioUploadHandler: null,
+
+ /**
+ * @description Called before the image is uploaded
+ * If true is returned, the internal upload process runs normally.
+ * If false is returned, no image upload is performed.
+ * If new fileList are returned, replaced the previous fileList
+ * If undefined is returned, it waits until "uploadHandler" is executed.
+ * @param {Array} files Files array
+ * @param {Object} info info: {
+ * - linkValue: Link url value
+ * - linkNewWindow: Open in new window Check Value
+ * - inputWidth: Value of width input
+ * - inputHeight: Value of height input
+ * - align: Align Check Value
+ * - isUpdate: Update image if true, create image if false
+ * - element: If isUpdate is true, the currently selected image.
+ * }
+ * @param {Object} core Core object
+ * @param {Function} uploadHandler If undefined is returned, it waits until "uploadHandler" is executed.
+ * "uploadHandler" is an upload function with "core" and "info" bound.
+ * [upload files] : uploadHandler(files or [new File(...),])
+ * [error] : uploadHandler("Error message")
+ * [Just finish] : uploadHandler()
+ * [directly register] : uploadHandler(response) // Same format as "imageUploadUrl" response
+ * ex) {
+ * // "errorMessage": "insert error message",
+ * "result": [ { "url": "...", "name": "...", "size": "999" }, ]
+ * }
+ * @returns {Boolean|Array|undefined}
+ */
+ onImageUploadBefore: null,
+ /**
+ * @description Called before the video is uploaded
+ * If true is returned, the internal upload process runs normally.
+ * If false is returned, no video(iframe, video) upload is performed.
+ * If new fileList are returned, replaced the previous fileList
+ * If undefined is returned, it waits until "uploadHandler" is executed.
+ * @param {Array} files Files array
+ * @param {Object} info info: {
+ * - inputWidth: Value of width input
+ * - inputHeight: Value of height input
+ * - align: Align Check Value
+ * - isUpdate: Update video if true, create video if false
+ * - element: If isUpdate is true, the currently selected video.
+ * }
+ * @param {Object} core Core object
+ * @param {Function} uploadHandler If undefined is returned, it waits until "uploadHandler" is executed.
+ * "uploadHandler" is an upload function with "core" and "info" bound.
+ * [upload files] : uploadHandler(files or [new File(...),])
+ * [error] : uploadHandler("Error message")
+ * [Just finish] : uploadHandler()
+ * [directly register] : uploadHandler(response) // Same format as "videoUploadUrl" response
+ * ex) {
+ * // "errorMessage": "insert error message",
+ * "result": [ { "url": "...", "name": "...", "size": "999" }, ]
+ * }
+ * @returns {Boolean|Array|undefined}
+ */
+ onVideoUploadBefore: null,
+ /**
+ * @description Called before the audio is uploaded
+ * If true is returned, the internal upload process runs normally.
+ * If false is returned, no audio upload is performed.
+ * If new fileList are returned, replaced the previous fileList
+ * If undefined is returned, it waits until "uploadHandler" is executed.
+ * @param {Array} files Files array
+ * @param {Object} info info: {
+ * - isUpdate: Update audio if true, create audio if false
+ * - element: If isUpdate is true, the currently selected audio.
+ * }
+ * @param {Object} core Core object
+ * @param {Function} uploadHandler If undefined is returned, it waits until "uploadHandler" is executed.
+ * "uploadHandler" is an upload function with "core" and "info" bound.
+ * [upload files] : uploadHandler(files or [new File(...),])
+ * [error] : uploadHandler("Error message")
+ * [Just finish] : uploadHandler()
+ * [directly register] : uploadHandler(response) // Same format as "audioUploadUrl" response
+ * ex) {
+ * // "errorMessage": "insert error message",
+ * "result": [ { "url": "...", "name": "...", "size": "999" }, ]
+ * }
+ * @returns {Boolean|Array|undefined}
+ */
+ onAudioUploadBefore: null,
+
+ /**
+ * @description Called when the image is uploaded, updated, deleted
+ * @param {Element} targetElement Target element
+ * @param {Number} index Uploaded index
+ * @param {String} state Upload status ('create', 'update', 'delete')
+ * @param {Object} info Image info object
+ * - index: data index
+ * - name: file name
+ * - size: file size
+ * - select: select function
+ * - delete: delete function
+ * - element: target element
+ * - src: src attribute of tag
+ * @param {Number} remainingFilesCount Count of remaining files to upload (0 when added as a url)
+ * @param {Object} core Core object
+ */
+ onImageUpload: null,
+ /**
+ * @description Called when the video(iframe, video) is is uploaded, updated, deleted
+ * -- arguments is same "onImageUpload" --
+ */
+ onVideoUpload: null,
+ /**
+ * @description Called when the audio is is uploaded, updated, deleted
+ * -- arguments is same "onImageUpload" --
+ */
+ onAudioUpload: null,
+
+ /**
+ * @description Called when the image is upload failed
+ * @param {String} errorMessage Error message
+ * @param {Object} result Response Object
+ * @param {Object} core Core object
+ * @returns {Boolean}
+ */
+ onImageUploadError: null,
+ /**
+ * @description Called when the video(iframe, video) upload failed
+ * -- arguments is same "onImageUploadError" --
+ */
+ onVideoUploadError: null,
+ /**
+ * @description Called when the audio upload failed
+ * -- arguments is same "onImageUploadError" --
+ */
+ onAudioUploadError: null,
+
+ /**
+ * @description Reset the buttons on the toolbar. (Editor is not reloaded)
+ * You cannot set a new plugin for the button.
+ * @param {Array} buttonList Button list
+ */
+ setToolbarButtons: function (buttonList) {
+ core.submenuOff();
+ core.containerOff();
+
+ const newToolbar = _Constructor._createToolBar(_d, buttonList, core.plugins, options);
+ _responsiveButtons = newToolbar.responsiveButtons;
+ core._moreLayerActiveButton = null;
+ event._setResponsiveToolbar();
+
+ context.element.toolbar.replaceChild(newToolbar._buttonTray, context.element._buttonTray);
+ const newContext = _Context(context.element.originElement, core._getConstructed(context.element), options);
+
+ context.element = newContext.element;
+ context.tool = newContext.tool;
+ if (options.iframe) context.element.wysiwyg = core._wd.body;
+ core._cachingButtons();
+ core.history._resetCachingButton();
+
+ core.activePlugins = [];
+ const oldCallButtons = pluginCallButtons;
+ pluginCallButtons = newToolbar.pluginCallButtons;
+ let plugin, button, oldButton;
+ for (let key in pluginCallButtons) {
+ if (!util.hasOwn(pluginCallButtons, key)) continue;
+ plugin = plugins[key];
+ button = pluginCallButtons[key];
+ if (plugin.active && button) {
+ oldButton = oldCallButtons[key];
+ core.callPlugin(key, null, oldButton || button);
+ if (oldButton) {
+ button.parentElement.replaceChild(oldButton, button);
+ pluginCallButtons[key] = oldButton;
+ }
+ }
+ }
+
+ if (core.hasFocus) event._applyTagEffects();
+
+ if (core._variable.isCodeView) util.addClass(core._styleCommandMap.codeView, 'active');
+ if (core._variable.isFullScreen) util.addClass(core._styleCommandMap.fullScreen, 'active');
+ if (util.hasClass(context.element.wysiwyg, 'se-show-block')) util.addClass(core._styleCommandMap.showBlocks, 'active');
+ },
+
+ /**
+ * @description Add or reset option property (Editor is reloaded)
+ * @param {Object} _options Options
+ */
+ setOptions: function (_options) {
+ event._removeEvent();
+ core._resetComponents();
+
+ util.removeClass(core._styleCommandMap.showBlocks, 'active');
+ util.removeClass(core._styleCommandMap.codeView, 'active');
+ core._variable.isCodeView = false;
+ core._iframeAuto = null;
+
+ core.plugins = _options.plugins || core.plugins;
+ const mergeOptions = [options, _options].reduce(function (init, option) {
+ for (let key in option) {
+ if (!util.hasOwn(option, key)) continue;
+ if (key === 'plugins' && option[key] && init[key]) {
+ let i = init[key], o = option[key];
+ i = i.length ? i : _w.Object.keys(i).map(function(name) { return i[name]; });
+ o = o.length ? o : _w.Object.keys(o).map(function(name) { return o[name]; });
+ init[key] = (o.filter(function(val) { return i.indexOf(val) === -1; })).concat(i);
+ } else {
+ init[key] = option[key];
+ }
+ }
+ return init;
+ }, {});
+
+ const el = context.element;
+ const _initHTML = el.wysiwyg.innerHTML;
+
+ // set option
+ const cons = _Constructor._setOptions(mergeOptions, context, core.plugins, options);
+
+ if (cons.callButtons) {
+ pluginCallButtons = cons.callButtons;
+ core.initPlugins = {};
+ }
+
+ if (cons.plugins) {
+ core.plugins = plugins = cons.plugins;
+ }
+
+ // reset context
+ if (el._menuTray.children.length === 0) this._menuTray = {};
+ _responsiveButtons = cons.toolbar.responsiveButtons;
+ options = mergeOptions;
+ core.lang = lang = options.lang;
+
+ if (options.iframe) {
+ el.wysiwygFrame.addEventListener('load', function () {
+ util._setIframeDocument(this, options);
+ core._setOptionsInit(el, _initHTML);
+ });
+ }
+
+ el.editorArea.appendChild(el.wysiwygFrame);
+
+ if (!options.iframe) {
+ core._setOptionsInit(el, _initHTML);
+ }
+ },
+
+ /**
+ * @description Set "options.defaultStyle" style.
+ * Define the style of the edit area
+ * It can also be defined with the "setOptions" method, but the "setDefaultStyle" method does not render the editor again.
+ * @param {String} style Style string
+ */
+ setDefaultStyle: function (style) {
+ const newStyles = options._editorStyles = util._setDefaultOptionStyle(options, style);
+ const el = context.element;
+
+ // top area
+ el.topArea.style.cssText = newStyles.top;
+ // code view
+ el.code.style.cssText = options._editorStyles.frame;
+ el.code.style.display = 'none';
+ if (options.height === 'auto') {
+ el.code.style.overflow = 'hidden';
+ } else {
+ el.code.style.overflow = '';
+ }
+ // wysiwyg frame
+ if (!options.iframe) {
+ el.wysiwygFrame.style.cssText = newStyles.frame + newStyles.editor;
+ } else {
+ el.wysiwygFrame.style.cssText = newStyles.frame;
+ el.wysiwyg.style.cssText = newStyles.editor;
+ }
+ },
+
+ /**
+ * @description Open a notice area
+ * @param {String} message Notice message
+ */
+ noticeOpen: function (message) {
+ core.notice.open.call(core, message);
+ },
+
+ /**
+ * @description Close a notice area
+ */
+ noticeClose: function () {
+ core.notice.close.call(core);
+ },
+
+ /**
+ * @description Copying the contents of the editor to the original textarea
+ */
+ save: function () {
+ context.element.originElement.value = core.getContents(false);
+ },
+
+ /**
+ * @description Gets the suneditor's context object. Contains settings, plugins, and cached element objects
+ * @returns {Object}
+ */
+ getContext: function () {
+ return context;
+ },
+
+ /**
+ * @description Gets the contents of the suneditor
+ * @param {Boolean} onlyContents - Return only the contents of the body without headers when the "fullPage" option is true
+ * @returns {String}
+ */
+ getContents: function (onlyContents) {
+ return core.getContents(onlyContents);
+ },
+
+ /**
+ * @description Gets only the text of the suneditor contents
+ * @returns {String}
+ */
+ getText: function () {
+ return context.element.wysiwyg.textContent;
+ },
+
+ /**
+ * @description Get the editor's number of characters or binary data size.
+ * You can use the "charCounterType" option format.
+ * @param {String|null} charCounterType options - charCounterType ('char', 'byte', 'byte-html')
+ * If argument is no value, the currently set "charCounterType" option is used.
+ * @returns {Number}
+ */
+ getCharCount: function (charCounterType) {
+ charCounterType = typeof charCounterType === 'string' ? charCounterType : options.charCounterType;
+ return core.getCharLength((core._charTypeHTML ? context.element.wysiwyg.innerHTML : context.element.wysiwyg.textContent), charCounterType);
+ },
+
+ /**
+ * @description Gets uploaded images informations
+ * - index: data index
+ * - name: file name
+ * - size: file size
+ * - select: select function
+ * - delete: delete function
+ * - element: target element
+ * - src: src attribute of tag
+ * @returns {Array}
+ */
+ getImagesInfo: function () {
+ return context.image ? context.image._infoList : [];
+ },
+
+ /**
+ * @description Gets uploaded files(plugin using fileManager) information list.
+ * image: [img], video: [video, iframe], audio: [audio]
+ * When the argument value is 'image', it is the same function as "getImagesInfo".
+ * - index: data index
+ * - name: file name
+ * - size: file size
+ * - select: select function
+ * - delete: delete function
+ * - element: target element
+ * - src: src attribute of tag
+ * @param {String} pluginName Plugin name (image, video, audio)
+ * @returns {Array}
+ */
+ getFilesInfo: function (pluginName) {
+ return context[pluginName] ? context[pluginName]._infoList : [];
+ },
+
+ /**
+ * @description Upload images using image plugin
+ * @param {FileList} files FileList
+ */
+ insertImage: function (files) {
+ if (!core.plugins.image || !files) return;
+
+ if (!core.initPlugins.image) core.callPlugin('image', core.plugins.image.submitAction.bind(core, files), null);
+ else core.plugins.image.submitAction.call(core, files);
+ core.focus();
+ },
+
+ /**
+ * @description Inserts an HTML element or HTML string or plain string at the current cursor position
+ * @param {Element|String} html HTML Element or HTML string or plain string
+ * @param {Boolean} notCleaningData If true, inserts the HTML string without refining it with core.cleanHTML.
+ * @param {Boolean} checkCharCount If true, if "options.maxCharCount" is exceeded when "element" is added, null is returned without addition.
+ * @param {Boolean} rangeSelection If true, range select the inserted node.
+ */
+ insertHTML: function (html, notCleaningData, checkCharCount, rangeSelection) {
+ if (typeof html === 'string') {
+ if (!notCleaningData) html = core.cleanHTML(html, null);
+ try {
+ const dom = _d.createRange().createContextualFragment(html);
+ const domTree = dom.childNodes;
+
+ if (checkCharCount) {
+ const type = core._charTypeHTML ? 'outerHTML' : 'textContent';
+ let checkHTML = '';
+ for (let i = 0, len = domTree.length; i < len; i++) {
+ checkHTML += domTree[i][type];
+ }
+ if (!core.checkCharCount(checkHTML, null)) return;
+ }
+
+ let c, a, t, firstCon;
+ while ((c = domTree[0])) {
+ t = core.insertNode(c, a, false);
+ a = t.container || t;
+ if (!firstCon) firstCon = t;
+ }
+
+ const offset = a.nodeType === 3 ? (t.endOffset || a.textContent.length): a.childNodes.length;
+ if (rangeSelection) core.setRange(firstCon.container || firstCon, firstCon.startOffset || 0, a, offset);
+ else core.setRange(a, offset, a, offset);
+ } catch (error) {
+ core.execCommand('insertHTML', false, html);
+ }
+ } else {
+ if (util.isComponent(html)) {
+ core.insertComponent(html, false, checkCharCount, false);
+ } else {
+ let afterNode = null;
+ if (util.isFormatElement(html) || util.isMedia(html)) {
+ afterNode = util.getFormatElement(core.getSelectionNode(), null);
+ }
+ core.insertNode(html, afterNode, checkCharCount);
+ }
+ }
+
+ core.effectNode = null;
+ core.focus();
+
+ // history stack
+ core.history.push(false);
+ },
+
+ /**
+ * @description Change the contents of the suneditor
+ * @param {String|undefined} contents Contents to Input
+ */
+ setContents: function (contents) {
+ core.setContents(contents);
+ },
+
+ /**
+ * @description Add contents to the suneditor
+ * @param {String} contents Contents to Input
+ */
+ appendContents: function (contents) {
+ const convertValue = core.convertContentsForEditor(contents);
+
+ if (!core._variable.isCodeView) {
+ const temp = util.createElement('DIV');
+ temp.innerHTML = convertValue;
+
+ const wysiwyg = context.element.wysiwyg;
+ const children = temp.children;
+ for (let i = 0, len = children.length; i < len; i++) {
+ wysiwyg.appendChild(children[i]);
+ }
+ } else {
+ core._setCodeView(core._getCodeView() + '\n' + core.convertHTMLForCodeView(convertValue));
+ }
+
+ // history stack
+ core.history.push(false);
+ },
+
+ /**
+ * @description Disable the suneditor
+ */
+ disabled: function () {
+ context.tool.cover.style.display = 'block';
+ context.element.wysiwyg.setAttribute('contenteditable', false);
+ core.isDisabled = true;
+
+ if (options.codeMirrorEditor) {
+ options.codeMirrorEditor.setOption('readOnly', true);
+ } else {
+ context.element.code.setAttribute('disabled', 'disabled');
+ }
+ },
+
+ /**
+ * @description Enable the suneditor
+ */
+ enabled: function () {
+ context.tool.cover.style.display = 'none';
+ context.element.wysiwyg.setAttribute('contenteditable', true);
+ core.isDisabled = false;
+
+ if (options.codeMirrorEditor) {
+ options.codeMirrorEditor.setOption('readOnly', false);
+ } else {
+ context.element.code.removeAttribute('disabled');
+ }
+ },
+
+ /**
+ * @description Show the suneditor
+ */
+ show: function () {
+ const topAreaStyle = context.element.topArea.style;
+ if (topAreaStyle.display === 'none') topAreaStyle.display = options.display;
+ },
+
+ /**
+ * @description Hide the suneditor
+ */
+ hide: function () {
+ context.element.topArea.style.display = 'none';
+ },
+
+ /**
+ * @description Destroy the suneditor
+ */
+ destroy: function () {
+ /** off menus */
+ core.submenuOff();
+ core.containerOff();
+ core.controllersOff();
+ if (core.notice) core.notice.close.call(core);
+ if (core.modalForm) core.plugins.dialog.close.call(core);
+
+ /** remove history */
+ core.history._destroy();
+
+ /** remove event listeners */
+ event._removeEvent();
+
+ /** remove element */
+ util.removeItem(context.element.toolbar);
+ util.removeItem(context.element.topArea);
+
+ /** remove object reference */
+ for (let k in core) { if (util.hasOwn(core, k)) delete core[k]; }
+ for (let k in event) { if (util.hasOwn(event, k)) delete event[k]; }
+ for (let k in context) { if (util.hasOwn(context, k)) delete context[k]; }
+ for (let k in pluginCallButtons) { if (util.hasOwn(pluginCallButtons, k)) delete pluginCallButtons[k]; }
+
+ /** remove user object */
+ for (let k in this) { if (util.hasOwn(this, k)) delete this[k]; }
+ },
+
+ /**
+ * @description Toolbar methods
+ */
+ toolbar: {
+ /**
+ * @description Disable the toolbar
+ */
+ disabled: function () {
+ context.tool.cover.style.display = 'block';
+ },
+
+ /**
+ * @description Enable the toolbar
+ */
+ enabled: function () {
+ context.tool.cover.style.display = 'none';
+ },
+
+ /**
+ * @description Show the toolbar
+ */
+ show: function () {
+ if (core._isInline) {
+ event._showToolbarInline();
+ } else {
+ context.element.toolbar.style.display = '';
+ context.element._stickyDummy.style.display = '';
+ }
+ },
+
+ /**
+ * @description Hide the toolbar
+ */
+ hide: function () {
+ if (core._isInline) {
+ event._hideToolbar();
+ } else {
+ context.element.toolbar.style.display = 'none';
+ context.element._stickyDummy.style.display = 'none';
+ }
+ },
+ }
+ };
+
+ /************ Core init ************/
+ // functions
+ core.functions = functions;
+
+ // Create to sibling node
+ let contextEl = context.element;
+ let originEl = contextEl.originElement;
+ let topEl = contextEl.topArea;
+ originEl.style.display = 'none';
+ topEl.style.display = 'block';
+
+ // init
+ if (options.iframe) {
+ contextEl.wysiwygFrame.addEventListener('load', function () {
+ util._setIframeDocument(this, options);
+ core._editorInit(false, options.value);
+ options.value = null;
+ });
+ }
+
+ // insert editor element
+ if (typeof originEl.nextElementSibling === 'object') {
+ originEl.parentNode.insertBefore(topEl, originEl.nextElementSibling);
+ } else {
+ originEl.parentNode.appendChild(topEl);
+ }
+
+ contextEl.editorArea.appendChild(contextEl.wysiwygFrame);
+ contextEl = originEl = topEl = null;
+
+ // init
+ if (!options.iframe) {
+ core._editorInit(false, options.value);
+ options.value = null;
+ }
+
+ return functions;
+}
\ No newline at end of file
--- /dev/null
+import { Core } from "./core";
+
+export interface History {
+ /**
+ * @description History stack
+ */
+ stack: any[];
+ /**
+ * @description Saving the current status to the history object stack
+ * If "delay" is true, it will be saved after (options.historyStackDelayTime || 400) miliseconds
+ * If the function is called again with the "delay" argument true before it is saved, the delay time is renewal
+ * You can specify the delay time by sending a number.
+ * @param {Boolean} delay If true, Add stack without delay time.
+ */
+ push: (delay: boolean | number) => void;
+ /**
+ * @description Undo function
+ */
+ undo: () => void;
+ /**
+ * @description Redo function
+ */
+ redo: () => void;
+ /**
+ * @description Go to the history stack for that index.
+ * If "index" is -1, go to the last stack
+ * @param {Number} index Stack index
+ */
+ go: (index: number) => void;
+ /**
+ * @description Reset the history object
+ */
+ reset: (ignoreChangeEvent: any) => void;
+ /**
+ * @description Remove all stacks and remove the timeout function.
+ * @private
+ */
+ _destroy: () => void;
+}
+
+export default function _default(core: Core, change: any): History;
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2019 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default function (core, change) {
+ const _w = core._w;
+ const util = core.util;
+ const delayTime = core.context.options.historyStackDelayTime;
+ let editor = core.context.element;
+ let undo = core.context.tool.undo;
+ let redo = core.context.tool.redo;
+
+ let pushDelay = null;
+ let stackIndex = 0;
+ let stack = [];
+
+ function setContentsFromStack () {
+ const item = stack[stackIndex];
+ editor.wysiwyg.innerHTML = item.contents;
+
+ core.setRange(util.getNodeFromPath(item.s.path, editor.wysiwyg), item.s.offset, util.getNodeFromPath(item.e.path, editor.wysiwyg), item.e.offset);
+ core.focus();
+
+ if (stackIndex === 0) {
+ if (undo) undo.setAttribute('disabled', true);
+ if (redo) redo.removeAttribute('disabled');
+ } else if (stackIndex === stack.length - 1) {
+ if (undo) undo.removeAttribute('disabled');
+ if (redo) redo.setAttribute('disabled', true);
+ } else {
+ if (undo) undo.removeAttribute('disabled');
+ if (redo) redo.removeAttribute('disabled');
+ }
+
+ core.controllersOff();
+ core._checkComponents();
+ core._setCharCount();
+ core._resourcesStateChange();
+
+ // onChange
+ change();
+ }
+
+ function pushStack () {
+ core._checkComponents();
+ const current = core.getContents(true);
+ if (!current || (!!stack[stackIndex] && current === stack[stackIndex].contents)) return;
+
+ stackIndex++;
+ const range = core._variable._range;
+
+ if (stack.length > stackIndex) {
+ stack = stack.slice(0, stackIndex);
+ if (redo) redo.setAttribute('disabled', true);
+ }
+
+ if (!range) {
+ stack[stackIndex] = {
+ contents: current,
+ s: { path: [0, 0], offset: [0, 0] },
+ e: { path: 0, offset: 0 }
+ };
+ } else {
+ stack[stackIndex] = {
+ contents: current,
+ s: {
+ path: util.getNodePath(range.startContainer, null, null),
+ offset: range.startOffset
+ },
+ e: {
+ path: util.getNodePath(range.endContainer, null, null),
+ offset: range.endOffset
+ }
+ };
+ }
+
+ if (stackIndex === 1 && undo) undo.removeAttribute('disabled');
+
+ core._setCharCount();
+ // onChange
+ change();
+ }
+
+ return {
+ /**
+ * @description History stack
+ */
+ stack: stack,
+
+ /**
+ * @description Saving the current status to the history object stack
+ * If "delay" is true, it will be saved after (options.historyStackDelayTime || 400) miliseconds
+ * If the function is called again with the "delay" argument true before it is saved, the delay time is renewal
+ * You can specify the delay time by sending a number.
+ * @param {Boolean|Number} delay If true, Add stack without delay time.
+ */
+ push: function (delay) {
+ _w.setTimeout(core._resourcesStateChange.bind(core));
+ const time = typeof delay === 'number' ? (delay > 0 ? delay : 0) : (!delay ? 0 : delayTime);
+
+ if (!time || pushDelay) {
+ _w.clearTimeout(pushDelay);
+ if (!time) {
+ pushStack();
+ return;
+ }
+ }
+
+ pushDelay = _w.setTimeout(function () {
+ _w.clearTimeout(pushDelay);
+ pushDelay = null;
+ pushStack();
+ }, time);
+ },
+
+ /**
+ * @description Undo function
+ */
+ undo: function () {
+ if (stackIndex > 0) {
+ stackIndex--;
+ setContentsFromStack();
+ }
+ },
+
+ /**
+ * @description Redo function
+ */
+ redo: function () {
+ if (stack.length - 1 > stackIndex) {
+ stackIndex++;
+ setContentsFromStack();
+ }
+ },
+
+ /**
+ * @description Go to the history stack for that index.
+ * If "index" is -1, go to the last stack
+ * @param {Number} index Stack index
+ */
+ go: function (index) {
+ stackIndex = index < 0 ? (stack.length - 1) : index;
+ setContentsFromStack();
+ },
+
+ /**
+ * @description Reset the history object
+ */
+ reset: function (ignoreChangeEvent) {
+ if (undo) undo.setAttribute('disabled', true);
+ if (redo) redo.setAttribute('disabled', true);
+ if (core.context.tool.save) core.context.tool.save.setAttribute('disabled', true);
+
+ stack.splice(0);
+ stackIndex = 0;
+
+ // pushStack
+ stack[stackIndex] = {
+ contents: core.getContents(true),
+ s: {
+ path: [0, 0],
+ offset: 0
+ },
+ e: {
+ path: [0, 0],
+ offset: 0
+ }
+ };
+
+ if (!ignoreChangeEvent) change();
+ },
+
+ /**
+ * @description Reset the disabled state of the buttons to fit the current stack.
+ * @private
+ */
+ _resetCachingButton: function () {
+ editor = core.context.element;
+ undo = core.context.tool.undo;
+ redo = core.context.tool.redo;
+
+ if (stackIndex === 0) {
+ if (undo) undo.setAttribute('disabled', true);
+ if (redo && stackIndex === stack.length - 1) redo.setAttribute('disabled', true);
+ if (core.context.tool.save) core.context.tool.save.setAttribute('disabled', true);
+ } else if (stackIndex === stack.length - 1) {
+ if (redo) redo.setAttribute('disabled', true);
+ }
+ },
+
+ /**
+ * @description Remove all stacks and remove the timeout function.
+ * @private
+ */
+ _destroy: function () {
+ if (pushDelay) _w.clearTimeout(pushDelay);
+ stack = null;
+ }
+ };
+}
\ No newline at end of file
--- /dev/null
+declare interface util {
+ isIE: boolean;
+ isIE_Edge: boolean;
+ /**
+ * @description Unicode Character 'ZERO WIDTH SPACE' (\u200B)
+ */
+ zeroWidthSpace: string;
+
+ /**
+ * @description Regular expression to find 'zero width space' (/\u200B/g)
+ */
+ zeroWidthRegExp: RegExp;
+
+ /**
+ * @description Regular expression to find only 'zero width space' (/^\u200B+$/)
+ */
+ onlyZeroWidthRegExp: RegExp;
+
+ /**
+ * @description A method that checks If the text is blank or to see if it contains 'ZERO WIDTH SPACE' or empty (util.zeroWidthSpace)
+ * @param text String value or Node
+ * @returns
+ */
+ onlyZeroWidthSpace(text: string | Node): boolean;
+
+ /**
+ * @description Gets XMLHttpRequest object
+ * @returns
+ */
+ getXMLHttpRequest(): XMLHttpRequest | ActiveXObject;
+
+ /**
+ * @description Create Element node
+ * @param elementName Element name
+ * @returns
+ */
+ createElement(elementName: string): Element;
+
+ /**
+ * @description Create text node
+ * @param text text contents
+ * @returns
+ */
+ createTextNode(text: string): Node;
+
+ /**
+ * @description The editor checks tags by string.
+ * If there is "<" or ">" in the attribute of tag, HTML is broken when checking the tag.
+ * When using an attribute with "<" or ">", use "HTMLEncoder" to save. (ex: math(katex))
+ * @param contents HTML or Text string
+ * @returns
+ */
+ HTMLEncoder(contents: string): string;
+
+ /**
+ * @description The editor checks tags by string.
+ * If there is "<" or ">" in the attribute of tag, HTML is broken when checking the tag.
+ * Decoder of data stored as "HTMLEncoder" (ex: math(katex))
+ * @param contents HTML or Text string
+ * @returns
+ */
+ HTMLDecoder(contents: string): string;
+
+ /**
+ * @description This method run Object.prototype.hasOwnProperty.call(obj, key)
+ * @param obj Object
+ * @param key obj.key
+ * @returns
+ */
+ hasOwn(obj: any, key: string): boolean;
+
+ /**
+ * @description Get the the tag path of the arguments value
+ * If not found, return the first found value
+ * @param nameArray File name array
+ * @param extension js, css
+ * @returns
+ */
+ getIncludePath(nameArray: string[], extension: string): string;
+
+ /**
+ * @description Returns the CSS text that has been applied to the current page.
+ * @param doc To get the CSS text of an document(core._wd). If null get the current document.
+ * @returns Styles string
+ */
+ getPageStyle(doc?: Document): string;
+
+ /**
+ * @description Get the argument iframe's document object
+ * @param iframe Iframe element (context.element.wysiwygFrame)
+ * @returns
+ */
+ getIframeDocument(iframe: Element): Document;
+
+ /**
+ * @description Get attributes of argument element to string ('class="---" name="---" ')
+ * @param element Element object
+ * @param exceptAttrs Array of attribute names to exclude from the result
+ * @returns
+ */
+ getAttributesToString(element: Element, exceptAttrs?: string[]): string;
+
+ /**
+ * @descriptionGets Get the length in bytes of a string.
+ * referencing code: "https://github.com/shaan1974/myrdin/blob/master/expressions/string.js#L11"
+ * @param text String text
+ * @returns
+ */
+ getByteLength(text: string): number;
+
+ /**
+ * @description It is judged whether it is the edit region top div element or iframe's body tag.
+ * @param element The node to check
+ * @returns
+ */
+ isWysiwygDiv(element: Node): boolean;
+
+ /**
+ * @description It is judged whether it is the contenteditable property is false.
+ * @param element The node to check
+ * @returns
+ */
+ isNonEditable(element: Node): boolean;
+
+ /**
+ * @description It is judged whether it is a node related to the text style.
+ * (strong|span|font|b|var|i|em|u|ins|s|strike|del|sub|sup|mark|a|label)
+ * @param element The node to check
+ * @returns
+ */
+ isTextStyleElement(element: Node): boolean;
+
+ /**
+ * @description It is judged whether it is the format element (P, DIV, H[1-6], PRE, LI | class="__se__format__replace_xxx")
+ * Format element also contain "free format Element"
+ * @param element The node to check
+ * @returns
+ */
+ isFormatElement(element: Node): boolean;
+
+ /**
+ * @description It is judged whether it is the range format element. (BLOCKQUOTE, OL, UL, FIGCAPTION, TABLE, THEAD, TBODY, TR, TH, TD | class="__se__format__range_xxx")
+ * * Range format element is wrap the format element (util.isFormatElement)
+ * @param element The node to check
+ * @returns
+ */
+ isRangeFormatElement(element: Node): boolean;
+
+ /**
+ * @description It is judged whether it is the closure range format element. (TH, TD | class="__se__format__range__closure_xxx")
+ * Closure range format elements is included in the range format element.
+ * - Closure range format element is wrap the "format element" and "component"
+ * ※ You cannot exit this format with the Enter key or Backspace key.
+ * ※ Use it only in special cases. ([ex] format of table cells)
+ * @param element The node to check
+ * @returns
+ */
+ isClosureRangeFormatElement(element: Node): boolean;
+
+ /**
+ * @description It is judged whether it is the free format element. (PRE | class="__se__format__free_xxx")
+ * Free format elements is included in the format element.
+ * Free format elements's line break is "BR" tag.
+ * ※ Entering the Enter key in the space on the last line ends "Free Format" and appends "Format".
+ * @param element The node to check
+ * @returns
+ */
+ isFreeFormatElement(element: Node): boolean;
+
+ /**
+ * @description It is judged whether it is the closure free format element. (class="__se__format__free__closure_xxx")
+ * Closure free format elements is included in the free format element.
+ * - Closure free format elements's line break is "BR" tag.
+ * ※ You cannot exit this format with the Enter key.
+ * ※ Use it only in special cases. ([ex] format of table cells)
+ * @param element The node to check
+ * @returns
+ */
+ isClosureFreeFormatElement(element: Node): boolean;
+
+ /**
+ * @description It is judged whether it is the component [img, iframe, video, audio] cover(class="se-component") and table, hr
+ * @param element The node to check
+ * @returns
+ */
+ isComponent(element: Node): boolean;
+
+ /**
+ * @description It is judged whether it is the not checking node. (class="katex", "__se__tag")
+ * @param element The node to check
+ * @returns
+ */
+ isMediaComponent(element: Node): boolean;
+
+ /**
+ * @description It is judged whether it is the component [img, iframe] cover(class="se-component")
+ * @param element The node to check
+ * @returns
+ */
+ isNotCheckingNode(element: Node): boolean;
+
+ /**
+ * @description If a parent node that contains an argument node finds a format node (util.isFormatElement), it returns that node.
+ * @param element Reference node.
+ * @param validation Additional validation function.
+ * @returns
+ */
+ getFormatElement(element: Node, validation?: Function): Element | null;
+
+ /**
+ * @description If a parent node that contains an argument node finds a format node (util.isRangeFormatElement), it returns that node.
+ * @param element Reference node.
+ * @param validation Additional validation function.
+ * @returns
+ */
+ getRangeFormatElement(element: Node, validation?: Function): Element | null;
+
+ /**
+ * @description If a parent node that contains an argument node finds a free format node (util.isFreeFormatElement), it returns that node.
+ * @param element Reference node.
+ * @param validation Additional validation function.
+ * @returns
+ */
+ getFreeFormatElement(element: Node, validation?: Function): Element | null;
+
+ /**
+ * @description If a parent node that contains an argument node finds a closure free format node (util.isClosureFreeFormatElement), it returns that node.
+ * @param element Reference node.
+ * @param validation Additional validation function.
+ * @returns
+ */
+ getClosureFreeFormatElement(element: Node, validation?: Function): Element | null;
+
+ /**
+ * @description Add style and className of copyEl to originEl
+ * @param originEl Origin element
+ * @param copyEl Element to copy
+ */
+ copyTagAttributes(originEl: Element, copyEl: Element): void;
+
+ /**
+ * @description Copy and apply attributes of format tag that should be maintained. (style, class) Ignore "__se__format__" class
+ * @param originEl Origin element
+ * @param copyEl Element to copy
+ */
+ copyFormatAttributes(originEl: Element, copyEl: Element): void;
+
+ /**
+ * @description Get the item from the array that matches the condition.
+ * @param array Array to get item
+ * @param validation Conditional function
+ * @param multi If true, returns all items that meet the criteria otherwise, returns an empty array.
+ * If false, returns only one item that meet the criteria otherwise return null.
+ * @returns
+ */
+ getArrayItem(array: any[] | HTMLCollection | NodeList, validation: Function | null, multi: boolean): any[] | Node | null;
+
+ /**
+ * @description Get the index of the argument value in the element array
+ * @param array element array
+ * @param element The element to find index
+ * @returns
+ */
+ getArrayIndex(array: any[] | HTMLCollection | NodeList, element: Node): number;
+
+ /**
+ * @description Get the next index of the argument value in the element array
+ * @param array element array
+ * @param item The element to find index
+ * @returns
+ */
+ nextIdx(array: any[] | HTMLCollection | NodeList, item: Node): number;
+
+ /**
+ * @description Get the previous index of the argument value in the element array
+ * @param array Element array
+ * @param item The element to find index
+ * @returns
+ */
+ prevIdx(array: any[] | HTMLCollection | NodeList, item: Node): number;
+
+ /**
+ * @description Returns the index compared to other sibling nodes.
+ * @param node The Node to find index
+ * @returns
+ */
+ getPositionIndex(node: Node): number;
+
+ /**
+ * @description Returns the position of the "node" in the "parentNode" in a numerical array.
+ * ex) <p><span>aa</span><span>bb</span></p> : getNodePath(node: "bb", parentNode: "<P>") -> [1, 0]
+ * @param node The Node to find position path
+ * @param parentNode Parent node. If null, wysiwyg div area
+ * @param _newOffsets If you send an object of the form "{s: 0, e: 0}", the text nodes that are attached together are merged into one, centered on the "node" argument.
+ * "_newOffsets.s" stores the length of the combined characters after "node" and "_newOffsets.e" stores the length of the combined characters before "node".
+ * Do not use unless absolutely necessary.
+ * @returns
+ */
+ getNodePath(node: Node, parentNode?: Node, _newOffsets?: { s: number; e: number; }): number[];
+
+ /**
+ * @description Returns the node in the location of the path array obtained from "util.getNodePath".
+ * @param offsets Position array, array obtained from "util.getNodePath"
+ * @param parentNode Base parent element
+ * @returns
+ */
+ getNodeFromPath(offsets: number[], parentNode: Node): Node;
+
+ /**
+ * @description Compares the style and class for equal values.
+ * Returns true if both are text nodes.
+ * @param a Node to compare
+ * @param b Node to compare
+ * @returns
+ */
+ isSameAttributes(a: Node, b: Node): boolean;
+
+ /**
+ * @description Check the node is a list (ol, ul)
+ * @param node The element or element name to check
+ * @returns
+ */
+ isList(node: string | Node): boolean;
+
+ /**
+ * @description Check the node is a list cell (li)
+ * @param node The element or element name to check
+ * @returns
+ */
+ isListCell(node: string | Node): boolean;
+
+ /**
+ * @description Check the node is a table (table, thead, tbody, tr, th, td)
+ * @param node The element or element name to check
+ * @returns
+ */
+ isTable(node: string | Node): boolean;
+
+ /**
+ * @description Check the node is a table cell (td, th)
+ * @param node The element or element name to check
+ * @returns
+ */
+ isCell(node: string | Node): boolean;
+
+ /**
+ * @description Check the node is a break node (BR)
+ * @param node The element or element name to check
+ * @returns
+ */
+ isBreak(node: string | Node): boolean;
+
+ /**
+ * @description Check the node is a anchor node (A)
+ * @param node The element or element name to check
+ * @returns
+ */
+ isAnchor(node: string | Node): boolean;
+
+ /**
+ * @description Check the node is a media node (img, iframe, audio, video, canvas)
+ * @param node The element or element name to check
+ * @returns
+ */
+ isMedia(node: string | Node): boolean;
+
+ /**
+ * @description Checks for numeric (with decimal point).
+ * @param text Text string or number
+ * @returns
+ */
+ isNumber(text: string | number): boolean;
+
+ /**
+ * @description Get a number.
+ * @param text Text string or number
+ * @param maxDec Maximum number of decimal places (-1 : Infinity)
+ * @returns
+ */
+ getNumber(text: string | number, maxDec: number): number;
+
+ /**
+ * @description Get all "children" of the argument value element (Without text nodes)
+ * @param element element to get child node
+ * @param validation Conditional function
+ * @returns
+ */
+ getListChildren(element: Element, validation?: Function): Element[];
+
+ /**
+ * @description Get all "childNodes" of the argument value element (Include text nodes)
+ * @param element element to get child node
+ * @param validation Conditional function
+ * @returns
+ */
+ getListChildNodes(element: Node, validation?: Function): Node[];
+
+ /**
+ * @description Returns the number of parents nodes.
+ * "0" when the parent node is the WYSIWYG area.
+ * "-1" when the element argument is the WYSIWYG area.
+ * @param element The element to check
+ * @returns
+ */
+ getElementDepth(element: Node): number;
+
+ /**
+ * @description Compares two elements to find a common ancestor, and returns the order of the two elements.
+ * @param a Node to compare.
+ * @param b Node to compare.
+ * @returns
+ */
+ compareElements(a: Node, b: Node): {ancestor: Element | null, a: Node, b: Node, result: number};
+
+ /**
+ * @description Get the parent element of the argument value.
+ * A tag that satisfies the query condition is imported.
+ * Returns null if not found.
+ * @param element Reference element
+ * @param query Query String (nodeName, .className, #ID, :name) or validation function.
+ * Not use it like jquery.
+ * Only one condition can be entered at a time.
+ * @returns
+ */
+ getParentElement(element: Node, query: TimerHandler): Element;
+
+ /**
+ * @description Get the child element of the argument value.
+ * A tag that satisfies the query condition is imported.
+ * Returns null if not found.
+ * @param element Reference element
+ * @param query Query String (nodeName, .className, #ID, :name) or validation function.
+ * @param last If true returns the last node among the found child nodes. (default: first node)
+ * Not use it like jquery.
+ * Only one condition can be entered at a time.
+ * @returns
+ */
+ getChildElement(element: Node, query: TimerHandler, last: boolean): Element;
+
+ /**
+ * @description 1. The first node of all the child nodes of the "first" element is returned.
+ * 2. The last node of all the child nodes of the "last" element is returned.
+ * 3. When there is no "last" element, the first and last nodes of all the children of the "first" element are returned.
+ * { sc: "first", ec: "last" }
+ * @param first First element
+ * @param last Last element
+ * @returns
+ */
+ getEdgeChildNodes(first: Node, last?: Node): {sc: Node; ec: Node | null;};
+
+ /**
+ * @description Returns the position of the left and top of argument. {left:0, top:0}
+ * @param element Target node
+ * @param wysiwygFrame When use iframe option, iframe object should be sent (context.element.wysiwygFrame)
+ * @returns
+ */
+ getOffset(element: Node, wysiwygFrame?: Element): Record<string, number>;
+
+ /**
+ * @description It compares the start and end indexes of "a" and "b" and returns the number of overlapping indexes in the range.
+ * ex) 1, 5, 4, 6 => "2" (4 ~ 5)
+ * @param aStart Start index of "a"
+ * @param aEnd End index of "a"
+ * @param bStart Start index of "b"
+ * @param bEnd Start index of "b"
+ * @returns
+ */
+ getOverlapRangeAtIndex(aStart: number, aEnd: number, bStart: number, bEnd: number): number;
+
+ /**
+ * @description Set the text content value of the argument value element
+ * @param element Element to replace text content
+ * @param txt Text to be applied
+ */
+ changeTxt(element: Node, txt: string): void;
+
+ /**
+ * @description Replace icon
+ * @param element Target element
+ * @param newElement String or element of the new element to apply
+ */
+ changeElement(icon: Element, newIcon: string | Element): void;
+
+ /**
+ * @description Set style, if all styles are deleted, the style properties are deleted.
+ * @param element Element to set style
+ * @param styleName Style attribute name (marginLeft, textAlign...)
+ * @param value Style value
+ */
+ setStyle(element: Element, styleName: string, value: string | number): void;
+
+ /**
+ * @description Determine whether any of the matched elements are assigned the given class
+ * @param element Elements to search class name
+ * @param className Class name to search for
+ * @returns
+ */
+ hasClass(element: Element, className: string): boolean;
+
+ /**
+ * @description Append the className value of the argument value element
+ * @param element Elements to add class name
+ * @param className Class name to be add
+ */
+ addClass(element: Element, className: string): void;
+
+ /**
+ * @description Delete the className value of the argument value element
+ * @param element Elements to remove class name
+ * @param className Class name to be remove
+ */
+ removeClass(element: Element, className: string): void;
+
+ /**
+ * @description Argument value If there is no class name, insert it and delete the class name if it exists
+ * @param element Elements to replace class name
+ * @param className Class name to be change
+ */
+ toggleClass(element: Element, className: string): void;
+
+ /**
+ * @description In the predefined code view mode, the buttons except the executable button are changed to the 'disabled' state.
+ * core.codeViewDisabledButtons (An array of buttons whose class name is not "se-code-view-enabled")
+ * core.resizingDisabledButtons (An array of buttons whose class name is not "se-resizing-enabled")
+ * @param disabled Disabled value
+ * @param buttonList Button array
+ */
+ setDisabledButtons(disabled: boolean, buttonList: Element[] | HTMLCollection | NodeList): void;
+
+ /**
+ * @description Delete argumenu value element
+ * @param item Node to be remove
+ */
+ removeItem(item: Node): void;
+
+ /**
+ * @description Delete all parent nodes that match the condition.
+ * Returns an {sc: previousSibling, ec: nextSibling}(the deleted node reference) or null.
+ * @param item Node to be remove
+ * @param validation Validation function. default(Deleted if it only have breakLine and blanks)
+ * @param stopParent Stop when the parent node reaches stopParent
+ * @returns
+ */
+ removeItemAllParents(item: Node, validation?: Function, stopParent?: Element): Record<string, Node | null> | null;
+
+ /**
+ * @description Detach Nested all nested lists under the "baseNode".
+ * Returns a list with nested removed.
+ * @param baseNode Element on which to base.
+ * @param all If true, it also detach all nested lists of a returned list.
+ * @returns
+ */
+ detachNestedList(baseNode: Node, all: boolean): Element;
+
+ /**
+ * @description Split all tags based on "baseNode"
+ * Returns the last element of the splited tag.
+ * @param baseNode Element or text node on which to base
+ * @param offset Text offset of "baseNode" (Only valid when "baseNode" is a text node)
+ * @param depth The nesting depth of the element being split. (default: 0)
+ * @returns
+ */
+ splitElement(baseNode: Node, offset: number | null, depth: number): Element;
+
+ /**
+ * @description Use with "npdePath (util.getNodePath)" to merge the same attributes and tags if they are present and modify the nodepath.
+ * If "offset" has been changed, it will return as much "offset" as it has been modified.
+ * An array containing change offsets is returned in the order of the "nodePathArray" array.
+ * @param element Element
+ * @param nodePathArray Array of NodePath object ([util.getNodePath(), ..])
+ * @param onlyText If true, non-text nodes(!util._isIgnoreNodeChange) like 'span', 'strong'.. are ignored.
+ * @returns [offset, ..]
+ */
+ mergeSameTags(element: Element, nodePathArray: any[], onlyText: boolean): number[];
+
+ /**
+ * @description Remove nested tags without other child nodes.
+ * @param element Element object
+ * @param validation Validation function / String("tag1|tag2..") / If null, all tags are applicable.
+ */
+ mergeNestedTags(element: Element, validation?: TimerHandler): void;
+
+ /**
+ * @description Delete a empty child node of argument element
+ * @param element Element node
+ * @param notRemoveNode Do not remove node
+ */
+ removeEmptyNode(element: Element, notRemoveNode?: Node): void;
+
+ /**
+ * @description Remove whitespace between tags in HTML string.
+ * @param html HTML string
+ * @returns
+ */
+ htmlRemoveWhiteSpace(html: string): string;
+
+ /**
+ * @description Sort a element array by depth of element.
+ * @param array Array object
+ * @param des true: descending order / false: ascending order
+ */
+ sortByDepth(array: Node[], des: boolean): void;
+
+ /**
+ * @description Create whitelist RegExp object.
+ * Return RegExp format: new RegExp("<\\/?\\b(?!" + list + ")\\b[^>^<]*+>", "gi")
+ * @param list Tags list ("br|p|div|pre...")
+ * @returns
+ */
+ createTagsWhitelist(list: string): RegExp;
+}
+
+export default util;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+/**
+ * @description utility function
+ */
+const util = {
+ _d: null,
+ _w: null,
+ isIE: null,
+ isIE_Edge: null,
+ isOSX_IOS: null,
+ _propertiesInit: function () {
+ if (this._d) return;
+ this._d = document;
+ this._w = window;
+ this.isIE = navigator.userAgent.indexOf('Trident') > -1;
+ this.isIE_Edge = (navigator.userAgent.indexOf('Trident') > -1) || (navigator.appVersion.indexOf('Edge') > -1);
+ this.isOSX_IOS = /(Mac|iPhone|iPod|iPad)/.test(navigator.platform);
+ },
+
+ /**
+ * @description HTML Reserved Word Converter.
+ * @param {String} contents
+ * @returns {String} HTML string
+ * @private
+ */
+ _HTMLConvertor: function (contents) {
+ const ec = {'&': '&', '\u00A0': ' ', '\'': ''', '"': '"', '<': '<', '>': '>'};
+ return contents.replace(/&|\u00A0|'|"|<|>/g, function (m) {
+ return (typeof ec[m] === 'string') ? ec[m] : m;
+ });
+ },
+
+ /**
+ * @description Unicode Character 'ZERO WIDTH SPACE' (\u200B)
+ */
+ zeroWidthSpace: String.fromCharCode(8203),
+
+ /**
+ * @description Regular expression to find 'zero width space' (/\u200B/g)
+ */
+ zeroWidthRegExp: new RegExp(String.fromCharCode(8203), 'g'),
+
+ /**
+ * @description Regular expression to find only 'zero width space' (/^\u200B+$/)
+ */
+ onlyZeroWidthRegExp: new RegExp('^' + String.fromCharCode(8203) + '+$'),
+
+ /**
+ * @description A method that checks If the text is blank or to see if it contains 'ZERO WIDTH SPACE' or empty (util.zeroWidthSpace)
+ * @param {String|Node} text String value or Node
+ * @returns {Boolean}
+ */
+ onlyZeroWidthSpace: function (text) {
+ if (typeof text !== 'string') text = text.textContent;
+ return text === '' || this.onlyZeroWidthRegExp.test(text);
+ },
+
+ /**
+ * @description Gets XMLHttpRequest object
+ * @returns {XMLHttpRequest|ActiveXObject}
+ */
+ getXMLHttpRequest: function () {
+ /** IE */
+ if (this._w.ActiveXObject) {
+ try {
+ return new ActiveXObject('Msxml2.XMLHTTP');
+ } catch (e) {
+ try {
+ return new ActiveXObject('Microsoft.XMLHTTP');
+ } catch (e1) {
+ return null;
+ }
+ }
+ }
+ /** netscape */
+ else if (this._w.XMLHttpRequest) {
+ return new XMLHttpRequest();
+ }
+ /** fail */
+ else {
+ return null;
+ }
+ },
+
+ /**
+ * @description Create Element node
+ * @param {String} elementName Element name
+ * @returns {Element}
+ */
+ createElement: function (elementName) {
+ return this._d.createElement(elementName);
+ },
+
+ /**
+ * @description Create text node
+ * @param {String} text text contents
+ * @returns {Node}
+ */
+ createTextNode: function (text) {
+ return this._d.createTextNode(text || '');
+ },
+
+ /**
+ * @description The editor checks tags by string.
+ * If there is "<" or ">" in the attribute of tag, HTML is broken when checking the tag.
+ * When using an attribute with "<" or ">", use "HTMLEncoder" to save. (ex: math(katex))
+ * @param {String} contents HTML or Text string
+ * @returns {String}
+ */
+ HTMLEncoder: function (contents) {
+ const ec = {'<': '$lt;', '>': '$gt;'};
+ return contents.replace(/<|>/g, function (m) {
+ return (typeof ec[m] === 'string') ? ec[m] : m;
+ });
+ },
+
+ /**
+ * @description The editor checks tags by string.
+ * If there is "<" or ">" in the attribute of tag, HTML is broken when checking the tag.
+ * Decoder of data stored as "HTMLEncoder" (ex: math(katex))
+ * @param {String} contents HTML or Text string
+ * @returns {String}
+ */
+ HTMLDecoder: function (contents) {
+ const ec = {'$lt;': '<', '$gt;': '>'};
+ return contents.replace(/\$lt;|\$gt;/g, function (m) {
+ return (typeof ec[m] === 'string') ? ec[m] : m;
+ });
+ },
+
+ /**
+ * @description This method run Object.prototype.hasOwnProperty.call(obj, key)
+ * @param {Object} obj Object
+ * @param {String} key obj.key
+ * @returns {Boolean}
+ */
+ hasOwn: function (obj, key) {
+ return this._hasOwn.call(obj, key);
+ },
+ _hasOwn: Object.prototype.hasOwnProperty,
+
+ /**
+ * @deprecated
+ * @description Get the the tag path of the arguments value
+ * If not found, return the first found value
+ * @param {Array} nameArray File name array
+ * @param {String} extension js, css
+ * @returns {String}
+ */
+ getIncludePath: function (nameArray, extension) {
+ let path = '';
+ const pathList = [];
+ const tagName = extension === 'js' ? 'script' : 'link';
+ const src = extension === 'js' ? 'src' : 'href';
+
+ let fileName = '(?:';
+ for (let i = 0, len = nameArray.length; i < len; i++) {
+ fileName += nameArray[i] + (i < len - 1 ? '|' : ')');
+ }
+
+ const regExp = new this._w.RegExp('(^|.*[\\/])' + fileName + '(\\.[^\\/]+)?\.' + extension + '(?:\\?.*|;.*)?$', 'i');
+ const extRegExp = new this._w.RegExp('.+\\.' + extension + '(?:\\?.*|;.*)?$', 'i');
+
+ for (let c = this._d.getElementsByTagName(tagName), i = 0; i < c.length; i++) {
+ if (extRegExp.test(c[i][src])) {
+ pathList.push(c[i]);
+ }
+ }
+
+ for (let i = 0; i < pathList.length; i++) {
+ let editorTag = pathList[i][src].match(regExp);
+ if (editorTag) {
+ path = editorTag[0];
+ break;
+ }
+ }
+
+ if (path === '') path = pathList.length > 0 ? pathList[0][src] : '';
+
+ -1 === path.indexOf(':/') && '//' !== path.slice(0, 2) && (path = 0 === path.indexOf('/') ? location.href.match(/^.*?:\/\/[^\/]*/)[0] + path : location.href.match(/^[^\?]*\/(?:)/)[0] + path);
+
+ if (!path) throw '[SUNEDITOR.util.getIncludePath.fail] The SUNEDITOR installation path could not be automatically detected. (name: +' + name + ', extension: ' + extension + ')';
+
+ return path;
+ },
+
+ /**
+ * @deprecated
+ * @description Returns the CSS text that has been applied to the current page.
+ * @param {Document|null} doc To get the CSS text of an document(core._wd). If null get the current document.
+ * @returns {String} Styles string
+ */
+ getPageStyle: function (doc) {
+ let cssText = '';
+ const sheets = (doc || this._d).styleSheets;
+
+ for (let i = 0, len = sheets.length, rules; i < len; i++) {
+ try {
+ rules = sheets[i].cssRules;
+ } catch (e) {
+ continue;
+ }
+
+ for (let c = 0, cLen = rules.length; c < cLen; c++) {
+ cssText += rules[c].cssText;
+ }
+ }
+
+ return cssText;
+ },
+
+ /**
+ * @description Get the argument iframe's document object
+ * @param {Element} iframe Iframe element (context.element.wysiwygFrame)
+ * @returns {Document}
+ */
+ getIframeDocument: function (iframe) {
+ let wDocument = iframe.contentWindow || iframe.contentDocument;
+ if (wDocument.document) wDocument = wDocument.document;
+ return wDocument;
+ },
+
+ /**
+ * @description Get attributes of argument element to string ('class="---" name="---" ')
+ * @param {Element} element Element object
+ * @param {Array|null} exceptAttrs Array of attribute names to exclude from the result
+ * @returns {String}
+ */
+ getAttributesToString: function (element, exceptAttrs) {
+ if (!element.attributes) return '';
+
+ const attrs = element.attributes;
+ let attrString = '';
+
+ for (let i = 0, len = attrs.length; i < len; i++) {
+ if (exceptAttrs && exceptAttrs.indexOf(attrs[i].name) > -1) continue;
+ attrString += attrs[i].name + '="' + attrs[i].value + '" ';
+ }
+
+ return attrString;
+ },
+
+ /**
+ * @descriptionGets Get the length in bytes of a string.
+ * referencing code: "https://github.com/shaan1974/myrdin/blob/master/expressions/string.js#L11"
+ * @param {String} text String text
+ * @returns {Number}
+ */
+ getByteLength: function(text) {
+ const encoder = this._w.encodeURIComponent;
+ let cr, cl;
+ if (this.isIE_Edge) {
+ cl = this._w.unescape(encoder(text.toString())).length;
+ cr = 0;
+
+ if (encoder(text.toString()).match(/(%0A|%0D)/gi) !== null) {
+ cr = encoder(text.toString()).match(/(%0A|%0D)/gi).length;
+ }
+
+ return cl + cr;
+ } else {
+ cl = (new this._w.TextEncoder('utf-8').encode(text.toString())).length;
+ cr = 0;
+
+ if (encoder(text.toString()).match(/(%0A|%0D)/gi) !== null) {
+ cr = encoder(text.toString()).match(/(%0A|%0D)/gi).length;
+ }
+
+ return cl + cr;
+ }
+ },
+
+ /**
+ * @description It is judged whether it is the edit region top div element or iframe's body tag.
+ * @param {Node} element The node to check
+ * @returns {Boolean}
+ */
+ isWysiwygDiv: function (element) {
+ return element && element.nodeType === 1 && (this.hasClass(element, 'se-wrapper-wysiwyg') || /^BODY$/i.test(element.nodeName));
+ },
+
+ /**
+ * @description It is judged whether it is the contenteditable property is false.
+ * @param {Node} element The node to check
+ * @returns {Boolean}
+ */
+ isNonEditable: function (element) {
+ return element && element.nodeType === 1 && element.getAttribute('contenteditable') === 'false';
+ },
+
+ /**
+ * @description It is judged whether it is a node related to the text style.
+ * (strong|span|font|b|var|i|em|u|ins|s|strike|del|sub|sup|mark|a|label|code)
+ * @param {Node} element The node to check
+ * @returns {Boolean}
+ */
+ isTextStyleElement: function (element) {
+ return element && element.nodeType !== 3 && /^(strong|span|font|b|var|i|em|u|ins|s|strike|del|sub|sup|mark|a|label|code)$/i.test(element.nodeName);
+ },
+
+ /**
+ * @description It is judged whether it is the format element (P, DIV, H[1-6], PRE, LI | class="__se__format__replace_xxx")
+ * Format element also contain "free format Element"
+ * @param {Node} element The node to check
+ * @returns {Boolean}
+ */
+ isFormatElement: function (element) {
+ return element && element.nodeType === 1 && (/^(P|DIV|H[1-6]|PRE|LI|TH|TD)$/i.test(element.nodeName) || this.hasClass(element, '(\\s|^)__se__format__replace_.+(\\s|$)|(\\s|^)__se__format__free_.+(\\s|$)')) && !this.isComponent(element) && !this.isWysiwygDiv(element);
+ },
+
+ /**
+ * @description It is judged whether it is the range format element. (BLOCKQUOTE, OL, UL, FIGCAPTION, TABLE, THEAD, TBODY, TR, TH, TD | class="__se__format__range_xxx")
+ * Range format element is wrap the "format element" and "component"
+ * @param {Node} element The node to check
+ * @returns {Boolean}
+ */
+ isRangeFormatElement: function (element) {
+ return element && element.nodeType === 1 && (/^(BLOCKQUOTE|OL|UL|FIGCAPTION|TABLE|THEAD|TBODY|TR|TH|TD)$/i.test(element.nodeName) || this.hasClass(element, '(\\s|^)__se__format__range_.+(\\s|$)'));
+ },
+
+ /**
+ * @description It is judged whether it is the closure range format element. (TH, TD | class="__se__format__range__closure_xxx")
+ * Closure range format elements is included in the range format element.
+ * - Closure range format element is wrap the "format element" and "component"
+ * ※ You cannot exit this format with the Enter key or Backspace key.
+ * ※ Use it only in special cases. ([ex] format of table cells)
+ * @param {Node} element The node to check
+ * @returns {Boolean}
+ */
+ isClosureRangeFormatElement: function (element) {
+ return element && element.nodeType === 1 && (/^(TH|TD)$/i.test(element.nodeName) || this.hasClass(element, '(\\s|^)__se__format__range__closure_.+(\\s|$)'));
+ },
+
+ /**
+ * @description It is judged whether it is the free format element. (PRE | class="__se__format__free_xxx")
+ * Free format elements is included in the format element.
+ * Free format elements's line break is "BR" tag.
+ * ※ Entering the Enter key in the space on the last line ends "Free Format" and appends "Format".
+ * @param {Node} element The node to check
+ * @returns {Boolean}
+ */
+ isFreeFormatElement: function (element) {
+ return element && element.nodeType === 1 && (/^PRE$/i.test(element.nodeName) || this.hasClass(element, '(\\s|^)__se__format__free_.+(\\s|$)')) && !this.isComponent(element) && !this.isWysiwygDiv(element);
+ },
+
+ /**
+ * @description It is judged whether it is the closure free format element. (class="__se__format__free__closure_xxx")
+ * Closure free format elements is included in the free format element.
+ * - Closure free format elements's line break is "BR" tag.
+ * ※ You cannot exit this format with the Enter key or Backspace key.
+ * ※ Use it only in special cases. ([ex] format of table cells)
+ * @param {Node} element The node to check
+ * @returns {Boolean}
+ */
+ isClosureFreeFormatElement: function (element) {
+ return element && element.nodeType === 1 && this.hasClass(element, '(\\s|^)__se__format__free__closure_.+(\\s|$)');
+ },
+
+ /**
+ * @description It is judged whether it is the component [img, iframe, video, audio] cover(class="se-component") and table, hr
+ * @param {Node} element The node to check
+ * @returns {Boolean}
+ */
+ isComponent: function (element) {
+ return element && (/se-component/.test(element.className) || /^(TABLE|HR)$/.test(element.nodeName));
+ },
+
+ /**
+ * @description It is judged whether it is the component [img, iframe] cover(class="se-component")
+ * @param {Node} element The node to check
+ * @returns {Boolean}
+ */
+ isMediaComponent: function (element) {
+ return element && /se-component/.test(element.className);
+ },
+
+ /**
+ * @description It is judged whether it is the not checking node. (class="katex", "__se__tag")
+ * @param {Node} element The node to check
+ * @returns {Boolean}
+ */
+ isNotCheckingNode: function (element) {
+ return element && /katex|__se__tag/.test(element.className);
+ },
+
+ /**
+ * @description If a parent node that contains an argument node finds a format node (util.isFormatElement), it returns that node.
+ * @param {Node} element Reference node.
+ * @param {Function|null} validation Additional validation function.
+ * @returns {Element|null}
+ */
+ getFormatElement: function (element, validation) {
+ if (!element) return null;
+ if (!validation) {
+ validation = function () { return true; };
+ }
+
+ while (element) {
+ if (this.isWysiwygDiv(element)) return null;
+ if (this.isRangeFormatElement(element)) element.firstElementChild;
+ if (this.isFormatElement(element) && validation(element)) return element;
+
+ element = element.parentNode;
+ }
+
+ return null;
+ },
+
+ /**
+ * @description If a parent node that contains an argument node finds a format node (util.isRangeFormatElement), it returns that node.
+ * @param {Node} element Reference node.
+ * @param {Function|null} validation Additional validation function.
+ * @returns {Element|null}
+ */
+ getRangeFormatElement: function (element, validation) {
+ if (!element) return null;
+ if (!validation) {
+ validation = function () { return true; };
+ }
+
+ while (element) {
+ if (this.isWysiwygDiv(element)) return null;
+ if (this.isRangeFormatElement(element) && !/^(THEAD|TBODY|TR)$/i.test(element.nodeName) && validation(element)) return element;
+ element = element.parentNode;
+ }
+
+ return null;
+ },
+
+ /**
+ * @description If a parent node that contains an argument node finds a free format node (util.isFreeFormatElement), it returns that node.
+ * @param {Node} element Reference node.
+ * @param {Function|null} validation Additional validation function.
+ * @returns {Element|null}
+ */
+ getFreeFormatElement: function (element, validation) {
+ if (!element) return null;
+ if (!validation) {
+ validation = function () { return true; };
+ }
+
+ while (element) {
+ if (this.isWysiwygDiv(element)) return null;
+ if (this.isFreeFormatElement(element) && validation(element)) return element;
+
+ element = element.parentNode;
+ }
+
+ return null;
+ },
+
+ /**
+ * @description If a parent node that contains an argument node finds a closure free format node (util.isClosureFreeFormatElement), it returns that node.
+ * @param {Node} element Reference node.
+ * @param {Function|null} validation Additional validation function.
+ * @returns {Element|null}
+ */
+ getClosureFreeFormatElement: function (element, validation) {
+ if (!element) return null;
+ if (!validation) {
+ validation = function () { return true; };
+ }
+
+ while (element) {
+ if (this.isWysiwygDiv(element)) return null;
+ if (this.isClosureFreeFormatElement(element) && validation(element)) return element;
+
+ element = element.parentNode;
+ }
+
+ return null;
+ },
+
+ /**
+ * @description Add style and className of copyEl to originEl
+ * @param {Element} originEl Origin element
+ * @param {Element} copyEl Element to copy
+ */
+ copyTagAttributes: function (originEl, copyEl) {
+ if (copyEl.style.cssText) {
+ originEl.style.cssText += copyEl.style.cssText;
+ }
+
+ const classes = copyEl.classList;
+ for (let i = 0, len = classes.length; i < len; i++) {
+ this.addClass(originEl, classes[i]);
+ }
+
+ if (!originEl.style.cssText) originEl.removeAttribute('style');
+ if (!originEl.className.trim()) originEl.removeAttribute('class');
+ },
+
+ /**
+ * @description Copy and apply attributes of format tag that should be maintained. (style, class) Ignore "__se__format__" class
+ * @param {Element} originEl Origin element
+ * @param {Element} copyEl Element to copy
+ */
+ copyFormatAttributes: function (originEl, copyEl) {
+ copyEl = copyEl.cloneNode(false);
+ copyEl.className = copyEl.className.replace(/(\s|^)__se__format__[^\s]+/g, '');
+ this.copyTagAttributes(originEl, copyEl);
+ },
+
+ /**
+ * @description Get the item from the array that matches the condition.
+ * @param {Array|HTMLCollection|NodeList} array Array to get item
+ * @param {Function|null} validation Conditional function
+ * @param {Boolean} multi If true, returns all items that meet the criteria otherwise, returns an empty array.
+ * If false, returns only one item that meet the criteria otherwise return null.
+ * @returns {Array|Node|null}
+ */
+ getArrayItem: function (array, validation, multi) {
+ if (!array || array.length === 0) return null;
+
+ validation = validation || function () { return true; };
+ const arr = [];
+
+ for (let i = 0, len = array.length, a; i < len; i++) {
+ a = array[i];
+ if (validation(a)) {
+ if (!multi) return a;
+ else arr.push(a);
+ }
+ }
+
+ return !multi ? null : arr;
+ },
+
+ /**
+ * @description Get the index of the argument value in the element array
+ * @param {Array|HTMLCollection|NodeList} array element array
+ * @param {Node} element The element to find index
+ * @returns {Number}
+ */
+ getArrayIndex: function (array, element) {
+ let idx = -1;
+ for (let i = 0, len = array.length; i < len; i++) {
+ if (array[i] === element) {
+ idx = i;
+ break;
+ }
+ }
+
+ return idx;
+ },
+
+ /**
+ * @description Get the next index of the argument value in the element array
+ * @param {Array|HTMLCollection|NodeList} array element array
+ * @param {Node} item The element to find index
+ * @returns {Number}
+ */
+ nextIdx: function (array, item) {
+ let idx = this.getArrayIndex(array, item);
+ if (idx === -1) return -1;
+ return idx + 1;
+ },
+
+ /**
+ * @description Get the previous index of the argument value in the element array
+ * @param {Array|HTMLCollection|NodeList} array Element array
+ * @param {Node} item The element to find index
+ * @returns {Number}
+ */
+ prevIdx: function (array, item) {
+ let idx = this.getArrayIndex(array, item);
+ if (idx === -1) return -1;
+ return idx - 1;
+ },
+
+ /**
+ * @description Returns the index compared to other sibling nodes.
+ * @param {Node} node The Node to find index
+ * @returns {Number}
+ */
+ getPositionIndex: function (node) {
+ let idx = 0;
+ while ((node = node.previousSibling)) {
+ idx += 1;
+ }
+ return idx;
+ },
+
+ /**
+ * @description Returns the position of the "node" in the "parentNode" in a numerical array.
+ * ex) <p><span>aa</span><span>bb</span></p> : getNodePath(node: "bb", parentNode: "<P>") -> [1, 0]
+ * @param {Node} node The Node to find position path
+ * @param {Node|null} parentNode Parent node. If null, wysiwyg div area
+ * @param {Object|null} _newOffsets If you send an object of the form "{s: 0, e: 0}", the text nodes that are attached together are merged into one, centered on the "node" argument.
+ * "_newOffsets.s" stores the length of the combined characters after "node" and "_newOffsets.e" stores the length of the combined characters before "node".
+ * Do not use unless absolutely necessary.
+ * @returns {Array}
+ */
+ getNodePath: function (node, parentNode, _newOffsets) {
+ const path = [];
+ let finds = true;
+
+ this.getParentElement(node, function (el) {
+ if (el === parentNode) finds = false;
+ if (finds && !this.isWysiwygDiv(el)) {
+ // merge text nodes
+ if (_newOffsets && el.nodeType === 3) {
+ let temp = null, tempText = null;
+ _newOffsets.s = _newOffsets.e = 0;
+
+ let previous = el.previousSibling;
+ while (previous && previous.nodeType === 3) {
+ tempText = previous.textContent.replace(this.zeroWidthRegExp, '');
+ _newOffsets.s += tempText.length;
+ el.textContent = tempText + el.textContent;
+ temp = previous;
+ previous = previous.previousSibling;
+ this.removeItem(temp);
+ }
+
+ let next = el.nextSibling;
+ while (next && next.nodeType === 3) {
+ tempText = next.textContent.replace(this.zeroWidthRegExp, '');
+ _newOffsets.e += tempText.length;
+ el.textContent += tempText;
+ temp = next;
+ next = next.nextSibling;
+ this.removeItem(temp);
+ }
+ }
+
+ // index push
+ path.push(el);
+ }
+ return false;
+ }.bind(this));
+
+ return path.map(this.getPositionIndex).reverse();
+ },
+
+ /**
+ * @description Returns the node in the location of the path array obtained from "util.getNodePath".
+ * @param {Array} offsets Position array, array obtained from "util.getNodePath"
+ * @param {Node} parentNode Base parent element
+ * @returns {Node}
+ */
+ getNodeFromPath: function (offsets, parentNode) {
+ let current = parentNode;
+ let nodes;
+
+ for (let i = 0, len = offsets.length; i < len; i++) {
+ nodes = current.childNodes;
+ if (nodes.length === 0) break;
+ if (nodes.length <= offsets[i]) {
+ current = nodes[nodes.length - 1];
+ } else {
+ current = nodes[offsets[i]];
+ }
+ }
+
+ return current;
+ },
+
+ /**
+ * @description Compares the style and class for equal values.
+ * Returns true if both are text nodes.
+ * @param {Node} a Node to compare
+ * @param {Node} b Node to compare
+ * @returns {Boolean}
+ */
+ isSameAttributes: function (a, b) {
+ if (a.nodeType === 3 && b.nodeType === 3) return true;
+ if (a.nodeType === 3 || b.nodeType === 3) return false;
+
+ const style_a = a.style;
+ const style_b = b.style;
+ let compStyle = 0;
+
+ for (let i = 0, len = style_a.length; i < len; i++) {
+ if (style_a[style_a[i]] === style_b[style_a[i]]) compStyle++;
+ }
+
+ const class_a = a.classList;
+ const class_b = b.classList;
+ const reg = this._w.RegExp;
+ let compClass = 0;
+
+ for (let i = 0, len = class_a.length; i < len; i++) {
+ if (reg('(\s|^)' + class_a[i] + '(\s|$)').test(class_b.value)) compClass++;
+ }
+
+ return (compStyle === style_b.length && compStyle === style_a.length) && (compClass === class_b.length && compClass === class_a.length);
+ },
+
+ /**
+ * @description Check the node is a list (ol, ul)
+ * @param {Node|String} node The element or element name to check
+ * @returns {Boolean}
+ */
+ isList: function (node) {
+ return node && /^(OL|UL)$/i.test(typeof node === 'string' ? node : node.nodeName);
+ },
+
+ /**
+ * @description Check the node is a list cell (li)
+ * @param {Node|String} node The element or element name to check
+ * @returns {Boolean}
+ */
+ isListCell: function (node) {
+ return node && /^LI$/i.test(typeof node === 'string' ? node : node.nodeName);
+ },
+
+ /**
+ * @description Check the node is a table (table, thead, tbody, tr, th, td)
+ * @param {Node|String} node The element or element name to check
+ * @returns {Boolean}
+ */
+ isTable: function (node) {
+ return node && /^(TABLE|THEAD|TBODY|TR|TH|TD)$/i.test(typeof node === 'string' ? node : node.nodeName);
+ },
+
+ /**
+ * @description Check the node is a table cell (td, th)
+ * @param {Node|String} node The element or element name to check
+ * @returns {Boolean}
+ */
+ isCell: function (node) {
+ return node && /^(TD|TH)$/i.test(typeof node === 'string' ? node : node.nodeName);
+ },
+
+ /**
+ * @description Check the node is a break node (BR)
+ * @param {Node|String} node The element or element name to check
+ * @returns {Boolean}
+ */
+ isBreak: function (node) {
+ return node && /^BR$/i.test(typeof node === 'string' ? node : node.nodeName);
+ },
+
+
+ /**
+ * @description Check the node is a anchor node (A)
+ * @param {Node|String} node The element or element name to check
+ * @returns {Boolean}
+ */
+ isAnchor: function (node) {
+ return node && /^A$/i.test(typeof node === 'string' ? node : node.nodeName);
+ },
+
+ /**
+ * @description Check the node is a media node (img, iframe, audio, video, canvas)
+ * @param {Node|String} node The element or element name to check
+ * @returns {Boolean}
+ */
+ isMedia: function (node) {
+ return node && /^(IMG|IFRAME|AUDIO|VIDEO|CANVAS)$/i.test(typeof node === 'string' ? node : node.nodeName);
+ },
+
+ /**
+ * @description Checks for numeric (with decimal point).
+ * @param {String|Number} text Text string or number
+ * @returns {Boolean}
+ */
+ isNumber: function (text) {
+ return !!text && /^-?\d+(\.\d+)?$/.test(text + '');
+ },
+
+ /**
+ * @description Get a number.
+ * @param {String|Number} text Text string or number
+ * @param {Number} maxDec Maximum number of decimal places (-1 : Infinity)
+ * @returns {Number}
+ */
+ getNumber: function (text, maxDec) {
+ if (!text) return 0;
+
+ let number = (text + '').match(/-?\d+(\.\d+)?/);
+ if (!number || !number[0]) return 0;
+
+ number = number[0];
+ return maxDec < 0 ? number * 1 : maxDec === 0 ? this._w.Math.round(number * 1) : (number * 1).toFixed(maxDec) * 1;
+ },
+
+ /**
+ * @description Get all "children" of the argument value element (Without text nodes)
+ * @param {Element} element element to get child node
+ * @param {Function|null} validation Conditional function
+ * @returns {Array}
+ */
+ getListChildren: function (element, validation) {
+ const children = [];
+ if (!element || !element.children || element.children.length === 0) return children;
+
+ validation = validation || function () { return true; };
+
+ (function recursionFunc(current) {
+ if (element !== current && validation(current)) {
+ children.push(current);
+ }
+
+ for (let i = 0, len = current.children.length; i < len; i++) {
+ recursionFunc(current.children[i]);
+ }
+ })(element);
+
+ return children;
+ },
+
+ /**
+ * @description Get all "childNodes" of the argument value element (Include text nodes)
+ * @param {Node} element element to get child node
+ * @param {Function|null} validation Conditional function
+ * @returns {Array}
+ */
+ getListChildNodes: function (element, validation) {
+ const children = [];
+ if (!element || element.childNodes.length === 0) return children;
+
+ validation = validation || function () { return true; };
+
+ (function recursionFunc(current) {
+ if (element !== current && validation(current)) {
+ children.push(current);
+ }
+
+ for (let i = 0, len = current.childNodes.length; i < len; i++) {
+ recursionFunc(current.childNodes[i]);
+ }
+ })(element);
+
+ return children;
+ },
+
+ /**
+ * @description Returns the number of parents nodes.
+ * "0" when the parent node is the WYSIWYG area.
+ * "-1" when the element argument is the WYSIWYG area.
+ * @param {Node} element The element to check
+ * @returns {Number}
+ */
+ getElementDepth: function (element) {
+ if (!element || this.isWysiwygDiv(element)) return -1;
+
+ let depth = 0;
+ element = element.parentNode;
+
+ while (element && !this.isWysiwygDiv(element)) {
+ depth += 1;
+ element = element.parentNode;
+ }
+
+ return depth;
+ },
+
+ /**
+ * @description Compares two elements to find a common ancestor, and returns the order of the two elements.
+ * @param {Node} a Node to compare.
+ * @param {Node} b Node to compare.
+ * @returns {Object} { ancesstor, a, b, result: (a > b ? 1 : a < b ? -1 : 0) };
+ */
+ compareElements: function (a, b) {
+ let aNode = a, bNode = b;
+ while (aNode && bNode && aNode.parentNode !== bNode.parentNode) {
+ aNode = aNode.parentNode;
+ bNode = bNode.parentNode;
+ }
+
+ if (!aNode || !bNode) return { ancestor: null, a: a, b: b, result: 0 };
+
+ const children = aNode.parentNode.childNodes;
+ const aIndex = this.getArrayIndex(children, aNode);
+ const bIndex = this.getArrayIndex(children, bNode);
+
+ return {
+ ancestor: aNode.parentNode,
+ a: aNode,
+ b: bNode,
+ result: aIndex > bIndex ? 1 : aIndex < bIndex ? -1 : 0
+ };
+ },
+
+ /**
+ * @description Get the parent element of the argument value.
+ * A tag that satisfies the query condition is imported.
+ * Returns null if not found.
+ * @param {Node} element Reference element
+ * @param {String|Function} query Query String (nodeName, .className, #ID, :name) or validation function.
+ * Not use it like jquery.
+ * Only one condition can be entered at a time.
+ * @returns {Element|null}
+ */
+ getParentElement: function (element, query) {
+ let check;
+
+ if (typeof query === 'function') {
+ check = query;
+ } else {
+ let attr;
+ if (/^\./.test(query)) {
+ attr = 'className';
+ query = query.split('.')[1];
+ } else if (/^#/.test(query)) {
+ attr = 'id';
+ query = '^' + query.split('#')[1] + '$';
+ } else if (/^:/.test(query)) {
+ attr = 'name';
+ query = '^' + query.split(':')[1] + '$';
+ } else {
+ attr = 'nodeName';
+ query = '^' + query + '$';
+ }
+
+ const regExp = new this._w.RegExp(query, 'i');
+ check = function (el) {
+ return regExp.test(el[attr]);
+ };
+ }
+
+ while (element && !check(element)) {
+ if (this.isWysiwygDiv(element)) {
+ return null;
+ }
+ element = element.parentNode;
+ }
+
+ return element;
+ },
+
+ /**
+ * @description Get the child element of the argument value.
+ * A tag that satisfies the query condition is imported.
+ * Returns null if not found.
+ * @param {Node} element Reference element
+ * @param {String|Function} query Query String (nodeName, .className, #ID, :name) or validation function.
+ * @param {Boolean} last If true returns the last node among the found child nodes. (default: first node)
+ * Not use it like jquery.
+ * Only one condition can be entered at a time.
+ * @returns {Element|null}
+ */
+ getChildElement: function (element, query, last) {
+ let check;
+
+ if (typeof query === 'function') {
+ check = query;
+ } else {
+ let attr;
+ if (/^\./.test(query)) {
+ attr = 'className';
+ query = query.split('.')[1];
+ } else if (/^#/.test(query)) {
+ attr = 'id';
+ query = '^' + query.split('#')[1] + '$';
+ } else if (/^:/.test(query)) {
+ attr = 'name';
+ query = '^' + query.split(':')[1] + '$';
+ } else {
+ attr = 'nodeName';
+ query = '^' + (query === 'text' ? '#' + query : query) + '$';
+ }
+
+ const regExp = new this._w.RegExp(query, 'i');
+ check = function (el) {
+ return regExp.test(el[attr]);
+ };
+ }
+
+ const childList = this.getListChildNodes(element, function (current) {
+ return check(current);
+ });
+
+ return childList[last ? childList.length - 1 : 0];
+ },
+
+ /**
+ * @description 1. The first node of all the child nodes of the "first" element is returned.
+ * 2. The last node of all the child nodes of the "last" element is returned.
+ * 3. When there is no "last" element, the first and last nodes of all the children of the "first" element are returned.
+ * { sc: "first", ec: "last" }
+ * @param {Node} first First element
+ * @param {Node|null} last Last element
+ * @returns {Object}
+ */
+ getEdgeChildNodes: function (first, last) {
+ if (!first) return;
+ if (!last) last = first;
+
+ while (first && first.nodeType === 1 && first.childNodes.length > 0 && !this.isBreak(first)) first = first.firstChild;
+ while (last && last.nodeType === 1 && last.childNodes.length > 0 && !this.isBreak(last)) last = last.lastChild;
+
+ return {
+ sc: first,
+ ec: last || first
+ };
+ },
+
+ /**
+ * @description Returns the position of the left and top of argument. {left:0, top:0}
+ * @param {Node} element Target node
+ * @param {Element|null} wysiwygFrame When use iframe option, iframe object should be sent (context.element.wysiwygFrame)
+ * @returns {Object}
+ */
+ getOffset: function (element, wysiwygFrame) {
+ let offsetLeft = 0;
+ let offsetTop = 0;
+ let offsetElement = element.nodeType === 3 ? element.parentElement : element;
+ const wysiwyg = this.getParentElement(element, this.isWysiwygDiv.bind(this));
+
+ while (offsetElement && !this.hasClass(offsetElement, 'se-container') && offsetElement !== wysiwyg) {
+ offsetLeft += offsetElement.offsetLeft;
+ offsetTop += offsetElement.offsetTop;
+ offsetElement = offsetElement.offsetParent;
+ }
+
+ const iframe = wysiwygFrame && /iframe/i.test(wysiwygFrame.nodeName);
+
+ return {
+ left: offsetLeft + (iframe ? wysiwygFrame.parentElement.offsetLeft : 0),
+ top: (offsetTop - wysiwyg.scrollTop) + (iframe ? wysiwygFrame.parentElement.offsetTop : 0)
+ };
+ },
+
+ /**
+ * @description It compares the start and end indexes of "a" and "b" and returns the number of overlapping indexes in the range.
+ * ex) 1, 5, 4, 6 => "2" (4 ~ 5)
+ * @param {Number} aStart Start index of "a"
+ * @param {Number} aEnd End index of "a"
+ * @param {Number} bStart Start index of "b"
+ * @param {Number} bEnd Start index of "b"
+ * @returns {Number}
+ */
+ getOverlapRangeAtIndex: function (aStart, aEnd, bStart, bEnd) {
+ if (aStart <= bEnd ? aEnd < bStart : aEnd > bStart) return 0;
+
+ const overlap = (aStart > bStart ? aStart : bStart) - (aEnd < bEnd ? aEnd : bEnd);
+ return (overlap < 0 ? overlap * -1 : overlap) + 1;
+ },
+
+ /**
+ * @description Set the text content value of the argument value element
+ * @param {Node} element Element to replace text content
+ * @param {String} txt Text to be applied
+ */
+ changeTxt: function (element, txt) {
+ if (!element || !txt) return;
+ element.textContent = txt;
+ },
+
+ /**
+ * @description Replace element
+ * @param {Element} element Target element
+ * @param {String|Element} newElement String or element of the new element to apply
+ */
+ changeElement: function (element, newElement) {
+ if (typeof newElement === 'string') {
+ if (element.outerHTML) {
+ element.outerHTML = newElement;
+ } else {
+ const doc = this.createElement('DIV');
+ doc.innerHTML = newElement;
+ newElement = doc.firstChild;
+ element.parentNode.replaceChild(newElement, element);
+ }
+ } else if (newElement.nodeType === 1) {
+ element.parentNode.replaceChild(newElement, element);
+ }
+ },
+
+ /**
+ * @description Set style, if all styles are deleted, the style properties are deleted.
+ * @param {Element} element Element to set style
+ * @param {String} styleName Style attribute name (marginLeft, textAlign...)
+ * @param {String|Number} value Style value
+ */
+ setStyle: function (element, styleName, value) {
+ element.style[styleName] = value;
+
+ if (!value && !element.style.cssText) {
+ element.removeAttribute('style');
+ }
+ },
+
+ /**
+ * @description Determine whether any of the matched elements are assigned the given class
+ * @param {Element} element Elements to search class name
+ * @param {String} className Class name to search for
+ * @returns {Boolean}
+ */
+ hasClass: function (element, className) {
+ if (!element) return;
+
+ return (new this._w.RegExp(className)).test(element.className);
+ },
+
+ /**
+ * @description Append the className value of the argument value element
+ * @param {Element} element Elements to add class name
+ * @param {String} className Class name to be add
+ */
+ addClass: function (element, className) {
+ if (!element) return;
+
+ const check = new this._w.RegExp('(\\s|^)' + className + '(\\s|$)');
+ if (check.test(element.className)) return;
+
+ element.className += (element.className.length > 0 ? ' ' : '') + className;
+ },
+
+ /**
+ * @description Delete the className value of the argument value element
+ * @param {Element} element Elements to remove class name
+ * @param {String} className Class name to be remove
+ */
+ removeClass: function (element, className) {
+ if (!element) return;
+
+ const check = new this._w.RegExp('(\\s|^)' + className + '(\\s|$)');
+ element.className = element.className.replace(check, ' ').trim();
+
+ if (!element.className.trim()) element.removeAttribute('class');
+ },
+
+ /**
+ * @description Argument value If there is no class name, insert it and delete the class name if it exists
+ * @param {Element} element Elements to replace class name
+ * @param {String} className Class name to be change
+ */
+ toggleClass: function (element, className) {
+ if (!element) return;
+
+ const check = new this._w.RegExp('(\\s|^)' + className + '(\\s|$)');
+ if (check.test(element.className)) {
+ element.className = element.className.replace(check, ' ').trim();
+ }
+ else {
+ element.className += ' ' + className;
+ }
+
+ if (!element.className.trim()) element.removeAttribute('class');
+ },
+
+ /**
+ * @description In the predefined code view mode, the buttons except the executable button are changed to the 'disabled' state.
+ * core.codeViewDisabledButtons (An array of buttons whose class name is not "se-code-view-enabled")
+ * core.resizingDisabledButtons (An array of buttons whose class name is not "se-resizing-enabled")
+ * @param {Boolean} disabled Disabled value
+ * @param {Array|HTMLCollection|NodeList} buttonList Button array
+ */
+ setDisabledButtons: function (disabled, buttonList) {
+ for (let i = 0, len = buttonList.length; i < len; i++) {
+ buttonList[i].disabled = disabled;
+ }
+ },
+
+ /**
+ * @description Delete argumenu value element
+ * @param {Node} item Node to be remove
+ */
+ removeItem: function (item) {
+ if (!item) return;
+ try {
+ item.remove();
+ } catch (e) {
+ if (item.parentNode) item.parentNode.removeChild(item);
+ }
+ },
+
+ /**
+ * @description Delete all parent nodes that match the condition.
+ * Returns an {sc: previousSibling, ec: nextSibling}(the deleted node reference) or null.
+ * @param {Node} item Node to be remove
+ * @param {Function|null} validation Validation function. default(Deleted if it only have breakLine and blanks)
+ * @param {Element|null} stopParent Stop when the parent node reaches stopParent
+ * @returns {Object|null} {sc: previousSibling, ec: nextSibling}
+ */
+ removeItemAllParents: function (item, validation, stopParent) {
+ if (!item) return null;
+ let cc = null;
+ if (!validation) {
+ validation = function (current) {
+ if (current === stopParent || this.isComponent(current)) return false;
+ const text = current.textContent.trim();
+ return text.length === 0 || /^(\n|\u200B)+$/.test(text);
+ }.bind(this);
+ }
+
+ (function recursionFunc (element) {
+ if (!util.isWysiwygDiv(element)) {
+ const parent = element.parentNode;
+ if (parent && validation(element)) {
+ cc = {
+ sc: element.previousElementSibling,
+ ec: element.nextElementSibling
+ };
+ util.removeItem(element);
+ recursionFunc(parent);
+ }
+ }
+ }(item));
+
+ return cc;
+ },
+
+ /**
+ * @description Detach Nested all nested lists under the "baseNode".
+ * Returns a list with nested removed.
+ * @param {Node} baseNode Element on which to base.
+ * @param {Boolean} all If true, it also detach all nested lists of a returned list.
+ * @returns {Element}
+ */
+ detachNestedList: function (baseNode, all) {
+ const rNode = this._deleteNestedList(baseNode);
+ let rangeElement, cNodes;
+
+ if (rNode) {
+ rangeElement = rNode.cloneNode(false);
+ cNodes = rNode.childNodes;
+ const index = this.getPositionIndex(baseNode);
+ while (cNodes[index]) {
+ rangeElement.appendChild(cNodes[index]);
+ }
+ } else {
+ rangeElement = baseNode;
+ }
+
+ let rChildren;
+ if (!all) {
+ const depth = this.getElementDepth(baseNode) + 2;
+ rChildren = this.getListChildren(baseNode, function (current) { return this.isListCell(current) && !current.previousElementSibling && this.getElementDepth(current) === depth; }.bind(this));
+ } else {
+ rChildren = this.getListChildren(rangeElement, function (current) { return this.isListCell(current) && !current.previousElementSibling; }.bind(this));
+ }
+
+ for (let i = 0, len = rChildren.length; i < len; i++) {
+ this._deleteNestedList(rChildren[i]);
+ }
+
+ if (rNode) {
+ rNode.parentNode.insertBefore(rangeElement, rNode.nextSibling);
+ if (cNodes && cNodes.length === 0) this.removeItem(rNode);
+ }
+
+ return rangeElement === baseNode ? rangeElement.parentNode : rangeElement;
+ },
+
+ /**
+ * @description Sub function of util.detachNestedList method.
+ * @private
+ */
+ _deleteNestedList: function (baseNode) {
+ const baseParent = baseNode.parentNode;
+ let sibling = baseParent;
+ let parent = sibling.parentNode;
+ let liSibling, liParent, child, index, c;
+
+ while (this.isListCell(parent)) {
+ index = this.getPositionIndex(baseNode);
+ liSibling = parent.nextElementSibling;
+ liParent = parent.parentNode;
+ child = sibling;
+ while(child) {
+ sibling = sibling.nextSibling;
+ if (this.isList(child)) {
+ c = child.childNodes;
+ while (c[index]) {
+ liParent.insertBefore(c[index], liSibling);
+ }
+ if (c.length === 0) this.removeItem(child);
+ } else {
+ liParent.appendChild(child);
+ }
+ child = sibling;
+ }
+ sibling = liParent;
+ parent = liParent.parentNode;
+ }
+
+ if (baseParent.children.length === 0) this.removeItem(baseParent);
+
+ return liParent;
+ },
+
+ /**
+ * @description Split all tags based on "baseNode"
+ * Returns the last element of the splited tag.
+ * @param {Node} baseNode Element or text node on which to base
+ * @param {Number|null} offset Text offset of "baseNode" (Only valid when "baseNode" is a text node)
+ * @param {Number} depth The nesting depth of the element being split. (default: 0)
+ * @returns {Element}
+ */
+ splitElement: function (baseNode, offset, depth) {
+ const bp = baseNode.parentNode;
+ let index = 0, newEl, children, temp;
+ let next = true;
+ if (!depth || depth < 0) depth = 0;
+
+ if (baseNode.nodeType === 3) {
+ index = this.getPositionIndex(baseNode);
+ if (offset >= 0) {
+ baseNode.splitText(offset);
+ const after = this.getNodeFromPath([index + 1], bp);
+ if (this.onlyZeroWidthSpace(after)) after.data = this.zeroWidthSpace;
+ }
+ } else if (baseNode.nodeType === 1) {
+ if (!baseNode.previousSibling) {
+ if (this.getElementDepth(baseNode) === depth) next = false;
+ } else {
+ baseNode = baseNode.previousSibling;
+ }
+ }
+
+ let depthEl = baseNode;
+ while (this.getElementDepth(depthEl) > depth) {
+ index = this.getPositionIndex(depthEl) + 1;
+ depthEl = depthEl.parentNode;
+
+ temp = newEl;
+ newEl = depthEl.cloneNode(false);
+ children = depthEl.childNodes;
+
+ if (temp) {
+ if (this.isListCell(newEl) && this.isList(temp) && temp.firstElementChild) {
+ newEl.innerHTML = temp.firstElementChild.innerHTML;
+ util.removeItem(temp.firstElementChild);
+ if (temp.children.length > 0) newEl.appendChild(temp);
+ } else {
+ newEl.appendChild(temp);
+ }
+ }
+
+ while (children[index]) {
+ newEl.appendChild(children[index]);
+ }
+ }
+
+ if (depthEl.childNodes.length <= 1 && (!depthEl.firstChild || depthEl.firstChild.textContent.length === 0)) depthEl.innerHTML = '<br>';
+
+ const pElement = depthEl.parentNode;
+ if (next) depthEl = depthEl.nextSibling;
+ if (!newEl) return depthEl;
+
+ this.mergeSameTags(newEl, null, false);
+ this.mergeNestedTags(newEl, function (current) { return this.isList(current); }.bind(this));
+
+ if (newEl.childNodes.length > 0) pElement.insertBefore(newEl, depthEl);
+ else newEl = depthEl;
+
+ if (bp.childNodes.length === 0) this.removeItem(bp);
+
+ return newEl;
+ },
+
+ /**
+ * @description Use with "npdePath (util.getNodePath)" to merge the same attributes and tags if they are present and modify the nodepath.
+ * If "offset" has been changed, it will return as much "offset" as it has been modified.
+ * An array containing change offsets is returned in the order of the "nodePathArray" array.
+ * @param {Element} element Element
+ * @param {Array|null} nodePathArray Array of NodePath object ([util.getNodePath(), ..])
+ * @param {Boolean} onlyText If true, non-text nodes(!util._isIgnoreNodeChange) like 'span', 'strong'.. are ignored.
+ * @returns {Array} [offset, ..]
+ */
+ mergeSameTags: function (element, nodePathArray, onlyText) {
+ const inst = this;
+ const nodePathLen = nodePathArray ? nodePathArray.length : 0;
+ let offsets = null;
+
+ if (nodePathLen) {
+ offsets = this._w.Array.apply(null, new this._w.Array(nodePathLen)).map(this._w.Number.prototype.valueOf, 0);
+ }
+
+ (function recursionFunc(current, depth, depthIndex) {
+ const children = current.childNodes;
+
+ for (let i = 0, len = children.length, child, next; i < len; i++) {
+ child = children[i];
+ next = children[i + 1];
+ if (!child) break;
+ if((onlyText && inst._isIgnoreNodeChange(child)) || (!onlyText && (inst.isTable(child) || inst.isListCell(child) || (inst.isFormatElement(child) && !inst.isFreeFormatElement(child))))) {
+ if (inst.isTable(child) || inst.isListCell(child)) {
+ recursionFunc(child, depth + 1, i);
+ }
+ continue;
+ }
+ if (len === 1 && current.nodeName === child.nodeName && current.parentNode) {
+ // update nodePath
+ if (nodePathLen) {
+ let path, c, p, cDepth, spliceDepth;
+ for (let n = 0; n < nodePathLen; n++) {
+ path = nodePathArray[n];
+ if (path && path[depth] === i) {
+ c = child, p = current, cDepth = depth, spliceDepth = true;
+ while (cDepth >= 0) {
+ if (inst.getArrayIndex(p.childNodes, c) !== path[cDepth]) {
+ spliceDepth = false;
+ break;
+ }
+ c = child.parentNode;
+ p = c.parentNode;
+ cDepth--;
+ }
+ if (spliceDepth) {
+ path.splice(depth, 1);
+ path[depth] = i;
+ }
+ }
+ }
+ }
+
+ // merge tag
+ inst.copyTagAttributes(child, current);
+ current.parentNode.insertBefore(child, current);
+ inst.removeItem(current);
+ }
+ if (!next) {
+ if (child.nodeType === 1) recursionFunc(child, depth + 1, i);
+ break;
+ }
+
+ if (child.nodeName === next.nodeName && inst.isSameAttributes(child, next) && child.href === next.href) {
+ const childs = child.childNodes;
+ let childLength = 0;
+ for (let n = 0, nLen = childs.length; n < nLen; n++) {
+ if (childs[n].textContent.length > 0) childLength++;
+ }
+
+ const l = child.lastChild;
+ const r = next.firstChild;
+ let addOffset = 0;
+ if (l && r) {
+ const textOffset = l.nodeType === 3 && r.nodeType === 3;
+ addOffset = l.textContent.length;
+ let tempL = l.previousSibling;
+ while(tempL && tempL.nodeType === 3) {
+ addOffset += tempL.textContent.length;
+ tempL = tempL.previousSibling;
+ }
+
+ if (childLength > 0 && l.nodeType === 3 && r.nodeType === 3 && (l.textContent.length > 0 || r.textContent.length > 0)) childLength--;
+
+ if (nodePathLen) {
+ let path = null;
+ for (let n = 0; n < nodePathLen; n++) {
+ path = nodePathArray[n];
+ if (path && path[depth] > i) {
+ if (depth > 0 && path[depth - 1] !== depthIndex) continue;
+
+ path[depth] -= 1;
+ if (path[depth + 1] >= 0 && path[depth] === i) {
+ path[depth + 1] += childLength;
+ if (textOffset) {
+ if (l && l.nodeType === 3 && r && r.nodeType === 3) {
+ offsets[n] += addOffset;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (child.nodeType === 3) {
+ addOffset = child.textContent.length;
+ child.textContent += next.textContent;
+ if (nodePathLen) {
+ let path = null;
+ for (let n = 0; n < nodePathLen; n++) {
+ path = nodePathArray[n];
+ if (path && path[depth] > i) {
+ if (depth > 0 && path[depth - 1] !== depthIndex) continue;
+
+ path[depth] -= 1;
+ if (path[depth + 1] >= 0 && path[depth] === i) {
+ path[depth + 1] += childLength;
+ offsets[n] += addOffset;
+ }
+ }
+ }
+ }
+ } else {
+ child.innerHTML += next.innerHTML;
+ }
+
+ inst.removeItem(next);
+ i--;
+ } else if (child.nodeType === 1) {
+ recursionFunc(child, depth + 1, i);
+ }
+ }
+ })(element, 0, 0);
+
+ return offsets;
+ },
+
+ /**
+ * @description Remove nested tags without other child nodes.
+ * @param {Element} element Element object
+ * @param {Function|String|null} validation Validation function / String("tag1|tag2..") / If null, all tags are applicable.
+ */
+ mergeNestedTags: function (element, validation) {
+ if (typeof validation === 'string') {
+ validation = function (current) { return this.test(current.tagName); }.bind(new this._w.RegExp('^(' + (validation ? validation : '.+') + ')$', 'i'));
+ } else if (typeof validation !== 'function') {
+ validation = function () { return true; };
+ }
+
+ (function recursionFunc(current) {
+ let children = current.children;
+ if (children.length === 1 && children[0].nodeName === current.nodeName && validation(current)) {
+ const temp = children[0];
+ children = temp.children;
+ while (children[0]) {
+ current.appendChild(children[0]);
+ }
+ current.removeChild(temp);
+ }
+
+ for (let i = 0, len = current.children.length; i < len; i++) {
+ recursionFunc(current.children[i]);
+ }
+ })(element);
+ },
+
+ /**
+ * @description Delete a empty child node of argument element
+ * @param {Element} element Element node
+ * @param {Node|null} notRemoveNode Do not remove node
+ */
+ removeEmptyNode: function (element, notRemoveNode) {
+ const inst = this;
+
+ if (notRemoveNode) {
+ notRemoveNode = inst.getParentElement(notRemoveNode, function (current) {
+ return element === current.parentElement;
+ });
+ }
+
+ (function recursionFunc(current) {
+ if (inst._notTextNode(current) || current === notRemoveNode || inst.isNonEditable(current)) return 0;
+ if (current !== element && inst.onlyZeroWidthSpace(current.textContent) && (!current.firstChild || !inst.isBreak(current.firstChild))) {
+ if (current.parentNode) {
+ current.parentNode.removeChild(current);
+ return -1;
+ }
+ } else {
+ const children = current.children;
+ for (let i = 0, len = children.length, r = 0; i < len; i++) {
+ if (!children[i + r] || inst.isComponent(children[i + r])) continue;
+ r += recursionFunc(children[i + r]);
+ }
+ }
+
+ return 0;
+ })(element);
+
+ if (element.childNodes.length === 0) element.innerHTML = '<br>';
+ },
+
+ /**
+ * @description Remove whitespace between tags in HTML string.
+ * @param {String} html HTML string
+ * @returns {String}
+ */
+ htmlRemoveWhiteSpace: function (html) {
+ if (!html) return '';
+ return html.trim().replace(/<\/?(?!strong|span|font|b|var|i|em|u|ins|s|strike|del|sub|sup|mark|a|label|code)[^>^<]+>\s+(?=<)/ig, function (m) { return m.trim(); });
+ },
+
+ /**
+ * @description Sort a element array by depth of element.
+ * @param {Array} array Array object
+ * @param {Boolean} des true: descending order / false: ascending order
+ */
+ sortByDepth: function (array, des) {
+ const t = !des ? -1 : 1;
+ const f = t * -1;
+
+ array.sort(function (a, b) {
+ if (!this.isListCell(a) || !this.isListCell(b)) return 0;
+ a = this.getElementDepth(a);
+ b = this.getElementDepth(b);
+ return a > b ? t : a < b ? f : 0;
+ }.bind(this));
+ },
+
+ /**
+ * @description Nodes that need to be added without modification when changing text nodes
+ * @param {Node} element Element to check
+ * @returns {Boolean}
+ * @private
+ */
+ _isIgnoreNodeChange: function (element) {
+ return element && element.nodeType !== 3 && (this.isNonEditable(element) || !this.isTextStyleElement(element));
+ },
+
+ /**
+ * @description Nodes that must remain undetached when changing text nodes (A, Label, Code)
+ * @param {Node|String} element Element to check
+ * @returns {Boolean}
+ * @private
+ */
+ _isMaintainedNode: function (element) {
+ return element && element.nodeType !== 3 && /^(a|label|code)$/i.test(typeof element === 'string' ? element : element.nodeName);
+ },
+
+ /**
+ * @description Node with font-size style
+ * @param {Node} element Element to check
+ * @returns {Boolean}
+ * @private
+ */
+ _isSizeNode: function (element) {
+ return element && element.nodeType !== 3 && this.isTextStyleElement(element) && !!element.style.fontSize;
+ },
+
+ /**
+ * @description Nodes without text
+ * @param {Node} element Element to check
+ * @returns {Boolean}
+ * @private
+ */
+ _notTextNode: function (element) {
+ return element && element.nodeType !== 3 && (this.isComponent(element) || /^(br|input|select|canvas|img|iframe|audio|video)$/i.test(typeof element === 'string' ? element : element.nodeName));
+ },
+
+ /**
+ * @description Check disallowed tags
+ * @param {Node} element Element to check
+ * @returns {Boolean}
+ * @private
+ */
+ _disallowedTags: function (element) {
+ return /^(meta|script|link|style|[a-z]+\:[a-z]+)$/i.test(element.nodeName);
+ },
+
+ /**
+ * @description Create whitelist RegExp object.
+ * Return RegExp format: new RegExp("<\\/?\\b(?!" + list + ")\\b[^>^<]*+>", "gi")
+ * @param {String} list Tags list ("br|p|div|pre...")
+ * @returns {RegExp}
+ */
+ createTagsWhitelist: function (list) {
+ return new RegExp('<\\/?\\b(?!\\b' + list.replace(/\|/g, '\\b|\\b') + '\\b)[^>]*>', 'gi');
+ },
+
+ /**
+ * @description Fix tags that do not fit the editor format.
+ * @param {Element} documentFragment Document fragment "DOCUMENT_FRAGMENT_NODE" (nodeType === 11)
+ * @param {RegExp} htmlCheckWhitelistRegExp Editor tags whitelist (core._htmlCheckWhitelistRegExp)
+ * @private
+ */
+ _consistencyCheckOfHTML: function (documentFragment, htmlCheckWhitelistRegExp) {
+ /**
+ * It is can use ".children(util.getListChildren)" to exclude text nodes, but "documentFragment.children" is not supported in IE.
+ * So check the node type and exclude the text no (current.nodeType !== 1)
+ */
+ const removeTags = [], emptyTags = [], wrongList = [], withoutFormatCells = [];
+
+ // wrong position
+ const wrongTags = this.getListChildNodes(documentFragment, function (current) {
+ if (current.nodeType !== 1) return false;
+
+ // white list
+ if (!htmlCheckWhitelistRegExp.test(current.nodeName) && current.childNodes.length === 0 && this.isNotCheckingNode(current)) {
+ removeTags.push(current);
+ return false;
+ }
+
+ const nrtag = !this.getParentElement(current, this.isNotCheckingNode);
+ // empty tags
+ if ((!this.isTable(current) && !this.isListCell(current)) && (this.isFormatElement(current) || this.isRangeFormatElement(current) || this.isTextStyleElement(current)) && current.childNodes.length === 0 && nrtag) {
+ emptyTags.push(current);
+ return false;
+ }
+
+ // wrong list
+ if (this.isList(current.parentNode) && !this.isList(current) && !this.isListCell(current)) {
+ wrongList.push(current);
+ return false;
+ }
+
+ // table cells
+ if (this.isCell(current)) {
+ const fel = current.firstElementChild;
+ if (!this.isFormatElement(fel) && !this.isRangeFormatElement(fel) && !this.isComponent(fel)) {
+ withoutFormatCells.push(current);
+ return false;
+ }
+ }
+
+ return current.parentNode !== documentFragment &&
+ (this.isFormatElement(current) || this.isComponent(current) || this.isList(current)) &&
+ !this.isRangeFormatElement(current.parentNode) && !this.isListCell(current.parentNode) &&
+ !this.getParentElement(current, this.isComponent) && nrtag;
+ }.bind(this));
+
+ for (let i = 0, len = removeTags.length; i < len; i++) {
+ this.removeItem(removeTags[i]);
+ }
+
+ const checkTags = [];
+ for (let i = 0, len = wrongTags.length, t, p; i < len; i++) {
+ t = wrongTags[i];
+ p = t.parentNode;
+ if (!p || !p.parentNode) continue;
+ p.parentNode.insertBefore(t, p);
+ checkTags.push(p);
+ }
+
+ for (let i = 0, len = checkTags.length, t; i < len; i++) {
+ t = checkTags[i];
+ if (this.onlyZeroWidthSpace(t.textContent.trim())) {
+ this.removeItem(t);
+ }
+ }
+
+ for (let i = 0, len = emptyTags.length; i < len; i++) {
+ this.removeItem(emptyTags[i]);
+ }
+
+ for (let i = 0, len = wrongList.length, t, tp, children, p; i < len; i++) {
+ t = wrongList[i];
+
+ tp = this.createElement('LI');
+ children = t.childNodes;
+ while (children[0]) {
+ tp.appendChild(children[0]);
+ }
+
+ p = t.parentNode;
+ if (!p) continue;
+ p.insertBefore(tp, t);
+ this.removeItem(t);
+ }
+
+ for (let i = 0, len = withoutFormatCells.length, t, f; i < len; i++) {
+ t = withoutFormatCells[i];
+ f = this.createElement('DIV');
+ f.innerHTML = t.textContent.trim().length === 0 ? '<br>' : t.innerHTML;
+ t.innerHTML = f.outerHTML;
+ }
+ },
+
+ _setDefaultOptionStyle: function (options, defaultStyle) {
+ let optionStyle = '';
+ if (options.height) optionStyle += 'height:' + options.height + ';';
+ if (options.minHeight) optionStyle += 'min-height:' + options.minHeight + ';';
+ if (options.maxHeight) optionStyle += 'max-height:' + options.maxHeight + ';';
+ if (options.position) optionStyle += 'position:' + options.position + ';';
+ if (options.width) optionStyle += 'width:' + options.width + ';';
+ if (options.minWidth) optionStyle += 'min-width:' + options.minWidth + ';';
+ if (options.maxWidth) optionStyle += 'max-width:' + options.maxWidth + ';';
+
+ let top = '', frame = '', editor = '';
+ defaultStyle = optionStyle + defaultStyle;
+ const styleArr = defaultStyle.split(';');
+ for (let i = 0, len = styleArr.length, s; i < len; i++) {
+ s = styleArr[i].trim();
+ if (!s) continue;
+ if (/^(min-|max-)?width\s*:/.test(s)) {
+ top += s + ';';
+ continue;
+ }
+ if (/^(min-|max-)?height\s*:/.test(s)) {
+ if (/^height/.test(s) && s.split(':')[1].trim() === 'auto') {
+ options.height = 'auto';
+ }
+ frame += s + ';';
+ continue;
+ }
+ editor += s + ';';
+ }
+
+ return {
+ top: top,
+ frame: frame,
+ editor: editor
+ };
+ },
+
+ _setIframeDocument: function (frame, options) {
+ frame.setAttribute('scrolling', 'auto');
+ frame.contentDocument.head.innerHTML = '' +
+ '<meta charset="utf-8" />' +
+ '<meta name="viewport" content="width=device-width, initial-scale=1">' +
+ this._setIframeCssTags(options);
+ frame.contentDocument.body.className = options._editableClass;
+ frame.contentDocument.body.setAttribute('contenteditable', true);
+ },
+
+ _setIframeCssTags: function (options) {
+ const linkNames = options.iframeCSSFileName;
+ const wRegExp = this._w.RegExp;
+ let tagString = '';
+
+ for (let f = 0, len = linkNames.length, path; f < len; f++) {
+ path = [];
+
+ if (/(^https?:\/\/)|(^data:text\/css,)/.test(linkNames[f])) {
+ path.push(linkNames[f]);
+ } else {
+ const CSSFileName = new wRegExp('(^|.*[\\/])' + linkNames[f] + '(\\..+)?\\.css(?:\\?.*|;.*)?$', 'i');
+ for (let c = document.getElementsByTagName('link'), i = 0, len = c.length, styleTag; i < len; i++) {
+ styleTag = c[i].href.match(CSSFileName);
+ if (styleTag) path.push(styleTag[0]);
+ }
+ }
+
+ if (!path || path.length === 0) throw '[SUNEDITOR.constructor.iframe.fail] The suneditor CSS files installation path could not be automatically detected. Please set the option property "iframeCSSFileName" before creating editor instances.';
+
+ for (let i = 0, len = path.length; i < len; i++) {
+ tagString += '<link href="' + path[i] + '" rel="stylesheet">';
+ }
+ }
+
+ return tagString + (options.height === 'auto' ? '<style>\n/** Iframe height auto */\nbody{height: min-content; overflow: hidden;}\n</style>' : '');
+ }
+};
+
+export default util;
\ No newline at end of file
--- /dev/null
+import { Lang } from './lang/Lang';
+import { Plugin } from './plugins/Plugin';
+
+export interface SunEditorOptions {
+ plugins: Plugin[] | Record<string, Plugin>;
+ /**
+ * Values
+ * ======
+ */
+ /**
+ * language object
+ */
+ lang?: Lang;
+ /**
+ * Specifies default tag name of the editor. (default: "p")
+ */
+ defaultTag?: string;
+ /**
+ * Initial value(html string) of the edit area.
+ * If not, the value of the "target textarea".
+ */
+ value?: string;
+ /**
+ * Whitelist
+ * ======
+ */
+ /**
+ * Add tags to the default tags whitelist of editor.
+ */
+ addTagsWhitelist?: string;
+ /**
+ * Whitelist of tags when pasting.
+ */
+ pasteTagsWhitelist?: string;
+ /**
+ * Add attributes whitelist of tags that should be kept undeleted from the editor.
+ */
+ attributesWhitelist?: Record<string, string>;
+ /**
+ * Layout
+ * ======
+ */
+ /**
+ * The mode of the editor (classic, inline, balloon, balloon-always)
+ */
+ mode?: 'classic' | 'inline' | 'balloon' | 'balloon-always';
+ /**
+ * If true, the editor is set to RTL(Right To Left) mode.
+ */
+ rtl?: boolean;
+ /**
+ * Button List
+ */
+ buttonList?: ButtonListItem[];
+ /**
+ * The width of the toolbar.
+ Applies only when the editor mode is 'inline' or 'balloon' mode.
+ */
+ toolbarWidth?: string;
+ /**
+ * A custom HTML selector placing the toolbar inside.
+ The class name of the element must be 'sun-editor'.
+ Element or querySelector argument.
+ */
+ toolbarContainer?: HTMLElement | string;
+ /**
+ * Reference height value that should be changed to sticky toolbar mode
+ */
+ stickyToolbar?: number;
+ /**
+ * Content will be placed in an iframe and isolated from the rest of the page
+ */
+ iframe?: boolean;
+ /**
+ * Allows the usage of HTML, HEAD, BODY tags and DOCTYPE declaration
+ */
+ fullPage?: boolean;
+ /**
+ * Name of the CSS file(s) to apply inside the iframe.
+ */
+ iframeCSSFileName?: string | string[];
+ /**
+ * A template of the "preview".
+ * The {{contents}} part in the HTML string is replaced with the contents of the editor.
+ * @example "<h1>Preview Template</h1> {{contents}} <div>_Footer_</div>"
+ */
+ previewTemplate?: string;
+ /**
+ * CodeMirror object
+ */
+ codeMirror?: any | { src: any; options: object };
+ /**
+ * Katex object (Use "math" plugin)
+ */
+ katex?: any | { src: any; options: object };
+ /**
+ * Display
+ * =======
+ */
+ /**
+ * The position property of editor
+ */
+ position?: string;
+ /**
+ * The display property of editor
+ */
+ display?: string;
+ /**
+ * Size of background area when activating dialog window ('full'||'local')
+ */
+ popupDisplay?: 'full' | 'local';
+ /**
+ * Bottom resizing bar
+ * ===================
+ */
+ /**
+ * Show the bottom resizing bar
+ */
+ resizingBar?: boolean;
+ /**
+ * Displays the current node structure to resizingBar
+ */
+ showPathLabel?: boolean;
+ /**
+ * Character count
+ * ===============
+ */
+ /**
+ * Shows the number of characters in the editor
+ */
+ charCounter?: boolean;
+ /**
+ * Defines the calculation method of the "charCounter" option
+ */
+ charCounterType?: 'char' | 'byte' | 'byte-html';
+ /**
+ * Text to be displayed in the "charCounter" area of the bottom bar.
+ */
+ charCounterLabel?: string;
+ /**
+ * The maximum number of characters allowed to be inserted into the editor
+ */
+ maxCharCount?: number;
+ /**
+ * Size
+ * ====
+ */
+ /**
+ * The width size of the editor
+ */
+ width?: string;
+ /**
+ * The min-width size of the editor
+ */
+ minWidth?: string;
+ /**
+ * The max-width size of the editor
+ */
+ maxWidth?: string;
+ /**
+ * The height size of the editor
+ */
+ height?: string;
+ /**
+ * The min-height size of the editor
+ */
+ minHeight?: string;
+ /**
+ * The max-height size of the editor
+ */
+ maxHeight?: string;
+ /**
+ * Editing area default style
+ */
+ defaultStyle?: string;
+ /**
+ * Defining menu items
+ * ===================
+ */
+ /**
+ * Change default font-family array
+ */
+ font?: string[];
+ /**
+ * Change default font-size array
+ */
+ fontSize?: number[];
+ /**
+ *
+ */
+ fontSizeUnit?: string;
+ /**
+ * Change default formatBlock array
+ */
+ formats?: FormatTagName[];
+ /**
+ * Change default color array of color picker
+ */
+ colorList?: string[];
+ /**
+ * Line Heights
+ */
+ lineHeights?: LineHeightsItem[];
+ /**
+ * Paragraph Styles
+ */
+ paragraphStyles?: ParagraphStyles;
+ /**
+ * Text Styles
+ */
+ textStyles?: TextStyles;
+ /**
+ * Image
+ * =====
+ */
+ /**
+ * Can resize the image
+ */
+ imageResizing?: boolean;
+ /**
+ * Choose whether the image height input is visible.
+ */
+ imageHeightShow?: boolean;
+ /**
+ * The default width size of the image frame
+ */
+ imageWidth?: string;
+ /**
+ * The default height size of the image frame
+ */
+ imageHeight?: string;
+ /**
+ * If true, image size can only be scaled by percentage.
+ */
+ imageSizeOnlyPercentage?: boolean;
+ /**
+ * It is determined by "imageSizeOnlyPercentage".
+ * @pivate
+ */
+ _videoSizeUnit?: '%' | 'px';
+ /**
+ * Choose whether to image rotation buttons display.
+ * When "imageSizeOnlyPercentage" is "true" or or "imageHeightShow" is "false" the default value is false.
+ * If you want the button to be visible, put it a true.
+ */
+ imageRotation?: boolean;
+ /**
+ * Choose whether to create a file input tag in the image upload window
+ */
+ imageFileInput?: boolean;
+ /**
+ * Choose whether to create a image url input tag in the image upload window
+ */
+ imageUrlInput?: boolean;
+ /**
+ * Http Header when uploading images.
+ */
+ imageUploadHeader?: Record<string, string>;
+ /**
+ * The image upload to server mapping address
+ */
+ imageUploadUrl?: string;
+ /**
+ * The size of the total uploadable images (in bytes)
+ */
+ imageUploadSizeLimit?: number;
+ /**
+ * If true, multiple images can be selected.
+ */
+ imageMultipleFile?: boolean;
+ /**
+ * Define the "accept" attribute of the input.
+ * ex) "*" or ".jpg, .png .."
+ */
+ imageAccept?: string;
+ /**
+ * Image - image gallery
+ * =====
+ * The url of the image gallery, if you use the image gallery
+ */
+ imageGalleryUrl?: string;
+ /**
+ * Video
+ * =====
+ */
+ /**
+ * Can resize the video iframe
+ */
+ videoResizing?: boolean;
+ /**
+ * Choose whether the video height input is visible.
+ */
+ videoHeightShow?: boolean;
+ /**
+ * Choose whether the video ratio options is visible.
+ */
+ videoRatioShow?: boolean;
+ /**
+ * The default width size of the video frame
+ */
+ videoWidth?: string;
+ /**
+ * The default height size of the video frame
+ */
+ videoHeight?: string;
+ /**
+ * If true, video size can only be scaled by percentage.
+ */
+ videoSizeOnlyPercentage?: boolean;
+ /**
+ * Choose whether to video rotation buttons display.
+ * When "videoSizeOnlyPercentage" is "true" or "videoHeightShow" is "false" the default value is false.
+ * If you want the button to be visible, put it a true.
+ */
+ videoRotation?: boolean;
+ /**
+ * The default aspect ratio of the video.
+ * Up to four decimal places are allowed.
+ */
+ videoRatio?: number;
+ /**
+ * Video ratio selection options.
+ */
+ videoRatioList?: { name: string; value: number }[];
+ /**
+ * The query string of a YouTube embedded URL
+ */
+ youtubeQuery?: string;
+ /**
+ * Choose whether to create a file input tag in the video upload window
+ */
+ videoFileInput?: boolean;
+ /**
+ * Choose whether to create a video url input tag in the video upload window
+ */
+ videoUrlInput?: boolean;
+ /**
+ * Http Header when uploading videos.
+ */
+ videoUploadHeader?: Record<string, string>;
+ /**
+ * The video upload to server mapping address
+ */
+ videoUploadUrl?: string;
+ /**
+ * The size of the total uploadable videos (in bytes)
+ */
+ videoUploadSizeLimit?: number;
+ /**
+ * If true, multiple videos can be selected.
+ */
+ videoMultipleFile?: boolean;
+ /**
+ * Define "Attributes" of the video tag.
+ * @example { poster: "http://suneditor.com/docs/loading.gif", autoplay: true }
+ */
+ videoTagAttrs?: Record<string, string | boolean>;
+ /**
+ * Define "Attributes" of the iframe tag. (Youtube, Vimeo).
+ * @example { style: "border: 2px solid red;" }
+ */
+ videoIframeAttrs?: Record<string, string | boolean>;
+ /**
+ * Define the "accept" attribute of the input.
+ * "*" or ".mp4, .avi .."
+ */
+ videoAccept?: string;
+ /**
+ * Audio
+ * =====
+ */
+ /**
+ * The default width size of the audio frame
+ */
+ audioWidth?: string;
+ /**
+ * The default height size of the audio frame
+ */
+ audioHeight?: string;
+ /**
+ * Choose whether to create a file input tag in the audio upload window
+ */
+ audioFileInput?: boolean;
+ /**
+ * Choose whether to create a audio url input tag in the audio upload window
+ */
+ audioUrlInput?: boolean;
+ /**
+ * Http Header when uploading audios.
+ */
+ audioUploadHeader?: Record<string, string>;
+ /**
+ * The audio upload to server mapping address
+ */
+ audioUploadUrl?: string;
+ /**
+ * The size of the total uploadable audios (in bytes)
+ */
+ audioUploadSizeLimit?: number;
+ /**
+ * If true, videos images can be selected.
+ */
+ audioMultipleFile?: boolean;
+ /**
+ * Define "Attributes" of the audio tag.
+ * @example { controlslist: "nodownload", autoplay: true }
+ */
+ audioTagAttrs?: Record<string, string | boolean>;
+ /**
+ * Define the "accept" attribute of the input.
+ * "*" or ".mp3, .wav .."
+ */
+ audioAccept?: string;
+ /**
+ * Table
+ * =====
+ */
+ /**
+ * Define position to the table cell controller. ('cell', 'top')
+ */
+ tableCellControllerPosition?: string;
+ /**
+ * Key actions
+ * =====
+ */
+ /**
+ * If true, disables the interaction of the editor and tab key
+ */
+ tabDisable?: boolean;
+ shortcutsDisable?: string[];
+ shortcutsHint?: boolean;
+ /**
+ * Defining save button
+ * ====================
+ */
+ /**
+ * Callback functions that is called when the Save button is clicked
+ */
+ callBackSave?: (contents: string) => void;
+ /**
+ * Templates Array
+ * ===============
+ */
+ /**
+ * Templates array
+ */
+ templates?: TemplatesItem[];
+ /**
+ * ETC
+ * ===
+ */
+ /**
+ * The placeholder text
+ */
+ placeholder?: string;
+ /**
+ * Protocol for the links (if link has been added without any protocol this one will be used).
+ */
+ linkProtocol?: string;
+ /**
+ * You can redefine icons.
+ */
+ icons?: Record<string, string>;
+ }
+ export type FormatTagName =
+ 'p'
+ | 'div'
+ | 'blockquote'
+ | 'pre'
+ | 'h1'
+ | 'h2'
+ | 'h3'
+ | 'h4'
+ | 'h5'
+ | 'h6'
+ | { tag: string; name?: string; command: 'replace' | 'range' | 'free'; class: string };
+export type TemplatesItem = { name: string; html: string };
+export type LineHeightsItem = { text: string; value: number };
+export type ParagraphStyles = (string | { name: string; class: string; _class?: string })[];
+export type TextStyles = (string | { name: string; style: string; tag: string; _class?: string })[];
+export type ButtonListDefaults =
+ | '/' // Line Break
+ | 'bold'
+ | 'underline'
+ | 'italic'
+ | 'strike'
+ | 'subscript'
+ | 'superscript'
+ | 'removeFormat'
+ | 'indent'
+ | 'outdent'
+ | 'fullScreen'
+ | 'showBlocks'
+ | 'codeView'
+ | 'undo'
+ | 'redo'
+ | 'preview'
+ | 'print'
+ | 'save'
+ | 'font'
+ | 'formatBlock'
+ | 'fontSize'
+ | 'fontColor'
+ | 'hiliteColor'
+ | 'align'
+ | 'list'
+ | 'horizontalRule'
+ | 'table'
+ | 'lineHeight'
+ | 'template'
+ | 'paragraphStyle'
+ | 'textStyle'
+ | 'link'
+ | 'image'
+ | 'video'
+ | 'math'
+ | 'imageGallery';
+export type ButtonListItem = ButtonListDefaults | ButtonListDefaults[] | string[];
--- /dev/null
+import { Plugin } from './Plugin';
+
+export interface CommandPlugin extends Plugin {
+ /**
+ * @description The behavior of the "command plugin" must be defined in the "action" method.
+ */
+ action: () => void;
+}
\ No newline at end of file
--- /dev/null
+import { Plugin } from './Plugin';
+
+export interface DialogPlugin extends Plugin {
+ /**
+ * @description This method is called when the plugin button is clicked.
+ * Open the modal window here.
+ */
+ open: () => void;
+
+ /**
+ * @description Called after the submenu has been rendered
+ */
+ on?: () => void;
+
+ /**
+ * @description This method is called when the dialog window is closed.
+ * Initialize the properties.
+ */
+ init: () => void;
+}
\ No newline at end of file
--- /dev/null
+import { Plugin } from './Plugin';
+
+export interface FileBrowserPlugin extends Plugin {
+ /**
+ * @description Open a file browser window
+ * @param pluginName Plugin name using the file browser
+ * @param selectorHandler When the function comes as an argument value, it substitutes "context.selectorHandler".
+ * @example this.plugins.fileBrowser.open.call(this, 'imageGallery', (selectorHandler || null));
+ */
+ open(kind: string, update: boolean): void;
+
+ /**
+ * @description Define the HTML of the item to be put in "div.se-file-item-column".
+ * @param item Item of the response data's array
+ */
+ drawItems: (item: object) => string;
+
+ /**
+ * @description Close a file browser window
+ * The plugin's "init" method is called.
+ * @example this.plugins.fileBrowser.close.call(this);
+ */
+ close(): void;
+
+ /**
+ * @description This method is called when the file browser window is closed.
+ * Initialize the properties.
+ */
+ init?: () => void;
+}
\ No newline at end of file
--- /dev/null
+import SunEditor from '../lib/core';
+
+export interface Module {
+ /**
+ * @description Module name
+ */
+ name: string;
+
+ /**
+ * @description Constructor, It will run automatically.
+ * @param core Core object
+ * @example core.addModule([dialog, resizing, fileManager])
+ */
+ add?: (core: SunEditor) => void;
+}
\ No newline at end of file
--- /dev/null
+export interface Plugin {
+ /**
+ * @description Plugin name
+ */
+ name: string;
+
+ /**
+ * @description Plugin type ('container', 'command', 'submenu', 'dialog')
+ */
+ display: string;
+
+ /**
+ * @description Constructor
+ * @param core Core object
+ * @param targetElement Target button Element
+ */
+ add: (core: any, targetElement?: any) => void;
+
+ /**
+ * @description Plugins with active methods load immediately when the editor loads.
+ * Called each time the selection is moved.
+ * @param element Selected elements
+ */
+ active?: (element: any) => boolean;
+
+ /**
+ * @description TML title attribute (tooltip) - default: plugin's name
+ */
+ title?: string,
+
+ /**
+ * @description HTML to be append to button (icon)
+ * Recommend using the inline svg icon. - default: "<span class="se-icon-text">!</span>"
+ */
+ innerHTML?: string,
+
+ /**
+ * @description The class of the button. - default: "se-btn"
+ * Do not recommend using it unless it is a special situation.
+ */
+ buttonClass?: string
+}
\ No newline at end of file
--- /dev/null
+import { Plugin } from './Plugin';
+
+export interface SubmenuPlugin extends Plugin {
+ /**
+ * @description Called after the submenu has been rendered
+ */
+ on?: () => void;
+}
\ No newline at end of file
--- /dev/null
+import { CommandPlugin } from '../CommandPlugin';
+
+declare const blockquote: CommandPlugin;
+
+export default blockquote;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ name: 'blockquote',
+ display: 'command',
+ add: function (core, targetElement) {
+ const context = core.context;
+ context.blockquote = {
+ targetButton: targetElement,
+ tag: core.util.createElement('BLOCKQUOTE')
+ };
+ },
+
+ /**
+ * @Override core
+ */
+ active: function (element) {
+ if (!element) {
+ this.util.removeClass(this.context.blockquote.targetButton, 'active');
+ } else if (/blockquote/i.test(element.nodeName)) {
+ this.util.addClass(this.context.blockquote.targetButton, 'active');
+ return true;
+ }
+
+ return false;
+ },
+
+ /**
+ * @Override core
+ */
+ action: function () {
+ const currentBlockquote = this.util.getParentElement(this.getSelectionNode(), 'blockquote');
+
+ if (currentBlockquote) {
+ this.detachRangeFormatElement(currentBlockquote, null, null, false, false);
+ } else {
+ this.applyRangeFormatElement(this.context.blockquote.tag.cloneNode(false));
+ }
+ }
+};
\ No newline at end of file
--- /dev/null
+import { DialogPlugin } from '../DialogPlugin';
+
+declare const audio: DialogPlugin;
+
+export default audio;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+import dialog from '../modules/dialog';
+import component from '../modules/component';
+import fileManager from '../modules/fileManager';
+
+export default {
+ name: 'audio',
+ display: 'dialog',
+ add: function (core) {
+ core.addModule([dialog, component, fileManager]);
+
+ const context = core.context;
+ const contextAudio = context.audio = {
+ _infoList: [], // @Override fileManager
+ _infoIndex: 0, // @Override fileManager
+ _uploadFileLength: 0, // @Override fileManager
+ focusElement: null, // @Override // This element has focus when the dialog is opened.
+ targetSelect: null,
+ _origin_w: context.option.audioWidth,
+ _origin_h: context.option.audioHeight,
+ _linkValue: '',
+ // @require @Override component
+ _element: null,
+ _cover: null,
+ _container: null,
+ };
+
+ /** dialog */
+ let audio_dialog = this.setDialog.call(core);
+ contextAudio.modal = audio_dialog;
+ contextAudio.audioInputFile = audio_dialog.querySelector('._se_audio_files');
+ contextAudio.audioUrlFile = audio_dialog.querySelector('.se-input-url');
+ contextAudio.focusElement = contextAudio.audioInputFile || contextAudio.audioUrlFile;
+ contextAudio.preview = audio_dialog.querySelector('.se-link-preview');
+
+ /** controller */
+ let audio_controller = this.setController.call(core);
+ contextAudio.controller = audio_controller;
+
+ audio_controller.addEventListener('mousedown', core.eventStop);
+
+ /** add event listeners */
+ audio_dialog.querySelector('.se-btn-primary').addEventListener('click', this.submit.bind(core));
+ if (contextAudio.audioInputFile) audio_dialog.querySelector('.se-dialog-files-edge-button').addEventListener('click', this._removeSelectedFiles.bind(contextAudio.audioInputFile, contextAudio.audioUrlFile, contextAudio.preview));
+ if (contextAudio.audioInputFile && contextAudio.audioUrlFile) contextAudio.audioInputFile.addEventListener('change', this._fileInputChange.bind(contextAudio));
+ audio_controller.addEventListener('click', this.onClick_controller.bind(core));
+ if (contextAudio.audioUrlFile) contextAudio.audioUrlFile.addEventListener('input', this._onLinkPreview.bind(contextAudio.preview, contextAudio, context.options.linkProtocol));
+
+ /** append html */
+ context.dialog.modal.appendChild(audio_dialog);
+
+ /** append controller */
+ context.element.relative.appendChild(audio_controller);
+
+ /** empty memory */
+ audio_dialog = null, audio_controller = null;
+ },
+
+ /** HTML - dialog */
+ setDialog: function () {
+ const option = this.context.option;
+ const lang = this.lang;
+ const dialog = this.util.createElement('DIV');
+
+ dialog.className = 'se-dialog-content';
+ dialog.style.display = 'none';
+ let html = '' +
+ '<form method="post" enctype="multipart/form-data">' +
+ '<div class="se-dialog-header">' +
+ '<button type="button" data-command="close" class="se-btn se-dialog-close" aria-label="Close" title="' + lang.dialogBox.close + '">' +
+ this.icons.cancel +
+ '</button>' +
+ '<span class="se-modal-title">' + lang.dialogBox.audioBox.title + '</span>' +
+ '</div>' +
+ '<div class="se-dialog-body">';
+
+ if (option.audioFileInput) {
+ html += '' +
+ '<div class="se-dialog-form">' +
+ '<label>' + lang.dialogBox.audioBox.file + '</label>' +
+ '<div class="se-dialog-form-files">' +
+ '<input class="se-input-form _se_audio_files" type="file" accept="' + option.audioAccept + '"' + (option.audioMultipleFile ? ' multiple="multiple"' : '') + '/>' +
+ '<button type="button" data-command="filesRemove" class="se-btn se-dialog-files-edge-button se-file-remove" title="' + lang.controller.remove + '">' + this.icons.cancel + '</button>' +
+ '</div>' +
+ '</div>';
+ }
+
+ if (option.audioUrlInput) {
+ html += '' +
+ '<div class="se-dialog-form">' +
+ '<label>' + lang.dialogBox.audioBox.url + '</label>' +
+ '<input class="se-input-form se-input-url" type="text" />' +
+ '<pre class="se-link-preview"></pre>' +
+ '</div>';
+ }
+
+ html += '' +
+ '</div>' +
+ '<div class="se-dialog-footer">' +
+ '<button type="submit" class="se-btn-primary" title="' + lang.dialogBox.submitButton + '"><span>' + lang.dialogBox.submitButton + '</span></button>' +
+ '</div>' +
+ '</form>';
+
+ dialog.innerHTML = html;
+
+ return dialog;
+ },
+
+ /** HTML - controller */
+ setController: function () {
+ const lang = this.lang;
+ const icons = this.icons;
+ const link_btn = this.util.createElement('DIV');
+
+ link_btn.className = 'se-controller se-controller-link';
+ link_btn.innerHTML = '' +
+ '<div class="se-arrow se-arrow-up"></div>' +
+ '<div class="link-content">' +
+ '<div class="se-btn-group">' +
+ '<button type="button" data-command="update" tabindex="-1" class="se-tooltip">' +
+ icons.edit +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.edit + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="delete" tabindex="-1" class="se-tooltip">' +
+ icons.delete +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.remove + '</span></span>' +
+ '</button>' +
+ '</div>' +
+ '</div>';
+
+ return link_btn;
+ },
+
+ // Disable url input when uploading files
+ _fileInputChange: function () {
+ if (!this.audioInputFile.value) {
+ this.audioUrlFile.removeAttribute('disabled');
+ this.preview.style.textDecoration = '';
+ } else {
+ this.audioUrlFile.setAttribute('disabled', true);
+ this.preview.style.textDecoration = 'line-through';
+ }
+ },
+
+ // Disable url input when uploading files
+ _removeSelectedFiles: function (urlInput, preview) {
+ this.value = '';
+ if (urlInput) {
+ urlInput.removeAttribute('disabled');
+ preview.style.textDecoration = '';
+ }
+ },
+
+ // create new audio tag
+ _createAudioTag: function () {
+ const oAudio = this.util.createElement('AUDIO');
+ this.plugins.audio._setTagAttrs.call(this, oAudio);
+
+ const w = this.context.audio._origin_w;
+ const h = this.context.audio._origin_h;
+ oAudio.setAttribute('origin-size', w + ',' + h);
+ oAudio.style.cssText = (w ? ('width:' + w + '; ') : '') + (h ? ('height:' + h + ';') : '');
+
+ return oAudio;
+ },
+
+ _setTagAttrs: function (element) {
+ element.setAttribute('controls', true);
+
+ const attrs = this.context.options.audioTagAttrs;
+ if (!attrs) return;
+
+ for (let key in attrs) {
+ if (!this.util.hasOwn(attrs, key)) continue;
+ element.setAttribute(key, attrs[key]);
+ }
+ },
+
+ _onLinkPreview: function (context, protocol, e) {
+ const value = e.target.value.trim();
+ context._linkValue = this.textContent = !value ? '' : (protocol && value.indexOf('://') === -1 && value.indexOf('#') !== 0) ? protocol + value : value.indexOf('://') === -1 ? '/' + value : value;
+ },
+
+ /**
+ * @Required @Override fileManager
+ */
+ fileTags: ['audio'],
+
+ /**
+ * @Override core, fileManager, resizing
+ * @description It is called from core.selectComponent.
+ * @param {Element} element Target element
+ */
+ select: function (element) {
+ this.plugins.audio.onModifyMode.call(this, element);
+ },
+
+ /**
+ * @Override fileManager, resizing
+ */
+ destroy: function (element) {
+ element = element || this.context.audio._element;
+ const container = this.util.getParentElement(element, this.util.isComponent) || element;
+ const dataIndex = element.getAttribute('data-index') * 1;
+ const focusEl = (container.previousElementSibling || container.nextElementSibling);
+
+ const emptyDiv = container.parentNode;
+ this.util.removeItem(container);
+ this.plugins.audio.init.call(this);
+ this.controllersOff();
+
+ if (emptyDiv !== this.context.element.wysiwyg) this.util.removeItemAllParents(emptyDiv, function (current) { return current.childNodes.length === 0; }, null);
+
+ // focus
+ this.focusEdge(focusEl);
+
+ // fileManager event
+ this.plugins.fileManager.deleteInfo.call(this, 'audio', dataIndex, this.functions.onAudioUpload);
+
+ // history stack
+ this.history.push(false);
+ },
+
+ /**
+ * @Override fileManager
+ */
+ checkFileInfo: function () {
+ this.plugins.fileManager.checkInfo.call(this, 'audio', ['audio'], this.functions.onAudioUpload, this.plugins.audio.updateCover.bind(this), false);
+ },
+
+ /**
+ * @Override fileManager
+ */
+ resetFileInfo: function () {
+ this.plugins.fileManager.resetInfo.call(this, 'audio', this.functions.onAudioUpload);
+ },
+
+ /**
+ * @Required @Override dialog
+ */
+ on: function (update) {
+ const contextAudio = this.context.audio;
+
+ if (!update) {
+ this.plugins.audio.init.call(this);
+ if (contextAudio.audioInputFile && this.context.options.audioMultipleFile) contextAudio.audioInputFile.setAttribute('multiple', 'multiple');
+ } else if (contextAudio._element) {
+ this.context.dialog.updateModal = true;
+ contextAudio._linkValue = contextAudio.preview.textContent = contextAudio.audioUrlFile.value = contextAudio._element.src;
+ if (contextAudio.audioInputFile && this.context.options.audioMultipleFile) contextAudio.audioInputFile.removeAttribute('multiple');
+ } else {
+ if (contextAudio.audioInputFile && this.context.options.audioMultipleFile) contextAudio.audioInputFile.removeAttribute('multiple');
+ }
+ },
+
+ /**
+ * @Required @Override dialog
+ */
+ open: function () {
+ this.plugins.dialog.open.call(this, 'audio', 'audio' === this.currentControllerName);
+ },
+
+ submit: function (e) {
+ const contextAudio = this.context.audio;
+
+ e.preventDefault();
+ e.stopPropagation();
+
+ try {
+ if (contextAudio.audioInputFile && contextAudio.audioInputFile.files.length > 0) {
+ this.showLoading();
+ this.plugins.audio.submitAction.call(this, contextAudio.audioInputFile.files);
+ } else if (contextAudio.audioUrlFile && contextAudio._linkValue.length > 0) {
+ this.showLoading();
+ this.plugins.audio.setupUrl.call(this, contextAudio._linkValue);
+ }
+ } catch (error) {
+ this.closeLoading();
+ throw Error('[SUNEDITOR.audio.submit.fail] cause : "' + error.message + '"');
+ } finally {
+ this.plugins.dialog.close.call(this);
+ }
+
+ return false;
+ },
+
+ submitAction: function (fileList) {
+ if (fileList.length === 0) return;
+
+ let fileSize = 0;
+ let files = [];
+ for (let i = 0, len = fileList.length; i < len; i++) {
+ if (/audio/i.test(fileList[i].type)) {
+ files.push(fileList[i]);
+ fileSize += fileList[i].size;
+ }
+ }
+
+ const limitSize = this.context.option.audioUploadSizeLimit;
+ if (limitSize > 0) {
+ let infoSize = 0;
+ const audiosInfo = this.context.audio._infoList;
+ for (let i = 0, len = audiosInfo.length; i < len; i++) {
+ infoSize += audiosInfo[i].size * 1;
+ }
+
+ if ((fileSize + infoSize) > limitSize) {
+ this.closeLoading();
+ const err = '[SUNEDITOR.audioUpload.fail] Size of uploadable total audios: ' + (limitSize/1000) + 'KB';
+ if (this.functions.onAudioUploadError !== 'function' || this.functions.onAudioUploadError(err, { 'limitSize': limitSize, 'currentSize': infoSize, 'uploadSize': fileSize }, this)) {
+ this.functions.noticeOpen(err);
+ }
+ return;
+ }
+ }
+
+ const contextAudio = this.context.audio;
+ contextAudio._uploadFileLength = files.length;
+
+ const info = {
+ isUpdate: this.context.dialog.updateModal,
+ element: contextAudio._element
+ };
+
+ if (typeof this.functions.onAudioUploadBefore === 'function') {
+ const result = this.functions.onAudioUploadBefore(files, info, this, function (data) {
+ if (data && this._w.Array.isArray(data.result)) {
+ this.plugins.audio.register.call(this, info, data);
+ } else {
+ this.plugins.audio.upload.call(this, info, data);
+ }
+ }.bind(this));
+
+ if (typeof result === 'undefined') return;
+ if (!result) {
+ this.closeLoading();
+ return;
+ }
+ if (typeof result === 'object' && result.length > 0) files = result;
+ }
+
+ this.plugins.audio.upload.call(this, info, files);
+ },
+
+ error: function (message, response) {
+ this.closeLoading();
+ if (typeof this.functions.onAudioUploadError !== 'function' || this.functions.onAudioUploadError(message, response, this)) {
+ this.functions.noticeOpen(message);
+ throw Error('[SUNEDITOR.plugin.audio.exception] response: ' + message);
+ }
+ },
+
+ upload: function (info, files) {
+ if (!files) {
+ this.closeLoading();
+ return;
+ }
+ if (typeof files === 'string') {
+ this.plugins.audio.error.call(this, files, null);
+ return;
+ }
+
+ const audioUploadUrl = this.context.option.audioUploadUrl;
+ const filesLen = this.context.dialog.updateModal ? 1 : files.length;
+
+ // create formData
+ const formData = new FormData();
+ for (let i = 0; i < filesLen; i++) {
+ formData.append('file-' + i, files[i]);
+ }
+
+ // server upload
+ this.plugins.fileManager.upload.call(this, audioUploadUrl, this.context.option.audioUploadHeader, formData, this.plugins.audio.callBack_upload.bind(this, info), this.functions.onAudioUploadError);
+ },
+
+ callBack_upload: function (info, xmlHttp) {
+ if (typeof this.functions.audioUploadHandler === 'function') {
+ this.functions.audioUploadHandler(xmlHttp, info, this);
+ } else {
+ const response = JSON.parse(xmlHttp.responseText);
+ if (response.errorMessage) {
+ this.plugins.audio.error.call(this, response.errorMessage, response);
+ } else {
+ this.plugins.audio.register.call(this, info, response);
+ }
+ }
+ },
+
+ register: function (info, response) {
+ const fileList = response.result;
+
+ for (let i = 0, len = fileList.length, file, oAudio; i < len; i++) {
+ if (info.isUpdate) oAudio = info.element;
+ else oAudio = this.plugins.audio._createAudioTag.call(this);
+
+ file = { name: fileList[i].name, size: fileList[i].size };
+ this.plugins.audio.create_audio.call(this, oAudio, fileList[i].url, file, info.isUpdate);
+ }
+
+ this.closeLoading();
+ },
+
+ setupUrl: function (src) {
+ try {
+ if (src.length === 0) return false;
+ this.plugins.audio.create_audio.call(this, this.plugins.audio._createAudioTag.call(this), src, null, this.context.dialog.updateModal);
+ } catch (error) {
+ throw Error('[SUNEDITOR.audio.audio.fail] cause : "' + error.message + '"');
+ } finally {
+ this.closeLoading();
+ }
+ },
+
+ create_audio: function (element, src, file, isUpdate) {
+ const contextAudio = this.context.audio;
+
+ // create new tag
+ if (!isUpdate) {
+ element.src = src;
+ const cover = this.plugins.component.set_cover.call(this, element);
+ const container = this.plugins.component.set_container.call(this, cover, '');
+ if (!this.insertComponent(container, false, true, false)) {
+ this.focus();
+ return;
+ }
+ } // update
+ else {
+ if (contextAudio._element) element = contextAudio._element;
+ if (element && element.src !== src) {
+ element.src = src;
+ } else {
+ this.selectComponent(element, 'audio');
+ return;
+ }
+ }
+
+ this.plugins.fileManager.setInfo.call(this, 'audio', element, this.functions.onAudioUpload, file, false);
+ this.selectComponent(element, 'audio');
+ if (isUpdate) this.history.push(false);
+ },
+
+ updateCover: function (element) {
+ const contextAudio = this.context.audio;
+ this.plugins.audio._setTagAttrs.call(this, element);
+
+ // find component element
+ const existElement = this.util.getParentElement(element, this.util.isMediaComponent) ||
+ this.util.getParentElement(element, function (current) {
+ return this.isWysiwygDiv(current.parentNode);
+ }.bind(this.util));
+
+ // clone element
+ contextAudio._element = element = element.cloneNode(false);
+ const cover = this.plugins.component.set_cover.call(this, element);
+ const container = this.plugins.component.set_container.call(this, cover, 'se-audio-container');
+
+ existElement.parentNode.replaceChild(container, existElement);
+ this.plugins.fileManager.setInfo.call(this, 'audio', element, this.functions.onAudioUpload, null, false);
+ },
+
+ /**
+ * @Required @Override fileManager, resizing
+ */
+ onModifyMode: function (selectionTag) {
+ const contextAudio = this.context.audio;
+
+ this.setControllerPosition(contextAudio.controller, selectionTag, 'bottom', {left: 0, top: 0});
+ this.controllersOn(contextAudio.controller, selectionTag, this.plugins.audio.onControllerOff.bind(this, selectionTag), 'audio');
+
+ this.util.addClass(selectionTag, 'active');
+ contextAudio._element = selectionTag;
+ contextAudio._cover = this.util.getParentElement(selectionTag, 'FIGURE');
+ contextAudio._container = this.util.getParentElement(selectionTag, this.util.isComponent);
+ },
+
+ /**
+ * @Required @Override fileManager, resizing
+ */
+ openModify: function (notOpen) {
+ if (this.context.audio.audioUrlFile) {
+ const contextAudio = this.context.audio;
+ contextAudio._linkValue = contextAudio.preview.textContent = contextAudio.audioUrlFile.value = contextAudio._element.src;
+ }
+ if (!notOpen) this.plugins.dialog.open.call(this, 'audio', true);
+ },
+
+ onClick_controller: function (e) {
+ e.stopPropagation();
+
+ const command = e.target.getAttribute('data-command');
+ if (!command) return;
+
+ e.preventDefault();
+
+ if (/update/.test(command)) {
+ this.plugins.audio.openModify.call(this, false);
+ }
+ else { /** delete */
+ this.plugins.audio.destroy.call(this, this.context.audio._element);
+ }
+
+ this.controllersOff();
+ },
+
+ onControllerOff: function (selectionTag) {
+ this.util.removeClass(selectionTag, 'active');
+ this.context.audio.controller.style.display = 'none';
+ },
+
+ /**
+ * @Required @Override dialog
+ */
+ init: function () {
+ if (this.context.dialog.updateModal) return;
+ const contextAudio = this.context.audio;
+
+ if (contextAudio.audioInputFile) contextAudio.audioInputFile.value = '';
+ if (contextAudio.audioUrlFile) contextAudio._linkValue = contextAudio.preview.textContent = contextAudio.audioUrlFile.value = '';
+ if (contextAudio.audioInputFile && contextAudio.audioUrlFile) {
+ contextAudio.audioUrlFile.removeAttribute('disabled');
+ contextAudio.preview.style.textDecoration = '';
+ }
+
+ contextAudio._element = null;
+ }
+};
\ No newline at end of file
--- /dev/null
+import { DialogPlugin } from '../DialogPlugin';
+
+declare const image: DialogPlugin;
+
+export default image;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+import dialog from '../modules/dialog';
+import component from '../modules/component';
+import resizing from '../modules/resizing';
+import fileManager from '../modules/fileManager';
+
+export default {
+ name: 'image',
+ display: 'dialog',
+ add: function (core) {
+ core.addModule([dialog, component, resizing, fileManager]);
+
+ const context = core.context;
+ const contextImage = context.image = {
+ _infoList: [], // @Override fileManager
+ _infoIndex: 0, // @Override fileManager
+ _uploadFileLength: 0, // @Override fileManager
+ sizeUnit: context.option._imageSizeUnit,
+ _altText: '',
+ _linkElement: null,
+ _align: 'none',
+ _floatClassRegExp: '__se__float\\-[a-z]+',
+ _v_link: {_linkValue: ''},
+ _v_src: {_linkValue: ''},
+ svgDefaultSize: '30%',
+ base64RenderIndex: 0,
+ // @require @Override component
+ _element: null,
+ _cover: null,
+ _container: null,
+ // @Override resizing properties
+ inputX: null,
+ inputY: null,
+ _element_w: 1,
+ _element_h: 1,
+ _element_l: 0,
+ _element_t: 0,
+ _defaultSizeX: 'auto',
+ _defaultSizeY: 'auto',
+ _origin_w: context.option.imageWidth === 'auto' ? '' : context.option.imageWidth,
+ _origin_h: context.option.imageHeight === 'auto' ? '' : context.option.imageHeight,
+ _proportionChecked: true,
+ _resizing: context.option.imageResizing,
+ _resizeDotHide: !context.option.imageHeightShow,
+ _rotation: context.option.imageRotation,
+ _onlyPercentage: context.option.imageSizeOnlyPercentage,
+ _ratio: false,
+ _ratioX: 1,
+ _ratioY: 1,
+ _captionShow: true,
+ _captionChecked: false,
+ _caption: null,
+ captionCheckEl: null
+ };
+
+ /** image dialog */
+ let image_dialog = this.setDialog.call(core);
+ contextImage.modal = image_dialog;
+ contextImage.imgInputFile = image_dialog.querySelector('._se_image_file');
+ contextImage.imgUrlFile = image_dialog.querySelector('._se_image_url');
+ contextImage.focusElement = contextImage.imgInputFile || contextImage.imgUrlFile;
+ contextImage.altText = image_dialog.querySelector('._se_image_alt');
+ contextImage.imgLink = image_dialog.querySelector('._se_image_link');
+ contextImage.imgLinkNewWindowCheck = image_dialog.querySelector('._se_image_link_check');
+ contextImage.captionCheckEl = image_dialog.querySelector('._se_image_check_caption');
+ contextImage.previewLink = image_dialog.querySelector('._se_tab_content_url .se-link-preview');
+ contextImage.previewSrc = image_dialog.querySelector('._se_tab_content_image .se-link-preview');
+
+ /** add event listeners */
+ image_dialog.querySelector('.se-dialog-tabs').addEventListener('click', this.openTab.bind(core));
+ image_dialog.querySelector('.se-btn-primary').addEventListener('click', this.submit.bind(core));
+ if (contextImage.imgInputFile) image_dialog.querySelector('.se-file-remove').addEventListener('click', this._removeSelectedFiles.bind(contextImage.imgInputFile, contextImage.imgUrlFile, contextImage.previewSrc));
+ if (contextImage.imgInputFile && contextImage.imgUrlFile) contextImage.imgInputFile.addEventListener('change', this._fileInputChange.bind(contextImage));
+
+ contextImage.imgLink.addEventListener('input', this._onLinkPreview.bind(contextImage.previewLink, contextImage._v_link, context.options.linkProtocol));
+ if (contextImage.imgUrlFile) contextImage.imgUrlFile.addEventListener('input', this._onLinkPreview.bind(contextImage.previewSrc, contextImage._v_src, context.options.linkProtocol));
+
+ const imageGalleryButton = image_dialog.querySelector('.__se__gallery');
+ if (imageGalleryButton) imageGalleryButton.addEventListener('click', this._openGallery.bind(core));
+
+ contextImage.proportion = {};
+ contextImage.inputX = {};
+ contextImage.inputY = {};
+ if (context.option.imageResizing) {
+ contextImage.proportion = image_dialog.querySelector('._se_image_check_proportion');
+ contextImage.inputX = image_dialog.querySelector('._se_image_size_x');
+ contextImage.inputY = image_dialog.querySelector('._se_image_size_y');
+ contextImage.inputX.value = context.option.imageWidth;
+ contextImage.inputY.value = context.option.imageHeight;
+
+ contextImage.inputX.addEventListener('keyup', this.setInputSize.bind(core, 'x'));
+ contextImage.inputY.addEventListener('keyup', this.setInputSize.bind(core, 'y'));
+
+ contextImage.inputX.addEventListener('change', this.setRatio.bind(core));
+ contextImage.inputY.addEventListener('change', this.setRatio.bind(core));
+ contextImage.proportion.addEventListener('change', this.setRatio.bind(core));
+
+ image_dialog.querySelector('.se-dialog-btn-revert').addEventListener('click', this.sizeRevert.bind(core));
+ }
+
+ /** append html */
+ context.dialog.modal.appendChild(image_dialog);
+
+ /** empty memory */
+ image_dialog = null;
+ },
+
+ /** dialog */
+ setDialog: function () {
+ const option = this.context.option;
+ const lang = this.lang;
+ const dialog = this.util.createElement('DIV');
+
+ dialog.className = 'se-dialog-content';
+ dialog.style.display = 'none';
+
+ let html = '' +
+ '<div class="se-dialog-header">' +
+ '<button type="button" data-command="close" class="se-btn se-dialog-close" class="close" aria-label="Close" title="' + lang.dialogBox.close + '">' +
+ this.icons.cancel +
+ '</button>' +
+ '<span class="se-modal-title">' + lang.dialogBox.imageBox.title + '</span>' +
+ '</div>' +
+ '<div class="se-dialog-tabs">' +
+ '<button type="button" class="_se_tab_link active" data-tab-link="image">' + lang.toolbar.image + '</button>' +
+ '<button type="button" class="_se_tab_link" data-tab-link="url">' + lang.toolbar.link + '</button>' +
+ '</div>' +
+ '<form method="post" enctype="multipart/form-data">' +
+ '<div class="_se_tab_content _se_tab_content_image">' +
+ '<div class="se-dialog-body"><div style="border-bottom: 1px dashed #ccc;">';
+
+ if (option.imageFileInput) {
+ html += '' +
+ '<div class="se-dialog-form">' +
+ '<label>' + lang.dialogBox.imageBox.file + '</label>' +
+ '<div class="se-dialog-form-files">' +
+ '<input class="se-input-form _se_image_file" type="file" accept="' + option.imageAccept + '"' + (option.imageMultipleFile ? ' multiple="multiple"' : '') + '/>' +
+ '<button type="button" class="se-btn se-dialog-files-edge-button se-file-remove" title="' + lang.controller.remove + '">' + this.icons.cancel + '</button>' +
+ '</div>' +
+ '</div>' ;
+ }
+
+ if (option.imageUrlInput) {
+ html += '' +
+ '<div class="se-dialog-form">' +
+ '<label>' + lang.dialogBox.imageBox.url + '</label>' +
+ '<div class="se-dialog-form-files">' +
+ '<input class="se-input-form se-input-url _se_image_url" type="text" />' +
+ ((option.imageGalleryUrl && this.plugins.imageGallery) ? '<button type="button" class="se-btn se-dialog-files-edge-button __se__gallery" title="' + lang.toolbar.imageGallery + '">' + this.icons.image_gallery + '</button>' : '') +
+ '</div>' +
+ '<pre class="se-link-preview"></pre>' +
+ '</div>';
+ }
+
+ html += '</div>' +
+ '<div class="se-dialog-form">' +
+ '<label>' + lang.dialogBox.imageBox.altText + '</label><input class="se-input-form _se_image_alt" type="text" />' +
+ '</div>';
+
+ if (option.imageResizing) {
+ const onlyPercentage = option.imageSizeOnlyPercentage;
+ const onlyPercentDisplay = onlyPercentage ? ' style="display: none !important;"' : '';
+ const heightDisplay = !option.imageHeightShow ? ' style="display: none !important;"' : '';
+ html += '<div class="se-dialog-form">';
+ if (onlyPercentage || !option.imageHeightShow) {
+ html += '' +
+ '<div class="se-dialog-size-text">' +
+ '<label class="size-w">' + lang.dialogBox.size + '</label>' +
+ '</div>';
+ } else {
+ html += '' +
+ '<div class="se-dialog-size-text">' +
+ '<label class="size-w">' + lang.dialogBox.width + '</label>' +
+ '<label class="se-dialog-size-x"> </label>' +
+ '<label class="size-h">' + lang.dialogBox.height + '</label>' +
+ '</div>';
+ }
+ html += '' +
+ '<input class="se-input-control _se_image_size_x" placeholder="auto"' + (onlyPercentage ? ' type="number" min="1"' : 'type="text"') + (onlyPercentage ? ' max="100"' : '') + ' />' +
+ '<label class="se-dialog-size-x"' + heightDisplay + '>' + (onlyPercentage ? '%' : 'x') + '</label>' +
+ '<input type="text" class="se-input-control _se_image_size_y" placeholder="auto"' + onlyPercentDisplay + (onlyPercentage ? ' max="100"' : '') + heightDisplay + '/>' +
+ '<label' + onlyPercentDisplay + heightDisplay + '><input type="checkbox" class="se-dialog-btn-check _se_image_check_proportion" checked/> ' + lang.dialogBox.proportion + '</label>' +
+ '<button type="button" title="' + lang.dialogBox.revertButton + '" class="se-btn se-dialog-btn-revert" style="float: right;">' + this.icons.revert + '</button>' +
+ '</div>' ;
+ }
+
+ html += '' +
+ '<div class="se-dialog-form se-dialog-form-footer">' +
+ '<label><input type="checkbox" class="se-dialog-btn-check _se_image_check_caption" /> ' + lang.dialogBox.caption + '</label>' +
+ '</div>' +
+ '</div>' +
+ '</div>' +
+ '<div class="_se_tab_content _se_tab_content_url" style="display: none">' +
+ '<div class="se-dialog-body">' +
+ '<div class="se-dialog-form">' +
+ '<label>' + lang.dialogBox.linkBox.url + '</label><input class="se-input-form se-input-url _se_image_link" type="text" />' +
+ '<pre class="se-link-preview"></pre>' +
+ '</div>' +
+ '<label><input type="checkbox" class="_se_image_link_check"/> ' + lang.dialogBox.linkBox.newWindowCheck + '</label>' +
+ '</div>' +
+ '</div>' +
+ '<div class="se-dialog-footer">' +
+ '<div>' +
+ '<label><input type="radio" name="suneditor_image_radio" class="se-dialog-btn-radio" value="none" checked>' + lang.dialogBox.basic + '</label>' +
+ '<label><input type="radio" name="suneditor_image_radio" class="se-dialog-btn-radio" value="left">' + lang.dialogBox.left + '</label>' +
+ '<label><input type="radio" name="suneditor_image_radio" class="se-dialog-btn-radio" value="center">' + lang.dialogBox.center + '</label>' +
+ '<label><input type="radio" name="suneditor_image_radio" class="se-dialog-btn-radio" value="right">' + lang.dialogBox.right + '</label>' +
+ '</div>' +
+ '<button type="submit" class="se-btn-primary" title="' + lang.dialogBox.submitButton + '"><span>' + lang.dialogBox.submitButton + '</span></button>' +
+ '</div>' +
+ '</form>';
+
+ dialog.innerHTML = html;
+
+ return dialog;
+ },
+
+ _fileInputChange: function () {
+ if (!this.imgInputFile.value) {
+ this.imgUrlFile.removeAttribute('disabled');
+ this.previewSrc.style.textDecoration = '';
+ } else {
+ this.imgUrlFile.setAttribute('disabled', true);
+ this.previewSrc.style.textDecoration = 'line-through';
+ }
+ },
+
+ _removeSelectedFiles: function (urlInput, previewSrc) {
+ this.value = '';
+ if (urlInput) {
+ urlInput.removeAttribute('disabled');
+ previewSrc.style.textDecoration = '';
+ }
+ },
+
+ _openGallery: function () {
+ this.callPlugin('imageGallery', this.plugins.imageGallery.open.bind(this, this.plugins.image._setUrlInput.bind(this.context.image)), null);
+ },
+
+ _setUrlInput: function (target) {
+ this.altText.value = target.alt;
+ this._v_src._linkValue = this.previewSrc.textContent = this.imgUrlFile.value = target.src;
+ this.imgUrlFile.focus();
+ },
+
+ _onLinkPreview: function (context, protocol, e) {
+ const value = e.target.value.trim();
+ context._linkValue = this.textContent = !value ? '' : (protocol && value.indexOf('://') === -1 && value.indexOf('#') !== 0) ? protocol + value : value.indexOf('://') === -1 ? '/' + value : value;
+ },
+
+ /**
+ * @Override @Required fileManager
+ */
+ fileTags: ['img'],
+
+ /**
+ * @Override core, fileManager, resizing
+ * @description It is called from core.selectComponent.
+ * @param {Element} element Target element
+ */
+ select: function (element) {
+ this.plugins.image.onModifyMode.call(this, element, this.plugins.resizing.call_controller_resize.call(this, element, 'image'));
+ },
+
+ /**
+ * @Override fileManager, resizing
+ */
+ destroy: function (element) {
+ const imageEl = element || this.context.image._element;
+ const imageContainer = this.util.getParentElement(imageEl, this.util.isMediaComponent) || imageEl;
+ const dataIndex = imageEl.getAttribute('data-index') * 1;
+ let focusEl = (imageContainer.previousElementSibling || imageContainer.nextElementSibling);
+
+ const emptyDiv = imageContainer.parentNode;
+ this.util.removeItem(imageContainer);
+ this.plugins.image.init.call(this);
+ this.controllersOff();
+
+ if (emptyDiv !== this.context.element.wysiwyg) this.util.removeItemAllParents(emptyDiv, function (current) { return current.childNodes.length === 0; }, null);
+
+ // focus
+ this.focusEdge(focusEl);
+
+ // event
+ this.plugins.fileManager.deleteInfo.call(this, 'image', dataIndex, this.functions.onImageUpload);
+
+ // history stack
+ this.history.push(false);
+ },
+
+ /**
+ * @Required @Override dialog
+ */
+ on: function (update) {
+ const contextImage = this.context.image;
+
+ if (!update) {
+ contextImage.inputX.value = contextImage._origin_w = this.context.option.imageWidth === contextImage._defaultSizeX ? '' : this.context.option.imageWidth;
+ contextImage.inputY.value = contextImage._origin_h = this.context.option.imageHeight === contextImage._defaultSizeY ? '' : this.context.option.imageHeight;
+ if (contextImage.imgInputFile && this.context.options.imageMultipleFile) contextImage.imgInputFile.setAttribute('multiple', 'multiple');
+ } else {
+ if (contextImage.imgInputFile && this.context.options.imageMultipleFile) contextImage.imgInputFile.removeAttribute('multiple');
+ }
+ },
+
+ /**
+ * @Required @Override dialog
+ */
+ open: function () {
+ this.plugins.dialog.open.call(this, 'image', 'image' === this.currentControllerName);
+ },
+
+ openTab: function (e) {
+ const modal = this.context.image.modal;
+ const targetElement = (e === 'init' ? modal.querySelector('._se_tab_link') : e.target);
+
+ if (!/^BUTTON$/i.test(targetElement.tagName)) {
+ return false;
+ }
+
+ // Declare all variables
+ const tabName = targetElement.getAttribute('data-tab-link');
+ const contentClassName = '_se_tab_content';
+ let i, tabContent, tabLinks;
+
+ // Get all elements with class="tabcontent" and hide them
+ tabContent = modal.getElementsByClassName(contentClassName);
+ for (i = 0; i < tabContent.length; i++) {
+ tabContent[i].style.display = 'none';
+ }
+
+ // Get all elements with class="tablinks" and remove the class "active"
+ tabLinks = modal.getElementsByClassName('_se_tab_link');
+ for (i = 0; i < tabLinks.length; i++) {
+ this.util.removeClass(tabLinks[i], 'active');
+ }
+
+ // Show the current tab, and add an "active" class to the button that opened the tab
+ modal.querySelector('.' + contentClassName + '_' + tabName).style.display = 'block';
+ this.util.addClass(targetElement, 'active');
+
+ // focus
+ if (tabName === 'image' && this.context.image.focusElement) {
+ this.context.image.focusElement.focus();
+ } else if (tabName === 'url' && this.context.image.imgLink) {
+ this.context.image.imgLink.focus();
+ }
+
+ return false;
+ },
+
+ submit: function (e) {
+ const contextImage = this.context.image;
+ const imagePlugin = this.plugins.image;
+
+ e.preventDefault();
+ e.stopPropagation();
+
+ contextImage._altText = contextImage.altText.value;
+ contextImage._align = contextImage.modal.querySelector('input[name="suneditor_image_radio"]:checked').value;
+ contextImage._captionChecked = contextImage.captionCheckEl.checked;
+ if (contextImage._resizing) contextImage._proportionChecked = contextImage.proportion.checked;
+
+ try {
+ if (this.context.dialog.updateModal) {
+ imagePlugin.update_image.call(this, false, true, false);
+ }
+
+ if (contextImage.imgInputFile && contextImage.imgInputFile.files.length > 0) {
+ this.showLoading();
+ imagePlugin.submitAction.call(this, this.context.image.imgInputFile.files);
+ } else if (contextImage.imgUrlFile && contextImage._v_src._linkValue.length > 0) {
+ this.showLoading();
+ imagePlugin.onRender_imgUrl.call(this);
+ }
+ } catch (error) {
+ this.closeLoading();
+ throw Error('[SUNEDITOR.image.submit.fail] cause : "' + error.message + '"');
+ } finally {
+ this.plugins.dialog.close.call(this);
+ }
+
+ return false;
+ },
+
+ submitAction: function (fileList) {
+ if (fileList.length === 0) return;
+
+ let fileSize = 0;
+ let files = [];
+ for (let i = 0, len = fileList.length; i < len; i++) {
+ if (/image/i.test(fileList[i].type)) {
+ files.push(fileList[i]);
+ fileSize += fileList[i].size;
+ }
+ }
+
+ const limitSize = this.context.option.imageUploadSizeLimit;
+ if (limitSize > 0) {
+ let infoSize = 0;
+ const imagesInfo = this.context.image._infoList;
+ for (let i = 0, len = imagesInfo.length; i < len; i++) {
+ infoSize += imagesInfo[i].size * 1;
+ }
+
+ if ((fileSize + infoSize) > limitSize) {
+ this.closeLoading();
+ const err = '[SUNEDITOR.imageUpload.fail] Size of uploadable total images: ' + (limitSize/1000) + 'KB';
+ if (this.functions.onImageUploadError !== 'function' || this.functions.onImageUploadError(err, { 'limitSize': limitSize, 'currentSize': infoSize, 'uploadSize': fileSize }, this)) {
+ this.functions.noticeOpen(err);
+ }
+ return;
+ }
+ }
+
+ const contextImage = this.context.image;
+ contextImage._uploadFileLength = files.length;
+
+ const info = {
+ linkValue: contextImage._v_link._linkValue,
+ linkNewWindow: contextImage.imgLinkNewWindowCheck.checked,
+ inputWidth: contextImage.inputX.value,
+ inputHeight: contextImage.inputY.value,
+ align: contextImage._align,
+ isUpdate: this.context.dialog.updateModal,
+ element: contextImage._element
+ };
+
+ if (typeof this.functions.onImageUploadBefore === 'function') {
+ const result = this.functions.onImageUploadBefore(files, info, this, function (data) {
+ if (data && this._w.Array.isArray(data.result)) {
+ this.plugins.image.register.call(this, info, data);
+ } else {
+ this.plugins.image.upload.call(this, info, data);
+ }
+ }.bind(this));
+
+ if (typeof result === 'undefined') return;
+ if (!result) {
+ this.closeLoading();
+ return;
+ }
+ if (this._w.Array.isArray(result) && result.length > 0) files = result;
+ }
+
+ this.plugins.image.upload.call(this, info, files);
+ },
+
+ error: function (message, response) {
+ this.closeLoading();
+ if (typeof this.functions.onImageUploadError !== 'function' || this.functions.onImageUploadError(message, response, this)) {
+ this.functions.noticeOpen(message);
+ throw Error('[SUNEDITOR.plugin.image.error] response: ' + message);
+ }
+ },
+
+ upload: function (info, files) {
+ if (!files) {
+ this.closeLoading();
+ return;
+ }
+ if (typeof files === 'string') {
+ this.plugins.image.error.call(this, files, null);
+ return;
+ }
+
+ const imageUploadUrl = this.context.option.imageUploadUrl;
+ const filesLen = this.context.dialog.updateModal ? 1 : files.length;
+
+ // server upload
+ if (typeof imageUploadUrl === 'string' && imageUploadUrl.length > 0) {
+ const formData = new FormData();
+ for (let i = 0; i < filesLen; i++) {
+ formData.append('file-' + i, files[i]);
+ }
+ this.plugins.fileManager.upload.call(this, imageUploadUrl, this.context.option.imageUploadHeader, formData, this.plugins.image.callBack_imgUpload.bind(this, info), this.functions.onImageUploadError);
+ } else { // base64
+ this.plugins.image.setup_reader.call(this, files, info.linkValue, info.linkNewWindow, info.inputWidth, info.inputHeight, info.align, filesLen, info.isUpdate);
+ }
+ },
+
+ callBack_imgUpload: function (info, xmlHttp) {
+ if (typeof this.functions.imageUploadHandler === 'function') {
+ this.functions.imageUploadHandler(xmlHttp, info, this);
+ } else {
+ const response = JSON.parse(xmlHttp.responseText);
+ if (response.errorMessage) {
+ this.plugins.image.error.call(this, response.errorMessage, response);
+ } else {
+ this.plugins.image.register.call(this, info, response);
+ }
+ }
+ },
+
+ register: function (info, response) {
+ const fileList = response.result;
+
+ for (let i = 0, len = fileList.length, file; i < len; i++) {
+ file = { name: fileList[i].name, size: fileList[i].size };
+ if (info.isUpdate) {
+ this.plugins.image.update_src.call(this, fileList[i].url, info.element, file);
+ break;
+ } else {
+ this.plugins.image.create_image.call(this, fileList[i].url, info.linkValue, info.linkNewWindow, info.inputWidth, info.inputHeight, info.align, file);
+ }
+ }
+
+ this.closeLoading();
+ },
+
+ setup_reader: function (files, imgLinkValue, newWindowCheck, width, height, align, filesLen, isUpdate) {
+ try {
+ this.context.image.base64RenderIndex = filesLen;
+ const wFileReader = this._w.FileReader;
+ const filesStack = [filesLen];
+ this.context.image.inputX.value = width;
+ this.context.image.inputY.value = height;
+
+ for (let i = 0, reader, file; i < filesLen; i++) {
+ reader = new wFileReader();
+ file = files[i];
+
+ reader.onload = function (reader, update, updateElement, file, index) {
+ filesStack[index] = { result: reader.result, file: file };
+
+ if (--this.context.image.base64RenderIndex === 0) {
+ this.plugins.image.onRender_imgBase64.call(this, update, filesStack, updateElement, imgLinkValue, newWindowCheck, width, height, align);
+ this.closeLoading();
+ }
+ }.bind(this, reader, isUpdate, this.context.image._element, file, i);
+
+ reader.readAsDataURL(file);
+ }
+ } catch (e) {
+ this.closeLoading();
+ throw Error('[SUNEDITOR.image.setup_reader.fail] cause : "' + e.message + '"');
+ }
+ },
+
+ onRender_imgBase64: function (update, filesStack, updateElement, imgLinkValue, newWindowCheck, width, height, align) {
+ const updateMethod = this.plugins.image.update_src;
+ const createMethod = this.plugins.image.create_image;
+
+ for (let i = 0, len = filesStack.length; i < len; i++) {
+ if (update) {
+ this.context.image._element.setAttribute('data-file-name', filesStack[i].file.name);
+ this.context.image._element.setAttribute('data-file-size', filesStack[i].file.size);
+ updateMethod.call(this, filesStack[i].result, updateElement, filesStack[i].file);
+ } else {
+ createMethod.call(this, filesStack[i].result, imgLinkValue, newWindowCheck, width, height, align, filesStack[i].file);
+ }
+ }
+ },
+
+ onRender_imgUrl: function () {
+ const contextImage = this.context.image;
+ if (contextImage._v_src._linkValue.length === 0) return false;
+
+ try {
+ const file = {name: contextImage._v_src._linkValue.split('/').pop(), size: 0};
+ if (this.context.dialog.updateModal) this.plugins.image.update_src.call(this, contextImage._v_src._linkValue, contextImage._element, file);
+ else this.plugins.image.create_image.call(this, contextImage._v_src._linkValue, contextImage._v_link._linkValue, contextImage.imgLinkNewWindowCheck.checked, contextImage.inputX.value, contextImage.inputY.value, contextImage._align, file);
+ } catch (e) {
+ throw Error('[SUNEDITOR.image.URLRendering.fail] cause : "' + e.message + '"');
+ } finally {
+ this.closeLoading();
+ }
+ },
+
+ onRender_link: function (imgTag, imgLinkValue, newWindowCheck) {
+ if (imgLinkValue.trim().length > 0) {
+ const link = this.util.createElement('A');
+ link.href = /^https?:\/\//.test(imgLinkValue) ? imgLinkValue : 'http://' + imgLinkValue;
+ link.target = (newWindowCheck ? '_blank' : '');
+ link.setAttribute('data-image-link', 'image');
+ imgTag.setAttribute('data-image-link', imgLinkValue);
+
+ link.appendChild(imgTag);
+ return link;
+ }
+
+ return imgTag;
+ },
+
+ /**
+ * @Override resizing
+ * @param {String} xy 'x': width, 'y': height
+ * @param {KeyboardEvent} e Event object
+ */
+ setInputSize: function (xy, e) {
+ if (e && e.keyCode === 32) {
+ e.preventDefault();
+ return;
+ }
+
+ this.plugins.resizing._module_setInputSize.call(this, this.context.image, xy);
+ },
+
+ /**
+ * @Override resizing
+ */
+ setRatio: function () {
+ this.plugins.resizing._module_setRatio.call(this, this.context.image);
+ },
+
+ /**
+ * @Override fileManager
+ */
+ checkFileInfo: function () {
+ const imagePlugin = this.plugins.image;
+
+ const modifyHandler = function (tag) {
+ imagePlugin.onModifyMode.call(this, tag, null);
+ imagePlugin.openModify.call(this, true);
+ imagePlugin.update_image.call(this, true, false, true);
+ }.bind(this);
+
+ this.plugins.fileManager.checkInfo.call(this, 'image', ['img'], this.functions.onImageUpload, modifyHandler, true);
+ },
+
+ /**
+ * @Override fileManager
+ */
+ resetFileInfo: function () {
+ this.plugins.fileManager.resetInfo.call(this, 'image', this.functions.onImageUpload);
+ },
+
+ create_image: function (src, linkValue, linkNewWindow, width, height, align, file) {
+ const imagePlugin = this.plugins.image;
+ const contextImage = this.context.image;
+ this.context.resizing._resize_plugin = 'image';
+
+ let oImg = this.util.createElement('IMG');
+ oImg.src = src;
+ oImg.alt = contextImage._altText;
+ oImg = imagePlugin.onRender_link.call(this, oImg, linkValue, linkNewWindow);
+ oImg.setAttribute('data-rotate', '0');
+
+ if (contextImage._resizing) {
+ oImg.setAttribute('data-proportion', contextImage._proportionChecked);
+ }
+
+ const cover = this.plugins.component.set_cover.call(this, oImg);
+ const container = this.plugins.component.set_container.call(this, cover, 'se-image-container');
+
+ // caption
+ if (contextImage._captionChecked) {
+ contextImage._caption = this.plugins.component.create_caption.call(this);
+ contextImage._caption.setAttribute('contenteditable', false);
+ cover.appendChild(contextImage._caption);
+ }
+
+ contextImage._element = oImg;
+ contextImage._cover = cover;
+ contextImage._container = container;
+
+ // set size
+ imagePlugin.applySize.call(this, width, height);
+
+ // align
+ imagePlugin.setAlign.call(this, align, oImg, cover, container);
+
+ oImg.onload = imagePlugin._image_create_onload.bind(this, oImg, contextImage.svgDefaultSize);
+ if (this.insertComponent(container, true, true, true)) this.plugins.fileManager.setInfo.call(this, 'image', oImg, this.functions.onImageUpload, file, true);
+ this.context.resizing._resize_plugin = '';
+ },
+
+ _image_create_onload: function (oImg, svgDefaultSize) {
+ // svg exception handling
+ if (oImg.offsetWidth === 0) this.plugins.image.applySize.call(this, svgDefaultSize, '');
+ this.selectComponent.call(this, oImg, 'image');
+ },
+
+ update_image: function (init, openController, notHistoryPush) {
+ const contextImage = this.context.image;
+ const linkValue = contextImage._v_link._linkValue;
+ let imageEl = contextImage._element;
+ let cover = contextImage._cover;
+ let container = contextImage._container;
+ let isNewContainer = false;
+
+ if (cover === null) {
+ isNewContainer = true;
+ imageEl = contextImage._element.cloneNode(true);
+ cover = this.plugins.component.set_cover.call(this, imageEl);
+ }
+
+ if (container === null) {
+ cover = cover.cloneNode(true);
+ imageEl = cover.querySelector('img');
+ isNewContainer = true;
+ container = this.plugins.component.set_container.call(this, cover, 'se-image-container');
+ } else if (isNewContainer) {
+ container.innerHTML = '';
+ container.appendChild(cover);
+ contextImage._cover = cover;
+ contextImage._element = imageEl;
+ isNewContainer = false;
+ }
+
+ // check size
+ let changeSize;
+ const x = this.util.isNumber(contextImage.inputX.value) ? contextImage.inputX.value + contextImage.sizeUnit : contextImage.inputX.value;
+ const y = this.util.isNumber(contextImage.inputY.value) ? contextImage.inputY.value + contextImage.sizeUnit : contextImage.inputY.value;
+ if (/%$/.test(imageEl.style.width)) {
+ changeSize = x !== container.style.width || y !== container.style.height;
+ } else {
+ changeSize = x !== imageEl.style.width || y !== imageEl.style.height;
+ }
+
+ // alt
+ imageEl.alt = contextImage._altText;
+
+ // caption
+ let modifiedCaption = false;
+ if (contextImage._captionChecked) {
+ if (!contextImage._caption) {
+ contextImage._caption = this.plugins.component.create_caption.call(this);
+ cover.appendChild(contextImage._caption);
+ modifiedCaption = true;
+ }
+ } else {
+ if (contextImage._caption) {
+ this.util.removeItem(contextImage._caption);
+ contextImage._caption = null;
+ modifiedCaption = true;
+ }
+ }
+
+ // link
+ if (linkValue.trim().length > 0) {
+ if (contextImage._linkElement !== null && cover.contains(contextImage._linkElement)) {
+ contextImage._linkElement.href = linkValue;
+ contextImage._linkElement.target = (contextImage.imgLinkNewWindowCheck.checked ? '_blank' : '');
+ imageEl.setAttribute('data-image-link', linkValue);
+ } else {
+ let newEl = this.plugins.image.onRender_link.call(this, imageEl, linkValue, this.context.image.imgLinkNewWindowCheck.checked);
+ cover.insertBefore(newEl, contextImage._caption);
+ }
+ }
+ else if (contextImage._linkElement !== null) {
+ const imageElement = imageEl;
+
+ imageElement.setAttribute('data-image-link', '');
+ let newEl = imageElement.cloneNode(true);
+ cover.removeChild(contextImage._linkElement);
+ cover.insertBefore(newEl, contextImage._caption);
+ imageEl = newEl;
+ }
+
+ if (isNewContainer) {
+ const existElement = (this.util.isRangeFormatElement(contextImage._element.parentNode) || this.util.isWysiwygDiv(contextImage._element.parentNode)) ?
+ contextImage._element :
+ /^A$/i.test(contextImage._element.parentNode.nodeName) ? contextImage._element.parentNode : this.util.getFormatElement(contextImage._element) || contextImage._element;
+
+ if (this.util.isFormatElement(existElement) && existElement.textContent.length > 0) {
+ existElement.parentNode.insertBefore(container, existElement.nextElementSibling);
+ this.util.removeItem(contextImage._element);
+ } else {
+ existElement.parentNode.replaceChild(container, existElement);
+ }
+
+ imageEl = container.querySelector('img');
+
+ contextImage._element = imageEl;
+ contextImage._cover = cover;
+ contextImage._container = container;
+ }
+
+ // transform
+ if (modifiedCaption || (!contextImage._onlyPercentage && changeSize)) {
+ if (!init && (/\d+/.test(imageEl.style.height) || (this.context.resizing._rotateVertical && contextImage._captionChecked))) {
+ if (/%$/.test(contextImage.inputX.value) || /%$/.test(contextImage.inputY.value)) {
+ this.plugins.resizing.resetTransform.call(this, imageEl);
+ } else {
+ this.plugins.resizing.setTransformSize.call(this, imageEl, this.util.getNumber(contextImage.inputX.value, 0), this.util.getNumber(contextImage.inputY.value, 0));
+ }
+ }
+ }
+
+ // size
+ let isPercent = false;
+ if (contextImage._resizing) {
+ imageEl.setAttribute('data-proportion', contextImage._proportionChecked);
+ if (changeSize) {
+ this.plugins.image.applySize.call(this);
+ }
+ }
+
+ // align
+ if (!(isPercent && contextImage._align === 'center')) {
+ this.plugins.image.setAlign.call(this, null, imageEl, null, null);
+ }
+
+ // set imagesInfo
+ if (init) {
+ this.plugins.fileManager.setInfo.call(this, 'image', imageEl, this.functions.onImageUpload, null, true);
+ }
+
+ if (openController) {
+ this.selectComponent(imageEl, 'image');
+ }
+
+ // history stack
+ if (!notHistoryPush) this.history.push(false);
+ },
+
+ update_src: function (src, element, file) {
+ element.src = src;
+ this._w.setTimeout(this.plugins.fileManager.setInfo.bind(this, 'image', element, this.functions.onImageUpload, file, true));
+ this.selectComponent(element, 'image');
+ },
+
+ /**
+ * @Required @Override fileManager, resizing
+ */
+ onModifyMode: function (element, size) {
+ if (!element) return;
+
+ const contextImage = this.context.image;
+ contextImage._linkElement = /^A$/i.test(element.parentNode.nodeName) ? element.parentNode : null;
+ contextImage._element = element;
+ contextImage._cover = this.util.getParentElement(element, 'FIGURE');
+ contextImage._container = this.util.getParentElement(element, this.util.isMediaComponent);
+ contextImage._caption = this.util.getChildElement(contextImage._cover, 'FIGCAPTION');
+ contextImage._align = element.getAttribute('data-align') || 'none';
+
+ if (size) {
+ contextImage._element_w = size.w;
+ contextImage._element_h = size.h;
+ contextImage._element_t = size.t;
+ contextImage._element_l = size.l;
+ }
+
+ let userSize = contextImage._element.getAttribute('data-size') || contextImage._element.getAttribute('data-origin');
+ if (userSize) {
+ userSize = userSize.split(',');
+ contextImage._origin_w = userSize[0];
+ contextImage._origin_h = userSize[1];
+ } else if (size) {
+ contextImage._origin_w = size.w;
+ contextImage._origin_h = size.h;
+ }
+ },
+
+ /**
+ * @Required @Override fileManager, resizing
+ */
+ openModify: function (notOpen) {
+ const contextImage = this.context.image;
+ if (contextImage.imgUrlFile) {
+ contextImage._v_src._linkValue = contextImage.previewSrc.textContent = contextImage.imgUrlFile.value = contextImage._element.src;
+ }
+ contextImage._altText = contextImage.altText.value = contextImage._element.alt;
+ contextImage._v_link._linkValue = contextImage.previewLink.textContent = contextImage.imgLink.value = contextImage._linkElement === null ? '' : contextImage._linkElement.href;
+ contextImage.imgLinkNewWindowCheck.checked = contextImage._linkElement && contextImage._linkElement.target === '_blank';
+ contextImage.modal.querySelector('input[name="suneditor_image_radio"][value="' + contextImage._align + '"]').checked = true;
+ contextImage._align = contextImage.modal.querySelector('input[name="suneditor_image_radio"]:checked').value;
+ contextImage._captionChecked = contextImage.captionCheckEl.checked = !!contextImage._caption;
+
+ if (contextImage._resizing) {
+ this.plugins.resizing._module_setModifyInputSize.call(this, contextImage, this.plugins.image);
+ }
+
+ if (!notOpen) this.plugins.dialog.open.call(this, 'image', true);
+ },
+
+ /**
+ * @Override resizing
+ */
+ sizeRevert: function () {
+ this.plugins.resizing._module_sizeRevert.call(this, this.context.image);
+ },
+
+ /**
+ * @Override resizing
+ */
+ applySize: function (w, h) {
+ const contextImage = this.context.image;
+
+ if (!w) w = contextImage.inputX.value || this.context.option.imageWidth;
+ if (!h) h = contextImage.inputY.value || this.context.option.imageHeight;
+
+ if ((contextImage._onlyPercentage && !!w) || /%$/.test(w)) {
+ this.plugins.image.setPercentSize.call(this, w, h);
+ return true;
+ } else if ((!w || w === 'auto') && (!h || h === 'auto')) {
+ this.plugins.image.setAutoSize.call(this);
+ } else {
+ this.plugins.image.setSize.call(this, w, h, false);
+ }
+
+ return false;
+ },
+
+ /**
+ * @Override resizing
+ */
+ setSize: function (w, h, notResetPercentage, direction) {
+ const contextImage = this.context.image;
+ const onlyW = /^(rw|lw)$/.test(direction);
+ const onlyH = /^(th|bh)$/.test(direction);
+
+ this.plugins.image.cancelPercentAttr.call(this);
+
+ if (!onlyH) contextImage._element.style.width = this.util.isNumber(w) ? w + contextImage.sizeUnit : w;
+ if (!onlyW) contextImage._element.style.height = this.util.isNumber(h) ? h + contextImage.sizeUnit : /%$/.test(h) ? '' : h;
+
+ if (contextImage._align === 'center') this.plugins.image.setAlign.call(this, null, null, null, null);
+ if (!notResetPercentage) contextImage._element.removeAttribute('data-percentage');
+
+ // save current size
+ this.plugins.resizing._module_saveCurrentSize.call(this, contextImage);
+ },
+
+ /**
+ * @Override resizing
+ */
+ setAutoSize: function () {
+ const contextImage = this.context.image;
+
+ this.plugins.resizing.resetTransform.call(this, contextImage._element);
+ this.plugins.image.cancelPercentAttr.call(this);
+
+ contextImage._element.style.maxWidth = '';
+ contextImage._element.style.width = '';
+ contextImage._element.style.height = '';
+ contextImage._cover.style.width = '';
+ contextImage._cover.style.height = '';
+
+ this.plugins.image.setAlign.call(this, null, null, null, null);
+ contextImage._element.setAttribute('data-percentage', 'auto,auto');
+
+ // save current size
+ this.plugins.resizing._module_saveCurrentSize.call(this, contextImage);
+ },
+
+ /**
+ * @Override resizing
+ */
+ setOriginSize: function () {
+ const contextImage = this.context.image;
+ contextImage._element.removeAttribute('data-percentage');
+
+ this.plugins.resizing.resetTransform.call(this, contextImage._element);
+ this.plugins.image.cancelPercentAttr.call(this);
+
+ const originSize = (contextImage._element.getAttribute('data-origin') || '').split(',');
+ const w = originSize[0];
+ const h = originSize[1];
+
+ if (originSize) {
+ if (contextImage._onlyPercentage || (/%$/.test(w) && (/%$/.test(h) || !/\d/.test(h)))) {
+ this.plugins.image.setPercentSize.call(this, w, h);
+ } else {
+ this.plugins.image.setSize.call(this, w, h);
+ }
+
+ // save current size
+ this.plugins.resizing._module_saveCurrentSize.call(this, contextImage);
+ }
+ },
+
+ /**
+ * @Override resizing
+ */
+ setPercentSize: function (w, h) {
+ const contextImage = this.context.image;
+ h = !!h && !/%$/.test(h) && !this.util.getNumber(h, 0) ? this.util.isNumber(h) ? h + '%' : h : this.util.isNumber(h) ? h + contextImage.sizeUnit : (h || '');
+ const heightPercentage = /%$/.test(h);
+
+ contextImage._container.style.width = this.util.isNumber(w) ? w + '%' : w;
+ contextImage._container.style.height = '';
+ contextImage._cover.style.width = '100%';
+ contextImage._cover.style.height = !heightPercentage ? '' : h;
+ contextImage._element.style.width = '100%';
+ contextImage._element.style.height = heightPercentage ? '' : h;
+ contextImage._element.style.maxWidth = '';
+
+ if (contextImage._align === 'center') this.plugins.image.setAlign.call(this, null, null, null, null);
+
+ contextImage._element.setAttribute('data-percentage', w + ',' + h);
+ this.plugins.resizing.setCaptionPosition.call(this, contextImage._element);
+
+ // save current size
+ this.plugins.resizing._module_saveCurrentSize.call(this, contextImage);
+ },
+
+ /**
+ * @Override resizing
+ */
+ cancelPercentAttr: function () {
+ const contextImage = this.context.image;
+
+ contextImage._cover.style.width = '';
+ contextImage._cover.style.height = '';
+ contextImage._container.style.width = '';
+ contextImage._container.style.height = '';
+
+ this.util.removeClass(contextImage._container, this.context.image._floatClassRegExp);
+ this.util.addClass(contextImage._container, '__se__float-' + contextImage._align);
+
+ if (contextImage._align === 'center') this.plugins.image.setAlign.call(this, null, null, null, null);
+ },
+
+ /**
+ * @Override resizing
+ */
+ setAlign: function (align, element, cover, container) {
+ const contextImage = this.context.image;
+
+ if (!align) align = contextImage._align;
+ if (!element) element = contextImage._element;
+ if (!cover) cover = contextImage._cover;
+ if (!container) container = contextImage._container;
+
+ if (align && align !== 'none') {
+ cover.style.margin = 'auto';
+ } else {
+ cover.style.margin = '0';
+ }
+
+ if (/%$/.test(element.style.width) && align === 'center') {
+ container.style.minWidth = '100%';
+ cover.style.width = container.style.width;
+ } else {
+ container.style.minWidth = '';
+ cover.style.width = this.context.resizing._rotateVertical ? (element.style.height || element.offsetHeight) : ((!element.style.width || element.style.width === 'auto') ? '' : element.style.width || '100%');
+ }
+
+ if (!this.util.hasClass(container, '__se__float-' + align)) {
+ this.util.removeClass(container, contextImage._floatClassRegExp);
+ this.util.addClass(container, '__se__float-' + align);
+ }
+
+ element.setAttribute('data-align', align);
+ },
+
+ resetAlign: function () {
+ const contextImage = this.context.image;
+
+ contextImage._element.setAttribute('data-align', '');
+ contextImage._align = 'none';
+ contextImage._cover.style.margin = '0';
+ this.util.removeClass(contextImage._container, contextImage._floatClassRegExp);
+ },
+
+ /**
+ * @Override dialog
+ */
+ init: function () {
+ const contextImage = this.context.image;
+ if (contextImage.imgInputFile) contextImage.imgInputFile.value = '';
+ if (contextImage.imgUrlFile) contextImage._v_src._linkValue = contextImage.previewSrc.textContent = contextImage.imgUrlFile.value = '';
+ if (contextImage.imgInputFile && contextImage.imgUrlFile) {
+ contextImage.imgUrlFile.removeAttribute('disabled');
+ contextImage.previewSrc.style.textDecoration = '';
+ }
+
+ contextImage.altText.value = '';
+ contextImage._v_link._linkValue = contextImage.previewLink.textContent = contextImage.imgLink.value = '';
+ contextImage.imgLinkNewWindowCheck.checked = false;
+ contextImage.modal.querySelector('input[name="suneditor_image_radio"][value="none"]').checked = true;
+ contextImage.captionCheckEl.checked = false;
+ contextImage._element = null;
+ this.plugins.image.openTab.call(this, 'init');
+
+ if (contextImage._resizing) {
+ contextImage.inputX.value = this.context.option.imageWidth === contextImage._defaultSizeX ? '' : this.context.option.imageWidth;
+ contextImage.inputY.value = this.context.option.imageHeight === contextImage._defaultSizeY ? '' : this.context.option.imageHeight;
+ contextImage.proportion.checked = true;
+ contextImage._ratio = false;
+ contextImage._ratioX = 1;
+ contextImage._ratioY = 1;
+ }
+ }
+};
--- /dev/null
+import { DialogPlugin } from '../DialogPlugin';
+
+declare const link: DialogPlugin;
+
+export default link;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+import dialog from '../modules/dialog';
+
+export default {
+ name: 'link',
+ display: 'dialog',
+ add: function (core) {
+ core.addModule([dialog]);
+
+ const context = core.context;
+ context.link = {
+ focusElement: null,
+ linkNewWindowCheck: null,
+ linkAnchorText: null,
+ _linkAnchor: null,
+ _linkValue: ''
+ };
+
+ /** link dialog */
+ let link_dialog = this.setDialog.call(core);
+ context.link.modal = link_dialog;
+ context.link.focusElement = link_dialog.querySelector('._se_link_url');
+ context.link.linkAnchorText = link_dialog.querySelector('._se_link_text');
+ context.link.linkNewWindowCheck = link_dialog.querySelector('._se_link_check');
+ context.link.preview = link_dialog.querySelector('.se-link-preview');
+
+ /** link controller */
+ let link_controller = this.setController_LinkButton.call(core);
+ context.link.linkController = link_controller;
+ context.link._linkAnchor = null;
+ link_controller.addEventListener('mousedown', core.eventStop);
+
+ /** add event listeners */
+ link_dialog.querySelector('.se-btn-primary').addEventListener('click', this.submit.bind(core));
+ link_controller.addEventListener('click', this.onClick_linkController.bind(core));
+ context.link.focusElement.addEventListener('input', this._onLinkPreview.bind(context.link.preview, context.link, context.options.linkProtocol));
+
+ /** append html */
+ context.dialog.modal.appendChild(link_dialog);
+
+ /** append controller */
+ context.element.relative.appendChild(link_controller);
+
+ /** empty memory */
+ link_dialog = null, link_controller = null;
+ },
+
+ /** dialog */
+ setDialog: function () {
+ const lang = this.lang;
+ const dialog = this.util.createElement('DIV');
+
+ dialog.className = 'se-dialog-content';
+ dialog.style.display = 'none';
+ dialog.innerHTML = '' +
+ '<form class="editor_link">' +
+ '<div class="se-dialog-header">' +
+ '<button type="button" data-command="close" class="se-btn se-dialog-close" aria-label="Close" title="' + lang.dialogBox.close + '">' +
+ this.icons.cancel +
+ '</button>' +
+ '<span class="se-modal-title">' + lang.dialogBox.linkBox.title + '</span>' +
+ '</div>' +
+ '<div class="se-dialog-body">' +
+ '<div class="se-dialog-form">' +
+ '<label>' + lang.dialogBox.linkBox.url + '</label>' +
+ '<input class="se-input-form se-input-url _se_link_url" type="text" />' +
+ '<pre class="se-link-preview"></pre>' +
+ '</div>' +
+ '<div class="se-dialog-form">' +
+ '<label>' + lang.dialogBox.linkBox.text + '</label><input class="se-input-form _se_link_text" type="text" />' +
+ '</div>' +
+ '<div class="se-dialog-form-footer">' +
+ '<label><input type="checkbox" class="se-dialog-btn-check _se_link_check" /> ' + lang.dialogBox.linkBox.newWindowCheck + '</label>' +
+ '</div>' +
+ '</div>' +
+ '<div class="se-dialog-footer">' +
+ '<button type="submit" class="se-btn-primary" title="' + lang.dialogBox.submitButton + '"><span>' + lang.dialogBox.submitButton + '</span></button>' +
+ '</div>' +
+ '</form>';
+
+ return dialog;
+ },
+
+ /** modify controller button */
+ setController_LinkButton: function () {
+ const lang = this.lang;
+ const icons = this.icons;
+ const link_btn = this.util.createElement('DIV');
+
+ link_btn.className = 'se-controller se-controller-link';
+ link_btn.innerHTML = '' +
+ '<div class="se-arrow se-arrow-up"></div>' +
+ '<div class="link-content"><span><a target="_blank" href=""></a> </span>' +
+ '<div class="se-btn-group">' +
+ '<button type="button" data-command="update" tabindex="-1" class="se-btn se-tooltip">' +
+ icons.edit +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.edit + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="unlink" tabindex="-1" class="se-btn se-tooltip">' +
+ icons.unlink +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.unlink + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="delete" tabindex="-1" class="se-btn se-tooltip">' +
+ icons.delete +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.remove + '</span></span>' +
+ '</button>' +
+ '</div>' +
+ '</div>';
+
+ return link_btn;
+ },
+
+ /**
+ * @Override dialog
+ */
+ open: function () {
+ this.plugins.dialog.open.call(this, 'link', 'link' === this.currentControllerName);
+ },
+
+ _onLinkPreview: function (context, protocol, e) {
+ const value = e.target.value.trim();
+ context._linkValue = this.textContent = !value ? '' : (protocol && value.indexOf('://') === -1 && value.indexOf('#') !== 0) ? protocol + value : value.indexOf('://') === -1 ? '/' + value : value;
+ },
+
+ submit: function (e) {
+ this.showLoading();
+
+ e.preventDefault();
+ e.stopPropagation();
+
+ const submitAction = function () {
+ const contextLink = this.context.link;
+ if (contextLink._linkValue.length === 0) return false;
+
+ const url = contextLink._linkValue;
+ const anchor = contextLink.linkAnchorText;
+ const anchorText = anchor.value.length === 0 ? url : anchor.value;
+
+ if (!this.context.dialog.updateModal) {
+ const oA = this.util.createElement('A');
+ oA.href = url;
+ oA.textContent = anchorText;
+ oA.target = (contextLink.linkNewWindowCheck.checked ? '_blank' : '');
+
+ const selectedFormats = this.getSelectedElements();
+ if (selectedFormats.length > 1) {
+ const oFormat = this.util.createElement(selectedFormats[0].nodeName);
+ oFormat.appendChild(oA);
+ if (!this.insertNode(oFormat, null, true)) return;
+ } else {
+ if (!this.insertNode(oA, null, true)) return;
+ }
+
+ this.setRange(oA.childNodes[0], 0, oA.childNodes[0], oA.textContent.length);
+ } else {
+ contextLink._linkAnchor.href = url;
+ contextLink._linkAnchor.textContent = anchorText;
+ contextLink._linkAnchor.target = (contextLink.linkNewWindowCheck.checked ? '_blank' : '');
+
+ // set range
+ const textNode = contextLink._linkAnchor.childNodes[0];
+ this.setRange(textNode, 0, textNode, textNode.textContent.length);
+ }
+
+ contextLink._linkValue = contextLink.preview.textContent = contextLink.focusElement.value = contextLink.linkAnchorText.value = '';
+ }.bind(this);
+
+ try {
+ submitAction();
+ } finally {
+ this.plugins.dialog.close.call(this);
+ this.closeLoading();
+ // history stack
+ this.history.push(false);
+ }
+
+ return false;
+ },
+
+ /**
+ * @Override core
+ */
+ active: function (element) {
+ if (!element) {
+ if (this.controllerArray.indexOf(this.context.link.linkController) > -1) {
+ this.controllersOff();
+ }
+ } else if (this.util.isAnchor(element) && element.getAttribute('data-image-link') === null) {
+ if (this.controllerArray.indexOf(this.context.link.linkController) < 0) {
+ this.plugins.link.call_controller.call(this, element);
+ }
+ return true;
+ }
+
+ return false;
+ },
+
+ /**
+ * @Override dialog
+ */
+ on: function (update) {
+ const contextLink = this.context.link;
+ if (!update) {
+ this.plugins.link.init.call(this);
+ contextLink.linkAnchorText.value = this.getSelection().toString();
+ } else if (contextLink._linkAnchor) {
+ this.context.dialog.updateModal = true;
+ contextLink._linkValue = contextLink.preview.textContent = contextLink.focusElement.value = contextLink._linkAnchor.href;
+ contextLink.linkAnchorText.value = contextLink._linkAnchor.textContent;
+ contextLink.linkNewWindowCheck.checked = (/_blank/i.test(contextLink._linkAnchor.target) ? true : false);
+ }
+ },
+
+ call_controller: function (selectionATag) {
+ this.editLink = this.context.link._linkAnchor = selectionATag;
+ const linkBtn = this.context.link.linkController;
+ const link = linkBtn.querySelector('a');
+
+ link.href = selectionATag.href;
+ link.title = selectionATag.textContent;
+ link.textContent = selectionATag.textContent;
+
+ this.setControllerPosition(linkBtn, selectionATag, 'bottom', {left: 0, top: 0});
+ this.controllersOn(linkBtn, selectionATag, 'link');
+ },
+
+ onClick_linkController: function (e) {
+ e.stopPropagation();
+
+ const command = e.target.getAttribute('data-command') || e.target.parentNode.getAttribute('data-command');
+ if (!command) return;
+
+ e.preventDefault();
+
+ if (/update/.test(command)) {
+ const contextLink = this.context.link;
+ contextLink._linkValue = contextLink.preview.textContent = contextLink.focusElement.value = contextLink._linkAnchor.href;
+ contextLink.linkAnchorText.value = contextLink._linkAnchor.textContent;
+ contextLink.linkNewWindowCheck.checked = (/_blank/i.test(contextLink._linkAnchor.target) ? true : false);
+ this.plugins.dialog.open.call(this, 'link', true);
+ }
+ else if (/unlink/.test(command)) {
+ const sc = this.util.getChildElement(this.context.link._linkAnchor, function (current) { return current.childNodes.length === 0 || current.nodeType === 3; }, false);
+ const ec = this.util.getChildElement(this.context.link._linkAnchor, function (current) { return current.childNodes.length === 0 || current.nodeType === 3; }, true);
+ this.setRange(sc, 0, ec, ec.textContent.length);
+ this.nodeChange(null, null, ['A'], false);
+ }
+ else {
+ /** delete */
+ this.util.removeItem(this.context.link._linkAnchor);
+ this.context.link._linkAnchor = null;
+ this.focus();
+
+ // history stack
+ this.history.push(false);
+ }
+
+ this.controllersOff();
+ },
+
+ /**
+ * @Override dialog
+ */
+ init: function () {
+ const contextLink = this.context.link;
+ contextLink.linkController.style.display = 'none';
+ contextLink._linkAnchor = null;
+ contextLink._linkValue = contextLink.preview.textContent = contextLink.focusElement.value = '';
+ contextLink.linkAnchorText.value = '';
+ contextLink.linkNewWindowCheck.checked = false;
+ }
+};
--- /dev/null
+import { DialogPlugin } from '../DialogPlugin';
+
+declare const math: DialogPlugin;
+
+export default math;
\ No newline at end of file
--- /dev/null
+'use strict';
+
+import dialog from '../modules/dialog';
+
+export default {
+ name: 'math',
+ display: 'dialog',
+ add: function (core) {
+ core.addModule([dialog]);
+
+ const context = core.context;
+ context.math = {
+ focusElement: null,
+ previewElement: null,
+ fontSizeElement: null,
+ _mathExp: null
+ };
+
+ /** math dialog */
+ let math_dialog = this.setDialog.call(core);
+ context.math.modal = math_dialog;
+ context.math.focusElement = math_dialog.querySelector('.se-math-exp');
+ context.math.previewElement = math_dialog.querySelector('.se-math-preview');
+ context.math.fontSizeElement = math_dialog.querySelector('.se-math-size');
+ context.math.focusElement.addEventListener('keyup', this._renderMathExp.bind(core, context.math), false);
+ context.math.focusElement.addEventListener('change', this._renderMathExp.bind(core, context.math), false);
+ context.math.fontSizeElement.addEventListener('change', function (e) { this.fontSize = e.target.value; }.bind(context.math.previewElement.style), false);
+
+ /** math controller */
+ let math_controller = this.setController_MathButton.call(core);
+ context.math.mathController = math_controller;
+ context.math._mathExp = null;
+ math_controller.addEventListener('mousedown', core.eventStop);
+
+ /** add event listeners */
+ math_dialog.querySelector('.se-btn-primary').addEventListener('click', this.submit.bind(core), false);
+ math_controller.addEventListener('click', this.onClick_mathController.bind(core));
+
+ /** append html */
+ context.dialog.modal.appendChild(math_dialog);
+ context.element.relative.appendChild(math_controller);
+
+ /** empty memory */
+ math_dialog = null, math_controller = null;
+ },
+
+ /** dialog */
+ setDialog: function () {
+ const lang = this.lang;
+ const dialog = this.util.createElement('DIV');
+
+ dialog.className = 'se-dialog-content';
+ dialog.style.display = 'none';
+ dialog.innerHTML = '' +
+ '<form>' +
+ '<div class="se-dialog-header">' +
+ '<button type="button" data-command="close" class="se-btn se-dialog-close" aria-label="Close" title="' + lang.dialogBox.close + '">' +
+ this.icons.cancel +
+ '</button>' +
+ '<span class="se-modal-title">' + lang.dialogBox.mathBox.title + '</span>' +
+ '</div>' +
+ '<div class="se-dialog-body">' +
+ '<div class="se-dialog-form">' +
+ '<label>' + lang.dialogBox.mathBox.inputLabel + ' (<a href="https://katex.org/docs/supported.html" target="_blank">KaTeX</a>)</label>' +
+ '<textarea class="se-input-form se-math-exp" type="text"></textarea>' +
+ '</div>' +
+ '<div class="se-dialog-form">' +
+ '<label>' + lang.dialogBox.mathBox.fontSizeLabel + '</label>' +
+ '<select class="se-input-select se-math-size">' +
+ '<option value="1em">1</option>' +
+ '<option value="1.5em">1.5</option>' +
+ '<option value="2em">2</option>' +
+ '<option value="2.5em">2.5</option>' +
+ '</select>' +
+ '</div>' +
+ '<div class="se-dialog-form">' +
+ '<label>' + lang.dialogBox.mathBox.previewLabel + '</label>' +
+ '<p class="se-math-preview"></p>' +
+ '</div>' +
+ '</div>' +
+ '<div class="se-dialog-footer">' +
+ '<button type="submit" class="se-btn-primary" title="' + lang.dialogBox.submitButton + '"><span>' + lang.dialogBox.submitButton + '</span></button>' +
+ '</div>' +
+ '</form>';
+
+ return dialog;
+ },
+
+ /** modify controller button */
+ setController_MathButton: function () {
+ const lang = this.lang;
+ const math_btn = this.util.createElement('DIV');
+
+ math_btn.className = 'se-controller se-controller-link';
+ math_btn.innerHTML = '' +
+ '<div class="se-arrow se-arrow-up"></div>' +
+ '<div class="link-content">' +
+ '<div class="se-btn-group">' +
+ '<button type="button" data-command="update" tabindex="-1" class="se-btn se-tooltip">' +
+ this.icons.edit +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.edit + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="delete" tabindex="-1" class="se-btn se-tooltip">' +
+ this.icons.delete +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.remove + '</span></span>' +
+ '</button>' +
+ '</div>' +
+ '</div>' +
+ '';
+
+ return math_btn;
+ },
+
+ /**
+ * @Required @Override dialog
+ */
+ open: function () {
+ this.plugins.dialog.open.call(this, 'math', 'math' === this.currentControllerName);
+ },
+
+ /**
+ * @Override core - managedTagsInfo
+ */
+ managedTags: function () {
+ return {
+ className: 'katex',
+ method: function (element) {
+ if (!element.getAttribute('data-exp')) return;
+ const dom = this._d.createRange().createContextualFragment(this.plugins.math._renderer.call(this, this.util.HTMLDecoder(element.getAttribute('data-exp'))));
+ element.innerHTML = dom.querySelector('.katex').innerHTML;
+ }
+ };
+ },
+
+ _renderer: function (exp) {
+ const katex = this.context.option.katex;
+ return katex.src.renderToString(exp, katex.options);
+ },
+
+ _renderMathExp: function (contextMath, e) {
+ contextMath.previewElement.innerHTML = this.plugins.math._renderer.call(this, e.target.value);
+ },
+
+ submit: function (e) {
+ this.showLoading();
+
+ e.preventDefault();
+ e.stopPropagation();
+
+ const submitAction = function () {
+ if (this.context.math.focusElement.value.trim().length === 0) return false;
+
+ const contextMath = this.context.math;
+ const mathExp = contextMath.focusElement.value;
+ const katexEl = contextMath.previewElement.querySelector('.katex');
+
+ if (!katexEl) return false;
+ katexEl.className = '__se__katex ' + katexEl.className;
+ katexEl.setAttribute('contenteditable', false);
+ katexEl.setAttribute('data-exp', this.util.HTMLEncoder(mathExp));
+ katexEl.setAttribute('data-font-size', contextMath.fontSizeElement.value);
+ katexEl.style.fontSize = contextMath.fontSizeElement.value;
+
+ if (!this.context.dialog.updateModal) {
+ const selectedFormats = this.getSelectedElements();
+
+ if (selectedFormats.length > 1) {
+ const oFormat = this.util.createElement(selectedFormats[0].nodeName);
+ oFormat.appendChild(katexEl);
+ if (!this.insertNode(oFormat, null, true)) return false;
+ } else {
+ if (!this.insertNode(katexEl, null, true)) return false;
+ }
+
+ const empty = this.util.createTextNode(this.util.zeroWidthSpace);
+ katexEl.parentNode.insertBefore(empty, katexEl.nextSibling);
+ this.setRange(katexEl, 0, katexEl, 1);
+ } else {
+ const containerEl = this.util.getParentElement(contextMath._mathExp, '.katex');
+ containerEl.parentNode.replaceChild(katexEl, containerEl);
+ this.setRange(katexEl, 0, katexEl, 1);
+ }
+
+ contextMath.focusElement.value = '';
+ contextMath.fontSizeElement.value = '1em';
+ contextMath.previewElement.style.fontSize = '1em';
+ contextMath.previewElement.innerHTML = '';
+
+ return true;
+ }.bind(this);
+
+ try {
+ if (submitAction()) {
+ this.plugins.dialog.close.call(this);
+ // history stack
+ this.history.push(false);
+ }
+ } catch (e) {
+ this.plugins.dialog.close.call(this);
+ } finally {
+ this.closeLoading();
+ }
+
+ return false;
+ },
+
+ active: function (element) {
+ if (!element) {
+ if (this.controllerArray.indexOf(this.context.math.mathController) > -1) {
+ this.controllersOff();
+ }
+ } else if (element.getAttribute('data-exp')) {
+ if (this.controllerArray.indexOf(this.context.math.mathController) < 0) {
+ this.setRange(element, 0, element, 1);
+ this.plugins.math.call_controller.call(this, element);
+ }
+ return true;
+ }
+
+ return false;
+ },
+
+ on: function (update) {
+ if (!update) {
+ this.plugins.math.init.call(this);
+ } else {
+ const contextMath = this.context.math;
+ if (contextMath._mathExp) {
+ const exp = this.util.HTMLDecoder(contextMath._mathExp.getAttribute('data-exp'));
+ const fontSize = contextMath._mathExp.getAttribute('data-font-size') || '1em';
+ this.context.dialog.updateModal = true;
+ contextMath.focusElement.value = exp;
+ contextMath.fontSizeElement.value = fontSize;
+ contextMath.previewElement.innerHTML = this.plugins.math._renderer.call(this, exp);
+ contextMath.previewElement.style.fontSize = fontSize;
+ }
+ }
+ },
+
+ call_controller: function (mathTag) {
+ this.context.math._mathExp = mathTag;
+ const mathBtn = this.context.math.mathController;
+
+ this.setControllerPosition(mathBtn, mathTag, 'bottom', {left: 0, top: 0});
+ this.controllersOn(mathBtn, mathTag, 'math');
+ },
+
+ onClick_mathController: function (e) {
+ e.stopPropagation();
+
+ const command = e.target.getAttribute('data-command') || e.target.parentNode.getAttribute('data-command');
+ if (!command) return;
+
+ e.preventDefault();
+
+ if (/update/.test(command)) {
+ this.context.math.focusElement.value = this.util.HTMLDecoder(this.context.math._mathExp.getAttribute('data-exp'));
+ this.plugins.dialog.open.call(this, 'math', true);
+ } else {
+ /** delete */
+ this.util.removeItem(this.context.math._mathExp);
+ this.context.math._mathExp = null;
+ this.focus();
+
+ // history stack
+ this.history.push(false);
+ }
+
+ this.controllersOff();
+ },
+
+ init: function () {
+ const contextMath = this.context.math;
+ contextMath.mathController.style.display = 'none';
+ contextMath._mathExp = null;
+ contextMath.focusElement.value = '';
+ contextMath.previewElement.innerHTML = '';
+ }
+};
--- /dev/null
+import { DialogPlugin } from '../DialogPlugin';
+
+declare const mention: DialogPlugin;
+
+export default mention;
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+"use strict";
+
+import dialog from "../modules/dialog";
+
+
+function insertAt(parent, child, index) {
+ if (!index) index = 0;
+ if (index >= parent.children.length) {
+ parent.appendChild(child);
+ } else {
+ parent.insertBefore(child, parent.children[index]);
+ }
+}
+
+export default {
+ name: "mention",
+ display: "dialog",
+
+ renderItem: function(item) {
+ return `<span>${item}</span>`;
+ },
+
+ getItems: function(term) {
+ return Promise.resolve(
+ ["overwite", "the", "mention", "plugin", "getItems", "method"].filter(
+ (w) => w.includes(term.toLowerCase())
+ )
+ );
+ },
+
+ renderList: function(term) {
+ const { mention } = this.context;
+ let promise = Promise.resolve();
+ if (mention.term !== term) {
+ mention.focussed = 0;
+ mention.term = term;
+ promise = mention.getItems(term).then((items) => {
+ mention._items = items;
+
+ Object.keys(mention._itemElements).forEach((id) => {
+ if (!items.find((i) => mention.getId(i) === id)) {
+ const child = mention._itemElements[id];
+ child.parentNode.removeChild(child);
+ delete mention._itemElements[id];
+ }
+ });
+
+ items.forEach((item, idx) => {
+ const id = mention.getId(item);
+ if (!mention._itemElements[id]) {
+ const el = this.util.createElement("LI");
+ el.setAttribute("data-mention", id);
+ this.util.addClass(el, 'se-mention-item');
+ el.innerHTML = mention.renderItem(item);
+ el.addEventListener("click", () => {
+ mention._addMention(item);
+ });
+ insertAt(mention._list, el, idx);
+ mention._itemElements[id] = el;
+ }
+ });
+ });
+ }
+
+ promise.then(() => {
+ const current = mention._list.querySelectorAll(".se-mention-item")[
+ mention.focussed
+ ];
+ if (current && !this.util.hasClass(current, "se-mention-active")) {
+ const prev = mention._list.querySelector(".se-mention-active");
+ if (prev) this.util.removeClass(prev, "se-mention-active");
+ this.util.addClass(current, "se-mention-active");
+ }
+ });
+ },
+
+ setDialog: function() {
+ const mention_dialog = this.util.createElement("DIV");
+ const lang = this.lang;
+ mention_dialog.className = "se-dialog-content";
+ mention_dialog.style.display = "none";
+ const html = `
+ <form class="se-dialog-form">
+ <div class="se-dialog-header">
+ <button type="button" data-command="close" class="se-btn se-dialog-close" aria-label="Close" title="${lang.dialogBox.close}">
+ ${this.icons.cancel}
+ </button>
+ <span class="se-modal-title">${lang.dialogBox.mentionBox.title}</span>
+ </div>
+ <div class="se-dialog-body">
+ <input class="se-input-form se-mention-search" type="text" placeholder="${lang.dialogBox.browser.search}" />
+ <ul class="se-mention-list">
+ </ul>
+ </div>
+ </form>
+ `;
+ mention_dialog.innerHTML = html;
+ return mention_dialog;
+ },
+
+ getId(mention) {
+ return mention;
+ },
+
+ getValue(mention) {
+ return `@${mention}`;
+ },
+
+ getLinkHref(/*mention*/) {
+ return "";
+ },
+
+ open: function() {
+ const { mention } = this.context;
+ this.plugins.dialog.open.call(
+ this,
+ "mention",
+ "mention" === this.currentControllerName
+ );
+ mention._search.focus();
+ mention.renderList("");
+ },
+
+ on: function(update) {
+ if (update) return;
+ this.plugins.mention.init.call(this);
+ },
+
+ init: function() {
+ const { mention } = this.context;
+ mention._search.value = "";
+ mention.focussed = 0;
+ mention._items = [];
+ mention._itemElements = {};
+ mention._list.innerHTML = "";
+ delete mention.term;
+ },
+
+ onKeyPress: function(e) {
+ const { mention } = this.context;
+ switch (e.key) {
+ case "ArrowDown":
+ mention.focussed += 1;
+ e.preventDefault();
+ e.stopPropagation();
+ break;
+
+ case "ArrowUp":
+ if (mention.focussed > 0) {
+ mention.focussed -= 1;
+ }
+ e.preventDefault();
+ e.stopPropagation();
+ break;
+
+ case "Enter":
+ mention._addMention();
+ e.preventDefault();
+ e.stopPropagation();
+ break;
+
+ default:
+ }
+ },
+
+ onKeyUp: function(e) {
+ const { mention } = this.context;
+ mention.renderList(e.target.value);
+ },
+
+ getMentions: function() {
+ const { mentions, getId } = this.context.mention;
+ return mentions.filter((mention) => {
+ const id = getId(mention);
+ return this.context.element.wysiwyg.querySelector(
+ `[data-mention="${id}"]`
+ );
+ });
+ },
+
+ _addMention: function(item) {
+ const { mention } = this.context;
+ const new_mention = item || mention._items[mention.focussed];
+ if (new_mention) {
+ if (
+ !mention.mentions.find(
+ (m) => mention.getId(m) === mention.getId(new_mention)
+ )
+ ) {
+ mention.mentions.push(new_mention);
+ }
+ const el = this.util.createElement("A");
+ el.href = mention.getLinkHref(new_mention);
+ el.target = "_blank";
+ el.innerHTML = mention.getValue(new_mention);
+ el.setAttribute("data-mention", mention.getId(new_mention));
+ this.insertNode(el, null, false);
+ const spacer = this.util.createElement("SPAN");
+ spacer.innerHTML = " ";
+ this.insertNode(spacer, el, false);
+ }
+ this.plugins.dialog.close.call(this);
+ },
+ add: function(core) {
+ core.addModule([dialog]);
+ this.title = core.lang.toolbar.mention;
+ const _dialog = this.setDialog.call(core);
+ core.getMentions = this.getMentions.bind(core);
+
+ const _search = _dialog.querySelector(".se-mention-search");
+ _search.addEventListener("keyup", this.onKeyUp.bind(core));
+ _search.addEventListener("keydown", this.onKeyPress.bind(core));
+ const _list = _dialog.querySelector(".se-mention-list");
+
+ core.context.mention = {
+ _addMention: this._addMention.bind(core),
+ _itemElements: {},
+ _items: [],
+ _list,
+ _search,
+ focussed: 0,
+ getId: this.getId.bind(core),
+ getItems: this.getItems,
+ getLinkHref: this.getLinkHref.bind(core),
+ getValue: this.getValue.bind(core),
+ mentions: [],
+ modal: _dialog,
+ open: this.open.bind(core),
+ renderItem: this.renderItem,
+ renderList: this.renderList.bind(core),
+ };
+ core.context.dialog.modal.appendChild(_dialog);
+ },
+ action: function() {},
+};
--- /dev/null
+import { DialogPlugin } from '../DialogPlugin';
+
+declare const video: DialogPlugin;
+
+export default video;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+import dialog from '../modules/dialog';
+import component from '../modules/component';
+import resizing from '../modules/resizing';
+import fileManager from '../modules/fileManager';
+
+export default {
+ name: 'video',
+ display: 'dialog',
+ add: function (core) {
+ core.addModule([dialog, component, resizing, fileManager]);
+
+ const context = core.context;
+ const contextVideo = context.video = {
+ _infoList: [], // @Override fileManager
+ _infoIndex: 0, // @Override fileManager
+ _uploadFileLength: 0, // @Override fileManager
+ sizeUnit: context.option._videoSizeUnit,
+ _align: 'none',
+ _floatClassRegExp: '__se__float\\-[a-z]+',
+ _youtubeQuery: context.option.youtubeQuery,
+ _videoRatio: (context.option.videoRatio * 100) + '%',
+ _defaultRatio: (context.option.videoRatio * 100) + '%',
+ _linkValue: '',
+ // @require @Override component
+ _element: null,
+ _cover: null,
+ _container: null,
+ // @Override resizing properties
+ inputX: null,
+ inputY: null,
+ _element_w: 1,
+ _element_h: 1,
+ _element_l: 0,
+ _element_t: 0,
+ _defaultSizeX: '100%',
+ _defaultSizeY: (context.option.videoRatio * 100) + '%',
+ _origin_w: context.option.videoWidth === '100%' ? '' : context.option.videoWidth,
+ _origin_h: context.option.videoHeight === '56.25%' ? '' : context.option.videoHeight,
+ _proportionChecked: true,
+ _resizing: context.option.videoResizing,
+ _resizeDotHide: !context.option.videoHeightShow,
+ _rotation: context.option.videoRotation,
+ _onlyPercentage: context.option.videoSizeOnlyPercentage,
+ _ratio: false,
+ _ratioX: 1,
+ _ratioY: 1,
+ _captionShow: false
+ };
+
+ /** video dialog */
+ let video_dialog = this.setDialog.call(core);
+ contextVideo.modal = video_dialog;
+ contextVideo.videoInputFile = video_dialog.querySelector('._se_video_file');
+ contextVideo.videoUrlFile = video_dialog.querySelector('.se-input-url');
+ contextVideo.focusElement = contextVideo.videoUrlFile || contextVideo.videoInputFile;
+ contextVideo.preview = video_dialog.querySelector('.se-link-preview');
+
+ /** add event listeners */
+ video_dialog.querySelector('.se-btn-primary').addEventListener('click', this.submit.bind(core));
+ if (contextVideo.videoInputFile) video_dialog.querySelector('.se-dialog-files-edge-button').addEventListener('click', this._removeSelectedFiles.bind(contextVideo.videoInputFile, contextVideo.videoUrlFile, contextVideo.preview));
+ if (contextVideo.videoInputFile && contextVideo.videoUrlFile) contextVideo.videoInputFile.addEventListener('change', this._fileInputChange.bind(contextVideo));
+ if (contextVideo.videoUrlFile) contextVideo.videoUrlFile.addEventListener('input', this._onLinkPreview.bind(contextVideo.preview, contextVideo, context.options.linkProtocol));
+
+ contextVideo.proportion = {};
+ contextVideo.videoRatioOption = {};
+ contextVideo.inputX = {};
+ contextVideo.inputY = {};
+ if (context.option.videoResizing) {
+ contextVideo.proportion = video_dialog.querySelector('._se_video_check_proportion');
+ contextVideo.videoRatioOption = video_dialog.querySelector('.se-video-ratio');
+ contextVideo.inputX = video_dialog.querySelector('._se_video_size_x');
+ contextVideo.inputY = video_dialog.querySelector('._se_video_size_y');
+ contextVideo.inputX.value = context.option.videoWidth;
+ contextVideo.inputY.value = context.option.videoHeight;
+
+ contextVideo.inputX.addEventListener('keyup', this.setInputSize.bind(core, 'x'));
+ contextVideo.inputY.addEventListener('keyup', this.setInputSize.bind(core, 'y'));
+
+ contextVideo.inputX.addEventListener('change', this.setRatio.bind(core));
+ contextVideo.inputY.addEventListener('change', this.setRatio.bind(core));
+ contextVideo.proportion.addEventListener('change', this.setRatio.bind(core));
+ contextVideo.videoRatioOption.addEventListener('change', this.setVideoRatio.bind(core));
+
+ video_dialog.querySelector('.se-dialog-btn-revert').addEventListener('click', this.sizeRevert.bind(core));
+ }
+
+ /** append html */
+ context.dialog.modal.appendChild(video_dialog);
+
+ /** empty memory */
+ video_dialog = null;
+ },
+
+ /** dialog */
+ setDialog: function () {
+ const option = this.context.option;
+ const lang = this.lang;
+ const dialog = this.util.createElement('DIV');
+
+ dialog.className = 'se-dialog-content';
+ dialog.style.display = 'none';
+ let html = '' +
+ '<form method="post" enctype="multipart/form-data">' +
+ '<div class="se-dialog-header">' +
+ '<button type="button" data-command="close" class="se-btn se-dialog-close" aria-label="Close" title="' + lang.dialogBox.close + '">' +
+ this.icons.cancel +
+ '</button>' +
+ '<span class="se-modal-title">' + lang.dialogBox.videoBox.title + '</span>' +
+ '</div>' +
+ '<div class="se-dialog-body">';
+
+ if (option.videoFileInput) {
+ html += '' +
+ '<div class="se-dialog-form">' +
+ '<label>' + lang.dialogBox.videoBox.file + '</label>' +
+ '<div class="se-dialog-form-files">' +
+ '<input class="se-input-form _se_video_file" type="file" accept="' + option.videoAccept + '"' + (option.videoMultipleFile ? ' multiple="multiple"' : '') + '/>' +
+ '<button type="button" data-command="filesRemove" class="se-btn se-dialog-files-edge-button se-file-remove" title="' + lang.controller.remove + '">' + this.icons.cancel + '</button>' +
+ '</div>' +
+ '</div>' ;
+ }
+
+ if (option.videoUrlInput) {
+ html += '' +
+ '<div class="se-dialog-form">' +
+ '<label>' + lang.dialogBox.videoBox.url + '</label>' +
+ '<input class="se-input-form se-input-url" type="text" />' +
+ '<pre class="se-link-preview"></pre>' +
+ '</div>';
+ }
+
+ if (option.videoResizing) {
+ const ratioList = option.videoRatioList || [{name: '16:9', value: 0.5625}, {name: '4:3', value: 0.75}, {name: '21:9', value: 0.4285}];
+ const ratio = option.videoRatio;
+ const onlyPercentage = option.videoSizeOnlyPercentage;
+ const onlyPercentDisplay = onlyPercentage ? ' style="display: none !important;"' : '';
+ const heightDisplay = !option.videoHeightShow ? ' style="display: none !important;"' : '';
+ const ratioDisplay = !option.videoRatioShow ? ' style="display: none !important;"' : '';
+ const onlyWidthDisplay = !onlyPercentage && !option.videoHeightShow && !option.videoRatioShow ? ' style="display: none !important;"' : '';
+ html += '' +
+ '<div class="se-dialog-form">' +
+ '<div class="se-dialog-size-text">' +
+ '<label class="size-w">' + lang.dialogBox.width + '</label>' +
+ '<label class="se-dialog-size-x"> </label>' +
+ '<label class="size-h"' + heightDisplay + '>' + lang.dialogBox.height + '</label>' +
+ '<label class="size-h"' + ratioDisplay + '>(' + lang.dialogBox.ratio + ')</label>' +
+ '</div>' +
+ '<input class="se-input-control _se_video_size_x" placeholder="100%"' + (onlyPercentage ? ' type="number" min="1"' : 'type="text"') + (onlyPercentage ? ' max="100"' : '') + '/>' +
+ '<label class="se-dialog-size-x"' + onlyWidthDisplay + '>' + (onlyPercentage ? '%' : 'x') + '</label>' +
+ '<input class="se-input-control _se_video_size_y" placeholder="' + (option.videoRatio * 100) + '%"' + (onlyPercentage ? ' type="number" min="1"' : 'type="text"') + (onlyPercentage ? ' max="100"' : '') + heightDisplay + '/>' +
+ '<select class="se-input-select se-video-ratio" title="' + lang.dialogBox.ratio + '"' + ratioDisplay + '>';
+ if (!heightDisplay) html += '<option value=""> - </option>';
+ for (let i = 0, len = ratioList.length; i < len; i++) {
+ html += '<option value="' + ratioList[i].value + '"' + (ratio.toString() === ratioList[i].value.toString() ? ' selected' : '') + '>' + ratioList[i].name + '</option>';
+ }
+ html += '</select>' +
+ '<button type="button" title="' + lang.dialogBox.revertButton + '" class="se-btn se-dialog-btn-revert" style="float: right;">' + this.icons.revert + '</button>' +
+ '</div>' +
+ '<div class="se-dialog-form se-dialog-form-footer"' + onlyPercentDisplay + onlyWidthDisplay + '>' +
+ '<label><input type="checkbox" class="se-dialog-btn-check _se_video_check_proportion" checked/> ' + lang.dialogBox.proportion + '</label>' +
+ '</div>';
+ }
+
+ html += '' +
+ '</div>' +
+ '<div class="se-dialog-footer">' +
+ '<div>' +
+ '<label><input type="radio" name="suneditor_video_radio" class="se-dialog-btn-radio" value="none" checked>' + lang.dialogBox.basic + '</label>' +
+ '<label><input type="radio" name="suneditor_video_radio" class="se-dialog-btn-radio" value="left">' + lang.dialogBox.left + '</label>' +
+ '<label><input type="radio" name="suneditor_video_radio" class="se-dialog-btn-radio" value="center">' + lang.dialogBox.center + '</label>' +
+ '<label><input type="radio" name="suneditor_video_radio" class="se-dialog-btn-radio" value="right">' + lang.dialogBox.right + '</label>' +
+ '</div>' +
+ '<button type="submit" class="se-btn-primary" title="' + lang.dialogBox.submitButton + '"><span>' + lang.dialogBox.submitButton + '</span></button>' +
+ '</div>' +
+ '</form>';
+
+ dialog.innerHTML = html;
+
+ return dialog;
+ },
+
+ _fileInputChange: function () {
+ if (!this.videoInputFile.value) {
+ this.videoUrlFile.removeAttribute('disabled');
+ this.preview.style.textDecoration = '';
+ } else {
+ this.videoUrlFile.setAttribute('disabled', true);
+ this.preview.style.textDecoration = 'line-through';
+ }
+ },
+
+ _removeSelectedFiles: function (urlInput, preview) {
+ this.value = '';
+ if (urlInput) {
+ urlInput.removeAttribute('disabled');
+ preview.style.textDecoration = '';
+ }
+ },
+
+ _onLinkPreview: function (context, protocol, e) {
+ const value = e.target.value.trim();
+ if (/^<iframe.*\/iframe>$/.test(value)) {
+ context._linkValue = value;
+ this.textContent = '<IFrame :src=".."></IFrame>';
+ } else {
+ context._linkValue = this.textContent = !value ? '' : (protocol && value.indexOf('://') === -1 && value.indexOf('#') !== 0) ? protocol + value : value.indexOf('://') === -1 ? '/' + value : value;
+ }
+ },
+
+ _setTagAttrs: function (element) {
+ element.setAttribute('controls', true);
+
+ const attrs = this.context.options.videoTagAttrs;
+ if (!attrs) return;
+
+ for (let key in attrs) {
+ if (!this.util.hasOwn(attrs, key)) continue;
+ element.setAttribute(key, attrs[key]);
+ }
+ },
+
+ createVideoTag: function () {
+ const videoTag = this.util.createElement('VIDEO');
+ this.plugins.video._setTagAttrs.call(this, videoTag);
+ return videoTag;
+ },
+
+ _setIframeAttrs: function (element) {
+ element.frameBorder = '0';
+ element.allowFullscreen = true;
+
+ const attrs = this.context.options.videoIframeAttrs;
+ if (!attrs) return;
+
+ for (let key in attrs) {
+ if (!this.util.hasOwn(attrs, key)) continue;
+ element.setAttribute(key, attrs[key]);
+ }
+ },
+
+ createIframeTag: function () {
+ const iframeTag = this.util.createElement('IFRAME');
+ this.plugins.video._setIframeAttrs.call(this, iframeTag);
+ return iframeTag;
+ },
+
+ /**
+ * @Override @Required fileManager
+ */
+ fileTags: ['iframe', 'video'],
+
+ /**
+ * @Override core, resizing, fileManager
+ * @description It is called from core.selectComponent.
+ * @param {Element} element Target element
+ */
+ select: function (element) {
+ this.plugins.video.onModifyMode.call(this, element, this.plugins.resizing.call_controller_resize.call(this, element, 'video'));
+ },
+
+ /**
+ * @Override fileManager, resizing
+ */
+ destroy: function (element) {
+ const frame = element || this.context.video._element;
+ const container = this.context.video._container;
+ const dataIndex = frame.getAttribute('data-index') * 1;
+ let focusEl = (container.previousElementSibling || container.nextElementSibling);
+
+ const emptyDiv = container.parentNode;
+ this.util.removeItem(container);
+ this.plugins.video.init.call(this);
+ this.controllersOff();
+
+ if (emptyDiv !== this.context.element.wysiwyg) this.util.removeItemAllParents(emptyDiv, function (current) { return current.childNodes.length === 0; }, null);
+
+ // focus
+ this.focusEdge(focusEl);
+
+ // event
+ this.plugins.fileManager.deleteInfo.call(this, 'video', dataIndex, this.functions.onVideoUpload);
+
+ // history stack
+ this.history.push(false);
+ },
+
+ /**
+ * @Required @Override dialog
+ */
+ on: function (update) {
+ const contextVideo = this.context.video;
+
+ if (!update) {
+ contextVideo.inputX.value = contextVideo._origin_w = this.context.option.videoWidth === contextVideo._defaultSizeX ? '' : this.context.option.videoWidth;
+ contextVideo.inputY.value = contextVideo._origin_h = this.context.option.videoHeight === contextVideo._defaultSizeY ? '' : this.context.option.videoHeight;
+ contextVideo.proportion.disabled = true;
+ if (contextVideo.videoInputFile && this.context.options.videoMultipleFile) contextVideo.videoInputFile.setAttribute('multiple', 'multiple');
+ } else {
+ if (contextVideo.videoInputFile && this.context.options.videoMultipleFile) contextVideo.videoInputFile.removeAttribute('multiple');
+ }
+
+ if (contextVideo._resizing) {
+ this.plugins.video.setVideoRatioSelect.call(this, contextVideo._origin_h || contextVideo._defaultRatio);
+ }
+ },
+
+ /**
+ * @Required @Override dialog
+ */
+ open: function () {
+ this.plugins.dialog.open.call(this, 'video', 'video' === this.currentControllerName);
+ },
+
+ setVideoRatio: function (e) {
+ const contextVideo = this.context.video;
+ const value = e.target.options[e.target.selectedIndex].value;
+
+ contextVideo._defaultSizeY = contextVideo._videoRatio = !value ? contextVideo._defaultSizeY : (value * 100) + '%';
+ contextVideo.inputY.placeholder = !value ? '' : (value * 100) + '%';
+ contextVideo.inputY.value = '';
+ },
+
+ /**
+ * @Override resizing
+ * @param {String} xy 'x': width, 'y': height
+ * @param {KeyboardEvent} e Event object
+ */
+ setInputSize: function (xy, e) {
+ if (e && e.keyCode === 32) {
+ e.preventDefault();
+ return;
+ }
+
+ const contextVideo = this.context.video;
+ this.plugins.resizing._module_setInputSize.call(this, contextVideo, xy);
+
+ if (xy === 'y') {
+ this.plugins.video.setVideoRatioSelect.call(this, e.target.value || contextVideo._defaultRatio);
+ }
+ },
+
+ /**
+ * @Override resizing
+ */
+ setRatio: function () {
+ this.plugins.resizing._module_setRatio.call(this, this.context.video);
+ },
+
+ submit: function (e) {
+ const contextVideo = this.context.video;
+ const videoPlugin = this.plugins.video;
+
+ e.preventDefault();
+ e.stopPropagation();
+
+ contextVideo._align = contextVideo.modal.querySelector('input[name="suneditor_video_radio"]:checked').value;
+
+ try {
+ if (contextVideo.videoInputFile && contextVideo.videoInputFile.files.length > 0) {
+ this.showLoading();
+ videoPlugin.submitAction.call(this, this.context.video.videoInputFile.files);
+ } else if (contextVideo.videoUrlFile && contextVideo._linkValue.length > 0) {
+ this.showLoading();
+ videoPlugin.setup_url.call(this);
+ }
+ } catch (error) {
+ this.closeLoading();
+ throw Error('[SUNEDITOR.video.submit.fail] cause : "' + error.message + '"');
+ } finally {
+ this.plugins.dialog.close.call(this);
+ }
+
+ return false;
+ },
+
+ submitAction: function (fileList) {
+ if (fileList.length === 0) return;
+
+ let fileSize = 0;
+ let files = [];
+ for (let i = 0, len = fileList.length; i < len; i++) {
+ if (/video/i.test(fileList[i].type)) {
+ files.push(fileList[i]);
+ fileSize += fileList[i].size;
+ }
+ }
+
+ const limitSize = this.context.option.videoUploadSizeLimit;
+ if (limitSize > 0) {
+ let infoSize = 0;
+ const videosInfo = this.context.video._infoList;
+ for (let i = 0, len = videosInfo.length; i < len; i++) {
+ infoSize += videosInfo[i].size * 1;
+ }
+
+ if ((fileSize + infoSize) > limitSize) {
+ this.closeLoading();
+ const err = '[SUNEDITOR.videoUpload.fail] Size of uploadable total videos: ' + (limitSize/1000) + 'KB';
+ if (this.functions.onVideoUploadError !== 'function' || this.functions.onVideoUploadError(err, { 'limitSize': limitSize, 'currentSize': infoSize, 'uploadSize': fileSize }, this)) {
+ this.functions.noticeOpen(err);
+ }
+ return;
+ }
+ }
+
+ const contextVideo = this.context.video;
+ contextVideo._uploadFileLength = files.length;
+
+ const info = {
+ inputWidth: contextVideo.inputX.value,
+ inputHeight: contextVideo.inputY.value,
+ align: contextVideo._align,
+ isUpdate: this.context.dialog.updateModal,
+ element: contextVideo._element
+ };
+
+ if (typeof this.functions.onVideoUploadBefore === 'function') {
+ const result = this.functions.onVideoUploadBefore(files, info, this, function (data) {
+ if (data && this._w.Array.isArray(data.result)) {
+ this.plugins.video.register.call(this, info, data);
+ } else {
+ this.plugins.video.upload.call(this, info, data);
+ }
+ }.bind(this));
+
+ if (typeof result === 'undefined') return;
+ if (!result) {
+ this.closeLoading();
+ return;
+ }
+ if (typeof result === 'object' && result.length > 0) files = result;
+ }
+
+ this.plugins.video.upload.call(this, info, files);
+ },
+
+ error: function (message, response) {
+ this.closeLoading();
+ if (typeof this.functions.onVideoUploadError !== 'function' || this.functions.onVideoUploadError(message, response, this)) {
+ this.functions.noticeOpen(message);
+ throw Error('[SUNEDITOR.plugin.video.error] response: ' + message);
+ }
+ },
+
+ upload: function (info, files) {
+ if (!files) {
+ this.closeLoading();
+ return;
+ }
+ if (typeof files === 'string') {
+ this.plugins.video.error.call(this, files, null);
+ return;
+ }
+
+ const videoUploadUrl = this.context.option.videoUploadUrl;
+ const filesLen = this.context.dialog.updateModal ? 1 : files.length;
+
+ // server upload
+ if (typeof videoUploadUrl === 'string' && videoUploadUrl.length > 0) {
+ const formData = new FormData();
+ for (let i = 0; i < filesLen; i++) {
+ formData.append('file-' + i, files[i]);
+ }
+ this.plugins.fileManager.upload.call(this, videoUploadUrl, this.context.option.videoUploadHeader, formData, this.plugins.video.callBack_videoUpload.bind(this, info), this.functions.onVideoUploadError);
+ } else {
+ throw Error('[SUNEDITOR.videoUpload.fail] cause : There is no "videoUploadUrl" option.');
+ }
+ },
+
+ callBack_videoUpload: function (info, xmlHttp) {
+ if (typeof this.functions.videoUploadHandler === 'function') {
+ this.functions.videoUploadHandler(xmlHttp, info, this);
+ } else {
+ const response = JSON.parse(xmlHttp.responseText);
+ if (response.errorMessage) {
+ this.plugins.video.error.call(this, response.errorMessage, response);
+ } else {
+ this.plugins.video.register.call(this, info, response);
+ }
+ }
+ },
+
+ register: function (info, response) {
+ const fileList = response.result;
+ const videoTag = this.plugins.video.createVideoTag.call(this);
+
+ for (let i = 0, len = fileList.length, file; i < len; i++) {
+ file = { name: fileList[i].name, size: fileList[i].size };
+ this.plugins.video.create_video.call(this, (info.isUpdate ? info.element : videoTag.cloneNode(false)), fileList[i].url, info.inputWidth, info.inputHeight, info.align, file, info.isUpdate);
+ }
+
+ this.closeLoading();
+ },
+
+ setup_url: function () {
+ try {
+ const contextVideo = this.context.video;
+ let url = contextVideo._linkValue;
+
+ if (url.length === 0) return false;
+
+ /** iframe source */
+ if (/^<iframe.*\/iframe>$/.test(url)) {
+ const oIframe = (new this._w.DOMParser()).parseFromString(url, 'text/html').querySelector('iframe');
+ url = oIframe.src;
+ if (url.length === 0) return false;
+ }
+
+ /** youtube */
+ if (/youtu\.?be/.test(url)) {
+ if (!/^http/.test(url)) url = 'https://' + url;
+ url = url.replace('watch?v=', '');
+ if (!/^\/\/.+\/embed\//.test(url)) {
+ url = url.replace(url.match(/\/\/.+\//)[0], '//www.youtube.com/embed/').replace('&', '?&');
+ }
+
+ if (contextVideo._youtubeQuery.length > 0) {
+ if (/\?/.test(url)) {
+ const splitUrl = url.split('?');
+ url = splitUrl[0] + '?' + contextVideo._youtubeQuery + '&' + splitUrl[1];
+ } else {
+ url += '?' + contextVideo._youtubeQuery;
+ }
+ }
+ } else if (/vimeo\.com/.test(url)) {
+ if (url.endsWith('/')) {
+ url = url.slice(0, -1);
+ }
+ url = 'https://player.vimeo.com/video/' + url.slice(url.lastIndexOf('/') + 1);
+ }
+
+ this.plugins.video.create_video.call(this, this.plugins.video.createIframeTag.call(this), url, contextVideo.inputX.value, contextVideo.inputY.value, contextVideo._align, null, this.context.dialog.updateModal);
+ } catch (error) {
+ throw Error('[SUNEDITOR.video.upload.fail] cause : "' + error.message + '"');
+ } finally {
+ this.closeLoading();
+ }
+ },
+
+ create_video: function (oFrame, src, width, height, align, file, isUpdate) {
+ this.context.resizing._resize_plugin = 'video';
+ const contextVideo = this.context.video;
+
+ let cover = null;
+ let container = null;
+ let init = false;
+
+ /** update */
+ if (isUpdate) {
+ oFrame = contextVideo._element;
+ if (oFrame.src !== src) {
+ init = true;
+ const isYoutube = /youtu\.?be/.test(src);
+ const isVimeo = /vimeo\.com/.test(src);
+ if ((isYoutube || isVimeo) && !/^iframe$/i.test(oFrame.nodeName)) {
+ const newTag = this.plugins.video.createIframeTag.call(this);
+ newTag.src = src;
+ oFrame.parentNode.replaceChild(newTag, oFrame);
+ contextVideo._element = oFrame = newTag;
+ } else if (!isYoutube && !isVimeo && !/^videoo$/i.test(oFrame.nodeName)) {
+ const newTag = this.plugins.video.createVideoTag.call(this);
+ newTag.src = src;
+ oFrame.parentNode.replaceChild(newTag, oFrame);
+ contextVideo._element = oFrame = newTag;
+ } else {
+ oFrame.src = src;
+ }
+ }
+ container = contextVideo._container;
+ cover = this.util.getParentElement(oFrame, 'FIGURE');
+ }
+ /** create */
+ else {
+ init = true;
+ oFrame.src = src;
+ contextVideo._element = oFrame;
+ cover = this.plugins.component.set_cover.call(this, oFrame);
+ container = this.plugins.component.set_container.call(this, cover, 'se-video-container');
+ }
+
+ /** rendering */
+ contextVideo._cover = cover;
+ contextVideo._container = container;
+
+ const inputUpdate = (this.plugins.resizing._module_getSizeX.call(this, contextVideo) !== (width || contextVideo._defaultSizeX)) || (this.plugins.resizing._module_getSizeY.call(this, contextVideo) !== (height || contextVideo._videoRatio));
+ const changeSize = !isUpdate || inputUpdate;
+
+ if (contextVideo._resizing) {
+ this.context.video._proportionChecked = contextVideo.proportion.checked;
+ oFrame.setAttribute('data-proportion', contextVideo._proportionChecked);
+ }
+
+ // size
+ let isPercent = false;
+ if (changeSize) {
+ isPercent = this.plugins.video.applySize.call(this);
+ }
+
+ // align
+ if (!(isPercent && align === 'center')) {
+ this.plugins.video.setAlign.call(this, null, oFrame, cover, container);
+ }
+
+ let changed = true;
+ if (!isUpdate) {
+ changed = this.insertComponent(container, false, true, false);
+ } else if (contextVideo._resizing && this.context.resizing._rotateVertical && changeSize) {
+ this.plugins.resizing.setTransformSize.call(this, oFrame, null, null);
+ }
+
+ if (changed) {
+ if (init) {
+ this.plugins.fileManager.setInfo.call(this, 'video', oFrame, this.functions.onVideoUpload, file, true);
+ }
+ if (isUpdate) {
+ this.selectComponent(oFrame, 'video');
+ // history stack
+ this.history.push(false);
+ }
+ }
+
+ this.context.resizing._resize_plugin = '';
+ },
+
+ _update_videoCover: function (oFrame) {
+ if (!oFrame) return;
+
+ const contextVideo = this.context.video;
+
+ if (/^video$/i.test(oFrame.nodeName)) this.plugins.video._setTagAttrs.call(this, oFrame);
+ else this.plugins.video._setIframeAttrs.call(this, oFrame);
+
+ const existElement = this.util.getParentElement(oFrame, this.util.isMediaComponent) ||
+ this.util.getParentElement(oFrame, function (current) {
+ return this.isWysiwygDiv(current.parentNode);
+ }.bind(this.util));
+
+ oFrame = oFrame.cloneNode(true);
+ const cover = contextVideo._cover = this.plugins.component.set_cover.call(this, oFrame);
+ const container = contextVideo._container = this.plugins.component.set_container.call(this, cover, 'se-video-container');
+
+ const figcaption = existElement.querySelector('figcaption');
+ let caption = null;
+ if (!!figcaption) {
+ caption = this.util.createElement('DIV');
+ caption.innerHTML = figcaption.innerHTML;
+ this.util.removeItem(figcaption);
+ }
+
+ const size = (oFrame.getAttribute('data-size') || oFrame.getAttribute('data-origin') || '').split(',');
+ this.plugins.video.applySize.call(this, size[0], size[1]);
+
+ if (this.util.isFormatElement(existElement) && existElement.textContent.length > 0) {
+ existElement.parentNode.insertBefore(container, existElement.nextElementSibling);
+ this.util.removeItem(contextVideo._element);
+ contextVideo._element = oFrame;
+ } else {
+ existElement.parentNode.replaceChild(container, existElement);
+ }
+
+ if (!!caption) existElement.parentNode.insertBefore(caption, container.nextElementSibling);
+ this.plugins.fileManager.setInfo.call(this, 'video', oFrame, this.functions.onVideoUpload, null, true);
+ },
+
+ /**
+ * @Required @Override fileManager, resizing
+ */
+ onModifyMode: function (element, size) {
+ const contextVideo = this.context.video;
+ contextVideo._element = element;
+ contextVideo._cover = this.util.getParentElement(element, 'FIGURE');
+ contextVideo._container = this.util.getParentElement(element, this.util.isMediaComponent);
+ contextVideo._align = element.getAttribute('data-align') || 'none';
+
+ if (size) {
+ contextVideo._element_w = size.w;
+ contextVideo._element_h = size.h;
+ contextVideo._element_t = size.t;
+ contextVideo._element_l = size.l;
+ }
+
+ let origin = contextVideo._element.getAttribute('data-size') || contextVideo._element.getAttribute('data-origin');
+ if (origin) {
+ origin = origin.split(',');
+ contextVideo._origin_w = origin[0];
+ contextVideo._origin_h = origin[1];
+ } else if (size) {
+ contextVideo._origin_w = size.w;
+ contextVideo._origin_h = size.h;
+ }
+ },
+
+ /**
+ * @Required @Override fileManager, resizing
+ */
+ openModify: function (notOpen) {
+ const contextVideo = this.context.video;
+
+ if (contextVideo.videoUrlFile) contextVideo._linkValue = contextVideo.preview.textContent = contextVideo.videoUrlFile.value = (contextVideo._element.src || (contextVideo._element.querySelector('source') || '').src || '');
+ contextVideo.modal.querySelector('input[name="suneditor_video_radio"][value="' + contextVideo._align + '"]').checked = true;
+
+ if (contextVideo._resizing) {
+ this.plugins.resizing._module_setModifyInputSize.call(this, contextVideo, this.plugins.video);
+
+ const y = contextVideo._videoRatio = this.plugins.resizing._module_getSizeY.call(this, contextVideo);
+ const ratioSelected = this.plugins.video.setVideoRatioSelect.call(this, y);
+ if (!ratioSelected) contextVideo.inputY.value = contextVideo._onlyPercentage ? this.util.getNumber(y, 2) : y;
+ }
+
+ if (!notOpen) this.plugins.dialog.open.call(this, 'video', true);
+ },
+
+ setVideoRatioSelect: function (value) {
+ let ratioSelected = false;
+ const contextVideo = this.context.video;
+ const ratioOptions = contextVideo.videoRatioOption.options;
+
+ if (/%$/.test(value) || contextVideo._onlyPercentage) value = (this.util.getNumber(value, 2) / 100) + '';
+ else if (!this.util.isNumber(value) || (value * 1) >= 1) value = '';
+
+ contextVideo.inputY.placeholder = '';
+ for (let i = 0, len = ratioOptions.length; i < len; i++) {
+ if (ratioOptions[i].value === value) {
+ ratioSelected = ratioOptions[i].selected = true;
+ contextVideo.inputY.placeholder = !value ? '' : (value * 100) + '%';
+ }
+ else ratioOptions[i].selected = false;
+ }
+
+ return ratioSelected;
+ },
+
+ /**
+ * @Override fileManager
+ */
+ checkFileInfo: function () {
+ this.plugins.fileManager.checkInfo.call(this, 'video', ['iframe', 'video'], this.functions.onVideoUpload, this.plugins.video._update_videoCover.bind(this), true);
+ },
+
+ /**
+ * @Override fileManager
+ */
+ resetFileInfo: function () {
+ this.plugins.fileManager.resetInfo.call(this, 'video', this.functions.onVideoUpload);
+ },
+
+ /**
+ * @Override resizing
+ */
+ sizeRevert: function () {
+ this.plugins.resizing._module_sizeRevert.call(this, this.context.video);
+ },
+
+ /**
+ * @Override resizing
+ */
+ applySize: function (w, h) {
+ const contextVideo = this.context.video;
+
+ if (!w) w = contextVideo.inputX.value || this.context.option.videoWidth;
+ if (!h) h = contextVideo.inputY.value || this.context.option.videoHeight;
+
+ if (contextVideo._onlyPercentage || /%$/.test(w) || !w) {
+ this.plugins.video.setPercentSize.call(this, (w || '100%'), (h || (/%$/.test(contextVideo._videoRatio) ? contextVideo._videoRatio : contextVideo._defaultRatio)));
+ return true;
+ } else if ((!w || w === 'auto') && (!h || h === 'auto')) {
+ this.plugins.video.setAutoSize.call(this);
+ } else {
+ this.plugins.video.setSize.call(this, w, (h || contextVideo._videoRatio || contextVideo._defaultRatio), false);
+ }
+
+ return false;
+ },
+
+ /**
+ * @Override resizing
+ */
+ setSize: function (w, h, notResetPercentage, direction) {
+ const contextVideo = this.context.video;
+ const onlyW = /^(rw|lw)$/.test(direction);
+ const onlyH = /^(th|bh)$/.test(direction);
+
+ if (!onlyH) w = this.util.getNumber(w, 0);
+ if (!onlyW) h = this.util.isNumber(h) ? h + contextVideo.sizeUnit : !h ? '' : h;
+
+ if (!onlyH) contextVideo._element.style.width = w ? w + contextVideo.sizeUnit : '';
+ if (!onlyW) contextVideo._cover.style.paddingBottom = contextVideo._cover.style.height = h;
+
+ if (!onlyH && !/%$/.test(w)) {
+ contextVideo._cover.style.width = '';
+ contextVideo._container.style.width = '';
+ }
+
+ if (!onlyW && !/%$/.test(h)) {
+ contextVideo._element.style.height = h;
+ } else {
+ contextVideo._element.style.height = '';
+ }
+
+ if (!notResetPercentage) contextVideo._element.removeAttribute('data-percentage');
+
+ // save current size
+ this.plugins.resizing._module_saveCurrentSize.call(this, contextVideo);
+ },
+
+ /**
+ * @Override resizing
+ */
+ setAutoSize: function () {
+ this.plugins.video.setPercentSize.call(this, 100, this.context.video._defaultRatio);
+ },
+
+ /**
+ * @Override resizing
+ */
+ setOriginSize: function (dataSize) {
+ const contextVideo = this.context.video;
+ contextVideo._element.removeAttribute('data-percentage');
+
+ this.plugins.resizing.resetTransform.call(this, contextVideo._element);
+ this.plugins.video.cancelPercentAttr.call(this);
+
+ const originSize = ((dataSize ? contextVideo._element.getAttribute('data-size') : '') || contextVideo._element.getAttribute('data-origin') || '').split(',');
+
+ if (originSize) {
+ const w = originSize[0];
+ const h = originSize[1];
+
+ if (contextVideo._onlyPercentage || (/%$/.test(w) && (/%$/.test(h) || !/\d/.test(h)))) {
+ this.plugins.video.setPercentSize.call(this, w, h);
+ } else {
+ this.plugins.video.setSize.call(this, w, h);
+ }
+
+ // save current size
+ this.plugins.resizing._module_saveCurrentSize.call(this, contextVideo);
+ }
+ },
+
+ /**
+ * @Override resizing
+ */
+ setPercentSize: function (w, h) {
+ const contextVideo = this.context.video;
+ h = !!h && !/%$/.test(h) && !this.util.getNumber(h, 0) ? this.util.isNumber(h) ? h + '%' : h : this.util.isNumber(h) ? h + contextVideo.sizeUnit : (h || contextVideo._defaultRatio);
+
+ contextVideo._container.style.width = this.util.isNumber(w) ? w + '%' : w;
+ contextVideo._container.style.height = '';
+ contextVideo._cover.style.width = '100%';
+ contextVideo._cover.style.height = h;
+ contextVideo._cover.style.paddingBottom = h;
+ contextVideo._element.style.width = '100%';
+ contextVideo._element.style.height = '100%';
+ contextVideo._element.style.maxWidth = '';
+
+ if (contextVideo._align === 'center') this.plugins.video.setAlign.call(this, null, null, null, null);
+ contextVideo._element.setAttribute('data-percentage', w + ',' + h);
+
+ // save current size
+ this.plugins.resizing._module_saveCurrentSize.call(this, contextVideo);
+ },
+
+ /**
+ * @Override resizing
+ */
+ cancelPercentAttr: function () {
+ const contextVideo = this.context.video;
+
+ contextVideo._cover.style.width = '';
+ contextVideo._cover.style.height = '';
+ contextVideo._cover.style.paddingBottom = '';
+ contextVideo._container.style.width = '';
+ contextVideo._container.style.height = '';
+
+ this.util.removeClass(contextVideo._container, this.context.video._floatClassRegExp);
+ this.util.addClass(contextVideo._container, '__se__float-' + contextVideo._align);
+
+ if (contextVideo._align === 'center') this.plugins.video.setAlign.call(this, null, null, null, null);
+ },
+
+ /**
+ * @Override resizing
+ */
+ setAlign: function (align, element, cover, container) {
+ const contextVideo = this.context.video;
+
+ if (!align) align = contextVideo._align;
+ if (!element) element = contextVideo._element;
+ if (!cover) cover = contextVideo._cover;
+ if (!container) container = contextVideo._container;
+
+ if (align && align !== 'none') {
+ cover.style.margin = 'auto';
+ } else {
+ cover.style.margin = '0';
+ }
+
+ if (/%$/.test(element.style.width) && align === 'center') {
+ container.style.minWidth = '100%';
+ cover.style.width = container.style.width;
+ cover.style.height = cover.style.height;
+ cover.style.paddingBottom = !/%$/.test(cover.style.height) ? cover.style.height : this.util.getNumber((this.util.getNumber(cover.style.height, 2) / 100) * this.util.getNumber(cover.style.width, 2), 2) + '%';
+ } else {
+ container.style.minWidth = '';
+ cover.style.width = this.context.resizing._rotateVertical ? (element.style.height || element.offsetHeight) : (element.style.width || '100%');
+ cover.style.paddingBottom = cover.style.height;
+ }
+
+ if (!this.util.hasClass(container, '__se__float-' + align)) {
+ this.util.removeClass(container, contextVideo._floatClassRegExp);
+ this.util.addClass(container, '__se__float-' + align);
+ }
+
+ element.setAttribute('data-align', align);
+ },
+
+ resetAlign: function () {
+ const contextVideo = this.context.video;
+
+ contextVideo._element.setAttribute('data-align', '');
+ contextVideo._align = 'none';
+ contextVideo._cover.style.margin = '0';
+ this.util.removeClass(contextVideo._container, contextVideo._floatClassRegExp);
+ },
+
+ /**
+ * @Override dialog
+ */
+ init: function () {
+ const contextVideo = this.context.video;
+ if (contextVideo.videoInputFile) contextVideo.videoInputFile.value = '';
+ if (contextVideo.videoUrlFile) contextVideo._linkValue = contextVideo.preview.textContent = contextVideo.videoUrlFile.value = '';
+ if (contextVideo.videoInputFile && contextVideo.videoUrlFile) {
+ contextVideo.videoUrlFile.removeAttribute('disabled');
+ contextVideo.preview.style.textDecoration = '';
+ }
+
+ contextVideo._origin_w = this.context.option.videoWidth;
+ contextVideo._origin_h = this.context.option.videoHeight;
+ contextVideo.modal.querySelector('input[name="suneditor_video_radio"][value="none"]').checked = true;
+
+ if (contextVideo._resizing) {
+ contextVideo.inputX.value = this.context.option.videoWidth === contextVideo._defaultSizeX ? '' : this.context.option.videoWidth;
+ contextVideo.inputY.value = this.context.option.videoHeight === contextVideo._defaultSizeY ? '' : this.context.option.videoHeight;
+ contextVideo.proportion.checked = true;
+ contextVideo.proportion.disabled = true;
+ this.plugins.video.setVideoRatioSelect.call(this, contextVideo._defaultRatio);
+ }
+ }
+};
--- /dev/null
+import { FileBrowserPlugin } from '../FileBrowserPlugin';
+
+declare const imageGallery: FileBrowserPlugin;
+
+export default imageGallery;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+import fileBrowser from '../modules/fileBrowser';
+
+export default {
+ name: 'imageGallery',
+ /**
+ * @description Constructor
+ * @param {Object} core Core object
+ */
+ add: function (core) {
+ core.addModule([fileBrowser]);
+
+ const context = core.context;
+ context.imageGallery = {
+ title: core.lang.toolbar.imageGallery, // @Required @Override fileBrowser - File browser window title.
+ url: context.options.imageGalleryUrl, // @Required @Override fileBrowser - File server url.
+ listClass: 'se-image-list', // @Required @Override fileBrowser - Class name of list div.
+ itemTemplateHandler: this.drawItems, // @Required @Override fileBrowser - Function that defines the HTML of an file item.
+ selectorHandler: this.setImage.bind(core), // @Required @Override fileBrowser - Function that action when item click.
+ columnSize: 4 // @Option @Override fileBrowser - Number of "div.se-file-item-column" to be created (default: 4)
+ };
+ },
+
+ /**
+ * @Required @Override fileBrowser
+ * @description Open a file browser.
+ * @param {Function|null} selectorHandler When the function comes as an argument value, it substitutes "context.selectorHandler".
+ */
+ open: function (selectorHandler) {
+ this.plugins.fileBrowser.open.call(this, 'imageGallery', selectorHandler);
+ },
+
+ /**
+ * @Required @Override fileBrowser
+ * @description Define the HTML of the item to be put in "div.se-file-item-column".
+ * Format: [
+ * { src: "image src", name: "name(@option)", alt: "image alt(@option)", tag: "tag name(@option)" }
+ * ]
+ * @param {Object} item Item of the response data's array
+ */
+ drawItems: function (item) {
+ const srcName = item.src.split('/').pop();
+ return '<div class="se-file-item-img"><img src="' + item.src + '" alt="' + (item.alt || srcName) + '" data-command="pick">' +
+ '<div class="se-file-img-name se-file-name-back"></div>' +
+ '<div class="se-file-img-name __se__img_name">' + (item.name || srcName) + '</div>' +
+ '</div>';
+ },
+
+ setImage: function (target) {
+ this.callPlugin('image', function () {
+ const file = {name: target.parentNode.querySelector('.__se__img_name').textContent, size: 0};
+ this.context.image._altText = target.alt;
+ this.plugins.image.create_image.call(this, target.src, '', false, this.context.image._origin_w, this.context.image._origin_h, 'none', file);
+ }.bind(this), null);
+ }
+};
\ No newline at end of file
--- /dev/null
+import { Plugin } from './Plugin';
+
+// command
+import blockquote from './command/blockquote';
+
+// submenu
+import align from './submenu/align';
+import font from './submenu/font';
+import fontSize from './submenu/fontSize';
+import fontColor from './submenu/fontColor';
+import hiliteColor from './submenu/hiliteColor';
+import horizontalRule from './submenu/horizontalRule';
+import list from './submenu/list';
+import table from './submenu/table';
+import formatBlock from './submenu/formatBlock';
+import lineHeight from './submenu/lineHeight';
+import template from './submenu/template';
+import paragraphStyle from './submenu/paragraphStyle';
+import textStyle from './submenu/textStyle';
+
+// dialog
+import link from './dialog/link';
+import image from './dialog/image';
+import video from './dialog/video';
+import audio from './dialog/audio';
+import math from './dialog/math';
+
+// file browser
+import imageGallery from './fileBrowser/imageGallery';
+
+declare const _plugins: Plugin[];
+
+export { blockquote, align, font, fontSize, fontColor, hiliteColor, horizontalRule, list, table, formatBlock, lineHeight, template, paragraphStyle, textStyle, link, image, video, audio, math, imageGallery };
+export default _plugins;
\ No newline at end of file
--- /dev/null
+'use strict';
+
+// command
+import blockquote from './command/blockquote';
+
+// submenu
+import align from './submenu/align';
+import font from './submenu/font';
+import fontSize from './submenu/fontSize';
+import fontColor from './submenu/fontColor';
+import hiliteColor from './submenu/hiliteColor';
+import horizontalRule from './submenu/horizontalRule';
+import list from './submenu/list';
+import table from './submenu/table';
+import formatBlock from './submenu/formatBlock';
+import lineHeight from './submenu/lineHeight';
+import template from './submenu/template';
+import paragraphStyle from './submenu/paragraphStyle';
+import textStyle from './submenu/textStyle';
+
+// dialog
+import link from './dialog/link';
+import image from './dialog/image';
+import video from './dialog/video';
+import audio from './dialog/audio';
+import math from './dialog/math';
+
+// file browser
+import imageGallery from './fileBrowser/imageGallery';
+
+export { blockquote, align, font, fontSize, fontColor, hiliteColor, horizontalRule, list, table, formatBlock, lineHeight, template, paragraphStyle, textStyle, link, image, video, audio, math, imageGallery };
+export default { blockquote, align, font, fontSize, fontColor, hiliteColor, horizontalRule, list, table, formatBlock, lineHeight, template, paragraphStyle, textStyle, link, image, video, audio, math, imageGallery };
--- /dev/null
+import SunEditor from '../../lib/core';
+import { Module } from '../Module';
+
+declare interface _colorPicker extends Module {
+ /**
+ * @description Create color list
+ * @param core Core object
+ * @param makeColor this._makeColorList
+ * @returns HTML string
+ */
+ createColorList(core: SunEditor, makeColor: Function): string;
+
+ /**
+ * @description Displays or resets the currently selected color at color list.
+ * @param node Current Selected node
+ * @param color Color value
+ */
+ init(node: Node, color: string): void;
+
+ /**
+ * @description Store color values
+ * @param hexColorStr Hax color value
+ */
+ setCurrentColor(hexColorStr: string): void;
+
+ /**
+ * @description Set color at input element
+ * @param hexColorStr Hax color value
+ */
+ setInputText(hexColorStr: string): void;
+
+ /**
+ * @description Gets color value at color property of node
+ * @param node Selected node
+ * @returns
+ */
+ getColorInNode(node: Node): string;
+
+ /**
+ * @description Function to check hex format color
+ * @param str Color value
+ */
+ isHexColor(str: string): boolean;
+
+ /**
+ * @description Function to convert hex format to a rgb color
+ * @param rgb RGB color format
+ * @returns
+ */
+ rgb2hex(rgb: string): string;
+
+ /**
+ * @description Converts color values of other formats to hex color values and returns.
+ * @param colorName Color value
+ * @returns
+ */
+ colorName2hex(colorName: string): string;
+}
+
+export default _colorPicker;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2018 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ name: 'colorPicker',
+ /**
+ * @description Constructor
+ * @param {Object} core Core object
+ */
+ add: function (core) {
+ const context = core.context;
+ context.colorPicker = {
+ colorListHTML: '',
+ _colorInput: '',
+ _defaultColor: '#000',
+ _styleProperty: 'color',
+ _currentColor: '',
+ _colorList: []
+ };
+
+ /** set submenu */
+ let listDiv = this.createColorList(core, this._makeColorList);
+
+ /** caching */
+ context.colorPicker.colorListHTML = listDiv;
+
+ /** empty memory */
+ listDiv = null;
+ },
+
+ /**
+ * @description Create color list
+ * @param {Object} core Core object
+ * @param {Function} makeColor this._makeColorList
+ * @returns {String} HTML string
+ */
+ createColorList: function (core, makeColor) {
+ const option = core.context.option;
+ const lang = core.lang;
+ const colorList = !option.colorList || option.colorList.length === 0 ?
+ [
+ '#ff0000', '#ff5e00', '#ffe400', '#abf200', '#00d8ff', '#0055ff', '#6600ff', '#ff00dd', '#000000',
+ '#ffd8d8', '#fae0d4', '#faf4c0', '#e4f7ba', '#d4f4fa', '#d9e5ff', '#e8d9ff', '#ffd9fa', '#f1f1f1',
+ '#ffa7a7', '#ffc19e', '#faed7d', '#cef279', '#b2ebf4', '#b2ccff', '#d1b2ff', '#ffb2f5', '#bdbdbd',
+ '#f15f5f', '#f29661', '#e5d85c', '#bce55c', '#5cd1e5', '#6699ff', '#a366ff', '#f261df', '#8c8c8c',
+ '#980000', '#993800', '#998a00', '#6b9900', '#008299', '#003399', '#3d0099', '#990085', '#353535',
+ '#670000', '#662500', '#665c00', '#476600', '#005766', '#002266', '#290066', '#660058', '#222222'
+ ] : option.colorList;
+
+ let colorArr = [];
+ let list = '<div class="se-list-inner">';
+ for (let i = 0, len = colorList.length, color; i < len; i++) {
+ color = colorList[i];
+ if (!color) continue;
+
+ if (typeof color === 'string') {
+ colorArr.push(color);
+ if (i < len - 1) continue;
+ }
+ if (colorArr.length > 0) {
+ list += '<div class="se-selector-color">' + makeColor(colorArr) + '</div>';
+ colorArr = [];
+ }
+ if (typeof color === 'object') {
+ list += '<div class="se-selector-color">' + makeColor(color) + '</div>';
+ }
+ }
+ list += '' +
+ '<form class="se-submenu-form-group">' +
+ '<input type="text" maxlength="9" class="_se_color_picker_input se-color-input"/>' +
+ '<button type="submit" class="se-btn-primary _se_color_picker_submit" title="' + lang.dialogBox.submitButton + '">' +
+ core.icons.checked +
+ '</button>' +
+ '<button type="button" class="se-btn _se_color_picker_remove" title="' + lang.toolbar.removeFormat + '">' +
+ core.icons.erase +
+ '</button>' +
+ '</form>' +
+ '</div>';
+
+ return list;
+ },
+
+ /**
+ * @description Internal function used by this.createColorList
+ * @param {Array} colorList Color list
+ * @private
+ */
+ _makeColorList: function (colorList) {
+ let list = '';
+
+ list += '<ul class="se-color-pallet">';
+ for (let i = 0, len = colorList.length, color; i < len; i++) {
+ color = colorList[i];
+ if (typeof color === 'string') {
+ list += '<li>' +
+ '<button type="button" data-value="' + color + '" title="' + color + '" style="background-color:' + color + ';"></button>' +
+ '</li>';
+ }
+ }
+ list += '</ul>';
+
+ return list;
+ },
+
+ /**
+ * @description Displays or resets the currently selected color at color list.
+ * @param {Node} node Current Selected node
+ * @param {String|null} color Color value
+ */
+ init: function (node, color) {
+ const colorPicker = this.plugins.colorPicker;
+ let fillColor = color ? color : colorPicker.getColorInNode.call(this, node) || this.context.colorPicker._defaultColor;
+ fillColor = colorPicker.isHexColor(fillColor) ? fillColor : colorPicker.rgb2hex(fillColor) || fillColor;
+
+ const colorList = this.context.colorPicker._colorList;
+ if (colorList) {
+ for (let i = 0, len = colorList.length; i < len; i++) {
+ if (fillColor.toLowerCase() === colorList[i].getAttribute('data-value').toLowerCase()) {
+ this.util.addClass(colorList[i], 'active');
+ } else {
+ this.util.removeClass(colorList[i], 'active');
+ }
+ }
+ }
+
+ colorPicker.setInputText.call(this, colorPicker.colorName2hex.call(this, fillColor));
+ },
+
+ /**
+ * @description Store color values
+ * @param {String} hexColorStr Hax color value
+ */
+ setCurrentColor: function (hexColorStr) {
+ this.context.colorPicker._currentColor = hexColorStr;
+ this.context.colorPicker._colorInput.style.borderColor = hexColorStr;
+ },
+
+ /**
+ * @description Set color at input element
+ * @param {String} hexColorStr Hax color value
+ */
+ setInputText: function (hexColorStr) {
+ hexColorStr = /^#/.test(hexColorStr) ? hexColorStr : '#' + hexColorStr;
+ this.context.colorPicker._colorInput.value = hexColorStr;
+ this.plugins.colorPicker.setCurrentColor.call(this, hexColorStr);
+ },
+
+ /**
+ * @description Gets color value at color property of node
+ * @param {Node} node Selected node
+ * @returns {String}
+ */
+ getColorInNode: function (node) {
+ let findColor = '';
+ const styleProperty = this.context.colorPicker._styleProperty;
+
+ while (node && !this.util.isWysiwygDiv(node) && findColor.length === 0) {
+ if (node.nodeType === 1 && node.style[styleProperty]) findColor = node.style[styleProperty];
+ node = node.parentNode;
+ }
+
+ return findColor;
+ },
+
+ /**
+ * @description Function to check hex format color
+ * @param {String} str Color value
+ */
+ isHexColor: function (str) {
+ return /^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(str);
+ },
+
+ /**
+ * @description Function to convert hex format to a rgb color
+ * @param {String} rgb RGB color format
+ * @returns {String}
+ */
+ rgb2hex: function (rgb) {
+ const rgbMatch = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
+
+ return (rgbMatch && rgbMatch.length === 4) ? "#" +
+ ("0" + parseInt(rgbMatch[1],10).toString(16)).slice(-2) +
+ ("0" + parseInt(rgbMatch[2],10).toString(16)).slice(-2) +
+ ("0" + parseInt(rgbMatch[3],10).toString(16)).slice(-2) : '';
+ },
+
+ /**
+ * @description Converts color values of other formats to hex color values and returns.
+ * @param {String} colorName Color value
+ * @returns {String}
+ */
+ colorName2hex: function (colorName) {
+ if (/^#/.test(colorName)) return colorName;
+ var temp = this.util.createElement('div');
+ temp.style.display = 'none';
+ temp.style.color = colorName;
+ var colors = this._w.getComputedStyle(this._d.body.appendChild(temp)).color.match(/\d+/g).map(function (a) { return parseInt(a,10); });
+ this.util.removeItem(temp);
+ return (colors.length >= 3) ? '#' + (((1 << 24) + (colors[0] << 16) + (colors[1] << 8) + colors[2]).toString(16).substr(1)) : false;
+ }
+};
\ No newline at end of file
--- /dev/null
+import { Module } from '../Module';
+
+declare interface _notice extends Module {
+ /**
+ * @description Event when clicking the cancel button
+ * @param e Event object
+ */
+ onClick_cancel(e: MouseEvent): void;
+ /**
+ * @description Open the notice panel
+ * @param text Notice message
+ */
+ open(text: string): void;
+
+ /**
+ * @description Open the notice panel
+ */
+ close(): void;
+}
+
+export default _notice;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ name: 'notice',
+ /**
+ * @description Constructor
+ * @param {Object} core Core object
+ */
+ add: function (core) {
+ const context = core.context;
+ context.notice = {};
+
+ /** dialog */
+ let notice_div = core.util.createElement('DIV');
+ let notice_span = core.util.createElement('SPAN');
+ let notice_button = core.util.createElement('BUTTON');
+
+ notice_div.className = 'se-notice';
+ notice_button.className = 'close';
+ notice_button.setAttribute('aria-label', 'Close');
+ notice_button.setAttribute('title', core.lang.dialogBox.close);
+ notice_button.innerHTML = core.icons.cancel;
+
+ notice_div.appendChild(notice_span);
+ notice_div.appendChild(notice_button);
+
+ context.notice.modal = notice_div;
+ context.notice.message = notice_span;
+
+ /** add event listeners */
+ notice_button.addEventListener('click', this.onClick_cancel.bind(core));
+
+ /** append html */
+ context.element.editorArea.appendChild(notice_div);
+
+ /** empty memory */
+ notice_div = null;
+ },
+
+ /**
+ * @description Event when clicking the cancel button
+ * @param {MouseEvent} e Event object
+ */
+ onClick_cancel: function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ this.plugins.notice.close.call(this);
+ },
+
+ /**
+ * @description Open the notice panel
+ * @param {String} text Notice message
+ */
+ open: function (text) {
+ this.context.notice.message.textContent = text;
+ this.context.notice.modal.style.display = 'block';
+ },
+
+ /**
+ * @description Open the notice panel
+ */
+ close: function () {
+ this.context.notice.modal.style.display = 'none';
+ }
+};
--- /dev/null
+import { Module } from '../Module';
+
+declare interface component extends Module {
+ /**
+ * @description Create a container for the resizing component and insert the element.
+ * @param cover Cover element (FIGURE)
+ * @param className Class name of container (fixed: se-component)
+ * @returns Created container element
+ */
+ set_container(cover: Element, className: string): Element;
+
+ /**
+ * @description Cover the target element with a FIGURE element.
+ * @param element Target element
+ */
+ set_cover(element: Element): void;
+
+ /**
+ * @description Return HTML string of caption(FIGCAPTION) element
+ * @returns
+ */
+ create_caption(): string;
+}
+
+export default resizing;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_MODULES a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const component = {
+ name: 'component',
+ /**
+ * @description Create a container for the resizing component and insert the element.
+ * @param {Element} cover Cover element (FIGURE)
+ * @param {String} className Class name of container (fixed: se-component)
+ * @returns {Element} Created container element
+ */
+ set_container: function (cover, className) {
+ const container = this.util.createElement('DIV');
+ container.className = 'se-component ' + className;
+ container.setAttribute('contenteditable', false);
+ container.appendChild(cover);
+
+ return container;
+ },
+
+ /**
+ * @description Cover the target element with a FIGURE element.
+ * @param {Element} element Target element
+ */
+ set_cover: function (element) {
+ const cover = this.util.createElement('FIGURE');
+ cover.appendChild(element);
+
+ return cover;
+ },
+
+ /**
+ * @description Return HTML string of caption(FIGCAPTION) element
+ * @returns {String}
+ */
+ create_caption: function () {
+ const caption = this.util.createElement('FIGCAPTION');
+ caption.setAttribute('contenteditable', true);
+ caption.innerHTML = '<div>' + this.lang.dialogBox.caption + '</div>';
+ return caption;
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_MODULES) {
+ Object.defineProperty(window, 'SUNEDITOR_MODULES', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_MODULES, 'component', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: component
+ });
+ }
+
+ return component;
+}));
\ No newline at end of file
--- /dev/null
+import { Module } from '../Module';
+
+/**
+ * @description This is a required module of dialog plugin.
+ */
+declare interface dialog extends Module {
+ /**
+ * @description Open a Dialog plugin
+ * @param kind Dialog plugin name
+ * @param update Whether it will open for update ('image' === this.currentControllerName)
+ * @example this.plugins.dialog.open.call(this, 'image', 'image' === this.currentControllerName);
+ */
+ open(kind: string, update: boolean): void;
+
+ /**
+ * @description Called after the submenu has been rendered
+ */
+ on?: () => void;
+
+ /**
+ * @description Close a Dialog plugin
+ * The plugin's "init" method is called.
+ * @example this.plugins.dialog.close.call(this);
+ */
+ close(): void;
+}
+
+export default dialog;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_MODULES a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const dialog = {
+ name: 'dialog',
+ /**
+ * @description Constructor
+ * @param {Object} core Core object
+ */
+ add: function (core) {
+ const context = core.context;
+ context.dialog = {
+ kind: '',
+ updateModal: false,
+ _closeSignal: false
+ };
+
+ /** dialog */
+ let dialog_div = core.util.createElement('DIV');
+ dialog_div.className = 'se-dialog sun-editor-common';
+
+ let dialog_back = core.util.createElement('DIV');
+ dialog_back.className = 'se-dialog-back';
+ dialog_back.style.display = 'none';
+
+ let dialog_area = core.util.createElement('DIV');
+ dialog_area.className = 'se-dialog-inner';
+ dialog_area.style.display = 'none';
+
+ dialog_div.appendChild(dialog_back);
+ dialog_div.appendChild(dialog_area);
+
+ context.dialog.modalArea = dialog_div;
+ context.dialog.back = dialog_back;
+ context.dialog.modal = dialog_area;
+
+ /** add event listeners */
+ context.dialog.modal.addEventListener('mousedown', this._onMouseDown_dialog.bind(core));
+ context.dialog.modal.addEventListener('click', this._onClick_dialog.bind(core));
+
+ /** append html */
+ context.element.relative.appendChild(dialog_div);
+
+ /** empty memory */
+ dialog_div = null, dialog_back = null, dialog_area = null;
+ },
+
+ /**
+ * @description Event to control the behavior of closing the dialog
+ * @param {MouseEvent} e Event object
+ * @private
+ */
+ _onMouseDown_dialog: function (e) {
+ if (/se-dialog-inner/.test(e.target.className)) {
+ this.context.dialog._closeSignal = true;
+ } else {
+ this.context.dialog._closeSignal = false;
+ }
+ },
+
+ /**
+ * @description Event to close the window when the outside area of the dialog or close button is click
+ * @param {MouseEvent} e Event object
+ * @private
+ */
+ _onClick_dialog: function (e) {
+ e.stopPropagation();
+
+ if (/close/.test(e.target.getAttribute('data-command')) || this.context.dialog._closeSignal) {
+ this.plugins.dialog.close.call(this);
+ }
+ },
+
+ /**
+ * @description Open a Dialog plugin
+ * @param {String} kind Dialog plugin name
+ * @param {Boolean} update Whether it will open for update ('image' === this.currentControllerName)
+ */
+ open: function (kind, update) {
+ if (this.modalForm) return false;
+ if (this.plugins.dialog._bindClose) {
+ this._d.removeEventListener('keydown', this.plugins.dialog._bindClose);
+ this.plugins.dialog._bindClose = null;
+ }
+
+ this.plugins.dialog._bindClose = function (e) {
+ if (!/27/.test(e.keyCode)) return;
+ this.plugins.dialog.close.call(this);
+ }.bind(this);
+ this._d.addEventListener('keydown', this.plugins.dialog._bindClose);
+
+ this.context.dialog.updateModal = update;
+
+ if (this.context.option.popupDisplay === 'full') {
+ this.context.dialog.modalArea.style.position = 'fixed';
+ } else {
+ this.context.dialog.modalArea.style.position = 'absolute';
+ }
+
+ this.context.dialog.kind = kind;
+ this.modalForm = this.context[kind].modal;
+ const focusElement = this.context[kind].focusElement;
+
+ if (typeof this.plugins[kind].on === 'function') this.plugins[kind].on.call(this, update);
+
+ this.context.dialog.modalArea.style.display = 'block';
+ this.context.dialog.back.style.display = 'block';
+ this.context.dialog.modal.style.display = 'block';
+ this.modalForm.style.display = 'block';
+
+ if (focusElement) focusElement.focus();
+ },
+
+ _bindClose: null,
+
+ /**
+ * @description Close a Dialog plugin
+ * The plugin's "init" method is called.
+ */
+ close: function () {
+ if (this.plugins.dialog._bindClose) {
+ this._d.removeEventListener('keydown', this.plugins.dialog._bindClose);
+ this.plugins.dialog._bindClose = null;
+ }
+
+ const kind = this.context.dialog.kind;
+ this.modalForm.style.display = 'none';
+ this.context.dialog.back.style.display = 'none';
+ this.context.dialog.modalArea.style.display = 'none';
+ this.context.dialog.updateModal = false;
+ if (typeof this.plugins[kind].init === 'function') this.plugins[kind].init.call(this);
+ this.context.dialog.kind = '';
+ this.modalForm = null;
+ this.focus();
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_MODULES) {
+ Object.defineProperty(window, 'SUNEDITOR_MODULES', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_MODULES, 'dialog', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: dialog
+ });
+ }
+
+ return dialog;
+}));
\ No newline at end of file
--- /dev/null
+import { Module } from '../Module';
+
+/**
+ * @description This is a required module of fileBrowser plugin.
+ Require context properties when using fileBrowser module:
+ title(@Required): "File browser window title",
+ url(@Required): "File server url",
+ listClass(@Required): "Class name of list div",
+ itemTemplateHandler(@Required): "Function that defines the HTML of an file item",
+ selectorHandler(@Required): "Function that action when item click",
+ columnSize(@Option): "Number of "div.se-file-item-column" to be created (default: 4)"
+*/
+declare interface fileBrowser extends Module {
+ /**
+ * @description Open a file browser window
+ * @param pluginName Plugin name using the file browser
+ * @param selectorHandler When the function comes as an argument value, it substitutes "context.selectorHandler".
+ * @example this.plugins.fileBrowser.open.call(this, 'imageGallery', (selectorHandler || null));
+ */
+ open(kind: string, update: boolean): void;
+
+ /**
+ * @description Define the HTML of the item to be put in "div.se-file-item-column".
+ * @param item Item of the response data's array
+ */
+ drawItems: (item: object) => string;
+
+ /**
+ * @description Close a file browser window
+ * The plugin's "init" method is called.
+ * @example this.plugins.fileBrowser.close.call(this);
+ */
+ close(): void;
+
+ /**
+ * @description This method is called when the file browser window is closed.
+ * Initialize the properties.
+ */
+ init?: () => void;
+}
+
+export default fileBrowser;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_MODULES a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const fileBrowser = {
+ name: 'fileBrowser',
+ _xmlHttp: null,
+ _loading: null,
+
+ /**
+ * @description Constructor
+ * @param {Object} core Core object
+ */
+ add: function (core) {
+ const context = core.context;
+ context.fileBrowser = {
+ _closeSignal: false,
+ area: null,
+ header: null,
+ tagArea: null,
+ body: null,
+ list: null,
+ tagElements: null,
+ items: [],
+ selectedTags: [],
+ selectorHandler: null,
+ contextPlugin: '',
+ columnSize: 4
+ };
+
+ /** fileBrowser */
+ let browser_div = core.util.createElement('DIV');
+ browser_div.className = 'se-file-browser sun-editor-common';
+
+ let back = core.util.createElement('DIV');
+ back.className = 'se-file-browser-back';
+
+ let content = core.util.createElement('DIV');
+ content.className = 'se-file-browser-inner';
+ content.innerHTML = this.set_browser(core);
+
+ browser_div.appendChild(back);
+ browser_div.appendChild(content);
+ this._loading = browser_div.querySelector('.se-loading-box');
+
+ context.fileBrowser.area = browser_div;
+ context.fileBrowser.header = content.querySelector('.se-file-browser-header');
+ context.fileBrowser.titleArea = content.querySelector('.se-file-browser-title');
+ context.fileBrowser.tagArea = content.querySelector('.se-file-browser-tags');
+ context.fileBrowser.body = content.querySelector('.se-file-browser-body');
+ context.fileBrowser.list = content.querySelector('.se-file-browser-list');
+
+ /** add event listeners */
+ context.fileBrowser.tagArea.addEventListener('click', this.onClickTag.bind(core));
+ context.fileBrowser.list.addEventListener('click', this.onClickFile.bind(core));
+ content.addEventListener('mousedown', this._onMouseDown_browser.bind(core));
+ content.addEventListener('click', this._onClick_browser.bind(core));
+
+ /** append html */
+ context.element.relative.appendChild(browser_div);
+
+ /** empty memory */
+ browser_div = null, back = null, content = null;
+ },
+
+ set_browser: function (core) {
+ const lang = core.lang;
+
+ return '<div class="se-file-browser-content">' +
+ '<div class="se-file-browser-header">' +
+ '<button type="button" data-command="close" class="se-btn se-file-browser-close" class="close" aria-label="Close" title="' + lang.dialogBox.close + '">' +
+ core.icons.cancel +
+ '</button>' +
+ '<span class="se-file-browser-title"></span>' +
+ '<div class="se-file-browser-tags"></div>' +
+ '</div>' +
+ '<div class="se-file-browser-body">' +
+ '<div class="se-loading-box sun-editor-common"><div class="se-loading-effect"></div></div>' +
+ '<div class="se-file-browser-list"></div>' +
+ '</div>' +
+ '</div>';
+ },
+
+ /**
+ * @description Event to control the behavior of closing the browser
+ * @param {MouseEvent} e Event object
+ * @private
+ */
+ _onMouseDown_browser: function (e) {
+ if (/se-file-browser-inner/.test(e.target.className)) {
+ this.context.fileBrowser._closeSignal = true;
+ } else {
+ this.context.fileBrowser._closeSignal = false;
+ }
+ },
+
+ /**
+ * @description Event to close the window when the outside area of the browser or close button is click
+ * @param {MouseEvent} e Event object
+ * @private
+ */
+ _onClick_browser: function (e) {
+ e.stopPropagation();
+
+ if (/close/.test(e.target.getAttribute('data-command')) || this.context.fileBrowser._closeSignal) {
+ this.plugins.fileBrowser.close.call(this);
+ }
+ },
+
+ /**
+ * @description Open a file browser plugin
+ * @param {String} pluginName Plugin name using the file browser
+ * @param {Function|null} selectorHandler When the function comes as an argument value, it substitutes "context.selectorHandler".
+ */
+ open: function (pluginName, selectorHandler) {
+ if (this.plugins.fileBrowser._bindClose) {
+ this._d.removeEventListener('keydown', this.plugins.fileBrowser._bindClose);
+ this.plugins.fileBrowser._bindClose = null;
+ }
+
+ this.plugins.fileBrowser._bindClose = function (e) {
+ if (!/27/.test(e.keyCode)) return;
+ this.plugins.fileBrowser.close.call(this);
+ }.bind(this);
+ this._d.addEventListener('keydown', this.plugins.fileBrowser._bindClose);
+
+ const fileBrowserContext = this.context.fileBrowser;
+ fileBrowserContext.contextPlugin = pluginName;
+ fileBrowserContext.selectorHandler = selectorHandler;
+
+ const pluginContext = this.context[pluginName];
+ const listClassName = pluginContext.listClass;
+ if (!this.util.hasClass(fileBrowserContext.list, listClassName)) {
+ fileBrowserContext.list.className = 'se-file-browser-list ' + listClassName;
+ }
+
+ if (this.context.option.popupDisplay === 'full') {
+ fileBrowserContext.area.style.position = 'fixed';
+ } else {
+ fileBrowserContext.area.style.position = 'absolute';
+ }
+
+ fileBrowserContext.titleArea.textContent = pluginContext.title;
+ fileBrowserContext.area.style.display = 'block';
+
+ this.plugins.fileBrowser._drawFileList.call(this, this.context[pluginName].url);
+ },
+
+ _bindClose: null,
+
+ /**
+ * @description Close a fileBrowser plugin
+ * The plugin's "init" method is called.
+ */
+ close: function () {
+ const fileBrowserPlugin = this.plugins.fileBrowser;
+
+ if (fileBrowserPlugin._xmlHttp) {
+ fileBrowserPlugin._xmlHttp.abort();
+ }
+
+ if (fileBrowserPlugin._bindClose) {
+ this._d.removeEventListener('keydown', fileBrowserPlugin._bindClose);
+ fileBrowserPlugin._bindClose = null;
+ }
+
+ const fileBrowserContext = this.context.fileBrowser;
+ fileBrowserContext.area.style.display = 'none';
+ fileBrowserContext.selectorHandler = null;
+ fileBrowserContext.selectedTags = [];
+ fileBrowserContext.items = [];
+ fileBrowserContext.list.innerHTML = fileBrowserContext.tagArea.innerHTML = fileBrowserContext.titleArea.textContent = '';
+
+ if (typeof this.plugins[fileBrowserContext.contextPlugin].init === 'function') this.plugins[fileBrowserContext.contextPlugin].init.call(this);
+ fileBrowserContext.contextPlugin = '';
+ },
+
+ /**
+ * @description Show file browser loading box
+ */
+ showBrowserLoading: function () {
+ this._loading.style.display = 'block';
+ },
+
+ /**
+ * @description Close file browser loading box
+ */
+ closeBrowserLoading: function () {
+ this._loading.style.display = 'none';
+ },
+
+ _drawFileList: function (url) {
+ const fileBrowserPlugin = this.plugins.fileBrowser;
+
+ const xmlHttp = fileBrowserPlugin._xmlHttp = this.util.getXMLHttpRequest();
+ xmlHttp.onreadystatechange = fileBrowserPlugin._callBackGet.bind(this, xmlHttp);
+ xmlHttp.open('get', url, true);
+ xmlHttp.send(null);
+
+ this.plugins.fileBrowser.showBrowserLoading();
+ },
+
+ _callBackGet: function (xmlHttp) {
+ if (xmlHttp.readyState === 4) {
+ this.plugins.fileBrowser._xmlHttp = null;
+ if (xmlHttp.status === 200) {
+ try {
+ this.plugins.fileBrowser._drawListItem.call(this, JSON.parse(xmlHttp.responseText).result, true);
+ } catch (e) {
+ throw Error('[SUNEDITOR.fileBrowser.drawList.fail] cause : "' + e.message + '"');
+ } finally {
+ this.plugins.fileBrowser.closeBrowserLoading();
+ this.context.fileBrowser.body.style.maxHeight = (this._w.innerHeight - this.context.fileBrowser.header.offsetHeight - 50) + 'px';
+ }
+ } else { // exception
+ this.plugins.fileBrowser.closeBrowserLoading();
+ if (xmlHttp.status !== 0) {
+ const res = !xmlHttp.responseText ? xmlHttp : JSON.parse(xmlHttp.responseText);
+ const err = '[SUNEDITOR.fileBrowser.get.serverException] status: ' + xmlHttp.status + ', response: ' + (res.errorMessage || xmlHttp.responseText);
+ throw Error(err);
+ }
+ }
+ }
+ },
+
+ _drawListItem: function (items, update) {
+ const fileBrowserContext = this.context.fileBrowser;
+ const pluginContext = this.context[fileBrowserContext.contextPlugin];
+
+ const _tags = [];
+ const len = items.length;
+ const columnSize = pluginContext.columnSize || fileBrowserContext.columnSize;
+ const splitSize = columnSize <= 1 ? 1 : (Math.round(len/columnSize) || 1);
+ const drawItemHandler = pluginContext.itemTemplateHandler;
+
+ let tagsHTML = '';
+ let listHTML = '<div class="se-file-item-column">';
+ let columns = 1;
+ for (let i = 0, item, tags; i < len; i++) {
+ item = items[i];
+ tags = !item.tag ? [] : typeof item.tag === 'string' ? item.tag.split(',') : item.tag;
+ tags = item.tag = tags.map(function (v) { return v.trim(); });
+ listHTML += drawItemHandler(item);
+
+ if ((i + 1) % splitSize === 0 && columns < columnSize && (i + 1) < len) {
+ columns++;
+ listHTML += '</div><div class="se-file-item-column">';
+ }
+
+ if (update && tags.length > 0) {
+ for (let t = 0, tLen = tags.length, tag; t < tLen; t++) {
+ tag = tags[t];
+ if (tag && _tags.indexOf(tag) === -1) {
+ _tags.push(tag);
+ tagsHTML += '<a title="' + tag + '">' + tag + '</a>';
+ }
+ }
+ }
+ }
+ listHTML += '</div>';
+
+ fileBrowserContext.list.innerHTML = listHTML;
+
+ if (update) {
+ fileBrowserContext.items = items;
+ fileBrowserContext.tagArea.innerHTML = tagsHTML;
+ fileBrowserContext.tagElements = fileBrowserContext.tagArea.querySelectorAll('A');
+ }
+ },
+
+ onClickTag: function (e) {
+ const target = e.target;
+ if (!this.util.isAnchor(target)) return;
+
+ const tagName = target.textContent;
+ const fileBrowserPlugin = this.plugins.fileBrowser;
+ const fileBrowserContext = this.context.fileBrowser;
+
+ const selectTag = fileBrowserContext.tagArea.querySelector('a[title="' + tagName + '"]');
+ const selectedTags = fileBrowserContext.selectedTags;
+ const sTagIndex = selectedTags.indexOf(tagName);
+
+ if (sTagIndex > -1){
+ selectedTags.splice(sTagIndex, 1);
+ this.util.removeClass(selectTag, 'on');
+ } else {
+ selectedTags.push(tagName);
+ this.util.addClass(selectTag, 'on');
+ }
+
+ fileBrowserPlugin._drawListItem.call(this,
+ selectedTags.length === 0 ?
+ fileBrowserContext.items :
+ fileBrowserContext.items.filter(function (item) {
+ return item.tag.some(function (tag) {
+ return selectedTags.indexOf(tag) > -1;
+ });
+ }), false);
+ },
+
+ onClickFile: function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ const fileBrowserContext = this.context.fileBrowser;
+ const listEl = fileBrowserContext.list;
+ let target = e.target;
+ let command = null;
+
+ if (target === listEl) return;
+
+ while (listEl !== target.parentNode) {
+ command = target.getAttribute('data-command');
+ if (command) break;
+ target = target.parentNode;
+ }
+
+ if (!command) return;
+
+ const handler = (fileBrowserContext.selectorHandler || this.context[fileBrowserContext.contextPlugin].selectorHandler);
+ this.plugins.fileBrowser.close.call(this);
+ handler(target);
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_MODULES) {
+ Object.defineProperty(window, 'SUNEDITOR_MODULES', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_MODULES, 'fileBrowser', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: fileBrowser
+ });
+ }
+
+ return fileBrowser;
+}));
\ No newline at end of file
--- /dev/null
+import { Module } from '../Module';
+
+/**
+ * @description Require context properties when fileManager module
+ _infoList: [],
+ _infoIndex: 0,
+ _uploadFileLength: 0
+*/
+declare interface fileManager extends Module {
+ /**
+ * @description Upload the file to the server.
+ * @param uploadUrl Upload server url
+ * @param uploadHeader Request header
+ * @param formData FormData in body
+ * @param callBack Success call back function
+ * @param errorCallBack Error call back function
+ * @example this.plugins.fileManager.upload.call(this, imageUploadUrl, this.context.option.imageUploadHeader, formData, this.plugins.image.callBack_imgUpload.bind(this, info), this.functions.onImageUploadError);
+ */
+ upload(uploadUrl: string, uploadHeader: Record<string, string> | null, formData: FormData, callBack: Function | null, errorCallBack: Function | null): void;
+
+ /**
+ * @description Checke the file's information and modify the tag that does not fit the format.
+ * @param pluginName Plugin name
+ * @param tagNames Tag array to check
+ * @param uploadEventHandler Event handler to process updated file info after checking (used in "setInfo")
+ * @param modifyHandler A function to modify a tag that does not fit the format (Argument value: Tag element)
+ * @param resizing True if the plugin is using a resizing module
+ * @example
+ * const modifyHandler = function (tag) {
+ * imagePlugin.onModifyMode.call(this, tag, null);
+ * imagePlugin.openModify.call(this, true);
+ * imagePlugin.update_image.call(this, true, false, true);
+ * }.bind(this);
+ * this.plugins.fileManager.checkInfo.call(this, 'image', ['img'], this.functions.onImageUpload, modifyHandler, true);
+ */
+ checkInfo(pluginName: string, tagNames: string[], uploadEventHandler: Function | null, modifyHandler: Function | null, resizing: boolean): void;
+
+ /**
+ * @description Create info object of file and add it to "_infoList" (this.context[pluginName]._infoList[])
+ * @param pluginName Plugin name
+ * @param element
+ * @param uploadEventHandler Event handler to process updated file info (created in setInfo)
+ * @param file
+ * @param resizing True if the plugin is using a resizing module
+ * @example
+ * uploadCallBack {.. file = { name: fileList[i].name, size: fileList[i].size };
+ * this.plugins.fileManager.setInfo.call(this, 'image', oImg, this.functions.onImageUpload, file, true);
+ */
+ setInfo(pluginName: string, element, uploadEventHandler: Function | null, file:Record<string, string|number> | null, resizing: boolean): void;
+
+ /**
+ * @description Delete info object at "_infoList"
+ * @param pluginName Plugin name
+ * @param index index of info object (this.context[pluginName]._infoList[].index)
+ * @param uploadEventHandler Event handler to process updated file info (created in setInfo)
+ */
+ deleteInfo(pluginName: string, index, uploadEventHandler: Function | null): void;
+
+ /**
+ * @description Reset info object and "_infoList = []", "_infoIndex = 0"
+ * @param pluginName Plugin name
+ * @param uploadEventHandler Event handler to process updated file info (created in setInfo)
+ */
+ resetInfo(pluginName: string, uploadEventHandler: Function | null): void;
+}
+
+export default fileManager;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_MODULES a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const fileManager = {
+ name: 'fileManager',
+ _xmlHttp: null,
+
+ /**
+ * @description Upload the file to the server.
+ * @param {String} uploadUrl Upload server url
+ * @param {Object|null} uploadHeader Request header
+ * @param {FormData} formData FormData in body
+ * @param {Function|null} callBack Success call back function
+ * @param {Function|null} errorCallBack Error call back function
+ * @example this.plugins.fileManager.upload.call(this, imageUploadUrl, this.context.option.imageUploadHeader, formData, this.plugins.image.callBack_imgUpload.bind(this, info), this.functions.onImageUploadError);
+ */
+ upload: function (uploadUrl, uploadHeader, formData, callBack, errorCallBack) {
+ this.showLoading();
+ const filePlugin = this.plugins.fileManager;
+ const xmlHttp = filePlugin._xmlHttp = this.util.getXMLHttpRequest();
+
+ xmlHttp.onreadystatechange = filePlugin._callBackUpload.bind(this, xmlHttp, callBack, errorCallBack);
+ xmlHttp.open('post', uploadUrl, true);
+ if(uploadHeader !== null && typeof uploadHeader === 'object' && this._w.Object.keys(uploadHeader).length > 0){
+ for(let key in uploadHeader){
+ xmlHttp.setRequestHeader(key, uploadHeader[key]);
+ }
+ }
+ xmlHttp.send(formData);
+ },
+
+ _callBackUpload: function (xmlHttp, callBack, errorCallBack) {
+ if (xmlHttp.readyState === 4) {
+ if (xmlHttp.status === 200) {
+ try {
+ callBack(xmlHttp);
+ } catch (e) {
+ throw Error('[SUNEDITOR.fileManager.upload.callBack.fail] cause : "' + e.message + '"');
+ } finally {
+ this.closeLoading();
+ }
+ } else { // exception
+ this.closeLoading();
+ const res = !xmlHttp.responseText ? xmlHttp : JSON.parse(xmlHttp.responseText);
+ if (typeof errorCallBack !== 'function' || errorCallBack('', res, this)) {
+ const err = '[SUNEDITOR.fileManager.upload.serverException] status: ' + xmlHttp.status + ', response: ' + (res.errorMessage || xmlHttp.responseText);
+ this.functions.noticeOpen(err);
+ throw Error(err);
+ }
+ }
+ }
+ },
+
+ /**
+ * @description Checke the file's information and modify the tag that does not fit the format.
+ * @param {String} pluginName Plugin name
+ * @param {Array} tagNames Tag array to check
+ * @param {Function|null} uploadEventHandler Event handler to process updated file info after checking (used in "setInfo")
+ * @param {Function} modifyHandler A function to modify a tag that does not fit the format (Argument value: Tag element)
+ * @param {Boolean} resizing True if the plugin is using a resizing module
+ * @example
+ * const modifyHandler = function (tag) {
+ * imagePlugin.onModifyMode.call(this, tag, null);
+ * imagePlugin.openModify.call(this, true);
+ * imagePlugin.update_image.call(this, true, false, true);
+ * }.bind(this);
+ * this.plugins.fileManager.checkInfo.call(this, 'image', ['img'], this.functions.onImageUpload, modifyHandler, true);
+ */
+ checkInfo: function (pluginName, tagNames, uploadEventHandler, modifyHandler, resizing) {
+ let tags = [];
+ for (let i = 0, len = tagNames.length; i < len; i++) {
+ tags = tags.concat([].slice.call(this.context.element.wysiwyg.getElementsByTagName(tagNames[i])));
+ }
+
+ const context = this.context[pluginName];
+ const infoList = context._infoList;
+ const setFileInfo = this.plugins.fileManager.setInfo.bind(this);
+
+ if (tags.length === infoList.length) {
+ // reset
+ if (this._componentsInfoReset) {
+ for (let i = 0, len = tags.length; i < len; i++) {
+ setFileInfo(pluginName, tags[i], uploadEventHandler, null, resizing);
+ }
+ return ;
+ } else {
+ let infoUpdate = false;
+ for (let i = 0, len = infoList.length, info; i < len; i++) {
+ info = infoList[i];
+ if (tags.filter(function (t) { return info.src === t.src && info.index.toString() === t.getAttribute('data-index'); }).length === 0) {
+ infoUpdate = true;
+ break;
+ }
+ }
+ // pass
+ if (!infoUpdate) return;
+ }
+ }
+
+ // check
+ const _resize_plugin = resizing ? this.context.resizing._resize_plugin : '';
+ if (resizing) this.context.resizing._resize_plugin = pluginName;
+ const currentTags = [];
+ const infoIndex = [];
+ for (let i = 0, len = infoList.length; i < len; i++) {
+ infoIndex[i] = infoList[i].index;
+ }
+
+ for (let i = 0, len = tags.length, tag; i < len; i++) {
+ tag = tags[i];
+ if (!this.util.getParentElement(tag, this.util.isMediaComponent) || !/FIGURE/i.test(tag.parentElement.nodeName)) {
+ currentTags.push(context._infoIndex);
+ modifyHandler(tag);
+ } else if (!tag.getAttribute('data-index') || infoIndex.indexOf(tag.getAttribute('data-index') * 1) < 0) {
+ currentTags.push(context._infoIndex);
+ tag.removeAttribute('data-index');
+ setFileInfo(pluginName, tag, uploadEventHandler, null, resizing);
+ } else {
+ currentTags.push(tag.getAttribute('data-index') * 1);
+ }
+ }
+
+ for (let i = 0, dataIndex; i < infoList.length; i++) {
+ dataIndex = infoList[i].index;
+ if (currentTags.indexOf(dataIndex) > -1) continue;
+
+ infoList.splice(i, 1);
+ if (typeof uploadEventHandler === 'function') uploadEventHandler(null, dataIndex, 'delete', null, 0, this);
+ i--;
+ }
+
+ if (resizing) this.context.resizing._resize_plugin = _resize_plugin;
+ },
+
+ /**
+ * @description Create info object of file and add it to "_infoList" (this.context[pluginName]._infoList[])
+ * @param {String} pluginName Plugin name
+ * @param {Element} element
+ * @param {Function|null} uploadEventHandler Event handler to process updated file info (created in setInfo)
+ * @param {Object|null} file
+ * @param {Boolean} resizing True if the plugin is using a resizing module
+ * @example
+ * uploadCallBack {.. file = { name: fileList[i].name, size: fileList[i].size };
+ * this.plugins.fileManager.setInfo.call(this, 'image', oImg, this.functions.onImageUpload, file, true);
+ */
+ setInfo: function (pluginName, element, uploadEventHandler, file, resizing) {
+ const _resize_plugin = resizing ? this.context.resizing._resize_plugin : '';
+ if (resizing) this.context.resizing._resize_plugin = pluginName;
+
+ const plguin = this.plugins[pluginName];
+ const context = this.context[pluginName];
+ const infoList = context._infoList;
+ let dataIndex = element.getAttribute('data-index');
+ let info = null;
+ let state = '';
+
+ if (!file) {
+ file = {
+ 'name': element.getAttribute('data-file-name') || (typeof element.src === 'string' ? element.src.split('/').pop() : ''),
+ 'size': element.getAttribute('data-file-size') || 0
+ };
+ }
+
+ // create
+ if (!dataIndex || this._componentsInfoInit) {
+ state = 'create';
+ dataIndex = context._infoIndex++;
+
+ element.setAttribute('data-index', dataIndex);
+ element.setAttribute('data-file-name', file.name);
+ element.setAttribute('data-file-size', file.size);
+
+ info = {
+ src: element.src,
+ index: dataIndex * 1,
+ name: file.name,
+ size: file.size
+ };
+
+ infoList.push(info);
+ } else { // update
+ state = 'update';
+ dataIndex *= 1;
+
+ for (let i = 0, len = infoList.length; i < len; i++) {
+ if (dataIndex === infoList[i].index) {
+ info = infoList[i];
+ break;
+ }
+ }
+
+ if (!info) {
+ dataIndex = context._infoIndex++;
+ info = { index: dataIndex };
+ infoList.push(info);
+ }
+
+ info.src = element.src;
+ info.name = element.getAttribute("data-file-name");
+ info.size = element.getAttribute("data-file-size") * 1;
+ }
+
+ // method bind
+ info.element = element;
+ info.delete = plguin.destroy.bind(this, element);
+ info.select = function (element) {
+ element.scrollIntoView(true);
+ this._w.setTimeout(plguin.select.bind(this, element));
+ }.bind(this, element);
+
+ if (resizing) {
+ if (!element.getAttribute('origin-size') && element.naturalWidth) {
+ element.setAttribute('origin-size', element.naturalWidth + ',' + element.naturalHeight);
+ }
+
+ if (!element.getAttribute('data-origin')) {
+ const container = this.util.getParentElement(element, this.util.isMediaComponent);
+ const cover = this.util.getParentElement(element, 'FIGURE');
+
+ const w = this.plugins.resizing._module_getSizeX.call(this, context, element, cover, container);
+ const h = this.plugins.resizing._module_getSizeY.call(this, context, element, cover, container);
+ element.setAttribute('data-origin', w + ',' + h);
+ element.setAttribute('data-size', w + ',' + h);
+ }
+
+ if (!element.style.width) {
+ const size = (element.getAttribute('data-size') || element.getAttribute('data-origin') || '').split(',');
+ plguin.onModifyMode.call(this, element, null);
+ plguin.applySize.call(this, size[0], size[1]);
+ }
+
+ this.context.resizing._resize_plugin = _resize_plugin;
+ }
+
+ if (typeof uploadEventHandler === 'function') uploadEventHandler(element, dataIndex, state, info, --context._uploadFileLength < 0 ? 0 : context._uploadFileLength, this);
+ },
+
+ /**
+ * @description Delete info object at "_infoList"
+ * @param {String} pluginName Plugin name
+ * @param {Number} index index of info object (this.context[pluginName]._infoList[].index)
+ * @param {Function|null} uploadEventHandler Event handler to process updated file info (created in setInfo)
+ */
+ deleteInfo: function (pluginName, index, uploadEventHandler) {
+ if (index >= 0) {
+ const infoList = this.context[pluginName]._infoList;
+
+ for (let i = 0, len = infoList.length; i < len; i++) {
+ if (index === infoList[i].index) {
+ infoList.splice(i, 1);
+ if (typeof uploadEventHandler === 'function') uploadEventHandler(null, index, 'delete', null, 0, this);
+ return;
+ }
+ }
+ }
+ },
+
+ /**
+ * @description Reset info object and "_infoList = []", "_infoIndex = 0"
+ * @param {String} pluginName Plugin name
+ * @param {Function|null} uploadEventHandler Event handler to process updated file info (created in setInfo)
+ */
+ resetInfo: function (pluginName, uploadEventHandler) {
+ const context = this.context[pluginName];
+
+ if (typeof uploadEventHandler === 'function') {
+ const infoList = context._infoList;
+ for (let i = 0, len = infoList.length; i < len; i++) {
+ uploadEventHandler(null, infoList[i].index, 'delete', null, 0, this);
+ }
+ }
+
+ context._infoList = [];
+ context._infoIndex = 0;
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_MODULES) {
+ Object.defineProperty(window, 'SUNEDITOR_MODULES', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_MODULES, 'fileManager', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: fileManager
+ });
+ }
+
+ return fileManager;
+}));
\ No newline at end of file
--- /dev/null
+import { Module } from '../Module';
+
+import dialog from './dialog';
+import component from './component';
+import fileManager from './fileManager';
+import resizing from './resizing';
+
+declare const _modules: Module[];
+
+export { dialog, component, fileManager, resizing };
+export default _modules;
\ No newline at end of file
--- /dev/null
+'use strict';
+
+import dialog from './dialog';
+import component from './component';
+import fileManager from './fileManager';
+import resizing from './resizing';
+
+export { dialog, component, fileManager, resizing };
+export default { dialog, component, fileManager, resizing };
\ No newline at end of file
--- /dev/null
+import { Module } from '../Module';
+
+/**
+ * @description Require context properties when resizing module
+ inputX: Element,
+ inputY: Element,
+ _container: null,
+ _cover: null,
+ _element: null,
+ _element_w: 1,
+ _element_h: 1,
+ _element_l: 0,
+ _element_t: 0,
+ _defaultSizeX: 'auto',
+ _defaultSizeY: 'auto',
+ _origin_w: context.option.imageWidth === 'auto' ? '' : context.option.imageWidth,
+ _origin_h: context.option.imageHeight === 'auto' ? '' : context.option.imageHeight,
+ _proportionChecked: true,
+ // -- select function --
+ _resizing: context.option.imageResizing,
+ _resizeDotHide: !context.option.imageHeightShow,
+ _rotation: context.option.imageRotation,
+ _onlyPercentage: context.option.imageSizeOnlyPercentage,
+ _ratio: false,
+ _ratioX: 1,
+ _ratioY: 1
+ _captionShow: true,
+ // -- when used caption (_captionShow: true) --
+ _caption: null,
+ _captionChecked: false,
+ captionCheckEl: null
+*/
+declare interface resizing extends Module {
+ /**
+ * @description Gets the width size
+ * @param contextPlugin context object of plugin (core.context[plugin])
+ * @param element Target element [default: "this.plugin[plugin]._element"]
+ * @param cover Cover element (FIGURE) [default: "this.plugin[plugin]._cover"]
+ * @param container Container element (DIV.se-component) [default: "this.plugin[plugin]._container"]
+ * @returns
+ */
+ _module_getSizeX(contextPlugin: Object, element: Element, cover: Element, container: Element): string;
+
+ /**
+ * @description Gets the height size
+ * @param contextPlugin context object of plugin (core.context[plugin])
+ * @param element Target element [default: "this.plugin[plugin]._element"]
+ * @param cover Cover element (FIGURE) [default: "this.plugin[plugin]._cover"]
+ * @param container Container element (DIV.se-component) [default: "this.plugin[plugin]._container"]
+ * @returns
+ */
+ _module_getSizeY(contextPlugin: Object, element: Element, cover: Element, container: Element): string;
+
+ /**
+ * @description Called at the "openModify" to put the size of the current target into the size input element.
+ * @param contextPlugin context object of plugin (core.context[plugin])
+ * @param pluginObj Plugin object
+ */
+ _module_setModifyInputSize(contextPlugin: Object, pluginObj: Object): void;
+
+ /**
+ * @description It is called in "setInputSize" (input tag keyupEvent),
+ * checks the value entered in the input tag,
+ * calculates the ratio, and sets the calculated value in the input tag of the opposite size.
+ * @param contextPlugin context object of plugin (core.context[plugin])
+ * @param xy 'x': width, 'y': height
+ */
+ _module_setInputSize(contextPlugin: Object, xy: string): void;
+
+ /**
+ * @description It is called in "setRatio" (input and proportionCheck tags changeEvent),
+ * checks the value of the input tag, calculates the ratio, and resets it in the input tag.
+ * @param contextPlugin context object of plugin (core.context[plugin])
+ */
+ _module_setRatio(contextPlugin: Object): void;
+
+ /**
+ * @description Revert size of element to origin size (plugin._origin_w, plugin._origin_h)
+ * @param contextPlugin context object of plugin (core.context[plugin])
+ */
+ _module_sizeRevert(contextPlugin: Object): void;
+
+ /**
+ * @description Save the size data (element.setAttribute("data-size"))
+ * Used at the "setSize" method
+ * @param contextPlugin context object of plugin (core.context[plugin])
+ */
+ _module_saveCurrentSize(contextPlugin: Object): void;
+
+ /**
+ * @description Call the resizing module
+ * @param targetElement Resizing target element
+ * @param plugin Plugin name
+ * @returns Size of resizing div {w, h, t, l}
+ */
+ call_controller_resize(targetElement: Element, plugin: string): Record<string, number>;
+
+ /**
+ * @description Open align submenu of module
+ */
+ openAlignMenu(): void;
+
+ /**
+ * @description Click event of resizing toolbar
+ * Performs the action of the clicked toolbar button.
+ * @param e Event object
+ */
+ onClick_resizeButton(e: MouseEvent): void;
+
+ /**
+ * @description Initialize the transform style (rotation) of the element.
+ * @param element Target element
+ */
+ resetTransform(element: Element): void;
+
+ /**
+ * @description Set the transform style (rotation) of the element.
+ * @param element Target element
+ * @param width Element's width size
+ * @param height Element's height size
+ */
+ setTransformSize(element: Element, width?: number, height?:number): void;
+
+ /**
+ * @description The position of the caption is set automatically.
+ * @param element Target element (not caption element)
+ */
+ setCaptionPosition(element: Element): void;
+
+ /**
+ * @description Mouse down event of resize handles
+ * @param e Event object
+ */
+ onMouseDown_resize_handle(e: MouseEvent): void;
+
+ /**
+ * @description Mouse move event after call "onMouseDown_resize_handle" of resize handles
+ * The size of the module's "div" is adjusted according to the mouse move event.
+ * @param contextResizing "core.context.resizing" object (binding argument)
+ * @param direction Direction ("tl", "tr", "bl", "br", "lw", "th", "rw", "bh") (binding argument)
+ * @param plugin "core.context[currentPlugin]" object (binding argument)
+ * @param e Event object
+ */
+ resizing_element(contextResizing: Object, direction: string, plugin: Object, e: MouseEvent): void;
+
+ /**
+ * @description Resize the element to the size of the "div" adjusted in the "resizing_element" method.
+ * Called at the mouse-up event registered in "onMouseDown_resize_handle".
+ * @param direction Direction ("tl", "tr", "bl", "br", "lw", "th", "rw", "bh")
+ */
+ cancel_controller_resize(direction: string): void;
+}
+
+export default resizing;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+(function (global, factory) {
+ if (typeof module === 'object' && typeof module.exports === 'object') {
+ module.exports = global.document ?
+ factory(global, true) :
+ function (w) {
+ if (!w.document) {
+ throw new Error('SUNEDITOR_MODULES a window with a document');
+ }
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ }
+}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
+ const resizing = {
+ name: 'resizing',
+ /**
+ * @description Constructor
+ * Require context properties when resizing module
+ inputX: Element,
+ inputY: Element,
+ _container: null,
+ _cover: null,
+ _element: null,
+ _element_w: 1,
+ _element_h: 1,
+ _element_l: 0,
+ _element_t: 0,
+ _defaultSizeX: 'auto',
+ _defaultSizeY: 'auto',
+ _origin_w: context.option.imageWidth === 'auto' ? '' : context.option.imageWidth,
+ _origin_h: context.option.imageHeight === 'auto' ? '' : context.option.imageHeight,
+ _proportionChecked: true,
+ // -- select function --
+ _resizing: context.option.imageResizing,
+ _resizeDotHide: !context.option.imageHeightShow,
+ _rotation: context.option.imageRotation,
+ _onlyPercentage: context.option.imageSizeOnlyPercentage,
+ _ratio: false,
+ _ratioX: 1,
+ _ratioY: 1
+ _captionShow: true,
+ // -- when used caption (_captionShow: true) --
+ _caption: null,
+ _captionChecked: false,
+ captionCheckEl: null,
+ * @param {Object} core Core object
+ */
+ add: function (core) {
+ const icons = core.icons;
+ const context = core.context;
+ context.resizing = {
+ _resizeClientX: 0,
+ _resizeClientY: 0,
+ _resize_plugin: '',
+ _resize_w: 0,
+ _resize_h: 0,
+ _origin_w: 0,
+ _origin_h: 0,
+ _rotateVertical: false,
+ _resize_direction: '',
+ _move_path: null,
+ _isChange: false,
+ alignIcons: {
+ basic: icons.align_justify,
+ left: icons.align_left,
+ right: icons.align_right,
+ center: icons.align_center
+ }
+ };
+
+ /** resize controller, button */
+ let resize_div_container = this.setController_resize.call(core);
+ context.resizing.resizeContainer = resize_div_container;
+
+ context.resizing.resizeDiv = resize_div_container.querySelector('.se-modal-resize');
+ context.resizing.resizeDot = resize_div_container.querySelector('.se-resize-dot');
+ context.resizing.resizeDisplay = resize_div_container.querySelector('.se-resize-display');
+
+ let resize_button = this.setController_button.call(core);
+ context.resizing.resizeButton = resize_button;
+
+ let resize_handles = context.resizing.resizeHandles = context.resizing.resizeDot.querySelectorAll('span');
+ context.resizing.resizeButtonGroup = resize_button.querySelector('._se_resizing_btn_group');
+ context.resizing.rotationButtons = resize_button.querySelectorAll('._se_resizing_btn_group ._se_rotation');
+ context.resizing.percentageButtons = resize_button.querySelectorAll('._se_resizing_btn_group ._se_percentage');
+
+ context.resizing.alignMenu = resize_button.querySelector('.se-resizing-align-list');
+ context.resizing.alignMenuList = context.resizing.alignMenu.querySelectorAll('button');
+
+ context.resizing.alignButton = resize_button.querySelector('._se_resizing_align_button');
+ context.resizing.autoSizeButton = resize_button.querySelector('._se_resizing_btn_group ._se_auto_size');
+ context.resizing.captionButton = resize_button.querySelector('._se_resizing_caption_button');
+
+ /** add event listeners */
+ resize_div_container.addEventListener('mousedown', function (e) { e.preventDefault(); });
+ resize_button.addEventListener('mousedown', core.eventStop);
+ resize_handles[0].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core));
+ resize_handles[1].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core));
+ resize_handles[2].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core));
+ resize_handles[3].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core));
+ resize_handles[4].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core));
+ resize_handles[5].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core));
+ resize_handles[6].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core));
+ resize_handles[7].addEventListener('mousedown', this.onMouseDown_resize_handle.bind(core));
+ resize_button.addEventListener('click', this.onClick_resizeButton.bind(core));
+
+ /** append html */
+ context.element.relative.appendChild(resize_div_container);
+ context.element.relative.appendChild(resize_button);
+
+ /** empty memory */
+ resize_div_container = null, resize_button = null, resize_handles = null;
+ },
+
+ /** resize controller, button (image, iframe, video) */
+ setController_resize: function () {
+ const resize_container = this.util.createElement('DIV');
+
+ resize_container.className = 'se-controller se-resizing-container';
+ resize_container.style.display = 'none';
+ resize_container.innerHTML = '' +
+ '<div class="se-modal-resize"></div>' +
+ '<div class="se-resize-dot">' +
+ '<span class="tl"></span>' +
+ '<span class="tr"></span>' +
+ '<span class="bl"></span>' +
+ '<span class="br"></span>' +
+ '<span class="lw"></span>' +
+ '<span class="th"></span>' +
+ '<span class="rw"></span>' +
+ '<span class="bh"></span>' +
+ '<div class="se-resize-display"></div>' +
+ '</div>';
+
+ return resize_container;
+ },
+
+ setController_button: function () {
+ const lang = this.lang;
+ const icons = this.icons;
+ const resize_button = this.util.createElement("DIV");
+
+ resize_button.className = "se-controller se-controller-resizing";
+ resize_button.innerHTML = '' +
+ '<div class="se-arrow se-arrow-up"></div>' +
+ '<div class="se-btn-group _se_resizing_btn_group">' +
+ '<button type="button" data-command="percent" data-value="1" class="se-tooltip _se_percentage">' +
+ '<span>100%</span>' +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.resize100 + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="percent" data-value="0.75" class="se-tooltip _se_percentage">' +
+ '<span>75%</span>' +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.resize75 + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="percent" data-value="0.5" class="se-tooltip _se_percentage">' +
+ '<span>50%</span>' +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.resize50 + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="auto" class="se-btn se-tooltip _se_auto_size">' +
+ icons.auto_size +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.autoSize + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="rotate" data-value="-90" class="se-btn se-tooltip _se_rotation">' +
+ icons.rotate_left +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.rotateLeft + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="rotate" data-value="90" class="se-btn se-tooltip _se_rotation">' +
+ icons.rotate_right +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.rotateRight + '</span></span>' +
+ '</button>' +
+ '</div>' +
+ '<div class="se-btn-group" style="padding-top: 0;">' +
+ '<button type="button" data-command="mirror" data-value="h" class="se-btn se-tooltip">' +
+ icons.mirror_horizontal +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.mirrorHorizontal + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="mirror" data-value="v" class="se-btn se-tooltip">' +
+ icons.mirror_vertical +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.mirrorVertical + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="onalign" class="se-btn se-tooltip _se_resizing_align_button">' +
+ icons.align_justify +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.toolbar.align + '</span></span>' +
+ '</button>' +
+ '<div class="se-btn-group-sub sun-editor-common se-list-layer se-resizing-align-list">' +
+ '<div class="se-list-inner">' +
+ '<ul class="se-list-basic">' +
+ '<li><button type="button" class="se-btn-list se-tooltip" data-command="align" data-value="basic">' +
+ icons.align_justify +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.dialogBox.basic + '</span></span>' +
+ '</button></li>' +
+ '<li><button type="button" class="se-btn-list se-tooltip" data-command="align" data-value="left">' +
+ icons.align_left +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.dialogBox.left + '</span></span>' +
+ '</button></li>' +
+ '<li><button type="button" class="se-btn-list se-tooltip" data-command="align" data-value="center">' +
+ icons.align_center +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.dialogBox.center + '</span></span>' +
+ '</button></li>' +
+ '<li><button type="button" class="se-btn-list se-tooltip" data-command="align" data-value="right">' +
+ icons.align_right +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.dialogBox.right + '</span></span>' +
+ '</button></li>' +
+ '</ul>' +
+ '</div>' +
+ '</div>' +
+ '<button type="button" data-command="caption" class="se-btn se-tooltip _se_resizing_caption_button">' +
+ icons.caption +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.dialogBox.caption + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="revert" class="se-btn se-tooltip">' +
+ icons.revert +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.dialogBox.revertButton + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="update" class="se-btn se-tooltip">' +
+ icons.modify +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.edit + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="delete" class="se-btn se-tooltip">' +
+ icons.delete +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.remove + '</span></span>' +
+ '</button>' +
+ '</div>';
+
+ return resize_button;
+ },
+
+ /**
+ * @description Gets the width size
+ * @param {Object} contextPlugin context object of plugin (core.context[plugin])
+ * @param {Element} element Target element
+ * @param {Element} cover Cover element (FIGURE)
+ * @param {Element} container Container element (DIV.se-component)
+ * @returns {String}
+ */
+ _module_getSizeX: function (contextPlugin, element, cover, container) {
+ if (!element) element = contextPlugin._element;
+ if (!cover) cover = contextPlugin._cover;
+ if (!container) container = contextPlugin._container;
+
+ if (!element) return '';
+
+ return !/%$/.test(element.style.width) ? element.style.width : ((container && this.util.getNumber(container.style.width, 2)) || 100) + '%';
+ },
+
+ /**
+ * @description Gets the height size
+ * @param {Object} contextPlugin context object of plugin (core.context[plugin])
+ * @param {Element} element Target element
+ * @param {Element} cover Cover element (FIGURE)
+ * @param {Element} container Container element (DIV.se-component)
+ * @returns {String}
+ */
+ _module_getSizeY: function (contextPlugin, element, cover, container) {
+ if (!element) element = contextPlugin._element;
+ if (!cover) cover = contextPlugin._cover;
+ if (!container) container = contextPlugin._container;
+
+ if (!container || !cover) return (element && element.style.height) || '';
+
+ return this.util.getNumber(cover.style.paddingBottom, 0) > 0 && !this.context.resizing._rotateVertical ? cover.style.height : (!/%$/.test(element.style.height) || !/%$/.test(element.style.width) ? element.style.height : ((container && this.util.getNumber(container.style.height, 2)) || 100) + '%');
+ },
+
+ /**
+ * @description Called at the "openModify" to put the size of the current target into the size input element.
+ * @param {Object} contextPlugin context object of plugin (core.context[plugin])
+ * @param {Object} pluginObj Plugin object
+ */
+ _module_setModifyInputSize: function (contextPlugin, pluginObj) {
+ const percentageRotation = contextPlugin._onlyPercentage && this.context.resizing._rotateVertical;
+ contextPlugin.proportion.checked = contextPlugin._proportionChecked = contextPlugin._element.getAttribute('data-proportion') !== 'false';
+
+ let x = percentageRotation ? '' : this.plugins.resizing._module_getSizeX.call(this, contextPlugin);
+ if (x === contextPlugin._defaultSizeX) x = '';
+ if (contextPlugin._onlyPercentage) x = this.util.getNumber(x, 2);
+ contextPlugin.inputX.value = x;
+ pluginObj.setInputSize.call(this, 'x');
+
+ if (!contextPlugin._onlyPercentage) {
+ let y = percentageRotation ? '' : this.plugins.resizing._module_getSizeY.call(this, contextPlugin);
+ if (y === contextPlugin._defaultSizeY) y = '';
+ if (contextPlugin._onlyPercentage) y = this.util.getNumber(y, 2);
+ contextPlugin.inputY.value = y;
+ }
+
+ contextPlugin.inputX.disabled = percentageRotation ? true : false;
+ contextPlugin.inputY.disabled = percentageRotation ? true : false;
+ contextPlugin.proportion.disabled = percentageRotation ? true : false;
+
+ pluginObj.setRatio.call(this);
+ },
+
+ /**
+ * @description It is called in "setInputSize" (input tag keyupEvent),
+ * checks the value entered in the input tag,
+ * calculates the ratio, and sets the calculated value in the input tag of the opposite size.
+ * @param {Object} contextPlugin context object of plugin (core.context[plugin])
+ * @param {String} xy 'x': width, 'y': height
+ */
+ _module_setInputSize: function (contextPlugin, xy) {
+ if (contextPlugin._onlyPercentage) {
+ if (xy === 'x' && contextPlugin.inputX.value > 100) contextPlugin.inputX.value = 100;
+ return;
+ }
+
+ if (contextPlugin.proportion.checked && contextPlugin._ratio && /\d/.test(contextPlugin.inputX.value) && /\d/.test(contextPlugin.inputY.value)) {
+ const xUnit = contextPlugin.inputX.value.replace(/\d+|\./g, '') || contextPlugin.sizeUnit;
+ const yUnit = contextPlugin.inputY.value.replace(/\d+|\./g, '') || contextPlugin.sizeUnit;
+
+ if (xUnit !== yUnit) return;
+
+ const dec = xUnit === '%' ? 2 : 0;
+
+ if (xy === 'x') {
+ contextPlugin.inputY.value = this.util.getNumber(contextPlugin._ratioY * this.util.getNumber(contextPlugin.inputX.value, dec), dec) + yUnit;
+ } else {
+ contextPlugin.inputX.value = this.util.getNumber(contextPlugin._ratioX * this.util.getNumber(contextPlugin.inputY.value, dec), dec) + xUnit;
+ }
+ }
+ },
+
+ /**
+ * @description It is called in "setRatio" (input and proportionCheck tags changeEvent),
+ * checks the value of the input tag, calculates the ratio, and resets it in the input tag.
+ * @param {Object} contextPlugin context object of plugin (core.context[plugin])
+ */
+ _module_setRatio: function (contextPlugin) {
+ const xValue = contextPlugin.inputX.value;
+ const yValue = contextPlugin.inputY.value;
+
+ if (contextPlugin.proportion.checked && /\d+/.test(xValue) && /\d+/.test(yValue)) {
+ const xUnit = xValue.replace(/\d+|\./g, '') || contextPlugin.sizeUnit;
+ const yUnit = yValue.replace(/\d+|\./g, '') || contextPlugin.sizeUnit;
+
+ if (xUnit !== yUnit) {
+ contextPlugin._ratio = false;
+ } else if (!contextPlugin._ratio) {
+ const x = this.util.getNumber(xValue, 0);
+ const y = this.util.getNumber(yValue, 0);
+
+ contextPlugin._ratio = true;
+ contextPlugin._ratioX = x / y;
+ contextPlugin._ratioY = y / x;
+ }
+ } else {
+ contextPlugin._ratio = false;
+ }
+ },
+
+ /**
+ * @description Revert size of element to origin size (plugin._origin_w, plugin._origin_h)
+ * @param {Object} contextPlugin context object of plugin (core.context[plugin])
+ */
+ _module_sizeRevert: function (contextPlugin) {
+ if (contextPlugin._onlyPercentage) {
+ contextPlugin.inputX.value = contextPlugin._origin_w > 100 ? 100 : contextPlugin._origin_w;
+ } else {
+ contextPlugin.inputX.value = contextPlugin._origin_w;
+ contextPlugin.inputY.value = contextPlugin._origin_h;
+ }
+ },
+
+ /**
+ * @description Save the size data (element.setAttribute("data-size"))
+ * Used at the "setSize" method
+ * @param {Object} contextPlugin context object of plugin (core.context[plugin])
+ */
+ _module_saveCurrentSize: function (contextPlugin) {
+ const x = this.plugins.resizing._module_getSizeX.call(this, contextPlugin);
+ const y = this.plugins.resizing._module_getSizeY.call(this, contextPlugin);
+ contextPlugin._element.setAttribute('data-size', x + ',' + y);
+ if (!!contextPlugin._videoRatio) contextPlugin._videoRatio = y;
+ },
+
+ /**
+ * @description Call the resizing module
+ * @param {Element} targetElement Resizing target element
+ * @param {string} plugin Plugin name
+ * @returns {Object} Size of resizing div {w, h, t, l}
+ */
+ call_controller_resize: function (targetElement, plugin) {
+ const contextResizing = this.context.resizing;
+ const contextPlugin = this.context[plugin];
+ contextResizing._resize_plugin = plugin;
+
+ const resizeContainer = contextResizing.resizeContainer;
+ const resizeDiv = contextResizing.resizeDiv;
+ const offset = this.util.getOffset(targetElement, this.context.element.wysiwygFrame);
+
+ const isVertical = contextResizing._rotateVertical = /^(90|270)$/.test(Math.abs(targetElement.getAttribute('data-rotate')).toString());
+
+ const w = isVertical ? targetElement.offsetHeight : targetElement.offsetWidth;
+ const h = isVertical ? targetElement.offsetWidth : targetElement.offsetHeight;
+ const t = offset.top;
+ const l = offset.left - this.context.element.wysiwygFrame.scrollLeft;
+
+ resizeContainer.style.top = t + 'px';
+ resizeContainer.style.left = l + 'px';
+ resizeContainer.style.width = w + 'px';
+ resizeContainer.style.height = h + 'px';
+
+ resizeDiv.style.top = '0px';
+ resizeDiv.style.left = '0px';
+ resizeDiv.style.width = w + 'px';
+ resizeDiv.style.height = h + 'px';
+
+ let align = targetElement.getAttribute('data-align') || 'basic';
+ align = align === 'none' ? 'basic' : align;
+
+ // text
+ const container = this.util.getParentElement(targetElement, this.util.isComponent);
+ const cover = this.util.getParentElement(targetElement, 'FIGURE');
+ const displayX = this.plugins.resizing._module_getSizeX.call(this, contextPlugin, targetElement, cover, container) || 'auto';
+ const displayY = contextPlugin._onlyPercentage && plugin === 'image' ? '' : ', ' + (this.plugins.resizing._module_getSizeY.call(this, contextPlugin, targetElement, cover, container) || 'auto');
+ this.util.changeTxt(contextResizing.resizeDisplay, this.lang.dialogBox[align] + ' (' + displayX + displayY + ')');
+
+ // resizing display
+ contextResizing.resizeButtonGroup.style.display = contextPlugin._resizing ? '' : 'none';
+ const resizeDotShow = contextPlugin._resizing && !contextPlugin._resizeDotHide && !contextPlugin._onlyPercentage ? 'flex' : 'none';
+ const resizeHandles = contextResizing.resizeHandles;
+ for (let i = 0, len = resizeHandles.length; i < len; i++) {
+ resizeHandles[i].style.display = resizeDotShow;
+ }
+
+ if (contextPlugin._resizing) {
+ const rotations = contextResizing.rotationButtons;
+ rotations[0].style.display = rotations[1].style.display = contextPlugin._rotation ? '' : 'none';
+ }
+
+ // align icon
+ const alignList = contextResizing.alignMenuList;
+ this.util.changeElement(contextResizing.alignButton.firstElementChild, contextResizing.alignIcons[align]);
+ for (let i = 0, len = alignList.length; i < len; i++) {
+ if (alignList[i].getAttribute('data-value') === align) this.util.addClass(alignList[i], 'on');
+ else this.util.removeClass(alignList[i], 'on');
+ }
+
+ // percentage active
+ const pButtons = contextResizing.percentageButtons;
+ const value = /%$/.test(targetElement.style.width) && /%$/.test(container.style.width) ? (this.util.getNumber(container.style.width, 0) / 100) + '' : '' ;
+ for (let i = 0, len = pButtons.length; i < len; i++) {
+ if (pButtons[i].getAttribute('data-value') === value) {
+ this.util.addClass(pButtons[i], 'active');
+ } else {
+ this.util.removeClass(pButtons[i], 'active');
+ }
+ }
+
+ // caption display, active
+ if (!contextPlugin._captionShow) {
+ contextResizing.captionButton.style.display = 'none';
+ } else {
+ contextResizing.captionButton.style.display = '';
+ if (this.util.getChildElement(targetElement.parentNode, 'figcaption')) {
+ this.util.addClass(contextResizing.captionButton, 'active');
+ contextPlugin._captionChecked = true;
+ } else {
+ this.util.removeClass(contextResizing.captionButton, 'active');
+ contextPlugin._captionChecked = false;
+ }
+ }
+
+ if (this.currentControllerName !== plugin) {
+ this.util.setDisabledButtons(true, this.resizingDisabledButtons);
+ resizeContainer.style.display = 'block';
+
+ const addOffset = {left: 0, top: 50};
+ if (this.context.options.iframe) {
+ addOffset.left -= this.context.element.wysiwygFrame.parentElement.offsetLeft;
+ addOffset.top -= this.context.element.wysiwygFrame.parentElement.offsetTop;
+ }
+
+ this.setControllerPosition(contextResizing.resizeButton, resizeContainer, 'bottom', addOffset);
+ this.controllersOn(resizeContainer, contextResizing.resizeButton, this.util.setDisabledButtons.bind(this, false, this.resizingDisabledButtons), targetElement, plugin);
+ }
+
+ contextResizing._resize_w = w;
+ contextResizing._resize_h = h;
+
+ const originSize = (targetElement.getAttribute('origin-size') || '').split(',');
+ contextResizing._origin_w = originSize[0] || targetElement.naturalWidth;
+ contextResizing._origin_h = originSize[1] || targetElement.naturalHeight;
+
+ return {
+ w: w,
+ h: h,
+ t: t,
+ l: l
+ };
+ },
+
+ _closeAlignMenu: null,
+
+ /**
+ * @description Open align submenu of module
+ */
+ openAlignMenu: function () {
+ const alignButton = this.context.resizing.alignButton;
+ this.util.addClass(alignButton, 'on');
+ this.context.resizing.alignMenu.style.top = (alignButton.offsetTop + alignButton.offsetHeight) + 'px';
+ this.context.resizing.alignMenu.style.left = (alignButton.offsetLeft - alignButton.offsetWidth / 2) + 'px';
+ this.context.resizing.alignMenu.style.display = 'block';
+
+ this.plugins.resizing._closeAlignMenu = function () {
+ this.util.removeClass(this.context.resizing.alignButton, 'on');
+ this.context.resizing.alignMenu.style.display = 'none';
+ this.removeDocEvent('mousedown', this.plugins.resizing._closeAlignMenu);
+ this.plugins.resizing._closeAlignMenu = null;
+ }.bind(this);
+
+ this.addDocEvent('mousedown', this.plugins.resizing._closeAlignMenu);
+ },
+
+ /**
+ * @description Click event of resizing toolbar
+ * Performs the action of the clicked toolbar button.
+ * @param {MouseEvent} e Event object
+ */
+ onClick_resizeButton: function (e) {
+ e.stopPropagation();
+
+ const target = e.target;
+ const command = target.getAttribute('data-command') || target.parentNode.getAttribute('data-command');
+
+ if (!command) return;
+
+ const value = target.getAttribute('data-value') || target.parentNode.getAttribute('data-value');
+
+ const pluginName = this.context.resizing._resize_plugin;
+ const currentContext = this.context[pluginName];
+ const contextEl = currentContext._element;
+ const currentModule = this.plugins[pluginName];
+
+ e.preventDefault();
+
+ if (typeof this.plugins.resizing._closeAlignMenu === 'function') {
+ this.plugins.resizing._closeAlignMenu();
+ if (command === 'onalign') return;
+ }
+
+ switch (command) {
+ case 'auto':
+ this.plugins.resizing.resetTransform.call(this, contextEl);
+ currentModule.setAutoSize.call(this);
+ this.selectComponent(contextEl, pluginName);
+ break;
+ case 'percent':
+ let percentY = this.plugins.resizing._module_getSizeY.call(this, currentContext);
+ if (this.context.resizing._rotateVertical) {
+ const percentage = contextEl.getAttribute('data-percentage');
+ if (percentage) percentY = percentage.split(',')[1];
+ }
+
+ this.plugins.resizing.resetTransform.call(this, contextEl);
+ currentModule.setPercentSize.call(this, (value * 100), (this.util.getNumber(percentY, 0) === null || !/%$/.test(percentY)) ? '' : percentY);
+ this.selectComponent(contextEl, pluginName);
+ break;
+ case 'mirror':
+ const r = contextEl.getAttribute('data-rotate') || '0';
+ let x = contextEl.getAttribute('data-rotateX') || '';
+ let y = contextEl.getAttribute('data-rotateY') || '';
+
+ if ((value === 'h' && !this.context.resizing._rotateVertical) || (value === 'v' && this.context.resizing._rotateVertical)) {
+ y = y ? '' : '180';
+ } else {
+ x = x ? '' : '180';
+ }
+
+ contextEl.setAttribute('data-rotateX', x);
+ contextEl.setAttribute('data-rotateY', y);
+
+ this.plugins.resizing._setTransForm(contextEl, r, x, y);
+ break;
+ case 'rotate':
+ const contextResizing = this.context.resizing;
+ const slope = (contextEl.getAttribute('data-rotate') * 1) + (value * 1);
+ const deg = this._w.Math.abs(slope) >= 360 ? 0 : slope;
+
+ contextEl.setAttribute('data-rotate', deg);
+ contextResizing._rotateVertical = /^(90|270)$/.test(this._w.Math.abs(deg).toString());
+ this.plugins.resizing.setTransformSize.call(this, contextEl, null, null);
+
+ this.selectComponent(contextEl, pluginName);
+ break;
+ case 'onalign':
+ this.plugins.resizing.openAlignMenu.call(this);
+ return;
+ case 'align':
+ const alignValue = value === 'basic' ? 'none' : value;
+ currentModule.setAlign.call(this, alignValue, null, null, null);
+ this.selectComponent(contextEl, pluginName);
+ break;
+ case 'caption':
+ const caption = !currentContext._captionChecked;
+ currentModule.openModify.call(this, true);
+ currentContext._captionChecked = currentContext.captionCheckEl.checked = caption;
+
+ currentModule.update_image.call(this, false, false, false);
+
+ if (caption) {
+ const captionText = this.util.getChildElement(currentContext._caption, function (current) {
+ return current.nodeType === 3;
+ });
+
+ if (!captionText) {
+ currentContext._caption.focus();
+ } else {
+ this.setRange(captionText, 0, captionText, captionText.textContent.length);
+ }
+
+ this.controllersOff();
+ } else {
+ this.selectComponent(contextEl, pluginName);
+ currentModule.openModify.call(this, true);
+ }
+
+ break;
+ case 'revert':
+ currentModule.setOriginSize.call(this);
+ this.selectComponent(contextEl, pluginName);
+ break;
+ case 'update':
+ currentModule.openModify.call(this);
+ this.controllersOff();
+ break;
+ case 'delete':
+ currentModule.destroy.call(this);
+ break;
+ }
+
+ // history stack
+ this.history.push(false);
+ },
+
+ /**
+ * @description Initialize the transform style (rotation) of the element.
+ * @param {Element} element Target element
+ */
+ resetTransform: function (element) {
+ const size = (element.getAttribute('data-size') || element.getAttribute('data-origin') || '').split(',');
+ this.context.resizing._rotateVertical = false;
+
+ element.style.maxWidth = '';
+ element.style.transform = '';
+ element.style.transformOrigin = '';
+ element.setAttribute('data-rotate', '');
+ element.setAttribute('data-rotateX', '');
+ element.setAttribute('data-rotateY', '');
+
+ this.plugins[this.context.resizing._resize_plugin].setSize.call(this, size[0] ? size[0] : 'auto', size[1] ? size[1] : '', true);
+ },
+
+ /**
+ * @description Set the transform style (rotation) of the element.
+ * @param {Element} element Target element
+ * @param {Number|null} width Element's width size
+ * @param {Number|null} height Element's height size
+ */
+ setTransformSize: function (element, width, height) {
+ let percentage = element.getAttribute('data-percentage');
+ const isVertical = this.context.resizing._rotateVertical;
+ const deg = element.getAttribute('data-rotate') * 1;
+ let transOrigin = '';
+
+ if (percentage && !isVertical) {
+ percentage = percentage.split(',');
+ if (percentage[0] === 'auto' && percentage[1] === 'auto') {
+ this.plugins[this.context.resizing._resize_plugin].setAutoSize.call(this);
+ } else {
+ this.plugins[this.context.resizing._resize_plugin].setPercentSize.call(this, percentage[0], percentage[1]);
+ }
+ } else {
+ const cover = this.util.getParentElement(element, 'FIGURE');
+
+ const offsetW = width || element.offsetWidth;
+ const offsetH = height || element.offsetHeight;
+ const w = (isVertical ? offsetH : offsetW) + 'px';
+ const h = (isVertical ? offsetW : offsetH) + 'px';
+
+ this.plugins[this.context.resizing._resize_plugin].cancelPercentAttr.call(this);
+ this.plugins[this.context.resizing._resize_plugin].setSize.call(this, offsetW + 'px', offsetH + 'px', true);
+
+ cover.style.width = w;
+ cover.style.height = (!!this.context[this.context.resizing._resize_plugin]._caption ? '' : h);
+
+ if (isVertical) {
+ let transW = (offsetW/2) + 'px ' + (offsetW/2) + 'px 0';
+ let transH = (offsetH/2) + 'px ' + (offsetH/2) + 'px 0';
+ transOrigin = deg === 90 || deg === -270 ? transH : transW;
+ }
+ }
+
+ element.style.transformOrigin = transOrigin;
+ this.plugins.resizing._setTransForm(element, deg.toString(), element.getAttribute('data-rotateX') || '', element.getAttribute('data-rotateY') || '');
+
+ if (isVertical) element.style.maxWidth = 'none';
+ else element.style.maxWidth = '';
+
+ this.plugins.resizing.setCaptionPosition.call(this, element);
+ },
+
+ _setTransForm: function (element, r, x, y) {
+ let width = (element.offsetWidth - element.offsetHeight) * (/-/.test(r) ? 1 : -1);
+ let translate = '';
+
+ if (/[1-9]/.test(r) && (x || y)) {
+ translate = x ? 'Y' : 'X';
+
+ switch (r) {
+ case '90':
+ translate = x && y ? 'X' : y ? translate : '';
+ break;
+ case '270':
+ width *= -1;
+ translate = x && y ? 'Y' : x ? translate : '';
+ break;
+ case '-90':
+ translate = x && y ? 'Y' : x ? translate : '';
+ break;
+ case '-270':
+ width *= -1;
+ translate = x && y ? 'X' : y ? translate : '';
+ break;
+ default:
+ translate = '';
+ }
+ }
+
+ if (r % 180 === 0) {
+ element.style.maxWidth = '';
+ }
+
+ element.style.transform = 'rotate(' + r + 'deg)' + (x ? ' rotateX(' + x + 'deg)' : '') + (y ? ' rotateY(' + y + 'deg)' : '') + (translate ? ' translate' + translate + '(' + width + 'px)' : '');
+ },
+
+ /**
+ * @description The position of the caption is set automatically.
+ * @param {Element} element Target element (not caption element)
+ */
+ setCaptionPosition: function (element) {
+ const figcaption = this.util.getChildElement(this.util.getParentElement(element, 'FIGURE'), 'FIGCAPTION');
+ if (figcaption) {
+ figcaption.style.marginTop = (this.context.resizing._rotateVertical ? element.offsetWidth - element.offsetHeight : 0) + 'px';
+ }
+ },
+
+ /**
+ * @description Mouse down event of resize handles
+ * @param {MouseEvent} e Event object
+ */
+ onMouseDown_resize_handle: function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+
+ const contextResizing = this.context.resizing;
+ const direction = contextResizing._resize_direction = e.target.classList[0];
+
+ contextResizing._resizeClientX = e.clientX;
+ contextResizing._resizeClientY = e.clientY;
+ this.context.element.resizeBackground.style.display = 'block';
+ contextResizing.resizeButton.style.display = 'none';
+ contextResizing.resizeDiv.style.float = /l/.test(direction) ? 'right' : /r/.test(direction) ? 'left' : 'none';
+
+ const closureFunc_bind = function closureFunc(e) {
+ if (e.type === 'keydown' && e.keyCode !== 27) return;
+
+ const change = contextResizing._isChange;
+ contextResizing._isChange = false;
+
+ this.removeDocEvent('mousemove', resizing_element_bind);
+ this.removeDocEvent('mouseup', closureFunc_bind);
+ this.removeDocEvent('keydown', closureFunc_bind);
+
+ if (e.type === 'keydown') {
+ this.controllersOff();
+ this.context.element.resizeBackground.style.display = 'none';
+ this.plugins[this.context.resizing._resize_plugin].init.call(this);
+ } else {
+ // element resize
+ this.plugins.resizing.cancel_controller_resize.call(this, direction);
+ // history stack
+ if (change) this.history.push(false);
+ }
+ }.bind(this);
+
+ const resizing_element_bind = this.plugins.resizing.resizing_element.bind(this, contextResizing, direction, this.context[contextResizing._resize_plugin]);
+ this.addDocEvent('mousemove', resizing_element_bind);
+ this.addDocEvent('mouseup', closureFunc_bind);
+ this.addDocEvent('keydown', closureFunc_bind);
+ },
+
+ /**
+ * @description Mouse move event after call "onMouseDown_resize_handle" of resize handles
+ * The size of the module's "div" is adjusted according to the mouse move event.
+ * @param {Object} contextResizing "core.context.resizing" object (binding argument)
+ * @param {String} direction Direction ("tl", "tr", "bl", "br", "lw", "th", "rw", "bh") (binding argument)
+ * @param {Object} plugin "core.context[currentPlugin]" object (binding argument)
+ * @param {MouseEvent} e Event object
+ */
+ resizing_element: function (contextResizing, direction, plugin, e) {
+ const clientX = e.clientX;
+ const clientY = e.clientY;
+
+ let resultW = plugin._element_w;
+ let resultH = plugin._element_h;
+
+ const w = plugin._element_w + (/r/.test(direction) ? clientX - contextResizing._resizeClientX : contextResizing._resizeClientX - clientX);
+ const h = plugin._element_h + (/b/.test(direction) ? clientY - contextResizing._resizeClientY : contextResizing._resizeClientY - clientY);
+ const wh = ((plugin._element_h / plugin._element_w) * w);
+
+ if (/t/.test(direction)) contextResizing.resizeDiv.style.top = (plugin._element_h - (/h/.test(direction) ? h : wh)) + 'px';
+ if (/l/.test(direction)) contextResizing.resizeDiv.style.left = (plugin._element_w - w) + 'px';
+
+ if (/r|l/.test(direction)) {
+ contextResizing.resizeDiv.style.width = w + 'px';
+ resultW = w;
+ }
+
+ if (/^(t|b)[^h]$/.test(direction)) {
+ contextResizing.resizeDiv.style.height = wh + 'px';
+ resultH = wh;
+ }
+ else if (/^(t|b)h$/.test(direction)) {
+ contextResizing.resizeDiv.style.height = h + 'px';
+ resultH = h;
+ }
+
+ contextResizing._resize_w = resultW;
+ contextResizing._resize_h = resultH;
+ this.util.changeTxt(contextResizing.resizeDisplay, this._w.Math.round(resultW) + ' x ' + this._w.Math.round(resultH));
+ contextResizing._isChange = true;
+ },
+
+ /**
+ * @description Resize the element to the size of the "div" adjusted in the "resizing_element" method.
+ * Called at the mouse-up event registered in "onMouseDown_resize_handle".
+ * @param {String} direction Direction ("tl", "tr", "bl", "br", "lw", "th", "rw", "bh")
+ */
+ cancel_controller_resize: function (direction) {
+ const isVertical = this.context.resizing._rotateVertical;
+ this.controllersOff();
+ this.context.element.resizeBackground.style.display = 'none';
+
+ let w = this._w.Math.round(isVertical ? this.context.resizing._resize_h : this.context.resizing._resize_w);
+ let h = this._w.Math.round(isVertical ? this.context.resizing._resize_w : this.context.resizing._resize_h);
+
+ if (!isVertical && !/%$/.test(w)) {
+ const padding = 16;
+ const limit = this.context.element.wysiwygFrame.clientWidth - (padding * 2) - 2;
+
+ if (this.util.getNumber(w, 0) > limit) {
+ h = this._w.Math.round((h / w) * limit);
+ w = limit;
+ }
+ }
+
+ const pluginName = this.context.resizing._resize_plugin;
+ this.plugins[pluginName].setSize.call(this, w, h, false, direction);
+ this.selectComponent(this.context[pluginName]._element, pluginName);
+ }
+ };
+
+ if (typeof noGlobal === typeof undefined) {
+ if (!window.SUNEDITOR_MODULES) {
+ Object.defineProperty(window, 'SUNEDITOR_MODULES', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: {}
+ });
+ }
+
+ Object.defineProperty(window.SUNEDITOR_MODULES, 'resizing', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: resizing
+ });
+ }
+
+ return resizing;
+}));
\ No newline at end of file
--- /dev/null
+import { SubmenuPlugin } from '../SubmenuPlugin';
+
+declare const align: SubmenuPlugin;
+
+export default align;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ name: 'align',
+ display: 'submenu',
+ add: function (core, targetElement) {
+ const icons = core.icons;
+ const context = core.context;
+ context.align = {
+ targetButton: targetElement,
+ _alignList: null,
+ currentAlign: '',
+ defaultDir: context.options.rtl ? 'right' : 'left',
+ icons: {
+ justify: icons.align_justify,
+ left: icons.align_left,
+ right: icons.align_right,
+ center: icons.align_center
+ }
+ };
+
+ /** set submenu */
+ let listDiv = this.setSubmenu.call(core);
+ let listUl = listDiv.querySelector('ul');
+
+ /** add event listeners */
+ listUl.addEventListener('click', this.pickup.bind(core));
+ context.align._alignList = listUl.querySelectorAll('li button');
+
+ /** append target button menu */
+ core.initMenuTarget(this.name, targetElement, listDiv);
+
+ /** empty memory */
+ listDiv = null, listUl = null;
+ },
+
+ setSubmenu: function () {
+ const lang = this.lang;
+ const icons = this.icons;
+ const listDiv = this.util.createElement('DIV');
+ const leftDir = this.context.align.defaultDir === 'left';
+
+ const leftMenu = '<li>' +
+ '<button type="button" class="se-btn-list se-btn-align" data-command="justifyleft" data-value="left" title="' + lang.toolbar.alignLeft + '">' +
+ '<span class="se-list-icon">' + icons.align_left + '</span>' + lang.toolbar.alignLeft +
+ '</button>' +
+ '</li>';
+
+ const rightMenu = '<li>' +
+ '<button type="button" class="se-btn-list se-btn-align" data-command="justifyright" data-value="right" title="' + lang.toolbar.alignRight + '">' +
+ '<span class="se-list-icon">' + icons.align_right +'</span>' + lang.toolbar.alignRight +
+ '</button>' +
+ '</li>';
+
+ listDiv.className = 'se-submenu se-list-layer se-list-align';
+ listDiv.innerHTML = '' +
+ '<div class="se-list-inner">' +
+ '<ul class="se-list-basic">' +
+ (leftDir ? leftMenu : rightMenu) +
+ '<li>' +
+ '<button type="button" class="se-btn-list se-btn-align" data-command="justifycenter" data-value="center" title="' + lang.toolbar.alignCenter + '">' +
+ '<span class="se-list-icon">' + icons.align_center + '</span>' + lang.toolbar.alignCenter +
+ '</button>' +
+ '</li>' +
+ (leftDir? rightMenu : leftMenu) +
+ '<li>' +
+ '<button type="button" class="se-btn-list se-btn-align" data-command="justifyfull" data-value="justify" title="' + lang.toolbar.alignJustify + '">' +
+ '<span class="se-list-icon">' + icons.align_justify + '</span>' + lang.toolbar.alignJustify +
+ '</button>' +
+ '</li>' +
+ '</ul>' +
+ '</div>';
+
+ return listDiv;
+ },
+
+ /**
+ * @Override core
+ */
+ active: function (element) {
+ const alignContext = this.context.align;
+ const targetButton = alignContext.targetButton;
+ const target = targetButton.firstElementChild;
+
+ if (!element) {
+ this.util.changeElement(target, alignContext.icons[alignContext.defaultDir]);
+ targetButton.removeAttribute('data-focus');
+ } else if (this.util.isFormatElement(element)) {
+ const textAlign = element.style.textAlign;
+ if (textAlign) {
+ this.util.changeElement(target, alignContext.icons[textAlign]);
+ targetButton.setAttribute('data-focus', textAlign);
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ /**
+ * @Override submenu
+ */
+ on: function () {
+ const alignContext = this.context.align;
+ const alignList = alignContext._alignList;
+ const currentAlign = alignContext.targetButton.getAttribute('data-focus') || alignContext.defaultDir;
+
+ if (currentAlign !== alignContext.currentAlign) {
+ for (let i = 0, len = alignList.length; i < len; i++) {
+ if (currentAlign === alignList[i].getAttribute('data-value')) {
+ this.util.addClass(alignList[i], 'active');
+ } else {
+ this.util.removeClass(alignList[i], 'active');
+ }
+ }
+
+ alignContext.currentAlign = currentAlign;
+ }
+ },
+
+ pickup: function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ let target = e.target;
+ let value = null;
+
+ while (!value && !/UL/i.test(target.tagName)) {
+ value = target.getAttribute('data-value');
+ target = target.parentNode;
+ }
+
+ if (!value) return;
+
+ const defaultDir = this.context.align.defaultDir;
+ const selectedFormsts = this.getSelectedElements();
+ for (let i = 0, len = selectedFormsts.length; i < len; i++) {
+ this.util.setStyle(selectedFormsts[i], 'textAlign', (value === defaultDir ? '' : value));
+ }
+
+ this.effectNode = null;
+ this.submenuOff();
+ this.focus();
+
+ // history stack
+ this.history.push(false);
+ }
+};
--- /dev/null
+import { SubmenuPlugin } from '../SubmenuPlugin';
+
+declare const font: SubmenuPlugin;
+
+export default font;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ name: 'font',
+ display: 'submenu',
+ add: function (core, targetElement) {
+ const context = core.context;
+ context.font = {
+ targetText: targetElement.querySelector('.txt'),
+ targetTooltip: targetElement.parentNode.querySelector('.se-tooltip-text'),
+ _fontList: null,
+ currentFont: ''
+ };
+
+ /** set submenu */
+ let listDiv = this.setSubmenu.call(core);
+
+ /** add event listeners */
+ listDiv.querySelector('.se-list-inner').addEventListener('click', this.pickup.bind(core));
+
+ context.font._fontList = listDiv.querySelectorAll('ul li button');
+
+ /** append target button menu */
+ core.initMenuTarget(this.name, targetElement, listDiv);
+
+ /** empty memory */
+ listDiv = null;
+ },
+
+ setSubmenu: function () {
+ const option = this.context.option;
+ const lang = this.lang;
+ const listDiv = this.util.createElement('DIV');
+
+ listDiv.className = 'se-submenu se-list-layer se-list-font-family';
+
+ let font, text, i, len;
+ let fontList = !option.font ?
+ [
+ 'Arial',
+ 'Comic Sans MS',
+ 'Courier New',
+ 'Impact',
+ 'Georgia',
+ 'tahoma',
+ 'Trebuchet MS',
+ 'Verdana'
+ ] : option.font;
+
+ let list = '<div class="se-list-inner">' +
+ '<ul class="se-list-basic">' +
+ '<li><button type="button" class="default_value se-btn-list" title="' + lang.toolbar.default + '">(' + lang.toolbar.default + ')</button></li>';
+ for (i = 0, len = fontList.length; i < len; i++) {
+ font = fontList[i];
+ text = font.split(',')[0];
+ list += '<li><button type="button" class="se-btn-list" data-value="' + font + '" data-txt="' + text + '" title="' + text + '" style="font-family:' + font + ';">' + text + '</button></li>';
+ }
+ list += '</ul></div>';
+ listDiv.innerHTML = list;
+
+ return listDiv;
+ },
+
+ /**
+ * @Override core
+ */
+ active: function (element) {
+ const target = this.context.font.targetText;
+ const tooltip = this.context.font.targetTooltip;
+
+ if (!element) {
+ const font = this.lang.toolbar.font;
+ this.util.changeTxt(target, font);
+ this.util.changeTxt(tooltip, font);
+ } else if (element.style && element.style.fontFamily.length > 0) {
+ const selectFont = element.style.fontFamily.replace(/["']/g,'');
+ this.util.changeTxt(target, selectFont);
+ this.util.changeTxt(tooltip, selectFont);
+ return true;
+ }
+
+ return false;
+ },
+
+ /**
+ * @Override submenu
+ */
+ on: function () {
+ const fontContext = this.context.font;
+ const fontList = fontContext._fontList;
+ const currentFont = fontContext.targetText.textContent;
+
+ if (currentFont !== fontContext.currentFont) {
+ for (let i = 0, len = fontList.length; i < len; i++) {
+ if (currentFont === fontList[i].getAttribute('data-value')) {
+ this.util.addClass(fontList[i], 'active');
+ } else {
+ this.util.removeClass(fontList[i], 'active');
+ }
+ }
+
+ fontContext.currentFont = currentFont;
+ }
+ },
+
+ pickup: function (e) {
+ if (!/^BUTTON$/i.test(e.target.tagName)) return false;
+
+ e.preventDefault();
+ e.stopPropagation();
+
+ const value = e.target.getAttribute('data-value');
+
+ if (value) {
+ const newNode = this.util.createElement('SPAN');
+ newNode.style.fontFamily = value;
+ this.nodeChange(newNode, ['font-family'], null, null);
+ } else {
+ this.nodeChange(null, ['font-family'], ['span'], true);
+ }
+
+ this.submenuOff();
+ }
+};
--- /dev/null
+import { SubmenuPlugin } from '../SubmenuPlugin';
+
+declare const fontColor: SubmenuPlugin;
+
+export default fontColor;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+import colorPicker from '../modules/_colorPicker';
+
+export default {
+ name: 'fontColor',
+ display: 'submenu',
+ add: function (core, targetElement) {
+ core.addModule([colorPicker]);
+
+ const context = core.context;
+ context.fontColor = {
+ previewEl: null,
+ colorInput: null,
+ colorList: null
+ };
+
+ /** set submenu */
+ let listDiv = this.setSubmenu.call(core);
+ context.fontColor.colorInput = listDiv.querySelector('._se_color_picker_input');
+
+ /** add event listeners */
+ context.fontColor.colorInput.addEventListener('keyup', this.onChangeInput.bind(core));
+ listDiv.querySelector('._se_color_picker_submit').addEventListener('click', this.submit.bind(core));
+ listDiv.querySelector('._se_color_picker_remove').addEventListener('click', this.remove.bind(core));
+ listDiv.addEventListener('click', this.pickup.bind(core));
+ context.fontColor.colorList = listDiv.querySelectorAll('li button');
+
+ /** append target button menu */
+ core.initMenuTarget(this.name, targetElement, listDiv);
+
+ /** empty memory */
+ listDiv = null;
+ },
+
+ setSubmenu: function () {
+ const colorArea = this.context.colorPicker.colorListHTML;
+ const listDiv = this.util.createElement('DIV');
+
+ listDiv.className = 'se-submenu se-list-layer';
+ listDiv.innerHTML = colorArea;
+
+ return listDiv;
+ },
+
+ /**
+ * @Override submenu
+ */
+ on: function () {
+ const contextPicker = this.context.colorPicker;
+ const contextFontColor = this.context.fontColor;
+
+ contextPicker._colorInput = contextFontColor.colorInput;
+ contextPicker._defaultColor = '#333333';
+ contextPicker._styleProperty = 'color';
+ contextPicker._colorList = contextFontColor.colorList;
+
+ this.plugins.colorPicker.init.call(this, this.getSelectionNode(), null);
+ },
+
+ /**
+ * @Override _colorPicker
+ */
+ onChangeInput: function (e) {
+ this.plugins.colorPicker.setCurrentColor.call(this, e.target.value);
+ },
+
+ submit: function () {
+ this.plugins.fontColor.applyColor.call(this, this.context.colorPicker._currentColor);
+ },
+
+ pickup: function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ this.plugins.fontColor.applyColor.call(this, e.target.getAttribute('data-value'));
+ },
+
+ remove: function () {
+ this.nodeChange(null, ['color'], ['span'], true);
+ this.submenuOff();
+ },
+
+ applyColor: function (color) {
+ if (!color) return;
+
+ const newNode = this.util.createElement('SPAN');
+ newNode.style.color = color;
+ this.nodeChange(newNode, ['color'], null, null);
+
+ this.submenuOff();
+ }
+};
--- /dev/null
+import { SubmenuPlugin } from '../SubmenuPlugin';
+
+declare const fontSize: SubmenuPlugin;
+
+export default fontSize;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ name: 'fontSize',
+ display: 'submenu',
+ add: function (core, targetElement) {
+ const context = core.context;
+ context.fontSize = {
+ targetText: targetElement.querySelector('.txt'),
+ _sizeList: null,
+ currentSize: ''
+ };
+
+ /** set submenu */
+ let listDiv = this.setSubmenu.call(core);
+ let listUl = listDiv.querySelector('ul');
+
+ /** add event listeners */
+ listUl.addEventListener('click', this.pickup.bind(core));
+ context.fontSize._sizeList = listUl.querySelectorAll('li button');
+
+ /** append target button menu */
+ core.initMenuTarget(this.name, targetElement, listDiv);
+
+ /** empty memory */
+ listDiv = null, listUl = null;
+ },
+
+ setSubmenu: function () {
+ const option = this.context.option;
+ const lang = this.lang;
+ const listDiv = this.util.createElement('DIV');
+
+ listDiv.className = 'se-submenu se-list-layer se-list-font-size';
+
+ const sizeList = !option.fontSize ? [8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72] : option.fontSize;
+
+ let list = '<div class="se-list-inner">' +
+ '<ul class="se-list-basic">' +
+ '<li><button type="button" class="default_value se-btn-list" title="' + lang.toolbar.default + '">(' + lang.toolbar.default + ')</button></li>';
+ for (let i = 0, unit = option.fontSizeUnit, len = sizeList.length, size; i < len; i++) {
+ size = sizeList[i];
+ list += '<li><button type="button" class="se-btn-list" data-value="' + size + unit + '" title="' + size + unit + '" style="font-size:' + size + unit + ';">' + size + '</button></li>';
+ }
+ list += '</ul></div>';
+
+ listDiv.innerHTML = list;
+
+ return listDiv;
+ },
+
+ /**
+ * @Override core
+ */
+ active: function (element) {
+ if (!element) {
+ this.util.changeTxt(this.context.fontSize.targetText, this.lang.toolbar.fontSize);
+ } else if (element.style && element.style.fontSize.length > 0) {
+ this.util.changeTxt(this.context.fontSize.targetText, element.style.fontSize);
+ return true;
+ }
+
+ return false;
+ },
+
+ /**
+ * @Override submenu
+ */
+ on: function () {
+ const fontSizeContext = this.context.fontSize;
+ const sizeList = fontSizeContext._sizeList;
+ const currentSize = fontSizeContext.targetText.textContent;
+
+ if (currentSize !== fontSizeContext.currentSize) {
+ for (let i = 0, len = sizeList.length; i < len; i++) {
+ if (currentSize === sizeList[i].getAttribute('data-value')) {
+ this.util.addClass(sizeList[i], 'active');
+ } else {
+ this.util.removeClass(sizeList[i], 'active');
+ }
+ }
+
+ fontSizeContext.currentSize = currentSize;
+ }
+ },
+
+ pickup: function (e) {
+ if (!/^BUTTON$/i.test(e.target.tagName)) return false;
+
+ e.preventDefault();
+ e.stopPropagation();
+
+ const value = e.target.getAttribute('data-value');
+
+ if (value) {
+ const newNode = this.util.createElement('SPAN');
+ newNode.style.fontSize = value;
+ this.nodeChange(newNode, ['font-size'], null, null);
+ } else {
+ this.nodeChange(null, ['font-size'], ['span'], true);
+ }
+
+ this.submenuOff();
+ }
+};
--- /dev/null
+import { SubmenuPlugin } from '../SubmenuPlugin';
+
+declare const formatBlock: SubmenuPlugin;
+
+export default formatBlock;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ name: 'formatBlock',
+ display: 'submenu',
+ add: function (core, targetElement) {
+ const context = core.context;
+ context.formatBlock = {
+ targetText: targetElement.querySelector('.txt'),
+ targetTooltip: targetElement.parentNode.querySelector('.se-tooltip-text'),
+ _formatList: null,
+ currentFormat: ''
+ };
+
+ /** set submenu */
+ let listDiv = this.setSubmenu.call(core);
+
+ /** add event listeners */
+ listDiv.querySelector('ul').addEventListener('click', this.pickUp.bind(core));
+ context.formatBlock._formatList = listDiv.querySelectorAll('li button');
+
+ /** append target button menu */
+ core.initMenuTarget(this.name, targetElement, listDiv);
+
+ /** empty memory */
+ listDiv = null;
+ },
+
+ setSubmenu: function () {
+ const option = this.context.option;
+ const lang_toolbar = this.lang.toolbar;
+ const listDiv = this.util.createElement('DIV');
+ listDiv.className = 'se-submenu se-list-layer se-list-format';
+
+ const defaultFormats = ['p', 'div', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
+ const formatList = !option.formats || option.formats.length === 0 ? defaultFormats : option.formats;
+
+ let list = '<div class="se-list-inner"><ul class="se-list-basic">';
+ for (let i = 0, len = formatList.length, format, tagName, command, name, h, attrs, className; i < len; i++) {
+ format = formatList[i];
+
+ if (typeof format === 'string' && defaultFormats.indexOf(format) > -1) {
+ tagName = format.toLowerCase();
+ command = tagName === 'blockquote' ? 'range' : tagName === 'pre' ? 'free' : 'replace';
+ h = /^h/.test(tagName) ? tagName.match(/\d+/)[0] : '';
+ name = lang_toolbar['tag_' + (h ? 'h' : tagName)] + h;
+ className = '';
+ attrs = '';
+ } else {
+ tagName = format.tag.toLowerCase();
+ command = format.command;
+ name = format.name || tagName;
+ className = format.class;
+ attrs = className ? ' class="' + className + '"' : '';
+ }
+
+ list += '<li>' +
+ '<button type="button" class="se-btn-list" data-command="' + command + '" data-value="' + tagName + '" data-class="' + className + '" title="' + name + '">' +
+ '<' + tagName + attrs + '>' + name + '</' + tagName + '>' +
+ '</button></li>';
+ }
+ list += '</ul></div>';
+
+ listDiv.innerHTML = list;
+
+ return listDiv;
+ },
+
+ /**
+ * @Override core
+ */
+ active: function (element) {
+ let formatTitle = this.lang.toolbar.formats;
+ const target = this.context.formatBlock.targetText;
+ const tooltip = this.context.formatBlock.targetTooltip;
+
+ if (!element) {
+ this.util.changeTxt(target, formatTitle);
+ this.util.changeTxt(tooltip, formatTitle);
+ } else if (this.util.isFormatElement(element)) {
+ const formatContext = this.context.formatBlock;
+ const formatList = formatContext._formatList;
+ const nodeName = element.nodeName.toLowerCase();
+ const className = (element.className.match(/(\s|^)__se__format__[^\s]+/) || [''])[0].trim();
+
+ for (let i = 0, len = formatList.length, f; i < len; i++) {
+ f = formatList[i];
+ if (nodeName === f.getAttribute('data-value') && className === f.getAttribute('data-class')) {
+ formatTitle = f.title;
+ break;
+ }
+ }
+
+ this.util.changeTxt(target, formatTitle);
+ this.util.changeTxt(tooltip, formatTitle);
+ target.setAttribute('data-value', nodeName);
+ target.setAttribute('data-class', className);
+
+ return true;
+ }
+
+ return false;
+ },
+
+ /**
+ * @Override submenu
+ */
+ on: function () {
+ const formatContext = this.context.formatBlock;
+ const formatList = formatContext._formatList;
+ const target = formatContext.targetText;
+ const currentFormat = (target.getAttribute('data-value') || '') + (target.getAttribute('data-class') || '');
+
+ if (currentFormat !== formatContext.currentFormat) {
+ for (let i = 0, len = formatList.length, f; i < len; i++) {
+ f = formatList[i];
+ if (currentFormat === f.getAttribute('data-value') + f.getAttribute('data-class')) {
+ this.util.addClass(f, 'active');
+ } else {
+ this.util.removeClass(f, 'active');
+ }
+ }
+
+ formatContext.currentFormat = currentFormat;
+ }
+ },
+
+ pickUp: function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ let target = e.target;
+ let command = null, value = null, tag = null, className = '';
+
+ while (!command && !/UL/i.test(target.tagName)) {
+ command = target.getAttribute('data-command');
+ value = target.getAttribute('data-value');
+ className = target.getAttribute('data-class');
+ if (command) {
+ tag = target.firstChild;
+ break;
+ }
+ target = target.parentNode;
+ }
+
+ if (!command) return;
+
+ // blockquote
+ if (command === 'range') {
+ const rangeElement = tag.cloneNode(false);
+ this.applyRangeFormatElement(rangeElement);
+ }
+ // free, replace
+ else {
+ let range = this.getRange();
+ let selectedFormsts = this.getSelectedElementsAndComponents(false);
+
+ if (selectedFormsts.length === 0) {
+ range = this.getRange_addLine(range, null);
+ selectedFormsts = this.getSelectedElementsAndComponents(false);
+ if (selectedFormsts.length === 0) return;
+ }
+
+ const startOffset = range.startOffset;
+ const endOffset = range.endOffset;
+
+ const util = this.util;
+ let first = selectedFormsts[0];
+ let last = selectedFormsts[selectedFormsts.length - 1];
+ const firstPath = util.getNodePath(range.startContainer, first, null, null);
+ const lastPath = util.getNodePath(range.endContainer, last, null, null);
+
+ // remove selected list
+ const rlist = this.detachList(selectedFormsts, false);
+ if (rlist.sc) first = rlist.sc;
+ if (rlist.ec) last = rlist.ec;
+
+ // change format tag
+ this.setRange(util.getNodeFromPath(firstPath, first), startOffset, util.getNodeFromPath(lastPath, last), endOffset);
+ const modifiedFormsts = this.getSelectedElementsAndComponents(false);
+
+ // free format
+ if (command === 'free') {
+ const len = modifiedFormsts.length - 1;
+ let parentNode = modifiedFormsts[len].parentNode;
+ let freeElement = tag.cloneNode(false);
+ const focusElement = freeElement;
+
+ for (let i = len, f, html, before, next, inner, isComp, first = true; i >= 0; i--) {
+ f = modifiedFormsts[i];
+ if (f === (!modifiedFormsts[i + 1] ? null : modifiedFormsts[i + 1].parentNode)) continue;
+
+ isComp = util.isComponent(f);
+ html = isComp ? '' : f.innerHTML.replace(/(?!>)\s+(?=<)|\n/g, ' ');
+ before = util.getParentElement(f, function (current) {
+ return current.parentNode === parentNode;
+ });
+
+ if (parentNode !== f.parentNode || isComp) {
+ if (util.isFormatElement(parentNode)) {
+ parentNode.parentNode.insertBefore(freeElement, parentNode.nextSibling);
+ parentNode = parentNode.parentNode;
+ } else {
+ parentNode.insertBefore(freeElement, before ? before.nextSibling : null);
+ parentNode = f.parentNode;
+ }
+
+ next = freeElement.nextSibling;
+ if (next && freeElement.nodeName === next.nodeName && util.isSameAttributes(freeElement, next)) {
+ freeElement.innerHTML += '<BR>' + next.innerHTML;
+ util.removeItem(next);
+ }
+
+ freeElement = tag.cloneNode(false);
+ first = true;
+ }
+
+ inner = freeElement.innerHTML;
+ freeElement.innerHTML = ((first || !html || !inner || /<br>$/i.test(html)) ? html : html + '<BR>') + inner;
+
+ if (i === 0) {
+ parentNode.insertBefore(freeElement, f);
+ next = f.nextSibling;
+ if (next && freeElement.nodeName === next.nodeName && util.isSameAttributes(freeElement, next)) {
+ freeElement.innerHTML += '<BR>' + next.innerHTML;
+ util.removeItem(next);
+ }
+
+ const prev = freeElement.previousSibling;
+ if (prev && freeElement.nodeName === prev.nodeName && util.isSameAttributes(freeElement, prev)) {
+ prev.innerHTML += '<BR>' + freeElement.innerHTML;
+ util.removeItem(freeElement);
+ }
+ }
+
+ if (!isComp) util.removeItem(f);
+ if (!!html) first = false;
+ }
+
+ this.setRange(focusElement, 0, focusElement, 0);
+ }
+ // replace format
+ else {
+ for (let i = 0, len = modifiedFormsts.length, node, newFormat; i < len; i++) {
+ node = modifiedFormsts[i];
+
+ if ((node.nodeName.toLowerCase() !== value.toLowerCase() || (node.className.match(/(\s|^)__se__format__[^\s]+/) || [''])[0].trim() !== className) && !util.isComponent(node)) {
+ newFormat = tag.cloneNode(false);
+ util.copyFormatAttributes(newFormat, node);
+ newFormat.innerHTML = node.innerHTML;
+
+ node.parentNode.replaceChild(newFormat, node);
+ }
+
+ if (i === 0) first = newFormat || node;
+ if (i === len - 1) last = newFormat || node;
+ newFormat = null;
+ }
+
+ this.setRange(util.getNodeFromPath(firstPath, first), startOffset, util.getNodeFromPath(lastPath, last), endOffset);
+ }
+
+ // history stack
+ this.history.push(false);
+ }
+
+ this.submenuOff();
+ }
+};
--- /dev/null
+import { SubmenuPlugin } from '../SubmenuPlugin';
+
+declare const hiliteColor: SubmenuPlugin;
+
+export default hiliteColor;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+import colorPicker from '../modules/_colorPicker';
+
+export default {
+ name: 'hiliteColor',
+ display: 'submenu',
+ add: function (core, targetElement) {
+ core.addModule([colorPicker]);
+
+ const context = core.context;
+ context.hiliteColor = {
+ previewEl: null,
+ colorInput: null,
+ colorList: null
+ };
+
+ /** set submenu */
+ let listDiv = this.setSubmenu.call(core);
+ context.hiliteColor.colorInput = listDiv.querySelector('._se_color_picker_input');
+
+ /** add event listeners */
+ context.hiliteColor.colorInput.addEventListener('keyup', this.onChangeInput.bind(core));
+ listDiv.querySelector('._se_color_picker_submit').addEventListener('click', this.submit.bind(core));
+ listDiv.querySelector('._se_color_picker_remove').addEventListener('click', this.remove.bind(core));
+ listDiv.addEventListener('click', this.pickup.bind(core));
+
+ context.hiliteColor.colorList = listDiv.querySelectorAll('li button');
+
+ /** append target button menu */
+ core.initMenuTarget(this.name, targetElement, listDiv);
+
+ /** empty memory */
+ listDiv = null;
+ },
+
+ setSubmenu: function () {
+ const colorArea = this.context.colorPicker.colorListHTML;
+ const listDiv = this.util.createElement('DIV');
+
+ listDiv.className = 'se-submenu se-list-layer';
+ listDiv.innerHTML = colorArea;
+
+ return listDiv;
+ },
+
+ /**
+ * @Override submenu
+ */
+ on: function () {
+ const contextPicker = this.context.colorPicker;
+ const contextHiliteColor = this.context.hiliteColor;
+
+ contextPicker._colorInput = contextHiliteColor.colorInput;
+ contextPicker._defaultColor = '#FFFFFF';
+ contextPicker._styleProperty = 'backgroundColor';
+ contextPicker._colorList = contextHiliteColor.colorList;
+
+ this.plugins.colorPicker.init.call(this, this.getSelectionNode(), null);
+ },
+
+ /**
+ * @Override _colorPicker
+ */
+ onChangeInput: function (e) {
+ this.plugins.colorPicker.setCurrentColor.call(this, e.target.value);
+ },
+
+ submit: function () {
+ this.plugins.hiliteColor.applyColor.call(this, this.context.colorPicker._currentColor);
+ },
+
+ pickup: function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ this.plugins.hiliteColor.applyColor.call(this, e.target.getAttribute('data-value'));
+ },
+
+ remove: function () {
+ this.nodeChange(null, ['background-color'], ['span'], true);
+ this.submenuOff();
+ },
+
+ applyColor: function (color) {
+ if (!color) return;
+
+ const newNode = this.util.createElement('SPAN');
+ newNode.style.backgroundColor = color;
+ this.nodeChange(newNode, ['background-color'], null, null);
+
+ this.submenuOff();
+ }
+};
--- /dev/null
+import { SubmenuPlugin } from '../SubmenuPlugin';
+
+declare const horizontalRule: SubmenuPlugin;
+
+export default horizontalRule;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ name: 'horizontalRule',
+ display: 'submenu',
+ add: function (core, targetElement) {
+ /** set submenu */
+ let listDiv = this.setSubmenu.call(core);
+
+ /** add event listeners */
+ listDiv.querySelector('ul').addEventListener('click', this.horizontalRulePick.bind(core));
+
+ /** append target button menu */
+ core.initMenuTarget(this.name, targetElement, listDiv);
+
+ /** empty memory */
+ listDiv = null;
+ },
+
+ setSubmenu: function () {
+ const lang = this.lang;
+ const listDiv = this.util.createElement('DIV');
+
+ listDiv.className = 'se-submenu se-list-layer se-list-line';
+ listDiv.innerHTML = '' +
+ '<div class="se-list-inner">' +
+ '<ul class="se-list-basic">' +
+ '<li>' +
+ '<button type="button" class="se-btn-list btn_line" data-command="horizontalRule" data-value="solid" title="' + lang.toolbar.hr_solid + '">' +
+ '<hr style="border-width: 1px 0 0; border-style: solid none none; border-color: black; border-image: initial; height: 1px;" />' +
+ '</button>' +
+ '</li>' +
+ '<li>' +
+ '<button type="button" class="se-btn-list btn_line" data-command="horizontalRule" data-value="dotted" title="' + lang.toolbar.hr_dotted + '">' +
+ '<hr style="border-width: 1px 0 0; border-style: dotted none none; border-color: black; border-image: initial; height: 1px;" />' +
+ '</button>' +
+ '</li>' +
+ '<li>' +
+ '<button type="button" class="se-btn-list btn_line" data-command="horizontalRule" data-value="dashed" title="' + lang.toolbar.hr_dashed + '">' +
+ '<hr style="border-width: 1px 0 0; border-style: dashed none none; border-color: black; border-image: initial; height: 1px;" />' +
+ '</button>' +
+ '</li>' +
+ '</ul>' +
+ '</div>';
+
+ return listDiv;
+ },
+
+ appendHr: function (className) {
+ const oHr = this.util.createElement('HR');
+ oHr.className = className;
+ this.focus();
+ return this.insertComponent(oHr, false, true, false);
+ },
+
+ horizontalRulePick: function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ let target = e.target;
+ let value = null;
+
+ while (!value && !/UL/i.test(target.tagName)) {
+ value = target.getAttribute('data-value');
+ target = target.parentNode;
+ }
+
+ if (!value) return;
+
+ const oNode = this.plugins.horizontalRule.appendHr.call(this, '__se__' + value);
+ if (oNode) {
+ this.setRange(oNode, 0, oNode, 0);
+ this.submenuOff();
+ }
+ }
+};
--- /dev/null
+import { SubmenuPlugin } from '../SubmenuPlugin';
+
+declare const lineHeight: SubmenuPlugin;
+
+export default lineHeight;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 20197 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ name: 'lineHeight',
+ display: 'submenu',
+ add: function (core, targetElement) {
+ const context = core.context;
+ context.lineHeight = {
+ _sizeList: null,
+ currentSize: -1
+ };
+
+ /** set submenu */
+ let listDiv = this.setSubmenu.call(core);
+ let listUl = listDiv.querySelector('ul');
+
+ /** add event listeners */
+ listUl.addEventListener('click', this.pickup.bind(core));
+
+ context.lineHeight._sizeList = listUl.querySelectorAll('li button');
+
+ /** append target button menu */
+ core.initMenuTarget(this.name, targetElement, listDiv);
+
+ /** empty memory */
+ listDiv = null, listUl = null;
+ },
+
+ setSubmenu: function () {
+ const option = this.context.option;
+ const lang = this.lang;
+ const listDiv = this.util.createElement('DIV');
+
+ listDiv.className = 'se-submenu se-list-layer';
+
+ const sizeList = !option.lineHeights ? [
+ {text: '1', value: 1},
+ {text: '1.15', value: 1.15},
+ {text: '1.5', value: 1.5},
+ {text: '2', value: 2}
+ ] : option.lineHeights;
+
+ let list = '<div class="se-list-inner">' +
+ '<ul class="se-list-basic">' +
+ '<li><button type="button" class="default_value se-btn-list" title="' + lang.toolbar.default + '">(' + lang.toolbar.default + ')</button></li>';
+ for (let i = 0, len = sizeList.length, text, size; i < len; i++) {
+ size = sizeList[i];
+ list += '<li><button type="button" class="se-btn-list" data-value="' + size.value + '" title="' + size.text + '">' + size.text + '</button></li>';
+ }
+ list += '</ul></div>';
+
+ listDiv.innerHTML = list;
+
+ return listDiv;
+ },
+
+ /**
+ * @Override submenu
+ */
+ on: function () {
+ const lineHeightContext = this.context.lineHeight;
+ const sizeList = lineHeightContext._sizeList;
+ const format = this.util.getFormatElement(this.getSelectionNode());
+ const currentSize = !format ? '' : format.style.lineHeight + '';
+
+ if (currentSize !== lineHeightContext.currentSize) {
+ for (let i = 0, len = sizeList.length; i < len; i++) {
+ if (currentSize === sizeList[i].getAttribute('data-value')) {
+ this.util.addClass(sizeList[i], 'active');
+ } else {
+ this.util.removeClass(sizeList[i], 'active');
+ }
+ }
+
+ lineHeightContext.currentSize = currentSize;
+ }
+ },
+
+ pickup: function (e) {
+ if (!/^BUTTON$/i.test(e.target.tagName)) return false;
+
+ e.preventDefault();
+ e.stopPropagation();
+
+ const value = e.target.getAttribute('data-value') || '';
+ const formats = this.getSelectedElements();
+
+ for (let i = 0, len = formats.length; i < len; i++) {
+ formats[i].style.lineHeight = value;
+ }
+
+ this.submenuOff();
+
+ // history stack
+ this.history.push(false);
+ }
+};
--- /dev/null
+import { SubmenuPlugin } from '../SubmenuPlugin';
+
+declare const list: SubmenuPlugin;
+
+export default list;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ name: 'list',
+ display: 'submenu',
+ add: function (core, targetElement) {
+ const context = core.context;
+ context.list = {
+ targetButton: targetElement,
+ _list: null,
+ currentList: '',
+ icons: {
+ bullets: core.icons.list_bullets,
+ number: core.icons.list_number
+ }
+ };
+
+ /** set submenu */
+ let listDiv = this.setSubmenu.call(core);
+ let listUl = listDiv.querySelector('ul');
+
+ /** add event listeners */
+ listUl.addEventListener('click', this.pickup.bind(core));
+ context.list._list = listUl.querySelectorAll('li button');
+
+ /** append target button menu */
+ core.initMenuTarget(this.name, targetElement, listDiv);
+
+ /** empty memory */
+ listDiv = null, listUl = null;
+ },
+
+ setSubmenu: function () {
+ const lang = this.lang;
+ const listDiv = this.util.createElement('DIV');
+
+ listDiv.className = 'se-submenu se-list-layer';
+ listDiv.innerHTML = '' +
+ '<div class="se-list-inner">' +
+ '<ul class="se-list-basic">' +
+ '<li><button type="button" class="se-btn-list se-tooltip" data-command="OL" title="' + lang.toolbar.orderList + '">' +
+ this.icons.list_number +
+ '</button></li>' +
+ '<li><button type="button" class="se-btn-list se-tooltip" data-command="UL" title="' + lang.toolbar.unorderList + '">' +
+ this.icons.list_bullets +
+ '</button></li>' +
+ '</ul>' +
+ '</div>';
+
+ return listDiv;
+ },
+
+ /**
+ * @Override core
+ */
+ active: function (element) {
+ const button = this.context.list.targetButton;
+ const icon = button.firstElementChild;
+ const util = this.util;
+
+ if (!element) {
+ button.removeAttribute('data-focus');
+ util.changeElement(icon, this.context.list.icons.number);
+ util.removeClass(button, 'active');
+ } else if (util.isList(element)) {
+ const nodeName = element.nodeName;
+ button.setAttribute('data-focus', nodeName);
+ util.addClass(button, 'active');
+ if (/UL/i.test(nodeName)) {
+ util.changeElement(icon, this.context.list.icons.bullets);
+ } else {
+ util.changeElement(icon, this.context.list.icons.number);
+ }
+
+ return true;
+ }
+
+ return false;
+ },
+
+ /**
+ * @Override submenu
+ */
+ on: function () {
+ const listContext = this.context.list;
+ const list = listContext._list;
+ const currentList = listContext.targetButton.getAttribute('data-focus') || '';
+
+ if (currentList !== listContext.currentList) {
+ for (let i = 0, len = list.length; i < len; i++) {
+ if (currentList === list[i].getAttribute('data-command')) {
+ this.util.addClass(list[i], 'active');
+ } else {
+ this.util.removeClass(list[i], 'active');
+ }
+ }
+
+ listContext.currentList = currentList;
+ }
+ },
+
+ editList: function (command, selectedCells, detach) {
+ let range = this.getRange();
+ let selectedFormats = !selectedCells ? this.getSelectedElementsAndComponents(false) : selectedCells;
+
+ if (selectedFormats.length === 0) {
+ if (selectedCells) return;
+ range = this.getRange_addLine(range, null);
+ selectedFormats = this.getSelectedElementsAndComponents(false);
+ if (selectedFormats.length === 0) return;
+ }
+
+ const util = this.util;
+ util.sortByDepth(selectedFormats, true);
+
+ // merge
+ let firstSel = selectedFormats[0];
+ let lastSel = selectedFormats[selectedFormats.length - 1];
+ let topEl = (util.isListCell(firstSel) || util.isComponent(firstSel)) && !firstSel.previousElementSibling ? firstSel.parentNode.previousElementSibling : firstSel.previousElementSibling;
+ let bottomEl = (util.isListCell(lastSel) || util.isComponent(lastSel)) && !lastSel.nextElementSibling ? lastSel.parentNode.nextElementSibling : lastSel.nextElementSibling;
+
+ const originRange = {
+ sc: range.startContainer,
+ so: range.startOffset,
+ ec: range.endContainer,
+ eo: range.endOffset
+ };
+
+ let isRemove = true;
+
+ for (let i = 0, len = selectedFormats.length; i < len; i++) {
+ if (!util.isList(util.getRangeFormatElement(selectedFormats[i], function (current) {
+ return this.getRangeFormatElement(current) && current !== selectedFormats[i];
+ }.bind(util)))) {
+ isRemove = false;
+ break;
+ }
+ }
+
+ if (isRemove && (!topEl || (firstSel.tagName !== topEl.tagName || command !== topEl.tagName.toUpperCase())) && (!bottomEl || (lastSel.tagName !== bottomEl.tagName || command !== bottomEl.tagName.toUpperCase()))) {
+ if (detach) {
+ for (let i = 0, len = selectedFormats.length; i < len; i++) {
+ for (let j = i - 1; j >= 0; j--) {
+ if (selectedFormats[j].contains(selectedFormats[i])) {
+ selectedFormats.splice(i, 1);
+ i--; len--;
+ break;
+ }
+ }
+ }
+ }
+
+ const currentFormat = util.getRangeFormatElement(firstSel);
+ const cancel = currentFormat && currentFormat.tagName === command;
+ let rangeArr, tempList;
+ const passComponent = function (current) {
+ return !this.isComponent(current);
+ }.bind(util);
+
+ if (!cancel) tempList = util.createElement(command);
+
+ for (let i = 0, len = selectedFormats.length, r, o; i < len; i++) {
+ o = util.getRangeFormatElement(selectedFormats[i], passComponent);
+ if (!o || !util.isList(o)) continue;
+
+ if (!r) {
+ r = o;
+ rangeArr = {r: r, f: [util.getParentElement(selectedFormats[i], 'LI')]};
+ } else {
+ if (r !== o) {
+ if (detach && util.isListCell(o.parentNode)) {
+ this.plugins.list._detachNested.call(this, rangeArr.f);
+ } else {
+ this.detachRangeFormatElement(rangeArr.f[0].parentNode, rangeArr.f, tempList, false, true);
+ }
+
+ o = selectedFormats[i].parentNode;
+ if (!cancel) tempList = util.createElement(command);
+
+ r = o;
+ rangeArr = {r: r, f: [util.getParentElement(selectedFormats[i], 'LI')]};
+ } else {
+ rangeArr.f.push(util.getParentElement(selectedFormats[i], 'LI'));
+ }
+ }
+
+ if (i === len - 1) {
+ if (detach && util.isListCell(o.parentNode)) {
+ this.plugins.list._detachNested.call(this, rangeArr.f);
+ } else {
+ this.detachRangeFormatElement(rangeArr.f[0].parentNode, rangeArr.f, tempList, false, true);
+ }
+ }
+ }
+ } else {
+ const topElParent = topEl ? topEl.parentNode : topEl;
+ const bottomElParent = bottomEl ? bottomEl.parentNode : bottomEl;
+ topEl = topElParent && !util.isWysiwygDiv(topElParent) && topElParent.nodeName === command ? topElParent : topEl;
+ bottomEl = bottomElParent && !util.isWysiwygDiv(bottomElParent) && bottomElParent.nodeName === command ? bottomElParent : bottomEl;
+
+ const mergeTop = topEl && topEl.tagName === command;
+ const mergeBottom = bottomEl && bottomEl.tagName === command;
+
+ let list = mergeTop ? topEl : util.createElement(command);
+ let firstList = null;
+ let lastList = null;
+ let topNumber = null;
+ let bottomNumber = null;
+
+ const passComponent = function (current) {
+ return !this.isComponent(current) && !this.isList(current);
+ }.bind(util);
+
+ for (let i = 0, len = selectedFormats.length, newCell, fTag, isCell, next, originParent, nextParent, parentTag, siblingTag, rangeTag; i < len; i++) {
+ fTag = selectedFormats[i];
+ if (fTag.childNodes.length === 0 && !util._isIgnoreNodeChange(fTag)) {
+ util.removeItem(fTag);
+ continue;
+ }
+ next = selectedFormats[i + 1];
+ originParent = fTag.parentNode;
+ nextParent = next ? next.parentNode : null;
+ isCell = util.isListCell(fTag);
+ rangeTag = util.isRangeFormatElement(originParent) ? originParent : null;
+ parentTag = isCell && !util.isWysiwygDiv(originParent) ? originParent.parentNode : originParent;
+ siblingTag = isCell && !util.isWysiwygDiv(originParent) ? (!next || util.isListCell(parentTag)) ? originParent : originParent.nextSibling : fTag.nextSibling;
+
+ newCell = util.createElement('LI');
+ util.copyFormatAttributes(newCell, fTag);
+ if (util.isComponent(fTag)) {
+ const isHR = /^HR$/i.test(fTag.nodeName);
+ if (!isHR) newCell.innerHTML = '<br>';
+ newCell.innerHTML += fTag.outerHTML;
+ if (isHR) newCell.innerHTML += '<br>';
+ } else {
+ const fChildren = fTag.childNodes;
+ while (fChildren[0]) {
+ newCell.appendChild(fChildren[0]);
+ }
+ }
+ list.appendChild(newCell);
+
+ if (!next) lastList = list;
+ if (!next || parentTag !== nextParent || util.isRangeFormatElement(siblingTag)) {
+ if (!firstList) firstList = list;
+ if ((!mergeTop || !next || parentTag !== nextParent) && !(next && util.isList(nextParent) && nextParent === originParent)) {
+ if (list.parentNode !== parentTag) parentTag.insertBefore(list, siblingTag);
+ }
+ }
+
+ util.removeItem(fTag);
+ if (mergeTop && topNumber === null) topNumber = list.children.length - 1;
+ if (next && (util.getRangeFormatElement(nextParent, passComponent) !== util.getRangeFormatElement(originParent, passComponent) || (util.isList(nextParent) && util.isList(originParent) && util.getElementDepth(nextParent) !== util.getElementDepth(originParent)))) {
+ list = util.createElement(command);
+ }
+
+ if (rangeTag && rangeTag.children.length === 0) util.removeItem(rangeTag);
+ }
+
+ if (topNumber) {
+ firstList = firstList.children[topNumber];
+ }
+
+ if (mergeBottom) {
+ bottomNumber = list.children.length - 1;
+ list.innerHTML += bottomEl.innerHTML;
+ lastList = list.children[bottomNumber];
+ util.removeItem(bottomEl);
+ }
+ }
+
+ this.effectNode = null;
+ return originRange;
+ },
+
+ _detachNested: function (cells) {
+ const first = cells[0];
+ const last = cells[cells.length - 1];
+ const next = last.nextElementSibling;
+ const originList = first.parentNode;
+ const sibling = originList.parentNode.nextElementSibling;
+ const parentNode = originList.parentNode.parentNode;
+
+ for (let c = 0, cLen = cells.length; c < cLen; c++) {
+ parentNode.insertBefore(cells[c], sibling);
+ }
+
+ if (next && originList.children.length > 0) {
+ const newList = originList.cloneNode(false);
+ const children = originList.childNodes;
+ const index = this.util.getPositionIndex(next);
+ while (children[index]) {
+ newList.appendChild(children[index]);
+ }
+ last.appendChild(newList);
+ }
+
+ if (originList.children.length === 0) this.util.removeItem(originList);
+ this.util.mergeSameTags(parentNode);
+
+ const edge = this.util.getEdgeChildNodes(first, last);
+
+ return {
+ cc: first.parentNode,
+ sc: edge.sc,
+ ec: edge.ec
+ };
+ },
+
+ editInsideList: function (remove, selectedCells) {
+ selectedCells = !selectedCells ? this.getSelectedElements().filter(function (el) { return this.isListCell(el); }.bind(this.util)) : selectedCells;
+ const cellsLen = selectedCells.length;
+ if (cellsLen === 0 || (!remove && (!this.util.isListCell(selectedCells[0].previousElementSibling) && !this.util.isListCell(selectedCells[cellsLen - 1].nextElementSibling)))) {
+ return {
+ sc: selectedCells[0],
+ so: 0,
+ ec: selectedCells[cellsLen - 1],
+ eo: 1
+ };
+ }
+
+ let originList = selectedCells[0].parentNode;
+ let lastCell = selectedCells[cellsLen - 1];
+ let range = null;
+
+ if (remove) {
+ if (originList !== lastCell.parentNode && this.util.isList(lastCell.parentNode.parentNode) && lastCell.nextElementSibling) {
+ lastCell = lastCell.nextElementSibling;
+ while (lastCell) {
+ selectedCells.push(lastCell);
+ lastCell = lastCell.nextElementSibling;
+ }
+ }
+ range = this.plugins.list.editList.call(this, originList.nodeName.toUpperCase(), selectedCells, true);
+ } else {
+ let innerList = this.util.createElement(originList.nodeName);
+ let prev = selectedCells[0].previousElementSibling;
+ let next = lastCell.nextElementSibling;
+ const nodePath = { s: null, e: null, sl: originList, el: originList };
+
+ for (let i = 0, len = cellsLen, c; i < len; i++) {
+ c = selectedCells[i];
+ if (c.parentNode !== originList) {
+ this.plugins.list._insiedList.call(this, originList, innerList, prev, next, nodePath);
+ originList = c.parentNode;
+ innerList = this.util.createElement(originList.nodeName);
+ }
+
+ prev = c.previousElementSibling;
+ next = c.nextElementSibling;
+ innerList.appendChild(c);
+ }
+
+ this.plugins.list._insiedList.call(this, originList, innerList, prev, next, nodePath);
+
+ const sc = this.util.getNodeFromPath(nodePath.s, nodePath.sl);
+ const ec = this.util.getNodeFromPath(nodePath.e, nodePath.el);
+ range = {
+ sc: sc,
+ so: 0,
+ ec: ec,
+ eo: ec.textContent.length
+ };
+ }
+
+ return range;
+ },
+
+ _insiedList: function (originList, innerList, prev, next, nodePath) {
+ let insertPrev = false;
+
+ if (prev && innerList.tagName === prev.tagName) {
+ const children = innerList.children;
+ while (children[0]) {
+ prev.appendChild(children[0]);
+ }
+
+ innerList = prev;
+ insertPrev = true;
+ }
+
+ if (next && innerList.tagName === next.tagName) {
+ const children = next.children;
+ while (children[0]) {
+ innerList.appendChild(children[0]);
+ }
+
+ const temp = next.nextElementSibling;
+ next.parentNode.removeChild(next);
+ next = temp;
+ }
+
+ if (!insertPrev) {
+ if (this.util.isListCell(prev)) {
+ originList = prev;
+ next = null;
+ }
+
+ originList.insertBefore(innerList, next);
+
+ if (!nodePath.s) {
+ nodePath.s = this.util.getNodePath(innerList.firstElementChild.firstChild, originList, null);
+ nodePath.sl = originList;
+ }
+
+ const slPath = originList.contains(nodePath.sl) ? this.util.getNodePath(nodePath.sl, originList) : null;
+ nodePath.e = this.util.getNodePath(innerList.lastElementChild.firstChild, originList, null);
+ nodePath.el = originList;
+
+ this.util.mergeSameTags(originList, [nodePath.s, nodePath.e, slPath], false);
+ this.util.mergeNestedTags(originList);
+ if (slPath) nodePath.sl = this.util.getNodeFromPath(slPath, originList);
+ }
+
+ return innerList;
+ },
+
+ pickup: function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ let target = e.target;
+ let command = '';
+
+ while (!command && !/^UL$/i.test(target.tagName)) {
+ command = target.getAttribute('data-command');
+ target = target.parentNode;
+ }
+
+ if (!command) return;
+
+ const range = this.plugins.list.editList.call(this, command, null, false);
+ if (range) this.setRange(range.sc, range.so, range.ec, range.eo);
+
+ this.submenuOff();
+
+ // history stack
+ this.history.push(false);
+ }
+};
--- /dev/null
+import { SubmenuPlugin } from '../SubmenuPlugin';
+
+declare const paragraphStyle: SubmenuPlugin;
+
+export default paragraphStyle;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ name: 'paragraphStyle',
+ display: 'submenu',
+ add: function (core, targetElement) {
+ const context = core.context;
+ context.paragraphStyle = {
+ _classList: null
+ };
+
+ /** set submenu */
+ let listDiv = this.setSubmenu.call(core);
+
+ /** add event listeners */
+ listDiv.querySelector('ul').addEventListener('click', this.pickUp.bind(core));
+
+ context.paragraphStyle._classList = listDiv.querySelectorAll('li button');
+
+ /** append target button menu */
+ core.initMenuTarget(this.name, targetElement, listDiv);
+
+ /** empty memory */
+ listDiv = null;
+ },
+
+ setSubmenu: function () {
+ const option = this.context.option;
+ const listDiv = this.util.createElement('DIV');
+ listDiv.className = 'se-submenu se-list-layer se-list-format';
+
+ const menuLang = this.lang.menu;
+ const defaultList = {
+ spaced: {
+ name: menuLang.spaced,
+ class: '__se__p-spaced',
+ _class: ''
+ },
+ bordered: {
+ name: menuLang.bordered,
+ class: '__se__p-bordered',
+ _class: ''
+ },
+ neon: {
+ name: menuLang.neon,
+ class: '__se__p-neon',
+ _class: ''
+ }
+ };
+ const paragraphStyles = !option.paragraphStyles || option.paragraphStyles.length === 0 ? ['spaced', 'bordered', 'neon'] : option.paragraphStyles;
+
+ let list = '<div class="se-list-inner"><ul class="se-list-basic">';
+ for (let i = 0, len = paragraphStyles.length, p, name, attrs, _class; i < len; i++) {
+ p = paragraphStyles[i];
+
+ if (typeof p === 'string') {
+ const defaultStyle = defaultList[p.toLowerCase()];
+ if (!defaultStyle) continue;
+ p = defaultStyle;
+ }
+
+ name = p.name;
+ attrs = p.class ? ' class="' + p.class + '"' : '';
+ _class = p._class;
+
+ list += '<li>' +
+ '<button type="button" class="se-btn-list' + (_class ? ' ' + _class: '') + '" data-value="' + p.class + '" title="' + name + '">' +
+ '<div' + attrs + '>' + name + '</div>' +
+ '</button></li>';
+ }
+ list += '</ul></div>';
+
+ listDiv.innerHTML = list;
+
+ return listDiv;
+ },
+
+ /**
+ * @Override submenu
+ */
+ on: function () {
+ const paragraphContext = this.context.paragraphStyle;
+ const paragraphList = paragraphContext._classList;
+ const currentFormat = this.util.getFormatElement(this.getSelectionNode());
+
+ for (let i = 0, len = paragraphList.length; i < len; i++) {
+ if (this.util.hasClass(currentFormat, paragraphList[i].getAttribute('data-value'))) {
+ this.util.addClass(paragraphList[i], 'active');
+ } else {
+ this.util.removeClass(paragraphList[i], 'active');
+ }
+ }
+ },
+
+ pickUp: function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ let target = e.target;
+ let value = null;
+
+ while (!/^UL$/i.test(target.tagName)) {
+ value = target.getAttribute('data-value');
+ if (value) break;
+ target = target.parentNode;
+ }
+
+ if (!value) return;
+
+ let selectedFormsts = this.getSelectedElements();
+ if (selectedFormsts.length === 0) {
+ this.getRange_addLine(this.getRange(), null);
+ selectedFormsts = this.getSelectedElements();
+ if (selectedFormsts.length === 0) return;
+ }
+
+ // change format class
+ const toggleClass = this.util.hasClass(target, 'active') ? this.util.removeClass.bind(this.util) : this.util.addClass.bind(this.util);
+ for (let i = 0, len = selectedFormsts.length; i < len; i++) {
+ toggleClass(selectedFormsts[i], value);
+ }
+
+ this.submenuOff();
+
+ // history stack
+ this.history.push(false);
+ }
+};
--- /dev/null
+import { SubmenuPlugin } from '../SubmenuPlugin';
+
+declare const table: SubmenuPlugin;
+
+export default table;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ name: 'table',
+ display: 'submenu',
+ add: function (core, targetElement) {
+ const context = core.context;
+ let contextTable = context.table = {
+ _element: null,
+ _tdElement: null,
+ _trElement: null,
+ _trElements: null,
+ _tableXY: [],
+ _maxWidth: true,
+ _fixedColumn: false,
+ _rtl: context.options.rtl,
+ cellControllerTop: context.options.tableCellControllerPosition === 'top',
+ resizeText: null,
+ headerButton: null,
+ mergeButton: null,
+ splitButton: null,
+ splitMenu: null,
+ maxText: core.lang.controller.maxSize,
+ minText: core.lang.controller.minSize,
+ _physical_cellCnt: 0,
+ _logical_cellCnt: 0,
+ _rowCnt: 0,
+ _rowIndex: 0,
+ _physical_cellIndex: 0,
+ _logical_cellIndex: 0,
+ _current_colSpan: 0,
+ _current_rowSpan: 0,
+ icons: {
+ expansion: core.icons.expansion,
+ reduction: core.icons.reduction
+ }
+ };
+
+ /** set submenu */
+ let listDiv = this.setSubmenu.call(core);
+ let tablePicker = listDiv.querySelector('.se-controller-table-picker');
+
+ contextTable.tableHighlight = listDiv.querySelector('.se-table-size-highlighted');
+ contextTable.tableUnHighlight = listDiv.querySelector('.se-table-size-unhighlighted');
+ contextTable.tableDisplay = listDiv.querySelector('.se-table-size-display');
+ if (context.options.rtl) contextTable.tableHighlight.style.left = (10 * 18 - 13) + 'px';
+
+ /** set table controller */
+ let tableController = this.setController_table.call(core);
+ contextTable.tableController = tableController;
+ contextTable.resizeButton = tableController.querySelector('._se_table_resize');
+ contextTable.resizeText = tableController.querySelector('._se_table_resize > span > span');
+ contextTable.columnFixedButton = tableController.querySelector('._se_table_fixed_column');
+ contextTable.headerButton = tableController.querySelector('._se_table_header');
+ tableController.addEventListener('mousedown', core.eventStop);
+
+ /** set resizing */
+ let resizeDiv = this.setController_tableEditor.call(core, contextTable.cellControllerTop);
+ contextTable.resizeDiv = resizeDiv;
+ contextTable.splitMenu = resizeDiv.querySelector('.se-btn-group-sub');
+ contextTable.mergeButton = resizeDiv.querySelector('._se_table_merge_button');
+ contextTable.splitButton = resizeDiv.querySelector('._se_table_split_button');
+ contextTable.insertRowAboveButton = resizeDiv.querySelector('._se_table_insert_row_a');
+ contextTable.insertRowBelowButton = resizeDiv.querySelector('._se_table_insert_row_b');
+ resizeDiv.addEventListener('mousedown', core.eventStop);
+
+ /** add event listeners */
+ tablePicker.addEventListener('mousemove', this.onMouseMove_tablePicker.bind(core, contextTable));
+ tablePicker.addEventListener('click', this.appendTable.bind(core));
+ resizeDiv.addEventListener('click', this.onClick_tableController.bind(core));
+ tableController.addEventListener('click', this.onClick_tableController.bind(core));
+
+ /** append target button menu */
+ core.initMenuTarget(this.name, targetElement, listDiv);
+
+ /** append controller */
+ context.element.relative.appendChild(resizeDiv);
+ context.element.relative.appendChild(tableController);
+
+ /** empty memory */
+ listDiv = null, tablePicker = null, resizeDiv = null, tableController = null, contextTable = null;
+ },
+
+ setSubmenu: function () {
+ const listDiv = this.util.createElement('DIV');
+ listDiv.className = 'se-submenu se-selector-table';
+ listDiv.innerHTML = '' +
+ '<div class="se-table-size">' +
+ '<div class="se-table-size-picker se-controller-table-picker"></div>' +
+ '<div class="se-table-size-highlighted"></div>' +
+ '<div class="se-table-size-unhighlighted"></div>' +
+ '</div>' +
+ '<div class="se-table-size-display">1 x 1</div>';
+
+ return listDiv;
+ },
+
+ setController_table: function () {
+ const lang = this.lang;
+ const icons = this.icons;
+ const tableResize = this.util.createElement('DIV');
+
+ tableResize.className = 'se-controller se-controller-table';
+ tableResize.innerHTML = '' +
+ '<div>' +
+ '<div class="se-btn-group">' +
+ '<button type="button" data-command="resize" class="se-btn se-tooltip _se_table_resize">' +
+ icons.expansion +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.maxSize + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="layout" class="se-btn se-tooltip _se_table_fixed_column">' +
+ icons.fixed_column_width +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.fixedColumnWidth + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="header" class="se-btn se-tooltip _se_table_header">' +
+ icons.table_header +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.tableHeader + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="remove" class="se-btn se-tooltip">' +
+ icons.delete +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.remove + '</span></span>' +
+ '</button>' +
+ '</div>' +
+ '</div>';
+
+ return tableResize;
+ },
+
+ setController_tableEditor: function (cellControllerTop) {
+ const lang = this.lang;
+ const icons = this.icons;
+ const tableResize = this.util.createElement('DIV');
+
+ tableResize.className = 'se-controller se-controller-table-cell';
+ tableResize.innerHTML = (cellControllerTop ? '' : '<div class="se-arrow se-arrow-up"></div>') +
+ '<div class="se-btn-group">' +
+ '<button type="button" data-command="insert" data-value="row" data-option="up" class="se-btn se-tooltip _se_table_insert_row_a">' +
+ icons.insert_row_above +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.insertRowAbove + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="insert" data-value="row" data-option="down" class="se-btn se-tooltip _se_table_insert_row_b">' +
+ icons.insert_row_below +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.insertRowBelow + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="delete" data-value="row" class="se-btn se-tooltip">' +
+ icons.delete_row +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.deleteRow + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="merge" class="_se_table_merge_button se-btn se-tooltip" disabled>' +
+ icons.merge_cell +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.mergeCells + '</span></span>' +
+ '</button>' +
+ '</div>' +
+ '<div class="se-btn-group" style="padding-top: 0;">' +
+ '<button type="button" data-command="insert" data-value="cell" data-option="left" class="se-btn se-tooltip">' +
+ icons.insert_column_left +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.insertColumnBefore + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="insert" data-value="cell" data-option="right" class="se-btn se-tooltip">' +
+ icons.insert_column_right +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.insertColumnAfter + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="delete" data-value="cell" class="se-btn se-tooltip">' +
+ icons.delete_column +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.deleteColumn + '</span></span>' +
+ '</button>' +
+ '<button type="button" data-command="onsplit" class="_se_table_split_button se-btn se-tooltip">' +
+ icons.split_cell +
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + lang.controller.splitCells + '</span></span>' +
+ '</button>' +
+ '<div class="se-btn-group-sub sun-editor-common se-list-layer">' +
+ '<div class="se-list-inner">' +
+ '<ul class="se-list-basic">' +
+ '<li class="se-btn-list" data-command="split" data-value="vertical" style="line-height:32px;" title="' + lang.controller.VerticalSplit + '">' +
+ lang.controller.VerticalSplit + '</li>' +
+ '<li class="se-btn-list" data-command="split" data-value="horizontal" style="line-height:32px;" title="' + lang.controller.HorizontalSplit + '">' +
+ lang.controller.HorizontalSplit + '</li>' +
+ '</ul>' +
+ '</div>' +
+ '</div>' +
+ '</div>';
+
+ return tableResize;
+ },
+
+ appendTable: function () {
+ const oTable = this.util.createElement('TABLE');
+ const createCells = this.plugins.table.createCells;
+
+ const x = this.context.table._tableXY[0];
+ let y = this.context.table._tableXY[1];
+ let tableHTML = '<tbody>';
+ while (y > 0) {
+ tableHTML += '<tr>' + createCells.call(this, 'td', x) + '</tr>';
+ --y;
+ }
+ tableHTML += '</tbody>';
+ oTable.innerHTML = tableHTML;
+
+ const changed = this.insertComponent(oTable, false, true, false);
+
+ if (changed) {
+ const firstTd = oTable.querySelector('td div');
+ this.setRange(firstTd, 0, firstTd, 0);
+ this.plugins.table.reset_table_picker.call(this);
+ }
+ },
+
+ createCells: function (nodeName, cnt, returnElement) {
+ nodeName = nodeName.toLowerCase();
+
+ if (!returnElement) {
+ let cellsHTML = '';
+ while (cnt > 0) {
+ cellsHTML += '<' +nodeName + '><div><br></div></' + nodeName + '>';
+ cnt--;
+ }
+ return cellsHTML;
+ } else {
+ const cell = this.util.createElement(nodeName);
+ cell.innerHTML = '<div><br></div>';
+ return cell;
+ }
+ },
+
+ onMouseMove_tablePicker: function (contextTable, e) {
+ e.stopPropagation();
+
+ let x = this._w.Math.ceil(e.offsetX / 18);
+ let y = this._w.Math.ceil(e.offsetY / 18);
+ x = x < 1 ? 1 : x;
+ y = y < 1 ? 1 : y;
+
+ if (contextTable._rtl) {
+ contextTable.tableHighlight.style.left = (x * 18 - 13) + 'px';
+ x = 11 - x;
+ }
+
+ contextTable.tableHighlight.style.width = x + 'em';
+ contextTable.tableHighlight.style.height = y + 'em';
+
+ // let x_u = x < 5 ? 5 : (x > 9 ? 10 : x + 1);
+ // let y_u = y < 5 ? 5 : (y > 9 ? 10 : y + 1);
+ // contextTable.tableUnHighlight.style.width = x_u + 'em';
+ // contextTable.tableUnHighlight.style.height = y_u + 'em';
+
+ this.util.changeTxt(contextTable.tableDisplay, x + ' x ' + y);
+ contextTable._tableXY = [x, y];
+ },
+
+ reset_table_picker: function () {
+ if (!this.context.table.tableHighlight) return;
+
+ const highlight = this.context.table.tableHighlight.style;
+ const unHighlight = this.context.table.tableUnHighlight.style;
+
+ highlight.width = '1em';
+ highlight.height = '1em';
+ unHighlight.width = '10em';
+ unHighlight.height = '10em';
+
+ this.util.changeTxt(this.context.table.tableDisplay, '1 x 1');
+ this.submenuOff();
+ },
+
+ init: function () {
+ const contextTable = this.context.table;
+ const tablePlugin = this.plugins.table;
+
+ tablePlugin._removeEvents.call(this);
+
+ if (tablePlugin._selectedTable) {
+ const selectedCells = tablePlugin._selectedTable.querySelectorAll('.se-table-selected-cell');
+ for (let i = 0, len = selectedCells.length; i < len; i++) {
+ this.util.removeClass(selectedCells[i], 'se-table-selected-cell');
+ }
+ }
+
+ tablePlugin._toggleEditor.call(this, true);
+
+ contextTable._element = null;
+ contextTable._tdElement = null;
+ contextTable._trElement = null;
+ contextTable._trElements = null;
+ contextTable._tableXY = [];
+ contextTable._maxWidth = true;
+ contextTable._fixedColumn = false;
+ contextTable._physical_cellCnt = 0;
+ contextTable._logical_cellCnt = 0;
+ contextTable._rowCnt = 0;
+ contextTable._rowIndex = 0;
+ contextTable._physical_cellIndex = 0;
+ contextTable._logical_cellIndex = 0;
+ contextTable._current_colSpan = 0;
+ contextTable._current_rowSpan = 0;
+
+ tablePlugin._shift = false;
+ tablePlugin._selectedCells = null;
+ tablePlugin._selectedTable = null;
+ tablePlugin._ref = null;
+
+ tablePlugin._fixedCell = null;
+ tablePlugin._selectedCell = null;
+ tablePlugin._fixedCellName = null;
+ },
+
+ /** table edit controller */
+ call_controller_tableEdit: function (tdElement) {
+ const tablePlugin = this.plugins.table;
+ const contextTable = this.context.table;
+
+ if (!this.getSelection().isCollapsed && !tablePlugin._selectedCell) {
+ this.controllersOff();
+ this.util.removeClass(tdElement, 'se-table-selected-cell');
+ return;
+ }
+
+ const tableElement = contextTable._element || this.plugins.table._selectedTable || this.util.getParentElement(tdElement, 'TABLE');
+ contextTable._maxWidth = this.util.hasClass(tableElement, 'se-table-size-100') || tableElement.style.width === '100%' || (!tableElement.style.width && !this.util.hasClass(tableElement, 'se-table-size-auto'));
+ contextTable._fixedColumn = this.util.hasClass(tableElement, 'se-table-layout-fixed') || tableElement.style.tableLayout === 'fixed';
+ tablePlugin.setTableStyle.call(this, contextTable._maxWidth ? 'width|column' : 'width');
+
+ tablePlugin.setPositionControllerTop.call(this, tableElement);
+ tablePlugin.setPositionControllerDiv.call(this, tdElement, tablePlugin._shift);
+
+ if (!tablePlugin._shift) this.controllersOn(contextTable.resizeDiv, contextTable.tableController, tablePlugin.init.bind(this), tdElement, 'table');
+ },
+
+ setPositionControllerTop: function (tableElement) {
+ this.setControllerPosition(this.context.table.tableController, tableElement, 'top', {left: 0, top: 0});
+ },
+
+ setPositionControllerDiv: function (tdElement, reset) {
+ const contextTable = this.context.table;
+ const resizeDiv = contextTable.resizeDiv;
+
+ this.plugins.table.setCellInfo.call(this, tdElement, reset);
+
+ if (contextTable.cellControllerTop) {
+ this.setControllerPosition(resizeDiv, contextTable._element, 'top', {left: contextTable.tableController.offsetWidth, top: 0});
+ } else {
+ this.setControllerPosition(resizeDiv, tdElement, 'bottom', {left: 0, top: 0});
+ }
+ },
+
+ setCellInfo: function (tdElement, reset) {
+ const contextTable = this.context.table;
+ const table = contextTable._element = this.plugins.table._selectedTable || this.util.getParentElement(tdElement, 'TABLE');
+
+ if (/THEAD/i.test(table.firstElementChild.nodeName)) {
+ this.util.addClass(contextTable.headerButton, 'active');
+ } else {
+ this.util.removeClass(contextTable.headerButton, 'active');
+ }
+
+ if (reset || contextTable._physical_cellCnt === 0) {
+ if (contextTable._tdElement !== tdElement) {
+ contextTable._tdElement = tdElement;
+ contextTable._trElement = tdElement.parentNode;
+ }
+
+ const rows = contextTable._trElements = table.rows;
+ const cellIndex = tdElement.cellIndex;
+
+ let cellCnt = 0;
+ for (let i = 0, cells = rows[0].cells, len = rows[0].cells.length; i < len; i++) {
+ cellCnt += cells[i].colSpan;
+ }
+
+ // row cnt, row index
+ const rowIndex = contextTable._rowIndex = contextTable._trElement.rowIndex;
+ contextTable._rowCnt = rows.length;
+
+ // cell cnt, physical cell index
+ contextTable._physical_cellCnt = contextTable._trElement.cells.length;
+ contextTable._logical_cellCnt = cellCnt;
+ contextTable._physical_cellIndex = cellIndex;
+
+ // span
+ contextTable._current_colSpan = contextTable._tdElement.colSpan - 1;
+ contextTable._current_rowSpan - contextTable._trElement.cells[cellIndex].rowSpan - 1;
+
+ // find logcal cell index
+ let rowSpanArr = [];
+ let spanIndex = [];
+ for (let i = 0, cells, colSpan; i <= rowIndex; i++) {
+ cells = rows[i].cells;
+ colSpan = 0;
+ for (let c = 0, cLen = cells.length, cell, cs, rs, logcalIndex; c < cLen; c++) {
+ cell = cells[c];
+ cs = cell.colSpan - 1;
+ rs = cell.rowSpan - 1;
+ logcalIndex = c + colSpan;
+
+ if (spanIndex.length > 0) {
+ for (let r = 0, arr; r < spanIndex.length; r++) {
+ arr = spanIndex[r];
+ if (arr.row > i) continue;
+ if (logcalIndex >= arr.index) {
+ colSpan += arr.cs;
+ logcalIndex += arr.cs;
+ arr.rs -= 1;
+ arr.row = i + 1;
+ if (arr.rs < 1) {
+ spanIndex.splice(r, 1);
+ r--;
+ }
+ } else if (c === cLen - 1) {
+ arr.rs -= 1;
+ arr.row = i + 1;
+ if (arr.rs < 1) {
+ spanIndex.splice(r, 1);
+ r--;
+ }
+ }
+ }
+ }
+
+ // logcal cell index
+ if (i === rowIndex && c === cellIndex) {
+ contextTable._logical_cellIndex = logcalIndex;
+ break;
+ }
+
+ if (rs > 0) {
+ rowSpanArr.push({
+ index: logcalIndex,
+ cs: cs + 1,
+ rs: rs,
+ row: -1
+ });
+ }
+
+ colSpan += cs;
+ }
+
+ spanIndex = spanIndex.concat(rowSpanArr).sort(function (a, b) {return a.index - b.index;});
+ rowSpanArr = [];
+ }
+
+ rowSpanArr = null;
+ spanIndex = null;
+ }
+ },
+
+ editTable: function (type, option) {
+ const tablePlugin = this.plugins.table;
+ const contextTable = this.context.table;
+ const table = contextTable._element;
+ const isRow = type === 'row';
+
+ if (isRow) {
+ const tableAttr = contextTable._trElement.parentNode;
+ if (/^THEAD$/i.test(tableAttr.nodeName)) {
+ if (option === 'up') {
+ return;
+ } else if (!tableAttr.nextElementSibling || !/^TBODY$/i.test(tableAttr.nextElementSibling.nodeName)) {
+ table.innerHTML += '<tbody><tr>' + tablePlugin.createCells.call(this, 'td', contextTable._logical_cellCnt, false) + '</tr></tbody>';
+ return;
+ }
+ }
+ }
+
+ // multi
+ if (tablePlugin._ref) {
+ const positionCell = contextTable._tdElement;
+ const selectedCells = tablePlugin._selectedCells;
+ // multi - row
+ if (isRow) {
+ // remove row
+ if (!option) {
+ let row = selectedCells[0].parentNode;
+ const removeCells = [selectedCells[0]];
+
+ for (let i = 1, len = selectedCells.length, cell; i < len; i++) {
+ cell = selectedCells[i];
+ if (row !== cell.parentNode) {
+ removeCells.push(cell);
+ row = cell.parentNode;
+ }
+ }
+
+ for (let i = 0, len = removeCells.length; i < len; i++) {
+ tablePlugin.setCellInfo.call(this, removeCells[i], true);
+ tablePlugin.editRow.call(this, option);
+ }
+ } else { // edit row
+ tablePlugin.setCellInfo.call(this, option === 'up' ? selectedCells[0] : selectedCells[selectedCells.length - 1], true);
+ tablePlugin.editRow.call(this, option, positionCell);
+ }
+ } else { // multi - cell
+ const firstRow = selectedCells[0].parentNode;
+ // remove cell
+ if (!option) {
+ const removeCells = [selectedCells[0]];
+
+ for (let i = 1, len = selectedCells.length, cell; i < len; i++) {
+ cell = selectedCells[i];
+ if (firstRow === cell.parentNode) {
+ removeCells.push(cell);
+ } else {
+ break;
+ }
+ }
+
+ for (let i = 0, len = removeCells.length; i < len; i++) {
+ tablePlugin.setCellInfo.call(this, removeCells[i], true);
+ tablePlugin.editCell.call(this, option);
+ }
+ } else { // edit cell
+ let rightCell = null;
+
+ for (let i = 0, len = selectedCells.length - 1; i < len; i++) {
+ if (firstRow !== selectedCells[i + 1].parentNode) {
+ rightCell = selectedCells[i];
+ break;
+ }
+ }
+
+ tablePlugin.setCellInfo.call(this, option === 'left' ? selectedCells[0] : rightCell || selectedCells[0], true);
+ tablePlugin.editCell.call(this, option, positionCell);
+ }
+ }
+
+ if (!option) tablePlugin.init.call(this);
+ } // one
+ else {
+ tablePlugin[isRow ? 'editRow' : 'editCell'].call(this, option);
+ }
+
+ // after remove
+ if (!option) {
+ const children = table.children;
+ for (let i = 0; i < children.length; i++) {
+ if (children[i].children.length === 0) {
+ this.util.removeItem(children[i]);
+ i--;
+ }
+ }
+
+ if (table.children.length === 0) this.util.removeItem(table);
+ }
+ },
+
+ editRow: function (option, positionResetElement) {
+ const contextTable = this.context.table;
+ const remove = !option;
+
+ const up = option === 'up';
+ const originRowIndex = contextTable._rowIndex;
+ const rowIndex = remove || up ? originRowIndex : originRowIndex + contextTable._current_rowSpan + 1;
+ const sign = remove ? -1 : 1;
+
+ const rows = contextTable._trElements;
+ let cellCnt = contextTable._logical_cellCnt;
+
+ for (let i = 0, len = originRowIndex + (remove ? -1 : 0), cell; i <= len; i++) {
+ cell = rows[i].cells;
+ if (cell.length === 0) return;
+
+ for (let c = 0, cLen = cell.length, rs, cs; c < cLen; c++) {
+ rs = cell[c].rowSpan;
+ cs = cell[c].colSpan;
+ if (rs < 2 && cs < 2) continue;
+
+ if (rs + i > rowIndex && rowIndex > i) {
+ cell[c].rowSpan = rs + sign;
+ cellCnt -= cs;
+ }
+ }
+ }
+
+ if (remove) {
+ const next = rows[originRowIndex + 1];
+ if (next) {
+ const spanCells = [];
+ let cells = rows[originRowIndex].cells;
+ let colSpan = 0;
+
+ for (let i = 0, len = cells.length, cell, logcalIndex; i < len; i++) {
+ cell = cells[i];
+ logcalIndex = i + colSpan;
+ colSpan += cell.colSpan - 1;
+
+ if (cell.rowSpan > 1) {
+ cell.rowSpan -= 1;
+ spanCells.push({cell: cell.cloneNode(false), index: logcalIndex});
+ }
+ }
+
+ if (spanCells.length > 0) {
+ let spanCell = spanCells.shift();
+ cells = next.cells;
+ colSpan = 0;
+
+ for (let i = 0, len = cells.length, cell, logcalIndex; i < len; i++) {
+ cell = cells[i];
+ logcalIndex = i + colSpan;
+ colSpan += cell.colSpan - 1;
+
+ if (logcalIndex >= spanCell.index) {
+ i--, colSpan--;
+ colSpan += spanCell.cell.colSpan - 1;
+ next.insertBefore(spanCell.cell, cell);
+ spanCell = spanCells.shift();
+ if (!spanCell) break;
+ }
+ }
+
+ if (spanCell) {
+ next.appendChild(spanCell.cell);
+ for (let i = 0, len = spanCells.length; i < len; i++) {
+ next.appendChild(spanCells[i].cell);
+ }
+ }
+ }
+ }
+
+ contextTable._element.deleteRow(rowIndex);
+ } else {
+ const newRow = contextTable._element.insertRow(rowIndex);
+ newRow.innerHTML = this.plugins.table.createCells.call(this, 'td', cellCnt, false);
+ }
+
+ if (!remove) {
+ this.plugins.table.setPositionControllerDiv.call(this, positionResetElement || contextTable._tdElement, true);
+ } else {
+ this.controllersOff();
+ }
+ },
+
+ editCell: function (option, positionResetElement) {
+ const contextTable = this.context.table;
+ const util = this.util;
+ const remove = !option;
+
+ const left = option === 'left';
+ const colSpan = contextTable._current_colSpan;
+ const cellIndex = remove || left ? contextTable._logical_cellIndex : contextTable._logical_cellIndex + colSpan + 1;
+
+ const rows = contextTable._trElements;
+ let rowSpanArr = [];
+ let spanIndex = [];
+ let passCell = 0;
+ const removeCell = [];
+ const removeSpanArr = [];
+
+ for (let i = 0, len = contextTable._rowCnt, row, insertIndex, cells, newCell, applySpan, cellColSpan; i < len; i++) {
+ row = rows[i];
+ insertIndex = cellIndex;
+ applySpan = false;
+ cells = row.cells;
+ cellColSpan = 0;
+
+ for (let c = 0, cell, cLen = cells.length, rs, cs, removeIndex; c < cLen; c++) {
+ cell = cells[c];
+ if (!cell) break;
+
+ rs = cell.rowSpan - 1;
+ cs = cell.colSpan - 1;
+
+ if (!remove) {
+ if (c >= insertIndex) break;
+ if (cs > 0) {
+ if (passCell < 1 && cs + c >= insertIndex) {
+ cell.colSpan += 1;
+ insertIndex = null;
+ passCell = rs + 1;
+ break;
+ }
+
+ insertIndex -= cs;
+ }
+
+ if (!applySpan) {
+ for (let r = 0, arr; r < spanIndex.length; r++) {
+ arr = spanIndex[r];
+ insertIndex -= arr.cs;
+ arr.rs -= 1;
+ if (arr.rs < 1) {
+ spanIndex.splice(r, 1);
+ r--;
+ }
+ }
+ applySpan = true;
+ }
+ } else {
+ removeIndex = c + cellColSpan;
+
+ if (spanIndex.length > 0) {
+ const lastCell = !cells[c + 1];
+ for (let r = 0, arr; r < spanIndex.length; r++) {
+ arr = spanIndex[r];
+ if (arr.row > i) continue;
+
+ if (removeIndex >= arr.index) {
+ cellColSpan += arr.cs;
+ removeIndex = c + cellColSpan;
+ arr.rs -= 1;
+ arr.row = i + 1;
+ if (arr.rs < 1) {
+ spanIndex.splice(r, 1);
+ r--;
+ }
+ } else if (lastCell) {
+ arr.rs -= 1;
+ arr.row = i + 1;
+ if (arr.rs < 1) {
+ spanIndex.splice(r, 1);
+ r--;
+ }
+ }
+ }
+ }
+
+ if (rs > 0) {
+ rowSpanArr.push({
+ rs: rs,
+ cs: cs + 1,
+ index: removeIndex,
+ row: -1
+ });
+ }
+
+ if (removeIndex >= insertIndex && removeIndex + cs <= insertIndex + colSpan) {
+ removeCell.push(cell);
+ } else if (removeIndex <= insertIndex + colSpan && removeIndex + cs >= insertIndex) {
+ cell.colSpan -= util.getOverlapRangeAtIndex(cellIndex, cellIndex + colSpan, removeIndex, removeIndex + cs);
+ } else if (rs > 0 && (removeIndex < insertIndex || removeIndex + cs > insertIndex + colSpan)) {
+ removeSpanArr.push({
+ cell: cell,
+ i: i,
+ rs: i + rs
+ });
+ }
+
+ cellColSpan += cs;
+ }
+ }
+
+ spanIndex = spanIndex.concat(rowSpanArr).sort(function (a, b) {return a.index - b.index;});
+ rowSpanArr = [];
+
+ if (!remove) {
+ if (passCell > 0) {
+ passCell -= 1;
+ continue;
+ }
+
+ if (insertIndex !== null && cells.length > 0) {
+ newCell = this.plugins.table.createCells.call(this, cells[0].nodeName, 0, true);
+ newCell = row.insertBefore(newCell, cells[insertIndex]);
+ }
+ }
+ }
+
+ if (remove) {
+ let removeFirst, removeEnd;
+ for (let r = 0, rLen = removeCell.length, row; r < rLen; r++) {
+ row = removeCell[r].parentNode;
+ util.removeItem(removeCell[r]);
+ if (row.cells.length === 0) {
+ if (!removeFirst) removeFirst = util.getArrayIndex(rows, row);
+ removeEnd = util.getArrayIndex(rows, row);
+ util.removeItem(row);
+ }
+ }
+
+ for (let c = 0, cLen = removeSpanArr.length, rowSpanCell; c < cLen; c++) {
+ rowSpanCell = removeSpanArr[c];
+ rowSpanCell.cell.rowSpan = util.getOverlapRangeAtIndex(removeFirst, removeEnd, rowSpanCell.i, rowSpanCell.rs);
+ }
+
+ this.controllersOff();
+ } else {
+ this.plugins.table.setPositionControllerDiv.call(this, positionResetElement || contextTable._tdElement, true);
+ }
+ },
+
+ _closeSplitMenu: null,
+ openSplitMenu: function () {
+ this.util.addClass(this.context.table.splitButton, 'on');
+ this.context.table.splitMenu.style.display = 'inline-table';
+
+ this.plugins.table._closeSplitMenu = function () {
+ this.util.removeClass(this.context.table.splitButton, 'on');
+ this.context.table.splitMenu.style.display = 'none';
+ this.removeDocEvent('mousedown', this.plugins.table._closeSplitMenu);
+ this.plugins.table._closeSplitMenu = null;
+ }.bind(this);
+
+ this.addDocEvent('mousedown', this.plugins.table._closeSplitMenu);
+ },
+
+ splitCells: function (direction) {
+ const util = this.util;
+ const vertical = direction === 'vertical';
+ const contextTable = this.context.table;
+ const currentCell = contextTable._tdElement;
+ const rows = contextTable._trElements;
+ const currentRow = contextTable._trElement;
+ const index = contextTable._logical_cellIndex;
+ const rowIndex = contextTable._rowIndex;
+ const newCell = this.plugins.table.createCells.call(this, currentCell.nodeName, 0, true);
+
+ // vertical
+ if (vertical) {
+ const currentColSpan = currentCell.colSpan;
+ newCell.rowSpan = currentCell.rowSpan;
+
+ // colspan > 1
+ if (currentColSpan > 1) {
+ newCell.colSpan = this._w.Math.floor(currentColSpan/2);
+ currentCell.colSpan = currentColSpan - newCell.colSpan;
+ currentRow.insertBefore(newCell, currentCell.nextElementSibling);
+ } else { // colspan - 1
+ let rowSpanArr = [];
+ let spanIndex = [];
+
+ for (let i = 0, len = contextTable._rowCnt, cells, colSpan; i < len; i++) {
+ cells = rows[i].cells;
+ colSpan = 0;
+ for (let c = 0, cLen = cells.length, cell, cs, rs, logcalIndex; c < cLen; c++) {
+ cell = cells[c];
+ cs = cell.colSpan - 1;
+ rs = cell.rowSpan - 1;
+ logcalIndex = c + colSpan;
+
+ if (spanIndex.length > 0) {
+ for (let r = 0, arr; r < spanIndex.length; r++) {
+ arr = spanIndex[r];
+ if (arr.row > i) continue;
+ if (logcalIndex >= arr.index) {
+ colSpan += arr.cs;
+ logcalIndex += arr.cs;
+ arr.rs -= 1;
+ arr.row = i + 1;
+ if (arr.rs < 1) {
+ spanIndex.splice(r, 1);
+ r--;
+ }
+ } else if (c === cLen - 1) {
+ arr.rs -= 1;
+ arr.row = i + 1;
+ if (arr.rs < 1) {
+ spanIndex.splice(r, 1);
+ r--;
+ }
+ }
+ }
+ }
+
+ if (logcalIndex <= index && rs > 0) {
+ rowSpanArr.push({
+ index: logcalIndex,
+ cs: cs + 1,
+ rs: rs,
+ row: -1
+ });
+ }
+
+ if (cell !== currentCell && logcalIndex <= index && logcalIndex + cs >= index + currentColSpan - 1) {
+ cell.colSpan += 1;
+ break;
+ }
+
+ if (logcalIndex > index) break;
+
+ colSpan += cs;
+ }
+
+ spanIndex = spanIndex.concat(rowSpanArr).sort(function (a, b) {return a.index - b.index;});
+ rowSpanArr = [];
+ }
+
+ currentRow.insertBefore(newCell, currentCell.nextElementSibling);
+ }
+ } else { // horizontal
+ const currentRowSpan = currentCell.rowSpan;
+ newCell.colSpan = currentCell.colSpan;
+
+ // rowspan > 1
+ if (currentRowSpan > 1) {
+ newCell.rowSpan = this._w.Math.floor(currentRowSpan/2);
+ const newRowSpan = currentRowSpan - newCell.rowSpan;
+
+ const rowSpanArr = [];
+ const nextRowIndex = util.getArrayIndex(rows, currentRow) + newRowSpan;
+
+ for (let i = 0, cells, colSpan; i < nextRowIndex; i++) {
+ cells = rows[i].cells;
+ colSpan = 0;
+ for (let c = 0, cLen = cells.length, cell, cs, logcalIndex; c < cLen; c++) {
+ logcalIndex = c + colSpan;
+ if (logcalIndex >= index) break;
+
+ cell = cells[c];
+ cs = cell.rowSpan - 1;
+ if (cs > 0 && cs + i >= nextRowIndex && logcalIndex < index) {
+ rowSpanArr.push({
+ index: logcalIndex,
+ cs: cell.colSpan
+ });
+ }
+ colSpan += cell.colSpan - 1;
+ }
+ }
+
+ const nextRow = rows[nextRowIndex];
+ const nextCells = nextRow.cells;
+ let rs = rowSpanArr.shift();
+
+ for (let c = 0, cLen = nextCells.length, colSpan = 0, cell, cs, logcalIndex, insertIndex; c < cLen; c++) {
+ logcalIndex = c + colSpan;
+ cell = nextCells[c];
+ cs = cell.colSpan - 1;
+ insertIndex = logcalIndex + cs + 1;
+
+ if (rs && insertIndex >= rs.index) {
+ colSpan += rs.cs;
+ insertIndex += rs.cs;
+ rs = rowSpanArr.shift();
+ }
+
+ if (insertIndex >= index || c === cLen - 1) {
+ nextRow.insertBefore(newCell, cell.nextElementSibling);
+ break;
+ }
+
+ colSpan += cs;
+ }
+
+ currentCell.rowSpan = newRowSpan;
+ } else { // rowspan - 1
+ newCell.rowSpan = currentCell.rowSpan;
+ const newRow = util.createElement('TR');
+ newRow.appendChild(newCell);
+
+ for (let i = 0, cells; i < rowIndex; i++) {
+ cells = rows[i].cells;
+ if (cells.length === 0) return;
+
+ for (let c = 0, cLen = cells.length; c < cLen; c++) {
+ if (i + cells[c].rowSpan - 1 >= rowIndex) {
+ cells[c].rowSpan += 1;
+ }
+ }
+ }
+
+ const physicalIndex = contextTable._physical_cellIndex;
+ const cells = currentRow.cells;
+
+ for (let c = 0, cLen = cells.length; c < cLen; c++) {
+ if (c === physicalIndex) continue;
+ cells[c].rowSpan += 1;
+ }
+
+ currentRow.parentNode.insertBefore(newRow, currentRow.nextElementSibling);
+ }
+ }
+
+ this.focusEdge(currentCell);
+ this.plugins.table.setPositionControllerDiv.call(this, currentCell, true);
+ },
+
+ mergeCells: function () {
+ const tablePlugin = this.plugins.table;
+ const contextTable = this.context.table;
+ const util = this.util;
+
+ const ref = tablePlugin._ref;
+ const selectedCells = tablePlugin._selectedCells;
+ const mergeCell = selectedCells[0];
+
+ let emptyRowFirst = null;
+ let emptyRowLast = null;
+ let cs = (ref.ce - ref.cs) + 1;
+ let rs = (ref.re - ref.rs) + 1;
+ let mergeHTML = '';
+ let row = null;
+
+ for (let i = 1, len = selectedCells.length, cell, ch; i < len; i++) {
+ cell = selectedCells[i];
+ if (row !== cell.parentNode) row = cell.parentNode;
+
+ ch = cell.children;
+ for (let c = 0, cLen = ch.length; c < cLen; c++) {
+ if (util.isFormatElement(ch[c]) && util.onlyZeroWidthSpace(ch[c].textContent)) {
+ util.removeItem(ch[c]);
+ }
+ }
+
+ mergeHTML += cell.innerHTML;
+ util.removeItem(cell);
+
+ if (row.cells.length === 0) {
+ if (!emptyRowFirst) emptyRowFirst = row;
+ else emptyRowLast = row;
+ rs -= 1;
+ }
+ }
+
+ if (emptyRowFirst) {
+ const rows = contextTable._trElements;
+ const rowIndexFirst = util.getArrayIndex(rows, emptyRowFirst);
+ const rowIndexLast = util.getArrayIndex(rows, emptyRowLast || emptyRowFirst);
+ const removeRows = [];
+
+ for (let i = 0, cells; i <= rowIndexLast; i++) {
+ cells = rows[i].cells;
+ if (cells.length === 0) {
+ removeRows.push(rows[i]);
+ continue;
+ }
+
+ for (let c = 0, cLen = cells.length, cell, rs; c < cLen; c++) {
+ cell = cells[c];
+ rs = cell.rowSpan - 1;
+ if (rs > 0 && i + rs >= rowIndexFirst) {
+ cell.rowSpan -= util.getOverlapRangeAtIndex(rowIndexFirst, rowIndexLast, i, i + rs);
+ }
+ }
+ }
+
+ for (let i = 0, len = removeRows.length; i < len; i++) {
+ util.removeItem(removeRows[i]);
+ }
+ }
+
+ mergeCell.innerHTML += mergeHTML;
+ mergeCell.colSpan = cs;
+ mergeCell.rowSpan = rs;
+
+ this.controllersOff();
+ tablePlugin.setActiveButton.call(this, true, false);
+ tablePlugin.call_controller_tableEdit.call(this, mergeCell);
+
+ util.addClass(mergeCell, 'se-table-selected-cell');
+ this.focusEdge(mergeCell);
+ },
+
+ toggleHeader: function () {
+ const util = this.util;
+ const headerButton = this.context.table.headerButton;
+ const active = util.hasClass(headerButton, 'active');
+ const table = this.context.table._element;
+
+ if (!active) {
+ const header = util.createElement('THEAD');
+ header.innerHTML = '<tr>' + this.plugins.table.createCells.call(this, 'th', this.context.table._logical_cellCnt, false) + '</tr>';
+ table.insertBefore(header, table.firstElementChild);
+ } else {
+ util.removeItem(table.querySelector('thead'));
+ }
+
+ util.toggleClass(headerButton, 'active');
+
+ if (/TH/i.test(this.context.table._tdElement.nodeName)) {
+ this.controllersOff();
+ } else {
+ this.plugins.table.setPositionControllerDiv.call(this, this.context.table._tdElement, false);
+ }
+ },
+
+ setTableStyle: function (styles) {
+ const contextTable = this.context.table;
+ const tableElement = contextTable._element;
+ let icon, span, sizeIcon, text;
+
+ if (styles.indexOf('width') > -1) {
+ icon = contextTable.resizeButton.firstElementChild;
+ span = contextTable.resizeText;
+
+ if (!contextTable._maxWidth) {
+ sizeIcon = contextTable.icons.expansion;
+ text = contextTable.maxText;
+ contextTable.columnFixedButton.style.display = 'none';
+ this.util.removeClass(tableElement, 'se-table-size-100');
+ this.util.addClass(tableElement, 'se-table-size-auto');
+ } else {
+ sizeIcon = contextTable.icons.reduction;
+ text = contextTable.minText;
+ contextTable.columnFixedButton.style.display = 'block';
+ this.util.removeClass(tableElement, 'se-table-size-auto');
+ this.util.addClass(tableElement, 'se-table-size-100');
+ }
+
+ this.util.changeElement(icon, sizeIcon);
+ this.util.changeTxt(span, text);
+ }
+
+ if (styles.indexOf('column') > -1) {
+ if (!contextTable._fixedColumn) {
+ this.util.removeClass(tableElement, 'se-table-layout-fixed');
+ this.util.addClass(tableElement, 'se-table-layout-auto');
+ this.util.removeClass(contextTable.columnFixedButton, 'active');
+ } else {
+ this.util.removeClass(tableElement, 'se-table-layout-auto');
+ this.util.addClass(tableElement, 'se-table-layout-fixed');
+ this.util.addClass(contextTable.columnFixedButton, 'active');
+ }
+
+ }
+ },
+
+ setActiveButton: function (fixedCell, selectedCell) {
+ const contextTable = this.context.table;
+
+ if (/^TH$/i.test(fixedCell.nodeName)) {
+ contextTable.insertRowAboveButton.setAttribute('disabled', true);
+ contextTable.insertRowBelowButton.setAttribute('disabled', true);
+ } else {
+ contextTable.insertRowAboveButton.removeAttribute('disabled');
+ contextTable.insertRowBelowButton.removeAttribute('disabled');
+ }
+
+ if (!selectedCell || fixedCell === selectedCell) {
+ contextTable.splitButton.removeAttribute('disabled');
+ contextTable.mergeButton.setAttribute('disabled', true);
+ } else {
+ contextTable.splitButton.setAttribute('disabled', true);
+ contextTable.mergeButton.removeAttribute('disabled');
+ }
+ },
+
+ // multi selecte
+ _bindOnSelect: null,
+ _bindOffSelect: null,
+ _bindOffShift: null,
+ _selectedCells: null,
+ _shift: false,
+ _fixedCell: null,
+ _fixedCellName: null,
+ _selectedCell: null,
+ _selectedTable: null,
+ _ref: null,
+ _toggleEditor: function (enabled) {
+ this.context.element.wysiwyg.setAttribute('contenteditable', enabled);
+ if (enabled) this.util.removeClass(this.context.element.wysiwyg, 'se-disabled');
+ else this.util.addClass(this.context.element.wysiwyg, 'se-disabled');
+ },
+
+ _offCellMultiSelect: function (e) {
+ e.stopPropagation();
+ const tablePlugin = this.plugins.table;
+
+ if (!tablePlugin._shift) {
+ tablePlugin._removeEvents.call(this);
+ tablePlugin._toggleEditor.call(this, true);
+ } else if (tablePlugin._initBind) {
+ this._wd.removeEventListener('touchmove', tablePlugin._initBind);
+ tablePlugin._initBind = null;
+ }
+
+ if (!tablePlugin._fixedCell || !tablePlugin._selectedTable) return;
+
+ tablePlugin.setActiveButton.call(this, tablePlugin._fixedCell, tablePlugin._selectedCell);
+ tablePlugin.call_controller_tableEdit.call(this, tablePlugin._selectedCell || tablePlugin._fixedCell);
+
+ tablePlugin._selectedCells = tablePlugin._selectedTable.querySelectorAll('.se-table-selected-cell');
+ if (tablePlugin._selectedCell && tablePlugin._fixedCell) this.focusEdge(tablePlugin._selectedCell);
+
+ if (!tablePlugin._shift) {
+ tablePlugin._fixedCell = null;
+ tablePlugin._selectedCell = null;
+ tablePlugin._fixedCellName = null;
+ }
+ },
+
+ _onCellMultiSelect: function (e) {
+ this._antiBlur = true;
+ const tablePlugin = this.plugins.table;
+ const target = this.util.getParentElement(e.target, this.util.isCell);
+
+ if (tablePlugin._shift) {
+ if (target === tablePlugin._fixedCell) tablePlugin._toggleEditor.call(this, true);
+ else tablePlugin._toggleEditor.call(this, false);
+ } else if (!tablePlugin._ref) {
+ if (target === tablePlugin._fixedCell) return;
+ else tablePlugin._toggleEditor.call(this, false);
+ }
+
+ if (!target || target === tablePlugin._selectedCell || tablePlugin._fixedCellName !== target.nodeName ||
+ tablePlugin._selectedTable !== this.util.getParentElement(target, 'TABLE')) {
+ return;
+ }
+
+ tablePlugin._selectedCell = target;
+ tablePlugin._setMultiCells.call(this, tablePlugin._fixedCell, target);
+ },
+
+ _setMultiCells: function (startCell, endCell) {
+ const tablePlugin = this.plugins.table;
+ const rows = tablePlugin._selectedTable.rows;
+ const util = this.util;
+
+ const selectedCells = tablePlugin._selectedTable.querySelectorAll('.se-table-selected-cell');
+ for (let i = 0, len = selectedCells.length; i < len; i++) {
+ util.removeClass(selectedCells[i], 'se-table-selected-cell');
+ }
+
+ if (startCell === endCell) {
+ util.addClass(startCell, 'se-table-selected-cell');
+ if (!tablePlugin._shift) return;
+ }
+
+ let findSelectedCell = true;
+ let spanIndex = [];
+ let rowSpanArr = [];
+ const ref = tablePlugin._ref = {_i: 0, cs: null, ce: null, rs: null, re: null};
+
+ for (let i = 0, len = rows.length, cells, colSpan; i < len; i++) {
+ cells = rows[i].cells;
+ colSpan = 0;
+
+ for (let c = 0, cLen = cells.length, cell, logcalIndex, cs, rs; c < cLen; c++) {
+ cell = cells[c];
+ cs = cell.colSpan - 1;
+ rs = cell.rowSpan - 1;
+ logcalIndex = c + colSpan;
+
+ if (spanIndex.length > 0) {
+ for (let r = 0, arr; r < spanIndex.length; r++) {
+ arr = spanIndex[r];
+ if (arr.row > i) continue;
+ if (logcalIndex >= arr.index) {
+ colSpan += arr.cs;
+ logcalIndex += arr.cs;
+ arr.rs -= 1;
+ arr.row = i + 1;
+ if (arr.rs < 1) {
+ spanIndex.splice(r, 1);
+ r--;
+ }
+ } else if (c === cLen - 1) {
+ arr.rs -= 1;
+ arr.row = i + 1;
+ if (arr.rs < 1) {
+ spanIndex.splice(r, 1);
+ r--;
+ }
+ }
+ }
+ }
+
+ if (findSelectedCell) {
+ if (cell === startCell || cell === endCell) {
+ ref.cs = ref.cs !== null && ref.cs < logcalIndex ? ref.cs : logcalIndex;
+ ref.ce = ref.ce !== null && ref.ce > logcalIndex + cs ? ref.ce : logcalIndex + cs;
+ ref.rs = ref.rs !== null && ref.rs < i ? ref.rs : i;
+ ref.re = ref.re !== null && ref.re > i + rs ? ref.re : i + rs;
+ ref._i += 1;
+ }
+
+ if (ref._i === 2) {
+ findSelectedCell = false;
+ spanIndex = [];
+ rowSpanArr = [];
+ i = -1;
+ break;
+ }
+ } else if (util.getOverlapRangeAtIndex(ref.cs, ref.ce, logcalIndex, logcalIndex + cs) && util.getOverlapRangeAtIndex(ref.rs, ref.re, i, i + rs)) {
+ const newCs = ref.cs < logcalIndex ? ref.cs : logcalIndex;
+ const newCe = ref.ce > logcalIndex + cs ? ref.ce : logcalIndex + cs;
+ const newRs = ref.rs < i ? ref.rs : i;
+ const newRe = ref.re > i + rs ? ref.re : i + rs;
+
+ if (ref.cs !== newCs || ref.ce !== newCe || ref.rs !== newRs || ref.re !== newRe) {
+ ref.cs = newCs;
+ ref.ce = newCe;
+ ref.rs = newRs;
+ ref.re = newRe;
+ i = -1;
+
+ spanIndex = [];
+ rowSpanArr = [];
+ break;
+ }
+
+ util.addClass(cell, 'se-table-selected-cell');
+ }
+
+ if (rs > 0) {
+ rowSpanArr.push({
+ index: logcalIndex,
+ cs: cs + 1,
+ rs: rs,
+ row: -1
+ });
+ }
+
+ colSpan += cell.colSpan - 1;
+ }
+
+ spanIndex = spanIndex.concat(rowSpanArr).sort(function (a, b) {return a.index - b.index;});
+ rowSpanArr = [];
+ }
+ },
+
+ _removeEvents: function () {
+ const tablePlugin = this.plugins.table;
+
+ if (tablePlugin._initBind) {
+ this._wd.removeEventListener('touchmove', tablePlugin._initBind);
+ tablePlugin._initBind = null;
+ }
+
+ if (tablePlugin._bindOnSelect) {
+ this._wd.removeEventListener('mousedown', tablePlugin._bindOnSelect);
+ this._wd.removeEventListener('mousemove', tablePlugin._bindOnSelect);
+ tablePlugin._bindOnSelect = null;
+ }
+
+ if (tablePlugin._bindOffSelect) {
+ this._wd.removeEventListener('mouseup', tablePlugin._bindOffSelect);
+ tablePlugin._bindOffSelect = null;
+ }
+
+ if (tablePlugin._bindOffShift) {
+ this._wd.removeEventListener('keyup', tablePlugin._bindOffShift);
+ tablePlugin._bindOffShift = null;
+ }
+ },
+
+ _initBind: null,
+ onTableCellMultiSelect: function (tdElement, shift) {
+ const tablePlugin = this.plugins.table;
+
+ tablePlugin._removeEvents.call(this);
+ this.controllersOff();
+
+ tablePlugin._shift = shift;
+ tablePlugin._fixedCell = tdElement;
+ tablePlugin._fixedCellName = tdElement.nodeName;
+ tablePlugin._selectedTable = this.util.getParentElement(tdElement, 'TABLE');
+
+ const selectedCells = tablePlugin._selectedTable.querySelectorAll('.se-table-selected-cell');
+ for (let i = 0, len = selectedCells.length; i < len; i++) {
+ this.util.removeClass(selectedCells[i], 'se-table-selected-cell');
+ }
+
+ this.util.addClass(tdElement, 'se-table-selected-cell');
+
+ tablePlugin._bindOnSelect = tablePlugin._onCellMultiSelect.bind(this);
+ tablePlugin._bindOffSelect = tablePlugin._offCellMultiSelect.bind(this);
+
+ if (!shift) {
+ this._wd.addEventListener('mousemove', tablePlugin._bindOnSelect, false);
+ } else {
+ tablePlugin._bindOffShift = function () {
+ this.controllersOn(this.context.table.resizeDiv, this.context.table.tableController, this.plugins.table.init.bind(this), tdElement, 'table');
+ if (!tablePlugin._ref) this.controllersOff();
+ }.bind(this);
+
+ this._wd.addEventListener('keyup', tablePlugin._bindOffShift, false);
+ this._wd.addEventListener('mousedown', tablePlugin._bindOnSelect, false);
+ }
+
+ this._wd.addEventListener('mouseup', tablePlugin._bindOffSelect, false);
+ tablePlugin._initBind = tablePlugin.init.bind(this);
+ this._wd.addEventListener('touchmove', tablePlugin._initBind, false);
+ },
+
+ onClick_tableController: function (e) {
+ e.stopPropagation();
+ const target = e.target.getAttribute('data-command') ? e.target : e.target.parentNode;
+
+ if (target.getAttribute('disabled')) return;
+
+ const command = target.getAttribute('data-command');
+ const value = target.getAttribute('data-value');
+ const option = target.getAttribute('data-option');
+ const tablePlugin = this.plugins.table;
+
+ if (typeof tablePlugin._closeSplitMenu === 'function') {
+ tablePlugin._closeSplitMenu();
+ if (command === 'onsplit') return;
+ }
+
+ if (!command) return;
+
+ e.preventDefault();
+ const contextTable = this.context.table;
+
+ switch (command) {
+ case 'insert':
+ case 'delete':
+ tablePlugin.editTable.call(this, value, option);
+ break;
+ case 'header':
+ tablePlugin.toggleHeader.call(this);
+ break;
+ case 'onsplit':
+ tablePlugin.openSplitMenu.call(this);
+ break;
+ case 'split':
+ tablePlugin.splitCells.call(this, value);
+ break;
+ case 'merge':
+ tablePlugin.mergeCells.call(this);
+ break;
+ case 'resize':
+ contextTable._maxWidth = !contextTable._maxWidth;
+ tablePlugin.setTableStyle.call(this, 'width');
+ tablePlugin.setPositionControllerTop.call(this, contextTable._element);
+ tablePlugin.setPositionControllerDiv.call(this, contextTable._tdElement, tablePlugin._shift);
+ break;
+ case 'layout':
+ contextTable._fixedColumn = !contextTable._fixedColumn;
+ tablePlugin.setTableStyle.call(this, 'column');
+ tablePlugin.setPositionControllerTop.call(this, contextTable._element);
+ tablePlugin.setPositionControllerDiv.call(this, contextTable._tdElement, tablePlugin._shift);
+ break;
+ case 'remove':
+ const emptyDiv = contextTable._element.parentNode;
+ this.util.removeItem(contextTable._element);
+ this.controllersOff();
+
+ if (emptyDiv !== this.context.element.wysiwyg) this.util.removeItemAllParents(emptyDiv, function (current) { return current.childNodes.length === 0; }, null);
+ this.focus();
+ }
+
+ // history stack
+ this.history.push(false);
+ }
+};
--- /dev/null
+import { SubmenuPlugin } from '../SubmenuPlugin';
+
+declare const template: SubmenuPlugin;
+
+export default template;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ name: 'template',
+ display: 'submenu',
+ add: function (core, targetElement) {
+ const context = core.context;
+ context.template = {};
+
+ /** set submenu */
+ let templateDiv = this.setSubmenu.call(core);
+
+ /** add event listeners */
+ templateDiv.querySelector('ul').addEventListener('click', this.pickup.bind(core));
+
+ /** append target button menu */
+ core.initMenuTarget(this.name, targetElement, templateDiv);
+
+ /** empty memory */
+ templateDiv = null;
+ },
+
+ setSubmenu: function () {
+ const templateList = this.context.option.templates;
+ if (!templateList || templateList.length === 0) {
+ throw Error('[SUNEDITOR.plugins.template.fail] To use the "template" plugin, please define the "templates" option.');
+ }
+
+ const listDiv = this.util.createElement('DIV');
+ listDiv.className = 'se-list-layer';
+
+ let list = '<div class="se-submenu se-list-inner">' +
+ '<ul class="se-list-basic">';
+ for (let i = 0, len = templateList.length, t; i < len; i++) {
+ t = templateList[i];
+ list += '<li><button type="button" class="se-btn-list" data-value="' + i + '" title="' + t.name + '">' + t.name + '</button></li>';
+ }
+ list += '</ul></div>';
+
+ listDiv.innerHTML = list;
+
+ return listDiv;
+ },
+
+ pickup: function (e) {
+ if (!/^BUTTON$/i.test(e.target.tagName)) return false;
+
+ e.preventDefault();
+ e.stopPropagation();
+
+ const temp = this.context.option.templates[e.target.getAttribute('data-value')];
+
+ if (temp.html) {
+ this.setContents(temp.html);
+ } else {
+ this.submenuOff();
+ throw Error('[SUNEDITOR.template.fail] cause : "templates[i].html not found"');
+ }
+
+ this.submenuOff();
+ }
+};
\ No newline at end of file
--- /dev/null
+import { SubmenuPlugin } from '../SubmenuPlugin';
+
+declare const textStyle: SubmenuPlugin;
+
+export default textStyle;
\ No newline at end of file
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+export default {
+ name: 'textStyle',
+ display: 'submenu',
+ add: function (core, targetElement) {
+ const context = core.context;
+ context.textStyle = {
+ _styleList: null
+ };
+
+ /** set submenu */
+ let listDiv = this.setSubmenu.call(core);
+ let listUl = listDiv.querySelector('ul');
+
+ /** add event listeners */
+ listUl.addEventListener('click', this.pickup.bind(core));
+
+ context.textStyle._styleList = listDiv.querySelectorAll('li button');
+
+ /** append target button menu */
+ core.initMenuTarget(this.name, targetElement, listDiv);
+
+ /** empty memory */
+ listDiv = null, listUl = null;
+ },
+
+ setSubmenu: function () {
+ const option = this.context.option;
+ const listDiv = this.util.createElement('DIV');
+ listDiv.className = 'se-submenu se-list-layer se-list-format';
+
+ const defaultList = {
+ code: {
+ name: this.lang.menu.code,
+ class: '__se__t-code',
+ tag: 'code',
+ },
+ translucent: {
+ name: this.lang.menu.translucent,
+ style: 'opacity: 0.5;',
+ tag: 'span',
+ },
+ shadow: {
+ name: this.lang.menu.shadow,
+ class: '__se__t-shadow',
+ tag: 'span',
+ }
+ };
+ const styleList = !option.textStyles ? this._w.Object.keys(defaultList) : option.textStyles;
+
+ let list = '<div class="se-list-inner"><ul class="se-list-basic">';
+ for (let i = 0, len = styleList.length, t, tag, name, attrs, command, value, _class; i < len; i++) {
+ t = styleList[i];
+ attrs = '', value = '', command = [];
+
+ if (typeof t === 'string') {
+ const defaultStyle = defaultList[t.toLowerCase()];
+ if (!defaultStyle) continue;
+ t = defaultStyle;
+ }
+
+ name = t.name;
+ tag = t.tag || 'span';
+ _class = t._class;
+
+ if (t.style) {
+ attrs += ' style="' + t.style + '"';
+ value += t.style.replace(/:[^;]+(;|$)\s*/g, ',');
+ command.push('style');
+ }
+ if (t.class) {
+ attrs += ' class="' + t.class + '"';
+ value += '.' + t.class.trim().replace(/\s+/g, ',.');
+ command.push('class');
+ }
+
+ value = value.replace(/,$/, '');
+
+ list += '<li>' +
+ '<button type="button" class="se-btn-list' + (_class ? ' ' + _class: '') + '" data-command="' + tag + '" data-value="' + value + '" title="' + name + '">' +
+ '<' + tag + attrs + '>' + name + '</' + tag + '>' +
+ '</button></li>';
+ }
+ list += '</ul></div>';
+
+ listDiv.innerHTML = list;
+
+ return listDiv;
+ },
+
+ /**
+ * @Override submenu
+ */
+ on: function () {
+ const util = this.util;
+ const textStyleContext = this.context.textStyle;
+ const styleButtonList = textStyleContext._styleList;
+ const selectionNode = this.getSelectionNode();
+
+ for (let i = 0, len = styleButtonList.length, btn, data, active; i < len; i++) {
+ btn = styleButtonList[i];
+ data = btn.getAttribute('data-value').split(',');
+
+ for (let v = 0, node, value; v < data.length; v++) {
+ node = selectionNode;
+ active = false;
+
+ while (node && !util.isFormatElement(node) && !util.isComponent(node)) {
+ if (node.nodeName.toLowerCase() === btn.getAttribute('data-command').toLowerCase()) {
+ value = data[v];
+ if (/^\./.test(value) ? util.hasClass(node, value.replace(/^\./, '')) : !!node.style[value]) {
+ active = true;
+ break;
+ }
+ }
+ node = node.parentNode;
+ }
+
+ if (!active) break;
+ }
+
+ active ? util.addClass(btn, 'active') : util.removeClass(btn, 'active');
+ }
+
+ },
+
+ pickup: function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ let target = e.target;
+ let command = null, tag = null;
+
+ while (!command && !/UL/i.test(target.tagName)) {
+ command = target.getAttribute('data-command');
+ if (command) {
+ tag = target.firstChild;
+ break;
+ }
+ target = target.parentNode;
+ }
+
+ if (!command) return;
+
+ const checkStyles = tag.style.cssText.replace(/:.+(;|$)/g, ',').split(',');
+ checkStyles.pop();
+
+ const classes = tag.classList;
+ for (let i = 0, len = classes.length; i < len; i++) {
+ checkStyles.push('.' + classes[i]);
+ }
+
+ const newNode = this.util.hasClass(target, 'active') ? null : tag.cloneNode(false);
+ const removeNodes = newNode ? null : [tag.nodeName];
+ this.nodeChange(newNode, checkStyles, removeNodes, true);
+
+ this.submenuOff();
+ }
+};
--- /dev/null
+import { SunEditorOptions } from './options.d';
+import SunEditor from './lib/core';
+
+declare namespace _default {
+ export function init(init_options: SunEditorOptions): { create: typeof create; };
+ export function create(idOrElement: String | Element, options: SunEditorOptions, _init_options?: SunEditorOptions): SunEditor;
+}
+
+export default _default;
--- /dev/null
+/*
+ * wysiwyg web editor
+ *
+ * suneditor.js
+ * Copyright 2017 JiHong Lee.
+ * MIT license.
+ */
+'use strict';
+
+import core from './lib/core';
+import util from './lib/util';
+import _Constructor from './lib/constructor';
+import _Context from './lib/context';
+
+export default {
+ /**
+ * @description Returns the create function with preset options.
+ * If the options overlap, the options of the 'create' function take precedence.
+ * @param {Json} options Initialization options
+ * @returns {Object}
+ */
+ init: function (init_options) {
+ return {
+ create: function (idOrElement, options) {
+ return this.create(idOrElement, options, init_options);
+ }.bind(this)
+ };
+ },
+
+ /**
+ * @description Create the suneditor
+ * @param {String|Element} idOrElement textarea Id or textarea element
+ * @param {JSON|Object} options user options
+ * @returns {Object}
+ */
+ create: function (idOrElement, options, _init_options) {
+ util._propertiesInit();
+
+ if (typeof options !== 'object') options = {};
+ if (_init_options) {
+ options = [_init_options, options].reduce(function (init, option) {
+ for (let key in option) {
+ if (!util.hasOwn(option, key)) continue;
+ if (key === 'plugins' && option[key] && init[key]) {
+ let i = init[key], o = option[key];
+ i = i.length ? i : Object.keys(i).map(function(name) { return i[name]; });
+ o = o.length ? o : Object.keys(o).map(function(name) { return o[name]; });
+ init[key] = (o.filter(function(val) { return i.indexOf(val) === -1; })).concat(i);
+ } else {
+ init[key] = option[key];
+ }
+ }
+ return init;
+ }, {});
+ }
+
+ const element = typeof idOrElement === 'string' ? document.getElementById(idOrElement) : idOrElement;
+
+ if (!element) {
+ if (typeof idOrElement === 'string') {
+ throw Error('[SUNEDITOR.create.fail] The element for that id was not found (ID:"' + idOrElement + '")');
+ }
+
+ throw Error('[SUNEDITOR.create.fail] suneditor requires textarea\'s element or id value');
+ }
+
+ const cons = _Constructor.init(element, options);
+
+ if (cons.constructed._top.id && document.getElementById(cons.constructed._top.id)) {
+ throw Error('[SUNEDITOR.create.fail] The ID of the suneditor you are trying to create already exists (ID:"' + cons.constructed._top.id + '")');
+ }
+
+ return core(_Context(element, cons.constructed, cons.options), cons.pluginCallButtons, cons.plugins, cons.options.lang, options, cons._responsiveButtons);
+ }
+};
--- /dev/null
+'use strict';
+
+import './assets/css/suneditor.css';
+import './assets/css/suneditor-contents.css';
+
+import plugins from './plugins';
+import suneditor from './suneditor';
+
+Object.defineProperty(window, 'SUNEDITOR', {
+ enumerable: true,
+ writable: false,
+ configurable: false,
+ value: suneditor.init({
+ plugins: plugins
+ })
+});
\ No newline at end of file
--- /dev/null
+!function(e){var t={};function n(i){if(t[i])return t[i].exports;var l=t[i]={i:i,l:!1,exports:{}};return e[i].call(l.exports,l,l.exports,n),l.l=!0,l.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var l in e)n.d(i,l,function(t){return e[t]}.bind(null,l));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s="XJR1")}({"1kvd":function(e,t,n){"use strict";var i,l;i="undefined"!=typeof window?window:this,l=function(e,t){const n={name:"dialog",add:function(e){const t=e.context;t.dialog={kind:"",updateModal:!1,_closeSignal:!1};let n=e.util.createElement("DIV");n.className="se-dialog sun-editor-common";let i=e.util.createElement("DIV");i.className="se-dialog-back",i.style.display="none";let l=e.util.createElement("DIV");l.className="se-dialog-inner",l.style.display="none",n.appendChild(i),n.appendChild(l),t.dialog.modalArea=n,t.dialog.back=i,t.dialog.modal=l,t.dialog.modal.addEventListener("mousedown",this._onMouseDown_dialog.bind(e)),t.dialog.modal.addEventListener("click",this._onClick_dialog.bind(e)),t.element.relative.appendChild(n),n=null,i=null,l=null},_onMouseDown_dialog:function(e){/se-dialog-inner/.test(e.target.className)?this.context.dialog._closeSignal=!0:this.context.dialog._closeSignal=!1},_onClick_dialog:function(e){e.stopPropagation(),(/close/.test(e.target.getAttribute("data-command"))||this.context.dialog._closeSignal)&&this.plugins.dialog.close.call(this)},open:function(e,t){if(this.modalForm)return!1;this.plugins.dialog._bindClose&&(this._d.removeEventListener("keydown",this.plugins.dialog._bindClose),this.plugins.dialog._bindClose=null),this.plugins.dialog._bindClose=function(e){/27/.test(e.keyCode)&&this.plugins.dialog.close.call(this)}.bind(this),this._d.addEventListener("keydown",this.plugins.dialog._bindClose),this.context.dialog.updateModal=t,"full"===this.context.option.popupDisplay?this.context.dialog.modalArea.style.position="fixed":this.context.dialog.modalArea.style.position="absolute",this.context.dialog.kind=e,this.modalForm=this.context[e].modal;const n=this.context[e].focusElement;"function"==typeof this.plugins[e].on&&this.plugins[e].on.call(this,t),this.context.dialog.modalArea.style.display="block",this.context.dialog.back.style.display="block",this.context.dialog.modal.style.display="block",this.modalForm.style.display="block",n&&n.focus()},_bindClose:null,close:function(){this.plugins.dialog._bindClose&&(this._d.removeEventListener("keydown",this.plugins.dialog._bindClose),this.plugins.dialog._bindClose=null);const e=this.context.dialog.kind;this.modalForm.style.display="none",this.context.dialog.back.style.display="none",this.context.dialog.modalArea.style.display="none",this.context.dialog.updateModal=!1,"function"==typeof this.plugins[e].init&&this.plugins[e].init.call(this),this.context.dialog.kind="",this.modalForm=null,this.focus()}};return void 0===t&&(e.SUNEDITOR_MODULES||Object.defineProperty(e,"SUNEDITOR_MODULES",{enumerable:!0,writable:!1,configurable:!1,value:{}}),Object.defineProperty(e.SUNEDITOR_MODULES,"dialog",{enumerable:!0,writable:!1,configurable:!1,value:n})),n},"object"==typeof e.exports?e.exports=i.document?l(i,!0):function(e){if(!e.document)throw new Error("SUNEDITOR_MODULES a window with a document");return l(e)}:l(i)},"3FqI":function(e,t,n){},JhlZ:function(e,t,n){"use strict";var i,l;i="undefined"!=typeof window?window:this,l=function(e,t){const n={name:"fileBrowser",_xmlHttp:null,_loading:null,add:function(e){const t=e.context;t.fileBrowser={_closeSignal:!1,area:null,header:null,tagArea:null,body:null,list:null,tagElements:null,items:[],selectedTags:[],selectorHandler:null,contextPlugin:"",columnSize:4};let n=e.util.createElement("DIV");n.className="se-file-browser sun-editor-common";let i=e.util.createElement("DIV");i.className="se-file-browser-back";let l=e.util.createElement("DIV");l.className="se-file-browser-inner",l.innerHTML=this.set_browser(e),n.appendChild(i),n.appendChild(l),this._loading=n.querySelector(".se-loading-box"),t.fileBrowser.area=n,t.fileBrowser.header=l.querySelector(".se-file-browser-header"),t.fileBrowser.titleArea=l.querySelector(".se-file-browser-title"),t.fileBrowser.tagArea=l.querySelector(".se-file-browser-tags"),t.fileBrowser.body=l.querySelector(".se-file-browser-body"),t.fileBrowser.list=l.querySelector(".se-file-browser-list"),t.fileBrowser.tagArea.addEventListener("click",this.onClickTag.bind(e)),t.fileBrowser.list.addEventListener("click",this.onClickFile.bind(e)),l.addEventListener("mousedown",this._onMouseDown_browser.bind(e)),l.addEventListener("click",this._onClick_browser.bind(e)),t.element.relative.appendChild(n),n=null,i=null,l=null},set_browser:function(e){return'<div class="se-file-browser-content"><div class="se-file-browser-header"><button type="button" data-command="close" class="se-btn se-file-browser-close" class="close" aria-label="Close" title="'+e.lang.dialogBox.close+'">'+e.icons.cancel+'</button><span class="se-file-browser-title"></span><div class="se-file-browser-tags"></div></div><div class="se-file-browser-body"><div class="se-loading-box sun-editor-common"><div class="se-loading-effect"></div></div><div class="se-file-browser-list"></div></div></div>'},_onMouseDown_browser:function(e){/se-file-browser-inner/.test(e.target.className)?this.context.fileBrowser._closeSignal=!0:this.context.fileBrowser._closeSignal=!1},_onClick_browser:function(e){e.stopPropagation(),(/close/.test(e.target.getAttribute("data-command"))||this.context.fileBrowser._closeSignal)&&this.plugins.fileBrowser.close.call(this)},open:function(e,t){this.plugins.fileBrowser._bindClose&&(this._d.removeEventListener("keydown",this.plugins.fileBrowser._bindClose),this.plugins.fileBrowser._bindClose=null),this.plugins.fileBrowser._bindClose=function(e){/27/.test(e.keyCode)&&this.plugins.fileBrowser.close.call(this)}.bind(this),this._d.addEventListener("keydown",this.plugins.fileBrowser._bindClose);const n=this.context.fileBrowser;n.contextPlugin=e,n.selectorHandler=t;const i=this.context[e],l=i.listClass;this.util.hasClass(n.list,l)||(n.list.className="se-file-browser-list "+l),"full"===this.context.option.popupDisplay?n.area.style.position="fixed":n.area.style.position="absolute",n.titleArea.textContent=i.title,n.area.style.display="block",this.plugins.fileBrowser._drawFileList.call(this,this.context[e].url)},_bindClose:null,close:function(){const e=this.plugins.fileBrowser;e._xmlHttp&&e._xmlHttp.abort(),e._bindClose&&(this._d.removeEventListener("keydown",e._bindClose),e._bindClose=null);const t=this.context.fileBrowser;t.area.style.display="none",t.selectorHandler=null,t.selectedTags=[],t.items=[],t.list.innerHTML=t.tagArea.innerHTML=t.titleArea.textContent="","function"==typeof this.plugins[t.contextPlugin].init&&this.plugins[t.contextPlugin].init.call(this),t.contextPlugin=""},showBrowserLoading:function(){this._loading.style.display="block"},closeBrowserLoading:function(){this._loading.style.display="none"},_drawFileList:function(e){const t=this.plugins.fileBrowser,n=t._xmlHttp=this.util.getXMLHttpRequest();n.onreadystatechange=t._callBackGet.bind(this,n),n.open("get",e,!0),n.send(null),this.plugins.fileBrowser.showBrowserLoading()},_callBackGet:function(e){if(4===e.readyState)if(this.plugins.fileBrowser._xmlHttp=null,200===e.status)try{this.plugins.fileBrowser._drawListItem.call(this,JSON.parse(e.responseText).result,!0)}catch(e){throw Error('[SUNEDITOR.fileBrowser.drawList.fail] cause : "'+e.message+'"')}finally{this.plugins.fileBrowser.closeBrowserLoading(),this.context.fileBrowser.body.style.maxHeight=this._w.innerHeight-this.context.fileBrowser.header.offsetHeight-50+"px"}else if(this.plugins.fileBrowser.closeBrowserLoading(),0!==e.status){const t=e.responseText?JSON.parse(e.responseText):e,n="[SUNEDITOR.fileBrowser.get.serverException] status: "+e.status+", response: "+(t.errorMessage||e.responseText);throw Error(n)}},_drawListItem:function(e,t){const n=this.context.fileBrowser,i=this.context[n.contextPlugin],l=[],o=e.length,s=i.columnSize||n.columnSize,a=s<=1?1:Math.round(o/s)||1,r=i.itemTemplateHandler;let c="",d='<div class="se-file-item-column">',u=1;for(let n,i,h=0;h<o;h++)if(n=e[h],i=n.tag?"string"==typeof n.tag?n.tag.split(","):n.tag:[],i=n.tag=i.map((function(e){return e.trim()})),d+=r(n),(h+1)%a==0&&u<s&&h+1<o&&(u++,d+='</div><div class="se-file-item-column">'),t&&i.length>0)for(let e,t=0,n=i.length;t<n;t++)e=i[t],e&&-1===l.indexOf(e)&&(l.push(e),c+='<a title="'+e+'">'+e+"</a>");d+="</div>",n.list.innerHTML=d,t&&(n.items=e,n.tagArea.innerHTML=c,n.tagElements=n.tagArea.querySelectorAll("A"))},onClickTag:function(e){const t=e.target;if(!this.util.isAnchor(t))return;const n=t.textContent,i=this.plugins.fileBrowser,l=this.context.fileBrowser,o=l.tagArea.querySelector('a[title="'+n+'"]'),s=l.selectedTags,a=s.indexOf(n);a>-1?(s.splice(a,1),this.util.removeClass(o,"on")):(s.push(n),this.util.addClass(o,"on")),i._drawListItem.call(this,0===s.length?l.items:l.items.filter((function(e){return e.tag.some((function(e){return s.indexOf(e)>-1}))})),!1)},onClickFile:function(e){e.preventDefault(),e.stopPropagation();const t=this.context.fileBrowser,n=t.list;let i=e.target,l=null;if(i===n)return;for(;n!==i.parentNode&&(l=i.getAttribute("data-command"),!l);)i=i.parentNode;if(!l)return;const o=t.selectorHandler||this.context[t.contextPlugin].selectorHandler;this.plugins.fileBrowser.close.call(this),o(i)}};return void 0===t&&(e.SUNEDITOR_MODULES||Object.defineProperty(e,"SUNEDITOR_MODULES",{enumerable:!0,writable:!1,configurable:!1,value:{}}),Object.defineProperty(e.SUNEDITOR_MODULES,"fileBrowser",{enumerable:!0,writable:!1,configurable:!1,value:n})),n},"object"==typeof e.exports?e.exports=i.document?l(i,!0):function(e){if(!e.document)throw new Error("SUNEDITOR_MODULES a window with a document");return l(e)}:l(i)},P6u4:function(e,t,n){"use strict";var i,l;i="undefined"!=typeof window?window:this,l=function(e,t){const n={code:"en",toolbar:{default:"Default",save:"Save",font:"Font",formats:"Formats",fontSize:"Size",bold:"Bold",underline:"Underline",italic:"Italic",strike:"Strike",subscript:"Subscript",superscript:"Superscript",removeFormat:"Remove Format",fontColor:"Font Color",hiliteColor:"Highlight Color",indent:"Indent",outdent:"Outdent",align:"Align",alignLeft:"Align left",alignRight:"Align right",alignCenter:"Align center",alignJustify:"Align justify",list:"List",orderList:"Ordered list",unorderList:"Unordered list",horizontalRule:"Horizontal line",hr_solid:"Solid",hr_dotted:"Dotted",hr_dashed:"Dashed",table:"Table",link:"Link",math:"Math",image:"Image",video:"Video",audio:"Audio",fullScreen:"Full screen",showBlocks:"Show blocks",codeView:"Code view",undo:"Undo",redo:"Redo",preview:"Preview",print:"print",tag_p:"Paragraph",tag_div:"Normal (DIV)",tag_h:"Header",tag_blockquote:"Quote",tag_pre:"Code",template:"Template",lineHeight:"Line height",paragraphStyle:"Paragraph style",textStyle:"Text style",imageGallery:"Image gallery",mention:"Mention"},dialogBox:{linkBox:{title:"Insert Link",url:"URL to link",text:"Text to display",newWindowCheck:"Open in new window"},mathBox:{title:"Math",inputLabel:"Mathematical Notation",fontSizeLabel:"Font Size",previewLabel:"Preview"},imageBox:{title:"Insert image",file:"Select from files",url:"Image URL",altText:"Alternative text"},videoBox:{title:"Insert Video",file:"Select from files",url:"Media embed URL, YouTube/Vimeo"},audioBox:{title:"Insert Audio",file:"Select from files",url:"Audio URL"},browser:{tags:"Tags",search:"Search"},caption:"Insert description",close:"Close",submitButton:"Submit",revertButton:"Revert",proportion:"Constrain proportions",basic:"Basic",left:"Left",right:"Right",center:"Center",width:"Width",height:"Height",size:"Size",ratio:"Ratio"},controller:{edit:"Edit",unlink:"Unlink",remove:"Remove",insertRowAbove:"Insert row above",insertRowBelow:"Insert row below",deleteRow:"Delete row",insertColumnBefore:"Insert column before",insertColumnAfter:"Insert column after",deleteColumn:"Delete column",fixedColumnWidth:"Fixed column width",resize100:"Resize 100%",resize75:"Resize 75%",resize50:"Resize 50%",resize25:"Resize 25%",autoSize:"Auto size",mirrorHorizontal:"Mirror, Horizontal",mirrorVertical:"Mirror, Vertical",rotateLeft:"Rotate left",rotateRight:"Rotate right",maxSize:"Max size",minSize:"Min size",tableHeader:"Table header",mergeCells:"Merge cells",splitCells:"Split Cells",HorizontalSplit:"Horizontal split",VerticalSplit:"Vertical split"},menu:{spaced:"Spaced",bordered:"Bordered",neon:"Neon",translucent:"Translucent",shadow:"Shadow",code:"Code"}};return void 0===t&&(e.SUNEDITOR_LANG||Object.defineProperty(e,"SUNEDITOR_LANG",{enumerable:!0,writable:!1,configurable:!1,value:{}}),Object.defineProperty(e.SUNEDITOR_LANG,"en",{enumerable:!0,writable:!0,configurable:!0,value:n})),n},"object"==typeof e.exports?e.exports=i.document?l(i,!0):function(e){if(!e.document)throw new Error("SUNEDITOR_LANG a window with a document");return l(e)}:l(i)},WUQj:function(e,t,n){},XJR1:function(e,t,n){"use strict";n.r(t);n("3FqI"),n("WUQj");var i={name:"colorPicker",add:function(e){const t=e.context;t.colorPicker={colorListHTML:"",_colorInput:"",_defaultColor:"#000",_styleProperty:"color",_currentColor:"",_colorList:[]};let n=this.createColorList(e,this._makeColorList);t.colorPicker.colorListHTML=n,n=null},createColorList:function(e,t){const n=e.context.option,i=e.lang,l=n.colorList&&0!==n.colorList.length?n.colorList:["#ff0000","#ff5e00","#ffe400","#abf200","#00d8ff","#0055ff","#6600ff","#ff00dd","#000000","#ffd8d8","#fae0d4","#faf4c0","#e4f7ba","#d4f4fa","#d9e5ff","#e8d9ff","#ffd9fa","#f1f1f1","#ffa7a7","#ffc19e","#faed7d","#cef279","#b2ebf4","#b2ccff","#d1b2ff","#ffb2f5","#bdbdbd","#f15f5f","#f29661","#e5d85c","#bce55c","#5cd1e5","#6699ff","#a366ff","#f261df","#8c8c8c","#980000","#993800","#998a00","#6b9900","#008299","#003399","#3d0099","#990085","#353535","#670000","#662500","#665c00","#476600","#005766","#002266","#290066","#660058","#222222"];let o=[],s='<div class="se-list-inner">';for(let e,n=0,i=l.length;n<i;n++)e=l[n],e&&("string"==typeof e&&(o.push(e),n<i-1)||(o.length>0&&(s+='<div class="se-selector-color">'+t(o)+"</div>",o=[]),"object"==typeof e&&(s+='<div class="se-selector-color">'+t(e)+"</div>")));return s+='<form class="se-submenu-form-group"><input type="text" maxlength="9" class="_se_color_picker_input se-color-input"/><button type="submit" class="se-btn-primary _se_color_picker_submit" title="'+i.dialogBox.submitButton+'">'+e.icons.checked+'</button><button type="button" class="se-btn _se_color_picker_remove" title="'+i.toolbar.removeFormat+'">'+e.icons.erase+"</button></form></div>",s},_makeColorList:function(e){let t="";t+='<ul class="se-color-pallet">';for(let n,i=0,l=e.length;i<l;i++)n=e[i],"string"==typeof n&&(t+='<li><button type="button" data-value="'+n+'" title="'+n+'" style="background-color:'+n+';"></button></li>');return t+="</ul>",t},init:function(e,t){const n=this.plugins.colorPicker;let i=t||(n.getColorInNode.call(this,e)||this.context.colorPicker._defaultColor);i=n.isHexColor(i)?i:n.rgb2hex(i)||i;const l=this.context.colorPicker._colorList;if(l)for(let e=0,t=l.length;e<t;e++)i.toLowerCase()===l[e].getAttribute("data-value").toLowerCase()?this.util.addClass(l[e],"active"):this.util.removeClass(l[e],"active");n.setInputText.call(this,n.colorName2hex.call(this,i))},setCurrentColor:function(e){this.context.colorPicker._currentColor=e,this.context.colorPicker._colorInput.style.borderColor=e},setInputText:function(e){e=/^#/.test(e)?e:"#"+e,this.context.colorPicker._colorInput.value=e,this.plugins.colorPicker.setCurrentColor.call(this,e)},getColorInNode:function(e){let t="";const n=this.context.colorPicker._styleProperty;for(;e&&!this.util.isWysiwygDiv(e)&&0===t.length;)1===e.nodeType&&e.style[n]&&(t=e.style[n]),e=e.parentNode;return t},isHexColor:function(e){return/^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(e)},rgb2hex:function(e){const t=e.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);return t&&4===t.length?"#"+("0"+parseInt(t[1],10).toString(16)).slice(-2)+("0"+parseInt(t[2],10).toString(16)).slice(-2)+("0"+parseInt(t[3],10).toString(16)).slice(-2):""},colorName2hex:function(e){if(/^#/.test(e))return e;var t=this.util.createElement("div");t.style.display="none",t.style.color=e;var n=this._w.getComputedStyle(this._d.body.appendChild(t)).color.match(/\d+/g).map((function(e){return parseInt(e,10)}));return this.util.removeItem(t),n.length>=3&&"#"+((1<<24)+(n[0]<<16)+(n[1]<<8)+n[2]).toString(16).substr(1)}},l={name:"fontColor",display:"submenu",add:function(e,t){e.addModule([i]);const n=e.context;n.fontColor={previewEl:null,colorInput:null,colorList:null};let l=this.setSubmenu.call(e);n.fontColor.colorInput=l.querySelector("._se_color_picker_input"),n.fontColor.colorInput.addEventListener("keyup",this.onChangeInput.bind(e)),l.querySelector("._se_color_picker_submit").addEventListener("click",this.submit.bind(e)),l.querySelector("._se_color_picker_remove").addEventListener("click",this.remove.bind(e)),l.addEventListener("click",this.pickup.bind(e)),n.fontColor.colorList=l.querySelectorAll("li button"),e.initMenuTarget(this.name,t,l),l=null},setSubmenu:function(){const e=this.context.colorPicker.colorListHTML,t=this.util.createElement("DIV");return t.className="se-submenu se-list-layer",t.innerHTML=e,t},on:function(){const e=this.context.colorPicker,t=this.context.fontColor;e._colorInput=t.colorInput,e._defaultColor="#333333",e._styleProperty="color",e._colorList=t.colorList,this.plugins.colorPicker.init.call(this,this.getSelectionNode(),null)},onChangeInput:function(e){this.plugins.colorPicker.setCurrentColor.call(this,e.target.value)},submit:function(){this.plugins.fontColor.applyColor.call(this,this.context.colorPicker._currentColor)},pickup:function(e){e.preventDefault(),e.stopPropagation(),this.plugins.fontColor.applyColor.call(this,e.target.getAttribute("data-value"))},remove:function(){this.nodeChange(null,["color"],["span"],!0),this.submenuOff()},applyColor:function(e){if(!e)return;const t=this.util.createElement("SPAN");t.style.color=e,this.nodeChange(t,["color"],null,null),this.submenuOff()}},o={name:"hiliteColor",display:"submenu",add:function(e,t){e.addModule([i]);const n=e.context;n.hiliteColor={previewEl:null,colorInput:null,colorList:null};let l=this.setSubmenu.call(e);n.hiliteColor.colorInput=l.querySelector("._se_color_picker_input"),n.hiliteColor.colorInput.addEventListener("keyup",this.onChangeInput.bind(e)),l.querySelector("._se_color_picker_submit").addEventListener("click",this.submit.bind(e)),l.querySelector("._se_color_picker_remove").addEventListener("click",this.remove.bind(e)),l.addEventListener("click",this.pickup.bind(e)),n.hiliteColor.colorList=l.querySelectorAll("li button"),e.initMenuTarget(this.name,t,l),l=null},setSubmenu:function(){const e=this.context.colorPicker.colorListHTML,t=this.util.createElement("DIV");return t.className="se-submenu se-list-layer",t.innerHTML=e,t},on:function(){const e=this.context.colorPicker,t=this.context.hiliteColor;e._colorInput=t.colorInput,e._defaultColor="#FFFFFF",e._styleProperty="backgroundColor",e._colorList=t.colorList,this.plugins.colorPicker.init.call(this,this.getSelectionNode(),null)},onChangeInput:function(e){this.plugins.colorPicker.setCurrentColor.call(this,e.target.value)},submit:function(){this.plugins.hiliteColor.applyColor.call(this,this.context.colorPicker._currentColor)},pickup:function(e){e.preventDefault(),e.stopPropagation(),this.plugins.hiliteColor.applyColor.call(this,e.target.getAttribute("data-value"))},remove:function(){this.nodeChange(null,["background-color"],["span"],!0),this.submenuOff()},applyColor:function(e){if(!e)return;const t=this.util.createElement("SPAN");t.style.backgroundColor=e,this.nodeChange(t,["background-color"],null,null),this.submenuOff()}},s={name:"template",display:"submenu",add:function(e,t){e.context.template={};let n=this.setSubmenu.call(e);n.querySelector("ul").addEventListener("click",this.pickup.bind(e)),e.initMenuTarget(this.name,t,n),n=null},setSubmenu:function(){const e=this.context.option.templates;if(!e||0===e.length)throw Error('[SUNEDITOR.plugins.template.fail] To use the "template" plugin, please define the "templates" option.');const t=this.util.createElement("DIV");t.className="se-list-layer";let n='<div class="se-submenu se-list-inner"><ul class="se-list-basic">';for(let t,i=0,l=e.length;i<l;i++)t=e[i],n+='<li><button type="button" class="se-btn-list" data-value="'+i+'" title="'+t.name+'">'+t.name+"</button></li>";return n+="</ul></div>",t.innerHTML=n,t},pickup:function(e){if(!/^BUTTON$/i.test(e.target.tagName))return!1;e.preventDefault(),e.stopPropagation();const t=this.context.option.templates[e.target.getAttribute("data-value")];if(!t.html)throw this.submenuOff(),Error('[SUNEDITOR.template.fail] cause : "templates[i].html not found"');this.setContents(t.html),this.submenuOff()}},a=n("1kvd"),r=n.n(a),c={name:"link",display:"dialog",add:function(e){e.addModule([r.a]);const t=e.context;t.link={focusElement:null,linkNewWindowCheck:null,linkAnchorText:null,_linkAnchor:null,_linkValue:""};let n=this.setDialog.call(e);t.link.modal=n,t.link.focusElement=n.querySelector("._se_link_url"),t.link.linkAnchorText=n.querySelector("._se_link_text"),t.link.linkNewWindowCheck=n.querySelector("._se_link_check"),t.link.preview=n.querySelector(".se-link-preview");let i=this.setController_LinkButton.call(e);t.link.linkController=i,t.link._linkAnchor=null,i.addEventListener("mousedown",e.eventStop),n.querySelector(".se-btn-primary").addEventListener("click",this.submit.bind(e)),i.addEventListener("click",this.onClick_linkController.bind(e)),t.link.focusElement.addEventListener("input",this._onLinkPreview.bind(t.link.preview,t.link,t.options.linkProtocol)),t.dialog.modal.appendChild(n),t.element.relative.appendChild(i),n=null,i=null},setDialog:function(){const e=this.lang,t=this.util.createElement("DIV");return t.className="se-dialog-content",t.style.display="none",t.innerHTML='<form class="editor_link"><div class="se-dialog-header"><button type="button" data-command="close" class="se-btn se-dialog-close" aria-label="Close" title="'+e.dialogBox.close+'">'+this.icons.cancel+'</button><span class="se-modal-title">'+e.dialogBox.linkBox.title+'</span></div><div class="se-dialog-body"><div class="se-dialog-form"><label>'+e.dialogBox.linkBox.url+'</label><input class="se-input-form se-input-url _se_link_url" type="text" /><pre class="se-link-preview"></pre></div><div class="se-dialog-form"><label>'+e.dialogBox.linkBox.text+'</label><input class="se-input-form _se_link_text" type="text" /></div><div class="se-dialog-form-footer"><label><input type="checkbox" class="se-dialog-btn-check _se_link_check" /> '+e.dialogBox.linkBox.newWindowCheck+'</label></div></div><div class="se-dialog-footer"><button type="submit" class="se-btn-primary" title="'+e.dialogBox.submitButton+'"><span>'+e.dialogBox.submitButton+"</span></button></div></form>",t},setController_LinkButton:function(){const e=this.lang,t=this.icons,n=this.util.createElement("DIV");return n.className="se-controller se-controller-link",n.innerHTML='<div class="se-arrow se-arrow-up"></div><div class="link-content"><span><a target="_blank" href=""></a> </span><div class="se-btn-group"><button type="button" data-command="update" tabindex="-1" class="se-btn se-tooltip">'+t.edit+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.edit+'</span></span></button><button type="button" data-command="unlink" tabindex="-1" class="se-btn se-tooltip">'+t.unlink+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.unlink+'</span></span></button><button type="button" data-command="delete" tabindex="-1" class="se-btn se-tooltip">'+t.delete+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.remove+"</span></span></button></div></div>",n},open:function(){this.plugins.dialog.open.call(this,"link","link"===this.currentControllerName)},_onLinkPreview:function(e,t,n){const i=n.target.value.trim();e._linkValue=this.textContent=i?t&&-1===i.indexOf("://")&&0!==i.indexOf("#")?t+i:-1===i.indexOf("://")?"/"+i:i:""},submit:function(e){this.showLoading(),e.preventDefault(),e.stopPropagation();const t=function(){const e=this.context.link;if(0===e._linkValue.length)return!1;const t=e._linkValue,n=e.linkAnchorText,i=0===n.value.length?t:n.value;if(this.context.dialog.updateModal){e._linkAnchor.href=t,e._linkAnchor.textContent=i,e._linkAnchor.target=e.linkNewWindowCheck.checked?"_blank":"";const n=e._linkAnchor.childNodes[0];this.setRange(n,0,n,n.textContent.length)}else{const n=this.util.createElement("A");n.href=t,n.textContent=i,n.target=e.linkNewWindowCheck.checked?"_blank":"";const l=this.getSelectedElements();if(l.length>1){const e=this.util.createElement(l[0].nodeName);if(e.appendChild(n),!this.insertNode(e,null,!0))return}else if(!this.insertNode(n,null,!0))return;this.setRange(n.childNodes[0],0,n.childNodes[0],n.textContent.length)}e._linkValue=e.preview.textContent=e.focusElement.value=e.linkAnchorText.value=""}.bind(this);try{t()}finally{this.plugins.dialog.close.call(this),this.closeLoading(),this.history.push(!1)}return!1},active:function(e){if(e){if(this.util.isAnchor(e)&&null===e.getAttribute("data-image-link"))return this.controllerArray.indexOf(this.context.link.linkController)<0&&this.plugins.link.call_controller.call(this,e),!0}else this.controllerArray.indexOf(this.context.link.linkController)>-1&&this.controllersOff();return!1},on:function(e){const t=this.context.link;e?t._linkAnchor&&(this.context.dialog.updateModal=!0,t._linkValue=t.preview.textContent=t.focusElement.value=t._linkAnchor.href,t.linkAnchorText.value=t._linkAnchor.textContent,t.linkNewWindowCheck.checked=!!/_blank/i.test(t._linkAnchor.target)):(this.plugins.link.init.call(this),t.linkAnchorText.value=this.getSelection().toString())},call_controller:function(e){this.editLink=this.context.link._linkAnchor=e;const t=this.context.link.linkController,n=t.querySelector("a");n.href=e.href,n.title=e.textContent,n.textContent=e.textContent,this.setControllerPosition(t,e,"bottom",{left:0,top:0}),this.controllersOn(t,e,"link")},onClick_linkController:function(e){e.stopPropagation();const t=e.target.getAttribute("data-command")||e.target.parentNode.getAttribute("data-command");if(t){if(e.preventDefault(),/update/.test(t)){const e=this.context.link;e._linkValue=e.preview.textContent=e.focusElement.value=e._linkAnchor.href,e.linkAnchorText.value=e._linkAnchor.textContent,e.linkNewWindowCheck.checked=!!/_blank/i.test(e._linkAnchor.target),this.plugins.dialog.open.call(this,"link",!0)}else if(/unlink/.test(t)){const e=this.util.getChildElement(this.context.link._linkAnchor,(function(e){return 0===e.childNodes.length||3===e.nodeType}),!1),t=this.util.getChildElement(this.context.link._linkAnchor,(function(e){return 0===e.childNodes.length||3===e.nodeType}),!0);this.setRange(e,0,t,t.textContent.length),this.nodeChange(null,null,["A"],!1)}else this.util.removeItem(this.context.link._linkAnchor),this.context.link._linkAnchor=null,this.focus(),this.history.push(!1);this.controllersOff()}},init:function(){const e=this.context.link;e.linkController.style.display="none",e._linkAnchor=null,e._linkValue=e.preview.textContent=e.focusElement.value="",e.linkAnchorText.value="",e.linkNewWindowCheck.checked=!1}},d=n("ZED3"),u=n.n(d),h=n("ee5k"),g=n.n(h),p=n("gjS+"),m=n.n(p),f={name:"image",display:"dialog",add:function(e){e.addModule([r.a,u.a,g.a,m.a]);const t=e.context,n=t.image={_infoList:[],_infoIndex:0,_uploadFileLength:0,sizeUnit:t.option._imageSizeUnit,_altText:"",_linkElement:null,_align:"none",_floatClassRegExp:"__se__float\\-[a-z]+",_v_link:{_linkValue:""},_v_src:{_linkValue:""},svgDefaultSize:"30%",base64RenderIndex:0,_element:null,_cover:null,_container:null,inputX:null,inputY:null,_element_w:1,_element_h:1,_element_l:0,_element_t:0,_defaultSizeX:"auto",_defaultSizeY:"auto",_origin_w:"auto"===t.option.imageWidth?"":t.option.imageWidth,_origin_h:"auto"===t.option.imageHeight?"":t.option.imageHeight,_proportionChecked:!0,_resizing:t.option.imageResizing,_resizeDotHide:!t.option.imageHeightShow,_rotation:t.option.imageRotation,_onlyPercentage:t.option.imageSizeOnlyPercentage,_ratio:!1,_ratioX:1,_ratioY:1,_captionShow:!0,_captionChecked:!1,_caption:null,captionCheckEl:null};let i=this.setDialog.call(e);n.modal=i,n.imgInputFile=i.querySelector("._se_image_file"),n.imgUrlFile=i.querySelector("._se_image_url"),n.focusElement=n.imgInputFile||n.imgUrlFile,n.altText=i.querySelector("._se_image_alt"),n.imgLink=i.querySelector("._se_image_link"),n.imgLinkNewWindowCheck=i.querySelector("._se_image_link_check"),n.captionCheckEl=i.querySelector("._se_image_check_caption"),n.previewLink=i.querySelector("._se_tab_content_url .se-link-preview"),n.previewSrc=i.querySelector("._se_tab_content_image .se-link-preview"),i.querySelector(".se-dialog-tabs").addEventListener("click",this.openTab.bind(e)),i.querySelector(".se-btn-primary").addEventListener("click",this.submit.bind(e)),n.imgInputFile&&i.querySelector(".se-file-remove").addEventListener("click",this._removeSelectedFiles.bind(n.imgInputFile,n.imgUrlFile,n.previewSrc)),n.imgInputFile&&n.imgUrlFile&&n.imgInputFile.addEventListener("change",this._fileInputChange.bind(n)),n.imgLink.addEventListener("input",this._onLinkPreview.bind(n.previewLink,n._v_link,t.options.linkProtocol)),n.imgUrlFile&&n.imgUrlFile.addEventListener("input",this._onLinkPreview.bind(n.previewSrc,n._v_src,t.options.linkProtocol));const l=i.querySelector(".__se__gallery");l&&l.addEventListener("click",this._openGallery.bind(e)),n.proportion={},n.inputX={},n.inputY={},t.option.imageResizing&&(n.proportion=i.querySelector("._se_image_check_proportion"),n.inputX=i.querySelector("._se_image_size_x"),n.inputY=i.querySelector("._se_image_size_y"),n.inputX.value=t.option.imageWidth,n.inputY.value=t.option.imageHeight,n.inputX.addEventListener("keyup",this.setInputSize.bind(e,"x")),n.inputY.addEventListener("keyup",this.setInputSize.bind(e,"y")),n.inputX.addEventListener("change",this.setRatio.bind(e)),n.inputY.addEventListener("change",this.setRatio.bind(e)),n.proportion.addEventListener("change",this.setRatio.bind(e)),i.querySelector(".se-dialog-btn-revert").addEventListener("click",this.sizeRevert.bind(e))),t.dialog.modal.appendChild(i),i=null},setDialog:function(){const e=this.context.option,t=this.lang,n=this.util.createElement("DIV");n.className="se-dialog-content",n.style.display="none";let i='<div class="se-dialog-header"><button type="button" data-command="close" class="se-btn se-dialog-close" class="close" aria-label="Close" title="'+t.dialogBox.close+'">'+this.icons.cancel+'</button><span class="se-modal-title">'+t.dialogBox.imageBox.title+'</span></div><div class="se-dialog-tabs"><button type="button" class="_se_tab_link active" data-tab-link="image">'+t.toolbar.image+'</button><button type="button" class="_se_tab_link" data-tab-link="url">'+t.toolbar.link+'</button></div><form method="post" enctype="multipart/form-data"><div class="_se_tab_content _se_tab_content_image"><div class="se-dialog-body"><div style="border-bottom: 1px dashed #ccc;">';if(e.imageFileInput&&(i+='<div class="se-dialog-form"><label>'+t.dialogBox.imageBox.file+'</label><div class="se-dialog-form-files"><input class="se-input-form _se_image_file" type="file" accept="'+e.imageAccept+'"'+(e.imageMultipleFile?' multiple="multiple"':"")+'/><button type="button" class="se-btn se-dialog-files-edge-button se-file-remove" title="'+t.controller.remove+'">'+this.icons.cancel+"</button></div></div>"),e.imageUrlInput&&(i+='<div class="se-dialog-form"><label>'+t.dialogBox.imageBox.url+'</label><div class="se-dialog-form-files"><input class="se-input-form se-input-url _se_image_url" type="text" />'+(e.imageGalleryUrl&&this.plugins.imageGallery?'<button type="button" class="se-btn se-dialog-files-edge-button __se__gallery" title="'+t.toolbar.imageGallery+'">'+this.icons.image_gallery+"</button>":"")+'</div><pre class="se-link-preview"></pre></div>'),i+='</div><div class="se-dialog-form"><label>'+t.dialogBox.imageBox.altText+'</label><input class="se-input-form _se_image_alt" type="text" /></div>',e.imageResizing){const n=e.imageSizeOnlyPercentage,l=n?' style="display: none !important;"':"",o=e.imageHeightShow?"":' style="display: none !important;"';i+='<div class="se-dialog-form">',n||!e.imageHeightShow?i+='<div class="se-dialog-size-text"><label class="size-w">'+t.dialogBox.size+"</label></div>":i+='<div class="se-dialog-size-text"><label class="size-w">'+t.dialogBox.width+'</label><label class="se-dialog-size-x"> </label><label class="size-h">'+t.dialogBox.height+"</label></div>",i+='<input class="se-input-control _se_image_size_x" placeholder="auto"'+(n?' type="number" min="1"':'type="text"')+(n?' max="100"':"")+' /><label class="se-dialog-size-x"'+o+">"+(n?"%":"x")+'</label><input type="text" class="se-input-control _se_image_size_y" placeholder="auto"'+l+(n?' max="100"':"")+o+"/><label"+l+o+'><input type="checkbox" class="se-dialog-btn-check _se_image_check_proportion" checked/> '+t.dialogBox.proportion+'</label><button type="button" title="'+t.dialogBox.revertButton+'" class="se-btn se-dialog-btn-revert" style="float: right;">'+this.icons.revert+"</button></div>"}return i+='<div class="se-dialog-form se-dialog-form-footer"><label><input type="checkbox" class="se-dialog-btn-check _se_image_check_caption" /> '+t.dialogBox.caption+'</label></div></div></div><div class="_se_tab_content _se_tab_content_url" style="display: none"><div class="se-dialog-body"><div class="se-dialog-form"><label>'+t.dialogBox.linkBox.url+'</label><input class="se-input-form se-input-url _se_image_link" type="text" /><pre class="se-link-preview"></pre></div><label><input type="checkbox" class="_se_image_link_check"/> '+t.dialogBox.linkBox.newWindowCheck+'</label></div></div><div class="se-dialog-footer"><div><label><input type="radio" name="suneditor_image_radio" class="se-dialog-btn-radio" value="none" checked>'+t.dialogBox.basic+'</label><label><input type="radio" name="suneditor_image_radio" class="se-dialog-btn-radio" value="left">'+t.dialogBox.left+'</label><label><input type="radio" name="suneditor_image_radio" class="se-dialog-btn-radio" value="center">'+t.dialogBox.center+'</label><label><input type="radio" name="suneditor_image_radio" class="se-dialog-btn-radio" value="right">'+t.dialogBox.right+'</label></div><button type="submit" class="se-btn-primary" title="'+t.dialogBox.submitButton+'"><span>'+t.dialogBox.submitButton+"</span></button></div></form>",n.innerHTML=i,n},_fileInputChange:function(){this.imgInputFile.value?(this.imgUrlFile.setAttribute("disabled",!0),this.previewSrc.style.textDecoration="line-through"):(this.imgUrlFile.removeAttribute("disabled"),this.previewSrc.style.textDecoration="")},_removeSelectedFiles:function(e,t){this.value="",e&&(e.removeAttribute("disabled"),t.style.textDecoration="")},_openGallery:function(){this.callPlugin("imageGallery",this.plugins.imageGallery.open.bind(this,this.plugins.image._setUrlInput.bind(this.context.image)),null)},_setUrlInput:function(e){this.altText.value=e.alt,this._v_src._linkValue=this.previewSrc.textContent=this.imgUrlFile.value=e.src,this.imgUrlFile.focus()},_onLinkPreview:function(e,t,n){const i=n.target.value.trim();e._linkValue=this.textContent=i?t&&-1===i.indexOf("://")&&0!==i.indexOf("#")?t+i:-1===i.indexOf("://")?"/"+i:i:""},fileTags:["img"],select:function(e){this.plugins.image.onModifyMode.call(this,e,this.plugins.resizing.call_controller_resize.call(this,e,"image"))},destroy:function(e){const t=e||this.context.image._element,n=this.util.getParentElement(t,this.util.isMediaComponent)||t,i=1*t.getAttribute("data-index");let l=n.previousElementSibling||n.nextElementSibling;const o=n.parentNode;this.util.removeItem(n),this.plugins.image.init.call(this),this.controllersOff(),o!==this.context.element.wysiwyg&&this.util.removeItemAllParents(o,(function(e){return 0===e.childNodes.length}),null),this.focusEdge(l),this.plugins.fileManager.deleteInfo.call(this,"image",i,this.functions.onImageUpload),this.history.push(!1)},on:function(e){const t=this.context.image;e?t.imgInputFile&&this.context.options.imageMultipleFile&&t.imgInputFile.removeAttribute("multiple"):(t.inputX.value=t._origin_w=this.context.option.imageWidth===t._defaultSizeX?"":this.context.option.imageWidth,t.inputY.value=t._origin_h=this.context.option.imageHeight===t._defaultSizeY?"":this.context.option.imageHeight,t.imgInputFile&&this.context.options.imageMultipleFile&&t.imgInputFile.setAttribute("multiple","multiple"))},open:function(){this.plugins.dialog.open.call(this,"image","image"===this.currentControllerName)},openTab:function(e){const t=this.context.image.modal,n="init"===e?t.querySelector("._se_tab_link"):e.target;if(!/^BUTTON$/i.test(n.tagName))return!1;const i=n.getAttribute("data-tab-link");let l,o,s;for(o=t.getElementsByClassName("_se_tab_content"),l=0;l<o.length;l++)o[l].style.display="none";for(s=t.getElementsByClassName("_se_tab_link"),l=0;l<s.length;l++)this.util.removeClass(s[l],"active");return t.querySelector("._se_tab_content_"+i).style.display="block",this.util.addClass(n,"active"),"image"===i&&this.context.image.focusElement?this.context.image.focusElement.focus():"url"===i&&this.context.image.imgLink&&this.context.image.imgLink.focus(),!1},submit:function(e){const t=this.context.image,n=this.plugins.image;e.preventDefault(),e.stopPropagation(),t._altText=t.altText.value,t._align=t.modal.querySelector('input[name="suneditor_image_radio"]:checked').value,t._captionChecked=t.captionCheckEl.checked,t._resizing&&(t._proportionChecked=t.proportion.checked);try{this.context.dialog.updateModal&&n.update_image.call(this,!1,!0,!1),t.imgInputFile&&t.imgInputFile.files.length>0?(this.showLoading(),n.submitAction.call(this,this.context.image.imgInputFile.files)):t.imgUrlFile&&t._v_src._linkValue.length>0&&(this.showLoading(),n.onRender_imgUrl.call(this))}catch(e){throw this.closeLoading(),Error('[SUNEDITOR.image.submit.fail] cause : "'+e.message+'"')}finally{this.plugins.dialog.close.call(this)}return!1},submitAction:function(e){if(0===e.length)return;let t=0,n=[];for(let i=0,l=e.length;i<l;i++)/image/i.test(e[i].type)&&(n.push(e[i]),t+=e[i].size);const i=this.context.option.imageUploadSizeLimit;if(i>0){let e=0;const n=this.context.image._infoList;for(let t=0,i=n.length;t<i;t++)e+=1*n[t].size;if(t+e>i){this.closeLoading();const n="[SUNEDITOR.imageUpload.fail] Size of uploadable total images: "+i/1e3+"KB";return void(("function"!==this.functions.onImageUploadError||this.functions.onImageUploadError(n,{limitSize:i,currentSize:e,uploadSize:t},this))&&this.functions.noticeOpen(n))}}const l=this.context.image;l._uploadFileLength=n.length;const o={linkValue:l._v_link._linkValue,linkNewWindow:l.imgLinkNewWindowCheck.checked,inputWidth:l.inputX.value,inputHeight:l.inputY.value,align:l._align,isUpdate:this.context.dialog.updateModal,element:l._element};if("function"==typeof this.functions.onImageUploadBefore){const e=this.functions.onImageUploadBefore(n,o,this,function(e){e&&this._w.Array.isArray(e.result)?this.plugins.image.register.call(this,o,e):this.plugins.image.upload.call(this,o,e)}.bind(this));if(void 0===e)return;if(!e)return void this.closeLoading();this._w.Array.isArray(e)&&e.length>0&&(n=e)}this.plugins.image.upload.call(this,o,n)},error:function(e,t){if(this.closeLoading(),"function"!=typeof this.functions.onImageUploadError||this.functions.onImageUploadError(e,t,this))throw this.functions.noticeOpen(e),Error("[SUNEDITOR.plugin.image.error] response: "+e)},upload:function(e,t){if(!t)return void this.closeLoading();if("string"==typeof t)return void this.plugins.image.error.call(this,t,null);const n=this.context.option.imageUploadUrl,i=this.context.dialog.updateModal?1:t.length;if("string"==typeof n&&n.length>0){const l=new FormData;for(let e=0;e<i;e++)l.append("file-"+e,t[e]);this.plugins.fileManager.upload.call(this,n,this.context.option.imageUploadHeader,l,this.plugins.image.callBack_imgUpload.bind(this,e),this.functions.onImageUploadError)}else this.plugins.image.setup_reader.call(this,t,e.linkValue,e.linkNewWindow,e.inputWidth,e.inputHeight,e.align,i,e.isUpdate)},callBack_imgUpload:function(e,t){if("function"==typeof this.functions.imageUploadHandler)this.functions.imageUploadHandler(t,e,this);else{const n=JSON.parse(t.responseText);n.errorMessage?this.plugins.image.error.call(this,n.errorMessage,n):this.plugins.image.register.call(this,e,n)}},register:function(e,t){const n=t.result;for(let t,i=0,l=n.length;i<l;i++){if(t={name:n[i].name,size:n[i].size},e.isUpdate){this.plugins.image.update_src.call(this,n[i].url,e.element,t);break}this.plugins.image.create_image.call(this,n[i].url,e.linkValue,e.linkNewWindow,e.inputWidth,e.inputHeight,e.align,t)}this.closeLoading()},setup_reader:function(e,t,n,i,l,o,s,a){try{this.context.image.base64RenderIndex=s;const r=this._w.FileReader,c=[s];this.context.image.inputX.value=i,this.context.image.inputY.value=l;for(let d,u,h=0;h<s;h++)d=new r,u=e[h],d.onload=function(e,s,a,r,d){c[d]={result:e.result,file:r},0==--this.context.image.base64RenderIndex&&(this.plugins.image.onRender_imgBase64.call(this,s,c,a,t,n,i,l,o),this.closeLoading())}.bind(this,d,a,this.context.image._element,u,h),d.readAsDataURL(u)}catch(e){throw this.closeLoading(),Error('[SUNEDITOR.image.setup_reader.fail] cause : "'+e.message+'"')}},onRender_imgBase64:function(e,t,n,i,l,o,s,a){const r=this.plugins.image.update_src,c=this.plugins.image.create_image;for(let d=0,u=t.length;d<u;d++)e?(this.context.image._element.setAttribute("data-file-name",t[d].file.name),this.context.image._element.setAttribute("data-file-size",t[d].file.size),r.call(this,t[d].result,n,t[d].file)):c.call(this,t[d].result,i,l,o,s,a,t[d].file)},onRender_imgUrl:function(){const e=this.context.image;if(0===e._v_src._linkValue.length)return!1;try{const t={name:e._v_src._linkValue.split("/").pop(),size:0};this.context.dialog.updateModal?this.plugins.image.update_src.call(this,e._v_src._linkValue,e._element,t):this.plugins.image.create_image.call(this,e._v_src._linkValue,e._v_link._linkValue,e.imgLinkNewWindowCheck.checked,e.inputX.value,e.inputY.value,e._align,t)}catch(e){throw Error('[SUNEDITOR.image.URLRendering.fail] cause : "'+e.message+'"')}finally{this.closeLoading()}},onRender_link:function(e,t,n){if(t.trim().length>0){const i=this.util.createElement("A");return i.href=/^https?:\/\//.test(t)?t:"http://"+t,i.target=n?"_blank":"",i.setAttribute("data-image-link","image"),e.setAttribute("data-image-link",t),i.appendChild(e),i}return e},setInputSize:function(e,t){t&&32===t.keyCode?t.preventDefault():this.plugins.resizing._module_setInputSize.call(this,this.context.image,e)},setRatio:function(){this.plugins.resizing._module_setRatio.call(this,this.context.image)},checkFileInfo:function(){const e=this.plugins.image,t=function(t){e.onModifyMode.call(this,t,null),e.openModify.call(this,!0),e.update_image.call(this,!0,!1,!0)}.bind(this);this.plugins.fileManager.checkInfo.call(this,"image",["img"],this.functions.onImageUpload,t,!0)},resetFileInfo:function(){this.plugins.fileManager.resetInfo.call(this,"image",this.functions.onImageUpload)},create_image:function(e,t,n,i,l,o,s){const a=this.plugins.image,r=this.context.image;this.context.resizing._resize_plugin="image";let c=this.util.createElement("IMG");c.src=e,c.alt=r._altText,c=a.onRender_link.call(this,c,t,n),c.setAttribute("data-rotate","0"),r._resizing&&c.setAttribute("data-proportion",r._proportionChecked);const d=this.plugins.component.set_cover.call(this,c),u=this.plugins.component.set_container.call(this,d,"se-image-container");r._captionChecked&&(r._caption=this.plugins.component.create_caption.call(this),r._caption.setAttribute("contenteditable",!1),d.appendChild(r._caption)),r._element=c,r._cover=d,r._container=u,a.applySize.call(this,i,l),a.setAlign.call(this,o,c,d,u),c.onload=a._image_create_onload.bind(this,c,r.svgDefaultSize),this.insertComponent(u,!0,!0,!0)&&this.plugins.fileManager.setInfo.call(this,"image",c,this.functions.onImageUpload,s,!0),this.context.resizing._resize_plugin=""},_image_create_onload:function(e,t){0===e.offsetWidth&&this.plugins.image.applySize.call(this,t,""),this.selectComponent.call(this,e,"image")},update_image:function(e,t,n){const i=this.context.image,l=i._v_link._linkValue;let o,s=i._element,a=i._cover,r=i._container,c=!1;null===a&&(c=!0,s=i._element.cloneNode(!0),a=this.plugins.component.set_cover.call(this,s)),null===r?(a=a.cloneNode(!0),s=a.querySelector("img"),c=!0,r=this.plugins.component.set_container.call(this,a,"se-image-container")):c&&(r.innerHTML="",r.appendChild(a),i._cover=a,i._element=s,c=!1);const d=this.util.isNumber(i.inputX.value)?i.inputX.value+i.sizeUnit:i.inputX.value,u=this.util.isNumber(i.inputY.value)?i.inputY.value+i.sizeUnit:i.inputY.value;o=/%$/.test(s.style.width)?d!==r.style.width||u!==r.style.height:d!==s.style.width||u!==s.style.height,s.alt=i._altText;let h=!1;if(i._captionChecked?i._caption||(i._caption=this.plugins.component.create_caption.call(this),a.appendChild(i._caption),h=!0):i._caption&&(this.util.removeItem(i._caption),i._caption=null,h=!0),l.trim().length>0)if(null!==i._linkElement&&a.contains(i._linkElement))i._linkElement.href=l,i._linkElement.target=i.imgLinkNewWindowCheck.checked?"_blank":"",s.setAttribute("data-image-link",l);else{let e=this.plugins.image.onRender_link.call(this,s,l,this.context.image.imgLinkNewWindowCheck.checked);a.insertBefore(e,i._caption)}else if(null!==i._linkElement){const e=s;e.setAttribute("data-image-link","");let t=e.cloneNode(!0);a.removeChild(i._linkElement),a.insertBefore(t,i._caption),s=t}if(c){const e=this.util.isRangeFormatElement(i._element.parentNode)||this.util.isWysiwygDiv(i._element.parentNode)?i._element:/^A$/i.test(i._element.parentNode.nodeName)?i._element.parentNode:this.util.getFormatElement(i._element)||i._element;this.util.isFormatElement(e)&&e.textContent.length>0?(e.parentNode.insertBefore(r,e.nextElementSibling),this.util.removeItem(i._element)):e.parentNode.replaceChild(r,e),s=r.querySelector("img"),i._element=s,i._cover=a,i._container=r}(h||!i._onlyPercentage&&o)&&!e&&(/\d+/.test(s.style.height)||this.context.resizing._rotateVertical&&i._captionChecked)&&(/%$/.test(i.inputX.value)||/%$/.test(i.inputY.value)?this.plugins.resizing.resetTransform.call(this,s):this.plugins.resizing.setTransformSize.call(this,s,this.util.getNumber(i.inputX.value,0),this.util.getNumber(i.inputY.value,0)));i._resizing&&(s.setAttribute("data-proportion",i._proportionChecked),o&&this.plugins.image.applySize.call(this)),this.plugins.image.setAlign.call(this,null,s,null,null),e&&this.plugins.fileManager.setInfo.call(this,"image",s,this.functions.onImageUpload,null,!0),t&&this.selectComponent(s,"image"),n||this.history.push(!1)},update_src:function(e,t,n){t.src=e,this._w.setTimeout(this.plugins.fileManager.setInfo.bind(this,"image",t,this.functions.onImageUpload,n,!0)),this.selectComponent(t,"image")},onModifyMode:function(e,t){if(!e)return;const n=this.context.image;n._linkElement=/^A$/i.test(e.parentNode.nodeName)?e.parentNode:null,n._element=e,n._cover=this.util.getParentElement(e,"FIGURE"),n._container=this.util.getParentElement(e,this.util.isMediaComponent),n._caption=this.util.getChildElement(n._cover,"FIGCAPTION"),n._align=e.getAttribute("data-align")||"none",t&&(n._element_w=t.w,n._element_h=t.h,n._element_t=t.t,n._element_l=t.l);let i=n._element.getAttribute("data-size")||n._element.getAttribute("data-origin");i?(i=i.split(","),n._origin_w=i[0],n._origin_h=i[1]):t&&(n._origin_w=t.w,n._origin_h=t.h)},openModify:function(e){const t=this.context.image;t.imgUrlFile&&(t._v_src._linkValue=t.previewSrc.textContent=t.imgUrlFile.value=t._element.src),t._altText=t.altText.value=t._element.alt,t._v_link._linkValue=t.previewLink.textContent=t.imgLink.value=null===t._linkElement?"":t._linkElement.href,t.imgLinkNewWindowCheck.checked=t._linkElement&&"_blank"===t._linkElement.target,t.modal.querySelector('input[name="suneditor_image_radio"][value="'+t._align+'"]').checked=!0,t._align=t.modal.querySelector('input[name="suneditor_image_radio"]:checked').value,t._captionChecked=t.captionCheckEl.checked=!!t._caption,t._resizing&&this.plugins.resizing._module_setModifyInputSize.call(this,t,this.plugins.image),e||this.plugins.dialog.open.call(this,"image",!0)},sizeRevert:function(){this.plugins.resizing._module_sizeRevert.call(this,this.context.image)},applySize:function(e,t){const n=this.context.image;return e||(e=n.inputX.value||this.context.option.imageWidth),t||(t=n.inputY.value||this.context.option.imageHeight),n._onlyPercentage&&e||/%$/.test(e)?(this.plugins.image.setPercentSize.call(this,e,t),!0):(e&&"auto"!==e||t&&"auto"!==t?this.plugins.image.setSize.call(this,e,t,!1):this.plugins.image.setAutoSize.call(this),!1)},setSize:function(e,t,n,i){const l=this.context.image,o=/^(rw|lw)$/.test(i),s=/^(th|bh)$/.test(i);this.plugins.image.cancelPercentAttr.call(this),s||(l._element.style.width=this.util.isNumber(e)?e+l.sizeUnit:e),o||(l._element.style.height=this.util.isNumber(t)?t+l.sizeUnit:/%$/.test(t)?"":t),"center"===l._align&&this.plugins.image.setAlign.call(this,null,null,null,null),n||l._element.removeAttribute("data-percentage"),this.plugins.resizing._module_saveCurrentSize.call(this,l)},setAutoSize:function(){const e=this.context.image;this.plugins.resizing.resetTransform.call(this,e._element),this.plugins.image.cancelPercentAttr.call(this),e._element.style.maxWidth="",e._element.style.width="",e._element.style.height="",e._cover.style.width="",e._cover.style.height="",this.plugins.image.setAlign.call(this,null,null,null,null),e._element.setAttribute("data-percentage","auto,auto"),this.plugins.resizing._module_saveCurrentSize.call(this,e)},setOriginSize:function(){const e=this.context.image;e._element.removeAttribute("data-percentage"),this.plugins.resizing.resetTransform.call(this,e._element),this.plugins.image.cancelPercentAttr.call(this);const t=(e._element.getAttribute("data-origin")||"").split(","),n=t[0],i=t[1];t&&(e._onlyPercentage||/%$/.test(n)&&(/%$/.test(i)||!/\d/.test(i))?this.plugins.image.setPercentSize.call(this,n,i):this.plugins.image.setSize.call(this,n,i),this.plugins.resizing._module_saveCurrentSize.call(this,e))},setPercentSize:function(e,t){const n=this.context.image;t=!t||/%$/.test(t)||this.util.getNumber(t,0)?this.util.isNumber(t)?t+n.sizeUnit:t||"":this.util.isNumber(t)?t+"%":t;const i=/%$/.test(t);n._container.style.width=this.util.isNumber(e)?e+"%":e,n._container.style.height="",n._cover.style.width="100%",n._cover.style.height=i?t:"",n._element.style.width="100%",n._element.style.height=i?"":t,n._element.style.maxWidth="","center"===n._align&&this.plugins.image.setAlign.call(this,null,null,null,null),n._element.setAttribute("data-percentage",e+","+t),this.plugins.resizing.setCaptionPosition.call(this,n._element),this.plugins.resizing._module_saveCurrentSize.call(this,n)},cancelPercentAttr:function(){const e=this.context.image;e._cover.style.width="",e._cover.style.height="",e._container.style.width="",e._container.style.height="",this.util.removeClass(e._container,this.context.image._floatClassRegExp),this.util.addClass(e._container,"__se__float-"+e._align),"center"===e._align&&this.plugins.image.setAlign.call(this,null,null,null,null)},setAlign:function(e,t,n,i){const l=this.context.image;e||(e=l._align),t||(t=l._element),n||(n=l._cover),i||(i=l._container),n.style.margin=e&&"none"!==e?"auto":"0",/%$/.test(t.style.width)&&"center"===e?(i.style.minWidth="100%",n.style.width=i.style.width):(i.style.minWidth="",n.style.width=this.context.resizing._rotateVertical?t.style.height||t.offsetHeight:t.style.width&&"auto"!==t.style.width?t.style.width||"100%":""),this.util.hasClass(i,"__se__float-"+e)||(this.util.removeClass(i,l._floatClassRegExp),this.util.addClass(i,"__se__float-"+e)),t.setAttribute("data-align",e)},resetAlign:function(){const e=this.context.image;e._element.setAttribute("data-align",""),e._align="none",e._cover.style.margin="0",this.util.removeClass(e._container,e._floatClassRegExp)},init:function(){const e=this.context.image;e.imgInputFile&&(e.imgInputFile.value=""),e.imgUrlFile&&(e._v_src._linkValue=e.previewSrc.textContent=e.imgUrlFile.value=""),e.imgInputFile&&e.imgUrlFile&&(e.imgUrlFile.removeAttribute("disabled"),e.previewSrc.style.textDecoration=""),e.altText.value="",e._v_link._linkValue=e.previewLink.textContent=e.imgLink.value="",e.imgLinkNewWindowCheck.checked=!1,e.modal.querySelector('input[name="suneditor_image_radio"][value="none"]').checked=!0,e.captionCheckEl.checked=!1,e._element=null,this.plugins.image.openTab.call(this,"init"),e._resizing&&(e.inputX.value=this.context.option.imageWidth===e._defaultSizeX?"":this.context.option.imageWidth,e.inputY.value=this.context.option.imageHeight===e._defaultSizeY?"":this.context.option.imageHeight,e.proportion.checked=!0,e._ratio=!1,e._ratioX=1,e._ratioY=1)}},_={name:"video",display:"dialog",add:function(e){e.addModule([r.a,u.a,g.a,m.a]);const t=e.context,n=t.video={_infoList:[],_infoIndex:0,_uploadFileLength:0,sizeUnit:t.option._videoSizeUnit,_align:"none",_floatClassRegExp:"__se__float\\-[a-z]+",_youtubeQuery:t.option.youtubeQuery,_videoRatio:100*t.option.videoRatio+"%",_defaultRatio:100*t.option.videoRatio+"%",_linkValue:"",_element:null,_cover:null,_container:null,inputX:null,inputY:null,_element_w:1,_element_h:1,_element_l:0,_element_t:0,_defaultSizeX:"100%",_defaultSizeY:100*t.option.videoRatio+"%",_origin_w:"100%"===t.option.videoWidth?"":t.option.videoWidth,_origin_h:"56.25%"===t.option.videoHeight?"":t.option.videoHeight,_proportionChecked:!0,_resizing:t.option.videoResizing,_resizeDotHide:!t.option.videoHeightShow,_rotation:t.option.videoRotation,_onlyPercentage:t.option.videoSizeOnlyPercentage,_ratio:!1,_ratioX:1,_ratioY:1,_captionShow:!1};let i=this.setDialog.call(e);n.modal=i,n.videoInputFile=i.querySelector("._se_video_file"),n.videoUrlFile=i.querySelector(".se-input-url"),n.focusElement=n.videoUrlFile||n.videoInputFile,n.preview=i.querySelector(".se-link-preview"),i.querySelector(".se-btn-primary").addEventListener("click",this.submit.bind(e)),n.videoInputFile&&i.querySelector(".se-dialog-files-edge-button").addEventListener("click",this._removeSelectedFiles.bind(n.videoInputFile,n.videoUrlFile,n.preview)),n.videoInputFile&&n.videoUrlFile&&n.videoInputFile.addEventListener("change",this._fileInputChange.bind(n)),n.videoUrlFile&&n.videoUrlFile.addEventListener("input",this._onLinkPreview.bind(n.preview,n,t.options.linkProtocol)),n.proportion={},n.videoRatioOption={},n.inputX={},n.inputY={},t.option.videoResizing&&(n.proportion=i.querySelector("._se_video_check_proportion"),n.videoRatioOption=i.querySelector(".se-video-ratio"),n.inputX=i.querySelector("._se_video_size_x"),n.inputY=i.querySelector("._se_video_size_y"),n.inputX.value=t.option.videoWidth,n.inputY.value=t.option.videoHeight,n.inputX.addEventListener("keyup",this.setInputSize.bind(e,"x")),n.inputY.addEventListener("keyup",this.setInputSize.bind(e,"y")),n.inputX.addEventListener("change",this.setRatio.bind(e)),n.inputY.addEventListener("change",this.setRatio.bind(e)),n.proportion.addEventListener("change",this.setRatio.bind(e)),n.videoRatioOption.addEventListener("change",this.setVideoRatio.bind(e)),i.querySelector(".se-dialog-btn-revert").addEventListener("click",this.sizeRevert.bind(e))),t.dialog.modal.appendChild(i),i=null},setDialog:function(){const e=this.context.option,t=this.lang,n=this.util.createElement("DIV");n.className="se-dialog-content",n.style.display="none";let i='<form method="post" enctype="multipart/form-data"><div class="se-dialog-header"><button type="button" data-command="close" class="se-btn se-dialog-close" aria-label="Close" title="'+t.dialogBox.close+'">'+this.icons.cancel+'</button><span class="se-modal-title">'+t.dialogBox.videoBox.title+'</span></div><div class="se-dialog-body">';if(e.videoFileInput&&(i+='<div class="se-dialog-form"><label>'+t.dialogBox.videoBox.file+'</label><div class="se-dialog-form-files"><input class="se-input-form _se_video_file" type="file" accept="'+e.videoAccept+'"'+(e.videoMultipleFile?' multiple="multiple"':"")+'/><button type="button" data-command="filesRemove" class="se-btn se-dialog-files-edge-button se-file-remove" title="'+t.controller.remove+'">'+this.icons.cancel+"</button></div></div>"),e.videoUrlInput&&(i+='<div class="se-dialog-form"><label>'+t.dialogBox.videoBox.url+'</label><input class="se-input-form se-input-url" type="text" /><pre class="se-link-preview"></pre></div>'),e.videoResizing){const n=e.videoRatioList||[{name:"16:9",value:.5625},{name:"4:3",value:.75},{name:"21:9",value:.4285}],l=e.videoRatio,o=e.videoSizeOnlyPercentage,s=o?' style="display: none !important;"':"",a=e.videoHeightShow?"":' style="display: none !important;"',r=e.videoRatioShow?"":' style="display: none !important;"',c=o||e.videoHeightShow||e.videoRatioShow?"":' style="display: none !important;"';i+='<div class="se-dialog-form"><div class="se-dialog-size-text"><label class="size-w">'+t.dialogBox.width+'</label><label class="se-dialog-size-x"> </label><label class="size-h"'+a+">"+t.dialogBox.height+'</label><label class="size-h"'+r+">("+t.dialogBox.ratio+')</label></div><input class="se-input-control _se_video_size_x" placeholder="100%"'+(o?' type="number" min="1"':'type="text"')+(o?' max="100"':"")+'/><label class="se-dialog-size-x"'+c+">"+(o?"%":"x")+'</label><input class="se-input-control _se_video_size_y" placeholder="'+100*e.videoRatio+'%"'+(o?' type="number" min="1"':'type="text"')+(o?' max="100"':"")+a+'/><select class="se-input-select se-video-ratio" title="'+t.dialogBox.ratio+'"'+r+">",a||(i+='<option value=""> - </option>');for(let e=0,t=n.length;e<t;e++)i+='<option value="'+n[e].value+'"'+(l.toString()===n[e].value.toString()?" selected":"")+">"+n[e].name+"</option>";i+='</select><button type="button" title="'+t.dialogBox.revertButton+'" class="se-btn se-dialog-btn-revert" style="float: right;">'+this.icons.revert+'</button></div><div class="se-dialog-form se-dialog-form-footer"'+s+c+'><label><input type="checkbox" class="se-dialog-btn-check _se_video_check_proportion" checked/> '+t.dialogBox.proportion+"</label></div>"}return i+='</div><div class="se-dialog-footer"><div><label><input type="radio" name="suneditor_video_radio" class="se-dialog-btn-radio" value="none" checked>'+t.dialogBox.basic+'</label><label><input type="radio" name="suneditor_video_radio" class="se-dialog-btn-radio" value="left">'+t.dialogBox.left+'</label><label><input type="radio" name="suneditor_video_radio" class="se-dialog-btn-radio" value="center">'+t.dialogBox.center+'</label><label><input type="radio" name="suneditor_video_radio" class="se-dialog-btn-radio" value="right">'+t.dialogBox.right+'</label></div><button type="submit" class="se-btn-primary" title="'+t.dialogBox.submitButton+'"><span>'+t.dialogBox.submitButton+"</span></button></div></form>",n.innerHTML=i,n},_fileInputChange:function(){this.videoInputFile.value?(this.videoUrlFile.setAttribute("disabled",!0),this.preview.style.textDecoration="line-through"):(this.videoUrlFile.removeAttribute("disabled"),this.preview.style.textDecoration="")},_removeSelectedFiles:function(e,t){this.value="",e&&(e.removeAttribute("disabled"),t.style.textDecoration="")},_onLinkPreview:function(e,t,n){const i=n.target.value.trim();/^<iframe.*\/iframe>$/.test(i)?(e._linkValue=i,this.textContent='<IFrame :src=".."></IFrame>'):e._linkValue=this.textContent=i?t&&-1===i.indexOf("://")&&0!==i.indexOf("#")?t+i:-1===i.indexOf("://")?"/"+i:i:""},_setTagAttrs:function(e){e.setAttribute("controls",!0);const t=this.context.options.videoTagAttrs;if(t)for(let n in t)this.util.hasOwn(t,n)&&e.setAttribute(n,t[n])},createVideoTag:function(){const e=this.util.createElement("VIDEO");return this.plugins.video._setTagAttrs.call(this,e),e},_setIframeAttrs:function(e){e.frameBorder="0",e.allowFullscreen=!0;const t=this.context.options.videoIframeAttrs;if(t)for(let n in t)this.util.hasOwn(t,n)&&e.setAttribute(n,t[n])},createIframeTag:function(){const e=this.util.createElement("IFRAME");return this.plugins.video._setIframeAttrs.call(this,e),e},fileTags:["iframe","video"],select:function(e){this.plugins.video.onModifyMode.call(this,e,this.plugins.resizing.call_controller_resize.call(this,e,"video"))},destroy:function(e){const t=e||this.context.video._element,n=this.context.video._container,i=1*t.getAttribute("data-index");let l=n.previousElementSibling||n.nextElementSibling;const o=n.parentNode;this.util.removeItem(n),this.plugins.video.init.call(this),this.controllersOff(),o!==this.context.element.wysiwyg&&this.util.removeItemAllParents(o,(function(e){return 0===e.childNodes.length}),null),this.focusEdge(l),this.plugins.fileManager.deleteInfo.call(this,"video",i,this.functions.onVideoUpload),this.history.push(!1)},on:function(e){const t=this.context.video;e?t.videoInputFile&&this.context.options.videoMultipleFile&&t.videoInputFile.removeAttribute("multiple"):(t.inputX.value=t._origin_w=this.context.option.videoWidth===t._defaultSizeX?"":this.context.option.videoWidth,t.inputY.value=t._origin_h=this.context.option.videoHeight===t._defaultSizeY?"":this.context.option.videoHeight,t.proportion.disabled=!0,t.videoInputFile&&this.context.options.videoMultipleFile&&t.videoInputFile.setAttribute("multiple","multiple")),t._resizing&&this.plugins.video.setVideoRatioSelect.call(this,t._origin_h||t._defaultRatio)},open:function(){this.plugins.dialog.open.call(this,"video","video"===this.currentControllerName)},setVideoRatio:function(e){const t=this.context.video,n=e.target.options[e.target.selectedIndex].value;t._defaultSizeY=t._videoRatio=n?100*n+"%":t._defaultSizeY,t.inputY.placeholder=n?100*n+"%":"",t.inputY.value=""},setInputSize:function(e,t){if(t&&32===t.keyCode)return void t.preventDefault();const n=this.context.video;this.plugins.resizing._module_setInputSize.call(this,n,e),"y"===e&&this.plugins.video.setVideoRatioSelect.call(this,t.target.value||n._defaultRatio)},setRatio:function(){this.plugins.resizing._module_setRatio.call(this,this.context.video)},submit:function(e){const t=this.context.video,n=this.plugins.video;e.preventDefault(),e.stopPropagation(),t._align=t.modal.querySelector('input[name="suneditor_video_radio"]:checked').value;try{t.videoInputFile&&t.videoInputFile.files.length>0?(this.showLoading(),n.submitAction.call(this,this.context.video.videoInputFile.files)):t.videoUrlFile&&t._linkValue.length>0&&(this.showLoading(),n.setup_url.call(this))}catch(e){throw this.closeLoading(),Error('[SUNEDITOR.video.submit.fail] cause : "'+e.message+'"')}finally{this.plugins.dialog.close.call(this)}return!1},submitAction:function(e){if(0===e.length)return;let t=0,n=[];for(let i=0,l=e.length;i<l;i++)/video/i.test(e[i].type)&&(n.push(e[i]),t+=e[i].size);const i=this.context.option.videoUploadSizeLimit;if(i>0){let e=0;const n=this.context.video._infoList;for(let t=0,i=n.length;t<i;t++)e+=1*n[t].size;if(t+e>i){this.closeLoading();const n="[SUNEDITOR.videoUpload.fail] Size of uploadable total videos: "+i/1e3+"KB";return void(("function"!==this.functions.onVideoUploadError||this.functions.onVideoUploadError(n,{limitSize:i,currentSize:e,uploadSize:t},this))&&this.functions.noticeOpen(n))}}const l=this.context.video;l._uploadFileLength=n.length;const o={inputWidth:l.inputX.value,inputHeight:l.inputY.value,align:l._align,isUpdate:this.context.dialog.updateModal,element:l._element};if("function"==typeof this.functions.onVideoUploadBefore){const e=this.functions.onVideoUploadBefore(n,o,this,function(e){e&&this._w.Array.isArray(e.result)?this.plugins.video.register.call(this,o,e):this.plugins.video.upload.call(this,o,e)}.bind(this));if(void 0===e)return;if(!e)return void this.closeLoading();"object"==typeof e&&e.length>0&&(n=e)}this.plugins.video.upload.call(this,o,n)},error:function(e,t){if(this.closeLoading(),"function"!=typeof this.functions.onVideoUploadError||this.functions.onVideoUploadError(e,t,this))throw this.functions.noticeOpen(e),Error("[SUNEDITOR.plugin.video.error] response: "+e)},upload:function(e,t){if(!t)return void this.closeLoading();if("string"==typeof t)return void this.plugins.video.error.call(this,t,null);const n=this.context.option.videoUploadUrl,i=this.context.dialog.updateModal?1:t.length;if(!("string"==typeof n&&n.length>0))throw Error('[SUNEDITOR.videoUpload.fail] cause : There is no "videoUploadUrl" option.');{const l=new FormData;for(let e=0;e<i;e++)l.append("file-"+e,t[e]);this.plugins.fileManager.upload.call(this,n,this.context.option.videoUploadHeader,l,this.plugins.video.callBack_videoUpload.bind(this,e),this.functions.onVideoUploadError)}},callBack_videoUpload:function(e,t){if("function"==typeof this.functions.videoUploadHandler)this.functions.videoUploadHandler(t,e,this);else{const n=JSON.parse(t.responseText);n.errorMessage?this.plugins.video.error.call(this,n.errorMessage,n):this.plugins.video.register.call(this,e,n)}},register:function(e,t){const n=t.result,i=this.plugins.video.createVideoTag.call(this);for(let t,l=0,o=n.length;l<o;l++)t={name:n[l].name,size:n[l].size},this.plugins.video.create_video.call(this,e.isUpdate?e.element:i.cloneNode(!1),n[l].url,e.inputWidth,e.inputHeight,e.align,t,e.isUpdate);this.closeLoading()},setup_url:function(){try{const e=this.context.video;let t=e._linkValue;if(0===t.length)return!1;if(/^<iframe.*\/iframe>$/.test(t)){if(t=(new this._w.DOMParser).parseFromString(t,"text/html").querySelector("iframe").src,0===t.length)return!1}if(/youtu\.?be/.test(t)){if(/^http/.test(t)||(t="https://"+t),t=t.replace("watch?v=",""),/^\/\/.+\/embed\//.test(t)||(t=t.replace(t.match(/\/\/.+\//)[0],"//www.youtube.com/embed/").replace("&","?&")),e._youtubeQuery.length>0)if(/\?/.test(t)){const n=t.split("?");t=n[0]+"?"+e._youtubeQuery+"&"+n[1]}else t+="?"+e._youtubeQuery}else/vimeo\.com/.test(t)&&(t.endsWith("/")&&(t=t.slice(0,-1)),t="https://player.vimeo.com/video/"+t.slice(t.lastIndexOf("/")+1));this.plugins.video.create_video.call(this,this.plugins.video.createIframeTag.call(this),t,e.inputX.value,e.inputY.value,e._align,null,this.context.dialog.updateModal)}catch(e){throw Error('[SUNEDITOR.video.upload.fail] cause : "'+e.message+'"')}finally{this.closeLoading()}},create_video:function(e,t,n,i,l,o,s){this.context.resizing._resize_plugin="video";const a=this.context.video;let r=null,c=null,d=!1;if(s){if((e=a._element).src!==t){d=!0;const n=/youtu\.?be/.test(t),i=/vimeo\.com/.test(t);if(!n&&!i||/^iframe$/i.test(e.nodeName))if(n||i||/^videoo$/i.test(e.nodeName))e.src=t;else{const n=this.plugins.video.createVideoTag.call(this);n.src=t,e.parentNode.replaceChild(n,e),a._element=e=n}else{const n=this.plugins.video.createIframeTag.call(this);n.src=t,e.parentNode.replaceChild(n,e),a._element=e=n}}c=a._container,r=this.util.getParentElement(e,"FIGURE")}else d=!0,e.src=t,a._element=e,r=this.plugins.component.set_cover.call(this,e),c=this.plugins.component.set_container.call(this,r,"se-video-container");a._cover=r,a._container=c;const u=this.plugins.resizing._module_getSizeX.call(this,a)!==(n||a._defaultSizeX)||this.plugins.resizing._module_getSizeY.call(this,a)!==(i||a._videoRatio),h=!s||u;a._resizing&&(this.context.video._proportionChecked=a.proportion.checked,e.setAttribute("data-proportion",a._proportionChecked));let g=!1;h&&(g=this.plugins.video.applySize.call(this)),g&&"center"===l||this.plugins.video.setAlign.call(this,null,e,r,c);let p=!0;s?a._resizing&&this.context.resizing._rotateVertical&&h&&this.plugins.resizing.setTransformSize.call(this,e,null,null):p=this.insertComponent(c,!1,!0,!1),p&&(d&&this.plugins.fileManager.setInfo.call(this,"video",e,this.functions.onVideoUpload,o,!0),s&&(this.selectComponent(e,"video"),this.history.push(!1))),this.context.resizing._resize_plugin=""},_update_videoCover:function(e){if(!e)return;const t=this.context.video;/^video$/i.test(e.nodeName)?this.plugins.video._setTagAttrs.call(this,e):this.plugins.video._setIframeAttrs.call(this,e);const n=this.util.getParentElement(e,this.util.isMediaComponent)||this.util.getParentElement(e,function(e){return this.isWysiwygDiv(e.parentNode)}.bind(this.util));e=e.cloneNode(!0);const i=t._cover=this.plugins.component.set_cover.call(this,e),l=t._container=this.plugins.component.set_container.call(this,i,"se-video-container"),o=n.querySelector("figcaption");let s=null;o&&(s=this.util.createElement("DIV"),s.innerHTML=o.innerHTML,this.util.removeItem(o));const a=(e.getAttribute("data-size")||e.getAttribute("data-origin")||"").split(",");this.plugins.video.applySize.call(this,a[0],a[1]),this.util.isFormatElement(n)&&n.textContent.length>0?(n.parentNode.insertBefore(l,n.nextElementSibling),this.util.removeItem(t._element),t._element=e):n.parentNode.replaceChild(l,n),s&&n.parentNode.insertBefore(s,l.nextElementSibling),this.plugins.fileManager.setInfo.call(this,"video",e,this.functions.onVideoUpload,null,!0)},onModifyMode:function(e,t){const n=this.context.video;n._element=e,n._cover=this.util.getParentElement(e,"FIGURE"),n._container=this.util.getParentElement(e,this.util.isMediaComponent),n._align=e.getAttribute("data-align")||"none",t&&(n._element_w=t.w,n._element_h=t.h,n._element_t=t.t,n._element_l=t.l);let i=n._element.getAttribute("data-size")||n._element.getAttribute("data-origin");i?(i=i.split(","),n._origin_w=i[0],n._origin_h=i[1]):t&&(n._origin_w=t.w,n._origin_h=t.h)},openModify:function(e){const t=this.context.video;if(t.videoUrlFile&&(t._linkValue=t.preview.textContent=t.videoUrlFile.value=t._element.src||(t._element.querySelector("source")||"").src||""),t.modal.querySelector('input[name="suneditor_video_radio"][value="'+t._align+'"]').checked=!0,t._resizing){this.plugins.resizing._module_setModifyInputSize.call(this,t,this.plugins.video);const e=t._videoRatio=this.plugins.resizing._module_getSizeY.call(this,t);this.plugins.video.setVideoRatioSelect.call(this,e)||(t.inputY.value=t._onlyPercentage?this.util.getNumber(e,2):e)}e||this.plugins.dialog.open.call(this,"video",!0)},setVideoRatioSelect:function(e){let t=!1;const n=this.context.video,i=n.videoRatioOption.options;/%$/.test(e)||n._onlyPercentage?e=this.util.getNumber(e,2)/100+"":(!this.util.isNumber(e)||1*e>=1)&&(e=""),n.inputY.placeholder="";for(let l=0,o=i.length;l<o;l++)i[l].value===e?(t=i[l].selected=!0,n.inputY.placeholder=e?100*e+"%":""):i[l].selected=!1;return t},checkFileInfo:function(){this.plugins.fileManager.checkInfo.call(this,"video",["iframe","video"],this.functions.onVideoUpload,this.plugins.video._update_videoCover.bind(this),!0)},resetFileInfo:function(){this.plugins.fileManager.resetInfo.call(this,"video",this.functions.onVideoUpload)},sizeRevert:function(){this.plugins.resizing._module_sizeRevert.call(this,this.context.video)},applySize:function(e,t){const n=this.context.video;return e||(e=n.inputX.value||this.context.option.videoWidth),t||(t=n.inputY.value||this.context.option.videoHeight),n._onlyPercentage||/%$/.test(e)||!e?(this.plugins.video.setPercentSize.call(this,e||"100%",t||(/%$/.test(n._videoRatio)?n._videoRatio:n._defaultRatio)),!0):(e&&"auto"!==e||t&&"auto"!==t?this.plugins.video.setSize.call(this,e,t||n._videoRatio||n._defaultRatio,!1):this.plugins.video.setAutoSize.call(this),!1)},setSize:function(e,t,n,i){const l=this.context.video,o=/^(rw|lw)$/.test(i),s=/^(th|bh)$/.test(i);s||(e=this.util.getNumber(e,0)),o||(t=this.util.isNumber(t)?t+l.sizeUnit:t||""),s||(l._element.style.width=e?e+l.sizeUnit:""),o||(l._cover.style.paddingBottom=l._cover.style.height=t),s||/%$/.test(e)||(l._cover.style.width="",l._container.style.width=""),o||/%$/.test(t)?l._element.style.height="":l._element.style.height=t,n||l._element.removeAttribute("data-percentage"),this.plugins.resizing._module_saveCurrentSize.call(this,l)},setAutoSize:function(){this.plugins.video.setPercentSize.call(this,100,this.context.video._defaultRatio)},setOriginSize:function(e){const t=this.context.video;t._element.removeAttribute("data-percentage"),this.plugins.resizing.resetTransform.call(this,t._element),this.plugins.video.cancelPercentAttr.call(this);const n=((e?t._element.getAttribute("data-size"):"")||t._element.getAttribute("data-origin")||"").split(",");if(n){const e=n[0],i=n[1];t._onlyPercentage||/%$/.test(e)&&(/%$/.test(i)||!/\d/.test(i))?this.plugins.video.setPercentSize.call(this,e,i):this.plugins.video.setSize.call(this,e,i),this.plugins.resizing._module_saveCurrentSize.call(this,t)}},setPercentSize:function(e,t){const n=this.context.video;t=!t||/%$/.test(t)||this.util.getNumber(t,0)?this.util.isNumber(t)?t+n.sizeUnit:t||n._defaultRatio:this.util.isNumber(t)?t+"%":t,n._container.style.width=this.util.isNumber(e)?e+"%":e,n._container.style.height="",n._cover.style.width="100%",n._cover.style.height=t,n._cover.style.paddingBottom=t,n._element.style.width="100%",n._element.style.height="100%",n._element.style.maxWidth="","center"===n._align&&this.plugins.video.setAlign.call(this,null,null,null,null),n._element.setAttribute("data-percentage",e+","+t),this.plugins.resizing._module_saveCurrentSize.call(this,n)},cancelPercentAttr:function(){const e=this.context.video;e._cover.style.width="",e._cover.style.height="",e._cover.style.paddingBottom="",e._container.style.width="",e._container.style.height="",this.util.removeClass(e._container,this.context.video._floatClassRegExp),this.util.addClass(e._container,"__se__float-"+e._align),"center"===e._align&&this.plugins.video.setAlign.call(this,null,null,null,null)},setAlign:function(e,t,n,i){const l=this.context.video;e||(e=l._align),t||(t=l._element),n||(n=l._cover),i||(i=l._container),n.style.margin=e&&"none"!==e?"auto":"0",/%$/.test(t.style.width)&&"center"===e?(i.style.minWidth="100%",n.style.width=i.style.width,n.style.height=n.style.height,n.style.paddingBottom=/%$/.test(n.style.height)?this.util.getNumber(this.util.getNumber(n.style.height,2)/100*this.util.getNumber(n.style.width,2),2)+"%":n.style.height):(i.style.minWidth="",n.style.width=this.context.resizing._rotateVertical?t.style.height||t.offsetHeight:t.style.width||"100%",n.style.paddingBottom=n.style.height),this.util.hasClass(i,"__se__float-"+e)||(this.util.removeClass(i,l._floatClassRegExp),this.util.addClass(i,"__se__float-"+e)),t.setAttribute("data-align",e)},resetAlign:function(){const e=this.context.video;e._element.setAttribute("data-align",""),e._align="none",e._cover.style.margin="0",this.util.removeClass(e._container,e._floatClassRegExp)},init:function(){const e=this.context.video;e.videoInputFile&&(e.videoInputFile.value=""),e.videoUrlFile&&(e._linkValue=e.preview.textContent=e.videoUrlFile.value=""),e.videoInputFile&&e.videoUrlFile&&(e.videoUrlFile.removeAttribute("disabled"),e.preview.style.textDecoration=""),e._origin_w=this.context.option.videoWidth,e._origin_h=this.context.option.videoHeight,e.modal.querySelector('input[name="suneditor_video_radio"][value="none"]').checked=!0,e._resizing&&(e.inputX.value=this.context.option.videoWidth===e._defaultSizeX?"":this.context.option.videoWidth,e.inputY.value=this.context.option.videoHeight===e._defaultSizeY?"":this.context.option.videoHeight,e.proportion.checked=!0,e.proportion.disabled=!0,this.plugins.video.setVideoRatioSelect.call(this,e._defaultRatio))}},b={name:"audio",display:"dialog",add:function(e){e.addModule([r.a,u.a,m.a]);const t=e.context,n=t.audio={_infoList:[],_infoIndex:0,_uploadFileLength:0,focusElement:null,targetSelect:null,_origin_w:t.option.audioWidth,_origin_h:t.option.audioHeight,_linkValue:"",_element:null,_cover:null,_container:null};let i=this.setDialog.call(e);n.modal=i,n.audioInputFile=i.querySelector("._se_audio_files"),n.audioUrlFile=i.querySelector(".se-input-url"),n.focusElement=n.audioInputFile||n.audioUrlFile,n.preview=i.querySelector(".se-link-preview");let l=this.setController.call(e);n.controller=l,l.addEventListener("mousedown",e.eventStop),i.querySelector(".se-btn-primary").addEventListener("click",this.submit.bind(e)),n.audioInputFile&&i.querySelector(".se-dialog-files-edge-button").addEventListener("click",this._removeSelectedFiles.bind(n.audioInputFile,n.audioUrlFile,n.preview)),n.audioInputFile&&n.audioUrlFile&&n.audioInputFile.addEventListener("change",this._fileInputChange.bind(n)),l.addEventListener("click",this.onClick_controller.bind(e)),n.audioUrlFile&&n.audioUrlFile.addEventListener("input",this._onLinkPreview.bind(n.preview,n,t.options.linkProtocol)),t.dialog.modal.appendChild(i),t.element.relative.appendChild(l),i=null,l=null},setDialog:function(){const e=this.context.option,t=this.lang,n=this.util.createElement("DIV");n.className="se-dialog-content",n.style.display="none";let i='<form method="post" enctype="multipart/form-data"><div class="se-dialog-header"><button type="button" data-command="close" class="se-btn se-dialog-close" aria-label="Close" title="'+t.dialogBox.close+'">'+this.icons.cancel+'</button><span class="se-modal-title">'+t.dialogBox.audioBox.title+'</span></div><div class="se-dialog-body">';return e.audioFileInput&&(i+='<div class="se-dialog-form"><label>'+t.dialogBox.audioBox.file+'</label><div class="se-dialog-form-files"><input class="se-input-form _se_audio_files" type="file" accept="'+e.audioAccept+'"'+(e.audioMultipleFile?' multiple="multiple"':"")+'/><button type="button" data-command="filesRemove" class="se-btn se-dialog-files-edge-button se-file-remove" title="'+t.controller.remove+'">'+this.icons.cancel+"</button></div></div>"),e.audioUrlInput&&(i+='<div class="se-dialog-form"><label>'+t.dialogBox.audioBox.url+'</label><input class="se-input-form se-input-url" type="text" /><pre class="se-link-preview"></pre></div>'),i+='</div><div class="se-dialog-footer"><button type="submit" class="se-btn-primary" title="'+t.dialogBox.submitButton+'"><span>'+t.dialogBox.submitButton+"</span></button></div></form>",n.innerHTML=i,n},setController:function(){const e=this.lang,t=this.icons,n=this.util.createElement("DIV");return n.className="se-controller se-controller-link",n.innerHTML='<div class="se-arrow se-arrow-up"></div><div class="link-content"><div class="se-btn-group"><button type="button" data-command="update" tabindex="-1" class="se-tooltip">'+t.edit+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.edit+'</span></span></button><button type="button" data-command="delete" tabindex="-1" class="se-tooltip">'+t.delete+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.remove+"</span></span></button></div></div>",n},_fileInputChange:function(){this.audioInputFile.value?(this.audioUrlFile.setAttribute("disabled",!0),this.preview.style.textDecoration="line-through"):(this.audioUrlFile.removeAttribute("disabled"),this.preview.style.textDecoration="")},_removeSelectedFiles:function(e,t){this.value="",e&&(e.removeAttribute("disabled"),t.style.textDecoration="")},_createAudioTag:function(){const e=this.util.createElement("AUDIO");this.plugins.audio._setTagAttrs.call(this,e);const t=this.context.audio._origin_w,n=this.context.audio._origin_h;return e.setAttribute("origin-size",t+","+n),e.style.cssText=(t?"width:"+t+"; ":"")+(n?"height:"+n+";":""),e},_setTagAttrs:function(e){e.setAttribute("controls",!0);const t=this.context.options.audioTagAttrs;if(t)for(let n in t)this.util.hasOwn(t,n)&&e.setAttribute(n,t[n])},_onLinkPreview:function(e,t,n){const i=n.target.value.trim();e._linkValue=this.textContent=i?t&&-1===i.indexOf("://")&&0!==i.indexOf("#")?t+i:-1===i.indexOf("://")?"/"+i:i:""},fileTags:["audio"],select:function(e){this.plugins.audio.onModifyMode.call(this,e)},destroy:function(e){e=e||this.context.audio._element;const t=this.util.getParentElement(e,this.util.isComponent)||e,n=1*e.getAttribute("data-index"),i=t.previousElementSibling||t.nextElementSibling,l=t.parentNode;this.util.removeItem(t),this.plugins.audio.init.call(this),this.controllersOff(),l!==this.context.element.wysiwyg&&this.util.removeItemAllParents(l,(function(e){return 0===e.childNodes.length}),null),this.focusEdge(i),this.plugins.fileManager.deleteInfo.call(this,"audio",n,this.functions.onAudioUpload),this.history.push(!1)},checkFileInfo:function(){this.plugins.fileManager.checkInfo.call(this,"audio",["audio"],this.functions.onAudioUpload,this.plugins.audio.updateCover.bind(this),!1)},resetFileInfo:function(){this.plugins.fileManager.resetInfo.call(this,"audio",this.functions.onAudioUpload)},on:function(e){const t=this.context.audio;e?t._element?(this.context.dialog.updateModal=!0,t._linkValue=t.preview.textContent=t.audioUrlFile.value=t._element.src,t.audioInputFile&&this.context.options.audioMultipleFile&&t.audioInputFile.removeAttribute("multiple")):t.audioInputFile&&this.context.options.audioMultipleFile&&t.audioInputFile.removeAttribute("multiple"):(this.plugins.audio.init.call(this),t.audioInputFile&&this.context.options.audioMultipleFile&&t.audioInputFile.setAttribute("multiple","multiple"))},open:function(){this.plugins.dialog.open.call(this,"audio","audio"===this.currentControllerName)},submit:function(e){const t=this.context.audio;e.preventDefault(),e.stopPropagation();try{t.audioInputFile&&t.audioInputFile.files.length>0?(this.showLoading(),this.plugins.audio.submitAction.call(this,t.audioInputFile.files)):t.audioUrlFile&&t._linkValue.length>0&&(this.showLoading(),this.plugins.audio.setupUrl.call(this,t._linkValue))}catch(e){throw this.closeLoading(),Error('[SUNEDITOR.audio.submit.fail] cause : "'+e.message+'"')}finally{this.plugins.dialog.close.call(this)}return!1},submitAction:function(e){if(0===e.length)return;let t=0,n=[];for(let i=0,l=e.length;i<l;i++)/audio/i.test(e[i].type)&&(n.push(e[i]),t+=e[i].size);const i=this.context.option.audioUploadSizeLimit;if(i>0){let e=0;const n=this.context.audio._infoList;for(let t=0,i=n.length;t<i;t++)e+=1*n[t].size;if(t+e>i){this.closeLoading();const n="[SUNEDITOR.audioUpload.fail] Size of uploadable total audios: "+i/1e3+"KB";return void(("function"!==this.functions.onAudioUploadError||this.functions.onAudioUploadError(n,{limitSize:i,currentSize:e,uploadSize:t},this))&&this.functions.noticeOpen(n))}}const l=this.context.audio;l._uploadFileLength=n.length;const o={isUpdate:this.context.dialog.updateModal,element:l._element};if("function"==typeof this.functions.onAudioUploadBefore){const e=this.functions.onAudioUploadBefore(n,o,this,function(e){e&&this._w.Array.isArray(e.result)?this.plugins.audio.register.call(this,o,e):this.plugins.audio.upload.call(this,o,e)}.bind(this));if(void 0===e)return;if(!e)return void this.closeLoading();"object"==typeof e&&e.length>0&&(n=e)}this.plugins.audio.upload.call(this,o,n)},error:function(e,t){if(this.closeLoading(),"function"!=typeof this.functions.onAudioUploadError||this.functions.onAudioUploadError(e,t,this))throw this.functions.noticeOpen(e),Error("[SUNEDITOR.plugin.audio.exception] response: "+e)},upload:function(e,t){if(!t)return void this.closeLoading();if("string"==typeof t)return void this.plugins.audio.error.call(this,t,null);const n=this.context.option.audioUploadUrl,i=this.context.dialog.updateModal?1:t.length,l=new FormData;for(let e=0;e<i;e++)l.append("file-"+e,t[e]);this.plugins.fileManager.upload.call(this,n,this.context.option.audioUploadHeader,l,this.plugins.audio.callBack_upload.bind(this,e),this.functions.onAudioUploadError)},callBack_upload:function(e,t){if("function"==typeof this.functions.audioUploadHandler)this.functions.audioUploadHandler(t,e,this);else{const n=JSON.parse(t.responseText);n.errorMessage?this.plugins.audio.error.call(this,n.errorMessage,n):this.plugins.audio.register.call(this,e,n)}},register:function(e,t){const n=t.result;for(let t,i,l=0,o=n.length;l<o;l++)i=e.isUpdate?e.element:this.plugins.audio._createAudioTag.call(this),t={name:n[l].name,size:n[l].size},this.plugins.audio.create_audio.call(this,i,n[l].url,t,e.isUpdate);this.closeLoading()},setupUrl:function(e){try{if(0===e.length)return!1;this.plugins.audio.create_audio.call(this,this.plugins.audio._createAudioTag.call(this),e,null,this.context.dialog.updateModal)}catch(e){throw Error('[SUNEDITOR.audio.audio.fail] cause : "'+e.message+'"')}finally{this.closeLoading()}},create_audio:function(e,t,n,i){const l=this.context.audio;if(i){if(l._element&&(e=l._element),!e||e.src===t)return void this.selectComponent(e,"audio");e.src=t}else{e.src=t;const n=this.plugins.component.set_cover.call(this,e),i=this.plugins.component.set_container.call(this,n,"");if(!this.insertComponent(i,!1,!0,!1))return void this.focus()}this.plugins.fileManager.setInfo.call(this,"audio",e,this.functions.onAudioUpload,n,!1),this.selectComponent(e,"audio"),i&&this.history.push(!1)},updateCover:function(e){const t=this.context.audio;this.plugins.audio._setTagAttrs.call(this,e);const n=this.util.getParentElement(e,this.util.isMediaComponent)||this.util.getParentElement(e,function(e){return this.isWysiwygDiv(e.parentNode)}.bind(this.util));t._element=e=e.cloneNode(!1);const i=this.plugins.component.set_cover.call(this,e),l=this.plugins.component.set_container.call(this,i,"se-audio-container");n.parentNode.replaceChild(l,n),this.plugins.fileManager.setInfo.call(this,"audio",e,this.functions.onAudioUpload,null,!1)},onModifyMode:function(e){const t=this.context.audio;this.setControllerPosition(t.controller,e,"bottom",{left:0,top:0}),this.controllersOn(t.controller,e,this.plugins.audio.onControllerOff.bind(this,e),"audio"),this.util.addClass(e,"active"),t._element=e,t._cover=this.util.getParentElement(e,"FIGURE"),t._container=this.util.getParentElement(e,this.util.isComponent)},openModify:function(e){if(this.context.audio.audioUrlFile){const e=this.context.audio;e._linkValue=e.preview.textContent=e.audioUrlFile.value=e._element.src}e||this.plugins.dialog.open.call(this,"audio",!0)},onClick_controller:function(e){e.stopPropagation();const t=e.target.getAttribute("data-command");t&&(e.preventDefault(),/update/.test(t)?this.plugins.audio.openModify.call(this,!1):this.plugins.audio.destroy.call(this,this.context.audio._element),this.controllersOff())},onControllerOff:function(e){this.util.removeClass(e,"active"),this.context.audio.controller.style.display="none"},init:function(){if(this.context.dialog.updateModal)return;const e=this.context.audio;e.audioInputFile&&(e.audioInputFile.value=""),e.audioUrlFile&&(e._linkValue=e.preview.textContent=e.audioUrlFile.value=""),e.audioInputFile&&e.audioUrlFile&&(e.audioUrlFile.removeAttribute("disabled"),e.preview.style.textDecoration=""),e._element=null}},v={name:"math",display:"dialog",add:function(e){e.addModule([r.a]);const t=e.context;t.math={focusElement:null,previewElement:null,fontSizeElement:null,_mathExp:null};let n=this.setDialog.call(e);t.math.modal=n,t.math.focusElement=n.querySelector(".se-math-exp"),t.math.previewElement=n.querySelector(".se-math-preview"),t.math.fontSizeElement=n.querySelector(".se-math-size"),t.math.focusElement.addEventListener("keyup",this._renderMathExp.bind(e,t.math),!1),t.math.focusElement.addEventListener("change",this._renderMathExp.bind(e,t.math),!1),t.math.fontSizeElement.addEventListener("change",function(e){this.fontSize=e.target.value}.bind(t.math.previewElement.style),!1);let i=this.setController_MathButton.call(e);t.math.mathController=i,t.math._mathExp=null,i.addEventListener("mousedown",e.eventStop),n.querySelector(".se-btn-primary").addEventListener("click",this.submit.bind(e),!1),i.addEventListener("click",this.onClick_mathController.bind(e)),t.dialog.modal.appendChild(n),t.element.relative.appendChild(i),n=null,i=null},setDialog:function(){const e=this.lang,t=this.util.createElement("DIV");return t.className="se-dialog-content",t.style.display="none",t.innerHTML='<form><div class="se-dialog-header"><button type="button" data-command="close" class="se-btn se-dialog-close" aria-label="Close" title="'+e.dialogBox.close+'">'+this.icons.cancel+'</button><span class="se-modal-title">'+e.dialogBox.mathBox.title+'</span></div><div class="se-dialog-body"><div class="se-dialog-form"><label>'+e.dialogBox.mathBox.inputLabel+' (<a href="https://katex.org/docs/supported.html" target="_blank">KaTeX</a>)</label><textarea class="se-input-form se-math-exp" type="text"></textarea></div><div class="se-dialog-form"><label>'+e.dialogBox.mathBox.fontSizeLabel+'</label><select class="se-input-select se-math-size"><option value="1em">1</option><option value="1.5em">1.5</option><option value="2em">2</option><option value="2.5em">2.5</option></select></div><div class="se-dialog-form"><label>'+e.dialogBox.mathBox.previewLabel+'</label><p class="se-math-preview"></p></div></div><div class="se-dialog-footer"><button type="submit" class="se-btn-primary" title="'+e.dialogBox.submitButton+'"><span>'+e.dialogBox.submitButton+"</span></button></div></form>",t},setController_MathButton:function(){const e=this.lang,t=this.util.createElement("DIV");return t.className="se-controller se-controller-link",t.innerHTML='<div class="se-arrow se-arrow-up"></div><div class="link-content"><div class="se-btn-group"><button type="button" data-command="update" tabindex="-1" class="se-btn se-tooltip">'+this.icons.edit+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.edit+'</span></span></button><button type="button" data-command="delete" tabindex="-1" class="se-btn se-tooltip">'+this.icons.delete+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.remove+"</span></span></button></div></div>",t},open:function(){this.plugins.dialog.open.call(this,"math","math"===this.currentControllerName)},managedTags:function(){return{className:"katex",method:function(e){if(!e.getAttribute("data-exp"))return;const t=this._d.createRange().createContextualFragment(this.plugins.math._renderer.call(this,this.util.HTMLDecoder(e.getAttribute("data-exp"))));e.innerHTML=t.querySelector(".katex").innerHTML}}},_renderer:function(e){const t=this.context.option.katex;return t.src.renderToString(e,t.options)},_renderMathExp:function(e,t){e.previewElement.innerHTML=this.plugins.math._renderer.call(this,t.target.value)},submit:function(e){this.showLoading(),e.preventDefault(),e.stopPropagation();const t=function(){if(0===this.context.math.focusElement.value.trim().length)return!1;const e=this.context.math,t=e.focusElement.value,n=e.previewElement.querySelector(".katex");if(!n)return!1;if(n.className="__se__katex "+n.className,n.setAttribute("contenteditable",!1),n.setAttribute("data-exp",this.util.HTMLEncoder(t)),n.setAttribute("data-font-size",e.fontSizeElement.value),n.style.fontSize=e.fontSizeElement.value,this.context.dialog.updateModal){const t=this.util.getParentElement(e._mathExp,".katex");t.parentNode.replaceChild(n,t),this.setRange(n,0,n,1)}else{const e=this.getSelectedElements();if(e.length>1){const t=this.util.createElement(e[0].nodeName);if(t.appendChild(n),!this.insertNode(t,null,!0))return!1}else if(!this.insertNode(n,null,!0))return!1;const t=this.util.createTextNode(this.util.zeroWidthSpace);n.parentNode.insertBefore(t,n.nextSibling),this.setRange(n,0,n,1)}return e.focusElement.value="",e.fontSizeElement.value="1em",e.previewElement.style.fontSize="1em",e.previewElement.innerHTML="",!0}.bind(this);try{t()&&(this.plugins.dialog.close.call(this),this.history.push(!1))}catch(e){this.plugins.dialog.close.call(this)}finally{this.closeLoading()}return!1},active:function(e){if(e){if(e.getAttribute("data-exp"))return this.controllerArray.indexOf(this.context.math.mathController)<0&&(this.setRange(e,0,e,1),this.plugins.math.call_controller.call(this,e)),!0}else this.controllerArray.indexOf(this.context.math.mathController)>-1&&this.controllersOff();return!1},on:function(e){if(e){const e=this.context.math;if(e._mathExp){const t=this.util.HTMLDecoder(e._mathExp.getAttribute("data-exp")),n=e._mathExp.getAttribute("data-font-size")||"1em";this.context.dialog.updateModal=!0,e.focusElement.value=t,e.fontSizeElement.value=n,e.previewElement.innerHTML=this.plugins.math._renderer.call(this,t),e.previewElement.style.fontSize=n}}else this.plugins.math.init.call(this)},call_controller:function(e){this.context.math._mathExp=e;const t=this.context.math.mathController;this.setControllerPosition(t,e,"bottom",{left:0,top:0}),this.controllersOn(t,e,"math")},onClick_mathController:function(e){e.stopPropagation();const t=e.target.getAttribute("data-command")||e.target.parentNode.getAttribute("data-command");t&&(e.preventDefault(),/update/.test(t)?(this.context.math.focusElement.value=this.util.HTMLDecoder(this.context.math._mathExp.getAttribute("data-exp")),this.plugins.dialog.open.call(this,"math",!0)):(this.util.removeItem(this.context.math._mathExp),this.context.math._mathExp=null,this.focus(),this.history.push(!1)),this.controllersOff())},init:function(){const e=this.context.math;e.mathController.style.display="none",e._mathExp=null,e.focusElement.value="",e.previewElement.innerHTML=""}},y=n("JhlZ"),C=n.n(y),w={blockquote:{name:"blockquote",display:"command",add:function(e,t){e.context.blockquote={targetButton:t,tag:e.util.createElement("BLOCKQUOTE")}},active:function(e){if(e){if(/blockquote/i.test(e.nodeName))return this.util.addClass(this.context.blockquote.targetButton,"active"),!0}else this.util.removeClass(this.context.blockquote.targetButton,"active");return!1},action:function(){const e=this.util.getParentElement(this.getSelectionNode(),"blockquote");e?this.detachRangeFormatElement(e,null,null,!1,!1):this.applyRangeFormatElement(this.context.blockquote.tag.cloneNode(!1))}},align:{name:"align",display:"submenu",add:function(e,t){const n=e.icons,i=e.context;i.align={targetButton:t,_alignList:null,currentAlign:"",defaultDir:i.options.rtl?"right":"left",icons:{justify:n.align_justify,left:n.align_left,right:n.align_right,center:n.align_center}};let l=this.setSubmenu.call(e),o=l.querySelector("ul");o.addEventListener("click",this.pickup.bind(e)),i.align._alignList=o.querySelectorAll("li button"),e.initMenuTarget(this.name,t,l),l=null,o=null},setSubmenu:function(){const e=this.lang,t=this.icons,n=this.util.createElement("DIV"),i="left"===this.context.align.defaultDir,l='<li><button type="button" class="se-btn-list se-btn-align" data-command="justifyleft" data-value="left" title="'+e.toolbar.alignLeft+'"><span class="se-list-icon">'+t.align_left+"</span>"+e.toolbar.alignLeft+"</button></li>",o='<li><button type="button" class="se-btn-list se-btn-align" data-command="justifyright" data-value="right" title="'+e.toolbar.alignRight+'"><span class="se-list-icon">'+t.align_right+"</span>"+e.toolbar.alignRight+"</button></li>";return n.className="se-submenu se-list-layer se-list-align",n.innerHTML='<div class="se-list-inner"><ul class="se-list-basic">'+(i?l:o)+'<li><button type="button" class="se-btn-list se-btn-align" data-command="justifycenter" data-value="center" title="'+e.toolbar.alignCenter+'"><span class="se-list-icon">'+t.align_center+"</span>"+e.toolbar.alignCenter+"</button></li>"+(i?o:l)+'<li><button type="button" class="se-btn-list se-btn-align" data-command="justifyfull" data-value="justify" title="'+e.toolbar.alignJustify+'"><span class="se-list-icon">'+t.align_justify+"</span>"+e.toolbar.alignJustify+"</button></li></ul></div>",n},active:function(e){const t=this.context.align,n=t.targetButton,i=n.firstElementChild;if(e){if(this.util.isFormatElement(e)){const l=e.style.textAlign;if(l)return this.util.changeElement(i,t.icons[l]),n.setAttribute("data-focus",l),!0}}else this.util.changeElement(i,t.icons[t.defaultDir]),n.removeAttribute("data-focus");return!1},on:function(){const e=this.context.align,t=e._alignList,n=e.targetButton.getAttribute("data-focus")||e.defaultDir;if(n!==e.currentAlign){for(let e=0,i=t.length;e<i;e++)n===t[e].getAttribute("data-value")?this.util.addClass(t[e],"active"):this.util.removeClass(t[e],"active");e.currentAlign=n}},pickup:function(e){e.preventDefault(),e.stopPropagation();let t=e.target,n=null;for(;!n&&!/UL/i.test(t.tagName);)n=t.getAttribute("data-value"),t=t.parentNode;if(!n)return;const i=this.context.align.defaultDir,l=this.getSelectedElements();for(let e=0,t=l.length;e<t;e++)this.util.setStyle(l[e],"textAlign",n===i?"":n);this.effectNode=null,this.submenuOff(),this.focus(),this.history.push(!1)}},font:{name:"font",display:"submenu",add:function(e,t){const n=e.context;n.font={targetText:t.querySelector(".txt"),targetTooltip:t.parentNode.querySelector(".se-tooltip-text"),_fontList:null,currentFont:""};let i=this.setSubmenu.call(e);i.querySelector(".se-list-inner").addEventListener("click",this.pickup.bind(e)),n.font._fontList=i.querySelectorAll("ul li button"),e.initMenuTarget(this.name,t,i),i=null},setSubmenu:function(){const e=this.context.option,t=this.lang,n=this.util.createElement("DIV");let i,l,o,s;n.className="se-submenu se-list-layer se-list-font-family";let a=e.font?e.font:["Arial","Comic Sans MS","Courier New","Impact","Georgia","tahoma","Trebuchet MS","Verdana"],r='<div class="se-list-inner"><ul class="se-list-basic"><li><button type="button" class="default_value se-btn-list" title="'+t.toolbar.default+'">('+t.toolbar.default+")</button></li>";for(o=0,s=a.length;o<s;o++)i=a[o],l=i.split(",")[0],r+='<li><button type="button" class="se-btn-list" data-value="'+i+'" data-txt="'+l+'" title="'+l+'" style="font-family:'+i+';">'+l+"</button></li>";return r+="</ul></div>",n.innerHTML=r,n},active:function(e){const t=this.context.font.targetText,n=this.context.font.targetTooltip;if(e){if(e.style&&e.style.fontFamily.length>0){const i=e.style.fontFamily.replace(/["']/g,"");return this.util.changeTxt(t,i),this.util.changeTxt(n,i),!0}}else{const e=this.lang.toolbar.font;this.util.changeTxt(t,e),this.util.changeTxt(n,e)}return!1},on:function(){const e=this.context.font,t=e._fontList,n=e.targetText.textContent;if(n!==e.currentFont){for(let e=0,i=t.length;e<i;e++)n===t[e].getAttribute("data-value")?this.util.addClass(t[e],"active"):this.util.removeClass(t[e],"active");e.currentFont=n}},pickup:function(e){if(!/^BUTTON$/i.test(e.target.tagName))return!1;e.preventDefault(),e.stopPropagation();const t=e.target.getAttribute("data-value");if(t){const e=this.util.createElement("SPAN");e.style.fontFamily=t,this.nodeChange(e,["font-family"],null,null)}else this.nodeChange(null,["font-family"],["span"],!0);this.submenuOff()}},fontSize:{name:"fontSize",display:"submenu",add:function(e,t){const n=e.context;n.fontSize={targetText:t.querySelector(".txt"),_sizeList:null,currentSize:""};let i=this.setSubmenu.call(e),l=i.querySelector("ul");l.addEventListener("click",this.pickup.bind(e)),n.fontSize._sizeList=l.querySelectorAll("li button"),e.initMenuTarget(this.name,t,i),i=null,l=null},setSubmenu:function(){const e=this.context.option,t=this.lang,n=this.util.createElement("DIV");n.className="se-submenu se-list-layer se-list-font-size";const i=e.fontSize?e.fontSize:[8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72];let l='<div class="se-list-inner"><ul class="se-list-basic"><li><button type="button" class="default_value se-btn-list" title="'+t.toolbar.default+'">('+t.toolbar.default+")</button></li>";for(let t,n=0,o=e.fontSizeUnit,s=i.length;n<s;n++)t=i[n],l+='<li><button type="button" class="se-btn-list" data-value="'+t+o+'" title="'+t+o+'" style="font-size:'+t+o+';">'+t+"</button></li>";return l+="</ul></div>",n.innerHTML=l,n},active:function(e){if(e){if(e.style&&e.style.fontSize.length>0)return this.util.changeTxt(this.context.fontSize.targetText,e.style.fontSize),!0}else this.util.changeTxt(this.context.fontSize.targetText,this.lang.toolbar.fontSize);return!1},on:function(){const e=this.context.fontSize,t=e._sizeList,n=e.targetText.textContent;if(n!==e.currentSize){for(let e=0,i=t.length;e<i;e++)n===t[e].getAttribute("data-value")?this.util.addClass(t[e],"active"):this.util.removeClass(t[e],"active");e.currentSize=n}},pickup:function(e){if(!/^BUTTON$/i.test(e.target.tagName))return!1;e.preventDefault(),e.stopPropagation();const t=e.target.getAttribute("data-value");if(t){const e=this.util.createElement("SPAN");e.style.fontSize=t,this.nodeChange(e,["font-size"],null,null)}else this.nodeChange(null,["font-size"],["span"],!0);this.submenuOff()}},fontColor:l,hiliteColor:o,horizontalRule:{name:"horizontalRule",display:"submenu",add:function(e,t){let n=this.setSubmenu.call(e);n.querySelector("ul").addEventListener("click",this.horizontalRulePick.bind(e)),e.initMenuTarget(this.name,t,n),n=null},setSubmenu:function(){const e=this.lang,t=this.util.createElement("DIV");return t.className="se-submenu se-list-layer se-list-line",t.innerHTML='<div class="se-list-inner"><ul class="se-list-basic"><li><button type="button" class="se-btn-list btn_line" data-command="horizontalRule" data-value="solid" title="'+e.toolbar.hr_solid+'"><hr style="border-width: 1px 0 0; border-style: solid none none; border-color: black; border-image: initial; height: 1px;" /></button></li><li><button type="button" class="se-btn-list btn_line" data-command="horizontalRule" data-value="dotted" title="'+e.toolbar.hr_dotted+'"><hr style="border-width: 1px 0 0; border-style: dotted none none; border-color: black; border-image: initial; height: 1px;" /></button></li><li><button type="button" class="se-btn-list btn_line" data-command="horizontalRule" data-value="dashed" title="'+e.toolbar.hr_dashed+'"><hr style="border-width: 1px 0 0; border-style: dashed none none; border-color: black; border-image: initial; height: 1px;" /></button></li></ul></div>',t},appendHr:function(e){const t=this.util.createElement("HR");return t.className=e,this.focus(),this.insertComponent(t,!1,!0,!1)},horizontalRulePick:function(e){e.preventDefault(),e.stopPropagation();let t=e.target,n=null;for(;!n&&!/UL/i.test(t.tagName);)n=t.getAttribute("data-value"),t=t.parentNode;if(!n)return;const i=this.plugins.horizontalRule.appendHr.call(this,"__se__"+n);i&&(this.setRange(i,0,i,0),this.submenuOff())}},list:{name:"list",display:"submenu",add:function(e,t){const n=e.context;n.list={targetButton:t,_list:null,currentList:"",icons:{bullets:e.icons.list_bullets,number:e.icons.list_number}};let i=this.setSubmenu.call(e),l=i.querySelector("ul");l.addEventListener("click",this.pickup.bind(e)),n.list._list=l.querySelectorAll("li button"),e.initMenuTarget(this.name,t,i),i=null,l=null},setSubmenu:function(){const e=this.lang,t=this.util.createElement("DIV");return t.className="se-submenu se-list-layer",t.innerHTML='<div class="se-list-inner"><ul class="se-list-basic"><li><button type="button" class="se-btn-list se-tooltip" data-command="OL" title="'+e.toolbar.orderList+'">'+this.icons.list_number+'</button></li><li><button type="button" class="se-btn-list se-tooltip" data-command="UL" title="'+e.toolbar.unorderList+'">'+this.icons.list_bullets+"</button></li></ul></div>",t},active:function(e){const t=this.context.list.targetButton,n=t.firstElementChild,i=this.util;if(e){if(i.isList(e)){const l=e.nodeName;return t.setAttribute("data-focus",l),i.addClass(t,"active"),/UL/i.test(l)?i.changeElement(n,this.context.list.icons.bullets):i.changeElement(n,this.context.list.icons.number),!0}}else t.removeAttribute("data-focus"),i.changeElement(n,this.context.list.icons.number),i.removeClass(t,"active");return!1},on:function(){const e=this.context.list,t=e._list,n=e.targetButton.getAttribute("data-focus")||"";if(n!==e.currentList){for(let e=0,i=t.length;e<i;e++)n===t[e].getAttribute("data-command")?this.util.addClass(t[e],"active"):this.util.removeClass(t[e],"active");e.currentList=n}},editList:function(e,t,n){let i=this.getRange(),l=t||this.getSelectedElementsAndComponents(!1);if(0===l.length){if(t)return;if(i=this.getRange_addLine(i,null),l=this.getSelectedElementsAndComponents(!1),0===l.length)return}const o=this.util;o.sortByDepth(l,!0);let s=l[0],a=l[l.length-1],r=!o.isListCell(s)&&!o.isComponent(s)||s.previousElementSibling?s.previousElementSibling:s.parentNode.previousElementSibling,c=!o.isListCell(a)&&!o.isComponent(a)||a.nextElementSibling?a.nextElementSibling:a.parentNode.nextElementSibling;const d={sc:i.startContainer,so:i.startOffset,ec:i.endContainer,eo:i.endOffset};let u=!0;for(let e=0,t=l.length;e<t;e++)if(!o.isList(o.getRangeFormatElement(l[e],function(t){return this.getRangeFormatElement(t)&&t!==l[e]}.bind(o)))){u=!1;break}if(!u||r&&s.tagName===r.tagName&&e===r.tagName.toUpperCase()||c&&a.tagName===c.tagName&&e===c.tagName.toUpperCase()){const t=r?r.parentNode:r,n=c?c.parentNode:c;r=t&&!o.isWysiwygDiv(t)&&t.nodeName===e?t:r,c=n&&!o.isWysiwygDiv(n)&&n.nodeName===e?n:c;const i=r&&r.tagName===e,s=c&&c.tagName===e;let a=i?r:o.createElement(e),d=null,u=null,h=null,g=null;const p=function(e){return!this.isComponent(e)&&!this.isList(e)}.bind(o);for(let t,n,s,r,c,g,m,f,_,b=0,v=l.length;b<v;b++)if(n=l[b],0!==n.childNodes.length||o._isIgnoreNodeChange(n)){if(r=l[b+1],c=n.parentNode,g=r?r.parentNode:null,s=o.isListCell(n),_=o.isRangeFormatElement(c)?c:null,m=s&&!o.isWysiwygDiv(c)?c.parentNode:c,f=s&&!o.isWysiwygDiv(c)?!r||o.isListCell(m)?c:c.nextSibling:n.nextSibling,t=o.createElement("LI"),o.copyFormatAttributes(t,n),o.isComponent(n)){const e=/^HR$/i.test(n.nodeName);e||(t.innerHTML="<br>"),t.innerHTML+=n.outerHTML,e&&(t.innerHTML+="<br>")}else{const e=n.childNodes;for(;e[0];)t.appendChild(e[0])}a.appendChild(t),r||(u=a),r&&m===g&&!o.isRangeFormatElement(f)||(d||(d=a),i&&r&&m===g||r&&o.isList(g)&&g===c||a.parentNode!==m&&m.insertBefore(a,f)),o.removeItem(n),i&&null===h&&(h=a.children.length-1),r&&(o.getRangeFormatElement(g,p)!==o.getRangeFormatElement(c,p)||o.isList(g)&&o.isList(c)&&o.getElementDepth(g)!==o.getElementDepth(c))&&(a=o.createElement(e)),_&&0===_.children.length&&o.removeItem(_)}else o.removeItem(n);h&&(d=d.children[h]),s&&(g=a.children.length-1,a.innerHTML+=c.innerHTML,u=a.children[g],o.removeItem(c))}else{if(n)for(let e=0,t=l.length;e<t;e++)for(let n=e-1;n>=0;n--)if(l[n].contains(l[e])){l.splice(e,1),e--,t--;break}const t=o.getRangeFormatElement(s),i=t&&t.tagName===e;let a,r;const c=function(e){return!this.isComponent(e)}.bind(o);i||(r=o.createElement(e));for(let t,s,d=0,u=l.length;d<u;d++)s=o.getRangeFormatElement(l[d],c),s&&o.isList(s)&&(t?t!==s?(n&&o.isListCell(s.parentNode)?this.plugins.list._detachNested.call(this,a.f):this.detachRangeFormatElement(a.f[0].parentNode,a.f,r,!1,!0),s=l[d].parentNode,i||(r=o.createElement(e)),t=s,a={r:t,f:[o.getParentElement(l[d],"LI")]}):a.f.push(o.getParentElement(l[d],"LI")):(t=s,a={r:t,f:[o.getParentElement(l[d],"LI")]}),d===u-1&&(n&&o.isListCell(s.parentNode)?this.plugins.list._detachNested.call(this,a.f):this.detachRangeFormatElement(a.f[0].parentNode,a.f,r,!1,!0)))}return this.effectNode=null,d},_detachNested:function(e){const t=e[0],n=e[e.length-1],i=n.nextElementSibling,l=t.parentNode,o=l.parentNode.nextElementSibling,s=l.parentNode.parentNode;for(let t=0,n=e.length;t<n;t++)s.insertBefore(e[t],o);if(i&&l.children.length>0){const e=l.cloneNode(!1),t=l.childNodes,o=this.util.getPositionIndex(i);for(;t[o];)e.appendChild(t[o]);n.appendChild(e)}0===l.children.length&&this.util.removeItem(l),this.util.mergeSameTags(s);const a=this.util.getEdgeChildNodes(t,n);return{cc:t.parentNode,sc:a.sc,ec:a.ec}},editInsideList:function(e,t){const n=(t=t||this.getSelectedElements().filter(function(e){return this.isListCell(e)}.bind(this.util))).length;if(0===n||!e&&!this.util.isListCell(t[0].previousElementSibling)&&!this.util.isListCell(t[n-1].nextElementSibling))return{sc:t[0],so:0,ec:t[n-1],eo:1};let i=t[0].parentNode,l=t[n-1],o=null;if(e){if(i!==l.parentNode&&this.util.isList(l.parentNode.parentNode)&&l.nextElementSibling)for(l=l.nextElementSibling;l;)t.push(l),l=l.nextElementSibling;o=this.plugins.list.editList.call(this,i.nodeName.toUpperCase(),t,!0)}else{let e=this.util.createElement(i.nodeName),s=t[0].previousElementSibling,a=l.nextElementSibling;const r={s:null,e:null,sl:i,el:i};for(let l,o=0,c=n;o<c;o++)l=t[o],l.parentNode!==i&&(this.plugins.list._insiedList.call(this,i,e,s,a,r),i=l.parentNode,e=this.util.createElement(i.nodeName)),s=l.previousElementSibling,a=l.nextElementSibling,e.appendChild(l);this.plugins.list._insiedList.call(this,i,e,s,a,r);const c=this.util.getNodeFromPath(r.s,r.sl),d=this.util.getNodeFromPath(r.e,r.el);o={sc:c,so:0,ec:d,eo:d.textContent.length}}return o},_insiedList:function(e,t,n,i,l){let o=!1;if(n&&t.tagName===n.tagName){const e=t.children;for(;e[0];)n.appendChild(e[0]);t=n,o=!0}if(i&&t.tagName===i.tagName){const e=i.children;for(;e[0];)t.appendChild(e[0]);const n=i.nextElementSibling;i.parentNode.removeChild(i),i=n}if(!o){this.util.isListCell(n)&&(e=n,i=null),e.insertBefore(t,i),l.s||(l.s=this.util.getNodePath(t.firstElementChild.firstChild,e,null),l.sl=e);const o=e.contains(l.sl)?this.util.getNodePath(l.sl,e):null;l.e=this.util.getNodePath(t.lastElementChild.firstChild,e,null),l.el=e,this.util.mergeSameTags(e,[l.s,l.e,o],!1),this.util.mergeNestedTags(e),o&&(l.sl=this.util.getNodeFromPath(o,e))}return t},pickup:function(e){e.preventDefault(),e.stopPropagation();let t=e.target,n="";for(;!n&&!/^UL$/i.test(t.tagName);)n=t.getAttribute("data-command"),t=t.parentNode;if(!n)return;const i=this.plugins.list.editList.call(this,n,null,!1);i&&this.setRange(i.sc,i.so,i.ec,i.eo),this.submenuOff(),this.history.push(!1)}},table:{name:"table",display:"submenu",add:function(e,t){const n=e.context;let i=n.table={_element:null,_tdElement:null,_trElement:null,_trElements:null,_tableXY:[],_maxWidth:!0,_fixedColumn:!1,_rtl:n.options.rtl,cellControllerTop:"top"===n.options.tableCellControllerPosition,resizeText:null,headerButton:null,mergeButton:null,splitButton:null,splitMenu:null,maxText:e.lang.controller.maxSize,minText:e.lang.controller.minSize,_physical_cellCnt:0,_logical_cellCnt:0,_rowCnt:0,_rowIndex:0,_physical_cellIndex:0,_logical_cellIndex:0,_current_colSpan:0,_current_rowSpan:0,icons:{expansion:e.icons.expansion,reduction:e.icons.reduction}},l=this.setSubmenu.call(e),o=l.querySelector(".se-controller-table-picker");i.tableHighlight=l.querySelector(".se-table-size-highlighted"),i.tableUnHighlight=l.querySelector(".se-table-size-unhighlighted"),i.tableDisplay=l.querySelector(".se-table-size-display"),n.options.rtl&&(i.tableHighlight.style.left="167px");let s=this.setController_table.call(e);i.tableController=s,i.resizeButton=s.querySelector("._se_table_resize"),i.resizeText=s.querySelector("._se_table_resize > span > span"),i.columnFixedButton=s.querySelector("._se_table_fixed_column"),i.headerButton=s.querySelector("._se_table_header"),s.addEventListener("mousedown",e.eventStop);let a=this.setController_tableEditor.call(e,i.cellControllerTop);i.resizeDiv=a,i.splitMenu=a.querySelector(".se-btn-group-sub"),i.mergeButton=a.querySelector("._se_table_merge_button"),i.splitButton=a.querySelector("._se_table_split_button"),i.insertRowAboveButton=a.querySelector("._se_table_insert_row_a"),i.insertRowBelowButton=a.querySelector("._se_table_insert_row_b"),a.addEventListener("mousedown",e.eventStop),o.addEventListener("mousemove",this.onMouseMove_tablePicker.bind(e,i)),o.addEventListener("click",this.appendTable.bind(e)),a.addEventListener("click",this.onClick_tableController.bind(e)),s.addEventListener("click",this.onClick_tableController.bind(e)),e.initMenuTarget(this.name,t,l),n.element.relative.appendChild(a),n.element.relative.appendChild(s),l=null,o=null,a=null,s=null,i=null},setSubmenu:function(){const e=this.util.createElement("DIV");return e.className="se-submenu se-selector-table",e.innerHTML='<div class="se-table-size"><div class="se-table-size-picker se-controller-table-picker"></div><div class="se-table-size-highlighted"></div><div class="se-table-size-unhighlighted"></div></div><div class="se-table-size-display">1 x 1</div>',e},setController_table:function(){const e=this.lang,t=this.icons,n=this.util.createElement("DIV");return n.className="se-controller se-controller-table",n.innerHTML='<div><div class="se-btn-group"><button type="button" data-command="resize" class="se-btn se-tooltip _se_table_resize">'+t.expansion+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.maxSize+'</span></span></button><button type="button" data-command="layout" class="se-btn se-tooltip _se_table_fixed_column">'+t.fixed_column_width+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.fixedColumnWidth+'</span></span></button><button type="button" data-command="header" class="se-btn se-tooltip _se_table_header">'+t.table_header+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.tableHeader+'</span></span></button><button type="button" data-command="remove" class="se-btn se-tooltip">'+t.delete+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.remove+"</span></span></button></div></div>",n},setController_tableEditor:function(e){const t=this.lang,n=this.icons,i=this.util.createElement("DIV");return i.className="se-controller se-controller-table-cell",i.innerHTML=(e?"":'<div class="se-arrow se-arrow-up"></div>')+'<div class="se-btn-group"><button type="button" data-command="insert" data-value="row" data-option="up" class="se-btn se-tooltip _se_table_insert_row_a">'+n.insert_row_above+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+t.controller.insertRowAbove+'</span></span></button><button type="button" data-command="insert" data-value="row" data-option="down" class="se-btn se-tooltip _se_table_insert_row_b">'+n.insert_row_below+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+t.controller.insertRowBelow+'</span></span></button><button type="button" data-command="delete" data-value="row" class="se-btn se-tooltip">'+n.delete_row+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+t.controller.deleteRow+'</span></span></button><button type="button" data-command="merge" class="_se_table_merge_button se-btn se-tooltip" disabled>'+n.merge_cell+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+t.controller.mergeCells+'</span></span></button></div><div class="se-btn-group" style="padding-top: 0;"><button type="button" data-command="insert" data-value="cell" data-option="left" class="se-btn se-tooltip">'+n.insert_column_left+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+t.controller.insertColumnBefore+'</span></span></button><button type="button" data-command="insert" data-value="cell" data-option="right" class="se-btn se-tooltip">'+n.insert_column_right+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+t.controller.insertColumnAfter+'</span></span></button><button type="button" data-command="delete" data-value="cell" class="se-btn se-tooltip">'+n.delete_column+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+t.controller.deleteColumn+'</span></span></button><button type="button" data-command="onsplit" class="_se_table_split_button se-btn se-tooltip">'+n.split_cell+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+t.controller.splitCells+'</span></span></button><div class="se-btn-group-sub sun-editor-common se-list-layer"><div class="se-list-inner"><ul class="se-list-basic"><li class="se-btn-list" data-command="split" data-value="vertical" style="line-height:32px;" title="'+t.controller.VerticalSplit+'">'+t.controller.VerticalSplit+'</li><li class="se-btn-list" data-command="split" data-value="horizontal" style="line-height:32px;" title="'+t.controller.HorizontalSplit+'">'+t.controller.HorizontalSplit+"</li></ul></div></div></div>",i},appendTable:function(){const e=this.util.createElement("TABLE"),t=this.plugins.table.createCells,n=this.context.table._tableXY[0];let i=this.context.table._tableXY[1],l="<tbody>";for(;i>0;)l+="<tr>"+t.call(this,"td",n)+"</tr>",--i;l+="</tbody>",e.innerHTML=l;if(this.insertComponent(e,!1,!0,!1)){const t=e.querySelector("td div");this.setRange(t,0,t,0),this.plugins.table.reset_table_picker.call(this)}},createCells:function(e,t,n){if(e=e.toLowerCase(),n){const t=this.util.createElement(e);return t.innerHTML="<div><br></div>",t}{let n="";for(;t>0;)n+="<"+e+"><div><br></div></"+e+">",t--;return n}},onMouseMove_tablePicker:function(e,t){t.stopPropagation();let n=this._w.Math.ceil(t.offsetX/18),i=this._w.Math.ceil(t.offsetY/18);n=n<1?1:n,i=i<1?1:i,e._rtl&&(e.tableHighlight.style.left=18*n-13+"px",n=11-n),e.tableHighlight.style.width=n+"em",e.tableHighlight.style.height=i+"em",this.util.changeTxt(e.tableDisplay,n+" x "+i),e._tableXY=[n,i]},reset_table_picker:function(){if(!this.context.table.tableHighlight)return;const e=this.context.table.tableHighlight.style,t=this.context.table.tableUnHighlight.style;e.width="1em",e.height="1em",t.width="10em",t.height="10em",this.util.changeTxt(this.context.table.tableDisplay,"1 x 1"),this.submenuOff()},init:function(){const e=this.context.table,t=this.plugins.table;if(t._removeEvents.call(this),t._selectedTable){const e=t._selectedTable.querySelectorAll(".se-table-selected-cell");for(let t=0,n=e.length;t<n;t++)this.util.removeClass(e[t],"se-table-selected-cell")}t._toggleEditor.call(this,!0),e._element=null,e._tdElement=null,e._trElement=null,e._trElements=null,e._tableXY=[],e._maxWidth=!0,e._fixedColumn=!1,e._physical_cellCnt=0,e._logical_cellCnt=0,e._rowCnt=0,e._rowIndex=0,e._physical_cellIndex=0,e._logical_cellIndex=0,e._current_colSpan=0,e._current_rowSpan=0,t._shift=!1,t._selectedCells=null,t._selectedTable=null,t._ref=null,t._fixedCell=null,t._selectedCell=null,t._fixedCellName=null},call_controller_tableEdit:function(e){const t=this.plugins.table,n=this.context.table;if(!this.getSelection().isCollapsed&&!t._selectedCell)return this.controllersOff(),void this.util.removeClass(e,"se-table-selected-cell");const i=n._element||this.plugins.table._selectedTable||this.util.getParentElement(e,"TABLE");n._maxWidth=this.util.hasClass(i,"se-table-size-100")||"100%"===i.style.width||!i.style.width&&!this.util.hasClass(i,"se-table-size-auto"),n._fixedColumn=this.util.hasClass(i,"se-table-layout-fixed")||"fixed"===i.style.tableLayout,t.setTableStyle.call(this,n._maxWidth?"width|column":"width"),t.setPositionControllerTop.call(this,i),t.setPositionControllerDiv.call(this,e,t._shift),t._shift||this.controllersOn(n.resizeDiv,n.tableController,t.init.bind(this),e,"table")},setPositionControllerTop:function(e){this.setControllerPosition(this.context.table.tableController,e,"top",{left:0,top:0})},setPositionControllerDiv:function(e,t){const n=this.context.table,i=n.resizeDiv;this.plugins.table.setCellInfo.call(this,e,t),n.cellControllerTop?this.setControllerPosition(i,n._element,"top",{left:n.tableController.offsetWidth,top:0}):this.setControllerPosition(i,e,"bottom",{left:0,top:0})},setCellInfo:function(e,t){const n=this.context.table,i=n._element=this.plugins.table._selectedTable||this.util.getParentElement(e,"TABLE");if(/THEAD/i.test(i.firstElementChild.nodeName)?this.util.addClass(n.headerButton,"active"):this.util.removeClass(n.headerButton,"active"),t||0===n._physical_cellCnt){n._tdElement!==e&&(n._tdElement=e,n._trElement=e.parentNode);const t=n._trElements=i.rows,l=e.cellIndex;let o=0;for(let e=0,n=t[0].cells,i=t[0].cells.length;e<i;e++)o+=n[e].colSpan;const s=n._rowIndex=n._trElement.rowIndex;n._rowCnt=t.length,n._physical_cellCnt=n._trElement.cells.length,n._logical_cellCnt=o,n._physical_cellIndex=l,n._current_colSpan=n._tdElement.colSpan-1,n._current_rowSpan,n._trElement.cells[l].rowSpan;let a=[],r=[];for(let e,i,o=0;o<=s;o++){e=t[o].cells,i=0;for(let t,c,d,u,h=0,g=e.length;h<g;h++){if(t=e[h],c=t.colSpan-1,d=t.rowSpan-1,u=h+i,r.length>0)for(let e,t=0;t<r.length;t++)e=r[t],e.row>o||(u>=e.index?(i+=e.cs,u+=e.cs,e.rs-=1,e.row=o+1,e.rs<1&&(r.splice(t,1),t--)):h===g-1&&(e.rs-=1,e.row=o+1,e.rs<1&&(r.splice(t,1),t--)));if(o===s&&h===l){n._logical_cellIndex=u;break}d>0&&a.push({index:u,cs:c+1,rs:d,row:-1}),i+=c}r=r.concat(a).sort((function(e,t){return e.index-t.index})),a=[]}a=null,r=null}},editTable:function(e,t){const n=this.plugins.table,i=this.context.table,l=i._element,o="row"===e;if(o){const e=i._trElement.parentNode;if(/^THEAD$/i.test(e.nodeName)){if("up"===t)return;if(!e.nextElementSibling||!/^TBODY$/i.test(e.nextElementSibling.nodeName))return void(l.innerHTML+="<tbody><tr>"+n.createCells.call(this,"td",i._logical_cellCnt,!1)+"</tr></tbody>")}}if(n._ref){const e=i._tdElement,l=n._selectedCells;if(o)if(t)n.setCellInfo.call(this,"up"===t?l[0]:l[l.length-1],!0),n.editRow.call(this,t,e);else{let e=l[0].parentNode;const i=[l[0]];for(let t,n=1,o=l.length;n<o;n++)t=l[n],e!==t.parentNode&&(i.push(t),e=t.parentNode);for(let e=0,l=i.length;e<l;e++)n.setCellInfo.call(this,i[e],!0),n.editRow.call(this,t)}else{const i=l[0].parentNode;if(t){let o=null;for(let e=0,t=l.length-1;e<t;e++)if(i!==l[e+1].parentNode){o=l[e];break}n.setCellInfo.call(this,"left"===t?l[0]:o||l[0],!0),n.editCell.call(this,t,e)}else{const e=[l[0]];for(let t,n=1,o=l.length;n<o&&(t=l[n],i===t.parentNode);n++)e.push(t);for(let i=0,l=e.length;i<l;i++)n.setCellInfo.call(this,e[i],!0),n.editCell.call(this,t)}}t||n.init.call(this)}else n[o?"editRow":"editCell"].call(this,t);if(!t){const e=l.children;for(let t=0;t<e.length;t++)0===e[t].children.length&&(this.util.removeItem(e[t]),t--);0===l.children.length&&this.util.removeItem(l)}},editRow:function(e,t){const n=this.context.table,i=!e,l="up"===e,o=n._rowIndex,s=i||l?o:o+n._current_rowSpan+1,a=i?-1:1,r=n._trElements;let c=n._logical_cellCnt;for(let e,t=0,n=o+(i?-1:0);t<=n;t++){if(e=r[t].cells,0===e.length)return;for(let n,i,l=0,o=e.length;l<o;l++)n=e[l].rowSpan,i=e[l].colSpan,n<2&&i<2||n+t>s&&s>t&&(e[l].rowSpan=n+a,c-=i)}if(i){const e=r[o+1];if(e){const t=[];let n=r[o].cells,i=0;for(let e,l,o=0,s=n.length;o<s;o++)e=n[o],l=o+i,i+=e.colSpan-1,e.rowSpan>1&&(e.rowSpan-=1,t.push({cell:e.cloneNode(!1),index:l}));if(t.length>0){let l=t.shift();n=e.cells,i=0;for(let o,s,a=0,r=n.length;a<r&&(o=n[a],s=a+i,i+=o.colSpan-1,!(s>=l.index)||(a--,i--,i+=l.cell.colSpan-1,e.insertBefore(l.cell,o),l=t.shift(),l));a++);if(l){e.appendChild(l.cell);for(let n=0,i=t.length;n<i;n++)e.appendChild(t[n].cell)}}}n._element.deleteRow(s)}else{n._element.insertRow(s).innerHTML=this.plugins.table.createCells.call(this,"td",c,!1)}i?this.controllersOff():this.plugins.table.setPositionControllerDiv.call(this,t||n._tdElement,!0)},editCell:function(e,t){const n=this.context.table,i=this.util,l=!e,o="left"===e,s=n._current_colSpan,a=l||o?n._logical_cellIndex:n._logical_cellIndex+s+1,r=n._trElements;let c=[],d=[],u=0;const h=[],g=[];for(let e,t,o,p,m,f,_=0,b=n._rowCnt;_<b;_++){e=r[_],t=a,m=!1,o=e.cells,f=0;for(let e,n,r,p,b=0,v=o.length;b<v&&(e=o[b],e);b++)if(n=e.rowSpan-1,r=e.colSpan-1,l){if(p=b+f,d.length>0){const e=!o[b+1];for(let t,n=0;n<d.length;n++)t=d[n],t.row>_||(p>=t.index?(f+=t.cs,p=b+f,t.rs-=1,t.row=_+1,t.rs<1&&(d.splice(n,1),n--)):e&&(t.rs-=1,t.row=_+1,t.rs<1&&(d.splice(n,1),n--)))}n>0&&c.push({rs:n,cs:r+1,index:p,row:-1}),p>=t&&p+r<=t+s?h.push(e):p<=t+s&&p+r>=t?e.colSpan-=i.getOverlapRangeAtIndex(a,a+s,p,p+r):n>0&&(p<t||p+r>t+s)&&g.push({cell:e,i:_,rs:_+n}),f+=r}else{if(b>=t)break;if(r>0){if(u<1&&r+b>=t){e.colSpan+=1,t=null,u=n+1;break}t-=r}if(!m){for(let e,n=0;n<d.length;n++)e=d[n],t-=e.cs,e.rs-=1,e.rs<1&&(d.splice(n,1),n--);m=!0}}if(d=d.concat(c).sort((function(e,t){return e.index-t.index})),c=[],!l){if(u>0){u-=1;continue}null!==t&&o.length>0&&(p=this.plugins.table.createCells.call(this,o[0].nodeName,0,!0),p=e.insertBefore(p,o[t]))}}if(l){let e,t;for(let n,l=0,o=h.length;l<o;l++)n=h[l].parentNode,i.removeItem(h[l]),0===n.cells.length&&(e||(e=i.getArrayIndex(r,n)),t=i.getArrayIndex(r,n),i.removeItem(n));for(let n,l=0,o=g.length;l<o;l++)n=g[l],n.cell.rowSpan=i.getOverlapRangeAtIndex(e,t,n.i,n.rs);this.controllersOff()}else this.plugins.table.setPositionControllerDiv.call(this,t||n._tdElement,!0)},_closeSplitMenu:null,openSplitMenu:function(){this.util.addClass(this.context.table.splitButton,"on"),this.context.table.splitMenu.style.display="inline-table",this.plugins.table._closeSplitMenu=function(){this.util.removeClass(this.context.table.splitButton,"on"),this.context.table.splitMenu.style.display="none",this.removeDocEvent("mousedown",this.plugins.table._closeSplitMenu),this.plugins.table._closeSplitMenu=null}.bind(this),this.addDocEvent("mousedown",this.plugins.table._closeSplitMenu)},splitCells:function(e){const t=this.util,n="vertical"===e,i=this.context.table,l=i._tdElement,o=i._trElements,s=i._trElement,a=i._logical_cellIndex,r=i._rowIndex,c=this.plugins.table.createCells.call(this,l.nodeName,0,!0);if(n){const e=l.colSpan;if(c.rowSpan=l.rowSpan,e>1)c.colSpan=this._w.Math.floor(e/2),l.colSpan=e-c.colSpan,s.insertBefore(c,l.nextElementSibling);else{let t=[],n=[];for(let s,r,c=0,d=i._rowCnt;c<d;c++){s=o[c].cells,r=0;for(let i,o,d,u,h=0,g=s.length;h<g;h++){if(i=s[h],o=i.colSpan-1,d=i.rowSpan-1,u=h+r,n.length>0)for(let e,t=0;t<n.length;t++)e=n[t],e.row>c||(u>=e.index?(r+=e.cs,u+=e.cs,e.rs-=1,e.row=c+1,e.rs<1&&(n.splice(t,1),t--)):h===g-1&&(e.rs-=1,e.row=c+1,e.rs<1&&(n.splice(t,1),t--)));if(u<=a&&d>0&&t.push({index:u,cs:o+1,rs:d,row:-1}),i!==l&&u<=a&&u+o>=a+e-1){i.colSpan+=1;break}if(u>a)break;r+=o}n=n.concat(t).sort((function(e,t){return e.index-t.index})),t=[]}s.insertBefore(c,l.nextElementSibling)}}else{const e=l.rowSpan;if(c.colSpan=l.colSpan,e>1){c.rowSpan=this._w.Math.floor(e/2);const n=e-c.rowSpan,i=[],r=t.getArrayIndex(o,s)+n;for(let e,t,n=0;n<r;n++){e=o[n].cells,t=0;for(let l,o,s,c=0,d=e.length;c<d&&(s=c+t,!(s>=a));c++)l=e[c],o=l.rowSpan-1,o>0&&o+n>=r&&s<a&&i.push({index:s,cs:l.colSpan}),t+=l.colSpan-1}const d=o[r],u=d.cells;let h=i.shift();for(let e,t,n,l,o=0,s=u.length,r=0;o<s;o++){if(n=o+r,e=u[o],t=e.colSpan-1,l=n+t+1,h&&l>=h.index&&(r+=h.cs,l+=h.cs,h=i.shift()),l>=a||o===s-1){d.insertBefore(c,e.nextElementSibling);break}r+=t}l.rowSpan=n}else{c.rowSpan=l.rowSpan;const e=t.createElement("TR");e.appendChild(c);for(let e,t=0;t<r;t++){if(e=o[t].cells,0===e.length)return;for(let n=0,i=e.length;n<i;n++)t+e[n].rowSpan-1>=r&&(e[n].rowSpan+=1)}const n=i._physical_cellIndex,a=s.cells;for(let e=0,t=a.length;e<t;e++)e!==n&&(a[e].rowSpan+=1);s.parentNode.insertBefore(e,s.nextElementSibling)}}this.focusEdge(l),this.plugins.table.setPositionControllerDiv.call(this,l,!0)},mergeCells:function(){const e=this.plugins.table,t=this.context.table,n=this.util,i=e._ref,l=e._selectedCells,o=l[0];let s=null,a=null,r=i.ce-i.cs+1,c=i.re-i.rs+1,d="",u=null;for(let e,t,i=1,o=l.length;i<o;i++){e=l[i],u!==e.parentNode&&(u=e.parentNode),t=e.children;for(let e=0,i=t.length;e<i;e++)n.isFormatElement(t[e])&&n.onlyZeroWidthSpace(t[e].textContent)&&n.removeItem(t[e]);d+=e.innerHTML,n.removeItem(e),0===u.cells.length&&(s?a=u:s=u,c-=1)}if(s){const e=t._trElements,i=n.getArrayIndex(e,s),l=n.getArrayIndex(e,a||s),o=[];for(let t,s=0;s<=l;s++)if(t=e[s].cells,0!==t.length)for(let e,o,a=0,r=t.length;a<r;a++)e=t[a],o=e.rowSpan-1,o>0&&s+o>=i&&(e.rowSpan-=n.getOverlapRangeAtIndex(i,l,s,s+o));else o.push(e[s]);for(let e=0,t=o.length;e<t;e++)n.removeItem(o[e])}o.innerHTML+=d,o.colSpan=r,o.rowSpan=c,this.controllersOff(),e.setActiveButton.call(this,!0,!1),e.call_controller_tableEdit.call(this,o),n.addClass(o,"se-table-selected-cell"),this.focusEdge(o)},toggleHeader:function(){const e=this.util,t=this.context.table.headerButton,n=e.hasClass(t,"active"),i=this.context.table._element;if(n)e.removeItem(i.querySelector("thead"));else{const t=e.createElement("THEAD");t.innerHTML="<tr>"+this.plugins.table.createCells.call(this,"th",this.context.table._logical_cellCnt,!1)+"</tr>",i.insertBefore(t,i.firstElementChild)}e.toggleClass(t,"active"),/TH/i.test(this.context.table._tdElement.nodeName)?this.controllersOff():this.plugins.table.setPositionControllerDiv.call(this,this.context.table._tdElement,!1)},setTableStyle:function(e){const t=this.context.table,n=t._element;let i,l,o,s;e.indexOf("width")>-1&&(i=t.resizeButton.firstElementChild,l=t.resizeText,t._maxWidth?(o=t.icons.reduction,s=t.minText,t.columnFixedButton.style.display="block",this.util.removeClass(n,"se-table-size-auto"),this.util.addClass(n,"se-table-size-100")):(o=t.icons.expansion,s=t.maxText,t.columnFixedButton.style.display="none",this.util.removeClass(n,"se-table-size-100"),this.util.addClass(n,"se-table-size-auto")),this.util.changeElement(i,o),this.util.changeTxt(l,s)),e.indexOf("column")>-1&&(t._fixedColumn?(this.util.removeClass(n,"se-table-layout-auto"),this.util.addClass(n,"se-table-layout-fixed"),this.util.addClass(t.columnFixedButton,"active")):(this.util.removeClass(n,"se-table-layout-fixed"),this.util.addClass(n,"se-table-layout-auto"),this.util.removeClass(t.columnFixedButton,"active")))},setActiveButton:function(e,t){const n=this.context.table;/^TH$/i.test(e.nodeName)?(n.insertRowAboveButton.setAttribute("disabled",!0),n.insertRowBelowButton.setAttribute("disabled",!0)):(n.insertRowAboveButton.removeAttribute("disabled"),n.insertRowBelowButton.removeAttribute("disabled")),t&&e!==t?(n.splitButton.setAttribute("disabled",!0),n.mergeButton.removeAttribute("disabled")):(n.splitButton.removeAttribute("disabled"),n.mergeButton.setAttribute("disabled",!0))},_bindOnSelect:null,_bindOffSelect:null,_bindOffShift:null,_selectedCells:null,_shift:!1,_fixedCell:null,_fixedCellName:null,_selectedCell:null,_selectedTable:null,_ref:null,_toggleEditor:function(e){this.context.element.wysiwyg.setAttribute("contenteditable",e),e?this.util.removeClass(this.context.element.wysiwyg,"se-disabled"):this.util.addClass(this.context.element.wysiwyg,"se-disabled")},_offCellMultiSelect:function(e){e.stopPropagation();const t=this.plugins.table;t._shift?t._initBind&&(this._wd.removeEventListener("touchmove",t._initBind),t._initBind=null):(t._removeEvents.call(this),t._toggleEditor.call(this,!0)),t._fixedCell&&t._selectedTable&&(t.setActiveButton.call(this,t._fixedCell,t._selectedCell),t.call_controller_tableEdit.call(this,t._selectedCell||t._fixedCell),t._selectedCells=t._selectedTable.querySelectorAll(".se-table-selected-cell"),t._selectedCell&&t._fixedCell&&this.focusEdge(t._selectedCell),t._shift||(t._fixedCell=null,t._selectedCell=null,t._fixedCellName=null))},_onCellMultiSelect:function(e){this._antiBlur=!0;const t=this.plugins.table,n=this.util.getParentElement(e.target,this.util.isCell);if(t._shift)n===t._fixedCell?t._toggleEditor.call(this,!0):t._toggleEditor.call(this,!1);else if(!t._ref){if(n===t._fixedCell)return;t._toggleEditor.call(this,!1)}n&&n!==t._selectedCell&&t._fixedCellName===n.nodeName&&t._selectedTable===this.util.getParentElement(n,"TABLE")&&(t._selectedCell=n,t._setMultiCells.call(this,t._fixedCell,n))},_setMultiCells:function(e,t){const n=this.plugins.table,i=n._selectedTable.rows,l=this.util,o=n._selectedTable.querySelectorAll(".se-table-selected-cell");for(let e=0,t=o.length;e<t;e++)l.removeClass(o[e],"se-table-selected-cell");if(e===t&&(l.addClass(e,"se-table-selected-cell"),!n._shift))return;let s=!0,a=[],r=[];const c=n._ref={_i:0,cs:null,ce:null,rs:null,re:null};for(let n,o,d=0,u=i.length;d<u;d++){n=i[d].cells,o=0;for(let i,u,h,g,p=0,m=n.length;p<m;p++){if(i=n[p],h=i.colSpan-1,g=i.rowSpan-1,u=p+o,a.length>0)for(let e,t=0;t<a.length;t++)e=a[t],e.row>d||(u>=e.index?(o+=e.cs,u+=e.cs,e.rs-=1,e.row=d+1,e.rs<1&&(a.splice(t,1),t--)):p===m-1&&(e.rs-=1,e.row=d+1,e.rs<1&&(a.splice(t,1),t--)));if(s){if(i!==e&&i!==t||(c.cs=null!==c.cs&&c.cs<u?c.cs:u,c.ce=null!==c.ce&&c.ce>u+h?c.ce:u+h,c.rs=null!==c.rs&&c.rs<d?c.rs:d,c.re=null!==c.re&&c.re>d+g?c.re:d+g,c._i+=1),2===c._i){s=!1,a=[],r=[],d=-1;break}}else if(l.getOverlapRangeAtIndex(c.cs,c.ce,u,u+h)&&l.getOverlapRangeAtIndex(c.rs,c.re,d,d+g)){const e=c.cs<u?c.cs:u,t=c.ce>u+h?c.ce:u+h,n=c.rs<d?c.rs:d,o=c.re>d+g?c.re:d+g;if(c.cs!==e||c.ce!==t||c.rs!==n||c.re!==o){c.cs=e,c.ce=t,c.rs=n,c.re=o,d=-1,a=[],r=[];break}l.addClass(i,"se-table-selected-cell")}g>0&&r.push({index:u,cs:h+1,rs:g,row:-1}),o+=i.colSpan-1}a=a.concat(r).sort((function(e,t){return e.index-t.index})),r=[]}},_removeEvents:function(){const e=this.plugins.table;e._initBind&&(this._wd.removeEventListener("touchmove",e._initBind),e._initBind=null),e._bindOnSelect&&(this._wd.removeEventListener("mousedown",e._bindOnSelect),this._wd.removeEventListener("mousemove",e._bindOnSelect),e._bindOnSelect=null),e._bindOffSelect&&(this._wd.removeEventListener("mouseup",e._bindOffSelect),e._bindOffSelect=null),e._bindOffShift&&(this._wd.removeEventListener("keyup",e._bindOffShift),e._bindOffShift=null)},_initBind:null,onTableCellMultiSelect:function(e,t){const n=this.plugins.table;n._removeEvents.call(this),this.controllersOff(),n._shift=t,n._fixedCell=e,n._fixedCellName=e.nodeName,n._selectedTable=this.util.getParentElement(e,"TABLE");const i=n._selectedTable.querySelectorAll(".se-table-selected-cell");for(let e=0,t=i.length;e<t;e++)this.util.removeClass(i[e],"se-table-selected-cell");this.util.addClass(e,"se-table-selected-cell"),n._bindOnSelect=n._onCellMultiSelect.bind(this),n._bindOffSelect=n._offCellMultiSelect.bind(this),t?(n._bindOffShift=function(){this.controllersOn(this.context.table.resizeDiv,this.context.table.tableController,this.plugins.table.init.bind(this),e,"table"),n._ref||this.controllersOff()}.bind(this),this._wd.addEventListener("keyup",n._bindOffShift,!1),this._wd.addEventListener("mousedown",n._bindOnSelect,!1)):this._wd.addEventListener("mousemove",n._bindOnSelect,!1),this._wd.addEventListener("mouseup",n._bindOffSelect,!1),n._initBind=n.init.bind(this),this._wd.addEventListener("touchmove",n._initBind,!1)},onClick_tableController:function(e){e.stopPropagation();const t=e.target.getAttribute("data-command")?e.target:e.target.parentNode;if(t.getAttribute("disabled"))return;const n=t.getAttribute("data-command"),i=t.getAttribute("data-value"),l=t.getAttribute("data-option"),o=this.plugins.table;if("function"==typeof o._closeSplitMenu&&(o._closeSplitMenu(),"onsplit"===n))return;if(!n)return;e.preventDefault();const s=this.context.table;switch(n){case"insert":case"delete":o.editTable.call(this,i,l);break;case"header":o.toggleHeader.call(this);break;case"onsplit":o.openSplitMenu.call(this);break;case"split":o.splitCells.call(this,i);break;case"merge":o.mergeCells.call(this);break;case"resize":s._maxWidth=!s._maxWidth,o.setTableStyle.call(this,"width"),o.setPositionControllerTop.call(this,s._element),o.setPositionControllerDiv.call(this,s._tdElement,o._shift);break;case"layout":s._fixedColumn=!s._fixedColumn,o.setTableStyle.call(this,"column"),o.setPositionControllerTop.call(this,s._element),o.setPositionControllerDiv.call(this,s._tdElement,o._shift);break;case"remove":const e=s._element.parentNode;this.util.removeItem(s._element),this.controllersOff(),e!==this.context.element.wysiwyg&&this.util.removeItemAllParents(e,(function(e){return 0===e.childNodes.length}),null),this.focus()}this.history.push(!1)}},formatBlock:{name:"formatBlock",display:"submenu",add:function(e,t){const n=e.context;n.formatBlock={targetText:t.querySelector(".txt"),targetTooltip:t.parentNode.querySelector(".se-tooltip-text"),_formatList:null,currentFormat:""};let i=this.setSubmenu.call(e);i.querySelector("ul").addEventListener("click",this.pickUp.bind(e)),n.formatBlock._formatList=i.querySelectorAll("li button"),e.initMenuTarget(this.name,t,i),i=null},setSubmenu:function(){const e=this.context.option,t=this.lang.toolbar,n=this.util.createElement("DIV");n.className="se-submenu se-list-layer se-list-format";const i=["p","div","blockquote","pre","h1","h2","h3","h4","h5","h6"],l=e.formats&&0!==e.formats.length?e.formats:i;let o='<div class="se-list-inner"><ul class="se-list-basic">';for(let e,n,s,a,r,c,d,u=0,h=l.length;u<h;u++)e=l[u],"string"==typeof e&&i.indexOf(e)>-1?(n=e.toLowerCase(),s="blockquote"===n?"range":"pre"===n?"free":"replace",r=/^h/.test(n)?n.match(/\d+/)[0]:"",a=t["tag_"+(r?"h":n)]+r,d="",c=""):(n=e.tag.toLowerCase(),s=e.command,a=e.name||n,d=e.class,c=d?' class="'+d+'"':""),o+='<li><button type="button" class="se-btn-list" data-command="'+s+'" data-value="'+n+'" data-class="'+d+'" title="'+a+'"><'+n+c+">"+a+"</"+n+"></button></li>";return o+="</ul></div>",n.innerHTML=o,n},active:function(e){let t=this.lang.toolbar.formats;const n=this.context.formatBlock.targetText,i=this.context.formatBlock.targetTooltip;if(e){if(this.util.isFormatElement(e)){const l=this.context.formatBlock._formatList,o=e.nodeName.toLowerCase(),s=(e.className.match(/(\s|^)__se__format__[^\s]+/)||[""])[0].trim();for(let e,n=0,i=l.length;n<i;n++)if(e=l[n],o===e.getAttribute("data-value")&&s===e.getAttribute("data-class")){t=e.title;break}return this.util.changeTxt(n,t),this.util.changeTxt(i,t),n.setAttribute("data-value",o),n.setAttribute("data-class",s),!0}}else this.util.changeTxt(n,t),this.util.changeTxt(i,t);return!1},on:function(){const e=this.context.formatBlock,t=e._formatList,n=e.targetText,i=(n.getAttribute("data-value")||"")+(n.getAttribute("data-class")||"");if(i!==e.currentFormat){for(let e,n=0,l=t.length;n<l;n++)e=t[n],i===e.getAttribute("data-value")+e.getAttribute("data-class")?this.util.addClass(e,"active"):this.util.removeClass(e,"active");e.currentFormat=i}},pickUp:function(e){e.preventDefault(),e.stopPropagation();let t=e.target,n=null,i=null,l=null,o="";for(;!n&&!/UL/i.test(t.tagName);){if(n=t.getAttribute("data-command"),i=t.getAttribute("data-value"),o=t.getAttribute("data-class"),n){l=t.firstChild;break}t=t.parentNode}if(n){if("range"===n){const e=l.cloneNode(!1);this.applyRangeFormatElement(e)}else{let e=this.getRange(),t=this.getSelectedElementsAndComponents(!1);if(0===t.length&&(e=this.getRange_addLine(e,null),t=this.getSelectedElementsAndComponents(!1),0===t.length))return;const s=e.startOffset,a=e.endOffset,r=this.util;let c=t[0],d=t[t.length-1];const u=r.getNodePath(e.startContainer,c,null,null),h=r.getNodePath(e.endContainer,d,null,null),g=this.detachList(t,!1);g.sc&&(c=g.sc),g.ec&&(d=g.ec),this.setRange(r.getNodeFromPath(u,c),s,r.getNodeFromPath(h,d),a);const p=this.getSelectedElementsAndComponents(!1);if("free"===n){const e=p.length-1;let t=p[e].parentNode,n=l.cloneNode(!1);const i=n;for(let i,o,s,a,c,d,u=e,h=!0;u>=0;u--)if(i=p[u],i!==(p[u+1]?p[u+1].parentNode:null)){if(d=r.isComponent(i),o=d?"":i.innerHTML.replace(/(?!>)\s+(?=<)|\n/g," "),s=r.getParentElement(i,(function(e){return e.parentNode===t})),(t!==i.parentNode||d)&&(r.isFormatElement(t)?(t.parentNode.insertBefore(n,t.nextSibling),t=t.parentNode):(t.insertBefore(n,s?s.nextSibling:null),t=i.parentNode),a=n.nextSibling,a&&n.nodeName===a.nodeName&&r.isSameAttributes(n,a)&&(n.innerHTML+="<BR>"+a.innerHTML,r.removeItem(a)),n=l.cloneNode(!1),h=!0),c=n.innerHTML,n.innerHTML=(h||!o||!c||/<br>$/i.test(o)?o:o+"<BR>")+c,0===u){t.insertBefore(n,i),a=i.nextSibling,a&&n.nodeName===a.nodeName&&r.isSameAttributes(n,a)&&(n.innerHTML+="<BR>"+a.innerHTML,r.removeItem(a));const e=n.previousSibling;e&&n.nodeName===e.nodeName&&r.isSameAttributes(n,e)&&(e.innerHTML+="<BR>"+n.innerHTML,r.removeItem(n))}d||r.removeItem(i),o&&(h=!1)}this.setRange(i,0,i,0)}else{for(let e,t,n=0,s=p.length;n<s;n++)e=p[n],e.nodeName.toLowerCase()===i.toLowerCase()&&(e.className.match(/(\s|^)__se__format__[^\s]+/)||[""])[0].trim()===o||r.isComponent(e)||(t=l.cloneNode(!1),r.copyFormatAttributes(t,e),t.innerHTML=e.innerHTML,e.parentNode.replaceChild(t,e)),0===n&&(c=t||e),n===s-1&&(d=t||e),t=null;this.setRange(r.getNodeFromPath(u,c),s,r.getNodeFromPath(h,d),a)}this.history.push(!1)}this.submenuOff()}}},lineHeight:{name:"lineHeight",display:"submenu",add:function(e,t){const n=e.context;n.lineHeight={_sizeList:null,currentSize:-1};let i=this.setSubmenu.call(e),l=i.querySelector("ul");l.addEventListener("click",this.pickup.bind(e)),n.lineHeight._sizeList=l.querySelectorAll("li button"),e.initMenuTarget(this.name,t,i),i=null,l=null},setSubmenu:function(){const e=this.context.option,t=this.lang,n=this.util.createElement("DIV");n.className="se-submenu se-list-layer";const i=e.lineHeights?e.lineHeights:[{text:"1",value:1},{text:"1.15",value:1.15},{text:"1.5",value:1.5},{text:"2",value:2}];let l='<div class="se-list-inner"><ul class="se-list-basic"><li><button type="button" class="default_value se-btn-list" title="'+t.toolbar.default+'">('+t.toolbar.default+")</button></li>";for(let e,t=0,n=i.length;t<n;t++)e=i[t],l+='<li><button type="button" class="se-btn-list" data-value="'+e.value+'" title="'+e.text+'">'+e.text+"</button></li>";return l+="</ul></div>",n.innerHTML=l,n},on:function(){const e=this.context.lineHeight,t=e._sizeList,n=this.util.getFormatElement(this.getSelectionNode()),i=n?n.style.lineHeight+"":"";if(i!==e.currentSize){for(let e=0,n=t.length;e<n;e++)i===t[e].getAttribute("data-value")?this.util.addClass(t[e],"active"):this.util.removeClass(t[e],"active");e.currentSize=i}},pickup:function(e){if(!/^BUTTON$/i.test(e.target.tagName))return!1;e.preventDefault(),e.stopPropagation();const t=e.target.getAttribute("data-value")||"",n=this.getSelectedElements();for(let e=0,i=n.length;e<i;e++)n[e].style.lineHeight=t;this.submenuOff(),this.history.push(!1)}},template:s,paragraphStyle:{name:"paragraphStyle",display:"submenu",add:function(e,t){const n=e.context;n.paragraphStyle={_classList:null};let i=this.setSubmenu.call(e);i.querySelector("ul").addEventListener("click",this.pickUp.bind(e)),n.paragraphStyle._classList=i.querySelectorAll("li button"),e.initMenuTarget(this.name,t,i),i=null},setSubmenu:function(){const e=this.context.option,t=this.util.createElement("DIV");t.className="se-submenu se-list-layer se-list-format";const n=this.lang.menu,i={spaced:{name:n.spaced,class:"__se__p-spaced",_class:""},bordered:{name:n.bordered,class:"__se__p-bordered",_class:""},neon:{name:n.neon,class:"__se__p-neon",_class:""}},l=e.paragraphStyles&&0!==e.paragraphStyles.length?e.paragraphStyles:["spaced","bordered","neon"];let o='<div class="se-list-inner"><ul class="se-list-basic">';for(let e,t,n,s,a=0,r=l.length;a<r;a++){if(e=l[a],"string"==typeof e){const t=i[e.toLowerCase()];if(!t)continue;e=t}t=e.name,n=e.class?' class="'+e.class+'"':"",s=e._class,o+='<li><button type="button" class="se-btn-list'+(s?" "+s:"")+'" data-value="'+e.class+'" title="'+t+'"><div'+n+">"+t+"</div></button></li>"}return o+="</ul></div>",t.innerHTML=o,t},on:function(){const e=this.context.paragraphStyle._classList,t=this.util.getFormatElement(this.getSelectionNode());for(let n=0,i=e.length;n<i;n++)this.util.hasClass(t,e[n].getAttribute("data-value"))?this.util.addClass(e[n],"active"):this.util.removeClass(e[n],"active")},pickUp:function(e){e.preventDefault(),e.stopPropagation();let t=e.target,n=null;for(;!/^UL$/i.test(t.tagName)&&(n=t.getAttribute("data-value"),!n);)t=t.parentNode;if(!n)return;let i=this.getSelectedElements();if(0===i.length&&(this.getRange_addLine(this.getRange(),null),i=this.getSelectedElements(),0===i.length))return;const l=this.util.hasClass(t,"active")?this.util.removeClass.bind(this.util):this.util.addClass.bind(this.util);for(let e=0,t=i.length;e<t;e++)l(i[e],n);this.submenuOff(),this.history.push(!1)}},textStyle:{name:"textStyle",display:"submenu",add:function(e,t){const n=e.context;n.textStyle={_styleList:null};let i=this.setSubmenu.call(e),l=i.querySelector("ul");l.addEventListener("click",this.pickup.bind(e)),n.textStyle._styleList=i.querySelectorAll("li button"),e.initMenuTarget(this.name,t,i),i=null,l=null},setSubmenu:function(){const e=this.context.option,t=this.util.createElement("DIV");t.className="se-submenu se-list-layer se-list-format";const n={code:{name:this.lang.menu.code,class:"__se__t-code",tag:"code"},translucent:{name:this.lang.menu.translucent,style:"opacity: 0.5;",tag:"span"},shadow:{name:this.lang.menu.shadow,class:"__se__t-shadow",tag:"span"}},i=e.textStyles?e.textStyles:this._w.Object.keys(n);let l='<div class="se-list-inner"><ul class="se-list-basic">';for(let e,t,o,s,a,r,c,d=0,u=i.length;d<u;d++){if(e=i[d],s="",r="",a=[],"string"==typeof e){const t=n[e.toLowerCase()];if(!t)continue;e=t}o=e.name,t=e.tag||"span",c=e._class,e.style&&(s+=' style="'+e.style+'"',r+=e.style.replace(/:[^;]+(;|$)\s*/g,","),a.push("style")),e.class&&(s+=' class="'+e.class+'"',r+="."+e.class.trim().replace(/\s+/g,",."),a.push("class")),r=r.replace(/,$/,""),l+='<li><button type="button" class="se-btn-list'+(c?" "+c:"")+'" data-command="'+t+'" data-value="'+r+'" title="'+o+'"><'+t+s+">"+o+"</"+t+"></button></li>"}return l+="</ul></div>",t.innerHTML=l,t},on:function(){const e=this.util,t=this.context.textStyle._styleList,n=this.getSelectionNode();for(let i,l,o,s=0,a=t.length;s<a;s++){i=t[s],l=i.getAttribute("data-value").split(",");for(let t,s,a=0;a<l.length;a++){for(t=n,o=!1;t&&!e.isFormatElement(t)&&!e.isComponent(t);){if(t.nodeName.toLowerCase()===i.getAttribute("data-command").toLowerCase()&&(s=l[a],/^\./.test(s)?e.hasClass(t,s.replace(/^\./,"")):t.style[s])){o=!0;break}t=t.parentNode}if(!o)break}o?e.addClass(i,"active"):e.removeClass(i,"active")}},pickup:function(e){e.preventDefault(),e.stopPropagation();let t=e.target,n=null,i=null;for(;!n&&!/UL/i.test(t.tagName);){if(n=t.getAttribute("data-command"),n){i=t.firstChild;break}t=t.parentNode}if(!n)return;const l=i.style.cssText.replace(/:.+(;|$)/g,",").split(",");l.pop();const o=i.classList;for(let e=0,t=o.length;e<t;e++)l.push("."+o[e]);const s=this.util.hasClass(t,"active")?null:i.cloneNode(!1),a=s?null:[i.nodeName];this.nodeChange(s,l,a,!0),this.submenuOff()}},link:c,image:f,video:_,audio:b,math:v,imageGallery:{name:"imageGallery",add:function(e){e.addModule([C.a]);const t=e.context;t.imageGallery={title:e.lang.toolbar.imageGallery,url:t.options.imageGalleryUrl,listClass:"se-image-list",itemTemplateHandler:this.drawItems,selectorHandler:this.setImage.bind(e),columnSize:4}},open:function(e){this.plugins.fileBrowser.open.call(this,"imageGallery",e)},drawItems:function(e){const t=e.src.split("/").pop();return'<div class="se-file-item-img"><img src="'+e.src+'" alt="'+(e.alt||t)+'" data-command="pick"><div class="se-file-img-name se-file-name-back"></div><div class="se-file-img-name __se__img_name">'+(e.name||t)+"</div></div>"},setImage:function(e){this.callPlugin("image",function(){const t={name:e.parentNode.querySelector(".__se__img_name").textContent,size:0};this.context.image._altText=e.alt,this.plugins.image.create_image.call(this,e.src,"",!1,this.context.image._origin_w,this.context.image._origin_h,"none",t)}.bind(this),null)}}},x={rtl:{italic:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10.5 15.8" xml:space="preserve"><g><path d="M0.3,0.1c0.3,0,0.5,0,0.7,0c1,0.1,1.7,0.1,2.2,0.1H4L7.2,0l0.2,1.1H7c-0.5,0-1,0.1-1.5,0.3v0.4l0.3,1.9L6,4.4L6.3,6 l0.1,0.4l0.1,0.5c0.1,0.2,0.1,0.4,0.2,0.7s0.1,0.6,0.2,0.9L7,9.1l0.6,2.8l0.3,1.4c0.1,0.4,0.2,0.7,0.4,1c0.4,0.2,0.8,0.3,1.2,0.4 l0.8,0.2l0.2,0.9l-1.1,0c-0.9-0.1-1.5-0.1-1.8-0.1h-2c-0.9,0.1-1.4,0.2-1.5,0.2c-0.1,0-0.2,0-0.3,0H3.4c-0.1,0-0.2,0-0.2,0 l-0.1-0.4c0-0.2-0.1-0.4-0.1-0.6l0.7-0.1c0.4,0,0.8-0.1,1.2-0.2c0-0.1,0-0.2,0-0.3l-0.1-0.5l-0.4-2.4L4,9.6L3.4,6.4 C3.2,5.7,3,4.7,2.7,3.3c0-0.3-0.1-0.5-0.1-0.8C2.5,2.1,2.4,1.9,2.3,1.6C2,1.4,1.6,1.3,1.3,1.2C0.9,1.2,0.5,1.1,0.2,0.9L0,0.4L0,0 L0.3,0.1L0.3,0.1z"/></g></svg>',indent:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 12.4" xml:space="preserve"><g><g><path d="M15.5,10.1L15.5,10.1c0.1,0,0.3,0.1,0.3,0.3v1.7c0,0.1,0,0.1-0.1,0.2c-0.1,0.1-0.1,0.1-0.2,0.1l-15.2,0 c-0.1,0-0.1,0-0.2-0.1C0,12.2,0,12.2,0,12.1l0-1.7c0-0.1,0-0.1,0.1-0.2c0.1-0.1,0.1-0.1,0.2-0.1C0.3,10.1,15.5,10.1,15.5,10.1z M9.8,6.7c0.1,0,0.1,0,0.2,0.1C10.1,6.9,10.1,7,10.1,7v1.7c0,0.1,0,0.2-0.1,0.2C10,9,9.9,9,9.8,9L0.3,9C0.2,9,0.1,9,0.1,8.9 C0,8.9,0,8.8,0,8.7V7C0,7,0,6.9,0.1,6.8c0.1-0.1,0.1-0.1,0.2-0.1C0.3,6.7,9.8,6.7,9.8,6.7z M0.3,3.4h9.6h0c0.1,0,0.3,0.1,0.3,0.3 v1.7v0c0,0.1-0.1,0.3-0.3,0.3H0.3c-0.1,0-0.1,0-0.2-0.1C0,5.5,0,5.4,0,5.3V3.6c0-0.1,0-0.1,0.1-0.2C0.1,3.4,0.2,3.4,0.3,3.4 L0.3,3.4z M0.3,0l15.2,0c0.1,0,0.1,0,0.2,0.1c0.1,0.1,0.1,0.1,0.1,0.2V2c0,0.1,0,0.2-0.1,0.2c-0.1,0.1-0.1,0.1-0.2,0.1H0.3 c-0.1,0-0.1,0-0.2-0.1C0,2.1,0,2,0,2l0-1.7c0-0.1,0-0.1,0.1-0.2C0.1,0,0.2,0,0.3,0z"/></g><path d="M13.1,3.5L15.7,6c0.1,0.1,0.1,0.3,0,0.4l-2.5,2.5C13.1,9,13,9,12.9,9c-0.1,0-0.1,0-0.2-0.1c-0.1-0.1-0.1-0.1-0.1-0.2V3.7 c0-0.1,0-0.2,0.1-0.2c0.1-0.1,0.1-0.1,0.2-0.1C13,3.4,13.1,3.4,13.1,3.5z"/></g></svg>',outdent:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 12.4" xml:space="preserve"><g><g><path d="M15.5,10.1L15.5,10.1c0.1,0,0.3,0.1,0.3,0.3v1.7c0,0.1,0,0.1-0.1,0.2c-0.1,0.1-0.1,0.1-0.2,0.1l-15.2,0 c-0.1,0-0.1,0-0.2-0.1C0,12.2,0,12.2,0,12.1l0-1.7c0-0.1,0-0.1,0.1-0.2c0.1-0.1,0.1-0.1,0.2-0.1C0.3,10.1,15.5,10.1,15.5,10.1z M9.8,6.7c0.1,0,0.1,0,0.2,0.1C10.1,6.9,10.1,7,10.1,7v1.7c0,0.1,0,0.2-0.1,0.2C10,9,9.9,9,9.8,9L0.3,9C0.2,9,0.1,9,0.1,8.9 C0,8.9,0,8.8,0,8.7V7C0,7,0,6.9,0.1,6.8c0.1-0.1,0.1-0.1,0.2-0.1C0.3,6.7,9.8,6.7,9.8,6.7z M0.3,3.4h9.6h0c0.1,0,0.3,0.1,0.3,0.3 v1.7v0c0,0.1-0.1,0.3-0.3,0.3H0.3c-0.1,0-0.1,0-0.2-0.1C0,5.5,0,5.4,0,5.3V3.6c0-0.1,0-0.1,0.1-0.2C0.1,3.4,0.2,3.4,0.3,3.4 L0.3,3.4z M0.3,0l15.2,0c0.1,0,0.1,0,0.2,0.1c0.1,0.1,0.1,0.1,0.1,0.2V2c0,0.1,0,0.2-0.1,0.2c-0.1,0.1-0.1,0.1-0.2,0.1H0.3 c-0.1,0-0.1,0-0.2-0.1C0,2.1,0,2,0,2l0-1.7c0-0.1,0-0.1,0.1-0.2C0.1,0,0.2,0,0.3,0z"/></g><path d="M15.5,3.4c0.1,0,0.1,0,0.2,0.1c0.1,0.1,0.1,0.1,0.1,0.2v5.1c0,0.1,0,0.1-0.1,0.2C15.6,9,15.5,9,15.5,9 c-0.1,0-0.1,0-0.2-0.1l-2.5-2.5c-0.1-0.1-0.1-0.3,0-0.4l2.5-2.5C15.3,3.4,15.4,3.4,15.5,3.4z"/></g></svg>',list_bullets:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 12.4" xml:space="preserve"><g><path d="M12.4,10.7c0,0.9,0.8,1.7,1.7,1.7c0.9,0,1.7-0.8,1.7-1.7C15.7,9.8,15,9,14.1,9c-0.4,0-0.9,0.2-1.2,0.5 C12.5,9.8,12.4,10.2,12.4,10.7C12.4,10.7,12.4,10.7,12.4,10.7z M12.4,6.2c0,0.9,0.8,1.7,1.7,1.7c0.4,0,0.9-0.2,1.2-0.5 c0.3-0.3,0.4-0.7,0.4-1.1c0-0.9-0.7-1.7-1.6-1.7C13.1,4.6,12.4,5.3,12.4,6.2C12.4,6.2,12.4,6.2,12.4,6.2z M0,9.8v1.7 c0,0.1,0,0.1,0.1,0.2c0.1,0.1,0.1,0.1,0.2,0.1l10.7,0c0,0,0,0,0,0c0.1,0,0.3-0.1,0.3-0.3V9.8c0-0.1,0-0.1-0.1-0.2 C11.1,9.6,11,9.6,11,9.6l-10.7,0c-0.1,0-0.1,0-0.2,0.1C0,9.7,0,9.8,0,9.8L0,9.8z M12.9,2.9c0.3,0.3,0.7,0.5,1.2,0.5 c0.4,0,0.9-0.2,1.2-0.5c0.7-0.7,0.7-1.7,0-2.4C14.9,0.2,14.5,0,14.1,0c-0.4,0-0.9,0.2-1.2,0.5c-0.3,0.3-0.5,0.7-0.5,1.2 C12.4,2.1,12.5,2.6,12.9,2.9z M0,5.3V7c0,0.1,0,0.1,0.1,0.2c0.1,0.1,0.1,0.1,0.2,0.1H11c0.1,0,0.1,0,0.2-0.1 c0.1-0.1,0.1-0.1,0.1-0.2V5.3c0,0,0,0,0,0c0-0.1-0.1-0.3-0.3-0.3H0.3c-0.1,0-0.1,0-0.2,0.1C0,5.2,0,5.3,0,5.3L0,5.3z M0,0.8v1.7 c0,0.1,0,0.1,0.1,0.2c0.1,0.1,0.1,0.1,0.2,0.1h10.7c0.1,0,0.1,0,0.2-0.1c0,0,0.1-0.1,0.1-0.2V0.8c0-0.1,0-0.1-0.1-0.2 c0-0.1-0.1-0.1-0.2-0.1H0.3c-0.1,0-0.1,0-0.2,0.1C0,0.7,0,0.8,0,0.8L0,0.8z"/></g></svg>',list_number:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 15.7" xml:space="preserve"><g><path d="M0,11.5l0,1.7c0,0.1,0,0.1,0.1,0.2c0.1,0.1,0.1,0.1,0.2,0.1H11c0.1,0,0.2,0,0.2-0.1c0.1-0.1,0.1-0.1,0.1-0.2v-1.7 c0-0.1,0-0.1-0.1-0.2c-0.1-0.1-0.1-0.1-0.2-0.1H0.3c-0.1,0-0.2,0-0.2,0.1C0,11.4,0,11.4,0,11.5L0,11.5z M0,8.7c0,0.1,0,0.1,0.1,0.2 C0.1,8.9,0.2,9,0.3,9H11c0.1,0,0.2,0,0.2-0.1c0.1-0.1,0.1-0.1,0.1-0.2V7c0-0.1,0-0.1-0.1-0.2c-0.1-0.1-0.1-0.1-0.2-0.1l-10.7,0 c-0.1,0-0.2,0-0.2,0.1C0,6.8,0,6.9,0,7C0,7,0,8.7,0,8.7z M0,2.5v1.7c0,0.1,0,0.1,0.1,0.2c0,0,0.1,0.1,0.2,0.1l10.7,0 c0.1,0,0.2,0,0.2-0.1c0.1-0.1,0.1-0.1,0.1-0.2V2.4c0-0.1,0-0.1-0.1-0.2c-0.1,0-0.1,0-0.2,0H0.3c-0.1,0-0.1,0-0.2,0 C0,2.3,0,2.4,0,2.5L0,2.5z"/></g><path d="M15.6,14.2c0-0.3-0.1-0.6-0.3-0.8c-0.2-0.2-0.4-0.4-0.7-0.4l0.9-1v-0.8h-2.9v1.3h0.9v-0.5h0.9l0,0c-0.1,0.1-0.2,0.2-0.3,0.3 s-0.2,0.3-0.4,0.5l-0.3,0.3l0.2,0.5c0.6,0,0.9,0.1,0.9,0.5c0,0.1-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.1-0.4,0.1c-0.3,0-0.7-0.1-0.9-0.3 l-0.5,0.8c0.4,0.4,0.9,0.6,1.5,0.6c0.4,0,0.9-0.1,1.2-0.4C15.5,15.1,15.6,14.7,15.6,14.2z"/><path d="M15.6,8.7h-0.9v0.5h-1.1c0-0.2,0.2-0.4,0.4-0.5c0.2-0.2,0.4-0.3,0.7-0.4c0.3-0.2,0.5-0.3,0.7-0.6c0.2-0.2,0.3-0.5,0.3-0.8 c0-0.4-0.2-0.8-0.5-1c-0.6-0.4-1.4-0.5-2-0.1c-0.3,0.2-0.5,0.4-0.6,0.7L13.3,7c0.1-0.3,0.4-0.5,0.7-0.5c0.1,0,0.3,0,0.3,0.1 c0.1,0.1,0.1,0.2,0.1,0.3c0,0.2-0.1,0.3-0.2,0.4c-0.2,0.1-0.3,0.3-0.5,0.4c-0.2,0.1-0.4,0.3-0.6,0.4c-0.2,0.2-0.4,0.4-0.5,0.6 c-0.1,0.2-0.2,0.5-0.2,0.8c0,0.2,0,0.3,0,0.5h3.2L15.6,8.7L15.6,8.7z"/><path d="M15.6,3.6h-1V0h-0.9l-1.2,1.1l0.6,0.7c0.2-0.1,0.3-0.3,0.4-0.5l0,0v2.2h-0.9v0.9h3L15.6,3.6L15.6,3.6z"/></svg>',link:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 15.7" xml:space="preserve"><g><path d="M7.4,9.9l3.1,3.1c0.3,0.3,0.8,0.5,1.3,0.5c0.5,0,0.9-0.2,1.3-0.5c0,0,0,0,0,0c0.7-0.7,0.7-1.9,0-2.6L9.9,7.3 c0-0.1,0-0.2,0-0.3C9.9,7,10,7,10.1,7l2.2-0.2c0.1,0,0.1,0,0.2,0.1l2.1,2.1c0.4,0.4,0.7,0.8,0.9,1.3c0.2,0.5,0.3,1,0.3,1.5 c0,0.5-0.1,1-0.3,1.5c-0.8,2-3.2,3-5.2,2.2c-0.5-0.2-0.9-0.5-1.3-0.9l-2.1-2.1c-0.1,0-0.1-0.1-0.1-0.2L7,10.1C7,10,7,9.9,7.1,9.9 C7.2,9.8,7.3,9.9,7.4,9.9z M1.2,1.1C1.6,0.7,2,0.4,2.5,0.3c1-0.4,2.1-0.4,3.1,0C6,0.4,6.5,0.7,6.8,1.1L9,3.2C9,3.3,9.1,3.3,9,3.4 L8.8,5.6c0,0.1-0.1,0.2-0.2,0.2c-0.1,0.1-0.2,0.1-0.3,0L5.3,2.7C5,2.3,4.5,2.1,4,2.1c-0.5,0-0.9,0.2-1.3,0.5c0,0,0,0,0,0 C2,3.4,2,4.5,2.7,5.2l3.1,3.2c0.1,0.1,0.1,0.2,0,0.3c0,0.1-0.1,0.1-0.2,0.1L3.5,9C3.4,9,3.4,9,3.3,8.9L1.2,6.8c0,0,0,0,0,0 C-0.4,5.2-0.4,2.7,1.2,1.1L1.2,1.1z M14.3,6h-2.6c0,0,0,0,0,0c-0.1,0-0.2-0.1-0.2-0.2c0-0.1,0-0.2,0.1-0.3l2.5-0.7 c0.1,0,0.1,0,0.2,0c0.1,0,0.1,0.1,0.1,0.2l0.1,0.8c0,0.1,0,0.1-0.1,0.2C14.5,6,14.4,6,14.3,6L14.3,6z M10.2,4.1 c0,0.1-0.1,0.2-0.2,0.2l0,0c0,0,0,0,0,0C9.8,4.2,9.7,4.1,9.8,4L9.7,1.4c0-0.1,0-0.1,0.1-0.2c0.1,0,0.1,0,0.2,0h0.8 c0.1,0,0.1,0,0.2,0.1c0,0.1,0,0.1,0,0.2L10.2,4.1L10.2,4.1z M1.5,9.7h1.3h1.3c0.1,0,0.2,0.1,0.2,0.2c0,0.1,0,0.2-0.1,0.3l-2.5,0.6 H1.6c0,0-0.1,0-0.1,0c-0.1,0-0.1-0.1-0.1-0.2L1.2,9.9c0-0.1,0-0.1,0.1-0.2c0-0.1,0.1-0.1,0.2-0.1L1.5,9.7z M5.6,11.6 C5.6,11.6,5.6,11.6,5.6,11.6c0-0.1,0.1-0.2,0.3-0.1c0,0,0,0,0,0c0.1,0,0.2,0.1,0.2,0.2v2.6c0,0.1,0,0.1-0.1,0.2 c0,0-0.1,0.1-0.2,0.1L5,14.5c-0.1,0-0.1,0-0.2-0.1c0-0.1,0-0.1,0-0.2L5.6,11.6L5.6,11.6z"/></g></svg>',unlink:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 15.7" xml:space="preserve"><g><path d="M14.6,14.6c1.6-1.6,1.6-4.1,0-5.7l0,0l-3.1-3.1l-1.2,1.6l2.9,2.9c0.4,0.4,0.6,0.9,0.6,1.5c0,1.1-0.9,2.1-2.1,2.1l0,0 c-0.6,0-1.1-0.2-1.5-0.6l-0.4-0.4l-1.7,1l0.8,0.8C10.4,16.2,13,16.2,14.6,14.6L14.6,14.6L14.6,14.6z M3.6,6C3,5.9,2.6,5.5,2.3,5 S1.9,4,2.1,3.4C2.3,2.9,2.6,2.5,3,2.2C3.5,2,4.1,1.9,4.6,2l3.3,1.4l0.5-2L5.1,0.1C4-0.1,2.9,0,2,0.5C1.1,1.1,0.4,1.9,0.2,3 C-0.1,4,0,5.1,0.6,6C1.1,6.9,1.9,7.6,3,7.8l5.4,2l0.5-2L6.2,6.9L3.6,6z"/></g></svg>'},redo:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.59 14.18"><g><path d="M11.58,18.48a6.84,6.84,0,1,1,6.85-6.85s0,.26,0,.67a8,8,0,0,1-.22,1.44l.91-.55a.51.51,0,0,1,.36,0,.45.45,0,0,1,.29.22.47.47,0,0,1,.06.36.45.45,0,0,1-.22.29L17.42,15.3l-.12,0h-.25l-.12-.06-.09-.09-.06-.07,0-.06-.87-2.12a.43.43,0,0,1,0-.37.49.49,0,0,1,.27-.26.41.41,0,0,1,.36,0,.53.53,0,0,1,.27.26l.44,1.09a6.51,6.51,0,0,0,.24-1.36,4.58,4.58,0,0,0,0-.64,5.83,5.83,0,0,0-1.73-4.17,5.88,5.88,0,0,0-8.34,0,5.9,5.9,0,0,0,4.17,10.06.51.51,0,0,1,.33.15.48.48,0,0,1,0,.68.53.53,0,0,1-.33.12Z" transform="translate(-4.48 -4.54)"/></g></svg>',undo:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.59 14.18"><g><path d="M5,14a.43.43,0,0,1-.22-.29.46.46,0,0,1,.06-.36.43.43,0,0,1,.29-.22.56.56,0,0,1,.36,0l.91.55a8.27,8.27,0,0,1-.22-1.45,5.07,5.07,0,0,1,0-.67A6.85,6.85,0,1,1,13,18.47a.44.44,0,0,1-.33-.13.48.48,0,0,1,0-.68.51.51,0,0,1,.33-.15A5.89,5.89,0,0,0,17.15,7.45a5.88,5.88,0,0,0-8.33,0,5.84,5.84,0,0,0-1.73,4.17s0,.25,0,.65a6.49,6.49,0,0,0,.24,1.37l.44-1.09a.57.57,0,0,1,.27-.26.41.41,0,0,1,.36,0,.53.53,0,0,1,.27.26.43.43,0,0,1,0,.37L7.82,15l0,.09-.09.09-.1.07-.06,0H7.28l-.13,0-1.09-.63c-.65-.36-1-.57-1.1-.63Z" transform="translate(-4.49 -4.53)"/></g></svg>',bold:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11.76 15.75"><g><path d="M6.4,3.76V19.5h6.76a5.55,5.55,0,0,0,2-.32,4.93,4.93,0,0,0,1.52-1,4.27,4.27,0,0,0,1.48-3.34,3.87,3.87,0,0,0-.69-2.37,5.74,5.74,0,0,0-.71-.83,3.44,3.44,0,0,0-1.1-.65,3.6,3.6,0,0,0,1.58-1.36,3.66,3.66,0,0,0,.53-1.93,3.7,3.7,0,0,0-1.21-2.87,4.65,4.65,0,0,0-3.25-1.1H6.4Zm2.46,6.65V5.57h3.52a4.91,4.91,0,0,1,1.36.15,2.3,2.3,0,0,1,.85.45,2.06,2.06,0,0,1,.74,1.71,2.3,2.3,0,0,1-.78,1.92,2.54,2.54,0,0,1-.86.46,4.7,4.7,0,0,1-1.32.15H8.86Zm0,7.27V12.15H12.7a4.56,4.56,0,0,1,1.38.17,3.43,3.43,0,0,1,.95.49,2.29,2.29,0,0,1,.92,2,2.73,2.73,0,0,1-.83,2.1,2.66,2.66,0,0,1-.83.58,3.25,3.25,0,0,1-1.26.2H8.86Z" transform="translate(-6.4 -3.75)"/></g></svg>',underline:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 9.78 15.74"><g><path d="M14.64,3.76h2.52v7.72a4.51,4.51,0,0,1-.59,2.31,3.76,3.76,0,0,1-1.71,1.53,6.12,6.12,0,0,1-2.64.53,5,5,0,0,1-3.57-1.18,4.17,4.17,0,0,1-1.27-3.24V3.76H9.9v7.3a3,3,0,0,0,.55,2,2.3,2.3,0,0,0,1.83.65,2.26,2.26,0,0,0,1.8-.65,3.09,3.09,0,0,0,.55-2V3.76Zm2.52,13.31V19.5H7.39V17.08h9.77Z" transform="translate(-7.38 -3.76)"/></g></svg>',italic:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10.49 15.76"><g><path d="M17.16,3.79l.37,0-.06.38-.14.52A10,10,0,0,1,16.21,5a9.37,9.37,0,0,0-1,.32,6.68,6.68,0,0,0-.25.89c-.06.31-.11.59-.14.85-.3,1.36-.52,2.41-.68,3.14l-.61,3.18L13.1,15l-.43,2.4-.12.46a.62.62,0,0,0,0,.28c.44.1.85.17,1.23.22l.68.11a4.51,4.51,0,0,1-.08.6l-.09.42a.92.92,0,0,0-.23,0l-.43,0a1.37,1.37,0,0,1-.29,0c-.13,0-.63-.08-1.49-.16l-2,0c-.28,0-.87,0-1.78.12L7,19.5l.17-.88.8-.2A6.61,6.61,0,0,0,9.19,18,2.62,2.62,0,0,0,9.61,17l.28-1.41.58-2.75.12-.66c.05-.3.11-.58.17-.86s.12-.51.17-.69l.12-.48.12-.43.31-1.6.15-.65.31-1.91V5.14a3.86,3.86,0,0,0-1.48-.29l-.38,0,.2-1.06,3.24.14.75,0c.45,0,1.18,0,2.18-.09.23,0,.46,0,.71,0Z" transform="translate(-7.04 -3.76)"/></g></svg>',strike:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 14.9"><g><path d="M12.94,13a4.27,4.27,0,0,1,1.32.58,1.46,1.46,0,0,1,.55,1.2,1.87,1.87,0,0,1-.88,1.64,4.17,4.17,0,0,1-2.35.59,4.44,4.44,0,0,1-2.74-.71,2.72,2.72,0,0,1-1-2.17H5.57a4.56,4.56,0,0,0,1.55,3.7,7,7,0,0,0,4.47,1.23,6,6,0,0,0,4.07-1.3,4.24,4.24,0,0,0,1.52-3.37,4,4,0,0,0-.26-1.4h-4ZM6.37,10.24A3.27,3.27,0,0,1,6,8.68a4,4,0,0,1,1.48-3.3,5.92,5.92,0,0,1,3.88-1.21,5.58,5.58,0,0,1,3.91,1.24,4.36,4.36,0,0,1,1.45,3.17H14.44a2.12,2.12,0,0,0-.91-1.81,4.45,4.45,0,0,0-2.44-.55,3.69,3.69,0,0,0-2,.51A1.64,1.64,0,0,0,8.3,8.22a1.3,1.3,0,0,0,.48,1.11,7,7,0,0,0,2.1.78l.28.06.28.08H6.37Zm13.09.68a.73.73,0,0,1,.49.21.66.66,0,0,1,.2.48.64.64,0,0,1-.2.48.71.71,0,0,1-.49.19H5.1a.67.67,0,0,1-.49-.19.66.66,0,0,1-.2-.48.64.64,0,0,1,.2-.48.73.73,0,0,1,.49-.21H19.46Z" transform="translate(-4.41 -4.17)"/></g></svg>',subscript:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.75 14.61"><g><path d="M15.38,4.33H12.74L11.19,7c-.28.46-.51.87-.69,1.21L10.07,9h0l-.44-.8c-.22-.4-.45-.81-.71-1.23L7.34,4.33H4.68L8.26,10,4.4,16.08H7.1l1.69-2.83c.38-.63.72-1.22,1-1.78l.25-.46h0l.49.92c.24.45.48.89.74,1.32L13,16.08h2.61L11.84,10l1.77-2.84,1.77-2.85Zm4.77,13.75H17v-.15c0-.4.05-.64.16-.72a4.42,4.42,0,0,1,1.16-.31,3.3,3.3,0,0,0,1.54-.56A1.84,1.84,0,0,0,20.15,15a1.78,1.78,0,0,0-.44-1.41A2.8,2.8,0,0,0,18,13.25a2.71,2.71,0,0,0-1.69.37,1.83,1.83,0,0,0-.44,1.43v.23H17v-.23q0-.63.18-.78a1.62,1.62,0,0,1,.88-.15,1.59,1.59,0,0,1,.88.15q.18.15.18.75t-.18.75a3.58,3.58,0,0,1-1.18.33,3.33,3.33,0,0,0-1.52.51,1.57,1.57,0,0,0-.32,1.18v1.15h4.27v-.86Z" transform="translate(-4.4 -4.33)"/></g></svg>',superscript:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.75 15.42"><g><path d="M12,13.14l3.61-5.81H12.94L11.33,10c-.28.46-.51.88-.69,1.25l-.45.83h0l-.45-.85c-.22-.41-.45-.82-.71-1.24L7.4,7.33H4.68l3.66,5.81L4.4,19.33H7.14l1.74-2.87q.58-1,1-1.83l.25-.48h0l.51.94.75,1.37,1.72,2.87h2.67l-1.92-3.09c-1.12-1.8-1.76-2.83-1.92-3.1Zm4.84-4.41h0l0,.15h3.27v.86H15.77V8.58a1.66,1.66,0,0,1,.33-1.22,3.51,3.51,0,0,1,1.56-.51,3.68,3.68,0,0,0,1.21-.34c.13-.1.19-.36.19-.77S19,5.07,18.87,5A1.63,1.63,0,0,0,18,4.8a1.58,1.58,0,0,0-.91.17c-.13.11-.19.38-.19.8V6H15.78V5.76a1.87,1.87,0,0,1,.45-1.47A2.84,2.84,0,0,1,18,3.91a2.8,2.8,0,0,1,1.72.38,1.84,1.84,0,0,1,.45,1.44,1.91,1.91,0,0,1-.34,1.35,3.24,3.24,0,0,1-1.58.57A3.69,3.69,0,0,0,17,8c-.12.1-.17.35-.17.76Z" transform="translate(-4.4 -3.91)"/></g></svg>',erase:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 13.76"><g><path d="M13.69,17.2h6.46v1.31H8.56L4.41,14.37,14,4.75l6.06,6.06L16.89,14l-3.2,3.19Zm-4.61,0h2.77L14.09,15,9.88,10.75,6.25,14.38l1.41,1.41c.84.82,1.31,1.29,1.42,1.41Z" transform="translate(-4.41 -4.75)"/></g></svg>',indent:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 12.36"><g><path d="M19.87,15.57a.27.27,0,0,1,.19.08.25.25,0,0,1,.08.19v1.69a.27.27,0,0,1-.08.19.25.25,0,0,1-.19.08H4.68a.27.27,0,0,1-.19-.08.25.25,0,0,1-.08-.19V15.84a.27.27,0,0,1,.27-.27H19.87ZM7.5,14.45a.25.25,0,0,1-.2-.09L4.76,11.84a.29.29,0,0,1,0-.4L7.3,8.9a.29.29,0,0,1,.4,0,.31.31,0,0,1,.07.2v5.06a.32.32,0,0,1-.08.21.26.26,0,0,1-.19.08ZM19.87,8.82a.27.27,0,0,1,.19.08.25.25,0,0,1,.08.19v1.69a.27.27,0,0,1-.08.19.25.25,0,0,1-.19.08H10.31a.27.27,0,0,1-.27-.27V9.1a.27.27,0,0,1,.27-.27h9.56Zm0,3.37a.27.27,0,0,1,.19.08.28.28,0,0,1,.08.21v1.68a.32.32,0,0,1-.08.21.25.25,0,0,1-.19.08H10.31a.27.27,0,0,1-.19-.08.3.3,0,0,1-.08-.21V12.48a.32.32,0,0,1,.08-.21.24.24,0,0,1,.19-.08h9.56Zm.2-6.66a.28.28,0,0,1,.08.2V7.41a.32.32,0,0,1-.08.21.25.25,0,0,1-.19.08H4.68a.27.27,0,0,1-.19-.08.3.3,0,0,1-.08-.21V5.73a.32.32,0,0,1,.08-.21.25.25,0,0,1,.19-.08H19.87a.28.28,0,0,1,.2.09Z" transform="translate(-4.41 -5.44)"/></g></svg>',outdent:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 12.36"><g><path d="M4.68,14.45a.27.27,0,0,1-.19-.08.3.3,0,0,1-.08-.21V9.1a.27.27,0,0,1,.08-.19.28.28,0,0,1,.2-.08.25.25,0,0,1,.19.07l2.54,2.54a.29.29,0,0,1,0,.4L4.88,14.36a.24.24,0,0,1-.2.09Zm15.19,1.12a.27.27,0,0,1,.19.08.25.25,0,0,1,.08.19v1.69a.27.27,0,0,1-.08.19.25.25,0,0,1-.19.08H4.68a.27.27,0,0,1-.19-.08.25.25,0,0,1-.08-.19V15.84a.27.27,0,0,1,.27-.27H19.87Zm0-3.38a.27.27,0,0,1,.19.08.28.28,0,0,1,.08.21v1.68a.32.32,0,0,1-.08.21.25.25,0,0,1-.19.08H10.31a.27.27,0,0,1-.19-.08.3.3,0,0,1-.08-.21V12.48a.32.32,0,0,1,.08-.21.24.24,0,0,1,.19-.08h9.56Zm0-3.37a.27.27,0,0,1,.19.08.25.25,0,0,1,.08.19v1.69a.27.27,0,0,1-.08.19.25.25,0,0,1-.19.08H10.31a.27.27,0,0,1-.27-.27V9.1a.27.27,0,0,1,.27-.27h9.56Zm.2-3.29a.28.28,0,0,1,.08.2V7.41a.32.32,0,0,1-.08.21.25.25,0,0,1-.19.08H4.68a.27.27,0,0,1-.19-.08.3.3,0,0,1-.08-.21V5.73a.32.32,0,0,1,.08-.21.25.25,0,0,1,.19-.08H19.87a.28.28,0,0,1,.2.09Z" transform="translate(-4.41 -5.44)"/></g></svg>',expansion:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.74"><g><path d="M11.8,13.06l-5.1,5.1H9.51V19.5H4.41V14.4H5.75v2.81L8.3,14.66q2.25-2.23,2.55-2.55Zm8.35-9.3v5.1H18.81V6.05l-5.1,5.1-1-1,5.1-5.1H15.05V3.76Z" transform="translate(-4.41 -3.76)"/></g></svg>',reduction:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.74"><g><path d="M14.91,10h2.87v1.38H12.55V6.12h1.38V9l5.24-5.24.48.49.49.48ZM6.77,11.92H12v5.23H10.62V14.26L5.37,19.5l-1-1L9.63,13.3H6.77Z" transform="translate(-4.4 -3.76)"/></g></svg>',code_view:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.73 11.8"><g><path d="M8.09,7.94a.76.76,0,0,1,.53.22.72.72,0,0,1,.21.52.76.76,0,0,1-.22.54L6.18,11.63l2.43,2.44a.69.69,0,0,1,.2.51.66.66,0,0,1-.21.51.75.75,0,0,1-.51.22.63.63,0,0,1-.51-.21h0L4.63,12.15a.7.7,0,0,1-.22-.53.67.67,0,0,1,.25-.55L7.57,8.16a.82.82,0,0,1,.52-.22Zm12.05,3.69a.7.7,0,0,1-.23.52L17,15.1h0a.66.66,0,0,1-.51.21.73.73,0,0,1-.51-.22.75.75,0,0,1-.22-.51.63.63,0,0,1,.21-.51l2.43-2.44L15.92,9.22a.73.73,0,0,1-.22-.53A.74.74,0,0,1,17,8.18h0l2.91,2.91a.67.67,0,0,1,.27.54Zm-5.9-5.9a.73.73,0,0,1,.61.32.71.71,0,0,1,.07.68L11,17a1,1,0,0,1-.22.32.6.6,0,0,1-.35.16.75.75,0,0,1-.69-.26.69.69,0,0,1-.12-.72L13.56,6.23a.75.75,0,0,1,.26-.35.74.74,0,0,1,.42-.15Z" transform="translate(-4.41 -5.73)"/></g></svg>',preview:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.65 15.66"><g><path d="M16.19,14.43l2.49,2.49a.73.73,0,0,1,.21.52.67.67,0,0,1-.22.51.7.7,0,0,1-.52.22.69.69,0,0,1-.51-.21l-2.49-2.48a5.17,5.17,0,0,1-1.34.69,4.64,4.64,0,0,1-1.48.24,4.78,4.78,0,1,1,0-9.56,4.79,4.79,0,0,1,1.84.36,4.9,4.9,0,0,1,1.56,1,4.77,4.77,0,0,1,.46,6.18ZM10,14a3.3,3.3,0,0,0,2.34.93A3.37,3.37,0,0,0,14.7,14a3.3,3.3,0,0,0-1.08-5.41,3.47,3.47,0,0,0-2.56,0A3,3,0,0,0,10,9.28,3.31,3.31,0,0,0,10,14ZM16,4a3.86,3.86,0,0,1,2.77,1.14A3.9,3.9,0,0,1,20,7.85v4a.77.77,0,0,1-.22.53.7.7,0,0,1-.52.21.72.72,0,0,1-.74-.74v-4a2.46,2.46,0,0,0-.72-1.73A2.37,2.37,0,0,0,16,5.45H8.53A2.42,2.42,0,0,0,6.08,7.89v7.52a2.41,2.41,0,0,0,.71,1.73,2.46,2.46,0,0,0,1.74.72h4.08a.73.73,0,0,1,0,1.46H8.53a3.85,3.85,0,0,1-2.78-1.14A3.93,3.93,0,0,1,4.6,15.4V7.87A3.94,3.94,0,0,1,5.76,5.09,3.88,3.88,0,0,1,8.54,4H16Z" transform="translate(-4.45 -3.8)"/></g></svg>',print:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16.05 16.04"><g><path d="M19.76,15.84a1.29,1.29,0,0,0,.39-.92V8.35A2.05,2.05,0,0,0,19.57,7a1.93,1.93,0,0,0-1.38-.57H6.37a1.95,1.95,0,0,0-2,2v6.56a1.23,1.23,0,0,0,.38.92,1.35,1.35,0,0,0,.93.38h2V14.9l-2,0V8.35a.67.67,0,0,1,.18-.47.62.62,0,0,1,.48-.19H18.18a.6.6,0,0,1,.46.19.66.66,0,0,1,.18.47V14.9h-2v1.32h2A1.35,1.35,0,0,0,19.76,15.84ZM17.52,7.69V5.06a1.31,1.31,0,0,0-.38-.92,1.34,1.34,0,0,0-.94-.38H8.34A1.3,1.3,0,0,0,7,5.06V7.69H8.34V5.06h7.87V7.69h1.31ZM8.34,12.93h7.87l0,5.26H8.34V12.93Zm7.87,5.26v0Zm.65,1.31a.6.6,0,0,0,.46-.19.72.72,0,0,0,.2-.47V12.29a.74.74,0,0,0-.2-.47.6.6,0,0,0-.46-.19H7.68a.6.6,0,0,0-.46.19.72.72,0,0,0-.2.47v6.55a.74.74,0,0,0,.2.47.6.6,0,0,0,.46.19h9.18ZM16.67,9.28a.7.7,0,0,0-.94,0,.63.63,0,0,0-.18.46.67.67,0,0,0,.18.47.68.68,0,0,0,.94,0,.66.66,0,0,0,.18-.47A.58.58,0,0,0,16.67,9.28Z" transform="translate(-4.25 -3.61)"/></g></svg>',template:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14.27 15.64"><g><path d="M18.18,19.16a1,1,0,0,0,1-1V5.73a1,1,0,0,0-1-1h-2v1h2V18.19H6.37V5.73h2v-1h-2A.94.94,0,0,0,5.68,5a1,1,0,0,0-.29.7V18.18a.94.94,0,0,0,.29.69,1,1,0,0,0,.69.29H18.18ZM9.82,10.31h4.92a.49.49,0,0,0,.35-.15.47.47,0,0,0,.15-.35.49.49,0,0,0-.15-.35.47.47,0,0,0-.35-.15H9.82a.49.49,0,0,0-.35.15.47.47,0,0,0-.15.35.49.49,0,0,0,.15.35.47.47,0,0,0,.35.15Zm5.9,4.92H8.83a.49.49,0,0,0-.35.15.47.47,0,0,0-.15.35.49.49,0,0,0,.15.35.47.47,0,0,0,.35.15h6.89a.49.49,0,0,0,.35-.15.47.47,0,0,0,.15-.35.51.51,0,0,0-.5-.5ZM7.36,12.77a.49.49,0,0,0,.15.35.47.47,0,0,0,.35.15h8.85a.49.49,0,0,0,.35-.15.47.47,0,0,0,.15-.35.49.49,0,0,0-.15-.35.47.47,0,0,0-.35-.15H7.85a.49.49,0,0,0-.35.15.52.52,0,0,0-.14.35Z" transform="translate(-5.14 -3.77)"/><path d="M14.24,6.71a1,1,0,0,0,1-1,1,1,0,0,0-1-1,1,1,0,0,0-1-1h-2a.94.94,0,0,0-.69.28,1,1,0,0,0-.29.7A.94.94,0,0,0,9.62,5a.91.91,0,0,0-.29.69,1,1,0,0,0,.29.7,1,1,0,0,0,.69.29h3.93Z" transform="translate(-5.14 -3.77)"/></g></svg>',line_height:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.76 13.56"><g><path d="M4.4,4.88V8.26a2,2,0,0,0,.5.39s.1,0,.18-.12a.62.62,0,0,0,.17-.28c.06-.19.13-.44.21-.74s.14-.52.19-.66a.58.58,0,0,1,.21-.3,2.41,2.41,0,0,1,.63-.21,3.83,3.83,0,0,1,.88-.12,9.15,9.15,0,0,1,1.31.06.16.16,0,0,1,.11,0,.26.26,0,0,1,.06.14,4,4,0,0,1,0,.49v2l.05,3.77c0,1.41,0,2.68-.05,3.81a1.79,1.79,0,0,1-.11.49,10.68,10.68,0,0,1-1.4.45,1.12,1.12,0,0,0-.69.43v.31l0,.22.61,0c.85-.08,1.54-.12,2.06-.12a19.76,19.76,0,0,1,2.09.08,15.08,15.08,0,0,0,1.64.08,1.4,1.4,0,0,0,.29,0,1.58,1.58,0,0,0,0-.26l-.05-.43a2.26,2.26,0,0,0-.43-.17l-.77-.22-.15,0a2.55,2.55,0,0,1-.78-.28,2.56,2.56,0,0,1-.11-.75l0-1.29,0-3.15V7.53a10.51,10.51,0,0,1,.06-1.2,3.83,3.83,0,0,1,.6,0l1.88,0a2.18,2.18,0,0,1,.38,0,.45.45,0,0,1,.23.17.9.9,0,0,1,.05.25c0,.16.06.35.1.58a3.33,3.33,0,0,0,.14.55A6.39,6.39,0,0,0,15,9a2.91,2.91,0,0,0,.6-.15,2.77,2.77,0,0,0,0-.46l0-.51,0-2.95-.25,0-.38,0L15,4.94a.71.71,0,0,1-.18.15.45.45,0,0,1-.25.07l-.29,0H8.75l-.15,0H7.45a17,17,0,0,1-1.86,0L5.36,5l-.25-.13ZM19.75,16.14h-.69v-9h.69A.4.4,0,0,0,20.13,7c.06-.11,0-.24-.1-.39L18.92,5.15a.52.52,0,0,0-.86,0L17,6.58c-.12.15-.16.28-.1.39s.18.16.38.16h.69v9h-.69a.4.4,0,0,0-.38.16c-.06.11,0,.24.1.39l1.11,1.43a.52.52,0,0,0,.86,0L20,16.69c.12-.15.16-.28.1-.39a.4.4,0,0,0-.38-.16Z" transform="translate(-4.4 -4.86)"/></g></svg>',paragraph_style:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11.81 15.74"><g><path d="M18.18,3.76v2h-2V19.5h-2V5.73h-2V19.5h-2V11.63a3.94,3.94,0,0,1,0-7.87h7.87Z" transform="translate(-6.37 -3.76)"/></g></svg>',text_style:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13.76 15.74"><g><path d="M17.68,6.71a2.22,2.22,0,0,0,1.06-.22.74.74,0,0,0,.42-.7.73.73,0,0,0-.08-.33.67.67,0,0,0-.17-.22,1,1,0,0,0-.31-.15L18.26,5l-.45-.09A15.27,15.27,0,0,0,13.26,5V4.74c0-.66-.63-1-1.92-1-.24,0-.43.15-.59.46a4,4,0,0,0-.36,1.14h0v0a26.45,26.45,0,0,1-3.5.35A2,2,0,0,0,5.77,6a.84.84,0,0,0-.37.79,2.14,2.14,0,0,0,.41,1.29,1.23,1.23,0,0,0,1.05.63,16.62,16.62,0,0,0,3.29-.45l-.34,3.35c-.16,1.61-.29,2.9-.37,3.86s-.12,1.66-.12,2.09l0,.65a5.15,5.15,0,0,0,.05.6,1.28,1.28,0,0,0,.16.54.34.34,0,0,0,.28.18,1.16,1.16,0,0,0,.79-.46,3.66,3.66,0,0,0,.68-1,22.08,22.08,0,0,0,1-4.33q.49-3.1.78-6.15a24.69,24.69,0,0,1,4.62-.84Z" transform="translate(-5.4 -3.76)"/></g></svg>',save:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.74"><g><path d="M18.53,19.5l.2-.05A1.78,1.78,0,0,0,20.13,18l0-.09V7.14a2,2,0,0,0-.28-.64A3.18,3.18,0,0,0,19.43,6c-.5-.52-1-1-1.55-1.54A2.59,2.59,0,0,0,17.37,4a1.83,1.83,0,0,0-.61-.25H6l-.21,0a1.78,1.78,0,0,0-1.4,1.49l0,.1V17.87a2.49,2.49,0,0,0,.09.37,1.79,1.79,0,0,0,1.44,1.23l.09,0Zm-6.25-.6H6.92a.61.61,0,0,1-.68-.48.78.78,0,0,1,0-.22V12.3a.62.62,0,0,1,.69-.68H17.64a.62.62,0,0,1,.69.69V18.2a.64.64,0,0,1-.71.69H12.28ZM12,9.81H8.15a.63.63,0,0,1-.72-.71v-4a.64.64,0,0,1,.72-.72h7.66a.64.64,0,0,1,.72.72v4a.65.65,0,0,1-.74.72ZM13.5,5V9.18h1.78V5Z" transform="translate(-4.41 -3.76)"/></g></svg>',blockquote:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 475.082 475.081"><g><path d="M164.45,219.27h-63.954c-7.614,0-14.087-2.664-19.417-7.994c-5.327-5.33-7.994-11.801-7.994-19.417v-9.132c0-20.177,7.139-37.401,21.416-51.678c14.276-14.272,31.503-21.411,51.678-21.411h18.271c4.948,0,9.229-1.809,12.847-5.424c3.616-3.617,5.424-7.898,5.424-12.847V54.819c0-4.948-1.809-9.233-5.424-12.85c-3.617-3.612-7.898-5.424-12.847-5.424h-18.271c-19.797,0-38.684,3.858-56.673,11.563c-17.987,7.71-33.545,18.132-46.68,31.267c-13.134,13.129-23.553,28.688-31.262,46.677C3.855,144.039,0,162.931,0,182.726v200.991c0,15.235,5.327,28.171,15.986,38.834c10.66,10.657,23.606,15.985,38.832,15.985h109.639c15.225,0,28.167-5.328,38.828-15.985c10.657-10.663,15.987-23.599,15.987-38.834V274.088c0-15.232-5.33-28.168-15.994-38.832C192.622,224.6,179.675,219.27,164.45,219.27z"/><path d="M459.103,235.256c-10.656-10.656-23.599-15.986-38.828-15.986h-63.953c-7.61,0-14.089-2.664-19.41-7.994c-5.332-5.33-7.994-11.801-7.994-19.417v-9.132c0-20.177,7.139-37.401,21.409-51.678c14.271-14.272,31.497-21.411,51.682-21.411h18.267c4.949,0,9.233-1.809,12.848-5.424c3.613-3.617,5.428-7.898,5.428-12.847V54.819c0-4.948-1.814-9.233-5.428-12.85c-3.614-3.612-7.898-5.424-12.848-5.424h-18.267c-19.808,0-38.691,3.858-56.685,11.563c-17.984,7.71-33.537,18.132-46.672,31.267c-13.135,13.129-23.559,28.688-31.265,46.677c-7.707,17.987-11.567,36.879-11.567,56.674v200.991c0,15.235,5.332,28.171,15.988,38.834c10.657,10.657,23.6,15.985,38.828,15.985h109.633c15.229,0,28.171-5.328,38.827-15.985c10.664-10.663,15.985-23.599,15.985-38.834V274.088C475.082,258.855,469.76,245.92,459.103,235.256z"/></g></svg>',arrow_down:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.73 8.67"><g><path d="M18.79,7.52a.8.8,0,0,1,.56-.23.82.82,0,0,1,.79.79.8.8,0,0,1-.23.56l-7.07,7.07a.79.79,0,0,1-.57.25.77.77,0,0,1-.57-.25h0L4.64,8.65a.8.8,0,0,1-.23-.57.82.82,0,0,1,.79-.79.8.8,0,0,1,.56.23L12.28,14l3.26-3.26,3.25-3.26Z" transform="translate(-4.41 -7.29)"/></g></svg>',align_justify:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 13.77"><g><path d="M4.41,4.74v2H20.15v-2H4.41Zm0,5.9H20.15v-2H4.41v2Zm0,3.94H20.15v-2H4.41v2Zm0,3.93h7.87v-2H4.41v2Z" transform="translate(-4.41 -4.74)"/></g></svg>',align_left:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 13.77"><g><path d="M4.41,4.74v2H20.15v-2H4.41Zm11.8,3.94H4.41v2H16.22v-2Zm-11.8,5.9H18.18v-2H4.41v2Zm0,3.93h9.84v-2H4.41v2Z" transform="translate(-4.41 -4.74)"/></g></svg>',align_right:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 13.77"><g><path d="M4.41,4.74v2H20.15v-2H4.41Zm3.93,5.9H20.15v-2H8.34v2Zm-2,3.94H20.14v-2H6.37v2Zm3.94,3.93h9.84v-2H10.31v2Z" transform="translate(-4.41 -4.74)"/></g></svg>',align_center:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 13.77"><g><path d="M4.41,4.74v2H20.15v-2H4.41Zm2,3.94v2H18.18v-2H6.37Zm-1,5.9H19.16v-2H5.39v2Zm2,3.93H17.2v-2H7.36v2Z" transform="translate(-4.41 -4.74)"/></g></svg>',font_color:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 14.61"><g><path d="M18.5,15.57,14.28,4.32h-3.4L6.65,15.57h3l.8-2.26h4.23l.8,2.26h3ZM14,11.07H11.14L12.54,7,13.25,9c.41,1.18.64,1.86.7,2ZM4.41,16.69v2.24H20.15V16.69H4.41Z" transform="translate(-4.41 -4.32)"/></g></svg>',highlight_color:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.66 15.74"><g><path d="M12.32,9.31,13.38,13H11.21l.52-1.83q.46-1.61.54-1.83ZM4.44,3.76H20.1V19.5H4.44V3.76ZM14.71,17.32h2.63L13.7,6H10.89L7.26,17.32H9.89l.63-2.24h3.55l.32,1.12c.18.65.29,1,.32,1.12Z" transform="translate(-4.44 -3.76)"/></g></svg>',list_bullets:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 12.37"><g><path d="M7.77,16.12a1.59,1.59,0,0,0-.49-1.18,1.62,1.62,0,0,0-1.19-.49,1.68,1.68,0,1,0,0,3.36,1.67,1.67,0,0,0,1.68-1.69Zm0-4.48A1.67,1.67,0,0,0,6.09,10,1.68,1.68,0,0,0,4.9,12.82a1.62,1.62,0,0,0,1.19.49,1.67,1.67,0,0,0,1.68-1.67Zm12.38,3.64a.27.27,0,0,0-.08-.19.28.28,0,0,0-.2-.09H9.19a.28.28,0,0,0-.2.08.29.29,0,0,0-.08.19V17a.27.27,0,0,0,.28.28H19.87a.27.27,0,0,0,.19-.08.24.24,0,0,0,.08-.2V15.28ZM7.77,7.13a1.63,1.63,0,0,0-.49-1.2,1.61,1.61,0,0,0-1.19-.49,1.61,1.61,0,0,0-1.19.49,1.71,1.71,0,0,0,0,2.4,1.62,1.62,0,0,0,1.19.49,1.61,1.61,0,0,0,1.19-.49,1.63,1.63,0,0,0,.49-1.2Zm12.38,3.66a.28.28,0,0,0-.08-.2.29.29,0,0,0-.19-.08H9.19a.27.27,0,0,0-.28.28v1.69a.27.27,0,0,0,.08.19.24.24,0,0,0,.2.08H19.87a.27.27,0,0,0,.19-.08.25.25,0,0,0,.08-.19V10.79Zm0-4.5a.27.27,0,0,0-.08-.19A.25.25,0,0,0,19.88,6H9.19A.28.28,0,0,0,9,6.1a.26.26,0,0,0-.08.19V8A.27.27,0,0,0,9,8.17a.24.24,0,0,0,.2.08H19.87a.27.27,0,0,0,.19-.08A.25.25,0,0,0,20.14,8V6.29Z" transform="translate(-4.41 -5.44)"/></g></svg>',list_number:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.69 15.74"><g><path d="M7.66,18a1.24,1.24,0,0,0-.26-.78,1.17,1.17,0,0,0-.72-.42l.85-1V15H4.58v1.34h.94v-.46l.85,0h0c-.11.11-.22.23-.32.35s-.23.27-.37.47L5.39,17l.23.51c.61-.05.92.11.92.49a.42.42,0,0,1-.18.37.79.79,0,0,1-.45.12A1.41,1.41,0,0,1,5,18.15l-.51.77A2.06,2.06,0,0,0,6,19.5a1.8,1.8,0,0,0,1.2-.41A1.38,1.38,0,0,0,7.66,18Zm0-5.54H6.75V13H5.63A.72.72,0,0,1,6,12.51a5.45,5.45,0,0,1,.66-.45,2.71,2.71,0,0,0,.67-.57,1.19,1.19,0,0,0,.31-.81,1.29,1.29,0,0,0-.45-1,1.86,1.86,0,0,0-2-.11,1.51,1.51,0,0,0-.62.7l.74.52A.87.87,0,0,1,6,10.28a.51.51,0,0,1,.35.12.42.42,0,0,1,.13.33.55.55,0,0,1-.21.4,3,3,0,0,1-.5.38c-.19.13-.39.27-.58.42a2,2,0,0,0-.5.6,1.63,1.63,0,0,0-.21.81,3.89,3.89,0,0,0,.05.48h3.2V12.44Zm12.45,2.82a.27.27,0,0,0-.08-.19.28.28,0,0,0-.21-.08H9.1a.32.32,0,0,0-.21.08.24.24,0,0,0-.08.2V17a.27.27,0,0,0,.08.19.3.3,0,0,0,.21.08H19.83a.32.32,0,0,0,.21-.08.25.25,0,0,0,.08-.19V15.26ZM7.69,7.32h-1V3.76H5.8L4.6,4.88l.63.68a1.85,1.85,0,0,0,.43-.48h0l0,2.24H4.74V8.2h3V7.32Zm12.43,3.42a.27.27,0,0,0-.08-.19.28.28,0,0,0-.21-.08H9.1a.32.32,0,0,0-.21.08.24.24,0,0,0-.08.2v1.71a.27.27,0,0,0,.08.19.3.3,0,0,0,.21.08H19.83a.32.32,0,0,0,.21-.08.25.25,0,0,0,.08-.19V10.74Zm0-4.52A.27.27,0,0,0,20,6,.28.28,0,0,0,19.83,6H9.1A.32.32,0,0,0,8.89,6a.24.24,0,0,0-.08.19V7.93a.27.27,0,0,0,.08.19.32.32,0,0,0,.21.08H19.83A.32.32,0,0,0,20,8.12a.26.26,0,0,0,.08-.2V6.22Z" transform="translate(-4.43 -3.76)"/></g></svg>',table:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.74"><g><path d="M4.41,8.05V3.76H8.7V8.05H4.41Zm5.71,0V3.76h4.3V8.05h-4.3Zm5.74-4.29h4.29V8.05H15.86V3.76Zm-11.45,10V9.48H8.7v4.3H4.41Zm5.71,0V9.48h4.3v4.3h-4.3Zm5.74,0V9.48h4.29v4.3H15.86ZM4.41,19.5V15.21H8.7V19.5H4.41Zm5.71,0V15.21h4.3V19.5h-4.3Zm5.74,0V15.21h4.29V19.5H15.86Z" transform="translate(-4.41 -3.76)"/></g></svg>',horizontal_rule:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 2.24"><g><path d="M20.15,12.75V10.51H4.41v2.24H20.15Z" transform="translate(-4.41 -10.51)"/></g></svg>',show_blocks:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.66 15.67"><g><path d="M19.72,5.58a1.64,1.64,0,0,0-1.64-1.64H6.23a1.62,1.62,0,0,0-1.16.48,1.63,1.63,0,0,0-.48,1.16V9.63a1.6,1.6,0,0,0,.48,1.16,1.62,1.62,0,0,0,1.16.47H18.09a1.67,1.67,0,0,0,1.16-.47,1.62,1.62,0,0,0,.48-1.16V5.58Zm-.94,4.05a.68.68,0,0,1-.7.7H6.23a.66.66,0,0,1-.48-.2.74.74,0,0,1-.21-.5V5.58a.66.66,0,0,1,.2-.48.71.71,0,0,1,.48-.21H18.08a.74.74,0,0,1,.5.21.66.66,0,0,1,.2.48ZM6.48,7.72a.21.21,0,0,0,.17-.07.22.22,0,0,0,.07-.17V7.06a1.27,1.27,0,0,1,.11-.52.37.37,0,0,1,.36-.23H8.77A.25.25,0,0,0,9,6.17a.19.19,0,0,0,0-.23.27.27,0,0,0-.2-.12H7.19a.88.88,0,0,0-.72.39,1.51,1.51,0,0,0-.23.85v.42a.24.24,0,0,0,.24.24Zm-.19.81a.21.21,0,0,0,.17-.07.26.26,0,0,0,.07-.17.24.24,0,0,0-.24-.24.2.2,0,0,0-.16.09.2.2,0,0,0-.07.16.22.22,0,0,0,.07.17.23.23,0,0,0,.16.06Zm8.46,5.1a1.63,1.63,0,0,0-.47-1.16A1.61,1.61,0,0,0,13.12,12H6.23a1.6,1.6,0,0,0-1.16.46,1.62,1.62,0,0,0-.48,1.16v4.05a1.64,1.64,0,0,0,1.64,1.64h6.89a1.6,1.6,0,0,0,1.16-.48,1.62,1.62,0,0,0,.47-1.16Zm-.94,4a.7.7,0,0,1-.2.49.65.65,0,0,1-.5.2H6.23a.66.66,0,0,1-.48-.2.75.75,0,0,1-.21-.49v-4a.74.74,0,0,1,.21-.5.66.66,0,0,1,.48-.2h6.89a.68.68,0,0,1,.7.7v4Zm6.15,0v-4a1.6,1.6,0,0,0-.48-1.16A1.67,1.67,0,0,0,18.32,12H17.1a1.63,1.63,0,0,0-1.16.47,1.61,1.61,0,0,0-.47,1.16v4a1.67,1.67,0,0,0,.47,1.16,1.62,1.62,0,0,0,1.16.48h1.22A1.64,1.64,0,0,0,20,17.68Zm-.94-4v4a.75.75,0,0,1-.21.49.62.62,0,0,1-.48.2H17.11a.69.69,0,0,1-.5-.2.7.7,0,0,1-.2-.49v-4a.68.68,0,0,1,.7-.7h1.22a.66.66,0,0,1,.48.2.72.72,0,0,1,.21.5Z" transform="translate(-4.44 -3.79)"/></g></svg>',cancel:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.74"><g><path d="M14.15,11.63l5.61,5.61a1.29,1.29,0,0,1,.38.93,1.27,1.27,0,0,1-.4.93,1.25,1.25,0,0,1-.92.4,1.31,1.31,0,0,1-.94-.4l-5.61-5.61L6.67,19.1a1.31,1.31,0,0,1-.94.4,1.24,1.24,0,0,1-.92-.4,1.27,1.27,0,0,1-.4-.93,1.33,1.33,0,0,1,.38-.93l5.61-5.63L4.79,6a1.26,1.26,0,0,1-.38-.93,1.22,1.22,0,0,1,.4-.92,1.28,1.28,0,0,1,.92-.39,1.38,1.38,0,0,1,.94.38l5.61,5.61,5.61-5.61a1.33,1.33,0,0,1,.94-.38,1.26,1.26,0,0,1,.92.39,1.24,1.24,0,0,1,.4.92,1.29,1.29,0,0,1-.39.93L17,8.81l-2.8,2.82Z" transform="translate(-4.41 -3.76)"/></g></svg>',image:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.75 15.77"><g><path d="M8.77,8.72a.88.88,0,0,1-.61-.27.82.82,0,0,1-.25-.61.89.89,0,0,1,.25-.62A.82.82,0,0,1,8.77,7a.81.81,0,0,1,.61.25.83.83,0,0,1,.27.62.81.81,0,0,1-.25.61.91.91,0,0,1-.63.27Zm9.62-5a1.74,1.74,0,0,1,1.76,1.76V17.76a1.74,1.74,0,0,1-1.76,1.76H6.16A1.74,1.74,0,0,1,4.4,17.76V5.51A1.74,1.74,0,0,1,6.16,3.75H18.39Zm0,1.75H6.16v8L8.53,11.8a.94.94,0,0,1,.54-.17.86.86,0,0,1,.54.2L11.09,13l3.64-4.55a.78.78,0,0,1,.34-.25.85.85,0,0,1,.42-.07.89.89,0,0,1,.39.12.78.78,0,0,1,.28.29l2.24,3.67V5.51Zm0,12.24V15.6L15.3,10.53,11.89,14.8a.89.89,0,0,1-.59.32.82.82,0,0,1-.64-.18L9,13.62,6.16,15.74v2Z" transform="translate(-4.4 -3.75)"/></g></svg>',video:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 14.55"><g><path d="M20.15,10.26V18.9l-3.94-1.57v1.2H4.41V10.66H16.22v1.23l2-.81,2-.82ZM14.64,17h0V12.54h0v-.31H6V17h8.67Zm3.94-.37v-4l-2.37,1v2l1.18.48,1.19.48ZM7.94,9.86A2.77,2.77,0,0,1,5.19,7.11a2.76,2.76,0,0,1,5.51,0A2.78,2.78,0,0,1,7.94,9.86Zm0-3.93a1.21,1.21,0,0,0-.83.35,1.15,1.15,0,0,0-.34.84A1.09,1.09,0,0,0,7.11,8,1.15,1.15,0,0,0,8,8.28,1.13,1.13,0,0,0,9.11,7.12,1.16,1.16,0,0,0,7.94,5.93Zm5.9,3.93a2.34,2.34,0,0,1-1.67-.68,2.3,2.3,0,0,1-.68-1.67,2.35,2.35,0,0,1,4-1.67,2.37,2.37,0,0,1,0,3.34,2.33,2.33,0,0,1-1.68.68Zm0-3.14a.75.75,0,1,0,.55.22.73.73,0,0,0-.55-.22Z" transform="translate(-4.41 -4.35)"/></g></svg>',link:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.72"><g><path d="M13.05,13.63a.24.24,0,0,1,.15.22L13.42,16a.19.19,0,0,1-.08.18l-2.12,2.14a4.08,4.08,0,0,1-1.29.85A4,4,0,0,1,4.71,17a3.92,3.92,0,0,1-.3-1.52A4,4,0,0,1,4.71,14a3.91,3.91,0,0,1,.87-1.3L7.7,10.56a.25.25,0,0,1,.2-.06l2.17.22a.21.21,0,0,1,.19.15.24.24,0,0,1,0,.25L7.12,14.23a1.81,1.81,0,0,0,0,2.58,1.78,1.78,0,0,0,1.29.52,1.74,1.74,0,0,0,1.28-.52L12.8,13.7a.24.24,0,0,1,.25-.07ZM19,4.92a4,4,0,0,1,0,5.66L16.86,12.7a.25.25,0,0,1-.17.08l-2.2-.23a.21.21,0,0,1-.19-.15.22.22,0,0,1,0-.25L17.44,9a1.81,1.81,0,0,0,0-2.58,1.78,1.78,0,0,0-1.29-.52,1.74,1.74,0,0,0-1.28.52L11.76,9.57a.21.21,0,0,1-.25,0,.24.24,0,0,1-.16-.21l-.22-2.17a.19.19,0,0,1,.08-.18l2.12-2.14a4.08,4.08,0,0,1,1.29-.85,4.05,4.05,0,0,1,3.06,0,3.85,3.85,0,0,1,1.3.85ZM5.84,9.82a.25.25,0,0,1-.18-.08.19.19,0,0,1-.07-.19l.11-.77a.2.2,0,0,1,.11-.17.24.24,0,0,1,.2,0l2.5.72a.25.25,0,0,1,.15.27.22.22,0,0,1-.23.21l-2.59,0Zm4.12-2-.73-2.5a.27.27,0,0,1,0-.2A.21.21,0,0,1,9.41,5L10.19,5a.25.25,0,0,1,.19,0,.23.23,0,0,1,.08.18l-.05,2.61a.2.2,0,0,1-.19.23h0A.22.22,0,0,1,10,7.85Zm8.76,5.58a.25.25,0,0,1,.18.08.23.23,0,0,1,.06.2l-.11.77a.25.25,0,0,1-.11.17.21.21,0,0,1-.12,0l-.08,0L16,14a.25.25,0,0,1-.15-.27.22.22,0,0,1,.22-.21l1.29,0,1.33,0Zm-4.12,2,.74,2.51a.28.28,0,0,1,0,.2.23.23,0,0,1-.18.11l-.8.11a.23.23,0,0,1-.17-.07.25.25,0,0,1-.08-.18l0-2.61a.22.22,0,0,1,.22-.22.21.21,0,0,1,.26.15Z" transform="translate(-4.41 -3.77)"/></g></svg>',math:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11.81 15.73"><g><path d="M17.19,5.73a1,1,0,0,0,.71-.29,1,1,0,0,0,.28-.7,1,1,0,0,0-1-1H7.35a1,1,0,0,0-1,1,.77.77,0,0,0,.13.47h0l4.58,6.43L6.68,17.81a1.25,1.25,0,0,0-.29.71.94.94,0,0,0,.28.7.92.92,0,0,0,.69.28H17.2a1,1,0,0,0,.71-.28,1,1,0,0,0,0-1.39.92.92,0,0,0-.71-.29H9.26l3.87-5.43a.86.86,0,0,0,0-.95L9.26,5.73h7.93Z" transform="translate(-6.38 -3.77)"/></g></svg>',unlink:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.72"><g><path d="M19,18.32a4,4,0,0,0,0-5.68L15.85,9.5l-1.17,1.55L17.57,14a2,2,0,0,1,.61,1.47,2.08,2.08,0,0,1-2.09,2.09,2,2,0,0,1-1.47-.61l-.38-.37-1.74,1,.8.78a4,4,0,0,0,5.68,0ZM8,9.77a2,2,0,0,1-1.27-1,1.89,1.89,0,0,1-.21-1.57A2.1,2.1,0,0,1,7.45,6,2,2,0,0,1,9,5.76L12.27,7.2l.49-2L9.48,3.9a4,4,0,0,0-3.06.41A3.82,3.82,0,0,0,4.56,6.73a3.8,3.8,0,0,0,.4,3A3.78,3.78,0,0,0,7.39,11.6l5.38,2,.49-2-2.64-.94L8,9.77Z" transform="translate(-4.41 -3.76)"/></g></svg>',table_header:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.75 15.74"><g><path d="M17,19.5v-.78H15.5v.78H17Zm-3,0v-.78H12.5v.78H14Zm-3,0v-.78H9.53v.78H11Zm-3,0v-.78H6.53v.78H8Zm10.55,0a1.73,1.73,0,0,0,.85-.35,1.67,1.67,0,0,0,.56-.76l-.71-.31a1.21,1.21,0,0,1-.35.4,1.34,1.34,0,0,1-.53.23l.08.38c.06.24.09.38.1.41Zm-13.7-.63.55-.55A.77.77,0,0,1,5.25,18a1.31,1.31,0,0,1-.06-.38v-.38H4.41v.38a2,2,0,0,0,.12.68,1.6,1.6,0,0,0,.35.57Zm15.27-2.12V15.26h-.78v1.49h.78Zm-15-1V14.23H4.41v1.49h.78Zm15-2V12.26h-.78v1.49h.78Zm-15-1V11.22H4.41v1.51h.78Zm15-2V9.26h-.78v1.51h.78Zm-15-1V8.17H4.41V9.74h.78Zm15-2V6.28h-.78V7.77h.78Zm-15-1.11V5.33L4.48,5.1a.77.77,0,0,0-.07.27,2.72,2.72,0,0,0,0,.28v1h.79ZM19.21,5l.63-.4A1.62,1.62,0,0,0,19.16,4a1.94,1.94,0,0,0-.91-.22v.78a1.31,1.31,0,0,1,.56.12.88.88,0,0,1,.4.36ZM6,4.54H7.78V3.76H6a.82.82,0,0,0-.28.06l.12.35c.07.21.1.33.11.36Zm10.8,0V3.76H15.28v.78h1.49Zm-3,0V3.76H12.28v.78h1.49Zm-3,0V3.76H9.28v.78h1.51ZM6,10.84h12.6V6.91H6Z" transform="translate(-4.4 -3.76)"/></g></svg>',merge_cell:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.76 15.74"><g><path d="M18.92,13.5h1.23v4.15A1.84,1.84,0,0,1,18.3,19.5H14V18.27H18.3a.6.6,0,0,0,.44-.18.59.59,0,0,0,.18-.44V13.5ZM18.3,3.76a1.84,1.84,0,0,1,1.85,1.85V9.82H18.92V5.6a.6.6,0,0,0-.18-.44A.59.59,0,0,0,18.3,5H14V3.76H18.3Zm1.85,8.51H15.6L17.26,14l-.86.86-3.14-3.17L16.4,8.51l.86.86L15.62,11h4.54v1.24Zm-13.9,6h4.27V19.5H6.25A1.84,1.84,0,0,1,4.4,17.65V13.5H5.63v4.15a.61.61,0,0,0,.62.62Zm0-14.51h4.27V5H6.25a.6.6,0,0,0-.44.18.57.57,0,0,0-.17.43V9.81H4.41V5.6A1.83,1.83,0,0,1,6.25,3.76Zm5,7.9L8.15,14.83,7.3,14,9,12.27H4.41V11H8.94L7.3,9.38,7.73,9l.43-.43Z" transform="translate(-4.4 -3.76)"/></g></svg>',split_cell:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.75 15.74"><g><path d="M10.37,12.25H6.74L8.4,13.94l-.87.86L4.41,11.63,7.53,8.5l.87.86L6.74,11h3.62v1.23Zm9.78-.61L17,14.81,16.13,14l1.66-1.69H14.16V11h3.63L16.13,9.37l.43-.43A5.24,5.24,0,0,1,17,8.51ZM18.9,8.22V5.61a.57.57,0,0,0-.18-.43A.65.65,0,0,0,18.29,5H12.88V18.28h5.41a.7.7,0,0,0,.44-.18.57.57,0,0,0,.18-.43V15h1.23v2.64a1.84,1.84,0,0,1-1.85,1.83h-12A1.84,1.84,0,0,1,4.94,19a1.81,1.81,0,0,1-.54-1.29V15H5.63v2.64a.57.57,0,0,0,.18.43.67.67,0,0,0,.44.18h5.41V5H6.25a.7.7,0,0,0-.44.18.56.56,0,0,0-.17.43V8.22H4.41V5.61A1.8,1.8,0,0,1,5,4.31a1.91,1.91,0,0,1,1.31-.55h12a1.89,1.89,0,0,1,1.31.55,1.8,1.8,0,0,1,.54,1.3V8.23H18.9Z" transform="translate(-4.4 -3.76)"/></g></svg>',caption:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 13.79"><g><path d="M4.41,18.52H20.15v-2H4.41ZM20,4.73H18.07V6h.65v.65H20V4.73ZM17,6V4.73H14.55V6H17ZM13.49,6V4.73H11V6h2.47ZM10,6V4.73H7.5V6H10ZM5.79,6h.65V4.73H4.5V6.67H5.8V6ZM4.5,11.34H5.79V8.48H4.5ZM6.44,13.8H5.79v-.65H4.5v1.94H6.44ZM17,15.09V13.8H14.55v1.29H17Zm-3.52,0V13.8H11v1.29h2.47Zm-3.53,0V13.8H7.5v1.29H10ZM20,13.16H18.72v.65h-.65V15.1H20Zm-1.29-1.82H20V8.48h-1.3v2.86Z" transform="translate(-4.41 -4.73)"/></g></svg>',edit:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.73"><g><path d="M7.51,5.68h6l1.52-1.57H6.94a2.4,2.4,0,0,0-1.79.82A2.8,2.8,0,0,0,4.41,6.8V17a2.55,2.55,0,0,0,.75,1.8A2.48,2.48,0,0,0,7,19.5H17.22a2.57,2.57,0,0,0,1.83-.74,2.52,2.52,0,0,0,.77-1.8V8.83l-1.58,1.54v6a1.54,1.54,0,0,1-1.53,1.53H7.51A1.54,1.54,0,0,1,6,16.41V7.21A1.52,1.52,0,0,1,7.51,5.68Zm5.63,7.47h0L10.7,10.74l-1,3.38,1.71-.48,1.7-.49Zm.34-.34h0l5.36-5.32L16.4,5.08,11,10.4l1.23,1.21,1.21,1.2ZM19.93,6.4a.82.82,0,0,0,.22-.48A.54.54,0,0,0,20,5.47L18.45,4A.67.67,0,0,0,18,3.77a.7.7,0,0,0-.48.21l-.74.72,2.44,2.43.37-.37.35-.36Z" transform="translate(-4.41 -3.77)"/></g></svg>',delete:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.73 15.74"><g><path d="M19.16,6.71a.94.94,0,0,0,.69-.28.91.91,0,0,0,.29-.68A1,1,0,0,0,19.85,5a.93.93,0,0,0-.69-.3H14.24A.94.94,0,0,0,14,4.06a.92.92,0,0,0-.7-.3h-2a1,1,0,0,0-.7.3.93.93,0,0,0-.28.68H5.39A.92.92,0,0,0,4.7,5a1,1,0,0,0-.29.71.91.91,0,0,0,.29.68,1,1,0,0,0,.69.28H19.16Zm-12.79,1a1,1,0,0,0-.7.3.94.94,0,0,0-.28.69v8.85A1.88,1.88,0,0,0,6,18.93a1.9,1.9,0,0,0,1.39.57H17.2a1.87,1.87,0,0,0,1.39-.58,1.91,1.91,0,0,0,.58-1.39V8.68A1,1,0,0,0,18.88,8a.89.89,0,0,0-.7-.29,1,1,0,0,0-.69.29.92.92,0,0,0-.29.68v7.87a1,1,0,0,1-1,1H8.34a.94.94,0,0,1-.69-.28,1,1,0,0,1-.29-.71V8.68a1,1,0,0,0-1-1Z" transform="translate(-4.41 -3.76)"/></g></svg>',modify:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 15.74"><g><path d="M19.79,15.23a.66.66,0,0,1,.3.38.59.59,0,0,1-.07.48l-.8,1.38a.66.66,0,0,1-.38.3.59.59,0,0,1-.48-.07l-.68-.38a4.55,4.55,0,0,1-1.34.77v.78a.64.64,0,0,1-.18.45.61.61,0,0,1-.45.18h-1.6a.6.6,0,0,1-.44-.18.66.66,0,0,1-.19-.45v-.78a4.36,4.36,0,0,1-1.32-.77l-.69.38a.58.58,0,0,1-.48.07.66.66,0,0,1-.38-.3l-.38-.66h.83a1.77,1.77,0,0,0,1.23-.52,1.72,1.72,0,0,0,.51-1.23v-.18a3,3,0,0,0,.49-.28l.15.09a1.83,1.83,0,0,0,.88.23A1.75,1.75,0,0,0,15.84,14l.88-1.52a1.7,1.7,0,0,0,.17-1.32,1.66,1.66,0,0,0-.3-.61,1.84,1.84,0,0,0-.51-.45l-.15-.09,0-.29,0-.28.15-.09a1,1,0,0,0,.26-.18l0,.06v.78a4.34,4.34,0,0,1,1.34.77l.68-.38a.68.68,0,0,1,.48-.06.64.64,0,0,1,.38.29l.8,1.38a.58.58,0,0,1,.07.48.63.63,0,0,1-.3.38l-.68.4a3.84,3.84,0,0,1,.08.76,4.13,4.13,0,0,1-.08.78l.34.18.32.2ZM10.17,7.86a1.9,1.9,0,0,1,1.35,3.23,1.85,1.85,0,0,1-1.35.55A1.9,1.9,0,0,1,8.83,8.41a1.92,1.92,0,0,1,1.34-.55Zm1.58,7.2a.73.73,0,0,1-.21.49.66.66,0,0,1-.48.2H9.29a.68.68,0,0,1-.69-.69V14.2a4.75,4.75,0,0,1-1.48-.86l-.75.45a.73.73,0,0,1-.7,0,.63.63,0,0,1-.25-.26L4.54,12a.67.67,0,0,1-.08-.53.71.71,0,0,1,.32-.42l.75-.43a4.8,4.8,0,0,1-.08-.85,4.71,4.71,0,0,1,.08-.85l-.74-.44a.71.71,0,0,1-.32-.42.65.65,0,0,1,.07-.54L5.42,6a.66.66,0,0,1,.42-.32l.18,0a.73.73,0,0,1,.35.09l.75.43A4.68,4.68,0,0,1,8.6,5.33V4.45a.68.68,0,0,1,.69-.69h1.77a.64.64,0,0,1,.48.2.73.73,0,0,1,.21.49v.88a4.75,4.75,0,0,1,1.48.85L14,5.75a.67.67,0,0,1,.34-.09l.18,0a.71.71,0,0,1,.42.32l.89,1.54a.67.67,0,0,1,.06.52.73.73,0,0,1-.32.43l-.75.42a4.8,4.8,0,0,1,.08.85,4.71,4.71,0,0,1-.08.85l.75.43a.66.66,0,0,1,.32.42.73.73,0,0,1-.06.54l-.89,1.52a.69.69,0,0,1-.25.26.7.7,0,0,1-.35.09.64.64,0,0,1-.34-.09l-.75-.45a4.87,4.87,0,0,1-1.48.86v.87ZM7.23,9.75a3,3,0,0,0,.86,2.08,2.94,2.94,0,1,0,4.16-4.16,3,3,0,0,0-2.08-.85A2.94,2.94,0,0,0,7.23,9.75Z" transform="translate(-4.44 -3.76)"/></g></svg>',revert:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.76 14.69"><g><path d="M18.26,15V12.3l1.89-2V15a2.58,2.58,0,0,1-.24,1c-.2.58-.75.92-1.65,1H7.56v2L4.41,15.63,7.56,13v2h10.7ZM6.3,8.28V11L4.41,13V8.28a2.58,2.58,0,0,1,.24-1c.2-.58.75-.92,1.65-1H17v-2l3.15,3.34L17,10.3v-2H6.3Z" transform="translate(-4.4 -4.28)"/></g></svg>',auto_size:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 15.74"><g><path d="M6.71,17.19,6.89,16l1.21-.15A6,6,0,0,1,6.81,13.9a5.78,5.78,0,0,1-.45-2.27A6,6,0,0,1,8.1,7.45a5.83,5.83,0,0,1,4.17-1.73l1-1-1-1A7.89,7.89,0,0,0,5,14.64a7.73,7.73,0,0,0,1.71,2.55Zm5.57,2.31h0A7.86,7.86,0,0,0,17.85,6.07L17.67,7.3l-1.21.15a5.9,5.9,0,0,1,1.29,1.92,5.81,5.81,0,0,1,.45,2.26,5.91,5.91,0,0,1-5.9,5.9l-1,1,.49.49.47.5Z" transform="translate(-4.41 -3.76)"/></g></svg>',insert_row_below:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.8 15.8"><g><path d="M15.7,1.3c-0.1-0.1-0.1-0.2-0.2-0.2L15.3,1H0.4L0.3,1.1c0,0-0.1,0.1-0.1,0.1c0,0-0.1,0.1-0.1,0.1L0,1.4v7.7l0.1,0.1c0,0.1,0.1,0.1,0.2,0.2l0.1,0.1h2.3V9.3l0.1-0.5L3,8.5l0.1-0.2c-0.1,0-0.2,0-0.3,0H1.2v-6h13.3v6h-1.6c-0.1,0-0.2,0-0.3,0l0.1,0.2l0.2,0.4C12.9,9,13,9.2,13,9.3v0.1h2.3l0.2-0.1c0.1,0,0.1-0.1,0.2-0.2l0.1-0.1V1.4L15.7,1.3z"/><path d="M10.5,7.5C9.9,7.1,9.3,6.8,8.6,6.7c-0.2,0-0.5-0.1-0.7,0c-0.2,0-0.5,0-0.7,0C6.6,6.7,6.1,6.9,5.6,7.3C5.2,7.6,4.7,8,4.4,8.4C4.3,8.6,4.2,8.8,4.2,8.9C4.1,9.1,4,9.3,3.9,9.4C3.9,9.6,3.8,9.7,3.8,9.9c0,0.2-0.1,0.3-0.1,0.5v-0.1c-0.1,0.8,0.1,1.6,0.5,2.4c0.4,0.7,1,1.3,1.7,1.7c0.3,0.2,0.6,0.3,0.9,0.3c0.3,0.1,0.7,0.1,1,0.1c0.3,0,0.7,0,1-0.1c0.3-0.1,0.6-0.2,0.9-0.3c0.5-0.3,0.9-0.6,1.3-1c0.3-0.4,0.6-0.8,0.8-1.3c0.1-0.4,0.2-0.9,0.2-1.4c0-0.5-0.1-1-0.3-1.4C11.5,8.6,11.1,8,10.5,7.5z M10.1,11.3H8.5v1.6H8H7.9H7.3v0v-0.1v-1.4H5.7v-0.4v-0.2v-0.6h0h1.5V8.5h1.2v1.6h1.6V11.3z"/></g></svg>',insert_row_above:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.8 15.8"><g><path d="M0.1,14.5c0.1,0.1,0.1,0.2,0.2,0.2l0.1,0.1h14.9l0.1-0.1c0,0,0.1-0.1,0.1-0.1c0,0,0.1-0.1,0.1-0.1l0.1-0.1V6.7l-0.1-0.1c0-0.1-0.1-0.1-0.2-0.2l-0.1-0.1h-2.3v0.1l-0.1,0.5l-0.2,0.4l-0.1,0.2c0.1,0,0.2,0,0.3,0h1.6v6H1.3v-6h1.6c0.1,0,0.2,0,0.3,0L3.1,7.3L2.9,6.9C2.8,6.8,2.8,6.6,2.7,6.5V6.3H0.4L0.3,6.4c-0.1,0-0.1,0.1-0.2,0.2L0,6.7v7.7L0.1,14.5z"/><path d="M5.3,8.3c0.6,0.5,1.2,0.8,1.9,0.9c0.2,0,0.5,0.1,0.7,0c0.2,0,0.5,0,0.7,0c0.6-0.1,1.1-0.3,1.6-0.6c0.5-0.3,0.9-0.7,1.2-1.2c0.1-0.2,0.2-0.3,0.3-0.5c0.1-0.2,0.2-0.4,0.2-0.5c0.1-0.1,0.1-0.3,0.1-0.4C12,5.8,12,5.6,12,5.4v0.1c0.1-0.8-0.1-1.6-0.5-2.4c-0.4-0.7-1-1.3-1.7-1.7C9.5,1.3,9.2,1.2,8.9,1.1C8.5,1,8.2,1,7.9,1c-0.3,0-0.7,0-1,0.1C6.6,1.2,6.3,1.3,6,1.4C5.5,1.7,5.1,2,4.7,2.4C4.4,2.8,4.1,3.3,3.9,3.8C3.8,4.2,3.7,4.7,3.7,5.2c0,0.5,0.1,1,0.3,1.4C4.3,7.2,4.7,7.8,5.3,8.3z M5.7,4.5h1.6V2.9h0.5h0.1h0.6v0v0.1v1.4H10v0.4v0.2v0.6h0H8.5v1.6H7.3V5.7H5.7V4.5z"/></g></svg>',insert_column_left:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.8 15.8"><g><path d="M14.5,15.7c0.1-0.1,0.2-0.1,0.2-0.2l0.1-0.1V0.4l-0.1-0.1c0,0-0.1-0.1-0.1-0.1c0,0-0.1-0.1-0.1-0.1L14.4,0H6.7L6.6,0.1c-0.1,0-0.1,0.1-0.2,0.2L6.3,0.4v2.3h0.1l0.5,0.1L7.3,3l0.2,0.1c0-0.1,0-0.2,0-0.3V1.2h6v13.3h-6v-1.6c0-0.1,0-0.2,0-0.3l-0.2,0.1l-0.4,0.2C6.7,12.9,6.6,13,6.4,13H6.3v2.3l0.1,0.2c0,0.1,0.1,0.1,0.2,0.2l0.1,0.1h7.7L14.5,15.7z"/><path d="M8.3,10.5C8.7,10,9,9.3,9.1,8.6c0-0.2,0.1-0.5,0-0.7c0-0.2,0-0.5,0-0.7C9,6.7,8.8,6.1,8.5,5.7C8.2,5.2,7.8,4.8,7.3,4.5C7.2,4.4,7,4.3,6.9,4.2C6.7,4.1,6.5,4,6.4,4C6.2,3.9,6.1,3.9,5.9,3.8c-0.2,0-0.3-0.1-0.5-0.1h0.1C4.7,3.7,3.8,3.9,3.1,4.3C2.4,4.7,1.8,5.3,1.4,6C1.3,6.3,1.2,6.6,1.1,6.9C1,7.2,1,7.6,1,7.9c0,0.3,0,0.7,0.1,1c0.1,0.3,0.2,0.6,0.3,0.9c0.3,0.5,0.6,0.9,1,1.3c0.4,0.3,0.8,0.6,1.3,0.8C4.2,12,4.7,12.1,5.1,12c0.5,0,1-0.1,1.4-0.3C7.2,11.5,7.8,11.1,8.3,10.5zM4.5,10.1V8.5H2.9V8V7.9V7.3h0H3h1.4V5.7h0.4h0.2h0.6v0v1.5h1.6v1.2H5.7v1.6H4.5z"/></g></svg>',insert_column_right:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.8 15.8"><g><path d="M1.3,0.1C1.2,0.2,1.1,0.2,1.1,0.3L1,0.4v14.9l0.1,0.1c0,0,0.1,0.1,0.1,0.1c0,0,0.1,0.1,0.1,0.1l0.1,0.1h7.7l0.1-0.1c0.1,0,0.1-0.1,0.2-0.2l0.1-0.1v-2.3H9.3l-0.5-0.1l-0.4-0.2l-0.2-0.1c0,0.1,0,0.2,0,0.3v1.6h-6V1.3h6v1.6c0,0.1,0,0.2,0,0.3l0.2-0.1l0.4-0.2C9,2.9,9.2,2.8,9.3,2.8h0.1V0.5L9.4,0.3c0-0.1-0.1-0.1-0.2-0.2L9.1,0H1.4L1.3,0.1z"/><path d="M7.5,5.3C7,5.8,6.7,6.5,6.6,7.2c0,0.2-0.1,0.5,0,0.7c0,0.2,0,0.5,0,0.7c0.1,0.6,0.3,1.1,0.6,1.6c0.3,0.5,0.7,0.9,1.2,1.2c0.2,0.1,0.3,0.2,0.5,0.3c0.2,0.1,0.4,0.2,0.5,0.2c0.1,0.1,0.3,0.1,0.4,0.1c0.2,0,0.3,0.1,0.5,0.1h-0.1c0.8,0.1,1.6-0.1,2.4-0.5c0.7-0.4,1.3-1,1.7-1.7c0.2-0.3,0.3-0.6,0.3-0.9c0.1-0.3,0.1-0.7,0.1-1c0-0.3,0-0.7-0.1-1c-0.1-0.3-0.2-0.6-0.3-0.9c-0.3-0.5-0.6-0.9-1-1.3C13,4.4,12.5,4.2,12,4c-0.4-0.1-0.9-0.2-1.4-0.2c-0.5,0-1,0.1-1.4,0.2C8.5,4.3,7.9,4.7,7.5,5.3z M11.3,5.7v1.6h1.6v0.5v0.1v0.6h0h-0.1h-1.4v1.6h-0.4h-0.2h-0.6v0V8.5H8.5V7.3h1.6V5.7H11.3z"/></g></svg>',delete_row:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.75 13.83"><g><path d="M4.7,18.46l.12.08H19.73l.12-.08a.58.58,0,0,0,.22-.22l.08-.12,0-7.69-.08-.11a.77.77,0,0,0-.18-.18l-.11-.08-2.31,0-.08.28-.1.29a1.58,1.58,0,0,1-.12.29l-.14.34s0,0,.18,0H18.9v6H5.64v-6H7.35c.14,0,.2,0,.18,0l-.14-.34a2.85,2.85,0,0,1-.12-.29l-.1-.29-.07-.27-2.31,0-.11.08a.77.77,0,0,0-.18.18l-.08.11,0,7.69.08.12a.47.47,0,0,0,.09.12l.13.09ZM12.11,13a4,4,0,0,0,1.46-.21,4.51,4.51,0,0,0,1.31-.71A4,4,0,0,0,16.26,10a4.32,4.32,0,0,0-.08-2.54,4.34,4.34,0,0,0-1-1.52,4.15,4.15,0,0,0-1.54-1,4.34,4.34,0,0,0-1.35-.22A4.07,4.07,0,0,0,11,4.93,3.94,3.94,0,0,0,9.24,6.07,3.92,3.92,0,0,0,8.15,8.88a3.91,3.91,0,0,0,.12.95A4.16,4.16,0,0,0,12.11,13Zm2.35-4.14v.58H10.09V8.27h4.37v.58Z" transform="translate(-4.4 -4.71)"/></g></svg>',delete_column:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13.81 15.74"><g><path d="M5.66,19.42l.12.08,7.69,0,.11-.08a.77.77,0,0,0,.18-.18l.08-.11,0-2.32-.15,0-.45-.15-.42-.18-.17-.07a1,1,0,0,0,0,.27v1.63h-6V5h6V6.62a.9.9,0,0,0,0,.26l.17-.07.42-.17a3.91,3.91,0,0,1,.45-.15l.15,0,0-2.32L13.75,4a.77.77,0,0,0-.18-.18l-.11-.08H5.79l-.13.07a.63.63,0,0,0-.21.22l-.08.12V19.08l.08.12a.47.47,0,0,0,.09.12.35.35,0,0,0,.12.1Zm9-3.67a4.16,4.16,0,0,0,2.36-.51,4.08,4.08,0,0,0,1.67-1.72,4,4,0,0,0,.35-.91,3.79,3.79,0,0,0,.1-1,4.71,4.71,0,0,0-.11-1,5,5,0,0,0-.3-.87,4.25,4.25,0,0,0-1-1.25,4.49,4.49,0,0,0-1.34-.81A4.26,4.26,0,0,0,15,7.48a3.88,3.88,0,0,0-1.41.25A4.32,4.32,0,0,0,11.86,9,4,4,0,0,0,11,10.94a4.4,4.4,0,0,0-.05.68,4.5,4.5,0,0,0,.05.68,3.93,3.93,0,0,0,.61,1.57,4.22,4.22,0,0,0,1.18,1.2,4.59,4.59,0,0,0,.48.27c.2.1.37.17.5.22a2.44,2.44,0,0,0,.45.12,4.61,4.61,0,0,0,.5.07Zm2.54-4.12v.58H12.87V11h4.37v.59Z" transform="translate(-5.37 -3.76)"/></g></svg>',fixed_column_width:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6,5H18A1,1 0 0,1 19,6A1,1 0 0,1 18,7H6A1,1 0 0,1 5,6A1,1 0 0,1 6,5M21,2V4H3V2H21M15,8H17V22H15V8M7,8H9V22H7V8M11,8H13V22H11V8Z" /></svg>',rotate_left:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.8 15.8"><g><path d="M0.5,10.2c0,0.1,0,0.2,0,0.3v0.2l0,0c0.1,0.3,0.3,0.6,0.4,0.9l0,0C1,11.8,1.3,12,1.5,11.9h0.1h0.2h0.1c0.1-0.1,0.3-0.3,0.4-0.5v-0.2c0-0.1,0-0.2-0.1-0.3l0,0c-0.2-0.2-0.3-0.4-0.3-0.7l0,0C1.8,10,1.7,9.9,1.5,9.8c-0.1,0-0.2,0-0.3,0H0.9C0.7,9.9,0.6,10,0.5,10.2L0.5,10.2z"/><path d="M2.2,11.5L2.2,11.5L2.2,11.5z"/><path d="M5.9,3.6L5.9,3.6L5.9,3.6z"/><path d="M0.1,7.9c0,0.3,0,0.6,0,0.9l0,0l0,0l0,0l0,0c0,0.2,0.1,0.3,0.2,0.4l0,0c0.2,0.1,0.3,0.2,0.5,0.2l0,0l0,0c0.2,0,0.4-0.1,0.5-0.3l0,0c0-0.1,0.1-0.3,0.1-0.4V8.6l0,0c0-0.2,0-0.5,0-0.7l0,0c0-0.2-0.1-0.4-0.2-0.5C1.1,7.3,0.9,7.2,0.7,7.2S0.3,7.3,0.2,7.4C0.1,7.5,0,7.7,0.1,7.9z"/><path d="M1.9,12.7L1.9,12.7c0,0.2,0,0.4,0.2,0.5l0,0l0.2,0.3l0,0c0.2,0.1,0.3,0.2,0.5,0.4l0,0l0,0l0,0l0,0C2.9,14,3,14.1,3.2,14.1s0.4-0.1,0.5-0.2c0.1-0.2,0.2-0.3,0.2-0.5v-0.1c0-0.2-0.1-0.4-0.2-0.5l0,0l-0.4-0.4l-0.2-0.2l0,0C3,12.1,2.8,12,2.6,12l0,0c-0.2,0-0.4,0.1-0.5,0.2l0,0C2,12.3,1.9,12.5,1.9,12.7z"/><path d="M6.6,15c0,0.2,0.1,0.4,0.2,0.5c0.1,0.1,0.2,0.2,0.4,0.3l0,0c0.3,0,0.5,0,0.7,0h0.3l0,0c0.2,0,0.4-0.1,0.5-0.2c0.1-0.2,0.2-0.3,0.2-0.5l0,0l0,0c0-0.2-0.1-0.4-0.2-0.5l0,0c-0.1-0.1-0.3-0.2-0.5-0.2l0,0H7.9c-0.1,0-0.3,0-0.5,0l0,0H7.3c-0.2-0.1-0.3,0-0.5,0.1l0,0C6.7,14.6,6.6,14.8,6.6,15L6.6,15L6.6,15L6.6,15z"/><path d="M4.2,7.4C4,7.5,4,7.7,4,7.9c0,0.2,0,0.4,0.2,0.5l0,0l3.2,3.2l0,0c0.1,0.1,0.3,0.2,0.5,0.2s0.3-0.1,0.5-0.2l0,0l3.2-3.2l0,0c0.1-0.1,0.2-0.3,0.2-0.5c0-0.2-0.1-0.4-0.2-0.5l0,0C11.5,7.3,11,6.7,10,5.8l0,0L8.4,4.2l0,0C8.3,4.1,8.1,4,7.9,4S7.5,4.1,7.4,4.2L4.2,7.4L4.2,7.4z M6.8,9L5.7,7.9l2.2-2.2l2.3,2.2l-2.3,2.2C7.7,9.9,7.3,9.5,6.8,9L6.8,9z"/><path d="M4.1,14.1C4,14.2,4,14.3,4,14.4v0.2l0,0c0.1,0.1,0.2,0.3,0.4,0.4l0,0c0.3,0.1,0.6,0.2,0.9,0.4h0.1h0.1l0,0c0.2,0,0.3-0.1,0.5-0.1l0,0c0.2-0.1,0.3-0.3,0.3-0.4l0,0l0,0l0,0l0,0v-0.2c0-0.1-0.1-0.2-0.1-0.3l0,0C6.1,14.2,6,14.1,5.8,14l0,0c-0.3-0.1-0.5-0.2-0.8-0.2l0,0c-0.1-0.1-0.2-0.1-0.3-0.1H4.5C4.3,13.7,4.2,13.9,4.1,14.1z"/><path d="M9.3,14.4c0,0.1-0.1,0.3,0,0.4V15l0,0c0,0.1,0.1,0.3,0.5,0.4c0.1,0.1,0.3,0.1,0.4,0.1l0,0h0.1l0,0c0.3-0.1,0.6-0.2,0.9-0.3l0,0c0.1-0.1,0.2-0.2,0.3-0.4l0.1-0.3c0-0.1-0.1-0.2-0.1-0.3l0,0c-0.1-0.2-0.2-0.3-0.4-0.4l0,0h-0.3c-0.1,0-0.2,0-0.3,0l0,0c-0.2,0.1-0.5,0.2-0.8,0.3l0,0C9.5,14.1,9.4,14.2,9.3,14.4L9.3,14.4z"/><path d="M11.4,14.7L11.4,14.7L11.4,14.7z"/><path d="M9.5,15.3L9.5,15.3L9.5,15.3z"/><path d="M15.9,7.9c0-1-0.2-2-0.6-3l0,0c-0.4-1-1-1.9-1.7-2.6C12.8,1.6,12,1,11,0.6l0,0C10.1,0.2,9,0,8,0C7.3,0,6.5,0.1,5.8,0.3l0,0C5.2,0.5,4.6,0.8,4,1.1L3.1,0.2l0,0C2.9,0.1,2.8,0,2.6,0H2.4l0,0C2.2,0,2,0.2,1.9,0.4l0,0L0.1,4.9l0,0C0,5,0,5.1,0,5.2c0,0.2,0.1,0.4,0.2,0.5l0,0c0.2,0.1,0.3,0.2,0.5,0.2h0.1H1l0,0l4.7-1.8l0,0C5.9,4,6.1,3.8,6.1,3.6V3.4C6.1,3.2,6,3,5.9,2.9l0,0L5.1,2.1c0.4-0.2,0.8-0.4,1.3-0.5c0.5-0.1,1.1-0.2,1.7-0.2c0.9,0,1.7,0.2,2.5,0.5l0,0c0.8,0.3,1.5,0.8,2.1,1.4c0.6,0.6,1.1,1.3,1.4,2.1l0,0c0.3,0.8,0.5,1.6,0.5,2.5s-0.2,1.7-0.5,2.5l0,0c-0.3,0.8-0.8,1.5-1.4,2.1c-0.2,0.2-0.4,0.3-0.6,0.5l0,0c-0.2,0.1-0.3,0.3-0.3,0.5v0.1c0,0.1,0,0.3,0.1,0.4l0,0c0.1,0.2,0.3,0.3,0.5,0.3l0,0c0.1,0,0.3-0.1,0.4-0.2l0,0l0,0l0,0l0,0c0.2-0.2,0.5-0.4,0.7-0.6l0,0l0,0l0,0l0,0c0.7-0.8,1.3-1.6,1.7-2.6C15.6,10,15.8,9,15.9,7.9z M1.9,4C2,3.8,2.1,3.5,2.3,3.1l0,0L2.7,2l1.2,1.2L1.9,4z"/><path d="M6.8,15.5L6.8,15.5L6.8,15.5z"/></g></svg>',rotate_right:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.8 15.8"><g><path d="M9.9,15.3L9.9,15.3L9.9,15.3z"/><path d="M6.9,15.1L6.9,15.1c0,0.1,0.1,0.3,0.2,0.4l0,0c0.1,0.2,0.3,0.3,0.5,0.3l0,0h0.3c0.2,0,0.4,0,0.7,0l0,0c0.2-0.1,0.3-0.2,0.4-0.3c0.1-0.1,0.2-0.2,0.2-0.4V15c0-0.2-0.1-0.4-0.2-0.4c-0.2-0.1-0.3-0.2-0.5-0.2H8.4l0,0c-0.1,0-0.3,0-0.5,0H7.6l0,0c-0.2,0-0.4,0.1-0.5,0.2C7,14.7,6.9,14.9,6.9,15.1z"/><path d="M6.5,14.4L6.5,14.4L6.5,14.4z"/><path d="M5.8,5.8L5.8,5.8c-1,0.9-1.5,1.5-1.7,1.6l0,0C4,7.5,4,7.7,4,7.9c0,0.2,0,0.4,0.2,0.5l0,0l3.2,3.2l0,0c0.2,0.1,0.3,0.2,0.5,0.2s0.4-0.1,0.5-0.2l0,0l3.2-3.2l0,0c0.1-0.1,0.2-0.3,0.2-0.5c0-0.2-0.1-0.4-0.2-0.5l0,0L8.4,4.2C8.3,4.1,8.1,4,7.9,4C7.7,4,7.5,4.1,7.4,4.2l0,0L5.8,5.8z M5.6,7.9l2.3-2.2l2.2,2.2L9,9l0,0l0,0l0,0l0,0c-0.5,0.6-0.9,0.9-1.1,1.1L5.6,7.9z"/><path d="M9,15.5L9,15.5L9,15.5z"/><path d="M9.6,14.7v0.2l0,0l0,0l0,0l0,0c0.1,0.2,0.1,0.3,0.3,0.3c0.1,0.1,0.3,0.1,0.4,0.1l0,0h0.1h0.1c0.3-0.1,0.6-0.3,0.9-0.4l0,0c0.1-0.1,0.2-0.2,0.3-0.4l0,0v-0.2c0-0.1,0-0.2-0.1-0.3c-0.1-0.2-0.2-0.3-0.4-0.4H11c-0.1,0-0.2,0.1-0.3,0.1l0,0c-0.2,0.1-0.4,0.2-0.7,0.3l0,0l0,0c-0.1,0.1-0.3,0.2-0.4,0.4C9.6,14.5,9.6,14.6,9.6,14.7z"/><path d="M9,14.5L9,14.5L9,14.5z"/><path d="M9.6,14.4L9.6,14.4L9.6,14.4z"/><path d="M11.7,14L11.7,14L11.7,14z"/><path d="M15.6,7.4L15.6,7.4L15.6,7.4z"/><path d="M15,9.4c0.2,0,0.4,0,0.6-0.2l0,0c0.1-0.1,0.2-0.2,0.2-0.4l0,0l0,0l0,0l0,0c0-0.3,0-0.6,0-0.9c0-0.2-0.1-0.4-0.2-0.5c-0.1-0.1-0.3-0.2-0.5-0.2s-0.4,0.1-0.5,0.2c-0.1,0.1-0.2,0.3-0.2,0.5l0,0c0,0.2,0,0.4,0,0.7l0,0v0.1c0,0.1,0,0.3,0.1,0.4l0,0C14.6,9.3,14.8,9.4,15,9.4L15,9.4L15,9.4z"/><path d="M14,12h0.1h0.2h0.1c0.2,0,0.5-0.2,0.6-0.4l0,0c0.2-0.3,0.3-0.6,0.4-0.9l0,0v-0.2c0-0.1-0.1-0.2-0.1-0.3c-0.1-0.2-0.2-0.3-0.4-0.4h-0.3c-0.1,0-0.2,0-0.3,0C14.2,9.9,14,10,14,10.3l0,0c-0.1,0.2-0.2,0.5-0.3,0.7l0,0c-0.1,0.1-0.1,0.2-0.1,0.3v0.2l0,0l0,0C13.6,11.6,13.8,11.8,14,12z"/><path d="M14.6,7.4L14.6,7.4L14.6,7.4z"/><path d="M4.4,14.2c-0.1,0.1-0.1,0.2-0.1,0.3l0.1,0.2c0,0.2,0.2,0.3,0.3,0.4l0,0c0.3,0.1,0.6,0.3,1.1,0.4l0,0h0.1l0,0c0.1,0,0.2-0.1,0.4-0.2c0.1,0,0.2-0.2,0.3-0.3l0,0v-0.2c0-0.1-0.1-0.3-0.2-0.4c-0.1-0.1-0.2-0.2-0.4-0.3l0,0c-0.2-0.1-0.5-0.2-0.7-0.3l0,0c-0.1,0-0.2,0-0.3,0H4.7l0,0C4.6,13.9,4.4,14,4.4,14.2L4.4,14.2z"/><path d="M11.9,13.3c0,0.2,0.1,0.4,0.2,0.6c0.1,0.1,0.3,0.2,0.5,0.2s0.4-0.1,0.5-0.2l0,0l0,0l0,0l0,0c0.1-0.1,0.3-0.3,0.4-0.4l0,0l0.2-0.3l0,0c0.1-0.2,0.2-0.3,0.2-0.5l0,0c0-0.2-0.1-0.4-0.2-0.5l0,0c-0.1-0.1-0.3-0.2-0.5-0.2l0,0c-0.2,0-0.4,0.1-0.5,0.2l0,0l-0.2,0.2l-0.4,0.4l0,0C12,13,11.9,13.1,11.9,13.3L11.9,13.3z"/><path d="M12.1,13.8L12.1,13.8L12.1,13.8z"/><path d="M11.9,13.3L11.9,13.3L11.9,13.3z"/><path d="M15.9,5.2c0-0.1-0.1-0.2-0.1-0.3l0,0L14,0.4l0,0C13.9,0.2,13.7,0,13.5,0l0,0l0,0h-0.2c-0.2,0-0.4,0.1-0.5,0.2l0,0l-0.9,0.9c-0.5-0.3-1.1-0.6-1.8-0.8l0,0C9.4,0.1,8.7,0,7.9,0c-1,0-2,0.2-3,0.6S3,1.6,2.3,2.3C1.6,3.1,1,3.9,0.6,4.9l0,0C0.2,5.8,0,6.8,0,7.9c0,1,0.2,2,0.6,3s0.9,1.8,1.7,2.6l0,0l0,0l0,0l0,0c0.2,0.2,0.5,0.4,0.7,0.6l0,0l0,0l0,0l0,0c0.2,0.1,0.3,0.2,0.5,0.2l0,0c0.2,0,0.4-0.1,0.6-0.3l0,0c0.1-0.1,0.1-0.3,0.1-0.4v-0.1l0,0C4.1,13.3,4,13.1,3.9,13l0,0c-0.2-0.1-0.4-0.3-0.6-0.5c-0.6-0.6-1.1-1.3-1.4-2.1l0,0C1.6,9.6,1.4,8.8,1.4,7.9s0.2-1.7,0.5-2.5l0,0c0.3-0.8,0.8-1.5,1.4-2.1c0.6-0.6,1.3-1.1,2.1-1.4l0,0C6.2,1.6,7,1.4,7.9,1.4c0.6,0,1.1,0.1,1.7,0.2c0.5,0.1,0.9,0.3,1.3,0.5l-0.8,0.8l0,0C10,3.1,9.9,3.2,9.9,3.4v0.2l0,0l0,0c0,0.2,0.2,0.4,0.4,0.5l0,0l4.5,1.8l0,0H15h0.1c0.2,0,0.4-0.1,0.5-0.2l0,0C15.7,5.6,15.8,5.4,15.9,5.2z M11.8,3.2L13,2l0.4,1.1l0,0c0.2,0.4,0.3,0.7,0.4,0.9L11.8,3.2z"/></g></svg>',mirror_horizontal:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14.75 15.74"><g><path d="M13.75,3.76l5.9,15.74h-5.9V3.76ZM4.9,19.5,10.8,3.76V19.5H4.9Z" transform="translate(-4.9 -3.76)"/></g></svg>',mirror_vertical:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.74 14.75"><g><path d="M20.15,13.1,4.41,19V13.1H20.15ZM4.41,4.25l15.74,5.9H4.41V4.25Z" transform="translate(-4.41 -4.25)"/></g></svg>',checked:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.75 12.1"><g><path d="M4.59,12.23l.12.18L9.43,17.5a.58.58,0,0,0,.84,0L20,7.45h0a.58.58,0,0,0,0-.84l-.85-.85a.58.58,0,0,0-.84,0H18.2l-8.12,8.41a.29.29,0,0,1-.42,0l-3.4-3.63a.58.58,0,0,0-.84,0l-.85.85a.6.6,0,0,0-.14.21.51.51,0,0,0,0,.44c.05.06.1.13.16.19Z" transform="translate(-4.38 -5.58)"/></g></svg>',line_break:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19,6a1,1,0,0,0-1,1v4a1,1,0,0,1-1,1H7.41l1.3-1.29A1,1,0,0,0,7.29,9.29l-3,3a1,1,0,0,0-.21.33,1,1,0,0,0,0,.76,1,1,0,0,0,.21.33l3,3a1,1,0,0,0,1.42,0,1,1,0,0,0,0-1.42L7.41,14H17a3,3,0,0,0,3-3V7A1,1,0,0,0,19,6Z"/></svg>',audio:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.84 14,18.7V20.77C18,19.86 21,16.28 21,12C21,7.72 18,4.14 14,3.23M16.5,12C16.5,10.23 15.5,8.71 14,7.97V16C15.5,15.29 16.5,13.76 16.5,12M3,9V15H7L12,20V4L7,9H3Z" /></svg>',image_gallery:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="30 30 150 150"><g><path d="M152.775,120.548V51.651c0-12.271-9.984-22.254-22.254-22.254H43.727c-12.271,0-22.254,9.983-22.254,22.254v68.896c0,12.27,9.983,22.254,22.254,22.254h86.795C142.791,142.802,152.775,132.817,152.775,120.548z M36.394,51.651c0-4.042,3.291-7.333,7.333-7.333h86.795c4.042,0,7.332,3.291,7.332,7.333v23.917l-14.938-17.767c-1.41-1.678-3.487-2.649-5.68-2.658h-0.029c-2.184,0-4.255,0.954-5.674,2.613L76.709,98.519l-9.096-9.398c-1.427-1.474-3.392-2.291-5.448-2.273c-2.052,0.025-4.004,0.893-5.396,2.4L36.394,111.32V51.651z M41.684,127.585l20.697-22.416l9.312,9.622c1.461,1.511,3.489,2.334,5.592,2.27c2.101-0.066,4.075-1.013,5.44-2.612l34.436-40.308l20.693,24.613v21.794c0,4.042-3.29,7.332-7.332,7.332H43.727C43.018,127.88,42.334,127.775,41.684,127.585z M182.616,152.5V75.657c0-4.12-3.34-7.46-7.461-7.46c-4.119,0-7.46,3.34-7.46,7.46V152.5c0,4.112-3.347,7.46-7.461,7.46h-94c-4.119,0-7.46,3.339-7.46,7.459c0,4.123,3.341,7.462,7.46,7.462h94C172.576,174.881,182.616,164.841,182.616,152.5z"/></g></svg>',more_text:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="10 10 180 180"><g><path d="M49.711,142.188h49.027c2.328,0.002,4.394,1.492,5.129,3.699l9.742,29.252c0.363,1.092,1.385,1.828,2.537,1.83l15.883,0.01c0.859,0,1.667-0.412,2.17-1.109s0.641-1.594,0.37-2.41l-16.625-50.045L86.503,28.953c-0.36-1.097-1.383-1.839-2.537-1.842H64.532c-1.153-0.001-2.178,0.736-2.542,1.831L13.847,173.457c-0.271,0.816-0.135,1.713,0.369,2.412c0.503,0.697,1.311,1.109,2.171,1.109h15.872c1.151,0,2.173-0.736,2.537-1.828l9.793-29.287C45.325,143.66,47.39,142.18,49.711,142.188L49.711,142.188z M53.493,119.098l15.607-46.9c0.744-2.196,2.806-3.674,5.125-3.674s4.381,1.478,5.125,3.674l15.607,46.904c0.537,1.621,0.263,3.402-0.736,4.789c-1.018,1.408-2.649,2.24-4.386,2.24H58.615c-1.736,0-3.368-0.832-4.386-2.24C53.23,122.504,52.956,120.721,53.493,119.098L53.493,119.098z M190.465,63.32c0-2.919-1.015-5.396-3.059-7.428c-2.029-2.031-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.016-7.388,3.047c-2.029,2.032-3.056,4.498-3.056,7.386c0,2.889,1.026,5.354,3.056,7.385c2.032,2.032,4.499,3.059,7.388,3.059c2.887,0,5.354-1.026,7.383-3.059C189.45,68.633,190.465,66.178,190.465,63.32L190.465,63.32z M190.465,101.994c0-2.858-1.015-5.313-3.059-7.333c-2.029-2.042-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.005-7.388,3.047c-2.029,2.021-3.056,4.486-3.056,7.376c0,2.887,1.026,5.352,3.056,7.395c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,107.389,190.465,104.914,190.465,101.994L190.465,101.994z M190.465,140.76c0-2.918-1.015-5.395-3.059-7.438c-2.029-2.041-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.006-7.388,3.047c-2.029,2.043-3.056,4.52-3.056,7.438c0,2.922,1.026,5.398,3.056,7.439c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,146.158,190.465,143.682,190.465,140.76L190.465,140.76z"/></g></svg>',more_paragraph:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="10 10 180 180"><g><path d="M128.39,28.499H63.493c-25.558,0-46.354,20.796-46.354,46.354c0,25.559,20.796,46.353,46.354,46.353h9.271v55.625h18.542V47.04h9.271V176.83h18.543V47.04h9.271V28.499z M72.764,102.664h-9.271c-15.337,0-27.813-12.475-27.813-27.812c0-15.336,12.476-27.813,27.813-27.813h9.271V102.664z M190.465,63.32c0-2.919-1.015-5.396-3.059-7.428c-2.029-2.031-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.016-7.388,3.047c-2.029,2.032-3.056,4.498-3.056,7.386c0,2.889,1.026,5.354,3.056,7.385c2.032,2.032,4.499,3.059,7.388,3.059c2.887,0,5.354-1.026,7.383-3.059C189.45,68.633,190.465,66.178,190.465,63.32L190.465,63.32z M190.465,101.994c0-2.858-1.015-5.313-3.059-7.333c-2.029-2.042-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.005-7.388,3.047c-2.029,2.021-3.056,4.486-3.056,7.376c0,2.887,1.026,5.352,3.056,7.395c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,107.389,190.465,104.914,190.465,101.994L190.465,101.994z M190.465,140.76c0-2.918-1.015-5.395-3.059-7.438c-2.029-2.041-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.006-7.388,3.047c-2.029,2.043-3.056,4.52-3.056,7.438c0,2.922,1.026,5.398,3.056,7.439c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,146.158,190.465,143.682,190.465,140.76L190.465,140.76z"/></g></svg>',more_plus:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="35 30 140 140"><g><path d="M137.215,102.045c0,3.498-2.835,6.332-6.333,6.332H24.549c-3.498,0-6.334-2.834-6.334-6.332l0,0c0-3.498,2.836-6.333,6.334-6.333h106.333C134.38,95.711,137.215,98.547,137.215,102.045L137.215,102.045z M77.715,161.545c-3.498,0-6.333-2.836-6.333-6.334V48.878c0-3.498,2.836-6.333,6.333-6.333l0,0c3.498,0,6.334,2.835,6.334,6.333v106.333C84.049,158.709,81.213,161.545,77.715,161.545L77.715,161.545z M190.465,63.32c0-2.919-1.015-5.396-3.059-7.428c-2.029-2.031-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.016-7.388,3.047c-2.029,2.032-3.056,4.498-3.056,7.386c0,2.889,1.026,5.354,3.056,7.385c2.032,2.032,4.499,3.059,7.388,3.059c2.887,0,5.354-1.026,7.383-3.059C189.45,68.632,190.465,66.177,190.465,63.32L190.465,63.32z M190.465,101.993c0-2.858-1.015-5.313-3.059-7.333c-2.029-2.042-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.005-7.388,3.047c-2.029,2.021-3.056,4.486-3.056,7.376c0,2.888,1.026,5.353,3.056,7.396c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,107.389,190.465,104.914,190.465,101.993L190.465,101.993z M190.465,140.76c0-2.918-1.015-5.395-3.059-7.438c-2.029-2.041-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.006-7.388,3.047c-2.029,2.043-3.056,4.52-3.056,7.438c0,2.922,1.026,5.398,3.056,7.439c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,146.158,190.465,143.682,190.465,140.76L190.465,140.76z"/></g></svg>',more_horizontal:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.76 3.58"><g><path d="M4.64,10.73a1.84,1.84,0,0,1,.65-.65,1.76,1.76,0,0,1,1.79,0A1.79,1.79,0,0,1,8,11.63a1.84,1.84,0,0,1-.25.9,1.69,1.69,0,0,1-.65.65,1.8,1.8,0,0,1-2.69-1.55A2.08,2.08,0,0,1,4.64,10.73Zm6.09,0a1.84,1.84,0,0,1,.65-.65,1.78,1.78,0,0,1,2.67,1.55,1.73,1.73,0,0,1-.24.9,1.84,1.84,0,0,1-.65.65,1.76,1.76,0,0,1-1.79,0,1.79,1.79,0,0,1-.64-2.44Zm6.08,0a1.69,1.69,0,0,1,.65-.65,1.76,1.76,0,0,1,1.79,0,1.79,1.79,0,0,1,.9,1.54,1.73,1.73,0,0,1-.24.9,1.84,1.84,0,0,1-.65.65,1.8,1.8,0,0,1-2.69-1.55A2,2,0,0,1,16.81,10.73Z" transform="translate(-4.39 -9.84)"/></g></svg>',more_vertical:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3.94 15.75"><g><path d="M12.28,7.69a1.92,1.92,0,0,1-1.39-.58,2,2,0,0,1-.58-1.39,1.92,1.92,0,0,1,.58-1.39,2,2,0,0,1,1.39-.58,1.92,1.92,0,0,1,1.39.58,2,2,0,0,1,.58,1.39,1.92,1.92,0,0,1-.58,1.39,2,2,0,0,1-1.39.58Zm0,2a1.92,1.92,0,0,1,1.39.58,2,2,0,0,1,.58,1.39A1.92,1.92,0,0,1,13.67,13a2,2,0,0,1-1.39.58A1.92,1.92,0,0,1,10.89,13a2,2,0,0,1-.58-1.39,2,2,0,0,1,2-2Zm0,5.9a1.92,1.92,0,0,1,1.39.58,2,2,0,0,1,.58,1.39,1.92,1.92,0,0,1-.58,1.39,2,2,0,0,1-1.39.58,1.92,1.92,0,0,1-1.39-.58,2,2,0,0,1-.58-1.39,1.92,1.92,0,0,1,.58-1.39,1.94,1.94,0,0,1,1.39-.58Z" transform="translate(-10.31 -3.75)"/></g></svg>',attachment:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8.38 15.68"><g><path d="M15.23,6h1v9.78a3.88,3.88,0,0,1-1.31,2.45,4,4,0,0,1-6.57-2.45V7A3,3,0,0,1,9.2,4.89a3,3,0,0,1,5,2.09v8.31a1.92,1.92,0,0,1-.58,1.39,2,2,0,0,1-1.39.58,1.92,1.92,0,0,1-1.39-.58,2,2,0,0,1-.58-1.39V8h1v7.32a1,1,0,0,0,.29.69,1,1,0,0,0,.69.28A.9.9,0,0,0,13,16a1,1,0,0,0,.29-.69V7a1.92,1.92,0,0,0-.58-1.39A2,2,0,0,0,11.27,5a1.92,1.92,0,0,0-1.39.58A2,2,0,0,0,9.33,7v8.31a3,3,0,1,0,5.9,0V6Z" transform="translate(-8.08 -3.78)"/></g></svg>',map:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11.7 15.62"><g><path d="M12.05,12.42a2.93,2.93,0,1,1,2.07-5A2.88,2.88,0,0,1,15,9.49a3,3,0,0,1-.86,2.07,2.89,2.89,0,0,1-2.07.86Zm0-5.36a2.43,2.43,0,0,0-1.72,4.16,2.48,2.48,0,0,0,1.72.72,2.44,2.44,0,0,0,0-4.88Zm0-3.3A5.84,5.84,0,0,1,17.9,9.62a9.94,9.94,0,0,1-1.73,5A33.59,33.59,0,0,1,12.84,19a1.52,1.52,0,0,1-.23.2,1,1,0,0,1-.55.2h0a1,1,0,0,1-.55-.2,1.52,1.52,0,0,1-.23-.2,33.59,33.59,0,0,1-3.33-4.32,9.93,9.93,0,0,1-1.72-5,5.84,5.84,0,0,1,5.85-5.86ZM12,18.34l.08.05.06-.06a35.58,35.58,0,0,0,3.06-3.93,9.35,9.35,0,0,0,1.74-4.77,4.88,4.88,0,0,0-4.88-4.88A4.79,4.79,0,0,0,8.6,6.17,4.84,4.84,0,0,0,7.17,9.62,9.29,9.29,0,0,0,8.91,14.4,36,36,0,0,0,12,18.34Z" transform="translate(-6.2 -3.76)"/></g></svg>',magic_stick:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.73 15.75"><g><path d="M19.86,19.21a1,1,0,0,0,.28-.68,1,1,0,0,0-.28-.7L13,10.93a1,1,0,0,0-.7-.28,1,1,0,0,0-.68,1.65l6.9,6.9a1,1,0,0,0,.69.29.93.93,0,0,0,.69-.28ZM9.19,8.55a3,3,0,0,0,1.68,0,14.12,14.12,0,0,0,1.41-.32A11.26,11.26,0,0,0,10.8,7.06c-.56-.36-.86-.56-.91-.58S10,5.91,10,5.11s0-1.26-.15-1.37a4.35,4.35,0,0,0-1.19.71c-.53.4-.81.62-.87.68a9,9,0,0,0-2-.6,6.84,6.84,0,0,0-.76-.09s0,.27.08.77a8.6,8.6,0,0,0,.61,2q-.09.09-.69.87a3.59,3.59,0,0,0-.68,1.17c.12.17.57.23,1.36.15S7,9.26,7.15,9.23s.21.36.57.91a10.49,10.49,0,0,0,1.14,1.48c0-.1.14-.57.31-1.4a3,3,0,0,0,0-1.67Z" transform="translate(-4.41 -3.74)"/></g></svg>',empty_file:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12.78 15.75"><g><path d="M14.73,3.76,18.67,7.7v9.84a2,2,0,0,1-2,2H7.84a1.89,1.89,0,0,1-1.38-.58,2,2,0,0,1-.57-1.39V5.73a1.93,1.93,0,0,1,.57-1.38,2,2,0,0,1,1.38-.58h6.62l.26,0v0Zm2.95,4.92h-2a1.93,1.93,0,0,1-1.38-.57,2,2,0,0,1-.58-1.4V6.17c0-.36,0-.84,0-1.43H7.85a1,1,0,0,0-.7.29,1,1,0,0,0-.29.7V17.54a1,1,0,0,0,.29.69,1,1,0,0,0,.69.29h8.85a1,1,0,0,0,.71-.29.92.92,0,0,0,.28-.69Zm0-1L14.73,4.74v2A1,1,0,0,0,15,7.4a1,1,0,0,0,.69.29Z" transform="translate(-5.89 -3.76)"/></g></svg>'},E=n("P6u4"),S=n.n(E);const N={_d:null,_w:null,isIE:null,isIE_Edge:null,isOSX_IOS:null,_propertiesInit:function(){this._d||(this._d=document,this._w=window,this.isIE=navigator.userAgent.indexOf("Trident")>-1,this.isIE_Edge=navigator.userAgent.indexOf("Trident")>-1||navigator.appVersion.indexOf("Edge")>-1,this.isOSX_IOS=/(Mac|iPhone|iPod|iPad)/.test(navigator.platform))},_HTMLConvertor:function(e){const t={"&":"&"," ":" ","'":"'",'"':""","<":"<",">":">"};return e.replace(/&|\u00A0|'|"|<|>/g,(function(e){return"string"==typeof t[e]?t[e]:e}))},zeroWidthSpace:String.fromCharCode(8203),zeroWidthRegExp:new RegExp(String.fromCharCode(8203),"g"),onlyZeroWidthRegExp:new RegExp("^"+String.fromCharCode(8203)+"+$"),onlyZeroWidthSpace:function(e){return"string"!=typeof e&&(e=e.textContent),""===e||this.onlyZeroWidthRegExp.test(e)},getXMLHttpRequest:function(){if(!this._w.ActiveXObject)return this._w.XMLHttpRequest?new XMLHttpRequest:null;try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(e){try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(e){return null}}},createElement:function(e){return this._d.createElement(e)},createTextNode:function(e){return this._d.createTextNode(e||"")},HTMLEncoder:function(e){const t={"<":"$lt;",">":"$gt;"};return e.replace(/<|>/g,(function(e){return"string"==typeof t[e]?t[e]:e}))},HTMLDecoder:function(e){const t={"$lt;":"<","$gt;":">"};return e.replace(/\$lt;|\$gt;/g,(function(e){return"string"==typeof t[e]?t[e]:e}))},hasOwn:function(e,t){return this._hasOwn.call(e,t)},_hasOwn:Object.prototype.hasOwnProperty,getIncludePath:function(e,t){let n="";const i=[],l="js"===t?"script":"link",o="js"===t?"src":"href";let s="(?:";for(let t=0,n=e.length;t<n;t++)s+=e[t]+(t<n-1?"|":")");const a=new this._w.RegExp("(^|.*[\\/])"+s+"(\\.[^\\/]+)?."+t+"(?:\\?.*|;.*)?$","i"),r=new this._w.RegExp(".+\\."+t+"(?:\\?.*|;.*)?$","i");for(let e=this._d.getElementsByTagName(l),t=0;t<e.length;t++)r.test(e[t][o])&&i.push(e[t]);for(let e=0;e<i.length;e++){let t=i[e][o].match(a);if(t){n=t[0];break}}if(""===n&&(n=i.length>0?i[0][o]:""),-1===n.indexOf(":/")&&"//"!==n.slice(0,2)&&(n=0===n.indexOf("/")?location.href.match(/^.*?:\/\/[^\/]*/)[0]+n:location.href.match(/^[^\?]*\/(?:)/)[0]+n),!n)throw"[SUNEDITOR.util.getIncludePath.fail] The SUNEDITOR installation path could not be automatically detected. (name: +"+name+", extension: "+t+")";return n},getPageStyle:function(e){let t="";const n=(e||this._d).styleSheets;for(let e,i=0,l=n.length;i<l;i++){try{e=n[i].cssRules}catch(e){continue}for(let n=0,i=e.length;n<i;n++)t+=e[n].cssText}return t},getIframeDocument:function(e){let t=e.contentWindow||e.contentDocument;return t.document&&(t=t.document),t},getAttributesToString:function(e,t){if(!e.attributes)return"";const n=e.attributes;let i="";for(let e=0,l=n.length;e<l;e++)t&&t.indexOf(n[e].name)>-1||(i+=n[e].name+'="'+n[e].value+'" ');return i},getByteLength:function(e){const t=this._w.encodeURIComponent;let n,i;return this.isIE_Edge?(i=this._w.unescape(t(e.toString())).length,n=0,null!==t(e.toString()).match(/(%0A|%0D)/gi)&&(n=t(e.toString()).match(/(%0A|%0D)/gi).length),i+n):(i=new this._w.TextEncoder("utf-8").encode(e.toString()).length,n=0,null!==t(e.toString()).match(/(%0A|%0D)/gi)&&(n=t(e.toString()).match(/(%0A|%0D)/gi).length),i+n)},isWysiwygDiv:function(e){return e&&1===e.nodeType&&(this.hasClass(e,"se-wrapper-wysiwyg")||/^BODY$/i.test(e.nodeName))},isNonEditable:function(e){return e&&1===e.nodeType&&"false"===e.getAttribute("contenteditable")},isTextStyleElement:function(e){return e&&3!==e.nodeType&&/^(strong|span|font|b|var|i|em|u|ins|s|strike|del|sub|sup|mark|a|label|code)$/i.test(e.nodeName)},isFormatElement:function(e){return e&&1===e.nodeType&&(/^(P|DIV|H[1-6]|PRE|LI|TH|TD)$/i.test(e.nodeName)||this.hasClass(e,"(\\s|^)__se__format__replace_.+(\\s|$)|(\\s|^)__se__format__free_.+(\\s|$)"))&&!this.isComponent(e)&&!this.isWysiwygDiv(e)},isRangeFormatElement:function(e){return e&&1===e.nodeType&&(/^(BLOCKQUOTE|OL|UL|FIGCAPTION|TABLE|THEAD|TBODY|TR|TH|TD)$/i.test(e.nodeName)||this.hasClass(e,"(\\s|^)__se__format__range_.+(\\s|$)"))},isClosureRangeFormatElement:function(e){return e&&1===e.nodeType&&(/^(TH|TD)$/i.test(e.nodeName)||this.hasClass(e,"(\\s|^)__se__format__range__closure_.+(\\s|$)"))},isFreeFormatElement:function(e){return e&&1===e.nodeType&&(/^PRE$/i.test(e.nodeName)||this.hasClass(e,"(\\s|^)__se__format__free_.+(\\s|$)"))&&!this.isComponent(e)&&!this.isWysiwygDiv(e)},isClosureFreeFormatElement:function(e){return e&&1===e.nodeType&&this.hasClass(e,"(\\s|^)__se__format__free__closure_.+(\\s|$)")},isComponent:function(e){return e&&(/se-component/.test(e.className)||/^(TABLE|HR)$/.test(e.nodeName))},isMediaComponent:function(e){return e&&/se-component/.test(e.className)},isNotCheckingNode:function(e){return e&&/katex|__se__tag/.test(e.className)},getFormatElement:function(e,t){if(!e)return null;for(t||(t=function(){return!0});e;){if(this.isWysiwygDiv(e))return null;if(this.isRangeFormatElement(e)&&e.firstElementChild,this.isFormatElement(e)&&t(e))return e;e=e.parentNode}return null},getRangeFormatElement:function(e,t){if(!e)return null;for(t||(t=function(){return!0});e;){if(this.isWysiwygDiv(e))return null;if(this.isRangeFormatElement(e)&&!/^(THEAD|TBODY|TR)$/i.test(e.nodeName)&&t(e))return e;e=e.parentNode}return null},getFreeFormatElement:function(e,t){if(!e)return null;for(t||(t=function(){return!0});e;){if(this.isWysiwygDiv(e))return null;if(this.isFreeFormatElement(e)&&t(e))return e;e=e.parentNode}return null},getClosureFreeFormatElement:function(e,t){if(!e)return null;for(t||(t=function(){return!0});e;){if(this.isWysiwygDiv(e))return null;if(this.isClosureFreeFormatElement(e)&&t(e))return e;e=e.parentNode}return null},copyTagAttributes:function(e,t){t.style.cssText&&(e.style.cssText+=t.style.cssText);const n=t.classList;for(let t=0,i=n.length;t<i;t++)this.addClass(e,n[t]);e.style.cssText||e.removeAttribute("style"),e.className.trim()||e.removeAttribute("class")},copyFormatAttributes:function(e,t){(t=t.cloneNode(!1)).className=t.className.replace(/(\s|^)__se__format__[^\s]+/g,""),this.copyTagAttributes(e,t)},getArrayItem:function(e,t,n){if(!e||0===e.length)return null;t=t||function(){return!0};const i=[];for(let l,o=0,s=e.length;o<s;o++)if(l=e[o],t(l)){if(!n)return l;i.push(l)}return n?i:null},getArrayIndex:function(e,t){let n=-1;for(let i=0,l=e.length;i<l;i++)if(e[i]===t){n=i;break}return n},nextIdx:function(e,t){let n=this.getArrayIndex(e,t);return-1===n?-1:n+1},prevIdx:function(e,t){let n=this.getArrayIndex(e,t);return-1===n?-1:n-1},getPositionIndex:function(e){let t=0;for(;e=e.previousSibling;)t+=1;return t},getNodePath:function(e,t,n){const i=[];let l=!0;return this.getParentElement(e,function(e){if(e===t&&(l=!1),l&&!this.isWysiwygDiv(e)){if(n&&3===e.nodeType){let t=null,i=null;n.s=n.e=0;let l=e.previousSibling;for(;l&&3===l.nodeType;)i=l.textContent.replace(this.zeroWidthRegExp,""),n.s+=i.length,e.textContent=i+e.textContent,t=l,l=l.previousSibling,this.removeItem(t);let o=e.nextSibling;for(;o&&3===o.nodeType;)i=o.textContent.replace(this.zeroWidthRegExp,""),n.e+=i.length,e.textContent+=i,t=o,o=o.nextSibling,this.removeItem(t)}i.push(e)}return!1}.bind(this)),i.map(this.getPositionIndex).reverse()},getNodeFromPath:function(e,t){let n,i=t;for(let t=0,l=e.length;t<l&&(n=i.childNodes,0!==n.length);t++)i=n.length<=e[t]?n[n.length-1]:n[e[t]];return i},isSameAttributes:function(e,t){if(3===e.nodeType&&3===t.nodeType)return!0;if(3===e.nodeType||3===t.nodeType)return!1;const n=e.style,i=t.style;let l=0;for(let e=0,t=n.length;e<t;e++)n[n[e]]===i[n[e]]&&l++;const o=e.classList,s=t.classList,a=this._w.RegExp;let r=0;for(let e=0,t=o.length;e<t;e++)a("(s|^)"+o[e]+"(s|$)").test(s.value)&&r++;return l===i.length&&l===n.length&&r===s.length&&r===o.length},isList:function(e){return e&&/^(OL|UL)$/i.test("string"==typeof e?e:e.nodeName)},isListCell:function(e){return e&&/^LI$/i.test("string"==typeof e?e:e.nodeName)},isTable:function(e){return e&&/^(TABLE|THEAD|TBODY|TR|TH|TD)$/i.test("string"==typeof e?e:e.nodeName)},isCell:function(e){return e&&/^(TD|TH)$/i.test("string"==typeof e?e:e.nodeName)},isBreak:function(e){return e&&/^BR$/i.test("string"==typeof e?e:e.nodeName)},isAnchor:function(e){return e&&/^A$/i.test("string"==typeof e?e:e.nodeName)},isMedia:function(e){return e&&/^(IMG|IFRAME|AUDIO|VIDEO|CANVAS)$/i.test("string"==typeof e?e:e.nodeName)},isNumber:function(e){return!!e&&/^-?\d+(\.\d+)?$/.test(e+"")},getNumber:function(e,t){if(!e)return 0;let n=(e+"").match(/-?\d+(\.\d+)?/);return n&&n[0]?(n=n[0],t<0?1*n:0===t?this._w.Math.round(1*n):1*(1*n).toFixed(t)):0},getListChildren:function(e,t){const n=[];return e&&e.children&&0!==e.children.length?(t=t||function(){return!0},function i(l){e!==l&&t(l)&&n.push(l);for(let e=0,t=l.children.length;e<t;e++)i(l.children[e])}(e),n):n},getListChildNodes:function(e,t){const n=[];return e&&0!==e.childNodes.length?(t=t||function(){return!0},function i(l){e!==l&&t(l)&&n.push(l);for(let e=0,t=l.childNodes.length;e<t;e++)i(l.childNodes[e])}(e),n):n},getElementDepth:function(e){if(!e||this.isWysiwygDiv(e))return-1;let t=0;for(e=e.parentNode;e&&!this.isWysiwygDiv(e);)t+=1,e=e.parentNode;return t},compareElements:function(e,t){let n=e,i=t;for(;n&&i&&n.parentNode!==i.parentNode;)n=n.parentNode,i=i.parentNode;if(!n||!i)return{ancestor:null,a:e,b:t,result:0};const l=n.parentNode.childNodes,o=this.getArrayIndex(l,n),s=this.getArrayIndex(l,i);return{ancestor:n.parentNode,a:n,b:i,result:o>s?1:o<s?-1:0}},getParentElement:function(e,t){let n;if("function"==typeof t)n=t;else{let e;/^\./.test(t)?(e="className",t=t.split(".")[1]):/^#/.test(t)?(e="id",t="^"+t.split("#")[1]+"$"):/^:/.test(t)?(e="name",t="^"+t.split(":")[1]+"$"):(e="nodeName",t="^"+t+"$");const i=new this._w.RegExp(t,"i");n=function(t){return i.test(t[e])}}for(;e&&!n(e);){if(this.isWysiwygDiv(e))return null;e=e.parentNode}return e},getChildElement:function(e,t,n){let i;if("function"==typeof t)i=t;else{let e;/^\./.test(t)?(e="className",t=t.split(".")[1]):/^#/.test(t)?(e="id",t="^"+t.split("#")[1]+"$"):/^:/.test(t)?(e="name",t="^"+t.split(":")[1]+"$"):(e="nodeName",t="^"+("text"===t?"#"+t:t)+"$");const n=new this._w.RegExp(t,"i");i=function(t){return n.test(t[e])}}const l=this.getListChildNodes(e,(function(e){return i(e)}));return l[n?l.length-1:0]},getEdgeChildNodes:function(e,t){if(e){for(t||(t=e);e&&1===e.nodeType&&e.childNodes.length>0&&!this.isBreak(e);)e=e.firstChild;for(;t&&1===t.nodeType&&t.childNodes.length>0&&!this.isBreak(t);)t=t.lastChild;return{sc:e,ec:t||e}}},getOffset:function(e,t){let n=0,i=0,l=3===e.nodeType?e.parentElement:e;const o=this.getParentElement(e,this.isWysiwygDiv.bind(this));for(;l&&!this.hasClass(l,"se-container")&&l!==o;)n+=l.offsetLeft,i+=l.offsetTop,l=l.offsetParent;const s=t&&/iframe/i.test(t.nodeName);return{left:n+(s?t.parentElement.offsetLeft:0),top:i-o.scrollTop+(s?t.parentElement.offsetTop:0)}},getOverlapRangeAtIndex:function(e,t,n,i){if(e<=i?t<n:t>n)return 0;const l=(e>n?e:n)-(t<i?t:i);return(l<0?-1*l:l)+1},changeTxt:function(e,t){e&&t&&(e.textContent=t)},changeElement:function(e,t){if("string"==typeof t)if(e.outerHTML)e.outerHTML=t;else{const n=this.createElement("DIV");n.innerHTML=t,t=n.firstChild,e.parentNode.replaceChild(t,e)}else 1===t.nodeType&&e.parentNode.replaceChild(t,e)},setStyle:function(e,t,n){e.style[t]=n,n||e.style.cssText||e.removeAttribute("style")},hasClass:function(e,t){if(e)return new this._w.RegExp(t).test(e.className)},addClass:function(e,t){if(!e)return;new this._w.RegExp("(\\s|^)"+t+"(\\s|$)").test(e.className)||(e.className+=(e.className.length>0?" ":"")+t)},removeClass:function(e,t){if(!e)return;const n=new this._w.RegExp("(\\s|^)"+t+"(\\s|$)");e.className=e.className.replace(n," ").trim(),e.className.trim()||e.removeAttribute("class")},toggleClass:function(e,t){if(!e)return;const n=new this._w.RegExp("(\\s|^)"+t+"(\\s|$)");n.test(e.className)?e.className=e.className.replace(n," ").trim():e.className+=" "+t,e.className.trim()||e.removeAttribute("class")},setDisabledButtons:function(e,t){for(let n=0,i=t.length;n<i;n++)t[n].disabled=e},removeItem:function(e){if(e)try{e.remove()}catch(t){e.parentNode&&e.parentNode.removeChild(e)}},removeItemAllParents:function(e,t,n){if(!e)return null;let i=null;return t||(t=function(e){if(e===n||this.isComponent(e))return!1;const t=e.textContent.trim();return 0===t.length||/^(\n|\u200B)+$/.test(t)}.bind(this)),function e(n){if(!N.isWysiwygDiv(n)){const l=n.parentNode;l&&t(n)&&(i={sc:n.previousElementSibling,ec:n.nextElementSibling},N.removeItem(n),e(l))}}(e),i},detachNestedList:function(e,t){const n=this._deleteNestedList(e);let i,l,o;if(n){i=n.cloneNode(!1),l=n.childNodes;const t=this.getPositionIndex(e);for(;l[t];)i.appendChild(l[t])}else i=e;if(t)o=this.getListChildren(i,function(e){return this.isListCell(e)&&!e.previousElementSibling}.bind(this));else{const t=this.getElementDepth(e)+2;o=this.getListChildren(e,function(e){return this.isListCell(e)&&!e.previousElementSibling&&this.getElementDepth(e)===t}.bind(this))}for(let e=0,t=o.length;e<t;e++)this._deleteNestedList(o[e]);return n&&(n.parentNode.insertBefore(i,n.nextSibling),l&&0===l.length&&this.removeItem(n)),i===e?i.parentNode:i},_deleteNestedList:function(e){const t=e.parentNode;let n,i,l,o,s,a=t,r=a.parentNode;for(;this.isListCell(r);){for(o=this.getPositionIndex(e),n=r.nextElementSibling,i=r.parentNode,l=a;l;){if(a=a.nextSibling,this.isList(l)){for(s=l.childNodes;s[o];)i.insertBefore(s[o],n);0===s.length&&this.removeItem(l)}else i.appendChild(l);l=a}a=i,r=i.parentNode}return 0===t.children.length&&this.removeItem(t),i},splitElement:function(e,t,n){const i=e.parentNode;let l,o,s,a=0,r=!0;if((!n||n<0)&&(n=0),3===e.nodeType){if(a=this.getPositionIndex(e),t>=0){e.splitText(t);const n=this.getNodeFromPath([a+1],i);this.onlyZeroWidthSpace(n)&&(n.data=this.zeroWidthSpace)}}else 1===e.nodeType&&(e.previousSibling?e=e.previousSibling:this.getElementDepth(e)===n&&(r=!1));let c=e;for(;this.getElementDepth(c)>n;)for(a=this.getPositionIndex(c)+1,c=c.parentNode,s=l,l=c.cloneNode(!1),o=c.childNodes,s&&(this.isListCell(l)&&this.isList(s)&&s.firstElementChild?(l.innerHTML=s.firstElementChild.innerHTML,N.removeItem(s.firstElementChild),s.children.length>0&&l.appendChild(s)):l.appendChild(s));o[a];)l.appendChild(o[a]);c.childNodes.length<=1&&(!c.firstChild||0===c.firstChild.textContent.length)&&(c.innerHTML="<br>");const d=c.parentNode;return r&&(c=c.nextSibling),l?(this.mergeSameTags(l,null,!1),this.mergeNestedTags(l,function(e){return this.isList(e)}.bind(this)),l.childNodes.length>0?d.insertBefore(l,c):l=c,0===i.childNodes.length&&this.removeItem(i),l):c},mergeSameTags:function(e,t,n){const i=this,l=t?t.length:0;let o=null;return l&&(o=this._w.Array.apply(null,new this._w.Array(l)).map(this._w.Number.prototype.valueOf,0)),function e(s,a,r){const c=s.childNodes;for(let d,u,h=0,g=c.length;h<g&&(d=c[h],u=c[h+1],d);h++)if(n&&i._isIgnoreNodeChange(d)||!n&&(i.isTable(d)||i.isListCell(d)||i.isFormatElement(d)&&!i.isFreeFormatElement(d)))(i.isTable(d)||i.isListCell(d))&&e(d,a+1,h);else{if(1===g&&s.nodeName===d.nodeName&&s.parentNode){if(l){let e,n,o,r,c;for(let u=0;u<l;u++)if(e=t[u],e&&e[a]===h){for(n=d,o=s,r=a,c=!0;r>=0;){if(i.getArrayIndex(o.childNodes,n)!==e[r]){c=!1;break}n=d.parentNode,o=n.parentNode,r--}c&&(e.splice(a,1),e[a]=h)}}i.copyTagAttributes(d,s),s.parentNode.insertBefore(d,s),i.removeItem(s)}if(!u){1===d.nodeType&&e(d,a+1,h);break}if(d.nodeName===u.nodeName&&i.isSameAttributes(d,u)&&d.href===u.href){const e=d.childNodes;let n=0;for(let t=0,i=e.length;t<i;t++)e[t].textContent.length>0&&n++;const s=d.lastChild,c=u.firstChild;let g=0;if(s&&c){const e=3===s.nodeType&&3===c.nodeType;g=s.textContent.length;let i=s.previousSibling;for(;i&&3===i.nodeType;)g+=i.textContent.length,i=i.previousSibling;if(n>0&&3===s.nodeType&&3===c.nodeType&&(s.textContent.length>0||c.textContent.length>0)&&n--,l){let i=null;for(let d=0;d<l;d++)if(i=t[d],i&&i[a]>h){if(a>0&&i[a-1]!==r)continue;i[a]-=1,i[a+1]>=0&&i[a]===h&&(i[a+1]+=n,e&&s&&3===s.nodeType&&c&&3===c.nodeType&&(o[d]+=g))}}}if(3===d.nodeType){if(g=d.textContent.length,d.textContent+=u.textContent,l){let e=null;for(let i=0;i<l;i++)if(e=t[i],e&&e[a]>h){if(a>0&&e[a-1]!==r)continue;e[a]-=1,e[a+1]>=0&&e[a]===h&&(e[a+1]+=n,o[i]+=g)}}}else d.innerHTML+=u.innerHTML;i.removeItem(u),h--}else 1===d.nodeType&&e(d,a+1,h)}}(e,0,0),o},mergeNestedTags:function(e,t){"string"==typeof t?t=function(e){return this.test(e.tagName)}.bind(new this._w.RegExp("^("+(t||".+")+")$","i")):"function"!=typeof t&&(t=function(){return!0}),function e(n){let i=n.children;if(1===i.length&&i[0].nodeName===n.nodeName&&t(n)){const e=i[0];for(i=e.children;i[0];)n.appendChild(i[0]);n.removeChild(e)}for(let t=0,i=n.children.length;t<i;t++)e(n.children[t])}(e)},removeEmptyNode:function(e,t){const n=this;t&&(t=n.getParentElement(t,(function(t){return e===t.parentElement}))),function i(l){if(n._notTextNode(l)||l===t||n.isNonEditable(l))return 0;if(l===e||!n.onlyZeroWidthSpace(l.textContent)||l.firstChild&&n.isBreak(l.firstChild)){const e=l.children;for(let t=0,l=e.length,o=0;t<l;t++)e[t+o]&&!n.isComponent(e[t+o])&&(o+=i(e[t+o]))}else if(l.parentNode)return l.parentNode.removeChild(l),-1;return 0}(e),0===e.childNodes.length&&(e.innerHTML="<br>")},htmlRemoveWhiteSpace:function(e){return e?e.trim().replace(/<\/?(?!strong|span|font|b|var|i|em|u|ins|s|strike|del|sub|sup|mark|a|label|code)[^>^<]+>\s+(?=<)/gi,(function(e){return e.trim()})):""},sortByDepth:function(e,t){const n=t?1:-1,i=-1*n;e.sort(function(e,t){return this.isListCell(e)&&this.isListCell(t)?(e=this.getElementDepth(e))>(t=this.getElementDepth(t))?n:e<t?i:0:0}.bind(this))},_isIgnoreNodeChange:function(e){return e&&3!==e.nodeType&&(this.isNonEditable(e)||!this.isTextStyleElement(e))},_isMaintainedNode:function(e){return e&&3!==e.nodeType&&/^(a|label|code)$/i.test("string"==typeof e?e:e.nodeName)},_isSizeNode:function(e){return e&&3!==e.nodeType&&this.isTextStyleElement(e)&&!!e.style.fontSize},_notTextNode:function(e){return e&&3!==e.nodeType&&(this.isComponent(e)||/^(br|input|select|canvas|img|iframe|audio|video)$/i.test("string"==typeof e?e:e.nodeName))},_disallowedTags:function(e){return/^(meta|script|link|style|[a-z]+\:[a-z]+)$/i.test(e.nodeName)},createTagsWhitelist:function(e){return new RegExp("<\\/?\\b(?!\\b"+e.replace(/\|/g,"\\b|\\b")+"\\b)[^>]*>","gi")},_consistencyCheckOfHTML:function(e,t){const n=[],i=[],l=[],o=[],s=this.getListChildNodes(e,function(s){if(1!==s.nodeType)return!1;if(!t.test(s.nodeName)&&0===s.childNodes.length&&this.isNotCheckingNode(s))return n.push(s),!1;const a=!this.getParentElement(s,this.isNotCheckingNode);if(!this.isTable(s)&&!this.isListCell(s)&&(this.isFormatElement(s)||this.isRangeFormatElement(s)||this.isTextStyleElement(s))&&0===s.childNodes.length&&a)return i.push(s),!1;if(this.isList(s.parentNode)&&!this.isList(s)&&!this.isListCell(s))return l.push(s),!1;if(this.isCell(s)){const e=s.firstElementChild;if(!this.isFormatElement(e)&&!this.isRangeFormatElement(e)&&!this.isComponent(e))return o.push(s),!1}return s.parentNode!==e&&(this.isFormatElement(s)||this.isComponent(s)||this.isList(s))&&!this.isRangeFormatElement(s.parentNode)&&!this.isListCell(s.parentNode)&&!this.getParentElement(s,this.isComponent)&&a}.bind(this));for(let e=0,t=n.length;e<t;e++)this.removeItem(n[e]);const a=[];for(let e,t,n=0,i=s.length;n<i;n++)e=s[n],t=e.parentNode,t&&t.parentNode&&(t.parentNode.insertBefore(e,t),a.push(t));for(let e,t=0,n=a.length;t<n;t++)e=a[t],this.onlyZeroWidthSpace(e.textContent.trim())&&this.removeItem(e);for(let e=0,t=i.length;e<t;e++)this.removeItem(i[e]);for(let e,t,n,i,o=0,s=l.length;o<s;o++){for(e=l[o],t=this.createElement("LI"),n=e.childNodes;n[0];)t.appendChild(n[0]);i=e.parentNode,i&&(i.insertBefore(t,e),this.removeItem(e))}for(let e,t,n=0,i=o.length;n<i;n++)e=o[n],t=this.createElement("DIV"),t.innerHTML=0===e.textContent.trim().length?"<br>":e.innerHTML,e.innerHTML=t.outerHTML},_setDefaultOptionStyle:function(e,t){let n="";e.height&&(n+="height:"+e.height+";"),e.minHeight&&(n+="min-height:"+e.minHeight+";"),e.maxHeight&&(n+="max-height:"+e.maxHeight+";"),e.position&&(n+="position:"+e.position+";"),e.width&&(n+="width:"+e.width+";"),e.minWidth&&(n+="min-width:"+e.minWidth+";"),e.maxWidth&&(n+="max-width:"+e.maxWidth+";");let i="",l="",o="";const s=(t=n+t).split(";");for(let t,n=0,a=s.length;n<a;n++)t=s[n].trim(),t&&(/^(min-|max-)?width\s*:/.test(t)?i+=t+";":/^(min-|max-)?height\s*:/.test(t)?(/^height/.test(t)&&"auto"===t.split(":")[1].trim()&&(e.height="auto"),l+=t+";"):o+=t+";");return{top:i,frame:l,editor:o}},_setIframeDocument:function(e,t){e.setAttribute("scrolling","auto"),e.contentDocument.head.innerHTML='<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1">'+this._setIframeCssTags(t),e.contentDocument.body.className=t._editableClass,e.contentDocument.body.setAttribute("contenteditable",!0)},_setIframeCssTags:function(e){const t=e.iframeCSSFileName,n=this._w.RegExp;let i="";for(let e,l=0,o=t.length;l<o;l++){if(e=[],/(^https?:\/\/)|(^data:text\/css,)/.test(t[l]))e.push(t[l]);else{const i=new n("(^|.*[\\/])"+t[l]+"(\\..+)?\\.css(?:\\?.*|;.*)?$","i");for(let t,n=document.getElementsByTagName("link"),l=0,o=n.length;l<o;l++)t=n[l].href.match(i),t&&e.push(t[0])}if(!e||0===e.length)throw'[SUNEDITOR.constructor.iframe.fail] The suneditor CSS files installation path could not be automatically detected. Please set the option property "iframeCSSFileName" before creating editor instances.';for(let t=0,n=e.length;t<n;t++)i+='<link href="'+e[t]+'" rel="stylesheet">'}return i+("auto"===e.height?"<style>\n/** Iframe height auto */\nbody{height: min-content; overflow: hidden;}\n</style>":"")}};var T=N,L={init:function(e,t){"object"!=typeof t&&(t={});const n=document;this._initOptions(e,t);const i=n.createElement("DIV");i.className="sun-editor"+(t.rtl?" se-rtl":""),e.id&&(i.id="suneditor_"+e.id);const l=n.createElement("DIV");l.className="se-container";const o=this._createToolBar(n,t.buttonList,t.plugins,t);o.element.style.visibility="hidden",o.pluginCallButtons.math&&this._checkKatexMath(t.katex);const s=n.createElement("DIV");s.className="se-arrow";const a=n.createElement("DIV");a.className="se-toolbar-sticky-dummy";const r=n.createElement("DIV");r.className="se-wrapper";const c=this._initElements(t,i,o.element,s),d=c.bottomBar,u=c.wysiwygFrame,h=c.placeholder;let g=c.codeView;const p=d.resizingBar,m=d.navigation,f=d.charWrapper,_=d.charCounter,b=n.createElement("DIV");b.className="se-loading-box sun-editor-common",b.innerHTML='<div class="se-loading-effect"></div>';const v=n.createElement("DIV");v.className="se-line-breaker",v.innerHTML='<button class="se-btn">'+t.icons.line_break+"</button>";const y=n.createElement("DIV");y.className+="se-line-breaker-component";const C=y.cloneNode(!0);y.innerHTML=C.innerHTML=t.icons.line_break;const w=n.createElement("DIV");w.className="se-resizing-back";const x=t.toolbarContainer;return x&&x.appendChild(o.element),r.appendChild(g),h&&r.appendChild(h),x||l.appendChild(o.element),l.appendChild(a),l.appendChild(r),l.appendChild(w),l.appendChild(b),l.appendChild(v),l.appendChild(y),l.appendChild(C),p&&l.appendChild(p),i.appendChild(l),g=this._checkCodeMirror(t,g),{constructed:{_top:i,_relative:l,_toolBar:o.element,_menuTray:o._menuTray,_editorArea:r,_wysiwygArea:u,_codeArea:g,_placeholder:h,_resizingBar:p,_navigation:m,_charWrapper:f,_charCounter:_,_loading:b,_lineBreaker:v,_lineBreaker_t:y,_lineBreaker_b:C,_resizeBack:w,_stickyDummy:a,_arrow:s},options:t,plugins:o.plugins,pluginCallButtons:o.pluginCallButtons,_responsiveButtons:o.responsiveButtons}},_checkCodeMirror:function(e,t){if(e.codeMirror){const n=[{mode:"htmlmixed",htmlMode:!0,lineNumbers:!0,lineWrapping:!0},e.codeMirror.options||{}].reduce((function(e,t){for(let n in t)T.hasOwn(t,n)&&(e[n]=t[n]);return e}),{});"auto"===e.height&&(n.viewportMargin=1/0,n.height="auto");const i=e.codeMirror.src.fromTextArea(t,n);i.display.wrapper.style.cssText=t.style.cssText,e.codeMirrorEditor=i,(t=i.display.wrapper).className+=" se-wrapper-code-mirror"}return t},_checkKatexMath:function(e){if(!e)throw Error('[SUNEDITOR.create.fail] To use the math button you need to add a "katex" object to the options.');const t=[{throwOnError:!1},e.options||{}].reduce((function(e,t){for(let n in t)T.hasOwn(t,n)&&(e[n]=t[n]);return e}),{});e.options=t},_setOptions:function(e,t,n,i){this._initOptions(t.element.originElement,e);const l=t.element,o=l.relative,s=l.editorArea,a=e.toolbarContainer&&e.toolbarContainer!==i.toolbarContainer,r=!!e.buttonList||e.mode!==i.mode||a,c=!!e.plugins,d=this._createToolBar(document,r?e.buttonList:i.buttonList,c?e.plugins:n,e);d.pluginCallButtons.math&&this._checkKatexMath(e.katex);const u=document.createElement("DIV");u.className="se-arrow",r&&(d.element.style.visibility="hidden",a?(e.toolbarContainer.appendChild(d.element),l.toolbar.parentElement.removeChild(l.toolbar)):l.toolbar.parentElement.replaceChild(d.element,l.toolbar),l.toolbar=d.element,l._menuTray=d._menuTray,l._arrow=u);const h=this._initElements(e,l.topArea,r?d.element:l.toolbar,u),g=h.bottomBar,p=h.wysiwygFrame,m=h.placeholder;let f=h.codeView;return l.resizingBar&&o.removeChild(l.resizingBar),g.resizingBar&&o.appendChild(g.resizingBar),s.innerHTML="",s.appendChild(f),m&&s.appendChild(m),f=this._checkCodeMirror(e,f),l.resizingBar=g.resizingBar,l.navigation=g.navigation,l.charWrapper=g.charWrapper,l.charCounter=g.charCounter,l.wysiwygFrame=p,l.code=f,l.placeholder=m,e.rtl?T.addClass(l.topArea,"se-rtl"):T.removeClass(l.topArea,"se-rtl"),{callButtons:r?d.pluginCallButtons:null,plugins:r||c?d.plugins:null,toolbar:d}},_initElements:function(e,t,n,i){t.style.cssText=e._editorStyles.top,/inline/i.test(e.mode)?(n.className+=" se-toolbar-inline",n.style.width=e.toolbarWidth):/balloon/i.test(e.mode)&&(n.className+=" se-toolbar-balloon",n.style.width=e.toolbarWidth,n.appendChild(i));const l=document.createElement(e.iframe?"IFRAME":"DIV");l.className="se-wrapper-inner se-wrapper-wysiwyg",e.iframe?(l.allowFullscreen=!0,l.frameBorder=0,l.style.cssText=e._editorStyles.frame):(l.setAttribute("contenteditable",!0),l.setAttribute("scrolling","auto"),l.className+=" "+e._editableClass,l.style.cssText=e._editorStyles.frame+e._editorStyles.editor);const o=document.createElement("TEXTAREA");o.className="se-wrapper-inner se-wrapper-code",o.style.cssText=e._editorStyles.frame,o.style.display="none","auto"===e.height&&(o.style.overflow="hidden");let s=null,a=null,r=null,c=null;if(e.resizingBar&&(s=document.createElement("DIV"),s.className="se-resizing-bar sun-editor-common",a=document.createElement("DIV"),a.className="se-navigation sun-editor-common",s.appendChild(a),e.charCounter)){if(r=document.createElement("DIV"),r.className="se-char-counter-wrapper",e.charCounterLabel){const t=document.createElement("SPAN");t.className="se-char-label",t.textContent=e.charCounterLabel,r.appendChild(t)}if(c=document.createElement("SPAN"),c.className="se-char-counter",c.textContent="0",r.appendChild(c),e.maxCharCount>0){const t=document.createElement("SPAN");t.textContent=" / "+e.maxCharCount,r.appendChild(t)}s.appendChild(r)}let d=null;return e.placeholder&&(d=document.createElement("SPAN"),d.className="se-placeholder",d.innerText=e.placeholder),{bottomBar:{resizingBar:s,navigation:a,charWrapper:r,charCounter:c},wysiwygFrame:l,codeView:o,placeholder:d}},_initOptions:function(e,t){t.lang=t.lang||S.a,t.defaultTag="string"==typeof t.defaultTag?t.defaultTag:"p",t.value="string"==typeof t.value?t.value:null,t.historyStackDelayTime="number"==typeof t.historyStackDelayTime?t.historyStackDelayTime:400,t._defaultTagsWhitelist="string"==typeof t._defaultTagsWhitelist?t._defaultTagsWhitelist:"br|p|div|pre|blockquote|h[1-6]|ol|ul|li|hr|figure|figcaption|img|iframe|audio|video|source|table|thead|tbody|tr|th|td|a|b|strong|var|i|em|u|ins|s|span|strike|del|sub|sup|code",t._editorTagsWhitelist=t._defaultTagsWhitelist+("string"==typeof t.addTagsWhitelist&&t.addTagsWhitelist.length>0?"|"+t.addTagsWhitelist:""),t.pasteTagsWhitelist="string"==typeof t.pasteTagsWhitelist?t.pasteTagsWhitelist:t._editorTagsWhitelist,t.attributesWhitelist=t.attributesWhitelist&&"object"==typeof t.attributesWhitelist?t.attributesWhitelist:null,t.mode=t.mode||"classic",t.rtl=!!t.rtl,t._editableClass="sun-editor-editable"+(t.rtl?" se-rtl":""),t.toolbarWidth=t.toolbarWidth?T.isNumber(t.toolbarWidth)?t.toolbarWidth+"px":t.toolbarWidth:"auto",t.toolbarContainer="string"==typeof t.toolbarContainer?document.querySelector(t.toolbarContainer):t.toolbarContainer,t.stickyToolbar=/balloon/i.test(t.mode)||t.toolbarContainer?-1:void 0===t.stickyToolbar?0:/^\d+/.test(t.stickyToolbar)?T.getNumber(t.stickyToolbar,0):-1,t.iframe=t.fullPage||t.iframe,t.fullPage=!!t.fullPage,t.iframeCSSFileName=t.iframe?"string"==typeof t.iframeCSSFileName?[t.iframeCSSFileName]:t.iframeCSSFileName||["suneditor"]:null,t.previewTemplate="string"==typeof t.previewTemplate?t.previewTemplate:null,t.codeMirror=t.codeMirror?t.codeMirror.src?t.codeMirror:{src:t.codeMirror}:null,t.katex=t.katex?t.katex.src?t.katex:{src:t.katex}:null,t.position="string"==typeof t.position?t.position:null,t.display=t.display||("none"!==e.style.display&&e.style.display?e.style.display:"block"),t.popupDisplay=t.popupDisplay||"full",t.resizingBar=void 0===t.resizingBar?!/inline|balloon/i.test(t.mode):t.resizingBar,t.showPathLabel=!!t.resizingBar&&("boolean"!=typeof t.showPathLabel||t.showPathLabel),t.charCounter=t.maxCharCount>0||"boolean"==typeof t.charCounter&&t.charCounter,t.charCounterType="string"==typeof t.charCounterType?t.charCounterType:"char",t.charCounterLabel="string"==typeof t.charCounterLabel?t.charCounterLabel.trim():null,t.maxCharCount=T.isNumber(t.maxCharCount)&&t.maxCharCount>-1?1*t.maxCharCount:null,t.width=t.width?T.isNumber(t.width)?t.width+"px":t.width:e.clientWidth?e.clientWidth+"px":"100%",t.minWidth=(T.isNumber(t.minWidth)?t.minWidth+"px":t.minWidth)||"",t.maxWidth=(T.isNumber(t.maxWidth)?t.maxWidth+"px":t.maxWidth)||"",t.height=t.height?T.isNumber(t.height)?t.height+"px":t.height:e.clientHeight?e.clientHeight+"px":"auto",t.minHeight=(T.isNumber(t.minHeight)?t.minHeight+"px":t.minHeight)||"",t.maxHeight=(T.isNumber(t.maxHeight)?t.maxHeight+"px":t.maxHeight)||"",t.defaultStyle="string"==typeof t.defaultStyle?t.defaultStyle:"",t.font=t.font?t.font:null,t.fontSize=t.fontSize?t.fontSize:null,t.formats=t.formats?t.formats:null,t.colorList=t.colorList?t.colorList:null,t.lineHeights=t.lineHeights?t.lineHeights:null,t.paragraphStyles=t.paragraphStyles?t.paragraphStyles:null,t.textStyles=t.textStyles?t.textStyles:null,t.fontSizeUnit="string"==typeof t.fontSizeUnit&&t.fontSizeUnit.trim()||"px",t.imageResizing=void 0===t.imageResizing||t.imageResizing,t.imageHeightShow=void 0===t.imageHeightShow||!!t.imageHeightShow,t.imageWidth=t.imageWidth?T.isNumber(t.imageWidth)?t.imageWidth+"px":t.imageWidth:"auto",t.imageHeight=t.imageHeight?T.isNumber(t.imageHeight)?t.imageHeight+"px":t.imageHeight:"auto",t.imageSizeOnlyPercentage=!!t.imageSizeOnlyPercentage,t._imageSizeUnit=t.imageSizeOnlyPercentage?"%":"px",t.imageRotation=void 0!==t.imageRotation?t.imageRotation:!(t.imageSizeOnlyPercentage||!t.imageHeightShow),t.imageFileInput=void 0===t.imageFileInput||t.imageFileInput,t.imageUrlInput=void 0===t.imageUrlInput||!t.imageFileInput||t.imageUrlInput,t.imageUploadHeader=t.imageUploadHeader||null,t.imageUploadUrl="string"==typeof t.imageUploadUrl?t.imageUploadUrl:null,t.imageUploadSizeLimit=/\d+/.test(t.imageUploadSizeLimit)?T.getNumber(t.imageUploadSizeLimit,0):null,t.imageMultipleFile=!!t.imageMultipleFile,t.imageAccept="string"!=typeof t.imageAccept||"*"===t.imageAccept.trim()?"image/*":t.imageAccept.trim()||"image/*",t.imageGalleryUrl="string"==typeof t.imageGalleryUrl?t.imageGalleryUrl:null,t.videoResizing=void 0===t.videoResizing||t.videoResizing,t.videoHeightShow=void 0===t.videoHeightShow||!!t.videoHeightShow,t.videoRatioShow=void 0===t.videoRatioShow||!!t.videoRatioShow,t.videoWidth=t.videoWidth&&T.getNumber(t.videoWidth,0)?T.isNumber(t.videoWidth)?t.videoWidth+"px":t.videoWidth:"",t.videoHeight=t.videoHeight&&T.getNumber(t.videoHeight,0)?T.isNumber(t.videoHeight)?t.videoHeight+"px":t.videoHeight:"",t.videoSizeOnlyPercentage=!!t.videoSizeOnlyPercentage,t._videoSizeUnit=t.videoSizeOnlyPercentage?"%":"px",t.videoRotation=void 0!==t.videoRotation?t.videoRotation:!(t.videoSizeOnlyPercentage||!t.videoHeightShow),t.videoRatio=T.getNumber(t.videoRatio,4)||.5625,t.videoRatioList=t.videoRatioList?t.videoRatioList:null,t.youtubeQuery=(t.youtubeQuery||"").replace("?",""),t.videoFileInput=!!t.videoFileInput,t.videoUrlInput=void 0===t.videoUrlInput||!t.videoFileInput||t.videoUrlInput,t.videoUploadHeader=t.videoUploadHeader||null,t.videoUploadUrl="string"==typeof t.videoUploadUrl?t.videoUploadUrl:null,t.videoUploadSizeLimit=/\d+/.test(t.videoUploadSizeLimit)?T.getNumber(t.videoUploadSizeLimit,0):null,t.videoMultipleFile=!!t.videoMultipleFile,t.videoTagAttrs=t.videoTagAttrs||null,t.videoIframeAttrs=t.videoIframeAttrs||null,t.videoAccept="string"!=typeof t.videoAccept||"*"===t.videoAccept.trim()?"video/*":t.videoAccept.trim()||"video/*",t.audioWidth=t.audioWidth?T.isNumber(t.audioWidth)?t.audioWidth+"px":t.audioWidth:"",t.audioHeight=t.audioHeight?T.isNumber(t.audioHeight)?t.audioHeight+"px":t.audioHeight:"",t.audioFileInput=!!t.audioFileInput,t.audioUrlInput=void 0===t.audioUrlInput||!t.audioFileInput||t.audioUrlInput,t.audioUploadHeader=t.audioUploadHeader||null,t.audioUploadUrl="string"==typeof t.audioUploadUrl?t.audioUploadUrl:null,t.audioUploadSizeLimit=/\d+/.test(t.audioUploadSizeLimit)?T.getNumber(t.audioUploadSizeLimit,0):null,t.audioMultipleFile=!!t.audioMultipleFile,t.audioTagAttrs=t.audioTagAttrs||null,t.audioAccept="string"!=typeof t.audioAccept||"*"===t.audioAccept.trim()?"audio/*":t.audioAccept.trim()||"audio/*",t.tableCellControllerPosition="string"==typeof t.tableCellControllerPosition?t.tableCellControllerPosition.toLowerCase():"cell",t.tabDisable=!!t.tabDisable,t.shortcutsDisable=Array.isArray(t.shortcutsDisable)&&t.shortcutsDisable.length>0?t.shortcutsDisable.map((function(e){return e.toLowerCase()})):[],t.shortcutsHint=void 0===t.shortcutsHint||!!t.shortcutsHint,t.callBackSave=t.callBackSave?t.callBackSave:null,t.templates=t.templates?t.templates:null,t.placeholder="string"==typeof t.placeholder?t.placeholder:null,t.linkProtocol="string"==typeof t.linkProtocol?t.linkProtocol:null,t.buttonList=t.buttonList?JSON.parse(JSON.stringify(t.buttonList)):[["undo","redo"],["bold","underline","italic","strike","subscript","superscript"],["removeFormat"],["outdent","indent"],["fullScreen","showBlocks","codeView"],["preview","print"]],t.rtl&&(t.buttonList=t.buttonList.reverse()),t.icons=t.icons&&"object"==typeof t.icons?[x,t.icons].reduce((function(e,t){for(let n in t)T.hasOwn(t,n)&&(e[n]=t[n]);return e}),{}):x,t.icons=t.rtl?[t.icons,t.icons.rtl].reduce((function(e,t){for(let n in t)T.hasOwn(t,n)&&(e[n]=t[n]);return e}),{}):t.icons,t._editorStyles=T._setDefaultOptionStyle(t,t.defaultStyle)},_defaultButtons:function(e){const t=e.icons,n=e.lang,i=T.isOSX_IOS?"⌘":"CTRL",l=T.isOSX_IOS?"⇧":"+SHIFT",o=e.shortcutsHint?e.shortcutsDisable:["bold","strike","underline","italic","undo","indent"],s=e.rtl?["[","]"]:["]","["];return{bold:["_se_command_bold",n.toolbar.bold+'<span class="se-shortcut">'+(o.indexOf("bold")>-1?"":i+'+<span class="se-shortcut-key">B</span>')+"</span>","STRONG","",t.bold],underline:["_se_command_underline",n.toolbar.underline+'<span class="se-shortcut">'+(o.indexOf("underline")>-1?"":i+'+<span class="se-shortcut-key">U</span>')+"</span>","U","",t.underline],italic:["_se_command_italic",n.toolbar.italic+'<span class="se-shortcut">'+(o.indexOf("italic")>-1?"":i+'+<span class="se-shortcut-key">I</span>')+"</span>","EM","",t.italic],strike:["_se_command_strike",n.toolbar.strike+'<span class="se-shortcut">'+(o.indexOf("strike")>-1?"":i+l+'+<span class="se-shortcut-key">S</span>')+"</span>","DEL","",t.strike],subscript:["_se_command_subscript",n.toolbar.subscript,"SUB","",t.subscript],superscript:["_se_command_superscript",n.toolbar.superscript,"SUP","",t.superscript],removeFormat:["",n.toolbar.removeFormat,"removeFormat","",t.erase],indent:["_se_command_indent",n.toolbar.indent+'<span class="se-shortcut">'+(o.indexOf("indent")>-1?"":i+'+<span class="se-shortcut-key">'+s[0]+"</span>")+"</span>","indent","",t.outdent],outdent:["_se_command_outdent",n.toolbar.outdent+'<span class="se-shortcut">'+(o.indexOf("indent")>-1?"":i+'+<span class="se-shortcut-key">'+s[1]+"</span>")+"</span>","outdent","",t.indent],fullScreen:["se-code-view-enabled se-resizing-enabled _se_command_fullScreen",n.toolbar.fullScreen,"fullScreen","",t.expansion],showBlocks:["_se_command_showBlocks",n.toolbar.showBlocks,"showBlocks","",t.show_blocks],codeView:["se-code-view-enabled se-resizing-enabled _se_command_codeView",n.toolbar.codeView,"codeView","",t.code_view],undo:["_se_command_undo se-resizing-enabled",n.toolbar.undo+'<span class="se-shortcut">'+(o.indexOf("undo")>-1?"":i+'+<span class="se-shortcut-key">Z</span>')+"</span>","undo","",t.undo],redo:["_se_command_redo se-resizing-enabled",n.toolbar.redo+'<span class="se-shortcut">'+(o.indexOf("undo")>-1?"":i+'+<span class="se-shortcut-key">Y</span> / '+i+l+'+<span class="se-shortcut-key">Z</span>')+"</span>","redo","",t.redo],preview:["se-resizing-enabled",n.toolbar.preview,"preview","",t.preview],print:["se-resizing-enabled",n.toolbar.print,"print","",t.print],save:["_se_command_save se-resizing-enabled",n.toolbar.save,"save","",t.save],blockquote:["",n.toolbar.tag_blockquote,"blockquote","command",t.blockquote],font:["se-btn-select se-btn-tool-font",n.toolbar.font,"font","submenu",'<span class="txt">'+n.toolbar.font+"</span>"+t.arrow_down],formatBlock:["se-btn-select se-btn-tool-format",n.toolbar.formats,"formatBlock","submenu",'<span class="txt">'+n.toolbar.formats+"</span>"+t.arrow_down],fontSize:["se-btn-select se-btn-tool-size",n.toolbar.fontSize,"fontSize","submenu",'<span class="txt">'+n.toolbar.fontSize+"</span>"+t.arrow_down],fontColor:["",n.toolbar.fontColor,"fontColor","submenu",t.font_color],hiliteColor:["",n.toolbar.hiliteColor,"hiliteColor","submenu",t.highlight_color],align:["se-btn-align",n.toolbar.align,"align","submenu",e.rtl?t.align_right:t.align_left],list:["",n.toolbar.list,"list","submenu",t.list_number],horizontalRule:["btn_line",n.toolbar.horizontalRule,"horizontalRule","submenu",t.horizontal_rule],table:["",n.toolbar.table,"table","submenu",t.table],lineHeight:["",n.toolbar.lineHeight,"lineHeight","submenu",t.line_height],template:["",n.toolbar.template,"template","submenu",t.template],paragraphStyle:["",n.toolbar.paragraphStyle,"paragraphStyle","submenu",t.paragraph_style],textStyle:["",n.toolbar.textStyle,"textStyle","submenu",t.text_style],link:["",n.toolbar.link,"link","dialog",t.link],image:["",n.toolbar.image,"image","dialog",t.image],video:["",n.toolbar.video,"video","dialog",t.video],audio:["",n.toolbar.audio,"audio","dialog",t.audio],math:["",n.toolbar.math,"math","dialog",t.math],imageGallery:["",n.toolbar.imageGallery,"imageGallery","fileBrowser",t.image_gallery]}},_createModuleGroup:function(){const e=T.createElement("DIV");e.className="se-btn-module se-btn-module-border";const t=T.createElement("UL");return t.className="se-menu-list",e.appendChild(t),{div:e,ul:t}},_createButton:function(e,t,n,i,l,o,s){const a=T.createElement("LI"),r=T.createElement("BUTTON");return r.setAttribute("type","button"),r.setAttribute("class","se-btn"+(e?" "+e:"")+" se-tooltip"),r.setAttribute("data-command",n),r.setAttribute("data-display",i),r.setAttribute("tabindex","-1"),l||(l='<span class="se-icon-text">!</span>'),/^default\./i.test(l)&&(l=s[l.replace(/^default\./i,"")]),/^text\./i.test(l)&&(l=l.replace(/^text\./i,""),r.className+=" se-btn-more-text"),l+='<span class="se-tooltip-inner"><span class="se-tooltip-text">'+(t||n)+"</span></span>",o&&r.setAttribute("disabled",!0),r.innerHTML=l,a.appendChild(r),{li:a,button:r}},_createToolBar:function(e,t,n,i){const l=e.createElement("DIV");l.className="se-toolbar-separator-vertical";const o=e.createElement("DIV");o.className="se-toolbar sun-editor-common";const s=e.createElement("DIV");s.className="se-btn-tray",o.appendChild(s);const a=i.icons,r=this._defaultButtons(i),c={},d=[],u={};if(n){const e=n.length?n:Object.keys(n).map((function(e){return n[e]}));for(let t,n=0,i=e.length;n<i;n++)t=e[n].default||e[n],u[t.name]=t}let h=null,g=null,p=null,m=null,f="",_=!1;const b=T.createElement("DIV");b.className="se-toolbar-more-layer";e:for(let n,i,o,v,y,C=0;C<t.length;C++)if(n=!1,y="",v=t[C],p=this._createModuleGroup(),"object"==typeof v){for(let e,l=0;l<v.length;l++){if(g=v[l],e=!1,/^\%\d+/.test(g)&&0===l){v[0]=g.replace(/[^\d]/g,""),d.push(v),t.splice(C--,1);continue e}if("object"==typeof g)"function"==typeof g.add?(f=g.name,h=r[f],u[f]=g):(f=g.name,h=[g.buttonClass,g.title,g.name,g.dataDisplay,g.innerHTML,g._disabled]);else{if(/^\-/.test(g)){y=g.substr(1),p.div.style.float=y;continue}if(/^\:/.test(g)){e=!0;const t=g.match(/^\:([^\-]+)\-([^\-]+)\-([^\-]+)/);o="__se__"+t[1].trim();h=["se-btn-more",t[2].trim(),o,"MORE",t[3].trim()]}else h=r[g];if(f=g,!h){const e=u[f];if(!e)throw Error("[SUNEDITOR.create.toolbar.fail] The button name of a plugin that does not exist. ["+f+"]");h=[e.buttonClass,e.title,e.name,e.display,e.innerHTML,e._disabled]}}m=this._createButton(h[0],h[1],h[2],h[3],h[4],h[5],a),(n?i:p.ul).appendChild(m.li),u[f]&&(c[f]=m.button),e&&(n=!0,i=T.createElement("DIV"),i.className="se-more-layer "+o,i.innerHTML='<div class="se-more-form"><ul class="se-menu-list"'+(y?' style="float: '+y+';"':"")+"></ul></div>",b.appendChild(i),i=i.firstElementChild.firstElementChild)}if(_){const e=l.cloneNode(!1);y&&(e.style.float=y),s.appendChild(e)}s.appendChild(p.div),_=!0}else if(/^\/$/.test(v)){const t=e.createElement("DIV");t.className="se-btn-module-enter",s.appendChild(t),_=!1}const v=s.lastElementChild.style.float;if(v){const e=l.cloneNode(!1);e.style.float=v,s.appendChild(e)}1===s.children.length&&T.removeClass(s.firstElementChild,"se-btn-module-border"),d.length>0&&d.unshift(t),b.children.length>0&&s.appendChild(b);const y=e.createElement("DIV");y.className="se-menu-tray",o.appendChild(y);const C=e.createElement("DIV");return C.className="se-toolbar-cover",o.appendChild(C),{element:o,plugins:u,pluginCallButtons:c,responsiveButtons:d,_menuTray:y,_buttonTray:s}}};var k=function(e,t,n){return{element:{originElement:e,topArea:t._top,relative:t._relative,toolbar:t._toolBar,_buttonTray:t._toolBar.querySelector(".se-btn-tray"),_menuTray:t._menuTray,resizingBar:t._resizingBar,navigation:t._navigation,charWrapper:t._charWrapper,charCounter:t._charCounter,editorArea:t._editorArea,wysiwygFrame:t._wysiwygArea,wysiwyg:t._wysiwygArea,code:t._codeArea,placeholder:t._placeholder,loading:t._loading,lineBreaker:t._lineBreaker,lineBreaker_t:t._lineBreaker_t,lineBreaker_b:t._lineBreaker_b,resizeBackground:t._resizeBack,_stickyDummy:t._stickyDummy,_arrow:t._arrow},tool:{cover:t._toolBar.querySelector(".se-toolbar-cover"),bold:t._toolBar.querySelector("._se_command_bold"),underline:t._toolBar.querySelector("._se_command_underline"),italic:t._toolBar.querySelector("._se_command_italic"),strike:t._toolBar.querySelector("._se_command_strike"),subscript:t._toolBar.querySelector("._se_command_subscript"),superscript:t._toolBar.querySelector("._se_command_superscript"),undo:t._toolBar.querySelector("._se_command_undo"),redo:t._toolBar.querySelector("._se_command_redo"),save:t._toolBar.querySelector("._se_command_save"),outdent:t._toolBar.querySelector("._se_command_outdent"),indent:t._toolBar.querySelector("._se_command_indent"),fullScreen:t._toolBar.querySelector("._se_command_fullScreen"),showBlocks:t._toolBar.querySelector("._se_command_showBlocks"),codeView:t._toolBar.querySelector("._se_command_codeView")},options:n,option:n}},B={name:"notice",add:function(e){const t=e.context;t.notice={};let n=e.util.createElement("DIV"),i=e.util.createElement("SPAN"),l=e.util.createElement("BUTTON");n.className="se-notice",l.className="close",l.setAttribute("aria-label","Close"),l.setAttribute("title",e.lang.dialogBox.close),l.innerHTML=e.icons.cancel,n.appendChild(i),n.appendChild(l),t.notice.modal=n,t.notice.message=i,l.addEventListener("click",this.onClick_cancel.bind(e)),t.element.editorArea.appendChild(n),n=null},onClick_cancel:function(e){e.preventDefault(),e.stopPropagation(),this.plugins.notice.close.call(this)},open:function(e){this.context.notice.message.textContent=e,this.context.notice.modal.style.display="block"},close:function(){this.context.notice.modal.style.display="none"}},A={init:function(e){return{create:function(t,n){return this.create(t,n,e)}.bind(this)}},create:function(e,t,n){T._propertiesInit(),"object"!=typeof t&&(t={}),n&&(t=[n,t].reduce((function(e,t){for(let n in t)if(T.hasOwn(t,n))if("plugins"===n&&t[n]&&e[n]){let i=e[n],l=t[n];i=i.length?i:Object.keys(i).map((function(e){return i[e]})),l=l.length?l:Object.keys(l).map((function(e){return l[e]})),e[n]=l.filter((function(e){return-1===i.indexOf(e)})).concat(i)}else e[n]=t[n];return e}),{}));const i="string"==typeof e?document.getElementById(e):e;if(!i){if("string"==typeof e)throw Error('[SUNEDITOR.create.fail] The element for that id was not found (ID:"'+e+'")');throw Error("[SUNEDITOR.create.fail] suneditor requires textarea's element or id value")}const l=L.init(i,t);if(l.constructed._top.id&&document.getElementById(l.constructed._top.id))throw Error('[SUNEDITOR.create.fail] The ID of the suneditor you are trying to create already exists (ID:"'+l.constructed._top.id+'")');return function(e,t,n,i,l,o){const s=e.element.originElement.ownerDocument||document,a=s.defaultView||window,r=T,c=l.icons,d={_d:s,_w:a,_parser:new a.DOMParser,_wd:null,_ww:null,_shadowRoot:null,util:r,functions:null,notice:B,icons:c,history:null,context:e,pluginCallButtons:t,plugins:n||{},initPlugins:{},_targetPlugins:{},_menuTray:{},lang:i,effectNode:null,submenu:null,container:null,_submenuName:"",_bindedSubmenuOff:null,_bindedContainerOff:null,submenuActiveButton:null,containerActiveButton:null,controllerArray:[],currentControllerName:"",currentControllerTarget:null,currentFileComponentInfo:null,codeViewDisabledButtons:null,resizingDisabledButtons:null,_moreLayerActiveButton:null,_htmlCheckWhitelistRegExp:null,_disallowedTextTagsRegExp:null,editorTagsWhitelistRegExp:null,pasteTagsWhitelistRegExp:null,hasFocus:!1,isDisabled:!1,_attributesWhitelistRegExp:null,_attributesTagsWhitelist:null,_bindControllersOff:null,_isInline:null,_isBalloon:null,_isBalloonAlways:null,_inlineToolbarAttr:{top:"",width:"",isShow:!1},_notHideToolbar:!1,_sticky:!1,_antiBlur:!1,_lineBreaker:null,_lineBreakerButton:null,_componentsInfoInit:!0,_componentsInfoReset:!1,activePlugins:null,managedTagsInfo:null,_charTypeHTML:!1,_fileInfoPluginsCheck:null,_fileInfoPluginsReset:null,_fileManager:{tags:null,regExp:null,queryString:null,pluginRegExp:null,pluginMap:null},commandMap:null,_styleCommandMap:null,_defaultCommand:{bold:"STRONG",underline:"U",italic:"EM",strike:"DEL",subscript:"SUB",superscript:"SUP"},_variable:{isCodeView:!1,isFullScreen:!1,innerHeight_fullScreen:0,resizeClientY:0,tabSize:4,codeIndent:4,minResizingSize:r.getNumber(e.element.wysiwygFrame.style.minHeight||"65",0),currentNodes:[],currentNodesMap:[],_range:null,_selectionNode:null,_originCssText:e.element.topArea.style.cssText,_bodyOverflow:"",_editorAreaOriginCssText:"",_wysiwygOriginCssText:"",_codeOriginCssText:"",_fullScreenAttrs:{sticky:!1,balloon:!1,inline:!1},_lineBreakComp:null,_lineBreakDir:""},callPlugin:function(e,n,i){if(i=i||t[e],!this.plugins[e])throw Error('[SUNEDITOR.core.callPlugin.fail] The called plugin does not exist or is in an invalid format. (pluginName:"'+e+'")');this.initPlugins[e]?"object"==typeof this._targetPlugins[e]&&i&&this.initMenuTarget(e,i,this._targetPlugins[e]):(this.plugins[e].add(this,i),this.initPlugins[e]=!0),this.plugins[e].active&&!this.commandMap[e]&&i&&(this.commandMap[e]=i,this.activePlugins.push(e)),"function"==typeof n&&n()},addModule:function(e){for(let t,n=0,i=e.length;n<i;n++)t=e[n].name,this.plugins[t]||(this.plugins[t]=e[n]),this.initPlugins[t]||(this.initPlugins[t]=!0,"function"==typeof this.plugins[t].add&&this.plugins[t].add(this))},initMenuTarget:function(t,n,i){n?(e.element._menuTray.appendChild(i),this._targetPlugins[t]=!0,this._menuTray[n.getAttribute("data-command")]=i):this._targetPlugins[t]=i},submenuOn:function(e){this._bindedSubmenuOff&&this._bindedSubmenuOff(),this._bindControllersOff&&this.controllersOff();const t=this._submenuName=e.getAttribute("data-command"),n=this.submenu=this._menuTray[t];this.submenuActiveButton=e,this._setMenuPosition(e,n),this._bindedSubmenuOff=this.submenuOff.bind(this),this.addDocEvent("mousedown",this._bindedSubmenuOff,!1),this.plugins[t].on&&this.plugins[t].on.call(this),this._antiBlur=!0},submenuOff:function(){this.removeDocEvent("mousedown",this._bindedSubmenuOff),this._bindedSubmenuOff=null,this.submenu&&(this._submenuName="",this.submenu.style.display="none",this.submenu=null,r.removeClass(this.submenuActiveButton,"on"),this.submenuActiveButton=null,this._notHideToolbar=!1),this._antiBlur=!1},containerOn:function(e){this._bindedContainerOff&&this._bindedContainerOff();const t=this._containerName=e.getAttribute("data-command"),n=this.container=this._menuTray[t];this.containerActiveButton=e,this._setMenuPosition(e,n),this._bindedContainerOff=this.containerOff.bind(this),this.addDocEvent("mousedown",this._bindedContainerOff,!1),this.plugins[t].on&&this.plugins[t].on.call(this),this._antiBlur=!0},containerOff:function(){this.removeDocEvent("mousedown",this._bindedContainerOff),this._bindedContainerOff=null,this.container&&(this._containerName="",this.container.style.display="none",this.container=null,r.removeClass(this.containerActiveButton,"on"),this.containerActiveButton=null,this._notHideToolbar=!1),this._antiBlur=!1},_setMenuPosition:function(t,n){n.style.visibility="hidden",n.style.display="block",n.style.height="",r.addClass(t,"on");const i=this.context.element.toolbar,o=i.offsetWidth,s=u._getEditorOffsets(e.element.toolbar),c=n.offsetWidth,d=t.parentElement.offsetLeft+3;if(l.rtl){const e=t.offsetWidth,i=c>e?c-e:0,l=i>0?0:e-c;n.style.left=d-i+l+"px",s.left>u._getEditorOffsets(n).left&&(n.style.left="0px")}else{const e=o<=c?0:o-(d+c);n.style.left=e<0?d+e+"px":d+"px"}let h=0,g=t;for(;g&&g!==i;)h+=g.offsetTop,g=g.offsetParent;const p=h;this._isBalloon?h+=i.offsetTop+t.offsetHeight:h-=t.offsetHeight;const m=s.top;let f=n.offsetHeight,_=e.element.topArea,b=0;for(;_;)b+=_.scrollTop,_=_.parentElement;const v=a.innerHeight-(m-b+p+t.parentElement.offsetHeight);if(v<f){let e=-1*(f-p+3);const i=m-b+e,l=f+(i<0?i:0);l>v?(n.style.height=l+"px",e=-1*(l-p+3)):(n.style.height=v+"px",e=p+t.parentElement.offsetHeight),n.style.top=e+"px"}else n.style.top=p+t.parentElement.offsetHeight+"px";n.style.visibility=""},controllersOn:function(){this._bindControllersOff&&this._bindControllersOff(),this.controllerArray=[];for(let e,t=0;t<arguments.length;t++)e=arguments[t],e&&("string"!=typeof e?"function"!=typeof e?r.hasClass(e,"se-controller")?(e.style&&(e.style.display="block"),this.controllerArray.push(e)):(this.currentControllerTarget=e,this.currentFileComponentInfo=this.getFileComponent(e)):this.controllerArray.push(e):this.currentControllerName=e);this._bindControllersOff=this.controllersOff.bind(this),this.addDocEvent("mousedown",this._bindControllersOff,!1),this.addDocEvent("keydown",this._bindControllersOff,!1),this._antiBlur=!0,"function"==typeof h.showController&&h.showController(this.currentControllerName,this.controllerArray,this)},controllersOff:function(t){if(this._fileManager.pluginRegExp.test(this.currentControllerName)&&t&&"keydown"===t.type&&27!==t.keyCode)return;if(e.element.lineBreaker_t.style.display=e.element.lineBreaker_b.style.display="none",this._variable._lineBreakComp=null,this.currentControllerName="",this.currentControllerTarget=null,this.currentFileComponentInfo=null,this.effectNode=null,!this._bindControllersOff)return;this.removeDocEvent("mousedown",this._bindControllersOff),this.removeDocEvent("keydown",this._bindControllersOff),this._bindControllersOff=null;const n=this.controllerArray.length;if(n>0){for(let e=0;e<n;e++)"function"==typeof this.controllerArray[e]?this.controllerArray[e]():this.controllerArray[e].style.display="none";this.controllerArray=[]}this._antiBlur=!1},setControllerPosition:function(t,n,i,o){l.rtl&&(o.left*=-1);const s=r.getOffset(n,e.element.wysiwygFrame);t.style.visibility="hidden",t.style.display="block";const a="top"===i?-(t.offsetHeight+2):n.offsetHeight+12;t.style.top=s.top+a+o.top+"px";const c=s.left-e.element.wysiwygFrame.scrollLeft+o.left,d=t.offsetWidth,u=n.offsetWidth;if(l.rtl){const n=d>u?d-u:0,i=n>0?0:u-d;t.style.left=c-n+i+"px",n>0&&(t.firstElementChild.style.left=(d-14<10+n?d-14:10+n)+"px");const l=e.element.wysiwygFrame.offsetLeft-t.offsetLeft;l>0&&(t.style.left="0px",t.firstElementChild.style.left=l+"px")}else{t.style.left=c+"px";const n=e.element.wysiwygFrame.offsetWidth-(t.offsetLeft+d);n<0?(t.style.left=t.offsetLeft+n+"px",t.firstElementChild.style.left=20-n+"px"):t.firstElementChild.style.left="20px"}t.style.visibility=""},eventStop:function(e){e.stopPropagation(),e.preventDefault()},execCommand:function(e,t,n){this._wd.execCommand(e,t,"formatBlock"===e?"<"+n+">":n),this.history.push(!0)},nativeFocus:function(){const t=r.getParentElement(this.getSelectionNode(),"figcaption");t?t.focus():e.element.wysiwyg.focus(),this._editorRange()},focus:function(){if("none"!==e.element.wysiwygFrame.style.display){if(l.iframe)this.nativeFocus();else try{const t=this.getRange();if(t.startContainer===t.endContainer&&r.isWysiwygDiv(t.startContainer)){const t=r.createElement(l.defaultTag),n=r.createElement("BR");t.appendChild(n),e.element.wysiwyg.appendChild(t),this.setRange(n,0,n,0)}else this.setRange(t.startContainer,t.startOffset,t.endContainer,t.endOffset)}catch(e){this.nativeFocus()}u._applyTagEffects(),this._isBalloon&&u._toggleToolbarBalloon()}},focusEdge:function(t){t||(t=e.element.wysiwyg.lastElementChild);const n=this.getFileComponent(t);n?this.selectComponent(n.target,n.pluginName):t?(t=r.getChildElement(t,(function(e){return 0===e.childNodes.length||3===e.nodeType}),!0))?this.setRange(t,t.textContent.length,t,t.textContent.length):this.nativeFocus():this.focus()},setRange:function(e,t,n,i){if(!e||!n)return;t>e.textContent.length&&(t=e.textContent.length),i>n.textContent.length&&(i=n.textContent.length);const o=this._wd.createRange();try{o.setStart(e,t),o.setEnd(n,i)}catch(e){return console.warn("[SUNEDITOR.core.focus.error] "+e),void this.nativeFocus()}const s=this.getSelection();return s.removeAllRanges&&s.removeAllRanges(),s.addRange(o),this._editorRange(),l.iframe&&this.nativeFocus(),o},removeRange:function(){this._variable._range=null,this._variable._selectionNode=null,this.getSelection().removeAllRanges();const e=this.commandMap,t=this.activePlugins;for(let i in e)r.hasOwn(e,i)&&(t.indexOf(i)>-1?n[i].active.call(this,null):e.OUTDENT&&/^OUTDENT$/i.test(i)?e.OUTDENT.setAttribute("disabled",!0):e.INDENT&&/^INDENT$/i.test(i)?e.INDENT.removeAttribute("disabled"):r.removeClass(e[i],"active"))},getRange:function(){const t=this._variable._range||this._createDefaultRange(),n=this.getSelection();if(t.collapsed===n.isCollapsed||!e.element.wysiwyg.contains(n.focusNode))return t;if(n.rangeCount>0)return this._variable._range=n.getRangeAt(0),this._variable._range;{const e=n.anchorNode,t=n.focusNode,i=n.anchorOffset,l=n.focusOffset,o=r.compareElements(e,t),s=o.ancestor&&(0===o.result?i<=l:o.result>1);return this.setRange(s?e:t,s?i:l,s?t:e,s?l:i)}},getRange_addLine:function(t,n){if(this._selectionVoid(t)){const i=e.element.wysiwyg,o=r.createElement(l.defaultTag);o.innerHTML="<br>",i.insertBefore(o,n&&n!==i?n.nextElementSibling:i.firstElementChild),this.setRange(o.firstElementChild,0,o.firstElementChild,1),t=this._variable._range}return t},getSelection:function(){return this._shadowRoot&&this._shadowRoot.getSelection?this._shadowRoot.getSelection():this._ww.getSelection()},getSelectionNode:function(){if(r.isWysiwygDiv(this._variable._selectionNode)&&this._editorRange(),!this._variable._selectionNode){const t=r.getChildElement(e.element.wysiwyg.firstChild,(function(e){return 0===e.childNodes.length||3===e.nodeType}),!1);if(t)return this._variable._selectionNode=t,t;this._editorRange()}return this._variable._selectionNode},_editorRange:function(){const e=this.getSelection();if(!e)return null;let t=null,n=null;t=e.rangeCount>0?e.getRangeAt(0):this._createDefaultRange(),this._variable._range=t,n=t.collapsed?t.commonAncestorContainer:e.extentNode||e.anchorNode,this._variable._selectionNode=n},_createDefaultRange:function(){const t=e.element.wysiwyg;t.focus();const n=this._wd.createRange();let i=t.firstElementChild;return i||(i=r.createElement(l.defaultTag),i.innerHTML="<br>",t.appendChild(i)),n.setStart(i,0),n.setEnd(i,0),n},_selectionVoid:function(e){const t=e.commonAncestorContainer;return r.isWysiwygDiv(e.startContainer)&&r.isWysiwygDiv(e.endContainer)||/FIGURE/i.test(t.nodeName)||this._fileManager.regExp.test(t.nodeName)||r.isMediaComponent(t)},_resetRangeToTextNode:function(){const t=this.getRange();if(this._selectionVoid(t))return!1;let n,i,o,s=t.startContainer,a=t.startOffset,c=t.endContainer,d=t.endOffset;if(r.isFormatElement(s)&&(s=s.childNodes[a]||s.lastChild,a=s.textContent.length),r.isFormatElement(c)&&(c=c.childNodes[d]||c.lastChild,d=c.textContent.length),n=r.isWysiwygDiv(s)?e.element.wysiwyg.firstChild:s,i=a,r.isBreak(n)||1===n.nodeType&&n.childNodes.length>0){const e=r.isBreak(n);if(!e){for(;n&&!r.isBreak(n)&&1===n.nodeType;)n=n.childNodes[i]||n.nextElementSibling||n.nextSibling,i=0;let e=r.getFormatElement(n,null);e===r.getRangeFormatElement(e,null)&&(e=r.createElement(r.getParentElement(n,r.isCell)?"DIV":l.defaultTag),n.parentNode.insertBefore(e,n),e.appendChild(n))}if(r.isBreak(n)){const t=r.createTextNode(r.zeroWidthSpace);n.parentNode.insertBefore(t,n),n=t,e&&s===c&&(c=n,d=1)}}if(s=n,a=i,n=r.isWysiwygDiv(c)?e.element.wysiwyg.lastChild:c,i=d,r.isBreak(n)||1===n.nodeType&&n.childNodes.length>0){const e=r.isBreak(n);if(!e){for(;n&&!r.isBreak(n)&&1===n.nodeType&&(o=n.childNodes,0!==o.length);)n=o[i>0?i-1:i]||!/FIGURE/i.test(o[0].nodeName)?o[0]:n.previousElementSibling||n.previousSibling||s,i=i>0?n.textContent.length:i;let e=r.getFormatElement(n,null);e===r.getRangeFormatElement(e,null)&&(e=r.createElement(r.isCell(e)?"DIV":l.defaultTag),n.parentNode.insertBefore(e,n),e.appendChild(n))}if(r.isBreak(n)){const t=r.createTextNode(r.zeroWidthSpace);n.parentNode.insertBefore(t,n),n=t,i=1,e&&!n.previousSibling&&r.removeItem(c)}}return c=n,d=i,this.setRange(s,a,c,d),!0},getSelectedElements:function(t){if(!this._resetRangeToTextNode())return[];let n=this.getRange();if(r.isWysiwygDiv(n.startContainer)){const t=e.element.wysiwyg.children;if(0===t.length)return[];this.setRange(t[0],0,t[t.length-1],t[t.length-1].textContent.trim().length),n=this.getRange()}const i=n.startContainer,l=n.endContainer,o=n.commonAncestorContainer,s=r.getListChildren(o,(function(e){return t?t(e):r.isFormatElement(e)}));if(r.isWysiwygDiv(o)||r.isRangeFormatElement(o)||s.unshift(r.getFormatElement(o,null)),i===l||1===s.length)return s;let a=r.getFormatElement(i,null),c=r.getFormatElement(l,null),d=null,u=null;const h=function(e){return!r.isTable(e)||/^TABLE$/i.test(e.nodeName)};let g=r.getRangeFormatElement(a,h),p=r.getRangeFormatElement(c,h);r.isTable(g)&&r.isListCell(g.parentNode)&&(g=g.parentNode),r.isTable(p)&&r.isListCell(p.parentNode)&&(p=p.parentNode);const m=g===p;for(let e,t=0,n=s.length;t<n;t++)if(e=s[t],a===e||!m&&e===g)d=t;else if(c===e||!m&&e===p){u=t;break}return null===d&&(d=0),null===u&&(u=s.length-1),s.slice(d,u+1)},getSelectedElementsAndComponents:function(e){const t=this.getRange().commonAncestorContainer,n=r.getParentElement(t,r.isComponent),i=r.isTable(t)?this.getSelectedElements(null):this.getSelectedElements(function(e){const t=this.getParentElement(e,this.isComponent);return this.isFormatElement(e)&&(!t||t===n)||this.isComponent(e)&&!this.getFormatElement(e)}.bind(r));if(e)for(let e=0,t=i.length;e<t;e++)for(let n=e-1;n>=0;n--)if(i[n].contains(i[e])){i.splice(e,1),e--,t--;break}return i},isEdgePoint:function(e,t){return 0===t||!e.nodeValue&&1===t||t===e.nodeValue.length},showLoading:function(){e.element.loading.style.display="block"},closeLoading:function(){e.element.loading.style.display="none"},appendFormatTag:function(e,t){const n=r.getFormatElement(this.getSelectionNode(),null),i=t?"string"==typeof t?t:t.nodeName:r.isFormatElement(n)&&!r.isFreeFormatElement(n)?n.nodeName:l.defaultTag,o=r.createElement(i);return o.innerHTML="<br>",(t&&"string"!=typeof t||!t&&r.isFormatElement(n))&&r.copyTagAttributes(o,t||n),r.isCell(e)?e.insertBefore(o,e.nextElementSibling):e.parentNode.insertBefore(o,e.nextElementSibling),o},insertComponent:function(e,t,n,i){if(n&&!this.checkCharCount(e,null))return null;const l=this.removeNode();this.getRange_addLine(this.getRange(),l.container);let o=null,s=this.getSelectionNode(),a=r.getFormatElement(s,null);if(r.isListCell(a))this.insertNode(e,s===a?null:l.container.nextSibling,!1),e.nextSibling||e.parentNode.appendChild(r.createElement("BR"));else{if(this.getRange().collapsed&&(3===l.container.nodeType||r.isBreak(l.container))){const e=r.getParentElement(l.container,function(e){return this.isRangeFormatElement(e)}.bind(r));o=r.splitElement(l.container,l.offset,e?r.getElementDepth(e)+1:0),o&&(a=o.previousSibling)}this.insertNode(e,a,!1),a&&r.onlyZeroWidthSpace(a)&&r.removeItem(a)}if(this.setRange(e,0,e,0),!i){const t=this.getFileComponent(e);t?this.selectComponent(t.target,t.pluginName):o&&(o=r.getEdgeChildNodes(o,null).sc||o,this.setRange(o,0,o,0))}return t||this.history.push(1),o||e},getFileComponent:function(e){if(!this._fileManager.queryString||!e)return null;let t,n;return(/^FIGURE$/i.test(e.nodeName)||/se-component/.test(e.className))&&(t=e.querySelector(this._fileManager.queryString)),!t&&e.nodeName&&this._fileManager.regExp.test(e.nodeName)&&(t=e),t&&(n=this._fileManager.pluginMap[t.nodeName.toLowerCase()],n)?{target:t,component:r.getParentElement(t,r.isComponent),pluginName:n}:null},selectComponent:function(e,t){this.hasFocus||this.focus();const n=this.plugins[t];n&&a.setTimeout(function(){"function"==typeof n.select&&this.callPlugin(t,n.select.bind(this,e),null),this._setComponentLineBreaker(e)}.bind(this))},_setComponentLineBreaker:function(t){this._lineBreaker.style.display="none";const n=r.getParentElement(t,r.isComponent),i=e.element.lineBreaker_t.style,l=e.element.lineBreaker_b.style,o="block"===this.context.resizing.resizeContainer.style.display?this.context.resizing.resizeContainer:t,s=r.isListCell(n.parentNode);let a,c,d;(s?n.previousSibling:r.isFormatElement(n.previousElementSibling))?i.display="none":(this._variable._lineBreakComp=n,c=e.element.wysiwyg.scrollTop,a=r.getOffset(t,e.element.wysiwygFrame).top+c,d=o.offsetWidth/2/2,i.top=a-c-12+"px",i.left=r.getOffset(o).left+d+"px",i.display="block"),(s?n.nextSibling:r.isFormatElement(n.nextElementSibling))?l.display="none":(a||(this._variable._lineBreakComp=n,c=e.element.wysiwyg.scrollTop,a=r.getOffset(t,e.element.wysiwygFrame).top+c,d=o.offsetWidth/2/2),l.top=a+o.offsetHeight-c-12+"px",l.left=r.getOffset(o).left+o.offsetWidth-d-24+"px",l.display="block")},insertNode:function(e,t,n){if(n&&!this.checkCharCount(e,null))return null;const i=r.getFreeFormatElement(this.getSelectionNode(),null),o=!i&&(r.isFormatElement(e)||r.isRangeFormatElement(e))||r.isComponent(e);if(!t&&o){const e=this.getRange();if(e.startOffset!==e.endOffset||e.startContainer!==e.endContainer){const e=this.removeNode();if(3===e.container.nodeType||r.isBreak(e.container)){const n=r.getParentElement(e.container,function(e){return this.isRangeFormatElement(e)||this.isListCell(e)}.bind(r));(t=r.splitElement(e.container,e.offset,n?r.getElementDepth(n)+1:0))&&(t=t.previousSibling)}}}const s=t||o?this.getRange():this.getRange_addLine(this.getRange(),null),a=s.commonAncestorContainer,c=s.startOffset,d=s.endOffset,u=s.startContainer===a&&r.isFormatElement(a),h=u?a.childNodes[c]:s.startContainer,g=u?a.childNodes[d]:s.endContainer;let p,m=null;if(t)p=t.parentNode,t=t.nextSibling,m=!0;else if(p=h,3===h.nodeType&&(p=h.parentNode),s.collapsed)if(3===a.nodeType)t=a.textContent.length>d?a.splitText(d):a.nextSibling;else if(r.isBreak(p))t=p,p=p.parentNode;else{let n=p.childNodes[c];const i=n&&3===n.nodeType&&r.onlyZeroWidthSpace(n)&&r.isBreak(n.nextSibling)?n.nextSibling:n;i?i.nextSibling?t=r.isBreak(i)&&!r.isBreak(e)?i:i.nextSibling:(p.removeChild(i),t=null):t=null}else{if(h===g){t=this.isEdgePoint(g,d)?g.nextSibling:g.splitText(d);let e=h;this.isEdgePoint(h,c)||(e=h.splitText(c)),p.removeChild(e),0===p.childNodes.length&&o&&(p.innerHTML="<br>")}else{const e=this.removeNode(),n=e.container,i=e.prevContainer;if(n&&0===n.childNodes.length&&o&&(r.isFormatElement(n)?n.innerHTML="<br>":r.isRangeFormatElement(n)&&(n.innerHTML="<"+l.defaultTag+"><br></"+l.defaultTag+">")),!o&&i)if(p=3===i.nodeType?i.parentNode:i,p.contains(n))for(t=n;t.parentNode===p;)t=t.parentNode;else t=null;else p=o?a:n,t=o?g:null;for(;t&&!r.isFormatElement(t)&&t.parentNode!==a;)t=t.parentNode}}try{if(r.isFormatElement(e)||r.isRangeFormatElement(e)||!r.isListCell(p)&&r.isComponent(e)){const e=p;if(r.isList(t))p=t,t=null;else if(r.isListCell(t))p=t.previousElementSibling||t;else if(!m&&!t){const e=this.removeNode(),n=3===e.container.nodeType?r.isListCell(r.getFormatElement(e.container,null))?e.container:r.getFormatElement(e.container,null)||e.container.parentNode:e.container,i=r.isWysiwygDiv(n)||r.isRangeFormatElement(n);p=i?n:n.parentNode,t=i?null:n.nextSibling}0===e.childNodes.length&&p!==e&&r.removeItem(e)}!o||i||r.isRangeFormatElement(p)||r.isListCell(p)||r.isWysiwygDiv(p)||(t=p.nextElementSibling,p=p.parentNode),p.insertBefore(e,p===t?p.lastChild:t)}catch(t){p.appendChild(e)}finally{if(i&&(r.isFormatElement(e)||r.isRangeFormatElement(e))&&(e=this._setIntoFreeFormat(e)),!r.isComponent(e)){let t=1;if(3===e.nodeType){const t=e.previousSibling,n=e.nextSibling,i=!t||1===t.nodeType||r.onlyZeroWidthSpace(t)?"":t.textContent,l=!n||1===n.nodeType||r.onlyZeroWidthSpace(n)?"":n.textContent;t&&i.length>0&&(e.textContent=i+e.textContent,r.removeItem(t)),n&&n.length>0&&(e.textContent+=l,r.removeItem(n));const o={container:e,startOffset:i.length,endOffset:e.textContent.length-l.length};return this.setRange(e,o.startOffset,e,o.endOffset),o}if(!r.isBreak(e)&&r.isFormatElement(p)){let n=null;e.previousSibling&&!r.isBreak(e.previousSibling)||(n=r.createTextNode(r.zeroWidthSpace),e.parentNode.insertBefore(n,e)),e.nextSibling&&!r.isBreak(e.nextSibling)||(n=r.createTextNode(r.zeroWidthSpace),e.parentNode.insertBefore(n,e.nextSibling)),r._isIgnoreNodeChange(e)&&(e=e.nextSibling,t=0)}this.setRange(e,t,e,t)}return this.history.push(!0),e}},_setIntoFreeFormat:function(e){const t=e.parentNode;let n,i;for(;r.isFormatElement(e)||r.isRangeFormatElement(e);){for(n=e.childNodes,i=null;n[0];)if(i=n[0],r.isFormatElement(i)||r.isRangeFormatElement(i)){if(this._setIntoFreeFormat(i),!e.parentNode)break;n=e.childNodes}else t.insertBefore(i,e);0===e.childNodes.length&&r.removeItem(e),e=r.createElement("BR"),t.insertBefore(e,i.nextSibling)}return e},removeNode:function(){this._resetRangeToTextNode();const t=this.getRange();let n,i=0,l=t.startContainer,o=t.endContainer;const s=t.startOffset,a=t.endOffset,c=3===t.commonAncestorContainer.nodeType&&t.commonAncestorContainer.parentNode===l.parentNode?l.parentNode:t.commonAncestorContainer;let d=null,u=null;const h=r.getListChildNodes(c,null);let g=r.getArrayIndex(h,l),p=r.getArrayIndex(h,o);if(h.length>0&&g>-1&&p>-1){for(let e=g+1,t=l;e>=0;e--)h[e]===t.parentNode&&h[e].firstChild===t&&0===s&&(g=e,t=t.parentNode);for(let e=p-1,t=o;e>g;e--)h[e]===t.parentNode&&1===h[e].nodeType&&(h.splice(e,1),t=t.parentNode,--p)}else{if(0===h.length){if(r.isFormatElement(c)||r.isRangeFormatElement(c)||r.isWysiwygDiv(c)||r.isBreak(c)||r.isMedia(c))return{container:c,offset:0};if(3===c.nodeType)return{container:c,offset:a};h.push(c),l=o=c}else if(l=o=h[0],r.isBreak(l)||r.onlyZeroWidthSpace(l))return{container:r.isMedia(c)?c:l,offset:0};g=p=0}function m(e){const t=r.getFormatElement(e,null);if(r.removeItem(e),r.isListCell(t)){const e=r.getArrayItem(t.children,r.isList,!1);if(e){const n=e.firstElementChild,i=n.childNodes;for(;i[0];)t.insertBefore(i[0],e);r.removeItemAllParents(n,null,null)}}}for(let e=g;e<=p;e++){const t=h[e];if(0===t.length||3===t.nodeType&&void 0===t.data)m(t);else if(t!==l)t!==o?m(t):(u=1===o.nodeType?r.createTextNode(o.textContent):r.createTextNode(o.substringData(a,o.length-a)),u.length>0?o.data=u.data:m(o));else if(1===l.nodeType?d=r.createTextNode(l.textContent):t===o?(d=r.createTextNode(l.substringData(0,s)+o.substringData(a,o.length-a)),i=s):d=r.createTextNode(l.substringData(0,s)),d.length>0?l.data=d.data:m(l),t===o)break}if(n=o&&o.parentNode?o:l&&l.parentNode?l:t.endContainer||t.startContainer,!r.isWysiwygDiv(n)){const t=r.removeItemAllParents(n,function(e){if(this.isComponent(e))return!1;const t=e.textContent;return 0===t.length||/^(\n|\u200B)+$/.test(t)}.bind(r),null);t&&(n=t.sc||t.ec||e.element.wysiwyg)}return this.setRange(n,i,n,i),this.history.push(!0),{container:n,offset:i,prevContainer:l&&l.parentNode?l:null}},applyRangeFormatElement:function(e){this.getRange_addLine(this.getRange(),null);const t=this.getSelectedElementsAndComponents(!1);if(!t||0===t.length)return;e:for(let e,n,i,l,o,s,a=0,c=t.length;a<c;a++)if(e=t[a],r.isListCell(e))if(n=e.lastElementChild,n&&r.isListCell(e.nextElementSibling)&&t.indexOf(e.nextElementSibling)>-1&&(l=n.lastElementChild,t.indexOf(l)>-1)){let e=null;for(;e=l.lastElementChild;)if(r.isList(e)){if(!(t.indexOf(e.lastElementChild)>-1))continue e;l=e.lastElementChild}i=n.firstElementChild,o=t.indexOf(i),s=t.indexOf(l),t.splice(o,s-o+1),c=t.length}else;let n,i,l,o=t[t.length-1];n=r.isRangeFormatElement(o)||r.isFormatElement(o)?o:r.getRangeFormatElement(o,null)||r.getFormatElement(o,null),r.isCell(n)?(i=null,l=n):(i=n.nextSibling,l=n.parentNode);let s=r.getElementDepth(n),a=null;const c=[],d=function(e,t,n){let i=null;if(e!==t&&!r.isTable(t)){if(t&&r.getElementDepth(e)===r.getElementDepth(t))return n;i=r.removeItemAllParents(t,null,e)}return i?i.ec:n};for(let n,o,u,h,g,p,m,f=0,_=t.length;f<_;f++)if(n=t[f],o=n.parentNode,o&&!e.contains(o))if(u=r.getElementDepth(n),r.isList(o)){if(null===a&&(p?(a=p,m=!0,p=null):a=o.cloneNode(!1)),c.push(n),g=t[f+1],f===_-1||g&&g.parentNode!==o){g&&n.contains(g.parentNode)&&(p=g.parentNode.cloneNode(!1));let t,f=o.parentNode;for(;r.isList(f);)t=r.createElement(f.nodeName),t.appendChild(a),a=t,f=f.parentNode;const _=this.detachRangeFormatElement(o,c,null,!0,!0);s>=u?(s=u,l=_.cc,i=d(l,o,_.ec),i&&(l=i.parentNode)):l===_.cc&&(i=_.ec),l!==_.cc&&(h=d(l,_.cc,h),i=void 0!==h?h:_.cc);for(let e=0,t=_.removeArray.length;e<t;e++)a.appendChild(_.removeArray[e]);m||e.appendChild(a),p&&_.removeArray[_.removeArray.length-1].appendChild(p),a=null,m=!1}}else s>=u&&(s=u,l=o,i=n.nextSibling),e.appendChild(n),l!==o&&(h=d(l,o),void 0!==h&&(i=h));if(this.effectNode=null,r.mergeSameTags(e,null,!1),r.mergeNestedTags(e,function(e){return this.isList(e)}.bind(r)),i&&r.getElementDepth(i)>0&&(r.isList(i.parentNode)||r.isList(i.parentNode.parentNode))){const t=r.getParentElement(i,function(e){return this.isRangeFormatElement(e)&&!this.isList(e)}.bind(r)),n=r.splitElement(i,null,t?r.getElementDepth(t)+1:0);n.parentNode.insertBefore(e,n)}else l.insertBefore(e,i),d(e,i);const u=r.getEdgeChildNodes(e.firstElementChild,e.lastElementChild);t.length>1?this.setRange(u.sc,0,u.ec,u.ec.textContent.length):this.setRange(u.ec,u.ec.textContent.length,u.ec,u.ec.textContent.length),this.history.push(!1)},detachRangeFormatElement:function(e,t,n,i,o){const s=this.getRange(),a=s.startOffset,c=s.endOffset;let d=r.getListChildNodes(e,(function(t){return t.parentNode===e})),u=e.parentNode,h=null,g=null,p=e.cloneNode(!1);const m=[],f=r.isList(n);let _=!1,b=!1,v=!1;function y(t,n,i,l){if(r.onlyZeroWidthSpace(n)&&(n.innerHTML=r.zeroWidthSpace),3===n.nodeType)return t.insertBefore(n,i),n;const o=(v?n:l).childNodes;let s=n.cloneNode(!1),a=null,c=null;for(;o[0];)c=o[0],!r._notTextNode(c)||r.isBreak(c)||r.isListCell(s)?s.appendChild(c):(s.childNodes.length>0&&(a||(a=s),t.insertBefore(s,i),s=n.cloneNode(!1)),t.insertBefore(c,i),a||(a=c));if(s.childNodes.length>0){if(r.isListCell(t)&&r.isListCell(s)&&r.isList(i))if(f){for(a=i;i;)s.appendChild(i),i=i.nextSibling;t.parentNode.insertBefore(s,t.nextElementSibling)}else{const t=l.nextElementSibling,n=r.detachNestedList(l,!1);if(e!==n||t!==l.nextElementSibling){const t=s.childNodes;for(;t[0];)l.appendChild(t[0]);e=n,b=!0}}else t.insertBefore(s,i);a||(a=s)}return a}for(let o,s,a,c=0,C=d.length;c<C;c++)if(o=d[c],3!==o.nodeType||!r.isList(p))if(v=!1,i&&0===c&&(h=t&&t.length!==C&&t[0]!==o?p:e.previousSibling),t&&(s=t.indexOf(o)),t&&-1===s)p||(p=e.cloneNode(!1)),p.appendChild(o);else{if(t&&(a=t[s+1]),p&&p.children.length>0&&(u.insertBefore(p,e),p=null),!f&&r.isListCell(o))if(a&&r.getElementDepth(o)!==r.getElementDepth(a)&&(r.isListCell(u)||r.getArrayItem(o.children,r.isList,!1))){const t=o.nextElementSibling,n=r.detachNestedList(o,!1);e===n&&t===o.nextElementSibling||(e=n,b=!0)}else{const t=o;o=r.createElement(i?t.nodeName:r.isList(e.parentNode)||r.isListCell(e.parentNode)?"LI":r.isCell(e.parentNode)?"DIV":l.defaultTag);const n=r.isListCell(o),s=t.childNodes;for(;s[0]&&(!r.isList(s[0])||n);)o.appendChild(s[0]);r.copyFormatAttributes(o,t),v=!0}else o=o.cloneNode(!1);if(!b&&(i?(m.push(o),r.removeItem(d[c])):(n?(_||(u.insertBefore(n,e),_=!0),o=y(n,o,null,d[c])):o=y(u,o,e,d[c]),b||(t?(g=o,h||(h=o)):h||(h=g=o))),b)){b=v=!1,d=r.getListChildNodes(e,(function(t){return t.parentNode===e})),p=e.cloneNode(!1),u=e.parentNode,c=-1,C=d.length;continue}}const C=e.parentNode;let w=e.nextSibling;p&&p.children.length>0&&C.insertBefore(p,w),n?h=n.previousSibling:h||(h=e.previousSibling),w=e.nextSibling,0===e.children.length||0===e.textContent.length?r.removeItem(e):r.removeEmptyNode(e,null);let x=null;if(i)x={cc:C,sc:h,ec:w,removeArray:m};else{h||(h=g),g||(g=h);const e=r.getEdgeChildNodes(h,g.parentNode?h:g);x={cc:(e.sc||e.ec).parentNode,sc:e.sc,ec:e.ec}}if(this.effectNode=null,o)return x;!i&&x&&(t?this.setRange(x.sc,a,x.ec,c):this.setRange(x.sc,0,x.sc,0)),this.history.push(!1)},detachList:function(e,t){let n={},i=!1,l=!1,o=null,s=null;const a=function(e){return!this.isComponent(e)}.bind(r);for(let c,d,u,h,g=0,p=e.length;g<p;g++){if(u=g===p-1,d=r.getRangeFormatElement(e[g],a),h=r.isList(d),!c&&h)c=d,n={r:c,f:[r.getParentElement(e[g],"LI")]},0===g&&(i=!0);else if(c&&h)if(c!==d){const a=this.detachRangeFormatElement(n.f[0].parentNode,n.f,null,t,!0);d=e[g].parentNode,i&&(o=a.sc,i=!1),u&&(s=a.ec),h?(c=d,n={r:c,f:[r.getParentElement(e[g],"LI")]},u&&(l=!0)):c=null}else n.f.push(r.getParentElement(e[g],"LI")),u&&(l=!0);if(u&&r.isList(c)){const e=this.detachRangeFormatElement(n.f[0].parentNode,n.f,null,t,!0);(l||1===p)&&(s=e.ec),i&&(o=e.sc||s)}}return{sc:o,ec:s}},nodeChange:function(e,t,n,i){this._resetRangeToTextNode();let l=this.getRange_addLine(this.getRange(),null);t=!!(t&&t.length>0)&&t,n=!!(n&&n.length>0)&&n;const o=!e,s=o&&!n&&!t;let c=l.startContainer,d=l.startOffset,u=l.endContainer,h=l.endOffset;if(s&&l.collapsed&&r.isFormatElement(c.parentNode)&&r.isFormatElement(u.parentNode)||c===u&&1===c.nodeType&&r.isNonEditable(c))return;if(l.collapsed&&!s&&1===c.nodeType&&!r.isBreak(c)&&!r.isComponent(c)){let e=null;const t=c.childNodes[d];t&&(e=t.nextSibling?r.isBreak(t)?t:t.nextSibling:null);const n=r.createTextNode(r.zeroWidthSpace);c.insertBefore(n,e),this.setRange(n,1,n,1),l=this.getRange(),c=l.startContainer,d=l.startOffset,u=l.endContainer,h=l.endOffset}r.isFormatElement(c)&&(c=c.childNodes[d]||c.firstChild,d=0),r.isFormatElement(u)&&(u=u.childNodes[h]||u.lastChild,h=u.textContent.length),o&&(e=r.createElement("DIV"));const g=a.RegExp,p=e.nodeName;if(!s&&c===u&&!n&&e){let t=c,n=0;const i=[],l=e.style;for(let e=0,t=l.length;e<t;e++)i.push(l[e]);const s=e.classList;for(let e=0,t=s.length;e<t;e++)i.push("."+s[e]);if(i.length>0){for(;!r.isFormatElement(t)&&!r.isWysiwygDiv(t);){for(let l=0;l<i.length;l++)if(1===t.nodeType){const s=i[l],a=!!/^\./.test(s)&&new g("\\s*"+s.replace(/^\./,"")+"(\\s+|$)","ig"),r=o?!!t.style[s]:!!t.style[s]&&!!e.style[s]&&t.style[s]===e.style[s],c=!1!==a&&(o?!!t.className.match(a):!!t.className.match(a)&&!!e.className.match(a));(r||c)&&n++}t=t.parentNode}if(n>=i.length)return}}let m,f={},_={},b="",v="",y="";if(t){for(let e,n=0,i=t.length;n<i;n++)e=t[n],/^\./.test(e)?v+=(v?"|":"\\s*(?:")+e.replace(/^\./,""):b+=(b?"|":"(?:;|^|\\s)(?:")+e;b&&(b+=")\\s*:[^;]*\\s*(?:;|$)",b=new g(b,"ig")),v&&(v+=")(?=\\s+|$)",v=new g(v,"ig"))}if(n){y="^(?:"+n[0];for(let e=1;e<n.length;e++)y+="|"+n[e];y+=")$",y=new g(y,"i")}const C=a.Boolean,w={v:!1},x=function(e){const t=e.cloneNode(!1);if(3===t.nodeType||r.isBreak(t))return t;if(s)return null;const n=!y&&o||y&&y.test(t.nodeName);if(n&&!i)return w.v=!0,null;const l=t.style.cssText;let a="";b&&l.length>0&&(a=l.replace(b,"").trim(),a!==l&&(w.v=!0));const c=t.className;let d="";return v&&c.length>0&&(d=c.replace(v,"").trim(),d!==c&&(w.v=!0)),(!o||!v&&c||!b&&l||a||d||!n)&&(a||d||t.nodeName!==p||C(b)!==C(l)||C(v)!==C(c))?(b&&l.length>0&&(t.style.cssText=a),t.style.cssText||t.removeAttribute("style"),v&&c.length>0&&(t.className=d.trim()),t.className.trim()||t.removeAttribute("class"),t.style.cssText||t.className||t.nodeName!==p&&!n?t:(w.v=!0,null)):(w.v=!0,null)},E=this.getSelectedElements(null);l=this.getRange(),c=l.startContainer,d=l.startOffset,u=l.endContainer,h=l.endOffset,r.getFormatElement(c,null)||(c=r.getChildElement(E[0],(function(e){return 3===e.nodeType}),!1),d=0),r.getFormatElement(u,null)||(u=r.getChildElement(E[E.length-1],(function(e){return 3===e.nodeType}),!1),h=u.textContent.length);const S=r.getFormatElement(c,null)===r.getFormatElement(u,null),N=E.length-(S?0:1);m=e.cloneNode(!1);const T=s||o&&function(e){for(let t=0,n=e.length;t<n;t++)if(r._isMaintainedNode(e[t])||r._isSizeNode(e[t]))return!0;return!1}(n),L=r._isSizeNode(m),k=this._util_getMaintainedNode.bind(r,T,L),B=this._util_isMaintainedNode.bind(r,T,L);if(S){const e=this._nodeChange_oneLine(E[0],m,x,c,d,u,h,s,o,l.collapsed,w,k,B);f.container=e.startContainer,f.offset=e.startOffset,_.container=e.endContainer,_.offset=e.endOffset,f.container===_.container&&r.onlyZeroWidthSpace(f.container)&&(f.offset=_.offset=1),this._setCommonListStyle(e.ancestor,null)}else{N>0&&(m=e.cloneNode(!1),_=this._nodeChange_endLine(E[N],m,x,u,h,s,o,w,k,B));for(let t,n=N-1;n>0;n--)m=e.cloneNode(!1),t=this._nodeChange_middleLine(E[n],m,x,s,o,w,_.container),t.endContainer&&(_.ancestor=null,_.container=t.endContainer),this._setCommonListStyle(t.ancestor,null);m=e.cloneNode(!1),f=this._nodeChange_startLine(E[0],m,x,c,d,s,o,w,k,B,_.container),f.endContainer&&(_.ancestor=null,_.container=f.endContainer),N<=0?_=f:_.container||(_.ancestor=null,_.container=f.container,_.offset=f.container.textContent.length),this._setCommonListStyle(f.ancestor,null),this._setCommonListStyle(_.ancestor||r.getFormatElement(_.container),null)}this.controllersOff(),this.setRange(f.container,f.offset,_.container,_.offset),this.history.push(!1)},_setCommonListStyle:function(e,t){if(!r.isListCell(e))return;t||e.removeAttribute("style");const n=r.getArrayItem((t||e).childNodes,(function(e){return!r.isBreak(e)&&!r.onlyZeroWidthSpace(e.textContent.trim())}),!0);if(n[0]&&1===n.length){if(!(t=n[0])||1!==t.nodeType)return;const i=t.style,l=e.style;/STRONG/i.test(t.nodeName)?l.fontWeight="bold":i.fontWeight&&(l.fontWeight=i.fontWeight),i.color&&(l.color=i.color),i.fontSize&&(l.fontSize=i.fontSize),this._setCommonListStyle(e,t)}},_stripRemoveNode:function(e){const t=e.parentNode;if(!e||3===e.nodeType||!t)return;const n=e.childNodes;for(;n[0];)t.insertBefore(n[0],e);t.removeChild(e)},_util_getMaintainedNode:function(e,t,n){return!n||e?null:this.getParentElement(n,this._isMaintainedNode.bind(this))||(t?null:this.getParentElement(n,this._isSizeNode.bind(this)))},_util_isMaintainedNode:function(e,t,n){if(!n||e||1!==n.nodeType)return!1;const i=this._isMaintainedNode(n);return this.getParentElement(n,this._isMaintainedNode.bind(this))?i:i||!t&&this._isSizeNode(n)},_nodeChange_oneLine:function(e,t,n,i,l,o,s,c,d,u,h,g,p){let m=i.parentNode;for(;!(m.nextSibling||m.previousSibling||r.isFormatElement(m.parentNode)||r.isWysiwygDiv(m.parentNode))&&m.nodeName!==t.nodeName;)m=m.parentNode;if(!d&&m===o.parentNode&&m.nodeName===t.nodeName&&r.onlyZeroWidthSpace(i.textContent.slice(0,l))&&r.onlyZeroWidthSpace(o.textContent.slice(s))){const e=m.childNodes;let n=!0;for(let t,l,s,a,c=0,d=e.length;c<d;c++)if(t=e[c],a=!r.onlyZeroWidthSpace(t),t!==i)if(t!==o){if(!l&&a||l&&s&&a){n=!1;break}}else s=!0;else l=!0;if(n)return r.copyTagAttributes(m,t),{startContainer:i,startOffset:l,endContainer:o,endOffset:s}}h.v=!1;const f=e,_=[t],b=e.cloneNode(!1),v=i===o;let y,C,w,x,E,S=i,N=l,T=o,L=s,k=!1,B=!1;const A=a.RegExp;function z(e){const t=new A("(?:;|^|\\s)(?:"+x+"null)\\s*:[^;]*\\s*(?:;|$)","ig");let n="";return t&&e.style.cssText.length>0&&(n=t.test(e.style.cssText)),!n}if(function e(i,l){const o=i.childNodes;for(let i,s=0,a=o.length;s<a;s++){let a=o[s];if(!a)continue;let d,h=l;if(!k&&a===S){let e=b;E=g(a);const o=r.createTextNode(1===S.nodeType?"":S.substringData(0,N)),s=r.createTextNode(1===S.nodeType?"":S.substringData(N,v&&L>=N?L-N:S.data.length-N));if(E){const t=g(l);if(t&&t.parentNode!==e){let n=t,i=null;for(;n.parentNode!==e;){for(l=i=n.parentNode.cloneNode(!1);n.childNodes[0];)i.appendChild(n.childNodes[0]);n.appendChild(i),n=n.parentNode}n.parentNode.appendChild(t)}E=E.cloneNode(!1)}r.onlyZeroWidthSpace(o)||l.appendChild(o);const c=g(l);for(c&&(E=c),E&&(e=E),C=a,y=[],x="";C!==e&&C!==f&&null!==C;)i=p(C)?null:n(C),i&&1===C.nodeType&&z(C)&&(y.push(i),x+=C.style.cssText.substr(0,C.style.cssText.indexOf(":"))+"|"),C=C.parentNode;const d=y.pop()||s;for(w=C=d;y.length>0;)C=y.pop(),w.appendChild(C),w=C;if(t.appendChild(d),e.appendChild(t),E&&!g(T)&&(t=t.cloneNode(!1),b.appendChild(t),_.push(t)),S=s,N=0,k=!0,C!==s&&C.appendChild(S),!v)continue}if(B||a!==T){if(k){if(1===a.nodeType&&!r.isBreak(a)){r._isIgnoreNodeChange(a)?(b.appendChild(a.cloneNode(!0)),u||(t=t.cloneNode(!1),b.appendChild(t),_.push(t))):e(a,a);continue}C=a,y=[],x="";const o=[];for(;null!==C.parentNode&&C!==f&&C!==t;)i=B?C.cloneNode(!1):n(C),1===C.nodeType&&!r.isBreak(a)&&i&&z(C)&&(p(C)?E||o.push(i):y.push(i),x+=C.style.cssText.substr(0,C.style.cssText.indexOf(":"))+"|"),C=C.parentNode;y=y.concat(o);const s=y.pop()||a;for(w=C=s;y.length>0;)C=y.pop(),w.appendChild(C),w=C;if(p(t.parentNode)&&!p(s)&&(t=t.cloneNode(!1),b.appendChild(t),_.push(t)),B||E||!p(s))s===a?l=B?b:t:B?(b.appendChild(s),l=C):(t.appendChild(s),l=C);else{t=t.cloneNode(!1);const e=s.childNodes;for(let n=0,i=e.length;n<i;n++)t.appendChild(e[n]);s.appendChild(t),b.appendChild(s),_.push(t),l=t.children.length>0?C:t}if(E&&3===a.nodeType)if(g(a)){const e=r.getParentElement(l,function(e){return this._isMaintainedNode(e.parentNode)||e.parentNode===b}.bind(r));E.appendChild(e),t=e.cloneNode(!1),_.push(t),b.appendChild(t)}else E=null}d=a.cloneNode(!1),l.appendChild(d),1!==a.nodeType||r.isBreak(a)||(h=d),e(a,h)}else{E=g(a);const e=r.createTextNode(1===T.nodeType?"":T.substringData(L,T.length-L)),l=r.createTextNode(v||1===T.nodeType?"":T.substringData(0,L));if(E?E=E.cloneNode(!1):p(t.parentNode)&&!E&&(t=t.cloneNode(!1),b.appendChild(t),_.push(t)),!r.onlyZeroWidthSpace(e)){C=a,x="",y=[];const t=[];for(;C!==b&&C!==f&&null!==C;)1===C.nodeType&&z(C)&&(p(C)?t.push(C.cloneNode(!1)):y.push(C.cloneNode(!1)),x+=C.style.cssText.substr(0,C.style.cssText.indexOf(":"))+"|"),C=C.parentNode;for(y=y.concat(t),d=w=C=y.pop()||e;y.length>0;)C=y.pop(),w.appendChild(C),w=C;b.appendChild(d),C.textContent=e.data}if(E&&d){const e=g(d);e&&(E=e)}for(C=a,y=[],x="";C!==b&&C!==f&&null!==C;)i=p(C)?null:n(C),i&&1===C.nodeType&&z(C)&&(y.push(i),x+=C.style.cssText.substr(0,C.style.cssText.indexOf(":"))+"|"),C=C.parentNode;const o=y.pop()||l;for(w=C=o;y.length>0;)C=y.pop(),w.appendChild(C),w=C;E?((t=t.cloneNode(!1)).appendChild(o),E.insertBefore(t,E.firstChild),b.appendChild(E),_.push(t),E=null):t.appendChild(o),T=l,L=l.data.length,B=!0,!c&&u&&(t=l,l.textContent=r.zeroWidthSpace),C!==l&&C.appendChild(T)}}}(e,b),d&&!c&&!h.v)return{ancestor:e,startContainer:i,startOffset:l,endContainer:o,endOffset:s};if(c=c&&d)for(let e=0;e<_.length;e++){let t,n,i,l=_[e];if(u)t=r.createTextNode(r.zeroWidthSpace),b.replaceChild(t,l);else{const e=l.childNodes;for(n=e[0];e[0];)i=e[0],b.insertBefore(i,l);r.removeItem(l)}0===e&&(u?S=T=t:(S=n,T=i))}else{if(d)for(let e=0;e<_.length;e++)this._stripRemoveNode(_[e]);u&&(S=T=t)}r.removeEmptyNode(b,t),u&&(N=S.textContent.length,L=T.textContent.length);const M=c||0===T.textContent.length;r.isBreak(T)||0!==T.textContent.length||(r.removeItem(T),T=S),L=M?T.textContent.length:L;const H={s:0,e:0},I=r.getNodePath(S,b,H),D=!T.parentNode;D&&(T=S);const O={s:0,e:0},R=r.getNodePath(T,b,D||M?null:O);N+=H.s,L=u?N:D?S.textContent.length:M?L+H.s:L+O.s;const F=r.mergeSameTags(b,[I,R],!0);return e.parentNode.replaceChild(b,e),S=r.getNodeFromPath(I,b),T=r.getNodeFromPath(R,b),{ancestor:b,startContainer:S,startOffset:N+F[0],endContainer:T,endOffset:L+F[1]}},_nodeChange_startLine:function(e,t,n,i,l,o,s,a,c,d,u){let h=i.parentNode;for(;!(h.nextSibling||h.previousSibling||r.isFormatElement(h.parentNode)||r.isWysiwygDiv(h.parentNode))&&h.nodeName!==t.nodeName;)h=h.parentNode;if(!s&&h.nodeName===t.nodeName&&!r.isFormatElement(h)&&!h.nextSibling&&r.onlyZeroWidthSpace(i.textContent.slice(0,l))){let n=!0,o=i.previousSibling;for(;o;){if(!r.onlyZeroWidthSpace(o)){n=!1;break}o=o.previousSibling}if(n)return r.copyTagAttributes(h,t),{ancestor:e,container:i,offset:l}}a.v=!1;const g=e,p=[t],m=e.cloneNode(!1);let f,_,b,v,y=i,C=l,w=!1;if(function e(i,l){const o=i.childNodes;for(let i,s,a=0,h=o.length;a<h;a++){const h=o[a];if(!h)continue;let x=l;if(w&&!r.isBreak(h)){if(1===h.nodeType){if(r._isIgnoreNodeChange(h)){if(t=t.cloneNode(!1),s=h.cloneNode(!0),m.appendChild(s),m.appendChild(t),p.push(t),u&&h.contains(u)){const e=r.getNodePath(u,h);u=r.getNodeFromPath(e,s)}}else e(h,h);continue}_=h,f=[];const o=[];for(;null!==_.parentNode&&_!==g&&_!==t;)i=n(_),1===_.nodeType&&i&&(d(_)?v||o.push(i):f.push(i)),_=_.parentNode;f=f.concat(o);const a=f.length>0,y=f.pop()||h;for(b=_=y;f.length>0;)_=f.pop(),b.appendChild(_),b=_;if(d(t.parentNode)&&!d(y)&&(t=t.cloneNode(!1),m.appendChild(t),p.push(t)),!v&&d(y)){t=t.cloneNode(!1);const e=y.childNodes;for(let n=0,i=e.length;n<i;n++)t.appendChild(e[n]);y.appendChild(t),m.appendChild(y),l=d(_)?t:_,p.push(t)}else a?(t.appendChild(y),l=_):l=t;if(v&&3===h.nodeType)if(c(h)){const e=r.getParentElement(l,function(e){return this._isMaintainedNode(e.parentNode)||e.parentNode===m}.bind(r));v.appendChild(e),t=e.cloneNode(!1),p.push(t),m.appendChild(t)}else v=null}if(w||h!==y)i=w?n(h):h.cloneNode(!1),i&&(l.appendChild(i),1!==h.nodeType||r.isBreak(h)||(x=i)),e(h,x);else{let e=m;v=c(h);const o=r.createTextNode(1===y.nodeType?"":y.substringData(0,C)),s=r.createTextNode(1===y.nodeType?"":y.substringData(C,y.length-C));if(v){const t=c(l);if(t&&t.parentNode!==e){let n=t,i=null;for(;n.parentNode!==e;){for(l=i=n.parentNode.cloneNode(!1);n.childNodes[0];)i.appendChild(n.childNodes[0]);n.appendChild(i),n=n.parentNode}n.parentNode.appendChild(t)}v=v.cloneNode(!1)}r.onlyZeroWidthSpace(o)||l.appendChild(o);const a=c(l);for(a&&(v=a),v&&(e=v),_=l,f=[];_!==e&&null!==_;)i=n(_),1===_.nodeType&&i&&f.push(i),_=_.parentNode;const d=f.pop()||l;for(b=_=d;f.length>0;)_=f.pop(),b.appendChild(_),b=_;d!==l?(t.appendChild(d),l=_):l=t,r.isBreak(h)&&t.appendChild(h.cloneNode(!1)),e.appendChild(t),y=s,C=0,w=!0,l.appendChild(y)}}}(e,m),s&&!o&&!a.v)return{ancestor:e,container:i,offset:l,endContainer:u};if(o=o&&s)for(let e=0;e<p.length;e++){let t=p[e];const n=t.childNodes,i=n[0];for(;n[0];)m.insertBefore(n[0],t);r.removeItem(t),0===e&&(y=i)}else if(s){t=t.firstChild;for(let e=0;e<p.length;e++)this._stripRemoveNode(p[e])}if(o||0!==m.childNodes.length){r.removeEmptyNode(m,t),r.onlyZeroWidthSpace(m.textContent)&&(y=m.firstChild,C=0);const n={s:0,e:0},i=r.getNodePath(y,m,n);C+=n.s;const l=r.mergeSameTags(m,[i],!0);e.parentNode.replaceChild(m,e),y=r.getNodeFromPath(i,m),C+=l[0]}else e.childNodes?y=e.childNodes[0]:(y=r.createTextNode(r.zeroWidthSpace),e.appendChild(y));return{ancestor:m,container:y,offset:C,endContainer:u}},_nodeChange_middleLine:function(e,t,n,i,l,o,s){if(!l){let n=null;s&&e.contains(s)&&(n=r.getNodePath(s,e));const i=e.cloneNode(!0),l=t.nodeName,o=t.style.cssText,a=t.className;let c,d=i.childNodes,u=0,h=d.length;for(;u<h&&(c=d[u],3!==c.nodeType);u++){if(c.nodeName!==l){if(!r.isBreak(c)&&r._isIgnoreNodeChange(c))continue;if(1===h){d=c.childNodes,h=d.length,u=-1;continue}break}c.style.cssText+=o,r.addClass(c,a)}if(h>0&&u===h)return e.innerHTML=i.innerHTML,{ancestor:e,endContainer:n?r.getNodeFromPath(n,e):null}}o.v=!1;const a=e.cloneNode(!1),c=[t];let d=!0;if(function e(i,l){const o=i.childNodes;for(let i,u,h=0,g=o.length;h<g;h++){let g=o[h];if(!g)continue;let p=l;if(r.isBreak(g)||!r._isIgnoreNodeChange(g))i=n(g),i&&(d=!1,l.appendChild(i),1===g.nodeType&&(p=i)),r.isBreak(g)||e(g,p);else if(t.childNodes.length>0&&(a.appendChild(t),t=t.cloneNode(!1)),u=g.cloneNode(!0),a.appendChild(u),a.appendChild(t),c.push(t),l=t,s&&g.contains(s)){const e=r.getNodePath(s,g);s=r.getNodeFromPath(e,u)}}}(e,t),d||l&&!i&&!o.v)return{ancestor:e,endContainer:s};if(a.appendChild(t),i&&l)for(let e=0;e<c.length;e++){let t=c[e];const n=t.childNodes;for(;n[0];)a.insertBefore(n[0],t);r.removeItem(t)}else if(l){t=t.firstChild;for(let e=0;e<c.length;e++)this._stripRemoveNode(c[e])}return r.removeEmptyNode(a,t),r.mergeSameTags(a,null,!0),e.parentNode.replaceChild(a,e),{ancestor:a,endContainer:s}},_nodeChange_endLine:function(e,t,n,i,l,o,s,a,c,d){let u=i.parentNode;for(;!(u.nextSibling||u.previousSibling||r.isFormatElement(u.parentNode)||r.isWysiwygDiv(u.parentNode))&&u.nodeName!==t.nodeName;)u=u.parentNode;if(!s&&u.nodeName===t.nodeName&&!r.isFormatElement(u)&&!u.previousSibling&&r.onlyZeroWidthSpace(i.textContent.slice(l))){let n=!0,o=i.nextSibling;for(;o;){if(!r.onlyZeroWidthSpace(o)){n=!1;break}o=o.nextSibling}if(n)return r.copyTagAttributes(u,t),{ancestor:e,container:i,offset:l}}a.v=!1;const h=e,g=[t],p=e.cloneNode(!1);let m,f,_,b,v=i,y=l,C=!1;if(function e(i,l){const o=i.childNodes;for(let i,s=o.length-1;0<=s;s--){const a=o[s];if(!a)continue;let u=l;if(C&&!r.isBreak(a)){if(1===a.nodeType){if(r._isIgnoreNodeChange(a)){t=t.cloneNode(!1);const e=a.cloneNode(!0);p.insertBefore(e,l),p.insertBefore(t,e),g.push(t)}else e(a,a);continue}f=a,m=[];const o=[];for(;null!==f.parentNode&&f!==h&&f!==t;)i=n(f),i&&1===f.nodeType&&(d(f)?b||o.push(i):m.push(i)),f=f.parentNode;m=m.concat(o);const s=m.length>0,u=m.pop()||a;for(_=f=u;m.length>0;)f=m.pop(),_.appendChild(f),_=f;if(d(t.parentNode)&&!d(u)&&(t=t.cloneNode(!1),p.insertBefore(t,p.firstChild),g.push(t)),!b&&d(u)){t=t.cloneNode(!1);const e=u.childNodes;for(let n=0,i=e.length;n<i;n++)t.appendChild(e[n]);u.appendChild(t),p.insertBefore(u,p.firstChild),g.push(t),l=t.children.length>0?f:t}else s?(t.insertBefore(u,t.firstChild),l=f):l=t;if(b&&3===a.nodeType)if(c(a)){const e=r.getParentElement(l,function(e){return this._isMaintainedNode(e.parentNode)||e.parentNode===p}.bind(r));b.appendChild(e),t=e.cloneNode(!1),g.push(t),p.insertBefore(t,p.firstChild)}else b=null}if(C||a!==v)i=C?n(a):a.cloneNode(!1),i&&(l.insertBefore(i,l.firstChild),1!==a.nodeType||r.isBreak(a)||(u=i)),e(a,u);else{b=c(a);const e=r.createTextNode(1===v.nodeType?"":v.substringData(y,v.length-y)),o=r.createTextNode(1===v.nodeType?"":v.substringData(0,y));if(b){b=b.cloneNode(!1);const e=c(l);if(e&&e.parentNode!==p){let t=e,n=null;for(;t.parentNode!==p;){for(l=n=t.parentNode.cloneNode(!1);t.childNodes[0];)n.appendChild(t.childNodes[0]);t.appendChild(n),t=t.parentNode}t.parentNode.insertBefore(e,t.parentNode.firstChild)}b=b.cloneNode(!1)}else d(t.parentNode)&&!b&&(t=t.cloneNode(!1),p.appendChild(t),g.push(t));for(r.onlyZeroWidthSpace(e)||l.insertBefore(e,l.firstChild),f=l,m=[];f!==p&&null!==f;)i=d(f)?null:n(f),i&&1===f.nodeType&&m.push(i),f=f.parentNode;const s=m.pop()||l;for(_=f=s;m.length>0;)f=m.pop(),_.appendChild(f),_=f;s!==l?(t.insertBefore(s,t.firstChild),l=f):l=t,r.isBreak(a)&&t.appendChild(a.cloneNode(!1)),b?(b.insertBefore(t,b.firstChild),p.insertBefore(b,p.firstChild),b=null):p.insertBefore(t,p.firstChild),v=o,y=o.data.length,C=!0,l.insertBefore(v,l.firstChild)}}}(e,p),s&&!o&&!a.v)return{ancestor:e,container:i,offset:l};if(o=o&&s)for(let e=0;e<g.length;e++){let t=g[e];const n=t.childNodes;let i=null;for(;n[0];)i=n[0],p.insertBefore(i,t);r.removeItem(t),e===g.length-1&&(v=i,y=i.textContent.length)}else if(s){t=t.firstChild;for(let e=0;e<g.length;e++)this._stripRemoveNode(g[e])}if(o||0!==p.childNodes.length){if(!s&&0===t.textContent.length)return r.removeEmptyNode(p,null),{ancestor:null,container:null,offset:0};r.removeEmptyNode(p,t),r.onlyZeroWidthSpace(p.textContent)?(v=p.firstChild,y=v.textContent.length):r.onlyZeroWidthSpace(v)&&(v=t,y=1);const n={s:0,e:0},i=r.getNodePath(v,p,n);y+=n.s;const l=r.mergeSameTags(p,[i],!0);e.parentNode.replaceChild(p,e),v=r.getNodeFromPath(i,p),y+=l[0]}else e.childNodes?v=e.childNodes[0]:(v=r.createTextNode(r.zeroWidthSpace),e.appendChild(v));return{ancestor:p,container:v,offset:y}},actionCall:function(t,n,i){if(n){if(/more/i.test(n)&&i!==this._moreLayerActiveButton){const n=e.element.toolbar.querySelector("."+t);return void(n&&(this._moreLayerActiveButton&&(e.element.toolbar.querySelector("."+this._moreLayerActiveButton.getAttribute("data-command")).style.display="none",r.removeClass(this._moreLayerActiveButton,"on")),r.addClass(i,"on"),this._moreLayerActiveButton=i,n.style.display="block",u._showToolbarBalloon(),u._showToolbarInline()))}if(/submenu/.test(n)&&(null===this._menuTray[t]||i!==this.submenuActiveButton))return void this.callPlugin(t,this.submenuOn.bind(this,i),i);if(/dialog/.test(n))return void this.callPlugin(t,this.plugins[t].open.bind(this),i);if(/command/.test(n))this.callPlugin(t,this.plugins[t].action.bind(this),i);else{if(/container/.test(n)&&(null===this._menuTray[t]||i!==this.containerActiveButton))return void this.callPlugin(t,this.containerOn.bind(this,i),i);/fileBrowser/.test(n)&&this.callPlugin(t,this.plugins[t].open.bind(this,null),i)}}else t&&this.commandHandler(i,t);if(/more/i.test(n)){const t=e.element.toolbar.querySelector("."+this._moreLayerActiveButton.getAttribute("data-command"));t&&(r.removeClass(this._moreLayerActiveButton,"on"),this._moreLayerActiveButton=null,t.style.display="none",u._showToolbarBalloon(),u._showToolbarInline())}else/submenu/.test(n)?this.submenuOff():(this.submenuOff(),this.containerOff())},commandHandler:function(t,n){switch(n){case"selectAll":const i=e.element.wysiwyg,o=r.getChildElement(i.firstChild,(function(e){return 0===e.childNodes.length||3===e.nodeType}),!1)||i.firstChild,s=r.getChildElement(i.lastChild,(function(e){return 0===e.childNodes.length||3===e.nodeType}),!0)||i.lastChild;if(!o||!s)return;this.setRange(o,0,s,s.textContent.length);break;case"codeView":this.toggleCodeView();break;case"fullScreen":this.toggleFullScreen(t);break;case"indent":case"outdent":this.indent(n);break;case"undo":this.history.undo();break;case"redo":this.history.redo();break;case"removeFormat":this.removeFormat(),this.focus();break;case"print":this.print();break;case"preview":this.preview();break;case"showBlocks":this.toggleDisplayBlocks();break;case"save":if("function"==typeof l.callBackSave)l.callBackSave(this.getContents(!1));else{if("function"!=typeof h.save)throw Error("[SUNEDITOR.core.commandHandler.fail] Please register call back function in creation option. (callBackSave : Function)");h.save()}e.tool.save&&e.tool.save.setAttribute("disabled",!0);break;default:n=this._defaultCommand[n.toLowerCase()]||n,this.commandMap[n]||(this.commandMap[n]=t);const a=this._variable.currentNodesMap,c=a.indexOf(n)>-1?null:r.createElement(n);let d=n;/^SUB$/i.test(n)&&a.indexOf("SUP")>-1?d="SUP":/^SUP$/i.test(n)&&a.indexOf("SUB")>-1&&(d="SUB"),this.nodeChange(c,null,[d],!1),this.focus()}},removeFormat:function(){this.nodeChange(null,null,null,null)},indent:function(e){const t=this.getRange(),n=this.getSelectedElements(null),i=[],o="indent"!==e,s=l.rtl?"marginRight":"marginLeft";let a=t.startContainer,c=t.endContainer,d=t.startOffset,u=t.endOffset;for(let e,t,l=0,a=n.length;l<a;l++)e=n[l],r.isListCell(e)&&this.plugins.list?(o||e.previousElementSibling)&&i.push(e):(t=/\d+/.test(e.style[s])?r.getNumber(e.style[s],0):0,o?t-=25:t+=25,r.setStyle(e,s,t<=0?"":t+"px"));i.length>0&&this.plugins.list.editInsideList.call(this,o,i),this.effectNode=null,this.setRange(a,d,c,u),this.history.push(!1)},toggleDisplayBlocks:function(){const t=e.element.wysiwyg;r.toggleClass(t,"se-show-block"),r.hasClass(t,"se-show-block")?r.addClass(this._styleCommandMap.showBlocks,"active"):r.removeClass(this._styleCommandMap.showBlocks,"active"),this._resourcesStateChange()},toggleCodeView:function(){const t=this._variable.isCodeView;this.controllersOff(),r.setDisabledButtons(!t,this.codeViewDisabledButtons),t?(this._setCodeDataToEditor(),e.element.wysiwygFrame.scrollTop=0,e.element.code.style.display="none",e.element.wysiwygFrame.style.display="block",this._variable._codeOriginCssText=this._variable._codeOriginCssText.replace(/(\s?display(\s+)?:(\s+)?)[a-zA-Z]+(?=;)/,"display: none"),this._variable._wysiwygOriginCssText=this._variable._wysiwygOriginCssText.replace(/(\s?display(\s+)?:(\s+)?)[a-zA-Z]+(?=;)/,"display: block"),"auto"!==l.height||l.codeMirrorEditor||(e.element.code.style.height="0px"),this._variable.isCodeView=!1,this._variable.isFullScreen||(this._notHideToolbar=!1,/balloon|balloon-always/i.test(l.mode)&&(e.element._arrow.style.display="",this._isInline=!1,this._isBalloon=!0,u._hideToolbar())),this.nativeFocus(),r.removeClass(this._styleCommandMap.codeView,"active"),this.history.push(!1)):(this._setEditorDataToCodeView(),this._variable._codeOriginCssText=this._variable._codeOriginCssText.replace(/(\s?display(\s+)?:(\s+)?)[a-zA-Z]+(?=;)/,"display: block"),this._variable._wysiwygOriginCssText=this._variable._wysiwygOriginCssText.replace(/(\s?display(\s+)?:(\s+)?)[a-zA-Z]+(?=;)/,"display: none"),"auto"!==l.height||l.codeMirrorEditor||(e.element.code.style.height=e.element.code.scrollHeight>0?e.element.code.scrollHeight+"px":"auto"),l.codeMirrorEditor&&l.codeMirrorEditor.refresh(),this._variable.isCodeView=!0,this._variable.isFullScreen||(this._notHideToolbar=!0,this._isBalloon&&(e.element._arrow.style.display="none",e.element.toolbar.style.left="",this._isInline=!0,this._isBalloon=!1,u._showToolbarInline())),this._variable._range=null,e.element.code.focus(),r.addClass(this._styleCommandMap.codeView,"active")),this._checkPlaceholder(),"function"==typeof h.toggleCodeView&&h.toggleCodeView(this._variable.isCodeView,this)},_setCodeDataToEditor:function(){const t=this._getCodeView();if(l.fullPage){const e=this._parser.parseFromString(t,"text/html"),n=e.head.children;for(let t=0,i=n.length;t<i;t++)/^script$/i.test(n[t].tagName)&&(e.head.removeChild(n[t]),t--,i--);this._wd.head.innerHTML=e.head.innerHTML,this._wd.body.innerHTML=this.convertContentsForEditor(e.body.innerHTML);const i=e.body.attributes;for(let e=0,t=i.length;e<t;e++)"contenteditable"!==i[e].name&&this._wd.body.setAttribute(i[e].name,i[e].value);if(!r.hasClass(this._wd.body,"sun-editor-editable")){const e=l._editableClass.split(" ");for(let t=0;t<e.length;t++)r.addClass(this._wd.body,l._editableClass[t])}}else e.element.wysiwyg.innerHTML=t.length>0?this.convertContentsForEditor(t):"<"+l.defaultTag+"><br></"+l.defaultTag+">"},_setEditorDataToCodeView:function(){const t=this.convertHTMLForCodeView(e.element.wysiwyg);let n="";if(l.fullPage){const e=r.getAttributesToString(this._wd.body,null);n="<!DOCTYPE html>\n<html>\n"+this._wd.head.outerHTML.replace(/>(?!\n)/g,">\n")+"<body "+e+">\n"+t+"</body>\n</html>"}else n=t;e.element.code.style.display="block",e.element.wysiwygFrame.style.display="none",this._setCodeView(n)},toggleFullScreen:function(t){const n=e.element.topArea,i=e.element.toolbar,o=e.element.editorArea,d=e.element.wysiwygFrame,g=e.element.code,p=this._variable;this.controllersOff(),p.isFullScreen?(p.isFullScreen=!1,d.style.cssText=p._wysiwygOriginCssText,g.style.cssText=p._codeOriginCssText,i.style.cssText="",o.style.cssText=p._editorAreaOriginCssText,n.style.cssText=p._originCssText,s.body.style.overflow=p._bodyOverflow,l.toolbarContainer&&l.toolbarContainer.appendChild(i),l.stickyToolbar>-1&&r.removeClass(i,"se-toolbar-sticky"),p._fullScreenAttrs.sticky&&!l.toolbarContainer&&(p._fullScreenAttrs.sticky=!1,e.element._stickyDummy.style.display="block",r.addClass(i,"se-toolbar-sticky")),this._isInline=p._fullScreenAttrs.inline,this._isBalloon=p._fullScreenAttrs.balloon,this._isInline&&u._showToolbarInline(),l.toolbarContainer&&r.removeClass(i,"se-toolbar-balloon"),u.onScroll_window(),r.changeElement(t.firstElementChild,c.expansion),r.removeClass(this._styleCommandMap.fullScreen,"active")):(p.isFullScreen=!0,p._fullScreenAttrs.inline=this._isInline,p._fullScreenAttrs.balloon=this._isBalloon,(this._isInline||this._isBalloon)&&(this._isInline=!1,this._isBalloon=!1),l.toolbarContainer&&e.element.relative.insertBefore(i,o),n.style.position="fixed",n.style.top="0",n.style.left="0",n.style.width="100%",n.style.maxWidth="100%",n.style.height="100%",n.style.zIndex="2147483647",""!==e.element._stickyDummy.style.display&&(p._fullScreenAttrs.sticky=!0,e.element._stickyDummy.style.display="none",r.removeClass(i,"se-toolbar-sticky")),p._bodyOverflow=s.body.style.overflow,s.body.style.overflow="hidden",p._editorAreaOriginCssText=o.style.cssText,p._wysiwygOriginCssText=d.style.cssText,p._codeOriginCssText=g.style.cssText,o.style.cssText=i.style.cssText="",d.style.cssText=(d.style.cssText.match(/\s?display(\s+)?:(\s+)?[a-zA-Z]+;/)||[""])[0],g.style.cssText=(g.style.cssText.match(/\s?display(\s+)?:(\s+)?[a-zA-Z]+;/)||[""])[0],i.style.width=d.style.height=g.style.height="100%",i.style.position="relative",i.style.display="block",p.innerHeight_fullScreen=a.innerHeight-i.offsetHeight,o.style.height=p.innerHeight_fullScreen+"px",r.changeElement(t.firstElementChild,c.reduction),l.iframe&&"auto"===l.height&&(o.style.overflow="auto",this._iframeAutoHeight()),r.addClass(this._styleCommandMap.fullScreen,"active")),"function"==typeof h.toggleFullScreen&&h.toggleFullScreen(this._variable.isFullScreen,this)},print:function(){const e=r.createElement("IFRAME");e.style.display="none",s.body.appendChild(e);const t=r.getIframeDocument(e),n=this.getContents(!0),i=this._wd;if(l.iframe){const e=l.fullPage?r.getAttributesToString(i.body,["contenteditable"]):'class="'+l._editableClass+'"';t.write("<!DOCTYPE html><html><head>"+i.head.innerHTML+"</head><body "+e+">"+n+"</body></html>")}else{const e=s.head.getElementsByTagName("link"),i=s.head.getElementsByTagName("style");let o="";for(let t=0,n=e.length;t<n;t++)o+=e[t].outerHTML;for(let e=0,t=i.length;e<t;e++)o+=i[e].outerHTML;t.write("<!DOCTYPE html><html><head>"+o+'</head><body class="'+l._editableClass+'">'+n+"</body></html>")}this.showLoading(),a.setTimeout((function(){try{if(e.focus(),r.isIE_Edge||s.documentMode||a.StyleMedia)try{e.contentWindow.document.execCommand("print",!1,null)}catch(t){e.contentWindow.print()}else e.contentWindow.print()}catch(e){throw Error("[SUNEDITOR.core.print.fail] error: "+e)}finally{d.closeLoading(),r.removeItem(e)}}),1e3)},preview:function(){d.submenuOff(),d.containerOff(),d.controllersOff();const t=l.previewTemplate?l.previewTemplate.replace(/\{\{\s*contents\s*\}\}/i,this.getContents(!0)):this.getContents(!0),n=a.open("","_blank");n.mimeType="text/html";const o=e.element.wysiwygFrame.offsetWidth+"px !important",c=this._wd;if(l.iframe){const e=l.fullPage?r.getAttributesToString(c.body,["contenteditable"]):'class="'+l._editableClass+'"';n.document.write("<!DOCTYPE html><html><head>"+c.head.innerHTML+"<style>body {overflow:auto !important; width:"+o+"; border:1px solid #ccc; margin: 10px auto !important; height:auto !important;}</style></head><body "+e+">"+t+"</body></html>")}else{const e=s.head.getElementsByTagName("link"),a=s.head.getElementsByTagName("style");let r="";for(let t=0,n=e.length;t<n;t++)r+=e[t].outerHTML;for(let e=0,t=a.length;e<t;e++)r+=a[e].outerHTML;n.document.write('<!DOCTYPE html><html><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1"><title>'+i.toolbar.preview+"</title>"+r+'</head><body class="'+l._editableClass+'" style="width:'+o+'; border:1px solid #ccc; margin:10px auto !important; height:auto !important;">'+t+"</body></html>")}},setContents:function(t){this.removeRange();const n=null==t?"":this.convertContentsForEditor(t);if(this._resetComponents(),this._variable.isCodeView){const e=this.convertHTMLForCodeView(n);this._setCodeView(e)}else e.element.wysiwyg.innerHTML=n,this.history.push(!1)},setIframeContents:function(e){if(!l.iframe)return!1;e.head&&(this._wd.head.innerHTML=e.head.replace(/<script\s*.*>.*<\/script>/g,"")),e.body&&(this._wd.body.innerHTML=this.convertContentsForEditor(e.body))},getContents:function(t){const n=e.element.wysiwyg.innerHTML,i=r.createElement("DIV");i.innerHTML=n;const o=r.getListChildren(i,(function(e){return/FIGCAPTION/i.test(e.nodeName)}));for(let e=0,t=o.length;e<t;e++)o[e].removeAttribute("contenteditable");if(l.fullPage&&!t){const e=r.getAttributesToString(this._wd.body,["contenteditable"]);return"<!DOCTYPE html><html>"+this._wd.head.outerHTML+"<body "+e+">"+i.innerHTML+"</body></html>"}return i.innerHTML},_makeLine:function(e,t){const n=l.defaultTag;if(1===e.nodeType)return r._disallowedTags(e)?"":!t||r.isFormatElement(e)||r.isRangeFormatElement(e)||r.isComponent(e)||r.isMedia(e)||r.isAnchor(e)&&r.isMedia(e.firstElementChild)?e.outerHTML:"<"+n+">"+e.outerHTML+"</"+n+">";if(3===e.nodeType){if(!t)return e.textContent;const i=e.textContent.split(/\n/g);let l="";for(let e,t=0,o=i.length;t<o;t++)e=i[t].trim(),e.length>0&&(l+="<"+n+">"+e+"</"+n+">");return l}return 8===e.nodeType&&this._allowHTMLComments?"\x3c!--"+e.textContent.trim()+"--\x3e":""},_tagConvertor:function(e){if(!this._disallowedTextTagsRegExp)return e;const t={b:"strong",i:"em",ins:"u",strike:"del",s:"del"};return e.replace(this._disallowedTextTagsRegExp,(function(e,n,i){return n+("string"==typeof t[i]?t[i]:i)}))},_deleteDisallowedTags:function(e){return e.replace(/\n/g,"").replace(/<(script|style).*>(\n|.)*<\/(script|style)>/gi,"").replace(/<[a-z0-9]+\:[a-z0-9]+[^>^\/]*>[^>]*<\/[a-z0-9]+\:[a-z0-9]+>/gi,"").replace(this.editorTagsWhitelistRegExp,"")},cleanHTML:function(e,t){e=this._deleteDisallowedTags(e).replace(/(<[a-zA-Z0-9]+)[^>]*(?=>)/g,function(e,t){if(/^<[a-z0-9]+\:[a-z0-9]+/i.test(e))return e;let n=null;const i=this._attributesTagsWhitelist[t.match(/(?!<)[a-zA-Z0-9]+/)[0].toLowerCase()];if(n=i?e.match(i):e.match(this._attributesWhitelistRegExp),/<span/i.test(t)&&(!n||!/style=/i.test(n.toString()))){const t=e.match(/style\s*=\s*"[^"]*"/);t&&(n||(n=[]),n.push(t[0]))}if(n)for(let e=0,i=n.length;e<i;e++)/^class="(?!(__se__|se-|katex))/.test(n[e])||(t+=" "+n[e]);return t}.bind(this));const n=s.createRange().createContextualFragment(e);try{r._consistencyCheckOfHTML(n,this._htmlCheckWhitelistRegExp)}catch(e){console.warn("[SUNEDITOR.cleanHTML.consistencyCheck.fail] "+e)}if(this.managedTagsInfo&&this.managedTagsInfo.query){const e=n.querySelectorAll(this.managedTagsInfo.query);for(let t,n,i=0,l=e.length;i<l;i++){n=[].slice.call(e[i].classList);for(let l=0,o=n.length;l<o;l++)if(t=this.managedTagsInfo.map[n[l]],t){t(e[i]);break}}}const i=n.childNodes;let l="",o=!1;for(let e,t=0,n=i.length;t<n;t++)if(e=i[t],1===e.nodeType&&!r.isTextStyleElement(e)&&!r.isBreak(e)&&!r._disallowedTags(e)){o=!0;break}for(let e=0,t=i.length;e<t;e++)l+=this._makeLine(i[e],o);return l=r.htmlRemoveWhiteSpace(l),this._tagConvertor(l?t?l.replace("string"==typeof t?r.createTagsWhitelist(t):t,""):l:e)},convertContentsForEditor:function(e){e=this._deleteDisallowedTags(e).replace(/(<[a-zA-Z0-9]+)[^>]*(?=>)/g,function(e,t){if(/^<[a-z0-9]+\:[a-z0-9]+/i.test(e))return e;let n=null;const i=this._attributesTagsWhitelist[t.match(/(?!<)[a-zA-Z0-9]+/)[0].toLowerCase()];if(n=i?e.match(i):e.match(this._attributesWhitelistRegExp),/<span/i.test(t)&&(!n||!/style=/i.test(n.toString()))){const t=e.match(/style\s*=\s*"[^"]*"/);t&&(n||(n=[]),n.push(t[0]))}if(n)for(let e=0,i=n.length;e<i;e++)t+=" "+n[e];return t}.bind(this));const t=s.createRange().createContextualFragment(this._deleteDisallowedTags(e));try{r._consistencyCheckOfHTML(t,this._htmlCheckWhitelistRegExp)}catch(e){console.warn("[SUNEDITOR.convertContentsForEditor.consistencyCheck.fail] "+e)}const n=t.childNodes;let i="";for(let e=0,t=n.length;e<t;e++)i+=this._makeLine(n[e],!0);return 0===i.length?"<"+l.defaultTag+"><br></"+l.defaultTag+">":(i=r.htmlRemoveWhiteSpace(i),this._tagConvertor(i))},convertHTMLForCodeView:function(e){let t="";const n=a.RegExp,i=new n("^(BLOCKQUOTE|PRE|TABLE|THEAD|TBODY|TR|TH|TD|OL|UL|IMG|IFRAME|VIDEO|AUDIO|FIGURE|FIGCAPTION|HR|BR|CANVAS|SELECT)$","i"),l=r.isFormatElement.bind(r),o="string"==typeof e?s.createRange().createContextualFragment(e):e;let c=1*this._variable.codeIndent;return c=c>0?new a.Array(c+1).join(" "):"",function e(o,s,a){const d=o.childNodes,u=i.test(o.nodeName),h=u?s:"";for(let g,p,m,f=0,_=d.length;f<_;f++){if(g=d[f],m=i.test(g.nodeName),p=m?"\n":"",a=!l(g)||u||/^(TH|TD)$/i.test(o.nodeName)?"":"\n",8===g.nodeType){t+="\n\x3c!-- "+g.textContent.trim()+" --\x3e"+p;continue}if(3===g.nodeType){t+=r._HTMLConvertor(/^\n+$/.test(g.data)?"":g.data);continue}if(0===g.childNodes.length){t+=(/^HR$/i.test(g.nodeName)?"\n":"")+h+g.outerHTML+p;continue}g.innerHTML=g.innerHTML;const _=g.nodeName.toLowerCase();t+=(a||(u?"":p))+(h||m?s:"")+g.outerHTML.match(n("<"+_+"[^>]*>","i"))[0]+p,e(g,s+c,""),t+=(m?s:"")+"</"+_+">"+(a||p||u||/^(TH|TD)$/i.test(g.nodeName)?"\n":"")}}(o,"","\n"),t.trim()+"\n"},addDocEvent:function(e,t,n){s.addEventListener(e,t,n),l.iframe&&this._wd.addEventListener(e,t)},removeDocEvent:function(e,t){s.removeEventListener(e,t),l.iframe&&this._wd.removeEventListener(e,t)},_charCount:function(e){const t=l.maxCharCount,n=l.charCounterType;let i=0;if(e&&(i=this.getCharLength(e,n)),this._setCharCount(),t>0){let e=!1;const l=h.getCharCount(n);if(l>t){if(e=!0,i>0){this._editorRange();const e=this.getRange(),n=e.endOffset-1,i=this.getSelectionNode().textContent,o=e.endOffset-(l-t);this.getSelectionNode().textContent=i.slice(0,o<0?0:o)+i.slice(e.endOffset,i.length),this.setRange(e.endContainer,n,e.endContainer,n)}}else l+i>t&&(e=!0);if(e&&(this._callCounterBlink(),i>0))return!1}return!0},checkCharCount:function(e,t){if(l.maxCharCount){const n=t||l.charCounterType,i=this.getCharLength("string"==typeof e?e:this._charTypeHTML?e.outerHTML:e.textContent,n);if(i>0&&i+h.getCharCount(n)>l.maxCharCount)return this._callCounterBlink(),!1}return!0},getCharLength:function(e,t){return/byte/.test(t)?r.getByteLength(e):e.length},_setCharCount:function(){e.element.charCounter&&a.setTimeout((function(){e.element.charCounter.textContent=h.getCharCount(l.charCounterType)}))},_callCounterBlink:function(){const t=e.element.charWrapper;t&&!r.hasClass(t,"se-blink")&&(r.addClass(t,"se-blink"),a.setTimeout((function(){r.removeClass(t,"se-blink")}),600))},_checkComponents:function(){for(let e=0,t=this._fileInfoPluginsCheck.length;e<t;e++)this._fileInfoPluginsCheck[e]()},_resetComponents:function(){for(let e=0,t=this._fileInfoPluginsReset.length;e<t;e++)this._fileInfoPluginsReset[e]()},_setCodeView:function(t){l.codeMirrorEditor?l.codeMirrorEditor.getDoc().setValue(t):e.element.code.value=t},_getCodeView:function(){return l.codeMirrorEditor?l.codeMirrorEditor.getDoc().getValue():e.element.code.value},_init:function(i,o){const c=a.RegExp;if(this._ww=l.iframe?e.element.wysiwygFrame.contentWindow:a,this._wd=s,this._charTypeHTML="byte-html"===l.charCounterType,!l.iframe&&"function"==typeof a.ShadowRoot){let t=e.element.wysiwygFrame;for(;t;){if(t.shadowRoot){this._shadowRoot=t.shadowRoot;break}if(t instanceof a.ShadowRoot){this._shadowRoot=t;break}t=t.parentNode}}const d=["b","i","ins","s","strike"],u=l.addTagsWhitelist?l.addTagsWhitelist.split("|").filter((function(e){return/b|i|ins|s|strike/i.test(e)})):[];for(let e=0;e<u.length;e++)d.splice(d.indexOf(u[e].toLowerCase()),1);this._disallowedTextTagsRegExp=0===d.length?null:new c("(<\\/?)("+d.join("|")+")\\b\\s*(?:[^>^<]+)?\\s*(?=>)","gi");const h="contenteditable|colspan|rowspan|target|href|src|class|type|controls|data-format|data-size|data-file-size|data-file-name|data-origin|data-align|data-image-link|data-rotate|data-proportion|data-percentage|origin-size|data-exp|data-font-size";this._allowHTMLComments=l._editorTagsWhitelist.indexOf("//")>-1,this._htmlCheckWhitelistRegExp=new c("^("+l._editorTagsWhitelist.replace("|//","")+")$","i"),this.editorTagsWhitelistRegExp=r.createTagsWhitelist(l._editorTagsWhitelist.replace("|//","|\x3c!--|--\x3e")),this.pasteTagsWhitelistRegExp=r.createTagsWhitelist(l.pasteTagsWhitelist);const g=l.attributesWhitelist,p={};let m="";if(g)for(let e in g)r.hasOwn(g,e)&&("all"===e?m=g[e]+"|":p[e]=new c("((?:"+g[e]+"|"+h+')s*=s*"[^"]*")',"ig"));this._attributesWhitelistRegExp=new c("((?:"+m+h+')s*=s*"[^"]*")',"ig"),this._attributesTagsWhitelist=p,this._isInline=/inline/i.test(l.mode),this._isBalloon=/balloon|balloon-always/i.test(l.mode),this._isBalloonAlways=/balloon-always/i.test(l.mode),this._cachingButtons(),this._fileInfoPluginsCheck=[],this._fileInfoPluginsReset=[],this.managedTagsInfo={query:"",map:{}};const f=[];this.activePlugins=[],this._fileManager.tags=[],this._fileManager.pluginMap={};let _,b,v=[];for(let e in n)if(r.hasOwn(n,e)){if(_=n[e],b=t[e],_.active&&b&&this.callPlugin(e,null,b),"function"==typeof _.checkFileInfo&&"function"==typeof _.resetFileInfo&&(this.callPlugin(e,null,b),this._fileInfoPluginsCheck.push(_.checkFileInfo.bind(this)),this._fileInfoPluginsReset.push(_.resetFileInfo.bind(this))),a.Array.isArray(_.fileTags)){const t=_.fileTags;this.callPlugin(e,null,b),this._fileManager.tags=this._fileManager.tags.concat(t),v.push(e);for(let n=0,i=t.length;n<i;n++)this._fileManager.pluginMap[t[n].toLowerCase()]=e}if(_.managedTags){const e=_.managedTags();f.push("."+e.className),this.managedTagsInfo.map[e.className]=e.method.bind(this)}}this.managedTagsInfo.query=f.toString(),this._fileManager.queryString=this._fileManager.tags.join(","),this._fileManager.regExp=new c("^("+this._fileManager.tags.join("|")+")$","i"),this._fileManager.pluginRegExp=new c("^("+(0===v.length?"undefined":v.join("|"))+")$","i"),this._variable._originCssText=e.element.topArea.style.cssText,this._placeholder=e.element.placeholder,this._lineBreaker=e.element.lineBreaker,this._lineBreakerButton=this._lineBreaker.querySelector("button"),this.history=function(e,t){const n=e._w,i=e.util,l=e.context.options.historyStackDelayTime;let o=e.context.element,s=e.context.tool.undo,a=e.context.tool.redo,r=null,c=0,d=[];function u(){const n=d[c];o.wysiwyg.innerHTML=n.contents,e.setRange(i.getNodeFromPath(n.s.path,o.wysiwyg),n.s.offset,i.getNodeFromPath(n.e.path,o.wysiwyg),n.e.offset),e.focus(),0===c?(s&&s.setAttribute("disabled",!0),a&&a.removeAttribute("disabled")):c===d.length-1?(s&&s.removeAttribute("disabled"),a&&a.setAttribute("disabled",!0)):(s&&s.removeAttribute("disabled"),a&&a.removeAttribute("disabled")),e.controllersOff(),e._checkComponents(),e._setCharCount(),e._resourcesStateChange(),t()}function h(){e._checkComponents();const n=e.getContents(!0);if(!n||d[c]&&n===d[c].contents)return;c++;const l=e._variable._range;d.length>c&&(d=d.slice(0,c),a&&a.setAttribute("disabled",!0)),d[c]=l?{contents:n,s:{path:i.getNodePath(l.startContainer,null,null),offset:l.startOffset},e:{path:i.getNodePath(l.endContainer,null,null),offset:l.endOffset}}:{contents:n,s:{path:[0,0],offset:[0,0]},e:{path:0,offset:0}},1===c&&s&&s.removeAttribute("disabled"),e._setCharCount(),t()}return{stack:d,push:function(t){n.setTimeout(e._resourcesStateChange.bind(e));const i="number"==typeof t?t>0?t:0:t?l:0;i&&!r||(n.clearTimeout(r),i)?r=n.setTimeout((function(){n.clearTimeout(r),r=null,h()}),i):h()},undo:function(){c>0&&(c--,u())},redo:function(){d.length-1>c&&(c++,u())},go:function(e){c=e<0?d.length-1:e,u()},reset:function(n){s&&s.setAttribute("disabled",!0),a&&a.setAttribute("disabled",!0),e.context.tool.save&&e.context.tool.save.setAttribute("disabled",!0),d.splice(0),c=0,d[c]={contents:e.getContents(!0),s:{path:[0,0],offset:0},e:{path:[0,0],offset:0}},n||t()},_resetCachingButton:function(){o=e.context.element,s=e.context.tool.undo,a=e.context.tool.redo,0===c?(s&&s.setAttribute("disabled",!0),a&&c===d.length-1&&a.setAttribute("disabled",!0),e.context.tool.save&&e.context.tool.save.setAttribute("disabled",!0)):c===d.length-1&&a&&a.setAttribute("disabled",!0)},_destroy:function(){r&&n.clearTimeout(r),d=null}}}(this,this._onChange_historyStack.bind(this)),this.addModule([B]),l.iframe&&(this._wd=e.element.wysiwygFrame.contentDocument,e.element.wysiwyg=this._wd.body,l._editorStyles.editor&&(e.element.wysiwyg.style.cssText=l._editorStyles.editor),"auto"===l.height&&(this._iframeAuto=this._wd.body)),this._initWysiwygArea(i,o)},_cachingButtons:function(){this.codeViewDisabledButtons=e.element.toolbar.querySelectorAll('.se-toolbar button:not([class~="se-code-view-enabled"])'),this.resizingDisabledButtons=e.element.toolbar.querySelectorAll('.se-toolbar button:not([class~="se-resizing-enabled"])');const t=e.tool;this.commandMap={STRONG:t.bold,U:t.underline,EM:t.italic,DEL:t.strike,SUB:t.subscript,SUP:t.superscript,OUTDENT:t.outdent,INDENT:t.indent},this._styleCommandMap={fullScreen:t.fullScreen,showBlocks:t.showBlocks,codeView:t.codeView}},_initWysiwygArea:function(t,n){e.element.wysiwyg.innerHTML=t?n:this.convertContentsForEditor("string"==typeof n?n:e.element.originElement.value)},_resourcesStateChange:function(){this._iframeAutoHeight(),this._checkPlaceholder()},_onChange_historyStack:function(){u._applyTagEffects(),e.tool.save&&e.tool.save.removeAttribute("disabled"),h.onChange&&h.onChange(this.getContents(!0),this)},_iframeAutoHeight:function(){this._iframeAuto&&a.setTimeout((function(){e.element.wysiwygFrame.style.height=d._iframeAuto.offsetHeight+"px"}))},_checkPlaceholder:function(){if(this._placeholder){if(this._variable.isCodeView)return void(this._placeholder.style.display="none");const t=e.element.wysiwyg;!r.onlyZeroWidthSpace(t.textContent)||t.querySelector(".se-component, pre, blockquote, hr, li, table, img, iframe, video")||(t.innerText.match(/\n/g)||"").length>1?this._placeholder.style.display="none":this._placeholder.style.display="block"}},_setDefaultFormat:function(e){if(this._fileManager.pluginRegExp.test(this.currentControllerName))return;const t=this.getRange(),n=t.commonAncestorContainer,i=t.startContainer,o=r.getRangeFormatElement(n,null);let s,a,c;const d=r.getParentElement(n,r.isComponent);if((!d||r.isTable(d))&&(!r.isRangeFormatElement(i)&&!r.isWysiwygDiv(i)||!r.isComponent(i.childNodes[t.startOffset]))){if(o)return c=r.createElement(e||l.defaultTag),c.innerHTML=o.innerHTML,0===c.childNodes.length&&(c.innerHTML=r.zeroWidthSpace),o.innerHTML=c.outerHTML,c=o.firstChild,s=r.getEdgeChildNodes(c,null).sc,s||(s=r.createTextNode(r.zeroWidthSpace),c.insertBefore(s,c.firstChild)),a=s.textContent.length,void this.setRange(s,a,s,a);if(r.isRangeFormatElement(n)&&n.childNodes.length<=1){let e=null;return 1===n.childNodes.length&&r.isBreak(n.firstChild)?e=n.firstChild:(e=r.createTextNode(r.zeroWidthSpace),n.appendChild(e)),void this.setRange(e,1,e,1)}if(this.execCommand("formatBlock",!1,e||l.defaultTag),s=r.getEdgeChildNodes(n,n),s=s?s.ec:n,c=r.getFormatElement(s,null),!c)return this.removeRange(),void this._editorRange();if(r.isBreak(c.nextSibling)&&r.removeItem(c.nextSibling),r.isBreak(c.previousSibling)&&r.removeItem(c.previousSibling),r.isBreak(s)){const e=r.createTextNode(r.zeroWidthSpace);s.parentNode.insertBefore(e,s),s=e}this.effectNode=null,this.nativeFocus()}},_setOptionsInit:function(t,n){this.context=e=k(t.originElement,this._getConstructed(t),l),this._componentsInfoReset=!0,this._editorInit(!0,n)},_editorInit:function(t,n){this._init(t,n),u._addEvent(),this._setCharCount(),u._offStickyToolbar(),u.onResize_window(),e.element.toolbar.style.visibility="",this._checkComponents(),this._componentsInfoInit=!1,this._componentsInfoReset=!1,this.history.reset(!0),this._resourcesStateChange(),a.setTimeout((function(){"function"==typeof h.onload&&h.onload(d,t)}))},_getConstructed:function(e){return{_top:e.topArea,_relative:e.relative,_toolBar:e.toolbar,_menuTray:e._menuTray,_editorArea:e.editorArea,_wysiwygArea:e.wysiwygFrame,_codeArea:e.code,_placeholder:e.placeholder,_resizingBar:e.resizingBar,_navigation:e.navigation,_charCounter:e.charCounter,_charWrapper:e.charWrapper,_loading:e.loading,_lineBreaker:e.lineBreaker,_lineBreaker_t:e.lineBreaker_t,_lineBreaker_b:e.lineBreaker_b,_resizeBack:e.resizeBackground,_stickyDummy:e._stickyDummy,_arrow:e._arrow}}},u={_IEisComposing:!1,_lineBreakerBind:null,_responsiveCurrentSize:"default",_responsiveButtonSize:null,_responsiveButtons:null,_directionKeyCode:new a.RegExp("^(8|13|3[2-9]|40|46)$"),_nonTextKeyCode:new a.RegExp("^(8|13|1[6-9]|20|27|3[3-9]|40|45|46|11[2-9]|12[0-3]|144|145)$"),_historyIgnoreKeyCode:new a.RegExp("^(1[6-9]|20|27|3[3-9]|40|45|11[2-9]|12[0-3]|144|145)$"),_onButtonsCheck:new a.RegExp("^(STRONG|U|EM|DEL|SUB|SUP)$"),_frontZeroWidthReg:new a.RegExp(r.zeroWidthSpace+"+",""),_keyCodeShortcut:{65:"A",66:"B",83:"S",85:"U",73:"I",89:"Y",90:"Z",219:"[",221:"]"},_shortcutCommand:function(e,t){let n=null;switch(u._keyCodeShortcut[e]){case"A":n="selectAll";break;case"B":-1===l.shortcutsDisable.indexOf("bold")&&(n="STRONG");break;case"S":t&&-1===l.shortcutsDisable.indexOf("strike")&&(n="DEL");break;case"U":-1===l.shortcutsDisable.indexOf("underline")&&(n="U");break;case"I":-1===l.shortcutsDisable.indexOf("italic")&&(n="EM");break;case"Z":-1===l.shortcutsDisable.indexOf("undo")&&(n=t?"redo":"undo");break;case"Y":-1===l.shortcutsDisable.indexOf("undo")&&(n="redo");break;case"[":-1===l.shortcutsDisable.indexOf("indent")&&(n=l.rtl?"indent":"outdent");break;case"]":-1===l.shortcutsDisable.indexOf("indent")&&(n=l.rtl?"outdent":"indent")}return!!n&&(d.commandHandler(d.commandMap[n],n),!0)},_applyTagEffects:function(){let t=d.getSelectionNode();if(t===d.effectNode)return;d.effectNode=t;const i=l.rtl?"marginRight":"marginLeft",o=d.commandMap,s=this._onButtonsCheck,a=[],c=[],u=d.activePlugins,h=u.length;let g="";for(;t.firstChild;)t=t.firstChild;for(let e=t;!r.isWysiwygDiv(e)&&e;e=e.parentNode)if(1===e.nodeType&&!r.isBreak(e)){g=e.nodeName.toUpperCase(),c.push(g);for(let t,i=0;i<h;i++)t=u[i],-1===a.indexOf(t)&&n[t].active.call(d,e)&&a.push(t);r.isFormatElement(e)?(-1===a.indexOf("OUTDENT")&&o.OUTDENT&&(r.isListCell(e)||e.style[i]&&r.getNumber(e.style[i],0)>0)&&(a.push("OUTDENT"),o.OUTDENT.removeAttribute("disabled")),-1===a.indexOf("INDENT")&&o.INDENT&&r.isListCell(e)&&!e.previousElementSibling&&(a.push("INDENT"),o.INDENT.setAttribute("disabled",!0))):s.test(g)&&(a.push(g),r.addClass(o[g],"active"))}for(let e in o)a.indexOf(e)>-1||!r.hasOwn(o,e)||(u.indexOf(e)>-1?n[e].active.call(d,null):o.OUTDENT&&/^OUTDENT$/i.test(e)?o.OUTDENT.setAttribute("disabled",!0):o.INDENT&&/^INDENT$/i.test(e)?o.INDENT.removeAttribute("disabled"):r.removeClass(o[e],"active"));d._variable.currentNodes=c.reverse(),d._variable.currentNodesMap=a,l.showPathLabel&&(e.element.navigation.textContent=d._variable.currentNodes.join(" > "))},_cancelCaptionEdit:function(){this.setAttribute("contenteditable",!1),this.removeEventListener("blur",u._cancelCaptionEdit)},_buttonsEventHandler:function(e){let t=e.target;if(d._bindControllersOff&&e.stopPropagation(),/^(input|textarea|select|option)$/i.test(t.nodeName)?d._antiBlur=!1:e.preventDefault(),r.getParentElement(t,".se-submenu"))e.stopPropagation(),d._notHideToolbar=!0;else{let n=t.getAttribute("data-command"),i=t.className;for(;!n&&!/se-menu-list/.test(i)&&!/sun-editor-common/.test(i);)t=t.parentNode,n=t.getAttribute("data-command"),i=t.className;n!==d._submenuName&&n!==d._containerName||e.stopPropagation()}},onClick_toolbar:function(e){let t=e.target,n=t.getAttribute("data-display"),i=t.getAttribute("data-command"),l=t.className;for(;t.parentNode&&!i&&!/se-menu-list/.test(l)&&!/se-toolbar/.test(l);)t=t.parentNode,i=t.getAttribute("data-command"),n=t.getAttribute("data-display"),l=t.className;(i||n)&&(t.disabled||(d.hasFocus||d.nativeFocus(),d._variable.isCodeView||d._editorRange(),d.actionCall(i,n,t)))},onMouseDown_wysiwyg:function(t){if(r.isNonEditable(e.element.wysiwyg))return;const n=r.getParentElement(t.target,r.isCell);if(n){const e=d.plugins.table;e&&n!==e._fixedCell&&!e._shift&&d.callPlugin("table",(function(){e.onTableCellMultiSelect.call(d,n,!1)}),null)}d._isBalloon&&u._hideToolbar(),/FIGURE/i.test(t.target.nodeName)&&t.preventDefault(),"function"==typeof h.onMouseDown&&h.onMouseDown(t,d)},onClick_wysiwyg:function(t){const n=t.target;if(r.isNonEditable(e.element.wysiwyg))return;const i=d.getFileComponent(n);if(i)return t.preventDefault(),void d.selectComponent(i.target,i.pluginName);const o=r.getParentElement(n,"FIGCAPTION");if(r.isNonEditable(o)&&(t.preventDefault(),o.setAttribute("contenteditable",!0),o.focus(),d._isInline&&!d._inlineToolbarAttr.isShow)){u._showToolbarInline();const e=function(){u._hideToolbar(),o.removeEventListener("blur",e)};o.addEventListener("blur",e)}a.setTimeout(d._editorRange.bind(d)),d._editorRange();const s=d.getSelectionNode(),c=r.getFormatElement(s,null),g=r.getRangeFormatElement(s,null);if(c&&c!==g||r.isNonEditable(n)||r.isList(g))u._applyTagEffects();else{const e=d.getRange();if(r.getFormatElement(e.startContainer)===r.getFormatElement(e.endContainer)){if(r.isList(g)){const e=r.createElement("LI"),t=s.nextElementSibling;e.appendChild(s),g.insertBefore(e,t)}else r.isWysiwygDiv(s)||r.isComponent(s)||r.isTable(s)&&!r.isCell(s)||d._setDefaultFormat(r.isRangeFormatElement(g)?"DIV":l.defaultTag);t.preventDefault(),d.focus()}}d._isBalloon&&a.setTimeout(u._toggleToolbarBalloon),"function"==typeof h.onClick&&h.onClick(t,d)},_balloonDelay:null,_showToolbarBalloonDelay:function(){u._balloonDelay&&a.clearTimeout(u._balloonDelay),u._balloonDelay=a.setTimeout(function(){a.clearTimeout(this._balloonDelay),this._balloonDelay=null,this._showToolbarBalloon()}.bind(u),350)},_toggleToolbarBalloon:function(){d._editorRange();const e=d.getRange();d._bindControllersOff||!d._isBalloonAlways&&e.collapsed?u._hideToolbar():u._showToolbarBalloon(e)},_showToolbarBalloon:function(t){if(!d._isBalloon)return;const n=t||d.getRange(),i=e.element.toolbar,o=e.element.topArea,s=d.getSelection();let c;if(d._isBalloonAlways&&n.collapsed)c=!0;else if(s.focusNode===s.anchorNode)c=s.focusOffset<s.anchorOffset;else{const e=r.getListChildNodes(n.commonAncestorContainer,null);c=r.getArrayIndex(e,s.focusNode)<r.getArrayIndex(e,s.anchorNode)}let h=n.getClientRects();h=h[c?0:h.length-1];let g=0,p=0,m=o;for(;m;)g+=m.scrollLeft,p+=m.scrollTop,m=m.parentElement;const f=o.offsetWidth,_=u._getEditorOffsets(null),b=_.top,v=_.left;if(i.style.top="-10000px",i.style.visibility="hidden",i.style.display="block",!h){const t=d.getSelectionNode();if(r.isFormatElement(t)){const e=r.createTextNode(r.zeroWidthSpace);d.insertNode(e,null,!1),d.setRange(e,1,e,1),d._editorRange(),h=d.getRange().getClientRects(),h=h[c?0:h.length-1]}if(!h){const n=r.getOffset(t,e.element.wysiwygFrame);h={left:n.left,top:n.top,right:n.left,bottom:n.top+t.offsetHeight,noText:!0},g=0,p=0}c=!0}const y=a.Math.round(e.element._arrow.offsetWidth/2),C=i.offsetWidth,w=i.offsetHeight,x=/iframe/i.test(e.element.wysiwygFrame.nodeName)?e.element.wysiwygFrame.getClientRects()[0]:null;if(x&&(h={left:h.left+x.left,top:h.top+x.top,right:h.right+x.right-x.width,bottom:h.bottom+x.bottom-x.height}),u._setToolbarOffset(c,h,i,v,f,g,p,b,y),C===i.offsetWidth&&w===i.offsetHeight||u._setToolbarOffset(c,h,i,v,f,g,p,b,y),l.toolbarContainer){const e=o.parentElement;let t=l.toolbarContainer,n=t.offsetLeft,s=t.offsetTop;for(;!t.parentElement.contains(e)||!/^(BODY|HTML)$/i.test(t.parentElement.nodeName);)t=t.offsetParent,n+=t.offsetLeft,s+=t.offsetTop;i.style.left=i.offsetLeft-n+o.offsetLeft+"px",i.style.top=i.offsetTop-s+o.offsetTop+"px"}i.style.visibility=""},_setToolbarOffset:function(t,n,i,l,o,c,d,h,g){const p=i.offsetWidth,m=n.noText&&!t?0:i.offsetHeight,f=(t?n.left:n.right)-l-p/2+c,_=f+p-o;let b=(t?n.top-m-g:n.bottom+g)-(n.noText?0:h)+d,v=f<0?1:_<0?f:f-_-1-1,y=!1;const C=b+(t?u._getEditorOffsets(null).top:i.offsetHeight-e.element.wysiwyg.offsetHeight);!t&&C>0&&u._getPageBottomSpace()<C?(t=!0,y=!0):t&&s.documentElement.offsetTop>C&&(t=!1,y=!0),y&&(b=(t?n.top-m-g:n.bottom+g)-(n.noText?0:h)+d),i.style.left=a.Math.floor(v)+"px",i.style.top=a.Math.floor(b)+"px",t?(r.removeClass(e.element._arrow,"se-arrow-up"),r.addClass(e.element._arrow,"se-arrow-down"),e.element._arrow.style.top=m+"px"):(r.removeClass(e.element._arrow,"se-arrow-down"),r.addClass(e.element._arrow,"se-arrow-up"),e.element._arrow.style.top=-g+"px");const w=a.Math.floor(p/2+(f-v));e.element._arrow.style.left=(w+g>i.offsetWidth?i.offsetWidth-g:w<g?g:w)+"px"},_showToolbarInline:function(){if(!d._isInline)return;const t=e.element.toolbar;l.toolbarContainer?t.style.position="relative":t.style.position="absolute",t.style.visibility="hidden",t.style.display="block",d._inlineToolbarAttr.width=t.style.width=l.toolbarWidth,d._inlineToolbarAttr.top=t.style.top=(l.toolbarContainer?0:-1-t.offsetHeight)+"px","function"==typeof h.showInline&&h.showInline(t,e,d),u.onScroll_window(),d._inlineToolbarAttr.isShow=!0,t.style.visibility=""},_hideToolbar:function(){d._notHideToolbar||d._variable.isFullScreen||(e.element.toolbar.style.display="none",d._inlineToolbarAttr.isShow=!1)},onInput_wysiwyg:function(e){d._editorRange();const t=(null===e.data?"":void 0===e.data?" ":e.data)||"";d._charCount(t)||(e.preventDefault(),e.stopPropagation()),d.history.push(!0),"function"==typeof h.onInput&&h.onInput(e,d)},_onShortcutKey:!1,onKeyDown_wysiwyg:function(t){const n=t.keyCode,i=t.shiftKey,o=t.ctrlKey||t.metaKey||91===n||92===n||224===n,s=t.altKey;if(u._IEisComposing=229===n,d.submenuOff(),d._isBalloon&&u._hideToolbar(),o&&u._shortcutCommand(n,i))return u._onShortcutKey=!0,t.preventDefault(),t.stopPropagation(),!1;u._onShortcutKey&&(u._onShortcutKey=!1);let c=d.getSelectionNode();const g=d.getRange(),p=!g.collapsed||g.startContainer!==g.endContainer,m=d._fileManager.pluginRegExp.test(d.currentControllerName)?d.currentControllerName:"";let f=r.getFormatElement(c,null)||c,_=r.getRangeFormatElement(f,null);switch(n){case 8:if(!p&&m){t.preventDefault(),t.stopPropagation(),d.plugins[m].destroy.call(d);break}if(p&&u._hardDelete()){t.preventDefault(),t.stopPropagation();break}if(!r.isFormatElement(f)&&!e.element.wysiwyg.firstElementChild&&!r.isComponent(c))return t.preventDefault(),t.stopPropagation(),d._setDefaultFormat(l.defaultTag),!1;if(!p&&!f.previousElementSibling&&0===g.startOffset&&!c.previousSibling&&!r.isListCell(f)&&r.isFormatElement(f)&&(!r.isFreeFormatElement(f)||r.isClosureFreeFormatElement(f))){if(r.isClosureRangeFormatElement(f.parentNode))return t.preventDefault(),t.stopPropagation(),!1;if(r.isWysiwygDiv(f.parentNode)&&f.childNodes.length<=1&&(!f.firstChild||r.onlyZeroWidthSpace(f.textContent))){t.preventDefault(),t.stopPropagation(),f.innerHTML="<br>";const e=f.attributes;for(;e[0];)f.removeAttribute(e[0].name);return d.nativeFocus(),!1}}if(f&&g.startContainer===g.endContainer&&3===c.nodeType&&!r.isFormatElement(c.parentNode)&&(g.collapsed?1===c.textContent.length:g.endOffset-g.startOffset===c.textContent.length)){t.preventDefault();let e=null,n=c.parentNode.previousSibling;const i=c.parentNode.nextSibling;n||(i?(n=i,e=0):(n=r.createElement("BR"),f.appendChild(n))),c.textContent="",r.removeItemAllParents(c,null,f),e="number"==typeof e?e:3===n.nodeType?n.textContent.length:1,d.setRange(n,e,n,e);break}const n=g.commonAncestorContainer;if(f=r.getFormatElement(g.startContainer,null),_=r.getRangeFormatElement(f,null),_&&f&&!r.isCell(_)&&!/^FIGCAPTION$/i.test(_.nodeName)){if(r.isListCell(f)&&r.isList(_)&&(r.isListCell(_.parentNode)||f.previousElementSibling)&&(c===f||3===c.nodeType&&(!c.previousSibling||r.isList(c.previousSibling)))&&(r.getFormatElement(g.startContainer,null)!==r.getFormatElement(g.endContainer,null)?_.contains(g.startContainer):0===g.startOffset&&g.collapsed)){if(g.startContainer!==g.endContainer)t.preventDefault(),d.removeNode(),3===g.startContainer.nodeType&&d.setRange(g.startContainer,g.startContainer.textContent.length,g.startContainer,g.startContainer.textContent.length),d.history.push(!0);else{let e=f.previousElementSibling||_.parentNode;if(r.isListCell(e)){t.preventDefault();let n=e;if(!e.contains(f)&&r.isListCell(n)&&r.isList(n.lastElementChild)){for(n=n.lastElementChild.lastElementChild;r.isListCell(n)&&r.isList(n.lastElementChild);)n=n.lastElementChild&&n.lastElementChild.lastElementChild;e=n}let i=e===_.parentNode?_.previousSibling:e.lastChild;i||(i=r.createTextNode(r.zeroWidthSpace),_.parentNode.insertBefore(i,_.parentNode.firstChild));const l=3===i.nodeType?i.textContent.length:1,o=f.childNodes;let s=i,a=o[0];for(;a=o[0];)e.insertBefore(a,s.nextSibling),s=a;r.removeItem(f),0===_.children.length&&r.removeItem(_),d.setRange(i,l,i,l),d.history.push(!0)}}break}if(!p&&0===g.startOffset){let e=!0,i=n;for(;i&&i!==_&&!r.isWysiwygDiv(i);){if(i.previousSibling&&(1===i.previousSibling.nodeType||!r.onlyZeroWidthSpace(i.previousSibling.textContent.trim()))){e=!1;break}i=i.parentNode}if(e&&_.parentNode){t.preventDefault(),d.detachRangeFormatElement(_,r.isListCell(f)?[f]:null,null,!1,!1),d.history.push(!0);break}}}if(!p&&(0===g.startOffset||c===f&&f.childNodes[g.startOffset])){const e=c===f?f.childNodes[g.startOffset]:c,i=(3===n.nodeType||r.isBreak(n))&&!n.previousSibling&&0===g.startOffset;if(!e.previousSibling&&(r.isComponent(n.previousSibling)||i&&r.isComponent(f.previousSibling))){const e=d.getFileComponent(f.previousSibling);e&&(t.preventDefault(),t.stopPropagation(),0===f.textContent.length&&r.removeItem(f),d.selectComponent(e.target,e.pluginName));break}if(r.isNonEditable(e.previousSibling)){t.preventDefault(),t.stopPropagation(),r.removeItem(e.previousSibling);break}}break;case 46:if(m){t.preventDefault(),t.stopPropagation(),d.plugins[m].destroy.call(d);break}if(p&&u._hardDelete()){t.preventDefault(),t.stopPropagation();break}if((r.isFormatElement(c)||null===c.nextSibling||r.onlyZeroWidthSpace(c.nextSibling)&&null===c.nextSibling.nextSibling)&&g.startOffset===c.textContent.length){let e=f.nextElementSibling;if(!e){t.preventDefault();break}if(r.isComponent(e)){if(t.preventDefault(),r.onlyZeroWidthSpace(f)&&(r.removeItem(f),r.isTable(e))){let t=r.getChildElement(e,r.isCell,!1);t=t.firstElementChild||t,d.setRange(t,0,t,0);break}const n=d.getFileComponent(e);n&&(t.stopPropagation(),d.selectComponent(n.target,n.pluginName));break}}if(!p&&(d.isEdgePoint(g.endContainer,g.endOffset)||c===f&&f.childNodes[g.startOffset])){const e=c===f?f.childNodes[g.startOffset]:c;if(r.isNonEditable(e.nextSibling)){t.preventDefault(),t.stopPropagation(),r.removeItem(e.nextSibling);break}}if(f=r.getFormatElement(g.startContainer,null),_=r.getRangeFormatElement(f,null),r.isListCell(f)&&r.isList(_)&&(c===f||3===c.nodeType&&(!c.nextSibling||r.isList(c.nextSibling))&&(r.getFormatElement(g.startContainer,null)!==r.getFormatElement(g.endContainer,null)?_.contains(g.endContainer):g.endOffset===c.textContent.length&&g.collapsed))){g.startContainer!==g.endContainer&&d.removeNode();let e=r.getArrayItem(f.children,r.isList,!1);if(e=e||f.nextElementSibling||_.parentNode.nextElementSibling,e&&(r.isList(e)||r.getArrayItem(e.children,r.isList,!1))){let n,i;if(t.preventDefault(),r.isList(e)){const t=e.firstElementChild;for(i=t.childNodes,n=i[0];i[0];)f.insertBefore(i[0],e);r.removeItem(t)}else{for(n=e.firstChild,i=e.childNodes;i[0];)f.appendChild(i[0]);r.removeItem(e)}d.setRange(n,0,n,0),d.history.push(!0)}break}break;case 9:if(m||l.tabDisable)break;if(t.preventDefault(),o||s||r.isWysiwygDiv(c))break;const b=!g.collapsed||d.isEdgePoint(g.startContainer,g.startOffset),v=d.getSelectedElements(null);c=d.getSelectionNode();const y=[];let C=[],w=r.isListCell(v[0]),x=r.isListCell(v[v.length-1]),E={sc:g.startContainer,so:g.startOffset,ec:g.endContainer,eo:g.endOffset};for(let e,t=0,n=v.length;t<n;t++)if(e=v[t],r.isListCell(e)){if(!e.previousElementSibling&&!i)continue;y.push(e)}else C.push(e);if(y.length>0&&b&&d.plugins.list)E=d.plugins.list.editInsideList.call(d,i,y);else{const e=r.getParentElement(c,r.isCell);if(e&&b){const t=r.getParentElement(e,"table"),n=r.getListChildren(t,r.isCell);let l=i?r.prevIdx(n,e):r.nextIdx(n,e);l!==n.length||i||(l=0),-1===l&&i&&(l=n.length-1);let o=n[l];if(!o)break;o=o.firstElementChild||o,d.setRange(o,0,o,0);break}C=C.concat(y),w=x=null}if(C.length>0)if(i){const e=C.length-1;for(let t,n=0;n<=e;n++){t=C[n].childNodes;for(let e,n=0,i=t.length;n<i&&(e=t[n],e);n++)if(!r.onlyZeroWidthSpace(e)){/^\s{1,4}$/.test(e.textContent)?r.removeItem(e):/^\s{1,4}/.test(e.textContent)&&(e.textContent=e.textContent.replace(/^\s{1,4}/,""));break}}const t=r.getChildElement(C[0],"text",!1),n=r.getChildElement(C[e],"text",!0);!w&&t&&(E.sc=t,E.so=0),!x&&n&&(E.ec=n,E.eo=n.textContent.length)}else{const e=r.createTextNode(new a.Array(d._variable.tabSize+1).join(" "));if(1===C.length){const t=d.insertNode(e,null,!0);if(!t)return!1;w||(E.sc=e,E.so=t.endOffset),x||(E.ec=e,E.eo=t.endOffset)}else{const t=C.length-1;for(let n,i=0;i<=t;i++)n=C[i].firstChild,n&&(r.isBreak(n)?C[i].insertBefore(e.cloneNode(!1),n):n.textContent=e.textContent+n.textContent);const n=r.getChildElement(C[0],"text",!1),i=r.getChildElement(C[t],"text",!0);!w&&n&&(E.sc=n,E.so=0),!x&&i&&(E.ec=i,E.eo=i.textContent.length)}}d.setRange(E.sc,E.so,E.ec,E.eo),d.history.push(!1);break;case 13:const S=r.getFreeFormatElement(c,null);if(d._charTypeHTML){let e="";if(e=!i&&S||i?"<br>":"<"+f.nodeName+"><br></"+f.nodeName+">",!d.checkCharCount(e,"byte-html"))return t.preventDefault(),!1}if(!i&&S){t.preventDefault();const e=c===S,n=d.getSelection(),i=c.childNodes,l=n.focusOffset,o=c.previousElementSibling,s=c.nextSibling;if(!r.isClosureFreeFormatElement(S)&&i&&(e&&g.collapsed&&i.length-1<=l+1&&r.isBreak(i[l])&&(!i[l+1]||(!i[l+2]||r.onlyZeroWidthSpace(i[l+2].textContent))&&3===i[l+1].nodeType&&r.onlyZeroWidthSpace(i[l+1].textContent))&&l>0&&r.isBreak(i[l-1])||!e&&r.onlyZeroWidthSpace(c.textContent)&&r.isBreak(o)&&(r.isBreak(o.previousSibling)||!r.onlyZeroWidthSpace(o.previousSibling.textContent))&&(!s||!r.isBreak(s)&&r.onlyZeroWidthSpace(s.textContent)))){e?r.removeItem(i[l-1]):r.removeItem(c);const t=d.appendFormatTag(S,r.isFormatElement(S.nextElementSibling)?S.nextElementSibling:null);r.copyFormatAttributes(t,S),d.setRange(t,1,t,1);break}if(e){h.insertHTML(g.collapsed&&r.isBreak(g.startContainer.childNodes[g.startOffset-1])?"<br>":"<br><br>",!0,!1);let e=n.focusNode;const t=n.focusOffset;S===e&&(e=e.childNodes[t-l>1?t-1:t]),d.setRange(e,1,e,1)}else{const e=n.focusNode.nextSibling,t=r.createElement("BR");d.insertNode(t,null,!1);const i=t.previousSibling,l=t.nextSibling;r.isBreak(e)||r.isBreak(i)||l&&!r.onlyZeroWidthSpace(l)?d.setRange(l,0,l,0):(t.parentNode.insertBefore(t.cloneNode(!1),t),d.setRange(t,1,t,1))}u._onShortcutKey=!0;break}if(p)break;if(_&&f&&!r.isCell(_)&&!/^FIGCAPTION$/i.test(_.nodeName)){const e=d.getRange();if(d.isEdgePoint(e.endContainer,e.endOffset)&&r.isList(c.nextSibling)){t.preventDefault();const e=r.createElement("LI"),n=r.createElement("BR");e.appendChild(n),f.parentNode.insertBefore(e,f.nextElementSibling),e.appendChild(c.nextSibling),d.setRange(n,1,n,1);break}if((3!==e.commonAncestorContainer.nodeType||!e.commonAncestorContainer.nextElementSibling)&&r.onlyZeroWidthSpace(f.innerText.trim())){t.preventDefault();let e=null;if(r.isListCell(_.parentNode)){if(_=f.parentNode.parentNode.parentNode,e=r.splitElement(f,null,r.getElementDepth(f)-2),!e){const t=r.createElement("LI");t.innerHTML="<br>",_.insertBefore(t,e),e=t}}else{const t=r.isCell(_.parentNode)?"DIV":r.isList(_.parentNode)?"LI":r.isFormatElement(_.nextElementSibling)?_.nextElementSibling.nodeName:r.isFormatElement(_.previousElementSibling)?_.previousElementSibling.nodeName:l.defaultTag;e=r.createElement(t);const n=d.detachRangeFormatElement(_,[f],null,!0,!0);n.cc.insertBefore(e,n.ec)}e.innerHTML="<br>",r.copyFormatAttributes(e,f),r.removeItemAllParents(f,null,null),d.setRange(e,1,e,1);break}}if(_&&r.getParentElement(_,"FIGCAPTION")&&r.getParentElement(_,r.isList)&&(t.preventDefault(),f=d.appendFormatTag(f,null),d.setRange(f,0,f,0)),m){t.preventDefault(),t.stopPropagation();const n=e[m],i=n._container,o=i.previousElementSibling||i.nextElementSibling;let s=null;r.isListCell(i.parentNode)?s=r.createElement("BR"):(s=r.createElement(r.isFormatElement(o)?o.nodeName:l.defaultTag),s.innerHTML="<br>"),i.parentNode.insertBefore(s,i),d.callPlugin(m,(function(){d.selectComponent(n._element,m)}),null)}break;case 27:if(m)return t.preventDefault(),t.stopPropagation(),d.controllersOff(),!1}if(i&&16===n){t.preventDefault(),t.stopPropagation();const e=d.plugins.table;if(e&&!e._shift&&!e._ref){const t=r.getParentElement(f,r.isCell);if(t)return void e.onTableCellMultiSelect.call(d,t,!0)}}if(!(o||s||p||u._nonTextKeyCode.test(n))&&g.collapsed&&g.startContainer===g.endContainer&&r.isBreak(g.commonAncestorContainer)){const e=r.createTextNode(r.zeroWidthSpace);d.insertNode(e,null,!1),d.setRange(e,1,e,1)}"function"==typeof h.onKeyDown&&h.onKeyDown(t,d)},onKeyUp_wysiwyg:function(e){if(u._onShortcutKey)return;d._editorRange();const t=d.getRange(),n=e.keyCode,i=e.ctrlKey||e.metaKey||91===n||92===n||224===n,o=e.altKey;let s=d.getSelectionNode();if(d._isBalloon&&(d._isBalloonAlways&&27!==n||!t.collapsed)){if(!d._isBalloonAlways)return void u._showToolbarBalloon();27!==n&&u._showToolbarBalloonDelay()}if(8===n&&r.isWysiwygDiv(s)&&""===s.textContent&&0===s.children.length){e.preventDefault(),e.stopPropagation(),s.innerHTML="";const t=r.createElement(r.isFormatElement(d._variable.currentNodes[0])?d._variable.currentNodes[0]:l.defaultTag);return t.innerHTML="<br>",s.appendChild(t),d.setRange(t,0,t,0),u._applyTagEffects(),void d.history.push(!1)}const a=r.getFormatElement(s,null),c=r.getRangeFormatElement(s,null);(a||!t.collapsed)&&a!==c||r.isComponent(s)||r.isList(s)||(d._setDefaultFormat(r.isRangeFormatElement(c)?"DIV":l.defaultTag),s=d.getSelectionNode()),u._directionKeyCode.test(n)&&u._applyTagEffects();if(!i&&!o&&!u._nonTextKeyCode.test(n)&&3===s.nodeType&&r.zeroWidthRegExp.test(s.textContent)&&!(void 0!==e.isComposing?e.isComposing:u._IEisComposing)){let e=t.startOffset,n=t.endOffset;const i=(s.textContent.substring(0,n).match(u._frontZeroWidthReg)||"").length;e=t.startOffset-i,n=t.endOffset-i,s.textContent=s.textContent.replace(r.zeroWidthRegExp,""),d.setRange(s,e<0?0:e,s,n<0?0:n)}d._charCount(""),d.history.push(!0),"function"==typeof h.onKeyUp&&h.onKeyUp(e,d)},onScroll_wysiwyg:function(e){d.controllersOff(),d._lineBreaker.style.display="none",d._isBalloon&&u._hideToolbar(),"function"==typeof h.onScroll&&h.onScroll(e,d)},onFocus_wysiwyg:function(e){d._antiBlur||(d.hasFocus=!0,d._isInline&&u._showToolbarInline(),"function"==typeof h.onFocus&&h.onFocus(e,d))},onBlur_wysiwyg:function(t){if(d._antiBlur||d._variable.isCodeView)return;d.hasFocus=!1,d.controllersOff(),(d._isInline||d._isBalloon)&&u._hideToolbar(),"function"==typeof h.onBlur&&h.onBlur(t,d);const i=d.commandMap,o=d.activePlugins;for(let e in i)r.hasOwn(i,e)&&(o.indexOf(e)>-1?n[e].active.call(d,null):i.OUTDENT&&/^OUTDENT$/i.test(e)?i.OUTDENT.setAttribute("disabled",!0):i.INDENT&&/^INDENT$/i.test(e)?i.INDENT.removeAttribute("disabled"):r.removeClass(i[e],"active"));d._variable.currentNodes=[],d._variable.currentNodesMap=[],l.showPathLabel&&(e.element.navigation.textContent="")},onMouseDown_resizingBar:function(t){t.stopPropagation(),d._variable.resizeClientY=t.clientY,e.element.resizeBackground.style.display="block",s.addEventListener("mousemove",u._resize_editor),s.addEventListener("mouseup",(function t(){e.element.resizeBackground.style.display="none",s.removeEventListener("mousemove",u._resize_editor),s.removeEventListener("mouseup",t)}))},_resize_editor:function(t){const n=e.element.editorArea.offsetHeight+(t.clientY-d._variable.resizeClientY);e.element.wysiwygFrame.style.height=e.element.code.style.height=(n<d._variable.minResizingSize?d._variable.minResizingSize:n)+"px",d._variable.resizeClientY=t.clientY},onResize_window:function(){d.controllersOff();const t=u._responsiveButtonSize;if(t){const e=a.innerWidth;let n="default";for(let i=1,l=t.length;i<l;i++)if(e<t[i]){n=t[i]+"";break}u._responsiveCurrentSize!==n&&(u._responsiveCurrentSize=n,h.setToolbarButtons(u._responsiveButtons[n]))}if(0!==e.element.toolbar.offsetWidth){if(e.fileBrowser&&"block"===e.fileBrowser.area.style.display&&(e.fileBrowser.body.style.maxHeight=a.innerHeight-e.fileBrowser.header.offsetHeight-50+"px"),d.submenuActiveButton&&d.submenu&&d._setMenuPosition(d.submenuActiveButton,d.submenu),d._variable.isFullScreen)return d._variable.innerHeight_fullScreen+=a.innerHeight-e.element.toolbar.offsetHeight-d._variable.innerHeight_fullScreen,void(e.element.editorArea.style.height=d._variable.innerHeight_fullScreen+"px");d._variable.isCodeView&&d._isInline?u._showToolbarInline():(d._iframeAutoHeight(),d._sticky&&(e.element.toolbar.style.width=e.element.topArea.offsetWidth-2+"px",u.onScroll_window()))}},onScroll_window:function(){if(d._variable.isFullScreen||0===e.element.toolbar.offsetWidth||l.stickyToolbar<0)return;const t=e.element,n=t.editorArea.offsetHeight,i=(this.scrollY||s.documentElement.scrollTop)+l.stickyToolbar,o=u._getEditorOffsets(l.toolbarContainer).top-(d._isInline?t.toolbar.offsetHeight:0);i<o?u._offStickyToolbar():i+d._variable.minResizingSize>=n+o?(d._sticky||u._onStickyToolbar(),t.toolbar.style.top=n+o+l.stickyToolbar-i-d._variable.minResizingSize+"px"):i>=o&&u._onStickyToolbar()},_getEditorOffsets:function(t){let n=t||e.element.topArea,i=0,l=0,o=0;for(;n;)i+=n.offsetTop,l+=n.offsetLeft,o+=n.scrollTop,n=n.offsetParent;return{top:i,left:l,scroll:o}},_getPageBottomSpace:function(){return s.documentElement.scrollHeight-(u._getEditorOffsets(null).top+e.element.topArea.offsetHeight)},_onStickyToolbar:function(){const t=e.element;d._isInline||l.toolbarContainer||(t._stickyDummy.style.height=t.toolbar.offsetHeight+"px",t._stickyDummy.style.display="block"),t.toolbar.style.top=l.stickyToolbar+"px",t.toolbar.style.width=d._isInline?d._inlineToolbarAttr.width:t.toolbar.offsetWidth+"px",r.addClass(t.toolbar,"se-toolbar-sticky"),d._sticky=!0},_offStickyToolbar:function(){const t=e.element;t._stickyDummy.style.display="none",t.toolbar.style.top=d._isInline?d._inlineToolbarAttr.top:"",t.toolbar.style.width=d._isInline?d._inlineToolbarAttr.width:"",t.editorArea.style.marginTop="",r.removeClass(t.toolbar,"se-toolbar-sticky"),d._sticky=!1},_codeViewAutoHeight:function(){e.element.code.style.height=e.element.code.scrollHeight+"px"},_hardDelete:function(){const e=d.getRange(),t=e.startContainer,n=e.endContainer,i=r.getRangeFormatElement(t),l=r.getRangeFormatElement(n),o=r.isCell(i),s=r.isCell(l);if((o&&!i.previousElementSibling&&!i.parentElement.previousElementSibling||s&&!l.nextElementSibling&&!l.parentElement.nextElementSibling)&&i!==l)if(o){if(s)return r.removeItem(r.getParentElement(i,r.isComponent)),d.nativeFocus(),!0;r.removeItem(r.getParentElement(i,r.isComponent))}else r.removeItem(r.getParentElement(l,r.isComponent));const a=1===t.nodeType?r.getParentElement(t,".se-component"):null,c=1===n.nodeType?r.getParentElement(n,".se-component"):null;return a&&r.removeItem(a),c&&r.removeItem(c),!1},onPaste_wysiwyg:function(e){const t=r.isIE?a.clipboardData:e.clipboardData;return!t||u._dataTransferAction("paste",e,t)},_setClipboardComponent:function(e,t,n){e.preventDefault(),e.stopPropagation(),n.setData("text/html",t.component.outerHTML)},onCopy_wysiwyg:function(e){const t=r.isIE?a.clipboardData:e.clipboardData;if("function"==typeof h.onCopy&&!h.onCopy(e,t,d))return e.preventDefault(),e.stopPropagation(),!1;const n=d.currentFileComponentInfo;n&&!r.isIE&&(u._setClipboardComponent(e,n,t),r.addClass(n.component,"se-component-copy"),a.setTimeout((function(){r.removeClass(n.component,"se-component-copy")}),150))},onCut_wysiwyg:function(e){const t=r.isIE?a.clipboardData:e.clipboardData;if("function"==typeof h.onCut&&!h.onCut(e,t,d))return e.preventDefault(),e.stopPropagation(),!1;const n=d.currentFileComponentInfo;n&&!r.isIE&&(u._setClipboardComponent(e,n,t),r.removeItem(n.component),d.controllersOff()),a.setTimeout((function(){d.history.push(!1)}))},onDrop_wysiwyg:function(e){const t=e.dataTransfer;return!t||(r.isIE?(e.preventDefault(),e.stopPropagation(),!1):(d.removeNode(),u._setDropLocationSelection(e),u._dataTransferAction("drop",e,t)))},_setDropLocationSelection:function(e){if(e.rangeParent)d.setRange(e.rangeParent,e.rangeOffset,e.rangeParent,e.rangeOffset);else if(d._wd.caretRangeFromPoint){const t=d._wd.caretRangeFromPoint(e.clientX,e.clientY);d.setRange(t.startContainer,t.startOffset,t.endContainer,t.endOffset)}else{const e=d.getRange();d.setRange(e.startContainer,e.startOffset,e.endContainer,e.endOffset)}},_dataTransferAction:function(t,n,i){let l,o;if(r.isIE){l=i.getData("Text");const s=d.getRange(),c=r.createElement("DIV"),h={sc:s.startContainer,so:s.startOffset,ec:s.endContainer,eo:s.endOffset};return c.setAttribute("contenteditable",!0),c.style.cssText="position:absolute; top:0; left:0; width:1px; height:1px; overflow:hidden;",e.element.relative.appendChild(c),c.focus(),a.setTimeout((function(){o=c.innerHTML,r.removeItem(c),d.setRange(h.sc,h.so,h.ec,h.eo),u._setClipboardData(t,n,l,o,i)})),!0}if(l=i.getData("text/plain"),o=i.getData("text/html")||l,!1===u._setClipboardData(t,n,l,o,i))return n.preventDefault(),n.stopPropagation(),!1},_setClipboardData:function(e,t,n,i,l){/class=["']*Mso(Normal|List)/i.test(i)||/content=["']*Word.Document/i.test(i)||/content=["']*OneNote.File/i.test(i)?(i=i.replace(/\n/g," "),n=n.replace(/\n/g," ")):n=n.replace(/\n/g,""),i=d.cleanHTML(i,d.pasteTagsWhitelistRegExp);const o=d._charCount(d._charTypeHTML?i:n);if("paste"===e&&"function"==typeof h.onPaste){const e=h.onPaste(t,i,o,d);if(!e)return!1;"string"==typeof e&&(i=e)}if("drop"===e&&"function"==typeof h.onDrop){const e=h.onDrop(t,i,o,d);if(!e)return!1;"string"==typeof e&&(i=e)}const s=l.files;return s.length>0?(/^image/.test(s[0].type)&&d.plugins.image&&h.insertImage(s),!1):!!o&&(i?(h.insertHTML(i,!0,!1),!1):void 0)},onMouseMove_wysiwyg:function(t){if(d.isDisabled)return;const n=r.getParentElement(t.target,r.isComponent),i=d._lineBreaker.style;if(n&&!d.currentControllerName){let o=0,s=e.element.wysiwyg;do{o+=s.scrollTop,s=s.parentElement}while(s&&!/^(BODY|HTML)$/i.test(s.nodeName));const a=e.element.wysiwyg.scrollTop,c=u._getEditorOffsets(null),h=r.getOffset(n,e.element.wysiwygFrame).top+a,g=t.pageY+o+(l.iframe&&!l.toolbarContainer?e.element.toolbar.offsetHeight:0),p=h+(l.iframe?o:c.top),m=r.isListCell(n.parentNode);let f="",_="";if((m?!n.previousSibling:!r.isFormatElement(n.previousElementSibling))&&g<p+20)_=h,f="t";else{if((m?n.nextSibling:r.isFormatElement(n.nextElementSibling))||!(g>p+n.offsetHeight-20))return void(i.display="none");_=h+n.offsetHeight,f="b"}d._variable._lineBreakComp=n,d._variable._lineBreakDir=f,i.top=_-a+"px",d._lineBreakerButton.style.left=r.getOffset(n).left+n.offsetWidth/2-15+"px",i.display="block"}else"none"!==i.display&&(i.display="none")},_onMouseDown_lineBreak:function(e){e.preventDefault()},_onLineBreak:function(e){e.preventDefault();const t=d._variable._lineBreakComp,n=this?this:d._variable._lineBreakDir,i=r.isListCell(t.parentNode),o=r.createElement(i?"BR":r.isCell(t.parentNode)?"DIV":l.defaultTag);if(i||(o.innerHTML="<br>"),d._charTypeHTML&&!d.checkCharCount(o.outerHTML,"byte-html"))return;t.parentNode.insertBefore(o,"t"===n?t:t.nextSibling),d._lineBreaker.style.display="none",d._variable._lineBreakComp=null;const s=i?o:o.firstChild;d.setRange(s,1,s,1),d.history.push(!1)},_addEvent:function(){const t=l.iframe?d._ww:e.element.wysiwyg;e.element.toolbar.addEventListener("mousedown",u._buttonsEventHandler,!1),e.element._menuTray.addEventListener("mousedown",u._buttonsEventHandler,!1),e.element.toolbar.addEventListener("click",u.onClick_toolbar,!1),t.addEventListener("mousedown",u.onMouseDown_wysiwyg,!1),t.addEventListener("click",u.onClick_wysiwyg,!1),t.addEventListener(r.isIE?"textinput":"input",u.onInput_wysiwyg,!1),t.addEventListener("keydown",u.onKeyDown_wysiwyg,!1),t.addEventListener("keyup",u.onKeyUp_wysiwyg,!1),t.addEventListener("paste",u.onPaste_wysiwyg,!1),t.addEventListener("copy",u.onCopy_wysiwyg,!1),t.addEventListener("cut",u.onCut_wysiwyg,!1),t.addEventListener("drop",u.onDrop_wysiwyg,!1),t.addEventListener("scroll",u.onScroll_wysiwyg,!1),t.addEventListener("focus",u.onFocus_wysiwyg,!1),t.addEventListener("blur",u.onBlur_wysiwyg,!1),u._lineBreakerBind={a:u._onLineBreak.bind(""),t:u._onLineBreak.bind("t"),b:u._onLineBreak.bind("b")},t.addEventListener("mousemove",u.onMouseMove_wysiwyg,!1),d._lineBreakerButton.addEventListener("mousedown",u._onMouseDown_lineBreak,!1),d._lineBreakerButton.addEventListener("click",u._lineBreakerBind.a,!1),e.element.lineBreaker_t.addEventListener("mousedown",u._lineBreakerBind.t,!1),e.element.lineBreaker_b.addEventListener("mousedown",u._lineBreakerBind.b,!1),d.plugins.table&&t.addEventListener("touchstart",u.onMouseDown_wysiwyg,{passive:!0,useCapture:!1}),"auto"!==l.height||l.codeMirrorEditor||(e.element.code.addEventListener("keydown",u._codeViewAutoHeight,!1),e.element.code.addEventListener("keyup",u._codeViewAutoHeight,!1),e.element.code.addEventListener("paste",u._codeViewAutoHeight,!1)),e.element.resizingBar&&(/\d+/.test(l.height)?e.element.resizingBar.addEventListener("mousedown",u.onMouseDown_resizingBar,!1):r.addClass(e.element.resizingBar,"se-resizing-none")),u._setResponsiveToolbar(),a.removeEventListener("resize",u.onResize_window),a.removeEventListener("scroll",u.onScroll_window),a.addEventListener("resize",u.onResize_window,!1),l.stickyToolbar>-1&&a.addEventListener("scroll",u.onScroll_window,!1)},_removeEvent:function(){const t=l.iframe?d._ww:e.element.wysiwyg;e.element.toolbar.removeEventListener("mousedown",u._buttonsEventHandler),e.element._menuTray.removeEventListener("mousedown",u._buttonsEventHandler),e.element.toolbar.removeEventListener("click",u.onClick_toolbar),t.removeEventListener("mousedown",u.onMouseDown_wysiwyg),t.removeEventListener("click",u.onClick_wysiwyg),t.removeEventListener(r.isIE?"textinput":"input",u.onInput_wysiwyg),t.removeEventListener("keydown",u.onKeyDown_wysiwyg),t.removeEventListener("keyup",u.onKeyUp_wysiwyg),t.removeEventListener("paste",u.onPaste_wysiwyg),t.removeEventListener("copy",u.onCopy_wysiwyg),t.removeEventListener("cut",u.onCut_wysiwyg),t.removeEventListener("drop",u.onDrop_wysiwyg),t.removeEventListener("scroll",u.onScroll_wysiwyg),t.removeEventListener("mousemove",u.onMouseMove_wysiwyg),d._lineBreakerButton.removeEventListener("mousedown",u._onMouseDown_lineBreak),d._lineBreakerButton.removeEventListener("click",u._lineBreakerBind.a),e.element.lineBreaker_t.removeEventListener("mousedown",u._lineBreakerBind.t),e.element.lineBreaker_b.removeEventListener("mousedown",u._lineBreakerBind.b),u._lineBreakerBind=null,t.removeEventListener("touchstart",u.onMouseDown_wysiwyg,{passive:!0,useCapture:!1}),t.removeEventListener("focus",u.onFocus_wysiwyg),t.removeEventListener("blur",u.onBlur_wysiwyg),e.element.code.removeEventListener("keydown",u._codeViewAutoHeight),e.element.code.removeEventListener("keyup",u._codeViewAutoHeight),e.element.code.removeEventListener("paste",u._codeViewAutoHeight),e.element.resizingBar&&e.element.resizingBar.removeEventListener("mousedown",u.onMouseDown_resizingBar),a.removeEventListener("resize",u.onResize_window),a.removeEventListener("scroll",u.onScroll_window)},_setResponsiveToolbar:function(){if(0===o.length)return void(o=null);const e=u._responsiveButtonSize=[],t=u._responsiveButtons={default:o[0]};for(let n,i,l=1,s=o.length;l<s;l++)i=o[l],n=1*i[0],e.push(n),t[n]=i[1];e.sort((function(e,t){return e-t})).unshift("default")}},h={core:d,util:r,onload:null,onScroll:null,onMouseDown:null,onClick:null,onInput:null,onKeyDown:null,onKeyUp:null,onChange:null,onCopy:null,onCut:null,onFocus:null,onBlur:null,onDrop:null,onPaste:null,showInline:null,showController:null,toggleCodeView:null,toggleFullScreen:null,imageUploadHandler:null,videoUploadHandler:null,audioUploadHandler:null,onImageUploadBefore:null,onVideoUploadBefore:null,onAudioUploadBefore:null,onImageUpload:null,onVideoUpload:null,onAudioUpload:null,onImageUploadError:null,onVideoUploadError:null,onAudioUploadError:null,setToolbarButtons:function(i){d.submenuOff(),d.containerOff();const a=L._createToolBar(s,i,d.plugins,l);o=a.responsiveButtons,d._moreLayerActiveButton=null,u._setResponsiveToolbar(),e.element.toolbar.replaceChild(a._buttonTray,e.element._buttonTray);const c=k(e.element.originElement,d._getConstructed(e.element),l);e.element=c.element,e.tool=c.tool,l.iframe&&(e.element.wysiwyg=d._wd.body),d._cachingButtons(),d.history._resetCachingButton(),d.activePlugins=[];const h=t;let g,p,m;t=a.pluginCallButtons;for(let e in t)r.hasOwn(t,e)&&(g=n[e],p=t[e],g.active&&p&&(m=h[e],d.callPlugin(e,null,m||p),m&&(p.parentElement.replaceChild(m,p),t[e]=m)));d.hasFocus&&u._applyTagEffects(),d._variable.isCodeView&&r.addClass(d._styleCommandMap.codeView,"active"),d._variable.isFullScreen&&r.addClass(d._styleCommandMap.fullScreen,"active"),r.hasClass(e.element.wysiwyg,"se-show-block")&&r.addClass(d._styleCommandMap.showBlocks,"active")},setOptions:function(s){u._removeEvent(),d._resetComponents(),r.removeClass(d._styleCommandMap.showBlocks,"active"),r.removeClass(d._styleCommandMap.codeView,"active"),d._variable.isCodeView=!1,d._iframeAuto=null,d.plugins=s.plugins||d.plugins;const c=[l,s].reduce((function(e,t){for(let n in t)if(r.hasOwn(t,n))if("plugins"===n&&t[n]&&e[n]){let i=e[n],l=t[n];i=i.length?i:a.Object.keys(i).map((function(e){return i[e]})),l=l.length?l:a.Object.keys(l).map((function(e){return l[e]})),e[n]=l.filter((function(e){return-1===i.indexOf(e)})).concat(i)}else e[n]=t[n];return e}),{}),h=e.element,g=h.wysiwyg.innerHTML,p=L._setOptions(c,e,d.plugins,l);p.callButtons&&(t=p.callButtons,d.initPlugins={}),p.plugins&&(d.plugins=n=p.plugins),0===h._menuTray.children.length&&(this._menuTray={}),o=p.toolbar.responsiveButtons,l=c,d.lang=i=l.lang,l.iframe&&h.wysiwygFrame.addEventListener("load",(function(){r._setIframeDocument(this,l),d._setOptionsInit(h,g)})),h.editorArea.appendChild(h.wysiwygFrame),l.iframe||d._setOptionsInit(h,g)},setDefaultStyle:function(t){const n=l._editorStyles=r._setDefaultOptionStyle(l,t),i=e.element;i.topArea.style.cssText=n.top,i.code.style.cssText=l._editorStyles.frame,i.code.style.display="none","auto"===l.height?i.code.style.overflow="hidden":i.code.style.overflow="",l.iframe?(i.wysiwygFrame.style.cssText=n.frame,i.wysiwyg.style.cssText=n.editor):i.wysiwygFrame.style.cssText=n.frame+n.editor},noticeOpen:function(e){d.notice.open.call(d,e)},noticeClose:function(){d.notice.close.call(d)},save:function(){e.element.originElement.value=d.getContents(!1)},getContext:function(){return e},getContents:function(e){return d.getContents(e)},getText:function(){return e.element.wysiwyg.textContent},getCharCount:function(t){return t="string"==typeof t?t:l.charCounterType,d.getCharLength(d._charTypeHTML?e.element.wysiwyg.innerHTML:e.element.wysiwyg.textContent,t)},getImagesInfo:function(){return e.image?e.image._infoList:[]},getFilesInfo:function(t){return e[t]?e[t]._infoList:[]},insertImage:function(e){d.plugins.image&&e&&(d.initPlugins.image?d.plugins.image.submitAction.call(d,e):d.callPlugin("image",d.plugins.image.submitAction.bind(d,e),null),d.focus())},insertHTML:function(e,t,n,i){if("string"==typeof e){t||(e=d.cleanHTML(e,null));try{const t=s.createRange().createContextualFragment(e).childNodes;if(n){const e=d._charTypeHTML?"outerHTML":"textContent";let n="";for(let i=0,l=t.length;i<l;i++)n+=t[i][e];if(!d.checkCharCount(n,null))return}let l,o,a,r;for(;l=t[0];)a=d.insertNode(l,o,!1),o=a.container||a,r||(r=a);const c=3===o.nodeType?a.endOffset||o.textContent.length:o.childNodes.length;i?d.setRange(r.container||r,r.startOffset||0,o,c):d.setRange(o,c,o,c)}catch(t){d.execCommand("insertHTML",!1,e)}}else if(r.isComponent(e))d.insertComponent(e,!1,n,!1);else{let t=null;(r.isFormatElement(e)||r.isMedia(e))&&(t=r.getFormatElement(d.getSelectionNode(),null)),d.insertNode(e,t,n)}d.effectNode=null,d.focus(),d.history.push(!1)},setContents:function(e){d.setContents(e)},appendContents:function(t){const n=d.convertContentsForEditor(t);if(d._variable.isCodeView)d._setCodeView(d._getCodeView()+"\n"+d.convertHTMLForCodeView(n));else{const t=r.createElement("DIV");t.innerHTML=n;const i=e.element.wysiwyg,l=t.children;for(let e=0,t=l.length;e<t;e++)i.appendChild(l[e])}d.history.push(!1)},disabled:function(){e.tool.cover.style.display="block",e.element.wysiwyg.setAttribute("contenteditable",!1),d.isDisabled=!0,l.codeMirrorEditor?l.codeMirrorEditor.setOption("readOnly",!0):e.element.code.setAttribute("disabled","disabled")},enabled:function(){e.tool.cover.style.display="none",e.element.wysiwyg.setAttribute("contenteditable",!0),d.isDisabled=!1,l.codeMirrorEditor?l.codeMirrorEditor.setOption("readOnly",!1):e.element.code.removeAttribute("disabled")},show:function(){const t=e.element.topArea.style;"none"===t.display&&(t.display=l.display)},hide:function(){e.element.topArea.style.display="none"},destroy:function(){d.submenuOff(),d.containerOff(),d.controllersOff(),d.notice&&d.notice.close.call(d),d.modalForm&&d.plugins.dialog.close.call(d),d.history._destroy(),u._removeEvent(),r.removeItem(e.element.toolbar),r.removeItem(e.element.topArea);for(let e in d)r.hasOwn(d,e)&&delete d[e];for(let e in u)r.hasOwn(u,e)&&delete u[e];for(let t in e)r.hasOwn(e,t)&&delete e[t];for(let e in t)r.hasOwn(t,e)&&delete t[e];for(let e in this)r.hasOwn(this,e)&&delete this[e]},toolbar:{disabled:function(){e.tool.cover.style.display="block"},enabled:function(){e.tool.cover.style.display="none"},show:function(){d._isInline?u._showToolbarInline():(e.element.toolbar.style.display="",e.element._stickyDummy.style.display="")},hide:function(){d._isInline?u._hideToolbar():(e.element.toolbar.style.display="none",e.element._stickyDummy.style.display="none")}}};d.functions=h;let g=e.element,p=g.originElement,m=g.topArea;return p.style.display="none",m.style.display="block",l.iframe&&g.wysiwygFrame.addEventListener("load",(function(){r._setIframeDocument(this,l),d._editorInit(!1,l.value),l.value=null})),"object"==typeof p.nextElementSibling?p.parentNode.insertBefore(m,p.nextElementSibling):p.parentNode.appendChild(m),g.editorArea.appendChild(g.wysiwygFrame),g=p=m=null,l.iframe||(d._editorInit(!1,l.value),l.value=null),h}(k(i,l.constructed,l.options),l.pluginCallButtons,l.plugins,l.options.lang,t,l._responsiveButtons)}};Object.defineProperty(window,"SUNEDITOR",{enumerable:!0,writable:!1,configurable:!1,value:A.init({plugins:w})})},ZED3:function(e,t,n){"use strict";var i,l;i="undefined"!=typeof window?window:this,l=function(e,t){const n={name:"component",set_container:function(e,t){const n=this.util.createElement("DIV");return n.className="se-component "+t,n.setAttribute("contenteditable",!1),n.appendChild(e),n},set_cover:function(e){const t=this.util.createElement("FIGURE");return t.appendChild(e),t},create_caption:function(){const e=this.util.createElement("FIGCAPTION");return e.setAttribute("contenteditable",!0),e.innerHTML="<div>"+this.lang.dialogBox.caption+"</div>",e}};return void 0===t&&(e.SUNEDITOR_MODULES||Object.defineProperty(e,"SUNEDITOR_MODULES",{enumerable:!0,writable:!1,configurable:!1,value:{}}),Object.defineProperty(e.SUNEDITOR_MODULES,"component",{enumerable:!0,writable:!1,configurable:!1,value:n})),n},"object"==typeof e.exports?e.exports=i.document?l(i,!0):function(e){if(!e.document)throw new Error("SUNEDITOR_MODULES a window with a document");return l(e)}:l(i)},ee5k:function(e,t,n){"use strict";var i,l;i="undefined"!=typeof window?window:this,l=function(e,t){const n={name:"resizing",add:function(e){const t=e.icons,n=e.context;n.resizing={_resizeClientX:0,_resizeClientY:0,_resize_plugin:"",_resize_w:0,_resize_h:0,_origin_w:0,_origin_h:0,_rotateVertical:!1,_resize_direction:"",_move_path:null,_isChange:!1,alignIcons:{basic:t.align_justify,left:t.align_left,right:t.align_right,center:t.align_center}};let i=this.setController_resize.call(e);n.resizing.resizeContainer=i,n.resizing.resizeDiv=i.querySelector(".se-modal-resize"),n.resizing.resizeDot=i.querySelector(".se-resize-dot"),n.resizing.resizeDisplay=i.querySelector(".se-resize-display");let l=this.setController_button.call(e);n.resizing.resizeButton=l;let o=n.resizing.resizeHandles=n.resizing.resizeDot.querySelectorAll("span");n.resizing.resizeButtonGroup=l.querySelector("._se_resizing_btn_group"),n.resizing.rotationButtons=l.querySelectorAll("._se_resizing_btn_group ._se_rotation"),n.resizing.percentageButtons=l.querySelectorAll("._se_resizing_btn_group ._se_percentage"),n.resizing.alignMenu=l.querySelector(".se-resizing-align-list"),n.resizing.alignMenuList=n.resizing.alignMenu.querySelectorAll("button"),n.resizing.alignButton=l.querySelector("._se_resizing_align_button"),n.resizing.autoSizeButton=l.querySelector("._se_resizing_btn_group ._se_auto_size"),n.resizing.captionButton=l.querySelector("._se_resizing_caption_button"),i.addEventListener("mousedown",(function(e){e.preventDefault()})),l.addEventListener("mousedown",e.eventStop),o[0].addEventListener("mousedown",this.onMouseDown_resize_handle.bind(e)),o[1].addEventListener("mousedown",this.onMouseDown_resize_handle.bind(e)),o[2].addEventListener("mousedown",this.onMouseDown_resize_handle.bind(e)),o[3].addEventListener("mousedown",this.onMouseDown_resize_handle.bind(e)),o[4].addEventListener("mousedown",this.onMouseDown_resize_handle.bind(e)),o[5].addEventListener("mousedown",this.onMouseDown_resize_handle.bind(e)),o[6].addEventListener("mousedown",this.onMouseDown_resize_handle.bind(e)),o[7].addEventListener("mousedown",this.onMouseDown_resize_handle.bind(e)),l.addEventListener("click",this.onClick_resizeButton.bind(e)),n.element.relative.appendChild(i),n.element.relative.appendChild(l),i=null,l=null,o=null},setController_resize:function(){const e=this.util.createElement("DIV");return e.className="se-controller se-resizing-container",e.style.display="none",e.innerHTML='<div class="se-modal-resize"></div><div class="se-resize-dot"><span class="tl"></span><span class="tr"></span><span class="bl"></span><span class="br"></span><span class="lw"></span><span class="th"></span><span class="rw"></span><span class="bh"></span><div class="se-resize-display"></div></div>',e},setController_button:function(){const e=this.lang,t=this.icons,n=this.util.createElement("DIV");return n.className="se-controller se-controller-resizing",n.innerHTML='<div class="se-arrow se-arrow-up"></div><div class="se-btn-group _se_resizing_btn_group"><button type="button" data-command="percent" data-value="1" class="se-tooltip _se_percentage"><span>100%</span><span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.resize100+'</span></span></button><button type="button" data-command="percent" data-value="0.75" class="se-tooltip _se_percentage"><span>75%</span><span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.resize75+'</span></span></button><button type="button" data-command="percent" data-value="0.5" class="se-tooltip _se_percentage"><span>50%</span><span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.resize50+'</span></span></button><button type="button" data-command="auto" class="se-btn se-tooltip _se_auto_size">'+t.auto_size+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.autoSize+'</span></span></button><button type="button" data-command="rotate" data-value="-90" class="se-btn se-tooltip _se_rotation">'+t.rotate_left+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.rotateLeft+'</span></span></button><button type="button" data-command="rotate" data-value="90" class="se-btn se-tooltip _se_rotation">'+t.rotate_right+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.rotateRight+'</span></span></button></div><div class="se-btn-group" style="padding-top: 0;"><button type="button" data-command="mirror" data-value="h" class="se-btn se-tooltip">'+t.mirror_horizontal+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.mirrorHorizontal+'</span></span></button><button type="button" data-command="mirror" data-value="v" class="se-btn se-tooltip">'+t.mirror_vertical+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.mirrorVertical+'</span></span></button><button type="button" data-command="onalign" class="se-btn se-tooltip _se_resizing_align_button">'+t.align_justify+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.toolbar.align+'</span></span></button><div class="se-btn-group-sub sun-editor-common se-list-layer se-resizing-align-list"><div class="se-list-inner"><ul class="se-list-basic"><li><button type="button" class="se-btn-list se-tooltip" data-command="align" data-value="basic">'+t.align_justify+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.dialogBox.basic+'</span></span></button></li><li><button type="button" class="se-btn-list se-tooltip" data-command="align" data-value="left">'+t.align_left+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.dialogBox.left+'</span></span></button></li><li><button type="button" class="se-btn-list se-tooltip" data-command="align" data-value="center">'+t.align_center+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.dialogBox.center+'</span></span></button></li><li><button type="button" class="se-btn-list se-tooltip" data-command="align" data-value="right">'+t.align_right+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.dialogBox.right+'</span></span></button></li></ul></div></div><button type="button" data-command="caption" class="se-btn se-tooltip _se_resizing_caption_button">'+t.caption+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.dialogBox.caption+'</span></span></button><button type="button" data-command="revert" class="se-btn se-tooltip">'+t.revert+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.dialogBox.revertButton+'</span></span></button><button type="button" data-command="update" class="se-btn se-tooltip">'+t.modify+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.edit+'</span></span></button><button type="button" data-command="delete" class="se-btn se-tooltip">'+t.delete+'<span class="se-tooltip-inner"><span class="se-tooltip-text">'+e.controller.remove+"</span></span></button></div>",n},_module_getSizeX:function(e,t,n,i){return t||(t=e._element),n||(n=e._cover),i||(i=e._container),t?/%$/.test(t.style.width)?(i&&this.util.getNumber(i.style.width,2)||100)+"%":t.style.width:""},_module_getSizeY:function(e,t,n,i){return t||(t=e._element),n||(n=e._cover),i||(i=e._container),i&&n?this.util.getNumber(n.style.paddingBottom,0)>0&&!this.context.resizing._rotateVertical?n.style.height:/%$/.test(t.style.height)&&/%$/.test(t.style.width)?(i&&this.util.getNumber(i.style.height,2)||100)+"%":t.style.height:t&&t.style.height||""},_module_setModifyInputSize:function(e,t){const n=e._onlyPercentage&&this.context.resizing._rotateVertical;e.proportion.checked=e._proportionChecked="false"!==e._element.getAttribute("data-proportion");let i=n?"":this.plugins.resizing._module_getSizeX.call(this,e);if(i===e._defaultSizeX&&(i=""),e._onlyPercentage&&(i=this.util.getNumber(i,2)),e.inputX.value=i,t.setInputSize.call(this,"x"),!e._onlyPercentage){let t=n?"":this.plugins.resizing._module_getSizeY.call(this,e);t===e._defaultSizeY&&(t=""),e._onlyPercentage&&(t=this.util.getNumber(t,2)),e.inputY.value=t}e.inputX.disabled=!!n,e.inputY.disabled=!!n,e.proportion.disabled=!!n,t.setRatio.call(this)},_module_setInputSize:function(e,t){if(e._onlyPercentage)"x"===t&&e.inputX.value>100&&(e.inputX.value=100);else if(e.proportion.checked&&e._ratio&&/\d/.test(e.inputX.value)&&/\d/.test(e.inputY.value)){const n=e.inputX.value.replace(/\d+|\./g,"")||e.sizeUnit,i=e.inputY.value.replace(/\d+|\./g,"")||e.sizeUnit;if(n!==i)return;const l="%"===n?2:0;"x"===t?e.inputY.value=this.util.getNumber(e._ratioY*this.util.getNumber(e.inputX.value,l),l)+i:e.inputX.value=this.util.getNumber(e._ratioX*this.util.getNumber(e.inputY.value,l),l)+n}},_module_setRatio:function(e){const t=e.inputX.value,n=e.inputY.value;if(e.proportion.checked&&/\d+/.test(t)&&/\d+/.test(n)){if((t.replace(/\d+|\./g,"")||e.sizeUnit)!==(n.replace(/\d+|\./g,"")||e.sizeUnit))e._ratio=!1;else if(!e._ratio){const i=this.util.getNumber(t,0),l=this.util.getNumber(n,0);e._ratio=!0,e._ratioX=i/l,e._ratioY=l/i}}else e._ratio=!1},_module_sizeRevert:function(e){e._onlyPercentage?e.inputX.value=e._origin_w>100?100:e._origin_w:(e.inputX.value=e._origin_w,e.inputY.value=e._origin_h)},_module_saveCurrentSize:function(e){const t=this.plugins.resizing._module_getSizeX.call(this,e),n=this.plugins.resizing._module_getSizeY.call(this,e);e._element.setAttribute("data-size",t+","+n),e._videoRatio&&(e._videoRatio=n)},call_controller_resize:function(e,t){const n=this.context.resizing,i=this.context[t];n._resize_plugin=t;const l=n.resizeContainer,o=n.resizeDiv,s=this.util.getOffset(e,this.context.element.wysiwygFrame),a=n._rotateVertical=/^(90|270)$/.test(Math.abs(e.getAttribute("data-rotate")).toString()),r=a?e.offsetHeight:e.offsetWidth,c=a?e.offsetWidth:e.offsetHeight,d=s.top,u=s.left-this.context.element.wysiwygFrame.scrollLeft;l.style.top=d+"px",l.style.left=u+"px",l.style.width=r+"px",l.style.height=c+"px",o.style.top="0px",o.style.left="0px",o.style.width=r+"px",o.style.height=c+"px";let h=e.getAttribute("data-align")||"basic";h="none"===h?"basic":h;const g=this.util.getParentElement(e,this.util.isComponent),p=this.util.getParentElement(e,"FIGURE"),m=this.plugins.resizing._module_getSizeX.call(this,i,e,p,g)||"auto",f=i._onlyPercentage&&"image"===t?"":", "+(this.plugins.resizing._module_getSizeY.call(this,i,e,p,g)||"auto");this.util.changeTxt(n.resizeDisplay,this.lang.dialogBox[h]+" ("+m+f+")"),n.resizeButtonGroup.style.display=i._resizing?"":"none";const _=!i._resizing||i._resizeDotHide||i._onlyPercentage?"none":"flex",b=n.resizeHandles;for(let e=0,t=b.length;e<t;e++)b[e].style.display=_;if(i._resizing){const e=n.rotationButtons;e[0].style.display=e[1].style.display=i._rotation?"":"none"}const v=n.alignMenuList;this.util.changeElement(n.alignButton.firstElementChild,n.alignIcons[h]);for(let e=0,t=v.length;e<t;e++)v[e].getAttribute("data-value")===h?this.util.addClass(v[e],"on"):this.util.removeClass(v[e],"on");const y=n.percentageButtons,C=/%$/.test(e.style.width)&&/%$/.test(g.style.width)?this.util.getNumber(g.style.width,0)/100+"":"";for(let e=0,t=y.length;e<t;e++)y[e].getAttribute("data-value")===C?this.util.addClass(y[e],"active"):this.util.removeClass(y[e],"active");if(i._captionShow?(n.captionButton.style.display="",this.util.getChildElement(e.parentNode,"figcaption")?(this.util.addClass(n.captionButton,"active"),i._captionChecked=!0):(this.util.removeClass(n.captionButton,"active"),i._captionChecked=!1)):n.captionButton.style.display="none",this.currentControllerName!==t){this.util.setDisabledButtons(!0,this.resizingDisabledButtons),l.style.display="block";const i={left:0,top:50};this.context.options.iframe&&(i.left-=this.context.element.wysiwygFrame.parentElement.offsetLeft,i.top-=this.context.element.wysiwygFrame.parentElement.offsetTop),this.setControllerPosition(n.resizeButton,l,"bottom",i),this.controllersOn(l,n.resizeButton,this.util.setDisabledButtons.bind(this,!1,this.resizingDisabledButtons),e,t)}n._resize_w=r,n._resize_h=c;const w=(e.getAttribute("origin-size")||"").split(",");return n._origin_w=w[0]||e.naturalWidth,n._origin_h=w[1]||e.naturalHeight,{w:r,h:c,t:d,l:u}},_closeAlignMenu:null,openAlignMenu:function(){const e=this.context.resizing.alignButton;this.util.addClass(e,"on"),this.context.resizing.alignMenu.style.top=e.offsetTop+e.offsetHeight+"px",this.context.resizing.alignMenu.style.left=e.offsetLeft-e.offsetWidth/2+"px",this.context.resizing.alignMenu.style.display="block",this.plugins.resizing._closeAlignMenu=function(){this.util.removeClass(this.context.resizing.alignButton,"on"),this.context.resizing.alignMenu.style.display="none",this.removeDocEvent("mousedown",this.plugins.resizing._closeAlignMenu),this.plugins.resizing._closeAlignMenu=null}.bind(this),this.addDocEvent("mousedown",this.plugins.resizing._closeAlignMenu)},onClick_resizeButton:function(e){e.stopPropagation();const t=e.target,n=t.getAttribute("data-command")||t.parentNode.getAttribute("data-command");if(!n)return;const i=t.getAttribute("data-value")||t.parentNode.getAttribute("data-value"),l=this.context.resizing._resize_plugin,o=this.context[l],s=o._element,a=this.plugins[l];if(e.preventDefault(),"function"!=typeof this.plugins.resizing._closeAlignMenu||(this.plugins.resizing._closeAlignMenu(),"onalign"!==n)){switch(n){case"auto":this.plugins.resizing.resetTransform.call(this,s),a.setAutoSize.call(this),this.selectComponent(s,l);break;case"percent":let e=this.plugins.resizing._module_getSizeY.call(this,o);if(this.context.resizing._rotateVertical){const t=s.getAttribute("data-percentage");t&&(e=t.split(",")[1])}this.plugins.resizing.resetTransform.call(this,s),a.setPercentSize.call(this,100*i,null!==this.util.getNumber(e,0)&&/%$/.test(e)?e:""),this.selectComponent(s,l);break;case"mirror":const t=s.getAttribute("data-rotate")||"0";let n=s.getAttribute("data-rotateX")||"",r=s.getAttribute("data-rotateY")||"";"h"===i&&!this.context.resizing._rotateVertical||"v"===i&&this.context.resizing._rotateVertical?r=r?"":"180":n=n?"":"180",s.setAttribute("data-rotateX",n),s.setAttribute("data-rotateY",r),this.plugins.resizing._setTransForm(s,t,n,r);break;case"rotate":const c=this.context.resizing,d=1*s.getAttribute("data-rotate")+1*i,u=this._w.Math.abs(d)>=360?0:d;s.setAttribute("data-rotate",u),c._rotateVertical=/^(90|270)$/.test(this._w.Math.abs(u).toString()),this.plugins.resizing.setTransformSize.call(this,s,null,null),this.selectComponent(s,l);break;case"onalign":return void this.plugins.resizing.openAlignMenu.call(this);case"align":const h="basic"===i?"none":i;a.setAlign.call(this,h,null,null,null),this.selectComponent(s,l);break;case"caption":const g=!o._captionChecked;if(a.openModify.call(this,!0),o._captionChecked=o.captionCheckEl.checked=g,a.update_image.call(this,!1,!1,!1),g){const e=this.util.getChildElement(o._caption,(function(e){return 3===e.nodeType}));e?this.setRange(e,0,e,e.textContent.length):o._caption.focus(),this.controllersOff()}else this.selectComponent(s,l),a.openModify.call(this,!0);break;case"revert":a.setOriginSize.call(this),this.selectComponent(s,l);break;case"update":a.openModify.call(this),this.controllersOff();break;case"delete":a.destroy.call(this)}this.history.push(!1)}},resetTransform:function(e){const t=(e.getAttribute("data-size")||e.getAttribute("data-origin")||"").split(",");this.context.resizing._rotateVertical=!1,e.style.maxWidth="",e.style.transform="",e.style.transformOrigin="",e.setAttribute("data-rotate",""),e.setAttribute("data-rotateX",""),e.setAttribute("data-rotateY",""),this.plugins[this.context.resizing._resize_plugin].setSize.call(this,t[0]?t[0]:"auto",t[1]?t[1]:"",!0)},setTransformSize:function(e,t,n){let i=e.getAttribute("data-percentage");const l=this.context.resizing._rotateVertical,o=1*e.getAttribute("data-rotate");let s="";if(i&&!l)i=i.split(","),"auto"===i[0]&&"auto"===i[1]?this.plugins[this.context.resizing._resize_plugin].setAutoSize.call(this):this.plugins[this.context.resizing._resize_plugin].setPercentSize.call(this,i[0],i[1]);else{const i=this.util.getParentElement(e,"FIGURE"),a=t||e.offsetWidth,r=n||e.offsetHeight,c=(l?r:a)+"px",d=(l?a:r)+"px";if(this.plugins[this.context.resizing._resize_plugin].cancelPercentAttr.call(this),this.plugins[this.context.resizing._resize_plugin].setSize.call(this,a+"px",r+"px",!0),i.style.width=c,i.style.height=this.context[this.context.resizing._resize_plugin]._caption?"":d,l){let e=a/2+"px "+a/2+"px 0",t=r/2+"px "+r/2+"px 0";s=90===o||-270===o?t:e}}e.style.transformOrigin=s,this.plugins.resizing._setTransForm(e,o.toString(),e.getAttribute("data-rotateX")||"",e.getAttribute("data-rotateY")||""),e.style.maxWidth=l?"none":"",this.plugins.resizing.setCaptionPosition.call(this,e)},_setTransForm:function(e,t,n,i){let l=(e.offsetWidth-e.offsetHeight)*(/-/.test(t)?1:-1),o="";if(/[1-9]/.test(t)&&(n||i))switch(o=n?"Y":"X",t){case"90":o=n&&i?"X":i?o:"";break;case"270":l*=-1,o=n&&i?"Y":n?o:"";break;case"-90":o=n&&i?"Y":n?o:"";break;case"-270":l*=-1,o=n&&i?"X":i?o:"";break;default:o=""}t%180==0&&(e.style.maxWidth=""),e.style.transform="rotate("+t+"deg)"+(n?" rotateX("+n+"deg)":"")+(i?" rotateY("+i+"deg)":"")+(o?" translate"+o+"("+l+"px)":"")},setCaptionPosition:function(e){const t=this.util.getChildElement(this.util.getParentElement(e,"FIGURE"),"FIGCAPTION");t&&(t.style.marginTop=(this.context.resizing._rotateVertical?e.offsetWidth-e.offsetHeight:0)+"px")},onMouseDown_resize_handle:function(e){e.stopPropagation(),e.preventDefault();const t=this.context.resizing,n=t._resize_direction=e.target.classList[0];t._resizeClientX=e.clientX,t._resizeClientY=e.clientY,this.context.element.resizeBackground.style.display="block",t.resizeButton.style.display="none",t.resizeDiv.style.float=/l/.test(n)?"right":/r/.test(n)?"left":"none";const i=function(e){if("keydown"===e.type&&27!==e.keyCode)return;const o=t._isChange;t._isChange=!1,this.removeDocEvent("mousemove",l),this.removeDocEvent("mouseup",i),this.removeDocEvent("keydown",i),"keydown"===e.type?(this.controllersOff(),this.context.element.resizeBackground.style.display="none",this.plugins[this.context.resizing._resize_plugin].init.call(this)):(this.plugins.resizing.cancel_controller_resize.call(this,n),o&&this.history.push(!1))}.bind(this),l=this.plugins.resizing.resizing_element.bind(this,t,n,this.context[t._resize_plugin]);this.addDocEvent("mousemove",l),this.addDocEvent("mouseup",i),this.addDocEvent("keydown",i)},resizing_element:function(e,t,n,i){const l=i.clientX,o=i.clientY;let s=n._element_w,a=n._element_h;const r=n._element_w+(/r/.test(t)?l-e._resizeClientX:e._resizeClientX-l),c=n._element_h+(/b/.test(t)?o-e._resizeClientY:e._resizeClientY-o),d=n._element_h/n._element_w*r;/t/.test(t)&&(e.resizeDiv.style.top=n._element_h-(/h/.test(t)?c:d)+"px"),/l/.test(t)&&(e.resizeDiv.style.left=n._element_w-r+"px"),/r|l/.test(t)&&(e.resizeDiv.style.width=r+"px",s=r),/^(t|b)[^h]$/.test(t)?(e.resizeDiv.style.height=d+"px",a=d):/^(t|b)h$/.test(t)&&(e.resizeDiv.style.height=c+"px",a=c),e._resize_w=s,e._resize_h=a,this.util.changeTxt(e.resizeDisplay,this._w.Math.round(s)+" x "+this._w.Math.round(a)),e._isChange=!0},cancel_controller_resize:function(e){const t=this.context.resizing._rotateVertical;this.controllersOff(),this.context.element.resizeBackground.style.display="none";let n=this._w.Math.round(t?this.context.resizing._resize_h:this.context.resizing._resize_w),i=this._w.Math.round(t?this.context.resizing._resize_w:this.context.resizing._resize_h);if(!t&&!/%$/.test(n)){const e=16,t=this.context.element.wysiwygFrame.clientWidth-2*e-2;this.util.getNumber(n,0)>t&&(i=this._w.Math.round(i/n*t),n=t)}const l=this.context.resizing._resize_plugin;this.plugins[l].setSize.call(this,n,i,!1,e),this.selectComponent(this.context[l]._element,l)}};return void 0===t&&(e.SUNEDITOR_MODULES||Object.defineProperty(e,"SUNEDITOR_MODULES",{enumerable:!0,writable:!1,configurable:!1,value:{}}),Object.defineProperty(e.SUNEDITOR_MODULES,"resizing",{enumerable:!0,writable:!1,configurable:!1,value:n})),n},"object"==typeof e.exports?e.exports=i.document?l(i,!0):function(e){if(!e.document)throw new Error("SUNEDITOR_MODULES a window with a document");return l(e)}:l(i)},"gjS+":function(e,t,n){"use strict";var i,l;i="undefined"!=typeof window?window:this,l=function(e,t){const n={name:"fileManager",_xmlHttp:null,upload:function(e,t,n,i,l){this.showLoading();const o=this.plugins.fileManager,s=o._xmlHttp=this.util.getXMLHttpRequest();if(s.onreadystatechange=o._callBackUpload.bind(this,s,i,l),s.open("post",e,!0),null!==t&&"object"==typeof t&&this._w.Object.keys(t).length>0)for(let e in t)s.setRequestHeader(e,t[e]);s.send(n)},_callBackUpload:function(e,t,n){if(4===e.readyState)if(200===e.status)try{t(e)}catch(e){throw Error('[SUNEDITOR.fileManager.upload.callBack.fail] cause : "'+e.message+'"')}finally{this.closeLoading()}else{this.closeLoading();const t=e.responseText?JSON.parse(e.responseText):e;if("function"!=typeof n||n("",t,this)){const n="[SUNEDITOR.fileManager.upload.serverException] status: "+e.status+", response: "+(t.errorMessage||e.responseText);throw this.functions.noticeOpen(n),Error(n)}}},checkInfo:function(e,t,n,i,l){let o=[];for(let e=0,n=t.length;e<n;e++)o=o.concat([].slice.call(this.context.element.wysiwyg.getElementsByTagName(t[e])));const s=this.context[e],a=s._infoList,r=this.plugins.fileManager.setInfo.bind(this);if(o.length===a.length){if(this._componentsInfoReset){for(let t=0,i=o.length;t<i;t++)r(e,o[t],n,null,l);return}{let e=!1;for(let t,n=0,i=a.length;n<i;n++)if(t=a[n],0===o.filter((function(e){return t.src===e.src&&t.index.toString()===e.getAttribute("data-index")})).length){e=!0;break}if(!e)return}}const c=l?this.context.resizing._resize_plugin:"";l&&(this.context.resizing._resize_plugin=e);const d=[],u=[];for(let e=0,t=a.length;e<t;e++)u[e]=a[e].index;for(let t,a=0,c=o.length;a<c;a++)t=o[a],this.util.getParentElement(t,this.util.isMediaComponent)&&/FIGURE/i.test(t.parentElement.nodeName)?!t.getAttribute("data-index")||u.indexOf(1*t.getAttribute("data-index"))<0?(d.push(s._infoIndex),t.removeAttribute("data-index"),r(e,t,n,null,l)):d.push(1*t.getAttribute("data-index")):(d.push(s._infoIndex),i(t));for(let e,t=0;t<a.length;t++)e=a[t].index,d.indexOf(e)>-1||(a.splice(t,1),"function"==typeof n&&n(null,e,"delete",null,0,this),t--);l&&(this.context.resizing._resize_plugin=c)},setInfo:function(e,t,n,i,l){const o=l?this.context.resizing._resize_plugin:"";l&&(this.context.resizing._resize_plugin=e);const s=this.plugins[e],a=this.context[e],r=a._infoList;let c=t.getAttribute("data-index"),d=null,u="";if(i||(i={name:t.getAttribute("data-file-name")||("string"==typeof t.src?t.src.split("/").pop():""),size:t.getAttribute("data-file-size")||0}),!c||this._componentsInfoInit)u="create",c=a._infoIndex++,t.setAttribute("data-index",c),t.setAttribute("data-file-name",i.name),t.setAttribute("data-file-size",i.size),d={src:t.src,index:1*c,name:i.name,size:i.size},r.push(d);else{u="update",c*=1;for(let e=0,t=r.length;e<t;e++)if(c===r[e].index){d=r[e];break}d||(c=a._infoIndex++,d={index:c},r.push(d)),d.src=t.src,d.name=t.getAttribute("data-file-name"),d.size=1*t.getAttribute("data-file-size")}if(d.element=t,d.delete=s.destroy.bind(this,t),d.select=function(e){e.scrollIntoView(!0),this._w.setTimeout(s.select.bind(this,e))}.bind(this,t),l){if(!t.getAttribute("origin-size")&&t.naturalWidth&&t.setAttribute("origin-size",t.naturalWidth+","+t.naturalHeight),!t.getAttribute("data-origin")){const e=this.util.getParentElement(t,this.util.isMediaComponent),n=this.util.getParentElement(t,"FIGURE"),i=this.plugins.resizing._module_getSizeX.call(this,a,t,n,e),l=this.plugins.resizing._module_getSizeY.call(this,a,t,n,e);t.setAttribute("data-origin",i+","+l),t.setAttribute("data-size",i+","+l)}if(!t.style.width){const e=(t.getAttribute("data-size")||t.getAttribute("data-origin")||"").split(",");s.onModifyMode.call(this,t,null),s.applySize.call(this,e[0],e[1])}this.context.resizing._resize_plugin=o}"function"==typeof n&&n(t,c,u,d,--a._uploadFileLength<0?0:a._uploadFileLength,this)},deleteInfo:function(e,t,n){if(t>=0){const i=this.context[e]._infoList;for(let e=0,l=i.length;e<l;e++)if(t===i[e].index)return i.splice(e,1),void("function"==typeof n&&n(null,t,"delete",null,0,this))}},resetInfo:function(e,t){const n=this.context[e];if("function"==typeof t){const e=n._infoList;for(let n=0,i=e.length;n<i;n++)t(null,e[n].index,"delete",null,0,this)}n._infoList=[],n._infoIndex=0}};return void 0===t&&(e.SUNEDITOR_MODULES||Object.defineProperty(e,"SUNEDITOR_MODULES",{enumerable:!0,writable:!1,configurable:!1,value:{}}),Object.defineProperty(e.SUNEDITOR_MODULES,"fileManager",{enumerable:!0,writable:!1,configurable:!1,value:n})),n},"object"==typeof e.exports?e.exports=i.document?l(i,!0):function(e){if(!e.document)throw new Error("SUNEDITOR_MODULES a window with a document");return l(e)}:l(i)}});
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vc3JjL3BsdWdpbnMvbW9kdWxlcy9kaWFsb2cuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3BsdWdpbnMvbW9kdWxlcy9maWxlQnJvd3Nlci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvbGFuZy9lbi5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvcGx1Z2lucy9tb2R1bGVzL19jb2xvclBpY2tlci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvcGx1Z2lucy9zdWJtZW51L2ZvbnRDb2xvci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvcGx1Z2lucy9zdWJtZW51L2hpbGl0ZUNvbG9yLmpzIiwid2VicGFjazovLy8uL3NyYy9wbHVnaW5zL3N1Ym1lbnUvdGVtcGxhdGUuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3BsdWdpbnMvZGlhbG9nL2xpbmsuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3BsdWdpbnMvZGlhbG9nL2ltYWdlLmpzIiwid2VicGFjazovLy8uL3NyYy9wbHVnaW5zL2RpYWxvZy92aWRlby5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvcGx1Z2lucy9kaWFsb2cvYXVkaW8uanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3BsdWdpbnMvZGlhbG9nL21hdGguanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3BsdWdpbnMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3BsdWdpbnMvY29tbWFuZC9ibG9ja3F1b3RlLmpzIiwid2VicGFjazovLy8uL3NyYy9wbHVnaW5zL3N1Ym1lbnUvYWxpZ24uanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3BsdWdpbnMvc3VibWVudS9mb250LmpzIiwid2VicGFjazovLy8uL3NyYy9wbHVnaW5zL3N1Ym1lbnUvZm9udFNpemUuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3BsdWdpbnMvc3VibWVudS9ob3Jpem9udGFsUnVsZS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvcGx1Z2lucy9zdWJtZW51L2xpc3QuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3BsdWdpbnMvc3VibWVudS90YWJsZS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvcGx1Z2lucy9zdWJtZW51L2Zvcm1hdEJsb2NrLmpzIiwid2VicGFjazovLy8uL3NyYy9wbHVnaW5zL3N1Ym1lbnUvbGluZUhlaWdodC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvcGx1Z2lucy9zdWJtZW51L3BhcmFncmFwaFN0eWxlLmpzIiwid2VicGFjazovLy8uL3NyYy9wbHVnaW5zL3N1Ym1lbnUvdGV4dFN0eWxlLmpzIiwid2VicGFjazovLy8uL3NyYy9wbHVnaW5zL2ZpbGVCcm93c2VyL2ltYWdlR2FsbGVyeS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL2RlZmF1bHRJY29ucy5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvbGliL3V0aWwuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2xpYi9jb25zdHJ1Y3Rvci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvbGliL2NvbnRleHQuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3BsdWdpbnMvbW9kdWxlcy9fbm90aWNlLmpzIiwid2VicGFjazovLy8uL3NyYy9zdW5lZGl0b3IuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2xpYi9jb3JlLmpzIiwid2VicGFjazovLy8uL3NyYy9saWIvaGlzdG9yeS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvc3VuZWRpdG9yX2J1aWxkLmpzIiwid2VicGFjazovLy8uL3NyYy9wbHVnaW5zL21vZHVsZXMvY29tcG9uZW50LmpzIiwid2VicGFjazovLy8uL3NyYy9wbHVnaW5zL21vZHVsZXMvcmVzaXppbmcuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3BsdWdpbnMvbW9kdWxlcy9maWxlTWFuYWdlci5qcyJdLCJuYW1lcyI6WyJpbnN0YWxsZWRNb2R1bGVzIiwiX193ZWJwYWNrX3JlcXVpcmVfXyIsIm1vZHVsZUlkIiwiZXhwb3J0cyIsIm1vZHVsZSIsImkiLCJsIiwibW9kdWxlcyIsImNhbGwiLCJtIiwiYyIsImQiLCJuYW1lIiwiZ2V0dGVyIiwibyIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZW51bWVyYWJsZSIsImdldCIsInIiLCJTeW1ib2wiLCJ0b1N0cmluZ1RhZyIsInZhbHVlIiwidCIsIm1vZGUiLCJfX2VzTW9kdWxlIiwibnMiLCJjcmVhdGUiLCJrZXkiLCJiaW5kIiwibiIsIm9iamVjdCIsInByb3BlcnR5IiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJwIiwicyIsImdsb2JhbCIsImZhY3RvcnkiLCJ3aW5kb3ciLCJ0aGlzIiwibm9HbG9iYWwiLCJkaWFsb2ciLCJhZGQiLCJjb3JlIiwiY29udGV4dCIsImtpbmQiLCJ1cGRhdGVNb2RhbCIsIl9jbG9zZVNpZ25hbCIsImRpYWxvZ19kaXYiLCJ1dGlsIiwiY3JlYXRlRWxlbWVudCIsImNsYXNzTmFtZSIsImRpYWxvZ19iYWNrIiwic3R5bGUiLCJkaXNwbGF5IiwiZGlhbG9nX2FyZWEiLCJhcHBlbmRDaGlsZCIsIm1vZGFsQXJlYSIsImJhY2siLCJtb2RhbCIsImFkZEV2ZW50TGlzdGVuZXIiLCJfb25Nb3VzZURvd25fZGlhbG9nIiwiX29uQ2xpY2tfZGlhbG9nIiwiZWxlbWVudCIsInJlbGF0aXZlIiwiZSIsInRlc3QiLCJ0YXJnZXQiLCJzdG9wUHJvcGFnYXRpb24iLCJnZXRBdHRyaWJ1dGUiLCJwbHVnaW5zIiwiY2xvc2UiLCJvcGVuIiwidXBkYXRlIiwibW9kYWxGb3JtIiwiX2JpbmRDbG9zZSIsIl9kIiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsImtleUNvZGUiLCJvcHRpb24iLCJwb3B1cERpc3BsYXkiLCJwb3NpdGlvbiIsImZvY3VzRWxlbWVudCIsIm9uIiwiZm9jdXMiLCJpbml0IiwiU1VORURJVE9SX01PRFVMRVMiLCJ3cml0YWJsZSIsImNvbmZpZ3VyYWJsZSIsImRvY3VtZW50IiwidyIsIkVycm9yIiwiZmlsZUJyb3dzZXIiLCJfeG1sSHR0cCIsIl9sb2FkaW5nIiwiYXJlYSIsImhlYWRlciIsInRhZ0FyZWEiLCJib2R5IiwibGlzdCIsInRhZ0VsZW1lbnRzIiwiaXRlbXMiLCJzZWxlY3RlZFRhZ3MiLCJzZWxlY3RvckhhbmRsZXIiLCJjb250ZXh0UGx1Z2luIiwiY29sdW1uU2l6ZSIsImJyb3dzZXJfZGl2IiwiY29udGVudCIsImlubmVySFRNTCIsInNldF9icm93c2VyIiwicXVlcnlTZWxlY3RvciIsInRpdGxlQXJlYSIsIm9uQ2xpY2tUYWciLCJvbkNsaWNrRmlsZSIsIl9vbk1vdXNlRG93bl9icm93c2VyIiwiX29uQ2xpY2tfYnJvd3NlciIsImxhbmciLCJkaWFsb2dCb3giLCJpY29ucyIsImNhbmNlbCIsInBsdWdpbk5hbWUiLCJmaWxlQnJvd3NlckNvbnRleHQiLCJwbHVnaW5Db250ZXh0IiwibGlzdENsYXNzTmFtZSIsImxpc3RDbGFzcyIsImhhc0NsYXNzIiwidGV4dENvbnRlbnQiLCJ0aXRsZSIsIl9kcmF3RmlsZUxpc3QiLCJ1cmwiLCJmaWxlQnJvd3NlclBsdWdpbiIsImFib3J0Iiwic2hvd0Jyb3dzZXJMb2FkaW5nIiwiY2xvc2VCcm93c2VyTG9hZGluZyIsInhtbEh0dHAiLCJnZXRYTUxIdHRwUmVxdWVzdCIsIm9ucmVhZHlzdGF0ZWNoYW5nZSIsIl9jYWxsQmFja0dldCIsInNlbmQiLCJyZWFkeVN0YXRlIiwic3RhdHVzIiwiX2RyYXdMaXN0SXRlbSIsIkpTT04iLCJwYXJzZSIsInJlc3BvbnNlVGV4dCIsInJlc3VsdCIsIm1lc3NhZ2UiLCJtYXhIZWlnaHQiLCJfdyIsImlubmVySGVpZ2h0Iiwib2Zmc2V0SGVpZ2h0IiwicmVzIiwiZXJyIiwiZXJyb3JNZXNzYWdlIiwiX3RhZ3MiLCJsZW4iLCJsZW5ndGgiLCJzcGxpdFNpemUiLCJNYXRoIiwicm91bmQiLCJkcmF3SXRlbUhhbmRsZXIiLCJpdGVtVGVtcGxhdGVIYW5kbGVyIiwidGFnc0hUTUwiLCJsaXN0SFRNTCIsImNvbHVtbnMiLCJpdGVtIiwidGFncyIsInRhZyIsInNwbGl0IiwibWFwIiwidiIsInRyaW0iLCJ0TGVuIiwiaW5kZXhPZiIsInB1c2giLCJxdWVyeVNlbGVjdG9yQWxsIiwiaXNBbmNob3IiLCJ0YWdOYW1lIiwic2VsZWN0VGFnIiwic1RhZ0luZGV4Iiwic3BsaWNlIiwicmVtb3ZlQ2xhc3MiLCJhZGRDbGFzcyIsImZpbHRlciIsInNvbWUiLCJwcmV2ZW50RGVmYXVsdCIsImxpc3RFbCIsImNvbW1hbmQiLCJwYXJlbnROb2RlIiwiaGFuZGxlciIsImNvZGUiLCJ0b29sYmFyIiwiZGVmYXVsdCIsInNhdmUiLCJmb250IiwiZm9ybWF0cyIsImZvbnRTaXplIiwiYm9sZCIsInVuZGVybGluZSIsIml0YWxpYyIsInN0cmlrZSIsInN1YnNjcmlwdCIsInN1cGVyc2NyaXB0IiwicmVtb3ZlRm9ybWF0IiwiZm9udENvbG9yIiwiaGlsaXRlQ29sb3IiLCJpbmRlbnQiLCJvdXRkZW50IiwiYWxpZ24iLCJhbGlnbkxlZnQiLCJhbGlnblJpZ2h0IiwiYWxpZ25DZW50ZXIiLCJhbGlnbkp1c3RpZnkiLCJvcmRlckxpc3QiLCJ1bm9yZGVyTGlzdCIsImhvcml6b250YWxSdWxlIiwiaHJfc29saWQiLCJocl9kb3R0ZWQiLCJocl9kYXNoZWQiLCJ0YWJsZSIsImxpbmsiLCJtYXRoIiwiaW1hZ2UiLCJ2aWRlbyIsImF1ZGlvIiwiZnVsbFNjcmVlbiIsInNob3dCbG9ja3MiLCJjb2RlVmlldyIsInVuZG8iLCJyZWRvIiwicHJldmlldyIsInByaW50IiwidGFnX3AiLCJ0YWdfZGl2IiwidGFnX2giLCJ0YWdfYmxvY2txdW90ZSIsInRhZ19wcmUiLCJ0ZW1wbGF0ZSIsImxpbmVIZWlnaHQiLCJwYXJhZ3JhcGhTdHlsZSIsInRleHRTdHlsZSIsImltYWdlR2FsbGVyeSIsIm1lbnRpb24iLCJsaW5rQm94IiwidGV4dCIsIm5ld1dpbmRvd0NoZWNrIiwibWF0aEJveCIsImlucHV0TGFiZWwiLCJmb250U2l6ZUxhYmVsIiwicHJldmlld0xhYmVsIiwiaW1hZ2VCb3giLCJmaWxlIiwiYWx0VGV4dCIsInZpZGVvQm94IiwiYXVkaW9Cb3giLCJicm93c2VyIiwic2VhcmNoIiwiY2FwdGlvbiIsInN1Ym1pdEJ1dHRvbiIsInJldmVydEJ1dHRvbiIsInByb3BvcnRpb24iLCJiYXNpYyIsImxlZnQiLCJyaWdodCIsImNlbnRlciIsIndpZHRoIiwiaGVpZ2h0Iiwic2l6ZSIsInJhdGlvIiwiY29udHJvbGxlciIsImVkaXQiLCJ1bmxpbmsiLCJyZW1vdmUiLCJpbnNlcnRSb3dBYm92ZSIsImluc2VydFJvd0JlbG93IiwiZGVsZXRlUm93IiwiaW5zZXJ0Q29sdW1uQmVmb3JlIiwiaW5zZXJ0Q29sdW1uQWZ0ZXIiLCJkZWxldGVDb2x1bW4iLCJmaXhlZENvbHVtbldpZHRoIiwicmVzaXplMTAwIiwicmVzaXplNzUiLCJyZXNpemU1MCIsInJlc2l6ZTI1IiwiYXV0b1NpemUiLCJtaXJyb3JIb3Jpem9udGFsIiwibWlycm9yVmVydGljYWwiLCJyb3RhdGVMZWZ0Iiwicm90YXRlUmlnaHQiLCJtYXhTaXplIiwibWluU2l6ZSIsInRhYmxlSGVhZGVyIiwibWVyZ2VDZWxscyIsInNwbGl0Q2VsbHMiLCJIb3Jpem9udGFsU3BsaXQiLCJWZXJ0aWNhbFNwbGl0IiwibWVudSIsInNwYWNlZCIsImJvcmRlcmVkIiwibmVvbiIsInRyYW5zbHVjZW50Iiwic2hhZG93IiwiU1VORURJVE9SX0xBTkciLCJjb2xvclBpY2tlciIsImNvbG9yTGlzdEhUTUwiLCJfY29sb3JJbnB1dCIsIl9kZWZhdWx0Q29sb3IiLCJfc3R5bGVQcm9wZXJ0eSIsIl9jdXJyZW50Q29sb3IiLCJfY29sb3JMaXN0IiwibGlzdERpdiIsImNyZWF0ZUNvbG9yTGlzdCIsIl9tYWtlQ29sb3JMaXN0IiwibWFrZUNvbG9yIiwiY29sb3JMaXN0IiwiY29sb3JBcnIiLCJjb2xvciIsImNoZWNrZWQiLCJlcmFzZSIsIm5vZGUiLCJmaWxsQ29sb3IiLCJnZXRDb2xvckluTm9kZSIsImlzSGV4Q29sb3IiLCJyZ2IyaGV4IiwidG9Mb3dlckNhc2UiLCJzZXRJbnB1dFRleHQiLCJjb2xvck5hbWUyaGV4Iiwic2V0Q3VycmVudENvbG9yIiwiaGV4Q29sb3JTdHIiLCJib3JkZXJDb2xvciIsImZpbmRDb2xvciIsInN0eWxlUHJvcGVydHkiLCJpc1d5c2l3eWdEaXYiLCJub2RlVHlwZSIsInN0ciIsInJnYiIsInJnYk1hdGNoIiwibWF0Y2giLCJwYXJzZUludCIsInRvU3RyaW5nIiwic2xpY2UiLCJjb2xvck5hbWUiLCJ0ZW1wIiwiY29sb3JzIiwiZ2V0Q29tcHV0ZWRTdHlsZSIsImEiLCJyZW1vdmVJdGVtIiwic3Vic3RyIiwidGFyZ2V0RWxlbWVudCIsImFkZE1vZHVsZSIsInByZXZpZXdFbCIsImNvbG9ySW5wdXQiLCJzZXRTdWJtZW51Iiwib25DaGFuZ2VJbnB1dCIsInN1Ym1pdCIsInBpY2t1cCIsImluaXRNZW51VGFyZ2V0IiwiY29sb3JBcmVhIiwiY29udGV4dFBpY2tlciIsImNvbnRleHRGb250Q29sb3IiLCJnZXRTZWxlY3Rpb25Ob2RlIiwiYXBwbHlDb2xvciIsIm5vZGVDaGFuZ2UiLCJzdWJtZW51T2ZmIiwibmV3Tm9kZSIsImNvbnRleHRIaWxpdGVDb2xvciIsImJhY2tncm91bmRDb2xvciIsInRlbXBsYXRlRGl2IiwidGVtcGxhdGVMaXN0IiwidGVtcGxhdGVzIiwiaHRtbCIsInNldENvbnRlbnRzIiwibGlua05ld1dpbmRvd0NoZWNrIiwibGlua0FuY2hvclRleHQiLCJfbGlua0FuY2hvciIsIl9saW5rVmFsdWUiLCJsaW5rX2RpYWxvZyIsInNldERpYWxvZyIsImxpbmtfY29udHJvbGxlciIsInNldENvbnRyb2xsZXJfTGlua0J1dHRvbiIsImxpbmtDb250cm9sbGVyIiwiZXZlbnRTdG9wIiwib25DbGlja19saW5rQ29udHJvbGxlciIsIl9vbkxpbmtQcmV2aWV3Iiwib3B0aW9ucyIsImxpbmtQcm90b2NvbCIsImxpbmtfYnRuIiwiZGVsZXRlIiwiY3VycmVudENvbnRyb2xsZXJOYW1lIiwicHJvdG9jb2wiLCJzaG93TG9hZGluZyIsInN1Ym1pdEFjdGlvbiIsImNvbnRleHRMaW5rIiwiYW5jaG9yIiwiYW5jaG9yVGV4dCIsImhyZWYiLCJ0ZXh0Tm9kZSIsImNoaWxkTm9kZXMiLCJzZXRSYW5nZSIsIm9BIiwic2VsZWN0ZWRGb3JtYXRzIiwiZ2V0U2VsZWN0ZWRFbGVtZW50cyIsIm9Gb3JtYXQiLCJub2RlTmFtZSIsImluc2VydE5vZGUiLCJjbG9zZUxvYWRpbmciLCJoaXN0b3J5IiwiYWN0aXZlIiwiY29udHJvbGxlckFycmF5IiwiY2FsbF9jb250cm9sbGVyIiwiY29udHJvbGxlcnNPZmYiLCJnZXRTZWxlY3Rpb24iLCJzZWxlY3Rpb25BVGFnIiwiZWRpdExpbmsiLCJsaW5rQnRuIiwic2V0Q29udHJvbGxlclBvc2l0aW9uIiwidG9wIiwiY29udHJvbGxlcnNPbiIsInNjIiwiZ2V0Q2hpbGRFbGVtZW50IiwiY3VycmVudCIsImVjIiwiY29tcG9uZW50IiwicmVzaXppbmciLCJmaWxlTWFuYWdlciIsImNvbnRleHRJbWFnZSIsIl9pbmZvTGlzdCIsIl9pbmZvSW5kZXgiLCJfdXBsb2FkRmlsZUxlbmd0aCIsInNpemVVbml0IiwiX2ltYWdlU2l6ZVVuaXQiLCJfYWx0VGV4dCIsIl9saW5rRWxlbWVudCIsIl9hbGlnbiIsIl9mbG9hdENsYXNzUmVnRXhwIiwiX3ZfbGluayIsIl92X3NyYyIsInN2Z0RlZmF1bHRTaXplIiwiYmFzZTY0UmVuZGVySW5kZXgiLCJfZWxlbWVudCIsIl9jb3ZlciIsIl9jb250YWluZXIiLCJpbnB1dFgiLCJpbnB1dFkiLCJfZWxlbWVudF93IiwiX2VsZW1lbnRfaCIsIl9lbGVtZW50X2wiLCJfZWxlbWVudF90IiwiX2RlZmF1bHRTaXplWCIsIl9kZWZhdWx0U2l6ZVkiLCJfb3JpZ2luX3ciLCJpbWFnZVdpZHRoIiwiX29yaWdpbl9oIiwiaW1hZ2VIZWlnaHQiLCJfcHJvcG9ydGlvbkNoZWNrZWQiLCJfcmVzaXppbmciLCJpbWFnZVJlc2l6aW5nIiwiX3Jlc2l6ZURvdEhpZGUiLCJpbWFnZUhlaWdodFNob3ciLCJfcm90YXRpb24iLCJpbWFnZVJvdGF0aW9uIiwiX29ubHlQZXJjZW50YWdlIiwiaW1hZ2VTaXplT25seVBlcmNlbnRhZ2UiLCJfcmF0aW8iLCJfcmF0aW9YIiwiX3JhdGlvWSIsIl9jYXB0aW9uU2hvdyIsIl9jYXB0aW9uQ2hlY2tlZCIsIl9jYXB0aW9uIiwiY2FwdGlvbkNoZWNrRWwiLCJpbWFnZV9kaWFsb2ciLCJpbWdJbnB1dEZpbGUiLCJpbWdVcmxGaWxlIiwiaW1nTGluayIsImltZ0xpbmtOZXdXaW5kb3dDaGVjayIsInByZXZpZXdMaW5rIiwicHJldmlld1NyYyIsIm9wZW5UYWIiLCJfcmVtb3ZlU2VsZWN0ZWRGaWxlcyIsIl9maWxlSW5wdXRDaGFuZ2UiLCJpbWFnZUdhbGxlcnlCdXR0b24iLCJfb3BlbkdhbGxlcnkiLCJzZXRJbnB1dFNpemUiLCJzZXRSYXRpbyIsInNpemVSZXZlcnQiLCJpbWFnZUZpbGVJbnB1dCIsImltYWdlQWNjZXB0IiwiaW1hZ2VNdWx0aXBsZUZpbGUiLCJpbWFnZVVybElucHV0IiwiaW1hZ2VHYWxsZXJ5VXJsIiwiaW1hZ2VfZ2FsbGVyeSIsIm9ubHlQZXJjZW50YWdlIiwib25seVBlcmNlbnREaXNwbGF5IiwiaGVpZ2h0RGlzcGxheSIsInJldmVydCIsInNldEF0dHJpYnV0ZSIsInRleHREZWNvcmF0aW9uIiwicmVtb3ZlQXR0cmlidXRlIiwidXJsSW5wdXQiLCJjYWxsUGx1Z2luIiwiX3NldFVybElucHV0IiwiYWx0Iiwic3JjIiwiZmlsZVRhZ3MiLCJzZWxlY3QiLCJvbk1vZGlmeU1vZGUiLCJjYWxsX2NvbnRyb2xsZXJfcmVzaXplIiwiZGVzdHJveSIsImltYWdlRWwiLCJpbWFnZUNvbnRhaW5lciIsImdldFBhcmVudEVsZW1lbnQiLCJpc01lZGlhQ29tcG9uZW50IiwiZGF0YUluZGV4IiwiZm9jdXNFbCIsInByZXZpb3VzRWxlbWVudFNpYmxpbmciLCJuZXh0RWxlbWVudFNpYmxpbmciLCJlbXB0eURpdiIsInd5c2l3eWciLCJyZW1vdmVJdGVtQWxsUGFyZW50cyIsImZvY3VzRWRnZSIsImRlbGV0ZUluZm8iLCJmdW5jdGlvbnMiLCJvbkltYWdlVXBsb2FkIiwidGFiTmFtZSIsInRhYkNvbnRlbnQiLCJ0YWJMaW5rcyIsImdldEVsZW1lbnRzQnlDbGFzc05hbWUiLCJpbWFnZVBsdWdpbiIsInVwZGF0ZV9pbWFnZSIsImZpbGVzIiwib25SZW5kZXJfaW1nVXJsIiwiZXJyb3IiLCJmaWxlTGlzdCIsImZpbGVTaXplIiwidHlwZSIsImxpbWl0U2l6ZSIsImltYWdlVXBsb2FkU2l6ZUxpbWl0IiwiaW5mb1NpemUiLCJpbWFnZXNJbmZvIiwib25JbWFnZVVwbG9hZEVycm9yIiwibm90aWNlT3BlbiIsImluZm8iLCJsaW5rVmFsdWUiLCJsaW5rTmV3V2luZG93IiwiaW5wdXRXaWR0aCIsImlucHV0SGVpZ2h0IiwiaXNVcGRhdGUiLCJvbkltYWdlVXBsb2FkQmVmb3JlIiwiZGF0YSIsIkFycmF5IiwiaXNBcnJheSIsInJlZ2lzdGVyIiwidXBsb2FkIiwicmVzcG9uc2UiLCJpbWFnZVVwbG9hZFVybCIsImZpbGVzTGVuIiwiZm9ybURhdGEiLCJGb3JtRGF0YSIsImFwcGVuZCIsImltYWdlVXBsb2FkSGVhZGVyIiwiY2FsbEJhY2tfaW1nVXBsb2FkIiwic2V0dXBfcmVhZGVyIiwiaW1hZ2VVcGxvYWRIYW5kbGVyIiwidXBkYXRlX3NyYyIsImNyZWF0ZV9pbWFnZSIsImltZ0xpbmtWYWx1ZSIsIndGaWxlUmVhZGVyIiwiRmlsZVJlYWRlciIsImZpbGVzU3RhY2siLCJyZWFkZXIiLCJvbmxvYWQiLCJ1cGRhdGVFbGVtZW50IiwiaW5kZXgiLCJvblJlbmRlcl9pbWdCYXNlNjQiLCJyZWFkQXNEYXRhVVJMIiwidXBkYXRlTWV0aG9kIiwiY3JlYXRlTWV0aG9kIiwicG9wIiwib25SZW5kZXJfbGluayIsImltZ1RhZyIsInh5IiwiX21vZHVsZV9zZXRJbnB1dFNpemUiLCJfbW9kdWxlX3NldFJhdGlvIiwiY2hlY2tGaWxlSW5mbyIsIm1vZGlmeUhhbmRsZXIiLCJvcGVuTW9kaWZ5IiwiY2hlY2tJbmZvIiwicmVzZXRGaWxlSW5mbyIsInJlc2V0SW5mbyIsIl9yZXNpemVfcGx1Z2luIiwib0ltZyIsImNvdmVyIiwic2V0X2NvdmVyIiwiY29udGFpbmVyIiwic2V0X2NvbnRhaW5lciIsImNyZWF0ZV9jYXB0aW9uIiwiYXBwbHlTaXplIiwic2V0QWxpZ24iLCJfaW1hZ2VfY3JlYXRlX29ubG9hZCIsImluc2VydENvbXBvbmVudCIsInNldEluZm8iLCJvZmZzZXRXaWR0aCIsInNlbGVjdENvbXBvbmVudCIsIm9wZW5Db250cm9sbGVyIiwibm90SGlzdG9yeVB1c2giLCJjaGFuZ2VTaXplIiwiaXNOZXdDb250YWluZXIiLCJjbG9uZU5vZGUiLCJ4IiwiaXNOdW1iZXIiLCJ5IiwibW9kaWZpZWRDYXB0aW9uIiwiY29udGFpbnMiLCJuZXdFbCIsImluc2VydEJlZm9yZSIsImltYWdlRWxlbWVudCIsInJlbW92ZUNoaWxkIiwiZXhpc3RFbGVtZW50IiwiaXNSYW5nZUZvcm1hdEVsZW1lbnQiLCJnZXRGb3JtYXRFbGVtZW50IiwiaXNGb3JtYXRFbGVtZW50IiwicmVwbGFjZUNoaWxkIiwiX3JvdGF0ZVZlcnRpY2FsIiwicmVzZXRUcmFuc2Zvcm0iLCJzZXRUcmFuc2Zvcm1TaXplIiwiZ2V0TnVtYmVyIiwic2V0VGltZW91dCIsImgiLCJ1c2VyU2l6ZSIsIm5vdE9wZW4iLCJfbW9kdWxlX3NldE1vZGlmeUlucHV0U2l6ZSIsIl9tb2R1bGVfc2l6ZVJldmVydCIsInNldFBlcmNlbnRTaXplIiwic2V0U2l6ZSIsInNldEF1dG9TaXplIiwibm90UmVzZXRQZXJjZW50YWdlIiwiZGlyZWN0aW9uIiwib25seVciLCJvbmx5SCIsImNhbmNlbFBlcmNlbnRBdHRyIiwiX21vZHVsZV9zYXZlQ3VycmVudFNpemUiLCJtYXhXaWR0aCIsInNldE9yaWdpblNpemUiLCJvcmlnaW5TaXplIiwiaGVpZ2h0UGVyY2VudGFnZSIsInNldENhcHRpb25Qb3NpdGlvbiIsIm1hcmdpbiIsIm1pbldpZHRoIiwicmVzZXRBbGlnbiIsImNvbnRleHRWaWRlbyIsIl92aWRlb1NpemVVbml0IiwiX3lvdXR1YmVRdWVyeSIsInlvdXR1YmVRdWVyeSIsIl92aWRlb1JhdGlvIiwidmlkZW9SYXRpbyIsIl9kZWZhdWx0UmF0aW8iLCJ2aWRlb1dpZHRoIiwidmlkZW9IZWlnaHQiLCJ2aWRlb1Jlc2l6aW5nIiwidmlkZW9IZWlnaHRTaG93IiwidmlkZW9Sb3RhdGlvbiIsInZpZGVvU2l6ZU9ubHlQZXJjZW50YWdlIiwidmlkZW9fZGlhbG9nIiwidmlkZW9JbnB1dEZpbGUiLCJ2aWRlb1VybEZpbGUiLCJ2aWRlb1JhdGlvT3B0aW9uIiwic2V0VmlkZW9SYXRpbyIsInZpZGVvRmlsZUlucHV0IiwidmlkZW9BY2NlcHQiLCJ2aWRlb011bHRpcGxlRmlsZSIsInZpZGVvVXJsSW5wdXQiLCJyYXRpb0xpc3QiLCJ2aWRlb1JhdGlvTGlzdCIsInJhdGlvRGlzcGxheSIsInZpZGVvUmF0aW9TaG93Iiwib25seVdpZHRoRGlzcGxheSIsIl9zZXRUYWdBdHRycyIsImF0dHJzIiwidmlkZW9UYWdBdHRycyIsImhhc093biIsImNyZWF0ZVZpZGVvVGFnIiwidmlkZW9UYWciLCJfc2V0SWZyYW1lQXR0cnMiLCJmcmFtZUJvcmRlciIsImFsbG93RnVsbHNjcmVlbiIsInZpZGVvSWZyYW1lQXR0cnMiLCJjcmVhdGVJZnJhbWVUYWciLCJpZnJhbWVUYWciLCJmcmFtZSIsIm9uVmlkZW9VcGxvYWQiLCJkaXNhYmxlZCIsInNldFZpZGVvUmF0aW9TZWxlY3QiLCJzZWxlY3RlZEluZGV4IiwicGxhY2Vob2xkZXIiLCJ2aWRlb1BsdWdpbiIsInNldHVwX3VybCIsInZpZGVvVXBsb2FkU2l6ZUxpbWl0IiwidmlkZW9zSW5mbyIsIm9uVmlkZW9VcGxvYWRFcnJvciIsIm9uVmlkZW9VcGxvYWRCZWZvcmUiLCJ2aWRlb1VwbG9hZFVybCIsInZpZGVvVXBsb2FkSGVhZGVyIiwiY2FsbEJhY2tfdmlkZW9VcGxvYWQiLCJ2aWRlb1VwbG9hZEhhbmRsZXIiLCJjcmVhdGVfdmlkZW8iLCJET01QYXJzZXIiLCJwYXJzZUZyb21TdHJpbmciLCJyZXBsYWNlIiwic3BsaXRVcmwiLCJlbmRzV2l0aCIsImxhc3RJbmRleE9mIiwib0ZyYW1lIiwiaXNZb3V0dWJlIiwiaXNWaW1lbyIsIm5ld1RhZyIsImlucHV0VXBkYXRlIiwiX21vZHVsZV9nZXRTaXplWCIsIl9tb2R1bGVfZ2V0U2l6ZVkiLCJpc1BlcmNlbnQiLCJjaGFuZ2VkIiwiX3VwZGF0ZV92aWRlb0NvdmVyIiwiZmlnY2FwdGlvbiIsIm9yaWdpbiIsInJhdGlvU2VsZWN0ZWQiLCJyYXRpb09wdGlvbnMiLCJzZWxlY3RlZCIsInBhZGRpbmdCb3R0b20iLCJkYXRhU2l6ZSIsImNvbnRleHRBdWRpbyIsInRhcmdldFNlbGVjdCIsImF1ZGlvV2lkdGgiLCJhdWRpb0hlaWdodCIsImF1ZGlvX2RpYWxvZyIsImF1ZGlvSW5wdXRGaWxlIiwiYXVkaW9VcmxGaWxlIiwiYXVkaW9fY29udHJvbGxlciIsInNldENvbnRyb2xsZXIiLCJvbkNsaWNrX2NvbnRyb2xsZXIiLCJhdWRpb0ZpbGVJbnB1dCIsImF1ZGlvQWNjZXB0IiwiYXVkaW9NdWx0aXBsZUZpbGUiLCJhdWRpb1VybElucHV0IiwiX2NyZWF0ZUF1ZGlvVGFnIiwib0F1ZGlvIiwiY3NzVGV4dCIsImF1ZGlvVGFnQXR0cnMiLCJpc0NvbXBvbmVudCIsIm9uQXVkaW9VcGxvYWQiLCJ1cGRhdGVDb3ZlciIsInNldHVwVXJsIiwiYXVkaW9VcGxvYWRTaXplTGltaXQiLCJhdWRpb3NJbmZvIiwib25BdWRpb1VwbG9hZEVycm9yIiwib25BdWRpb1VwbG9hZEJlZm9yZSIsImF1ZGlvVXBsb2FkVXJsIiwiYXVkaW9VcGxvYWRIZWFkZXIiLCJjYWxsQmFja191cGxvYWQiLCJhdWRpb1VwbG9hZEhhbmRsZXIiLCJjcmVhdGVfYXVkaW8iLCJzZWxlY3Rpb25UYWciLCJvbkNvbnRyb2xsZXJPZmYiLCJwcmV2aWV3RWxlbWVudCIsImZvbnRTaXplRWxlbWVudCIsIl9tYXRoRXhwIiwibWF0aF9kaWFsb2ciLCJfcmVuZGVyTWF0aEV4cCIsIm1hdGhfY29udHJvbGxlciIsInNldENvbnRyb2xsZXJfTWF0aEJ1dHRvbiIsIm1hdGhDb250cm9sbGVyIiwib25DbGlja19tYXRoQ29udHJvbGxlciIsIm1hdGhfYnRuIiwibWFuYWdlZFRhZ3MiLCJtZXRob2QiLCJkb20iLCJjcmVhdGVSYW5nZSIsImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIsIl9yZW5kZXJlciIsIkhUTUxEZWNvZGVyIiwiZXhwIiwia2F0ZXgiLCJyZW5kZXJUb1N0cmluZyIsImNvbnRleHRNYXRoIiwibWF0aEV4cCIsImthdGV4RWwiLCJIVE1MRW5jb2RlciIsImNvbnRhaW5lckVsIiwiZW1wdHkiLCJjcmVhdGVUZXh0Tm9kZSIsInplcm9XaWR0aFNwYWNlIiwibmV4dFNpYmxpbmciLCJtYXRoVGFnIiwibWF0aEJ0biIsImJsb2NrcXVvdGUiLCJ0YXJnZXRCdXR0b24iLCJhY3Rpb24iLCJjdXJyZW50QmxvY2txdW90ZSIsImRldGFjaFJhbmdlRm9ybWF0RWxlbWVudCIsImFwcGx5UmFuZ2VGb3JtYXRFbGVtZW50IiwiX2FsaWduTGlzdCIsImN1cnJlbnRBbGlnbiIsImRlZmF1bHREaXIiLCJydGwiLCJqdXN0aWZ5IiwiYWxpZ25fanVzdGlmeSIsImFsaWduX2xlZnQiLCJhbGlnbl9yaWdodCIsImFsaWduX2NlbnRlciIsImxpc3RVbCIsImxlZnREaXIiLCJsZWZ0TWVudSIsInJpZ2h0TWVudSIsImFsaWduQ29udGV4dCIsImZpcnN0RWxlbWVudENoaWxkIiwidGV4dEFsaWduIiwiY2hhbmdlRWxlbWVudCIsImFsaWduTGlzdCIsInNlbGVjdGVkRm9ybXN0cyIsInNldFN0eWxlIiwiZWZmZWN0Tm9kZSIsInRhcmdldFRleHQiLCJ0YXJnZXRUb29sdGlwIiwiX2ZvbnRMaXN0IiwiY3VycmVudEZvbnQiLCJmb250TGlzdCIsInRvb2x0aXAiLCJmb250RmFtaWx5Iiwic2VsZWN0Rm9udCIsImNoYW5nZVR4dCIsImZvbnRDb250ZXh0IiwiX3NpemVMaXN0IiwiY3VycmVudFNpemUiLCJzaXplTGlzdCIsInVuaXQiLCJmb250U2l6ZVVuaXQiLCJmb250U2l6ZUNvbnRleHQiLCJob3Jpem9udGFsUnVsZVBpY2siLCJhcHBlbmRIciIsIm9IciIsIm9Ob2RlIiwiX2xpc3QiLCJjdXJyZW50TGlzdCIsImJ1bGxldHMiLCJsaXN0X2J1bGxldHMiLCJudW1iZXIiLCJsaXN0X251bWJlciIsImJ1dHRvbiIsImljb24iLCJpc0xpc3QiLCJsaXN0Q29udGV4dCIsImVkaXRMaXN0Iiwic2VsZWN0ZWRDZWxscyIsImRldGFjaCIsInJhbmdlIiwiZ2V0UmFuZ2UiLCJnZXRTZWxlY3RlZEVsZW1lbnRzQW5kQ29tcG9uZW50cyIsImdldFJhbmdlX2FkZExpbmUiLCJzb3J0QnlEZXB0aCIsImZpcnN0U2VsIiwibGFzdFNlbCIsInRvcEVsIiwiaXNMaXN0Q2VsbCIsImJvdHRvbUVsIiwib3JpZ2luUmFuZ2UiLCJzdGFydENvbnRhaW5lciIsInNvIiwic3RhcnRPZmZzZXQiLCJlbmRDb250YWluZXIiLCJlbyIsImVuZE9mZnNldCIsImlzUmVtb3ZlIiwiZ2V0UmFuZ2VGb3JtYXRFbGVtZW50IiwidG9VcHBlckNhc2UiLCJ0b3BFbFBhcmVudCIsImJvdHRvbUVsUGFyZW50IiwibWVyZ2VUb3AiLCJtZXJnZUJvdHRvbSIsImZpcnN0TGlzdCIsImxhc3RMaXN0IiwidG9wTnVtYmVyIiwiYm90dG9tTnVtYmVyIiwicGFzc0NvbXBvbmVudCIsIm5ld0NlbGwiLCJmVGFnIiwiaXNDZWxsIiwibmV4dCIsIm9yaWdpblBhcmVudCIsIm5leHRQYXJlbnQiLCJwYXJlbnRUYWciLCJzaWJsaW5nVGFnIiwicmFuZ2VUYWciLCJfaXNJZ25vcmVOb2RlQ2hhbmdlIiwiY29weUZvcm1hdEF0dHJpYnV0ZXMiLCJpc0hSIiwib3V0ZXJIVE1MIiwiZkNoaWxkcmVuIiwiY2hpbGRyZW4iLCJnZXRFbGVtZW50RGVwdGgiLCJqIiwiY3VycmVudEZvcm1hdCIsInJhbmdlQXJyIiwidGVtcExpc3QiLCJfZGV0YWNoTmVzdGVkIiwiZiIsImNlbGxzIiwiZmlyc3QiLCJsYXN0Iiwib3JpZ2luTGlzdCIsInNpYmxpbmciLCJjTGVuIiwibmV3TGlzdCIsImdldFBvc2l0aW9uSW5kZXgiLCJtZXJnZVNhbWVUYWdzIiwiZWRnZSIsImdldEVkZ2VDaGlsZE5vZGVzIiwiY2MiLCJlZGl0SW5zaWRlTGlzdCIsImNlbGxzTGVuIiwiZWwiLCJsYXN0Q2VsbCIsImlubmVyTGlzdCIsInByZXYiLCJub2RlUGF0aCIsInNsIiwiX2luc2llZExpc3QiLCJnZXROb2RlRnJvbVBhdGgiLCJpbnNlcnRQcmV2IiwiZ2V0Tm9kZVBhdGgiLCJmaXJzdENoaWxkIiwic2xQYXRoIiwibGFzdEVsZW1lbnRDaGlsZCIsIm1lcmdlTmVzdGVkVGFncyIsImNvbnRleHRUYWJsZSIsIl90ZEVsZW1lbnQiLCJfdHJFbGVtZW50IiwiX3RyRWxlbWVudHMiLCJfdGFibGVYWSIsIl9tYXhXaWR0aCIsIl9maXhlZENvbHVtbiIsIl9ydGwiLCJjZWxsQ29udHJvbGxlclRvcCIsInRhYmxlQ2VsbENvbnRyb2xsZXJQb3NpdGlvbiIsInJlc2l6ZVRleHQiLCJoZWFkZXJCdXR0b24iLCJtZXJnZUJ1dHRvbiIsInNwbGl0QnV0dG9uIiwic3BsaXRNZW51IiwibWF4VGV4dCIsIm1pblRleHQiLCJfcGh5c2ljYWxfY2VsbENudCIsIl9sb2dpY2FsX2NlbGxDbnQiLCJfcm93Q250IiwiX3Jvd0luZGV4IiwiX3BoeXNpY2FsX2NlbGxJbmRleCIsIl9sb2dpY2FsX2NlbGxJbmRleCIsIl9jdXJyZW50X2NvbFNwYW4iLCJfY3VycmVudF9yb3dTcGFuIiwiZXhwYW5zaW9uIiwicmVkdWN0aW9uIiwidGFibGVQaWNrZXIiLCJ0YWJsZUhpZ2hsaWdodCIsInRhYmxlVW5IaWdobGlnaHQiLCJ0YWJsZURpc3BsYXkiLCJ0YWJsZUNvbnRyb2xsZXIiLCJzZXRDb250cm9sbGVyX3RhYmxlIiwicmVzaXplQnV0dG9uIiwiY29sdW1uRml4ZWRCdXR0b24iLCJyZXNpemVEaXYiLCJzZXRDb250cm9sbGVyX3RhYmxlRWRpdG9yIiwiaW5zZXJ0Um93QWJvdmVCdXR0b24iLCJpbnNlcnRSb3dCZWxvd0J1dHRvbiIsIm9uTW91c2VNb3ZlX3RhYmxlUGlja2VyIiwiYXBwZW5kVGFibGUiLCJvbkNsaWNrX3RhYmxlQ29udHJvbGxlciIsInRhYmxlUmVzaXplIiwiZml4ZWRfY29sdW1uX3dpZHRoIiwidGFibGVfaGVhZGVyIiwiaW5zZXJ0X3Jvd19hYm92ZSIsImluc2VydF9yb3dfYmVsb3ciLCJkZWxldGVfcm93IiwibWVyZ2VfY2VsbCIsImluc2VydF9jb2x1bW5fbGVmdCIsImluc2VydF9jb2x1bW5fcmlnaHQiLCJkZWxldGVfY29sdW1uIiwic3BsaXRfY2VsbCIsIm9UYWJsZSIsImNyZWF0ZUNlbGxzIiwidGFibGVIVE1MIiwiZmlyc3RUZCIsInJlc2V0X3RhYmxlX3BpY2tlciIsImNudCIsInJldHVybkVsZW1lbnQiLCJjZWxsIiwiY2VsbHNIVE1MIiwiY2VpbCIsIm9mZnNldFgiLCJvZmZzZXRZIiwiaGlnaGxpZ2h0IiwidW5IaWdobGlnaHQiLCJ0YWJsZVBsdWdpbiIsIl9yZW1vdmVFdmVudHMiLCJfc2VsZWN0ZWRUYWJsZSIsIl90b2dnbGVFZGl0b3IiLCJfc2hpZnQiLCJfc2VsZWN0ZWRDZWxscyIsIl9yZWYiLCJfZml4ZWRDZWxsIiwiX3NlbGVjdGVkQ2VsbCIsIl9maXhlZENlbGxOYW1lIiwiY2FsbF9jb250cm9sbGVyX3RhYmxlRWRpdCIsInRkRWxlbWVudCIsImlzQ29sbGFwc2VkIiwidGFibGVFbGVtZW50IiwidGFibGVMYXlvdXQiLCJzZXRUYWJsZVN0eWxlIiwic2V0UG9zaXRpb25Db250cm9sbGVyVG9wIiwic2V0UG9zaXRpb25Db250cm9sbGVyRGl2IiwicmVzZXQiLCJzZXRDZWxsSW5mbyIsInJvd3MiLCJjZWxsSW5kZXgiLCJjZWxsQ250IiwiY29sU3BhbiIsInJvd0luZGV4Iiwicm93U3BhbiIsInJvd1NwYW5BcnIiLCJzcGFuSW5kZXgiLCJjcyIsInJzIiwibG9nY2FsSW5kZXgiLCJhcnIiLCJyb3ciLCJjb25jYXQiLCJzb3J0IiwiYiIsImVkaXRUYWJsZSIsImlzUm93IiwidGFibGVBdHRyIiwicG9zaXRpb25DZWxsIiwiZWRpdFJvdyIsInJlbW92ZUNlbGxzIiwiZmlyc3RSb3ciLCJyaWdodENlbGwiLCJlZGl0Q2VsbCIsInBvc2l0aW9uUmVzZXRFbGVtZW50IiwidXAiLCJvcmlnaW5Sb3dJbmRleCIsInNpZ24iLCJzcGFuQ2VsbHMiLCJzcGFuQ2VsbCIsInNoaWZ0IiwiaW5zZXJ0Um93IiwicGFzc0NlbGwiLCJyZW1vdmVDZWxsIiwicmVtb3ZlU3BhbkFyciIsImluc2VydEluZGV4IiwiYXBwbHlTcGFuIiwiY2VsbENvbFNwYW4iLCJyZW1vdmVJbmRleCIsImdldE92ZXJsYXBSYW5nZUF0SW5kZXgiLCJyZW1vdmVGaXJzdCIsInJlbW92ZUVuZCIsInJMZW4iLCJnZXRBcnJheUluZGV4Iiwicm93U3BhbkNlbGwiLCJfY2xvc2VTcGxpdE1lbnUiLCJvcGVuU3BsaXRNZW51IiwicmVtb3ZlRG9jRXZlbnQiLCJhZGREb2NFdmVudCIsInZlcnRpY2FsIiwiY3VycmVudENlbGwiLCJjdXJyZW50Um93IiwiY3VycmVudENvbFNwYW4iLCJmbG9vciIsImN1cnJlbnRSb3dTcGFuIiwibmV3Um93U3BhbiIsIm5leHRSb3dJbmRleCIsIm5leHRSb3ciLCJuZXh0Q2VsbHMiLCJuZXdSb3ciLCJwaHlzaWNhbEluZGV4IiwicmVmIiwibWVyZ2VDZWxsIiwiZW1wdHlSb3dGaXJzdCIsImVtcHR5Um93TGFzdCIsImNlIiwicmUiLCJtZXJnZUhUTUwiLCJjaCIsIm9ubHlaZXJvV2lkdGhTcGFjZSIsInJvd0luZGV4Rmlyc3QiLCJyb3dJbmRleExhc3QiLCJyZW1vdmVSb3dzIiwic2V0QWN0aXZlQnV0dG9uIiwidG9nZ2xlSGVhZGVyIiwidG9nZ2xlQ2xhc3MiLCJzdHlsZXMiLCJzcGFuIiwic2l6ZUljb24iLCJmaXhlZENlbGwiLCJzZWxlY3RlZENlbGwiLCJfYmluZE9uU2VsZWN0IiwiX2JpbmRPZmZTZWxlY3QiLCJfYmluZE9mZlNoaWZ0IiwiZW5hYmxlZCIsIl9vZmZDZWxsTXVsdGlTZWxlY3QiLCJfaW5pdEJpbmQiLCJfd2QiLCJfb25DZWxsTXVsdGlTZWxlY3QiLCJfYW50aUJsdXIiLCJfc2V0TXVsdGlDZWxscyIsInN0YXJ0Q2VsbCIsImVuZENlbGwiLCJmaW5kU2VsZWN0ZWRDZWxsIiwiX2kiLCJuZXdDcyIsIm5ld0NlIiwibmV3UnMiLCJuZXdSZSIsIm9uVGFibGVDZWxsTXVsdGlTZWxlY3QiLCJmb3JtYXRCbG9jayIsIl9mb3JtYXRMaXN0IiwicGlja1VwIiwibGFuZ190b29sYmFyIiwiZGVmYXVsdEZvcm1hdHMiLCJmb3JtYXRMaXN0IiwiZm9ybWF0IiwiY2xhc3MiLCJmb3JtYXRUaXRsZSIsImZvcm1hdENvbnRleHQiLCJyYW5nZUVsZW1lbnQiLCJmaXJzdFBhdGgiLCJsYXN0UGF0aCIsInJsaXN0IiwiZGV0YWNoTGlzdCIsIm1vZGlmaWVkRm9ybXN0cyIsImZyZWVFbGVtZW50IiwiYmVmb3JlIiwiaW5uZXIiLCJpc0NvbXAiLCJpc1NhbWVBdHRyaWJ1dGVzIiwicHJldmlvdXNTaWJsaW5nIiwibmV3Rm9ybWF0IiwibGluZUhlaWdodHMiLCJsaW5lSGVpZ2h0Q29udGV4dCIsIl9jbGFzc0xpc3QiLCJtZW51TGFuZyIsImRlZmF1bHRMaXN0IiwiX2NsYXNzIiwicGFyYWdyYXBoU3R5bGVzIiwiZGVmYXVsdFN0eWxlIiwicGFyYWdyYXBoTGlzdCIsIl9zdHlsZUxpc3QiLCJzdHlsZUxpc3QiLCJ0ZXh0U3R5bGVzIiwia2V5cyIsInN0eWxlQnV0dG9uTGlzdCIsInNlbGVjdGlvbk5vZGUiLCJidG4iLCJjaGVja1N0eWxlcyIsImNsYXNzZXMiLCJjbGFzc0xpc3QiLCJyZW1vdmVOb2RlcyIsImRyYXdJdGVtcyIsInNldEltYWdlIiwic3JjTmFtZSIsImNvZGVfdmlldyIsImxpbmVfaGVpZ2h0IiwicGFyYWdyYXBoX3N0eWxlIiwidGV4dF9zdHlsZSIsImFycm93X2Rvd24iLCJmb250X2NvbG9yIiwiaGlnaGxpZ2h0X2NvbG9yIiwiaG9yaXpvbnRhbF9ydWxlIiwic2hvd19ibG9ja3MiLCJtb2RpZnkiLCJhdXRvX3NpemUiLCJyb3RhdGVfbGVmdCIsInJvdGF0ZV9yaWdodCIsIm1pcnJvcl9ob3Jpem9udGFsIiwibWlycm9yX3ZlcnRpY2FsIiwibGluZV9icmVhayIsIm1vcmVfdGV4dCIsIm1vcmVfcGFyYWdyYXBoIiwibW9yZV9wbHVzIiwibW9yZV9ob3Jpem9udGFsIiwibW9yZV92ZXJ0aWNhbCIsImF0dGFjaG1lbnQiLCJtYWdpY19zdGljayIsImVtcHR5X2ZpbGUiLCJpc0lFIiwiaXNJRV9FZGdlIiwiaXNPU1hfSU9TIiwiX3Byb3BlcnRpZXNJbml0IiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwiYXBwVmVyc2lvbiIsInBsYXRmb3JtIiwiX0hUTUxDb252ZXJ0b3IiLCJjb250ZW50cyIsIiciLCJTdHJpbmciLCJmcm9tQ2hhckNvZGUiLCJ6ZXJvV2lkdGhSZWdFeHAiLCJSZWdFeHAiLCJvbmx5WmVyb1dpZHRoUmVnRXhwIiwiQWN0aXZlWE9iamVjdCIsIlhNTEh0dHBSZXF1ZXN0IiwiZTEiLCJlbGVtZW50TmFtZSIsIm9iaiIsIl9oYXNPd24iLCJnZXRJbmNsdWRlUGF0aCIsIm5hbWVBcnJheSIsImV4dGVuc2lvbiIsInBhdGgiLCJwYXRoTGlzdCIsImZpbGVOYW1lIiwicmVnRXhwIiwiZXh0UmVnRXhwIiwiZ2V0RWxlbWVudHNCeVRhZ05hbWUiLCJlZGl0b3JUYWciLCJsb2NhdGlvbiIsImdldFBhZ2VTdHlsZSIsImRvYyIsInNoZWV0cyIsInN0eWxlU2hlZXRzIiwicnVsZXMiLCJjc3NSdWxlcyIsImdldElmcmFtZURvY3VtZW50IiwiaWZyYW1lIiwid0RvY3VtZW50IiwiY29udGVudFdpbmRvdyIsImNvbnRlbnREb2N1bWVudCIsImdldEF0dHJpYnV0ZXNUb1N0cmluZyIsImV4Y2VwdEF0dHJzIiwiYXR0cmlidXRlcyIsImF0dHJTdHJpbmciLCJnZXRCeXRlTGVuZ3RoIiwiZW5jb2RlciIsImVuY29kZVVSSUNvbXBvbmVudCIsImNyIiwiY2wiLCJ1bmVzY2FwZSIsIlRleHRFbmNvZGVyIiwiZW5jb2RlIiwiaXNOb25FZGl0YWJsZSIsImlzVGV4dFN0eWxlRWxlbWVudCIsImlzQ2xvc3VyZVJhbmdlRm9ybWF0RWxlbWVudCIsImlzRnJlZUZvcm1hdEVsZW1lbnQiLCJpc0Nsb3N1cmVGcmVlRm9ybWF0RWxlbWVudCIsImlzTm90Q2hlY2tpbmdOb2RlIiwidmFsaWRhdGlvbiIsImdldEZyZWVGb3JtYXRFbGVtZW50IiwiZ2V0Q2xvc3VyZUZyZWVGb3JtYXRFbGVtZW50IiwiY29weVRhZ0F0dHJpYnV0ZXMiLCJvcmlnaW5FbCIsImNvcHlFbCIsImdldEFycmF5SXRlbSIsImFycmF5IiwibXVsdGkiLCJpZHgiLCJuZXh0SWR4IiwicHJldklkeCIsIl9uZXdPZmZzZXRzIiwiZmluZHMiLCJ0ZW1wVGV4dCIsInByZXZpb3VzIiwicmV2ZXJzZSIsIm9mZnNldHMiLCJub2RlcyIsInN0eWxlX2EiLCJzdHlsZV9iIiwiY29tcFN0eWxlIiwiY2xhc3NfYSIsImNsYXNzX2IiLCJyZWciLCJjb21wQ2xhc3MiLCJpc1RhYmxlIiwiaXNCcmVhayIsImlzTWVkaWEiLCJtYXhEZWMiLCJ0b0ZpeGVkIiwiZ2V0TGlzdENoaWxkcmVuIiwicmVjdXJzaW9uRnVuYyIsImdldExpc3RDaGlsZE5vZGVzIiwiZGVwdGgiLCJjb21wYXJlRWxlbWVudHMiLCJhTm9kZSIsImJOb2RlIiwiYW5jZXN0b3IiLCJhSW5kZXgiLCJiSW5kZXgiLCJxdWVyeSIsImNoZWNrIiwiYXR0ciIsImNoaWxkTGlzdCIsImxhc3RDaGlsZCIsImdldE9mZnNldCIsInd5c2l3eWdGcmFtZSIsIm9mZnNldExlZnQiLCJvZmZzZXRUb3AiLCJvZmZzZXRFbGVtZW50IiwicGFyZW50RWxlbWVudCIsIm9mZnNldFBhcmVudCIsInNjcm9sbFRvcCIsImFTdGFydCIsImFFbmQiLCJiU3RhcnQiLCJiRW5kIiwib3ZlcmxhcCIsInR4dCIsIm5ld0VsZW1lbnQiLCJzdHlsZU5hbWUiLCJzZXREaXNhYmxlZEJ1dHRvbnMiLCJidXR0b25MaXN0Iiwic3RvcFBhcmVudCIsInBhcmVudCIsImRldGFjaE5lc3RlZExpc3QiLCJiYXNlTm9kZSIsImFsbCIsInJOb2RlIiwiX2RlbGV0ZU5lc3RlZExpc3QiLCJjTm9kZXMiLCJyQ2hpbGRyZW4iLCJiYXNlUGFyZW50IiwibGlTaWJsaW5nIiwibGlQYXJlbnQiLCJjaGlsZCIsInNwbGl0RWxlbWVudCIsIm9mZnNldCIsImJwIiwic3BsaXRUZXh0IiwiYWZ0ZXIiLCJkZXB0aEVsIiwicEVsZW1lbnQiLCJub2RlUGF0aEFycmF5Iiwib25seVRleHQiLCJpbnN0Iiwibm9kZVBhdGhMZW4iLCJhcHBseSIsIk51bWJlciIsInZhbHVlT2YiLCJkZXB0aEluZGV4IiwiY0RlcHRoIiwic3BsaWNlRGVwdGgiLCJjaGlsZHMiLCJjaGlsZExlbmd0aCIsIm5MZW4iLCJhZGRPZmZzZXQiLCJ0ZXh0T2Zmc2V0IiwidGVtcEwiLCJyZW1vdmVFbXB0eU5vZGUiLCJub3RSZW1vdmVOb2RlIiwiX25vdFRleHROb2RlIiwiaHRtbFJlbW92ZVdoaXRlU3BhY2UiLCJkZXMiLCJfaXNNYWludGFpbmVkTm9kZSIsIl9pc1NpemVOb2RlIiwiX2Rpc2FsbG93ZWRUYWdzIiwiY3JlYXRlVGFnc1doaXRlbGlzdCIsIl9jb25zaXN0ZW5jeUNoZWNrT2ZIVE1MIiwiZG9jdW1lbnRGcmFnbWVudCIsImh0bWxDaGVja1doaXRlbGlzdFJlZ0V4cCIsInJlbW92ZVRhZ3MiLCJlbXB0eVRhZ3MiLCJ3cm9uZ0xpc3QiLCJ3aXRob3V0Rm9ybWF0Q2VsbHMiLCJ3cm9uZ1RhZ3MiLCJucnRhZyIsImZlbCIsImNoZWNrVGFncyIsInRwIiwiX3NldERlZmF1bHRPcHRpb25TdHlsZSIsIm9wdGlvblN0eWxlIiwibWluSGVpZ2h0IiwiZWRpdG9yIiwic3R5bGVBcnIiLCJfc2V0SWZyYW1lRG9jdW1lbnQiLCJoZWFkIiwiX3NldElmcmFtZUNzc1RhZ3MiLCJfZWRpdGFibGVDbGFzcyIsImxpbmtOYW1lcyIsImlmcmFtZUNTU0ZpbGVOYW1lIiwid1JlZ0V4cCIsInRhZ1N0cmluZyIsIkNTU0ZpbGVOYW1lIiwic3R5bGVUYWciLCJfaW5pdE9wdGlvbnMiLCJ0b3BfZGl2IiwiaWQiLCJ0b29sX2JhciIsIl9jcmVhdGVUb29sQmFyIiwidmlzaWJpbGl0eSIsInBsdWdpbkNhbGxCdXR0b25zIiwiX2NoZWNrS2F0ZXhNYXRoIiwiYXJyb3ciLCJzdGlja3lfZHVtbXkiLCJlZGl0b3JfZGl2IiwiaW5pdEVsZW1lbnRzIiwiX2luaXRFbGVtZW50cyIsImJvdHRvbUJhciIsInd5c2l3eWdfZGl2IiwicGxhY2Vob2xkZXJfc3BhbiIsInRleHRhcmVhIiwicmVzaXppbmdfYmFyIiwicmVzaXppbmdCYXIiLCJuYXZpZ2F0aW9uIiwiY2hhcl93cmFwcGVyIiwiY2hhcldyYXBwZXIiLCJjaGFyX2NvdW50ZXIiLCJjaGFyQ291bnRlciIsImxvYWRpbmdfYm94IiwibGluZV9icmVha2VyIiwibGluZV9icmVha2VyX3QiLCJsaW5lX2JyZWFrZXJfYiIsInJlc2l6ZV9iYWNrIiwidG9vbGJhckNvbnRhaW5lciIsIl9jaGVja0NvZGVNaXJyb3IiLCJjb25zdHJ1Y3RlZCIsIl90b3AiLCJfcmVsYXRpdmUiLCJfdG9vbEJhciIsIl9tZW51VHJheSIsIl9lZGl0b3JBcmVhIiwiX3d5c2l3eWdBcmVhIiwiX2NvZGVBcmVhIiwiX3BsYWNlaG9sZGVyIiwiX3Jlc2l6aW5nQmFyIiwiX25hdmlnYXRpb24iLCJfY2hhcldyYXBwZXIiLCJfY2hhckNvdW50ZXIiLCJfbGluZUJyZWFrZXIiLCJfbGluZUJyZWFrZXJfdCIsIl9saW5lQnJlYWtlcl9iIiwiX3Jlc2l6ZUJhY2siLCJfc3RpY2t5RHVtbXkiLCJfYXJyb3ciLCJfcmVzcG9uc2l2ZUJ1dHRvbnMiLCJyZXNwb25zaXZlQnV0dG9ucyIsImNvZGVNaXJyb3IiLCJjbU9wdGlvbnMiLCJodG1sTW9kZSIsImxpbmVOdW1iZXJzIiwibGluZVdyYXBwaW5nIiwicmVkdWNlIiwidmlld3BvcnRNYXJnaW4iLCJJbmZpbml0eSIsImNtIiwiZnJvbVRleHRBcmVhIiwid3JhcHBlciIsImNvZGVNaXJyb3JFZGl0b3IiLCJrYXRleE9wdGlvbnMiLCJ0aHJvd09uRXJyb3IiLCJfc2V0T3B0aW9ucyIsIm1lcmdlT3B0aW9ucyIsIm9yaWdpbk9wdGlvbnMiLCJvcmlnaW5FbGVtZW50IiwiZWRpdG9yQXJlYSIsImlzTmV3VG9vbGJhckNvbnRhaW5lciIsImlzTmV3VG9vbGJhciIsImlzTmV3UGx1Z2lucyIsInRvcEFyZWEiLCJjYWxsQnV0dG9ucyIsInRvcERpdiIsInRvb2xCYXIiLCJ0b29sQmFyQXJyb3ciLCJfZWRpdG9yU3R5bGVzIiwidG9vbGJhcldpZHRoIiwid3lzaXd5Z0RpdiIsIm92ZXJmbG93IiwiY2hhckNvdW50ZXJMYWJlbCIsImNoYXJMYWJlbCIsIm1heENoYXJDb3VudCIsImNoYXJfbWF4IiwiaW5uZXJUZXh0IiwiX2RlZmF1bHRMYW5nIiwiZGVmYXVsdFRhZyIsImhpc3RvcnlTdGFja0RlbGF5VGltZSIsIl9kZWZhdWx0VGFnc1doaXRlbGlzdCIsIl9lZGl0b3JUYWdzV2hpdGVsaXN0IiwiYWRkVGFnc1doaXRlbGlzdCIsInBhc3RlVGFnc1doaXRlbGlzdCIsImF0dHJpYnV0ZXNXaGl0ZWxpc3QiLCJzdGlja3lUb29sYmFyIiwidW5kZWZpbmVkIiwiZnVsbFBhZ2UiLCJwcmV2aWV3VGVtcGxhdGUiLCJzaG93UGF0aExhYmVsIiwiY2hhckNvdW50ZXJUeXBlIiwiY2xpZW50V2lkdGgiLCJjbGllbnRIZWlnaHQiLCJ0YWJEaXNhYmxlIiwic2hvcnRjdXRzRGlzYWJsZSIsInNob3J0Y3V0c0hpbnQiLCJjYWxsQmFja1NhdmUiLCJzdHJpbmdpZnkiLCJfaWNvbnMiLCJfZGVmYXVsdCIsIl9uZXciLCJfZGVmYXVsdEJ1dHRvbnMiLCJjbWQiLCJhZGRTaGlmdCIsImluZGVudEtleSIsIl9jcmVhdGVNb2R1bGVHcm91cCIsIm9EaXYiLCJvVWwiLCJfY3JlYXRlQnV0dG9uIiwiYnV0dG9uQ2xhc3MiLCJkYXRhQ29tbWFuZCIsImRhdGFEaXNwbGF5IiwiX2Rpc2FibGVkIiwib0xpIiwib0J1dHRvbiIsIl9wbHVnaW5zIiwic2VwYXJhdG9yX3ZlcnRpY2FsIiwiX2J1dHRvblRyYXkiLCJkZWZhdWx0QnV0dG9uTGlzdCIsInBsdWdpbnNWYWx1ZXMiLCJtb2R1bGVFbGVtZW50IiwiYnV0dG9uRWxlbWVudCIsIm1vcmVMYXllciIsImJ1dHRvbkdyb3VwTG9vcCIsIm1vcmUiLCJtb3JlQ29udGFpbmVyIiwibW9yZUNvbW1hbmQiLCJidXR0b25Hcm91cCIsIm1vcmVCdXR0b24iLCJkaXYiLCJmbG9hdCIsIm1hdGNoZWQiLCJjdXN0b20iLCJ1bCIsImxpIiwic3YiLCJlbnRlckRpdiIsImxhc3RGbG9hdCIsInVuc2hpZnQiLCJ0b29sX2NvdmVyIiwiX0NvbnRleHQiLCJjb25zIiwibG9hZGluZyIsImxpbmVCcmVha2VyIiwibGluZUJyZWFrZXJfdCIsImxpbmVCcmVha2VyX2IiLCJyZXNpemVCYWNrZ3JvdW5kIiwidG9vbCIsIm5vdGljZSIsIm5vdGljZV9kaXYiLCJub3RpY2Vfc3BhbiIsIm5vdGljZV9idXR0b24iLCJvbkNsaWNrX2NhbmNlbCIsImluaXRfb3B0aW9ucyIsImlkT3JFbGVtZW50IiwiX2luaXRfb3B0aW9ucyIsInZhbCIsImdldEVsZW1lbnRCeUlkIiwiX0NvbnN0cnVjdG9yIiwib3duZXJEb2N1bWVudCIsImRlZmF1bHRWaWV3IiwiX3V0aWwiLCJfcGFyc2VyIiwiX3d3IiwiX3NoYWRvd1Jvb3QiLCJfbm90aWNlIiwiaW5pdFBsdWdpbnMiLCJfdGFyZ2V0UGx1Z2lucyIsInN1Ym1lbnUiLCJfc3VibWVudU5hbWUiLCJfYmluZGVkU3VibWVudU9mZiIsIl9iaW5kZWRDb250YWluZXJPZmYiLCJzdWJtZW51QWN0aXZlQnV0dG9uIiwiY29udGFpbmVyQWN0aXZlQnV0dG9uIiwiY3VycmVudENvbnRyb2xsZXJUYXJnZXQiLCJjdXJyZW50RmlsZUNvbXBvbmVudEluZm8iLCJjb2RlVmlld0Rpc2FibGVkQnV0dG9ucyIsInJlc2l6aW5nRGlzYWJsZWRCdXR0b25zIiwiX21vcmVMYXllckFjdGl2ZUJ1dHRvbiIsIl9odG1sQ2hlY2tXaGl0ZWxpc3RSZWdFeHAiLCJfZGlzYWxsb3dlZFRleHRUYWdzUmVnRXhwIiwiZWRpdG9yVGFnc1doaXRlbGlzdFJlZ0V4cCIsInBhc3RlVGFnc1doaXRlbGlzdFJlZ0V4cCIsImhhc0ZvY3VzIiwiaXNEaXNhYmxlZCIsIl9hdHRyaWJ1dGVzV2hpdGVsaXN0UmVnRXhwIiwiX2F0dHJpYnV0ZXNUYWdzV2hpdGVsaXN0IiwiX2JpbmRDb250cm9sbGVyc09mZiIsIl9pc0lubGluZSIsIl9pc0JhbGxvb24iLCJfaXNCYWxsb29uQWx3YXlzIiwiX2lubGluZVRvb2xiYXJBdHRyIiwiaXNTaG93IiwiX25vdEhpZGVUb29sYmFyIiwiX3N0aWNreSIsIl9saW5lQnJlYWtlckJ1dHRvbiIsIl9jb21wb25lbnRzSW5mb0luaXQiLCJfY29tcG9uZW50c0luZm9SZXNldCIsImFjdGl2ZVBsdWdpbnMiLCJtYW5hZ2VkVGFnc0luZm8iLCJfY2hhclR5cGVIVE1MIiwiX2ZpbGVJbmZvUGx1Z2luc0NoZWNrIiwiX2ZpbGVJbmZvUGx1Z2luc1Jlc2V0IiwiX2ZpbGVNYW5hZ2VyIiwicXVlcnlTdHJpbmciLCJwbHVnaW5SZWdFeHAiLCJwbHVnaW5NYXAiLCJjb21tYW5kTWFwIiwiX3N0eWxlQ29tbWFuZE1hcCIsIl9kZWZhdWx0Q29tbWFuZCIsIl92YXJpYWJsZSIsImlzQ29kZVZpZXciLCJpc0Z1bGxTY3JlZW4iLCJpbm5lckhlaWdodF9mdWxsU2NyZWVuIiwicmVzaXplQ2xpZW50WSIsInRhYlNpemUiLCJjb2RlSW5kZW50IiwibWluUmVzaXppbmdTaXplIiwiY3VycmVudE5vZGVzIiwiY3VycmVudE5vZGVzTWFwIiwiX3JhbmdlIiwiX3NlbGVjdGlvbk5vZGUiLCJfb3JpZ2luQ3NzVGV4dCIsIl9ib2R5T3ZlcmZsb3ciLCJfZWRpdG9yQXJlYU9yaWdpbkNzc1RleHQiLCJfd3lzaXd5Z09yaWdpbkNzc1RleHQiLCJfY29kZU9yaWdpbkNzc1RleHQiLCJfZnVsbFNjcmVlbkF0dHJzIiwic3RpY2t5IiwiYmFsbG9vbiIsImlubGluZSIsIl9saW5lQnJlYWtDb21wIiwiX2xpbmVCcmVha0RpciIsImNhbGxCYWNrRnVuY3Rpb24iLCJfdGFyZ2V0IiwibW9kdWxlQXJyYXkiLCJtb2R1bGVOYW1lIiwic3VibWVudU9uIiwic3VibWVudU5hbWUiLCJfc2V0TWVudVBvc2l0aW9uIiwiY29udGFpbmVyT24iLCJjb250YWluZXJOYW1lIiwiX2NvbnRhaW5lck5hbWUiLCJjb250YWluZXJPZmYiLCJ0b29sYmFyVyIsInRvb2xiYXJPZmZzZXQiLCJldmVudCIsIl9nZXRFZGl0b3JPZmZzZXRzIiwibWVudVciLCJlbGVtZW50VyIsInJ0bFciLCJydGxMIiwib3ZlckxlZnQiLCJvZmZzZXRFbCIsImJ0IiwidG9vbGJhclRvcCIsIm1lbnVIZWlnaHQiLCJtZW51SGVpZ2h0X2JvdHRvbSIsIm1lbnVUb3AiLCJpbnNUb3AiLCJtZW51SGVpZ2h0X3RvcCIsImFyZyIsImFyZ3VtZW50cyIsImdldEZpbGVDb21wb25lbnQiLCJzaG93Q29udHJvbGxlciIsInJlZmVyRWwiLCJ0b3BNYXJnaW4iLCJzY3JvbGxMZWZ0IiwiY29udHJvbGxlclciLCJyZWZlckVsVyIsIm92ZXJTaXplIiwiZXhlY0NvbW1hbmQiLCJzaG93RGVmYXVsdFVJIiwibmF0aXZlRm9jdXMiLCJfZWRpdG9yUmFuZ2UiLCJiciIsIl9hcHBseVRhZ0VmZmVjdHMiLCJfdG9nZ2xlVG9vbGJhckJhbGxvb24iLCJmaWxlQ29tcG9uZW50SW5mbyIsInN0YXJ0Q29uIiwic3RhcnRPZmYiLCJlbmRDb24iLCJlbmRPZmYiLCJzZXRTdGFydCIsInNldEVuZCIsImNvbnNvbGUiLCJ3YXJuIiwic2VsZWN0aW9uIiwicmVtb3ZlQWxsUmFuZ2VzIiwiYWRkUmFuZ2UiLCJyZW1vdmVSYW5nZSIsIk9VVERFTlQiLCJJTkRFTlQiLCJfY3JlYXRlRGVmYXVsdFJhbmdlIiwiY29sbGFwc2VkIiwiZm9jdXNOb2RlIiwicmFuZ2VDb3VudCIsImdldFJhbmdlQXQiLCJhbmNob3JOb2RlIiwiYW5jaG9yT2Zmc2V0IiwiZm9jdXNPZmZzZXQiLCJjb21wYXJlVmFsdWUiLCJyaWdodERpciIsIl9zZWxlY3Rpb25Wb2lkIiwib3AiLCJjb21tb25BbmNlc3RvckNvbnRhaW5lciIsImV4dGVudE5vZGUiLCJjb21tIiwiX3Jlc2V0UmFuZ2VUb1RleHROb2RlIiwidGVtcENvbiIsInRlbXBPZmZzZXQiLCJ0ZW1wQ2hpbGQiLCJvbmx5QnJlYWsiLCJlbXB0eVRleHQiLCJjb21tb25Db24iLCJsaW5lTm9kZXMiLCJzdGFydExpbmUiLCJlbmRMaW5lIiwic3RhcnRJZHgiLCJlbmRJZHgiLCJvbmx5VGFibGUiLCJzdGFydFJhbmdlRWwiLCJlbmRSYW5nZUVsIiwic2FtZVJhbmdlIiwibGluZSIsInJlbW92ZUR1cGxpY2F0ZSIsIm15Q29tcG9uZW50Iiwic2VsZWN0ZWRMaW5lcyIsImlzRWRnZVBvaW50Iiwibm9kZVZhbHVlIiwiYXBwZW5kRm9ybWF0VGFnIiwiZm9ybWF0Tm9kZSIsImN1cnJlbnRGb3JtYXRFbCIsIm9Gb3JtYXROYW1lIiwiY2hlY2tDaGFyQ291bnQiLCJub3RTZWxlY3QiLCJyZW1vdmVOb2RlIiwiZm9ybWF0RWwiLCJkZXB0aEZvcm1hdCIsInBsdWdpbiIsIl9zZXRDb21wb25lbnRMaW5lQnJlYWtlciIsInRfc3R5bGUiLCJiX3N0eWxlIiwicmVzaXplQ29udGFpbmVyIiwiY29tcG9uZW50VG9wIiwid1Njcm9sbCIsImFmdGVyTm9kZSIsImZyZWVGb3JtYXQiLCJpc0Zvcm1hdHMiLCJmb3JtYXRSYW5nZSIsIm9yaWdpbkFmdGVyIiwicmVtb3ZlZFRhZyIsInByZXZDb250YWluZXIiLCJvbGRQYXJlbnQiLCJyYW5nZUNvbiIsIl9zZXRJbnRvRnJlZUZvcm1hdCIsInByZXZpb3VzVGV4dCIsIm5leHRUZXh0IiwibmV3UmFuZ2UiLCJ6ZXJvV2lkdGgiLCJvTm9kZUNoaWxkcmVuIiwibGFzdE9Ob2RlIiwiYmVmb3JlTm9kZSIsInN0YXJ0SW5kZXgiLCJlbmRJbmRleCIsInN0YXJ0Tm9kZSIsImVuZE5vZGUiLCJzdWJzdHJpbmdEYXRhIiwicmMiLCJyYW5nZUxpbmVzIiwibGluZXNMb29wIiwibmVzdGVkIiwiZkVsIiwibEVsIiwic3RhbmRUYWciLCJiZWZvcmVUYWciLCJwYXJlbnREZXB0aCIsImxpc3RQYXJlbnQiLCJsaW5lQXJyIiwicmVtb3ZlSXRlbXMiLCJuZXh0TGluZSIsIm5leHRMaXN0IiwicmVtb3ZlQXJyYXkiLCJzcGxpdFJhbmdlIiwibmV3UmFuZ2VFbGVtZW50IiwiZmlyc3ROb2RlIiwibGFzdE5vZGUiLCJyYW5nZUVsIiwiaW5zZXJ0ZWROZXciLCJtb3ZlQ29tcGxldGUiLCJhcHBlbmROb2RlIiwiaW5zTm9kZSIsIm9yaWdpbk5vZGUiLCJpbnNDaGlsZHJlbiIsIm9yaWdpbk5leHQiLCJkZXRhY2hSYW5nZSIsImxpbmVJbmRleCIsImluc05leHQiLCJpbm5lckNoaWxkcmVuIiwicmFuZ2VQYXJlbnQiLCJyYW5nZVJpZ2h0IiwiY2hpbGRFZGdlIiwibGlzdEZpcnN0IiwibGlzdExhc3QiLCJsYXN0SW5kZXgiLCJzdHlsZUFycmF5IiwicmVtb3ZlTm9kZUFycmF5Iiwic3RyaWN0UmVtb3ZlIiwiaXNSZW1vdmVOb2RlIiwiaXNSZW1vdmVGb3JtYXQiLCJuZXdOb2RlTmFtZSIsInNOb2RlIiwiY2hlY2tDbnQiLCJjaGVja0F0dHJzIiwiY2tlY2tDbGFzc2VzIiwiY2xhc3NSZWciLCJzdHlsZUNoZWNrIiwiY2xhc3NDaGVjayIsInN0YXJ0IiwiZW5kIiwic3R5bGVSZWdFeHAiLCJjbGFzc1JlZ0V4cCIsInJlbW92ZU5vZGVSZWdFeHAiLCJ3Qm9vbGVhbiIsIkJvb2xlYW4iLCJfcmVtb3ZlQ2hlY2siLCJjaGVja05vZGUiLCJ2Tm9kZSIsInRhZ1JlbW92ZSIsIm9yaWdpblN0eWxlIiwib3JpZ2luQ2xhc3NlcyIsIm9uZUxpbmUiLCJlbmRMZW5ndGgiLCJpc1JlbW92ZUFuY2hvciIsImlzU2l6ZU5vZGUiLCJfZ2V0TWFpbnRhaW5lZE5vZGUiLCJfdXRpbF9nZXRNYWludGFpbmVkTm9kZSIsIl91dGlsX2lzTWFpbnRhaW5lZE5vZGUiLCJfbm9kZUNoYW5nZV9vbmVMaW5lIiwiX3NldENvbW1vbkxpc3RTdHlsZSIsIl9ub2RlQ2hhbmdlX2VuZExpbmUiLCJfbm9kZUNoYW5nZV9taWRkbGVMaW5lIiwiX25vZGVDaGFuZ2Vfc3RhcnRMaW5lIiwiY2hpbGRTdHlsZSIsImVsU3R5bGUiLCJmb250V2VpZ2h0IiwiX3N0cmlwUmVtb3ZlTm9kZSIsIl9pc1JlbW92ZSIsIm5ld0lubmVyTm9kZSIsInBhcmVudENvbiIsInNhbWVUYWciLCJ6Iiwibk5vZGVBcnJheSIsInBOb2RlIiwiaXNTYW1lTm9kZSIsInBDdXJyZW50Iiwic3RhcnRQYXNzIiwiZW5kUGFzcyIsImNoZWNrQ3NzIiwiY292ZXJOb2RlIiwicHJldk5vZGUiLCJwcmV2QW5jaG9yTm9kZSIsImNoaWxkTm9kZSIsImFuY2hvcnMiLCJhQ2hpbGRyZW4iLCJhTGVuIiwiYW5jZXN0b3JBbmNob3JOb2RlIiwiYWZ0ZXJBbmNob3JOb2RlIiwidGV4dE5vZGVfcyIsInRleHROb2RlX2UiLCJlbmRDb25SZXNldCIsIm5ld1N0YXJ0T2Zmc2V0Iiwic3RhcnRQYXRoIiwibWVyZ2VFbmRDb24iLCJuZXdFbmRPZmZzZXQiLCJlbmRQYXRoIiwibmV3T2Zmc2V0cyIsIl9lbmRDb250YWluZXIiLCJwYXNzTm9kZSIsImNsb25lQ2hpbGQiLCJpc1RvcE5vZGUiLCJ0ZW1wTm9kZSIsIm5ld0Nzc1RleHQiLCJuZXdDbGFzcyIsIm5vbmVDaGFuZ2UiLCJhY3Rpb25DYWxsIiwibGF5ZXIiLCJfc2hvd1Rvb2xiYXJCYWxsb29uIiwiX3Nob3dUb29sYmFySW5saW5lIiwiY29tbWFuZEhhbmRsZXIiLCJ0b2dnbGVDb2RlVmlldyIsInRvZ2dsZUZ1bGxTY3JlZW4iLCJ0b2dnbGVEaXNwbGF5QmxvY2tzIiwiZ2V0Q29udGVudHMiLCJub2Rlc01hcCIsIm1hcmdpbkRpciIsIl9yZXNvdXJjZXNTdGF0ZUNoYW5nZSIsIl9zZXRDb2RlRGF0YVRvRWRpdG9yIiwiX2hpZGVUb29sYmFyIiwiX3NldEVkaXRvckRhdGFUb0NvZGVWaWV3Iiwic2Nyb2xsSGVpZ2h0IiwicmVmcmVzaCIsIl9jaGVja1BsYWNlaG9sZGVyIiwiY29kZV9odG1sIiwiX2dldENvZGVWaWV3IiwicGFyc2VEb2N1bWVudCIsImhlYWRDaGlsZHJlbiIsImNvbnZlcnRDb250ZW50c0ZvckVkaXRvciIsImVkaXRhYmxlQ2xhc3NlcyIsImNvZGVDb250ZW50cyIsImNvbnZlcnRIVE1MRm9yQ29kZVZpZXciLCJjb2RlVmFsdWUiLCJfc2V0Q29kZVZpZXciLCJfdmFyIiwib25TY3JvbGxfd2luZG93IiwiekluZGV4IiwiX2lmcmFtZUF1dG9IZWlnaHQiLCJwcmludERvY3VtZW50IiwiY29udGVudHNIVE1MIiwid0RvYyIsImFycnRzIiwid3JpdGUiLCJsaW5rcyIsImxpbmtIVE1MIiwiZG9jdW1lbnRNb2RlIiwiU3R5bGVNZWRpYSIsIndpbmRvd09iamVjdCIsIm1pbWVUeXBlIiwiY29udmVydFZhbHVlIiwiX3Jlc2V0Q29tcG9uZW50cyIsInNldElmcmFtZUNvbnRlbnRzIiwiY3R4Iiwib25seUNvbnRlbnRzIiwicmVuZGVySFRNTCIsImZpZ2NhcHRpb25zIiwiX21ha2VMaW5lIiwicmVxdWlyZUZvcm1hdCIsInRleHRBcnJheSIsIl9hbGxvd0hUTUxDb21tZW50cyIsIl90YWdDb252ZXJ0b3IiLCJfZGVsZXRlRGlzYWxsb3dlZFRhZ3MiLCJjbGVhbkhUTUwiLCJ3aGl0ZWxpc3QiLCJ0QXR0ciIsInRleHRDb21wTGlzdCIsImluaXRNZXRob2QiLCJkb21UcmVlIiwicmV0dXJuSFRNTCIsImJyUmVnIiwiaW5kZW50U2l6ZSIsImpvaW4iLCJsaW5lQlIiLCJlbGVtZW50UmVnVGVzdCIsImVsZW1lbnRJbmRlbnQiLCJub2RlUmVnVGVzdCIsImxpc3RlbmVyIiwidXNlQ2FwdHVyZSIsIl9jaGFyQ291bnQiLCJpbnB1dFRleHQiLCJjb3VudFR5cGUiLCJuZXh0Q2hhckNvdW50IiwiZ2V0Q2hhckxlbmd0aCIsIl9zZXRDaGFyQ291bnQiLCJvdmVyIiwiY291bnQiLCJnZXRDaGFyQ291bnQiLCJzbGljZVBvc2l0aW9uIiwiX2NhbGxDb3VudGVyQmxpbmsiLCJfY2hlY2tDb21wb25lbnRzIiwiZ2V0RG9jIiwic2V0VmFsdWUiLCJnZXRWYWx1ZSIsIl9pbml0IiwicmVsb2FkIiwiX2luaXRIVE1MIiwiU2hhZG93Um9vdCIsInNoYWRvd1Jvb3QiLCJkaXNhbGxvd1RleHRUYWdzIiwiYWxsb3dUZXh0VGFncyIsImRlZmF1bHRBdHRyIiwiX2F0dHIiLCJ0YWdzQXR0ciIsImFsbEF0dHIiLCJrIiwiX2NhY2hpbmdCdXR0b25zIiwibWFuYWdlZENsYXNzIiwiZmlsZVBsdWdpblJlZ0V4cCIsImNoYW5nZSIsImRlbGF5VGltZSIsInB1c2hEZWxheSIsInN0YWNrSW5kZXgiLCJzdGFjayIsInNldENvbnRlbnRzRnJvbVN0YWNrIiwicHVzaFN0YWNrIiwiZGVsYXkiLCJ0aW1lIiwiY2xlYXJUaW1lb3V0IiwiZ28iLCJpZ25vcmVDaGFuZ2VFdmVudCIsIl9yZXNldENhY2hpbmdCdXR0b24iLCJfZGVzdHJveSIsIl9oaXN0b3J5IiwiX29uQ2hhbmdlX2hpc3RvcnlTdGFjayIsIl9pZnJhbWVBdXRvIiwiX2luaXRXeXNpd3lnQXJlYSIsIlNUUk9ORyIsIlUiLCJFTSIsIkRFTCIsIlNVQiIsIlNVUCIsIm9uQ2hhbmdlIiwiX3NldERlZmF1bHRGb3JtYXQiLCJmb3JtYXROYW1lIiwiZmlsZUNvbXBvbmVudCIsIl9zZXRPcHRpb25zSW5pdCIsIl9nZXRDb25zdHJ1Y3RlZCIsIl9lZGl0b3JJbml0IiwiX2FkZEV2ZW50IiwiX29mZlN0aWNreVRvb2xiYXIiLCJvblJlc2l6ZV93aW5kb3ciLCJjb250ZXh0RWwiLCJfSUVpc0NvbXBvc2luZyIsIl9saW5lQnJlYWtlckJpbmQiLCJfcmVzcG9uc2l2ZUN1cnJlbnRTaXplIiwiX3Jlc3BvbnNpdmVCdXR0b25TaXplIiwiX2RpcmVjdGlvbktleUNvZGUiLCJfbm9uVGV4dEtleUNvZGUiLCJfaGlzdG9yeUlnbm9yZUtleUNvZGUiLCJfb25CdXR0b25zQ2hlY2siLCJfZnJvbnRaZXJvV2lkdGhSZWciLCJfa2V5Q29kZVNob3J0Y3V0IiwiNjUiLCI2NiIsIjgzIiwiODUiLCI3MyIsIjg5IiwiOTAiLCIyMTkiLCIyMjEiLCJfc2hvcnRjdXRDb21tYW5kIiwiY2xhc3NPbkNoZWNrIiwiY29tbWFuZE1hcE5vZGVzIiwiX2NhbmNlbENhcHRpb25FZGl0IiwiX2J1dHRvbnNFdmVudEhhbmRsZXIiLCJvbkNsaWNrX3Rvb2xiYXIiLCJvbk1vdXNlRG93bl93eXNpd3lnIiwidGFibGVDZWxsIiwib25Nb3VzZURvd24iLCJvbkNsaWNrX3d5c2l3eWciLCJoaWRlVG9vbGJhciIsInByZXZMaSIsIm9uQ2xpY2siLCJfYmFsbG9vbkRlbGF5IiwiX3Nob3dUb29sYmFyQmFsbG9vbkRlbGF5IiwicmFuZ2VPYmoiLCJpc0RpclRvcCIsInJlY3RzIiwiZ2V0Q2xpZW50UmVjdHMiLCJlZGl0b3JXaWR0aCIsInN0aWNreVRvcCIsImVkaXRvckxlZnQiLCJub2RlT2Zmc2V0IiwiYm90dG9tIiwibm9UZXh0IiwiYXJyb3dNYXJnaW4iLCJ0b29sYmFySGVpZ2h0IiwiaWZyYW1lUmVjdHMiLCJfc2V0VG9vbGJhck9mZnNldCIsImVkaXRvclBhcmVudCIsImFic29sdXRlTGVmdCIsIm92ZXJSaWdodCIsInJlc2V0VG9wIiwic3BhY2UiLCJfZ2V0UGFnZUJvdHRvbVNwYWNlIiwiZG9jdW1lbnRFbGVtZW50IiwiYXJyb3dfbGVmdCIsInNob3dJbmxpbmUiLCJvbklucHV0X3d5c2l3eWciLCJvbklucHV0IiwiX29uU2hvcnRjdXRLZXkiLCJvbktleURvd25fd3lzaXd5ZyIsInNoaWZ0S2V5IiwiY3RybCIsImN0cmxLZXkiLCJtZXRhS2V5IiwiYWx0S2V5Iiwic2VsZWN0UmFuZ2UiLCJmaWxlQ29tcG9uZW50TmFtZSIsIl9oYXJkRGVsZXRlIiwicHJldkxhc3QiLCJjb24iLCJzZWwiLCJpZ25vcmVaV1MiLCJuZXh0RWwiLCJpc0VkZ2UiLCJsaW5lcyIsImZjIiwibGMiLCJtb3ZlQ2VsbCIsImVuZENoaWxkIiwidGFiVGV4dCIsInRleHRSYW5nZSIsImZyZWVGb3JtYXRFbCIsImVudGVySFRNTCIsInNlbGVjdGlvbkZvcm1hdCIsIndTZWxlY3Rpb24iLCJpbnNlcnRIVE1MIiwid09mZnNldCIsImZvY3VzTmV4dCIsImJyUHJldiIsImJyTmV4dCIsIm5ld0xpc3RDZWxsIiwiY29tcENvbnRleHQiLCJvbktleURvd24iLCJvbktleVVwX3d5c2l3eWciLCJvRm9ybWF0VGFnIiwiaXNDb21wb3NpbmciLCJmcm9udFplcm9XaWR0aENudCIsInN1YnN0cmluZyIsIm9uS2V5VXAiLCJvblNjcm9sbF93eXNpd3lnIiwib25TY3JvbGwiLCJvbkZvY3VzX3d5c2l3eWciLCJvbkZvY3VzIiwib25CbHVyX3d5c2l3eWciLCJvbkJsdXIiLCJvbk1vdXNlRG93bl9yZXNpemluZ0JhciIsImNsaWVudFkiLCJfcmVzaXplX2VkaXRvciIsImNsb3N1cmVGdW5jIiwicmVzaXplSW50ZXJ2YWwiLCJyZXNwb25zaXZlU2l6ZSIsIndpbmRvd1dpZHRoIiwiaW5uZXJXaWR0aCIsInJlc3BvbnNpdmVXaWR0aCIsInNldFRvb2xiYXJCdXR0b25zIiwiZWRpdG9ySGVpZ2h0Iiwic2Nyb2xsWSIsImVkaXRvclRvcCIsIl9vblN0aWNreVRvb2xiYXIiLCJzY3JvbGwiLCJtYXJnaW5Ub3AiLCJfY29kZVZpZXdBdXRvSGVpZ2h0Iiwic0NlbGwiLCJlQ2VsbCIsInNJc0NlbGwiLCJlSXNDZWxsIiwic0NvbXAiLCJlQ29tcCIsIm9uUGFzdGVfd3lzaXd5ZyIsImNsaXBib2FyZERhdGEiLCJfZGF0YVRyYW5zZmVyQWN0aW9uIiwiX3NldENsaXBib2FyZENvbXBvbmVudCIsInNldERhdGEiLCJvbkNvcHlfd3lzaXd5ZyIsIm9uQ29weSIsIm9uQ3V0X3d5c2l3eWciLCJvbkN1dCIsIm9uRHJvcF93eXNpd3lnIiwiZGF0YVRyYW5zZmVyIiwiX3NldERyb3BMb2NhdGlvblNlbGVjdGlvbiIsInJhbmdlT2Zmc2V0IiwiY2FyZXRSYW5nZUZyb21Qb2ludCIsImNsaWVudFgiLCJwbGFpblRleHQiLCJjbGVhbkRhdGEiLCJnZXREYXRhIiwidGVtcERpdiIsInRlbXBSYW5nZSIsIl9zZXRDbGlwYm9hcmREYXRhIiwib25QYXN0ZSIsIm9uRHJvcCIsImluc2VydEltYWdlIiwib25Nb3VzZU1vdmVfd3lzaXd5ZyIsImxpbmVCcmVha2VyU3R5bGUiLCJwYWdlWSIsImRpciIsIl9vbk1vdXNlRG93bl9saW5lQnJlYWsiLCJfb25MaW5lQnJlYWsiLCJldmVudFd5c2l3eWciLCJwYXNzaXZlIiwiX3NldFJlc3BvbnNpdmVUb29sYmFyIiwiX3JlbW92ZUV2ZW50Iiwic2l6ZUFycmF5IiwiYnV0dG9uc09iaiIsIm5ld1Rvb2xiYXIiLCJuZXdDb250ZXh0Iiwib2xkQ2FsbEJ1dHRvbnMiLCJvbGRCdXR0b24iLCJzZXRPcHRpb25zIiwiX29wdGlvbnMiLCJzZXREZWZhdWx0U3R5bGUiLCJuZXdTdHlsZXMiLCJub3RpY2VDbG9zZSIsImdldENvbnRleHQiLCJnZXRUZXh0IiwiZ2V0SW1hZ2VzSW5mbyIsImdldEZpbGVzSW5mbyIsIm5vdENsZWFuaW5nRGF0YSIsInJhbmdlU2VsZWN0aW9uIiwiY2hlY2tIVE1MIiwiZmlyc3RDb24iLCJhcHBlbmRDb250ZW50cyIsInNldE9wdGlvbiIsInNob3ciLCJ0b3BBcmVhU3R5bGUiLCJoaWRlIiwic3VuZWRpdG9yIiwiX3Jlc2l6ZUNsaWVudFgiLCJfcmVzaXplQ2xpZW50WSIsIl9yZXNpemVfdyIsIl9yZXNpemVfaCIsIl9yZXNpemVfZGlyZWN0aW9uIiwiX21vdmVfcGF0aCIsIl9pc0NoYW5nZSIsImFsaWduSWNvbnMiLCJyZXNpemVfZGl2X2NvbnRhaW5lciIsInNldENvbnRyb2xsZXJfcmVzaXplIiwicmVzaXplRG90IiwicmVzaXplRGlzcGxheSIsInJlc2l6ZV9idXR0b24iLCJzZXRDb250cm9sbGVyX2J1dHRvbiIsInJlc2l6ZV9oYW5kbGVzIiwicmVzaXplSGFuZGxlcyIsInJlc2l6ZUJ1dHRvbkdyb3VwIiwicm90YXRpb25CdXR0b25zIiwicGVyY2VudGFnZUJ1dHRvbnMiLCJhbGlnbk1lbnUiLCJhbGlnbk1lbnVMaXN0IiwiYWxpZ25CdXR0b24iLCJhdXRvU2l6ZUJ1dHRvbiIsImNhcHRpb25CdXR0b24iLCJvbk1vdXNlRG93bl9yZXNpemVfaGFuZGxlIiwib25DbGlja19yZXNpemVCdXR0b24iLCJyZXNpemVfY29udGFpbmVyIiwicGx1Z2luT2JqIiwicGVyY2VudGFnZVJvdGF0aW9uIiwieFVuaXQiLCJ5VW5pdCIsImRlYyIsInhWYWx1ZSIsInlWYWx1ZSIsImNvbnRleHRSZXNpemluZyIsImlzVmVydGljYWwiLCJhYnMiLCJkaXNwbGF5WCIsImRpc3BsYXlZIiwicmVzaXplRG90U2hvdyIsInJvdGF0aW9ucyIsInBCdXR0b25zIiwibmF0dXJhbFdpZHRoIiwibmF0dXJhbEhlaWdodCIsIl9jbG9zZUFsaWduTWVudSIsIm9wZW5BbGlnbk1lbnUiLCJjdXJyZW50Q29udGV4dCIsImN1cnJlbnRNb2R1bGUiLCJwZXJjZW50WSIsInBlcmNlbnRhZ2UiLCJfc2V0VHJhbnNGb3JtIiwic2xvcGUiLCJkZWciLCJhbGlnblZhbHVlIiwiY2FwdGlvblRleHQiLCJ0cmFuc2Zvcm0iLCJ0cmFuc2Zvcm1PcmlnaW4iLCJ0cmFuc09yaWdpbiIsIm9mZnNldFciLCJvZmZzZXRIIiwidHJhbnNXIiwidHJhbnNIIiwidHJhbnNsYXRlIiwiY2xvc3VyZUZ1bmNfYmluZCIsInJlc2l6aW5nX2VsZW1lbnRfYmluZCIsImNhbmNlbF9jb250cm9sbGVyX3Jlc2l6ZSIsInJlc2l6aW5nX2VsZW1lbnQiLCJyZXN1bHRXIiwicmVzdWx0SCIsIndoIiwicGFkZGluZyIsImxpbWl0IiwidXBsb2FkVXJsIiwidXBsb2FkSGVhZGVyIiwiY2FsbEJhY2siLCJlcnJvckNhbGxCYWNrIiwiZmlsZVBsdWdpbiIsIl9jYWxsQmFja1VwbG9hZCIsInNldFJlcXVlc3RIZWFkZXIiLCJ0YWdOYW1lcyIsInVwbG9hZEV2ZW50SGFuZGxlciIsImluZm9MaXN0Iiwic2V0RmlsZUluZm8iLCJpbmZvVXBkYXRlIiwiY3VycmVudFRhZ3MiLCJpbmZvSW5kZXgiLCJwbGd1aW4iLCJzdGF0ZSIsInNjcm9sbEludG9WaWV3Il0sIm1hcHBpbmdzIjoiYUFDRSxJQUFJQSxFQUFtQixHQUd2QixTQUFTQyxFQUFvQkMsR0FHNUIsR0FBR0YsRUFBaUJFLEdBQ25CLE9BQU9GLEVBQWlCRSxHQUFVQyxRQUduQyxJQUFJQyxFQUFTSixFQUFpQkUsR0FBWSxDQUN6Q0csRUFBR0gsRUFDSEksR0FBRyxFQUNISCxRQUFTLElBVVYsT0FOQUksRUFBUUwsR0FBVU0sS0FBS0osRUFBT0QsUUFBU0MsRUFBUUEsRUFBT0QsUUFBU0YsR0FHL0RHLEVBQU9FLEdBQUksRUFHSkYsRUFBT0QsUUFLZkYsRUFBb0JRLEVBQUlGLEVBR3hCTixFQUFvQlMsRUFBSVYsRUFHeEJDLEVBQW9CVSxFQUFJLFNBQVNSLEVBQVNTLEVBQU1DLEdBQzNDWixFQUFvQmEsRUFBRVgsRUFBU1MsSUFDbENHLE9BQU9DLGVBQWViLEVBQVNTLEVBQU0sQ0FBRUssWUFBWSxFQUFNQyxJQUFLTCxLQUtoRVosRUFBb0JrQixFQUFJLFNBQVNoQixHQUNYLG9CQUFYaUIsUUFBMEJBLE9BQU9DLGFBQzFDTixPQUFPQyxlQUFlYixFQUFTaUIsT0FBT0MsWUFBYSxDQUFFQyxNQUFPLFdBRTdEUCxPQUFPQyxlQUFlYixFQUFTLGFBQWMsQ0FBRW1CLE9BQU8sS0FRdkRyQixFQUFvQnNCLEVBQUksU0FBU0QsRUFBT0UsR0FFdkMsR0FEVSxFQUFQQSxJQUFVRixFQUFRckIsRUFBb0JxQixJQUMvQixFQUFQRSxFQUFVLE9BQU9GLEVBQ3BCLEdBQVcsRUFBUEUsR0FBOEIsaUJBQVZGLEdBQXNCQSxHQUFTQSxFQUFNRyxXQUFZLE9BQU9ILEVBQ2hGLElBQUlJLEVBQUtYLE9BQU9ZLE9BQU8sTUFHdkIsR0FGQTFCLEVB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T0FBT0MsZUFBZXVCLEVBQVEsb0JBQXFCLENBQy9DdEIsWUFBWSxFQUNadUUsVUFBVSxFQUNWQyxjQUFjLEVBQ2RuRSxNQUFPLEtBSWZQLE9BQU9DLGVBQWV1QixFQUFPZ0Qsa0JBQW1CLGNBQWUsQ0FDM0R0RSxZQUFZLEVBQ1p1RSxVQUFVLEVBQ1ZDLGNBQWMsRUFDZG5FLE1BQU9tWixLQUlSQSxHQWpUcUQsaUJBQW5CcmEsRUFBT0QsUUFDNUNDLEVBQU9ELFFBQVVrQyxFQUFPcUQsU0FDcEJwRCxFQUFRRCxHQUFRLEdBQ2hCLFNBQVVzRCxHQUNOLElBQUtBLEVBQUVELFNBQ0gsTUFBTSxJQUFJRSxNQUFNLDhDQUVwQixPQUFPdEQsRUFBUXFELElBR3ZCckQsRUFBUUQiLCJmaWxlIjoic3VuZWRpdG9yLm1pbi5qcyIsInNvdXJjZXNDb250ZW50IjpbIiBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbiBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XG5cbiBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbiBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKSB7XG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG4gXHRcdH1cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGk6IG1vZHVsZUlkLFxuIFx0XHRcdGw6IGZhbHNlLFxuIFx0XHRcdGV4cG9ydHM6IHt9XG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuXG4gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbiBcdH1cblxuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbiBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cbiBcdC8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIGhhcm1vbnkgZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4gXHRcdGlmKCFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywgbmFtZSkpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgbmFtZSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGdldHRlciB9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yID0gZnVuY3Rpb24oZXhwb3J0cykge1xuIFx0XHRpZih0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9TdHJpbmdUYWcpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcbiBcdFx0fVxuIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuIFx0fTtcblxuIFx0Ly8gY3JlYXRlIGEgZmFrZSBuYW1lc3BhY2Ugb2JqZWN0XG4gXHQvLyBtb2RlICYgMTogdmFsdWUgaXMgYSBtb2R1bGUgaWQsIHJlcXVpcmUgaXRcbiBcdC8vIG1vZGUgJiAyOiBtZXJnZSBhbGwgcHJvcGVydGllcyBvZiB2YWx1ZSBpbnRvIHRoZSBuc1xuIFx0Ly8gbW9kZSAmIDQ6IHJldHVybiB2YWx1ZSB3aGVuIGFscmVhZHkgbnMgb2JqZWN0XG4gXHQvLyBtb2RlICYgOHwxOiBiZWhhdmUgbGlrZSByZXF1aXJlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnQgPSBmdW5jdGlvbih2YWx1ZSwgbW9kZSkge1xuIFx0XHRpZihtb2RlICYgMSkgdmFsdWUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKHZhbHVlKTtcbiBcdFx0aWYobW9kZSAmIDgpIHJldHVybiB2YWx1ZTtcbiBcdFx0aWYoKG1vZGUgJiA0KSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICYmIHZhbHVlLl9fZXNNb2R1bGUpIHJldHVybiB2YWx1ZTtcbiBcdFx0dmFyIG5zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yKG5zKTtcbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG5zLCAnZGVmYXVsdCcsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHZhbHVlIH0pO1xuIFx0XHRpZihtb2RlICYgMiAmJiB0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIGZvcih2YXIga2V5IGluIHZhbHVlKSBfX3dlYnBhY2tfcmVxdWlyZV9fLmQobnMsIGtleSwgZnVuY3Rpb24oa2V5KSB7IHJldHVybiB2YWx1ZVtrZXldOyB9LmJpbmQobnVsbCwga2V5KSk7XG4gXHRcdHJldHVybiBucztcbiBcdH07XG5cbiBcdC8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbiBcdFx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHsgcmV0dXJuIG1vZHVsZVsnZGVmYXVsdCddOyB9IDpcbiBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCAnYScsIGdldHRlcik7XG4gXHRcdHJldHVybiBnZXR0ZXI7XG4gXHR9O1xuXG4gXHQvLyBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGxcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubyA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHsgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsgfTtcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiXCI7XG5cblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSBcIlhKUjFcIik7XG4iLCIvKlxuICogd3lzaXd5ZyB3ZWIgZWRpdG9yXG4gKlxuICogc3VuZWRpdG9yLmpzXG4gKiBDb3B5cmlnaHQgMjAxNyBKaUhvbmcgTGVlLlxuICogTUlUIGxpY2Vuc2UuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgICBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZS5leHBvcnRzID09PSAnb2JqZWN0Jykge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGdsb2JhbC5kb2N1bWVudCA/XG4gICAgICAgICAgICBmYWN0b3J5KGdsb2JhbCwgdHJ1ZSkgOlxuICAgICAgICAgICAgZnVuY3Rpb24gKHcpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXcuZG9jdW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTVU5FRElUT1JfTU9EVUxFUyBhIHdpbmRvdyB3aXRoIGEgZG9jdW1lbnQnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhY3Rvcnkodyk7XG4gICAgICAgICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGZhY3RvcnkoZ2xvYmFsKTtcbiAgICB9XG59KHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdGhpcywgZnVuY3Rpb24gKHdpbmRvdywgbm9HbG9iYWwpIHtcbiAgICBjb25zdCBkaWFsb2cgPSB7XG4gICAgICAgIG5hbWU6ICdkaWFsb2cnLFxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIENvbnN0cnVjdG9yXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb3JlIENvcmUgb2JqZWN0IFxuICAgICAgICAgKi9cbiAgICAgICAgYWRkOiBmdW5jdGlvbiAoY29yZSkge1xuICAgICAgICAgICAgY29uc3QgY29udGV4dCA9IGNvcmUuY29udGV4dDtcbiAgICAgICAgICAgIGNvbnRleHQuZGlhbG9nID0ge1xuICAgICAgICAgICAgICAgIGtpbmQ6ICcnLFxuICAgICAgICAgICAgICAgIHVwZGF0ZU1vZGFsOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBfY2xvc2VTaWduYWw6IGZhbHNlXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKiogZGlhbG9nICovXG4gICAgICAgICAgICBsZXQgZGlhbG9nX2RpdiA9IGNvcmUudXRpbC5jcmVhdGVFbGVtZW50KCdESVYnKTtcbiAgICAgICAgICAgIGRpYWxvZ19kaXYuY2xhc3NOYW1lID0gJ3NlLWRpYWxvZyBzdW4tZWRpdG9yLWNvbW1vbic7XG5cbiAgICAgICAgICAgIGxldCBkaWFsb2dfYmFjayA9IGNvcmUudXRpbC5jcmVhdGVFbGVtZW50KCdESVYnKTtcbiAgICAgICAgICAgIGRpYWxvZ19iYWNrLmNsYXNzTmFtZSA9ICdzZS1kaWFsb2ctYmFjayc7XG4gICAgICAgICAgICBkaWFsb2dfYmFjay5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXG4gICAgICAgICAgICBsZXQgZGlhbG9nX2FyZWEgPSBjb3JlLnV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XG4gICAgICAgICAgICBkaWFsb2dfYXJlYS5jbGFzc05hbWUgPSAnc2UtZGlhbG9nLWlubmVyJztcbiAgICAgICAgICAgIGRpYWxvZ19hcmVhLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cbiAgICAgICAgICAgIGRpYWxvZ19kaXYuYXBwZW5kQ2hpbGQoZGlhbG9nX2JhY2spO1xuICAgICAgICAgICAgZGlhbG9nX2Rpdi5hcHBlbmRDaGlsZChkaWFsb2dfYXJlYSk7XG5cbiAgICAgICAgICAgIGNvbnRleHQuZGlhbG9nLm1vZGFsQXJlYSA9IGRpYWxvZ19kaXY7XG4gICAgICAgICAgICBjb250ZXh0LmRpYWxvZy5iYWNrID0gZGlhbG9nX2JhY2s7XG4gICAgICAgICAgICBjb250ZXh0LmRpYWxvZy5tb2RhbCA9IGRpYWxvZ19hcmVhO1xuXG4gICAgICAgICAgICAvKiogYWRkIGV2ZW50IGxpc3RlbmVycyAqL1xuICAgICAgICAgICAgY29udGV4dC5kaWFsb2cubW9kYWwuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5fb25Nb3VzZURvd25fZGlhbG9nLmJpbmQoY29yZSkpO1xuICAgICAgICAgICAgY29udGV4dC5kaWFsb2cubW9kYWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9vbkNsaWNrX2RpYWxvZy5iaW5kKGNvcmUpKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLyoqIGFwcGVuZCBodG1sICovXG4gICAgICAgICAgICBjb250ZXh0LmVsZW1lbnQucmVsYXRpdmUuYXBwZW5kQ2hpbGQoZGlhbG9nX2Rpdik7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIC8qKiBlbXB0eSBtZW1vcnkgKi9cbiAgICAgICAgICAgIGRpYWxvZ19kaXYgPSBudWxsLCBkaWFsb2dfYmFjayA9IG51bGwsIGRpYWxvZ19hcmVhID0gbnVsbDtcbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEV2ZW50IHRvIGNvbnRyb2wgdGhlIGJlaGF2aW9yIG9mIGNsb3NpbmcgdGhlIGRpYWxvZ1xuICAgICAgICAgKiBAcGFyYW0ge01vdXNlRXZlbnR9IGUgRXZlbnQgb2JqZWN0XG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICBfb25Nb3VzZURvd25fZGlhbG9nOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgaWYgKC9zZS1kaWFsb2ctaW5uZXIvLnRlc3QoZS50YXJnZXQuY2xhc3NOYW1lKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC5kaWFsb2cuX2Nsb3NlU2lnbmFsID0gdHJ1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LmRpYWxvZy5fY2xvc2VTaWduYWwgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEV2ZW50IHRvIGNsb3NlIHRoZSB3aW5kb3cgd2hlbiB0aGUgb3V0c2lkZSBhcmVhIG9mIHRoZSBkaWFsb2cgb3IgY2xvc2UgYnV0dG9uIGlzIGNsaWNrXG4gICAgICAgICAqIEBwYXJhbSB7TW91c2VFdmVudH0gZSBFdmVudCBvYmplY3RcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIF9vbkNsaWNrX2RpYWxvZzogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgICAgIGlmICgvY2xvc2UvLnRlc3QoZS50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLWNvbW1hbmQnKSkgfHwgdGhpcy5jb250ZXh0LmRpYWxvZy5fY2xvc2VTaWduYWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMuZGlhbG9nLmNsb3NlLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBPcGVuIGEgRGlhbG9nIHBsdWdpblxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30ga2luZCBEaWFsb2cgcGx1Z2luIG5hbWVcbiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSB1cGRhdGUgV2hldGhlciBpdCB3aWxsIG9wZW4gZm9yIHVwZGF0ZSAoJ2ltYWdlJyA9PT0gdGhpcy5jdXJyZW50Q29udHJvbGxlck5hbWUpXG4gICAgICAgICAqL1xuICAgICAgICBvcGVuOiBmdW5jdGlvbiAoa2luZCwgdXBkYXRlKSAge1xuICAgICAgICAgICAgaWYgKHRoaXMubW9kYWxGb3JtKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBpZiAodGhpcy5wbHVnaW5zLmRpYWxvZy5fYmluZENsb3NlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5wbHVnaW5zLmRpYWxvZy5fYmluZENsb3NlKTtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMuZGlhbG9nLl9iaW5kQ2xvc2UgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMuZGlhbG9nLl9iaW5kQ2xvc2UgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIGlmICghLzI3Ly50ZXN0KGUua2V5Q29kZSkpIHJldHVybjtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMuZGlhbG9nLmNsb3NlLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB9LmJpbmQodGhpcyk7XG4gICAgICAgICAgICB0aGlzLl9kLmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLnBsdWdpbnMuZGlhbG9nLl9iaW5kQ2xvc2UpO1xuXG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuZGlhbG9nLnVwZGF0ZU1vZGFsID0gdXBkYXRlO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0Lm9wdGlvbi5wb3B1cERpc3BsYXkgPT09ICdmdWxsJykge1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC5kaWFsb2cubW9kYWxBcmVhLnN0eWxlLnBvc2l0aW9uID0gJ2ZpeGVkJztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LmRpYWxvZy5tb2RhbEFyZWEuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuZGlhbG9nLmtpbmQgPSBraW5kO1xuICAgICAgICAgICAgdGhpcy5tb2RhbEZvcm0gPSB0aGlzLmNvbnRleHRba2luZF0ubW9kYWw7XG4gICAgICAgICAgICBjb25zdCBmb2N1c0VsZW1lbnQgPSB0aGlzLmNvbnRleHRba2luZF0uZm9jdXNFbGVtZW50O1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMucGx1Z2luc1traW5kXS5vbiA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5wbHVnaW5zW2tpbmRdLm9uLmNhbGwodGhpcywgdXBkYXRlKTtcblxuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmRpYWxvZy5tb2RhbEFyZWEuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuZGlhbG9nLmJhY2suc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuZGlhbG9nLm1vZGFsLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICAgICAgdGhpcy5tb2RhbEZvcm0uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cbiAgICAgICAgICAgIGlmIChmb2N1c0VsZW1lbnQpIGZvY3VzRWxlbWVudC5mb2N1cygpO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9iaW5kQ2xvc2U6IG51bGwsXG4gICAgICAgIFxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIENsb3NlIGEgRGlhbG9nIHBsdWdpblxuICAgICAgICAgKiBUaGUgcGx1Z2luJ3MgXCJpbml0XCIgbWV0aG9kIGlzIGNhbGxlZC5cbiAgICAgICAgICovXG4gICAgICAgIGNsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wbHVnaW5zLmRpYWxvZy5fYmluZENsb3NlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5wbHVnaW5zLmRpYWxvZy5fYmluZENsb3NlKTtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMuZGlhbG9nLl9iaW5kQ2xvc2UgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBraW5kID0gdGhpcy5jb250ZXh0LmRpYWxvZy5raW5kO1xuICAgICAgICAgICAgdGhpcy5tb2RhbEZvcm0uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5kaWFsb2cuYmFjay5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmRpYWxvZy5tb2RhbEFyZWEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5kaWFsb2cudXBkYXRlTW9kYWwgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5wbHVnaW5zW2tpbmRdLmluaXQgPT09ICdmdW5jdGlvbicpIHRoaXMucGx1Z2luc1traW5kXS5pbml0LmNhbGwodGhpcyk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuZGlhbG9nLmtpbmQgPSAnJztcbiAgICAgICAgICAgIHRoaXMubW9kYWxGb3JtID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuZm9jdXMoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAodHlwZW9mIG5vR2xvYmFsID09PSB0eXBlb2YgdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghd2luZG93LlNVTkVESVRPUl9NT0RVTEVTKSB7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LCAnU1VORURJVE9SX01PRFVMRVMnLCB7XG4gICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB2YWx1ZToge31cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdy5TVU5FRElUT1JfTU9EVUxFUywgJ2RpYWxvZycsIHtcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgdmFsdWU6IGRpYWxvZ1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGlhbG9nO1xufSkpOyIsIi8qXG4gKiB3eXNpd3lnIHdlYiBlZGl0b3JcbiAqXG4gKiBzdW5lZGl0b3IuanNcbiAqIENvcHlyaWdodCAyMDE3IEppSG9uZyBMZWUuXG4gKiBNSVQgbGljZW5zZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG4oZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuICAgIGlmICh0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlLmV4cG9ydHMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gZ2xvYmFsLmRvY3VtZW50ID9cbiAgICAgICAgICAgIGZhY3RvcnkoZ2xvYmFsLCB0cnVlKSA6XG4gICAgICAgICAgICBmdW5jdGlvbiAodykge1xuICAgICAgICAgICAgICAgIGlmICghdy5kb2N1bWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NVTkVESVRPUl9NT0RVTEVTIGEgd2luZG93IHdpdGggYSBkb2N1bWVudCcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZmFjdG9yeSh3KTtcbiAgICAgICAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZmFjdG9yeShnbG9iYWwpO1xuICAgIH1cbn0odHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0aGlzLCBmdW5jdGlvbiAod2luZG93LCBub0dsb2JhbCkge1xuICAgIGNvbnN0IGZpbGVCcm93c2VyID0ge1xuICAgICAgICBuYW1lOiAnZmlsZUJyb3dzZXInLFxuICAgICAgICBfeG1sSHR0cDogbnVsbCxcbiAgICAgICAgX2xvYWRpbmc6IG51bGwsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDb25zdHJ1Y3RvclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY29yZSBDb3JlIG9iamVjdCBcbiAgICAgICAgICovXG4gICAgICAgIGFkZDogZnVuY3Rpb24gKGNvcmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSBjb3JlLmNvbnRleHQ7XG4gICAgICAgICAgICBjb250ZXh0LmZpbGVCcm93c2VyID0ge1xuICAgICAgICAgICAgICAgIF9jbG9zZVNpZ25hbDogZmFsc2UsXG4gICAgICAgICAgICAgICAgYXJlYTogbnVsbCxcbiAgICAgICAgICAgICAgICBoZWFkZXI6IG51bGwsXG4gICAgICAgICAgICAgICAgdGFnQXJlYTogbnVsbCxcbiAgICAgICAgICAgICAgICBib2R5OiBudWxsLFxuICAgICAgICAgICAgICAgIGxpc3Q6IG51bGwsXG4gICAgICAgICAgICAgICAgdGFnRWxlbWVudHM6IG51bGwsXG4gICAgICAgICAgICAgICAgaXRlbXM6IFtdLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkVGFnczogW10sXG4gICAgICAgICAgICAgICAgc2VsZWN0b3JIYW5kbGVyOiBudWxsLFxuICAgICAgICAgICAgICAgIGNvbnRleHRQbHVnaW46ICcnLFxuICAgICAgICAgICAgICAgIGNvbHVtblNpemU6IDRcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKiBmaWxlQnJvd3NlciAqL1xuICAgICAgICAgICAgbGV0IGJyb3dzZXJfZGl2ID0gY29yZS51dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xuICAgICAgICAgICAgYnJvd3Nlcl9kaXYuY2xhc3NOYW1lID0gJ3NlLWZpbGUtYnJvd3NlciBzdW4tZWRpdG9yLWNvbW1vbic7XG5cbiAgICAgICAgICAgIGxldCBiYWNrID0gY29yZS51dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xuICAgICAgICAgICAgYmFjay5jbGFzc05hbWUgPSAnc2UtZmlsZS1icm93c2VyLWJhY2snO1xuXG4gICAgICAgICAgICBsZXQgY29udGVudCA9IGNvcmUudXRpbC5jcmVhdGVFbGVtZW50KCdESVYnKTtcbiAgICAgICAgICAgIGNvbnRlbnQuY2xhc3NOYW1lID0gJ3NlLWZpbGUtYnJvd3Nlci1pbm5lcic7XG4gICAgICAgICAgICBjb250ZW50LmlubmVySFRNTCA9IHRoaXMuc2V0X2Jyb3dzZXIoY29yZSk7XG5cbiAgICAgICAgICAgIGJyb3dzZXJfZGl2LmFwcGVuZENoaWxkKGJhY2spO1xuICAgICAgICAgICAgYnJvd3Nlcl9kaXYuYXBwZW5kQ2hpbGQoY29udGVudCk7XG4gICAgICAgICAgICB0aGlzLl9sb2FkaW5nID0gYnJvd3Nlcl9kaXYucXVlcnlTZWxlY3RvcignLnNlLWxvYWRpbmctYm94Jyk7XG5cbiAgICAgICAgICAgIGNvbnRleHQuZmlsZUJyb3dzZXIuYXJlYSA9IGJyb3dzZXJfZGl2O1xuICAgICAgICAgICAgY29udGV4dC5maWxlQnJvd3Nlci5oZWFkZXIgPSBjb250ZW50LnF1ZXJ5U2VsZWN0b3IoJy5zZS1maWxlLWJyb3dzZXItaGVhZGVyJyk7XG4gICAgICAgICAgICBjb250ZXh0LmZpbGVCcm93c2VyLnRpdGxlQXJlYSA9IGNvbnRlbnQucXVlcnlTZWxlY3RvcignLnNlLWZpbGUtYnJvd3Nlci10aXRsZScpO1xuICAgICAgICAgICAgY29udGV4dC5maWxlQnJvd3Nlci50YWdBcmVhID0gY29udGVudC5xdWVyeVNlbGVjdG9yKCcuc2UtZmlsZS1icm93c2VyLXRhZ3MnKTtcbiAgICAgICAgICAgIGNvbnRleHQuZmlsZUJyb3dzZXIuYm9keSA9IGNvbnRlbnQucXVlcnlTZWxlY3RvcignLnNlLWZpbGUtYnJvd3Nlci1ib2R5Jyk7XG4gICAgICAgICAgICBjb250ZXh0LmZpbGVCcm93c2VyLmxpc3QgPSBjb250ZW50LnF1ZXJ5U2VsZWN0b3IoJy5zZS1maWxlLWJyb3dzZXItbGlzdCcpO1xuXG4gICAgICAgICAgICAvKiogYWRkIGV2ZW50IGxpc3RlbmVycyAqL1xuICAgICAgICAgICAgY29udGV4dC5maWxlQnJvd3Nlci50YWdBcmVhLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5vbkNsaWNrVGFnLmJpbmQoY29yZSkpO1xuICAgICAgICAgICAgY29udGV4dC5maWxlQnJvd3Nlci5saXN0LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5vbkNsaWNrRmlsZS5iaW5kKGNvcmUpKTtcbiAgICAgICAgICAgIGNvbnRlbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5fb25Nb3VzZURvd25fYnJvd3Nlci5iaW5kKGNvcmUpKTtcbiAgICAgICAgICAgIGNvbnRlbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9vbkNsaWNrX2Jyb3dzZXIuYmluZChjb3JlKSk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIC8qKiBhcHBlbmQgaHRtbCAqL1xuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LnJlbGF0aXZlLmFwcGVuZENoaWxkKGJyb3dzZXJfZGl2KTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLyoqIGVtcHR5IG1lbW9yeSAqL1xuICAgICAgICAgICAgYnJvd3Nlcl9kaXYgPSBudWxsLCBiYWNrID0gbnVsbCwgY29udGVudCA9IG51bGw7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2V0X2Jyb3dzZXI6IGZ1bmN0aW9uIChjb3JlKSB7XG4gICAgICAgICAgICBjb25zdCBsYW5nID0gY29yZS5sYW5nO1xuXG4gICAgICAgICAgICByZXR1cm4gJzxkaXYgY2xhc3M9XCJzZS1maWxlLWJyb3dzZXItY29udGVudFwiPicgK1xuICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWZpbGUtYnJvd3Nlci1oZWFkZXJcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJjbG9zZVwiIGNsYXNzPVwic2UtYnRuIHNlLWZpbGUtYnJvd3Nlci1jbG9zZVwiIGNsYXNzPVwiY2xvc2VcIiBhcmlhLWxhYmVsPVwiQ2xvc2VcIiB0aXRsZT1cIicgKyBsYW5nLmRpYWxvZ0JveC5jbG9zZSArICdcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuaWNvbnMuY2FuY2VsICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLWZpbGUtYnJvd3Nlci10aXRsZVwiPjwvc3Bhbj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZmlsZS1icm93c2VyLXRhZ3NcIj48L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWZpbGUtYnJvd3Nlci1ib2R5XCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWxvYWRpbmctYm94IHN1bi1lZGl0b3ItY29tbW9uXCI+PGRpdiBjbGFzcz1cInNlLWxvYWRpbmctZWZmZWN0XCI+PC9kaXY+PC9kaXY+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWZpbGUtYnJvd3Nlci1saXN0XCI+PC9kaXY+JyArXG4gICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPC9kaXY+JztcbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEV2ZW50IHRvIGNvbnRyb2wgdGhlIGJlaGF2aW9yIG9mIGNsb3NpbmcgdGhlIGJyb3dzZXJcbiAgICAgICAgICogQHBhcmFtIHtNb3VzZUV2ZW50fSBlIEV2ZW50IG9iamVjdFxuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgX29uTW91c2VEb3duX2Jyb3dzZXI6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBpZiAoL3NlLWZpbGUtYnJvd3Nlci1pbm5lci8udGVzdChlLnRhcmdldC5jbGFzc05hbWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LmZpbGVCcm93c2VyLl9jbG9zZVNpZ25hbCA9IHRydWU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC5maWxlQnJvd3Nlci5fY2xvc2VTaWduYWwgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEV2ZW50IHRvIGNsb3NlIHRoZSB3aW5kb3cgd2hlbiB0aGUgb3V0c2lkZSBhcmVhIG9mIHRoZSBicm93c2VyIG9yIGNsb3NlIGJ1dHRvbiBpcyBjbGlja1xuICAgICAgICAgKiBAcGFyYW0ge01vdXNlRXZlbnR9IGUgRXZlbnQgb2JqZWN0XG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICBfb25DbGlja19icm93c2VyOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICAgICAgaWYgKC9jbG9zZS8udGVzdChlLnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY29tbWFuZCcpKSB8fCB0aGlzLmNvbnRleHQuZmlsZUJyb3dzZXIuX2Nsb3NlU2lnbmFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmZpbGVCcm93c2VyLmNsb3NlLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBPcGVuIGEgZmlsZSBicm93c2VyIHBsdWdpblxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gcGx1Z2luTmFtZSBQbHVnaW4gbmFtZSB1c2luZyB0aGUgZmlsZSBicm93c2VyXG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb258bnVsbH0gc2VsZWN0b3JIYW5kbGVyIFdoZW4gdGhlIGZ1bmN0aW9uIGNvbWVzIGFzIGFuIGFyZ3VtZW50IHZhbHVlLCBpdCBzdWJzdGl0dXRlcyBcImNvbnRleHQuc2VsZWN0b3JIYW5kbGVyXCIuXG4gICAgICAgICAqL1xuICAgICAgICBvcGVuOiBmdW5jdGlvbiAocGx1Z2luTmFtZSwgc2VsZWN0b3JIYW5kbGVyKSAge1xuICAgICAgICAgICAgaWYgKHRoaXMucGx1Z2lucy5maWxlQnJvd3Nlci5fYmluZENsb3NlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5wbHVnaW5zLmZpbGVCcm93c2VyLl9iaW5kQ2xvc2UpO1xuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2lucy5maWxlQnJvd3Nlci5fYmluZENsb3NlID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmZpbGVCcm93c2VyLl9iaW5kQ2xvc2UgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIGlmICghLzI3Ly50ZXN0KGUua2V5Q29kZSkpIHJldHVybjtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMuZmlsZUJyb3dzZXIuY2xvc2UuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgIH0uYmluZCh0aGlzKTtcbiAgICAgICAgICAgIHRoaXMuX2QuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMucGx1Z2lucy5maWxlQnJvd3Nlci5fYmluZENsb3NlKTtcblxuICAgICAgICAgICAgY29uc3QgZmlsZUJyb3dzZXJDb250ZXh0ID0gdGhpcy5jb250ZXh0LmZpbGVCcm93c2VyO1xuICAgICAgICAgICAgZmlsZUJyb3dzZXJDb250ZXh0LmNvbnRleHRQbHVnaW4gPSBwbHVnaW5OYW1lO1xuICAgICAgICAgICAgZmlsZUJyb3dzZXJDb250ZXh0LnNlbGVjdG9ySGFuZGxlciA9IHNlbGVjdG9ySGFuZGxlcjtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29uc3QgcGx1Z2luQ29udGV4dCA9IHRoaXMuY29udGV4dFtwbHVnaW5OYW1lXTtcbiAgICAgICAgICAgIGNvbnN0IGxpc3RDbGFzc05hbWUgPSBwbHVnaW5Db250ZXh0Lmxpc3RDbGFzcztcbiAgICAgICAgICAgIGlmICghdGhpcy51dGlsLmhhc0NsYXNzKGZpbGVCcm93c2VyQ29udGV4dC5saXN0LCBsaXN0Q2xhc3NOYW1lKSkge1xuICAgICAgICAgICAgICAgIGZpbGVCcm93c2VyQ29udGV4dC5saXN0LmNsYXNzTmFtZSA9ICdzZS1maWxlLWJyb3dzZXItbGlzdCAnICsgbGlzdENsYXNzTmFtZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC5vcHRpb24ucG9wdXBEaXNwbGF5ID09PSAnZnVsbCcpIHtcbiAgICAgICAgICAgICAgICBmaWxlQnJvd3NlckNvbnRleHQuYXJlYS5zdHlsZS5wb3NpdGlvbiA9ICdmaXhlZCc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZpbGVCcm93c2VyQ29udGV4dC5hcmVhLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgZmlsZUJyb3dzZXJDb250ZXh0LnRpdGxlQXJlYS50ZXh0Q29udGVudCA9IHBsdWdpbkNvbnRleHQudGl0bGU7XG4gICAgICAgICAgICBmaWxlQnJvd3NlckNvbnRleHQuYXJlYS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblxuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmZpbGVCcm93c2VyLl9kcmF3RmlsZUxpc3QuY2FsbCh0aGlzLCB0aGlzLmNvbnRleHRbcGx1Z2luTmFtZV0udXJsKTtcbiAgICAgICAgfSxcblxuICAgICAgICBfYmluZENsb3NlOiBudWxsLFxuICAgICAgICBcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDbG9zZSBhIGZpbGVCcm93c2VyIHBsdWdpblxuICAgICAgICAgKiBUaGUgcGx1Z2luJ3MgXCJpbml0XCIgbWV0aG9kIGlzIGNhbGxlZC5cbiAgICAgICAgICovXG4gICAgICAgIGNsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBmaWxlQnJvd3NlclBsdWdpbiA9IHRoaXMucGx1Z2lucy5maWxlQnJvd3NlcjtcblxuICAgICAgICAgICAgaWYgKGZpbGVCcm93c2VyUGx1Z2luLl94bWxIdHRwKSB7XG4gICAgICAgICAgICAgICAgZmlsZUJyb3dzZXJQbHVnaW4uX3htbEh0dHAuYWJvcnQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGZpbGVCcm93c2VyUGx1Z2luLl9iaW5kQ2xvc2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9kLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBmaWxlQnJvd3NlclBsdWdpbi5fYmluZENsb3NlKTtcbiAgICAgICAgICAgICAgICBmaWxlQnJvd3NlclBsdWdpbi5fYmluZENsb3NlID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZmlsZUJyb3dzZXJDb250ZXh0ID0gdGhpcy5jb250ZXh0LmZpbGVCcm93c2VyO1xuICAgICAgICAgICAgZmlsZUJyb3dzZXJDb250ZXh0LmFyZWEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGZpbGVCcm93c2VyQ29udGV4dC5zZWxlY3RvckhhbmRsZXIgPSBudWxsO1xuICAgICAgICAgICAgZmlsZUJyb3dzZXJDb250ZXh0LnNlbGVjdGVkVGFncyA9IFtdO1xuICAgICAgICAgICAgZmlsZUJyb3dzZXJDb250ZXh0Lml0ZW1zID0gW107XG4gICAgICAgICAgICBmaWxlQnJvd3NlckNvbnRleHQubGlzdC5pbm5lckhUTUwgPSBmaWxlQnJvd3NlckNvbnRleHQudGFnQXJlYS5pbm5lckhUTUwgPSBmaWxlQnJvd3NlckNvbnRleHQudGl0bGVBcmVhLnRleHRDb250ZW50ID0gJyc7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5wbHVnaW5zW2ZpbGVCcm93c2VyQ29udGV4dC5jb250ZXh0UGx1Z2luXS5pbml0ID09PSAnZnVuY3Rpb24nKSB0aGlzLnBsdWdpbnNbZmlsZUJyb3dzZXJDb250ZXh0LmNvbnRleHRQbHVnaW5dLmluaXQuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgIGZpbGVCcm93c2VyQ29udGV4dC5jb250ZXh0UGx1Z2luID0gJyc7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBTaG93IGZpbGUgYnJvd3NlciBsb2FkaW5nIGJveFxuICAgICAgICAgKi9cbiAgICAgICAgc2hvd0Jyb3dzZXJMb2FkaW5nOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aGlzLl9sb2FkaW5nLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ2xvc2UgZmlsZSBicm93c2VyIGxvYWRpbmcgYm94XG4gICAgICAgICAqL1xuICAgICAgICBjbG9zZUJyb3dzZXJMb2FkaW5nOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aGlzLl9sb2FkaW5nLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2RyYXdGaWxlTGlzdDogZnVuY3Rpb24gKHVybCkge1xuICAgICAgICAgICAgY29uc3QgZmlsZUJyb3dzZXJQbHVnaW4gPSB0aGlzLnBsdWdpbnMuZmlsZUJyb3dzZXI7XG5cbiAgICAgICAgICAgIGNvbnN0IHhtbEh0dHAgPSBmaWxlQnJvd3NlclBsdWdpbi5feG1sSHR0cCA9IHRoaXMudXRpbC5nZXRYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgeG1sSHR0cC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmaWxlQnJvd3NlclBsdWdpbi5fY2FsbEJhY2tHZXQuYmluZCh0aGlzLCB4bWxIdHRwKTtcbiAgICAgICAgICAgIHhtbEh0dHAub3BlbignZ2V0JywgdXJsLCB0cnVlKTtcbiAgICAgICAgICAgIHhtbEh0dHAuc2VuZChudWxsKTtcblxuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmZpbGVCcm93c2VyLnNob3dCcm93c2VyTG9hZGluZygpO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9jYWxsQmFja0dldDogZnVuY3Rpb24gKHhtbEh0dHApIHtcbiAgICAgICAgICAgIGlmICh4bWxIdHRwLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMuZmlsZUJyb3dzZXIuX3htbEh0dHAgPSBudWxsO1xuICAgICAgICAgICAgICAgIGlmICh4bWxIdHRwLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMuZmlsZUJyb3dzZXIuX2RyYXdMaXN0SXRlbS5jYWxsKHRoaXMsIEpTT04ucGFyc2UoeG1sSHR0cC5yZXNwb25zZVRleHQpLnJlc3VsdCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKCdbU1VORURJVE9SLmZpbGVCcm93c2VyLmRyYXdMaXN0LmZhaWxdIGNhdXNlIDogXCInICsgZS5tZXNzYWdlICsgJ1wiJyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMuZmlsZUJyb3dzZXIuY2xvc2VCcm93c2VyTG9hZGluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LmZpbGVCcm93c2VyLmJvZHkuc3R5bGUubWF4SGVpZ2h0ID0gKHRoaXMuX3cuaW5uZXJIZWlnaHQgLSB0aGlzLmNvbnRleHQuZmlsZUJyb3dzZXIuaGVhZGVyLm9mZnNldEhlaWdodCAtIDUwKSArICdweCc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBleGNlcHRpb25cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmZpbGVCcm93c2VyLmNsb3NlQnJvd3NlckxvYWRpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHhtbEh0dHAuc3RhdHVzICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZXMgPSAheG1sSHR0cC5yZXNwb25zZVRleHQgPyB4bWxIdHRwIDogSlNPTi5wYXJzZSh4bWxIdHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnIgPSAnW1NVTkVESVRPUi5maWxlQnJvd3Nlci5nZXQuc2VydmVyRXhjZXB0aW9uXSBzdGF0dXM6ICcgKyB4bWxIdHRwLnN0YXR1cyArICcsIHJlc3BvbnNlOiAnICsgKHJlcy5lcnJvck1lc3NhZ2UgfHwgeG1sSHR0cC5yZXNwb25zZVRleHQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBfZHJhd0xpc3RJdGVtOiBmdW5jdGlvbiAoaXRlbXMsIHVwZGF0ZSkge1xuICAgICAgICAgICAgY29uc3QgZmlsZUJyb3dzZXJDb250ZXh0ID0gdGhpcy5jb250ZXh0LmZpbGVCcm93c2VyO1xuICAgICAgICAgICAgY29uc3QgcGx1Z2luQ29udGV4dCA9IHRoaXMuY29udGV4dFtmaWxlQnJvd3NlckNvbnRleHQuY29udGV4dFBsdWdpbl07XG5cbiAgICAgICAgICAgIGNvbnN0IF90YWdzID0gW107XG4gICAgICAgICAgICBjb25zdCBsZW4gPSBpdGVtcy5sZW5ndGg7XG4gICAgICAgICAgICBjb25zdCBjb2x1bW5TaXplID0gcGx1Z2luQ29udGV4dC5jb2x1bW5TaXplIHx8IGZpbGVCcm93c2VyQ29udGV4dC5jb2x1bW5TaXplO1xuICAgICAgICAgICAgY29uc3Qgc3BsaXRTaXplID0gY29sdW1uU2l6ZSA8PSAxID8gMSA6IChNYXRoLnJvdW5kKGxlbi9jb2x1bW5TaXplKSB8fCAxKTtcbiAgICAgICAgICAgIGNvbnN0IGRyYXdJdGVtSGFuZGxlciA9IHBsdWdpbkNvbnRleHQuaXRlbVRlbXBsYXRlSGFuZGxlcjtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgbGV0IHRhZ3NIVE1MID0gJyc7XG4gICAgICAgICAgICBsZXQgbGlzdEhUTUwgPSAnPGRpdiBjbGFzcz1cInNlLWZpbGUtaXRlbS1jb2x1bW5cIj4nO1xuICAgICAgICAgICAgbGV0IGNvbHVtbnMgPSAxO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGl0ZW0sIHRhZ3M7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIGl0ZW0gPSBpdGVtc1tpXTtcbiAgICAgICAgICAgICAgICB0YWdzID0gIWl0ZW0udGFnID8gW10gOiB0eXBlb2YgaXRlbS50YWcgPT09ICdzdHJpbmcnID8gaXRlbS50YWcuc3BsaXQoJywnKSA6IGl0ZW0udGFnO1xuICAgICAgICAgICAgICAgIHRhZ3MgPSBpdGVtLnRhZyA9IHRhZ3MubWFwKGZ1bmN0aW9uICh2KSB7IHJldHVybiB2LnRyaW0oKTsgfSk7XG4gICAgICAgICAgICAgICAgbGlzdEhUTUwgKz0gZHJhd0l0ZW1IYW5kbGVyKGl0ZW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKChpICsgMSkgJSBzcGxpdFNpemUgPT09IDAgJiYgY29sdW1ucyA8IGNvbHVtblNpemUgJiYgKGkgKyAxKSA8IGxlbikge1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW5zKys7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RIVE1MICs9ICc8L2Rpdj48ZGl2IGNsYXNzPVwic2UtZmlsZS1pdGVtLWNvbHVtblwiPic7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmICh1cGRhdGUgJiYgdGFncy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHQgPSAwLCB0TGVuID0gdGFncy5sZW5ndGgsIHRhZzsgdCA8IHRMZW47IHQrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGFnID0gdGFnc1t0XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YWcgJiYgX3RhZ3MuaW5kZXhPZih0YWcpID09PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90YWdzLnB1c2godGFnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWdzSFRNTCArPSAnPGEgdGl0bGU9XCInICsgdGFnICsgJ1wiPicgKyB0YWcgKyAnPC9hPic7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsaXN0SFRNTCArPSAnPC9kaXY+JztcblxuICAgICAgICAgICAgZmlsZUJyb3dzZXJDb250ZXh0Lmxpc3QuaW5uZXJIVE1MID0gbGlzdEhUTUw7XG5cbiAgICAgICAgICAgIGlmICh1cGRhdGUpIHtcbiAgICAgICAgICAgICAgICBmaWxlQnJvd3NlckNvbnRleHQuaXRlbXMgPSBpdGVtcztcbiAgICAgICAgICAgICAgICBmaWxlQnJvd3NlckNvbnRleHQudGFnQXJlYS5pbm5lckhUTUwgPSB0YWdzSFRNTDtcbiAgICAgICAgICAgICAgICBmaWxlQnJvd3NlckNvbnRleHQudGFnRWxlbWVudHMgPSBmaWxlQnJvd3NlckNvbnRleHQudGFnQXJlYS5xdWVyeVNlbGVjdG9yQWxsKCdBJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgb25DbGlja1RhZzogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgaWYgKCF0aGlzLnV0aWwuaXNBbmNob3IodGFyZ2V0KSkgcmV0dXJuO1xuXG4gICAgICAgICAgICBjb25zdCB0YWdOYW1lID0gdGFyZ2V0LnRleHRDb250ZW50O1xuICAgICAgICAgICAgY29uc3QgZmlsZUJyb3dzZXJQbHVnaW4gPSB0aGlzLnBsdWdpbnMuZmlsZUJyb3dzZXI7XG4gICAgICAgICAgICBjb25zdCBmaWxlQnJvd3NlckNvbnRleHQgPSB0aGlzLmNvbnRleHQuZmlsZUJyb3dzZXI7XG5cbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdFRhZyA9IGZpbGVCcm93c2VyQ29udGV4dC50YWdBcmVhLnF1ZXJ5U2VsZWN0b3IoJ2FbdGl0bGU9XCInICsgdGFnTmFtZSArICdcIl0nKTtcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkVGFncyA9IGZpbGVCcm93c2VyQ29udGV4dC5zZWxlY3RlZFRhZ3M7XG4gICAgICAgICAgICBjb25zdCBzVGFnSW5kZXggPSBzZWxlY3RlZFRhZ3MuaW5kZXhPZih0YWdOYW1lKTtcblxuICAgICAgICAgICAgaWYgKHNUYWdJbmRleCA+IC0xKXtcbiAgICAgICAgICAgICAgICBzZWxlY3RlZFRhZ3Muc3BsaWNlKHNUYWdJbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUNsYXNzKHNlbGVjdFRhZywgJ29uJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNlbGVjdGVkVGFncy5wdXNoKHRhZ05hbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMudXRpbC5hZGRDbGFzcyhzZWxlY3RUYWcsICdvbicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmaWxlQnJvd3NlclBsdWdpbi5fZHJhd0xpc3RJdGVtLmNhbGwodGhpcyxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZFRhZ3MubGVuZ3RoID09PSAwID9cbiAgICAgICAgICAgICAgICBmaWxlQnJvd3NlckNvbnRleHQuaXRlbXMgOlxuICAgICAgICAgICAgICAgIGZpbGVCcm93c2VyQ29udGV4dC5pdGVtcy5maWx0ZXIoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0udGFnLnNvbWUoZnVuY3Rpb24gKHRhZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGVjdGVkVGFncy5pbmRleE9mKHRhZykgPiAtMTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSksIGZhbHNlKTtcbiAgICAgICAgfSxcblxuICAgICAgICBvbkNsaWNrRmlsZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgICAgIGNvbnN0IGZpbGVCcm93c2VyQ29udGV4dCA9IHRoaXMuY29udGV4dC5maWxlQnJvd3NlcjtcbiAgICAgICAgICAgIGNvbnN0IGxpc3RFbCA9IGZpbGVCcm93c2VyQ29udGV4dC5saXN0O1xuICAgICAgICAgICAgbGV0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgbGV0IGNvbW1hbmQgPSBudWxsO1xuXG4gICAgICAgICAgICBpZiAodGFyZ2V0ID09PSBsaXN0RWwpIHJldHVybjtcblxuICAgICAgICAgICAgd2hpbGUgKGxpc3RFbCAhPT0gdGFyZ2V0LnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgICAgICBjb21tYW5kID0gdGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS1jb21tYW5kJyk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbW1hbmQpIGJyZWFrO1xuICAgICAgICAgICAgICAgIHRhcmdldCA9IHRhcmdldC5wYXJlbnROb2RlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWNvbW1hbmQpIHJldHVybjtcblxuICAgICAgICAgICAgY29uc3QgaGFuZGxlciA9IChmaWxlQnJvd3NlckNvbnRleHQuc2VsZWN0b3JIYW5kbGVyIHx8IHRoaXMuY29udGV4dFtmaWxlQnJvd3NlckNvbnRleHQuY29udGV4dFBsdWdpbl0uc2VsZWN0b3JIYW5kbGVyKTtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5maWxlQnJvd3Nlci5jbG9zZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgaGFuZGxlcih0YXJnZXQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGlmICh0eXBlb2Ygbm9HbG9iYWwgPT09IHR5cGVvZiB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCF3aW5kb3cuU1VORURJVE9SX01PRFVMRVMpIHtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3csICdTVU5FRElUT1JfTU9EVUxFUycsIHtcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB7fVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LlNVTkVESVRPUl9NT0RVTEVTLCAnZmlsZUJyb3dzZXInLCB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiBmaWxlQnJvd3NlclxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmlsZUJyb3dzZXI7XG59KSk7IiwiLypcbiAqIHd5c2l3eWcgd2ViIGVkaXRvclxuICpcbiAqIHN1bmVkaXRvci5qc1xuICogQ29weXJpZ2h0IDIwMTcgSmlIb25nIExlZS5cbiAqIE1JVCBsaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gICAgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBnbG9iYWwuZG9jdW1lbnQgP1xuICAgICAgICAgICAgZmFjdG9yeShnbG9iYWwsIHRydWUpIDpcbiAgICAgICAgICAgIGZ1bmN0aW9uICh3KSB7XG4gICAgICAgICAgICAgICAgaWYgKCF3LmRvY3VtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU1VORURJVE9SX0xBTkcgYSB3aW5kb3cgd2l0aCBhIGRvY3VtZW50Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWN0b3J5KHcpO1xuICAgICAgICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBmYWN0b3J5KGdsb2JhbCk7XG4gICAgfVxufSh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHRoaXMsIGZ1bmN0aW9uICh3aW5kb3csIG5vR2xvYmFsKSB7XG4gICAgY29uc3QgbGFuZyA9IHtcbiAgICAgICAgY29kZTogJ2VuJyxcbiAgICAgICAgdG9vbGJhcjoge1xuICAgICAgICAgICAgZGVmYXVsdDogJ0RlZmF1bHQnLFxuICAgICAgICAgICAgc2F2ZTogJ1NhdmUnLFxuICAgICAgICAgICAgZm9udDogJ0ZvbnQnLFxuICAgICAgICAgICAgZm9ybWF0czogJ0Zvcm1hdHMnLFxuICAgICAgICAgICAgZm9udFNpemU6ICdTaXplJyxcbiAgICAgICAgICAgIGJvbGQ6ICdCb2xkJyxcbiAgICAgICAgICAgIHVuZGVybGluZTogJ1VuZGVybGluZScsXG4gICAgICAgICAgICBpdGFsaWM6ICdJdGFsaWMnLFxuICAgICAgICAgICAgc3RyaWtlOiAnU3RyaWtlJyxcbiAgICAgICAgICAgIHN1YnNjcmlwdDogJ1N1YnNjcmlwdCcsXG4gICAgICAgICAgICBzdXBlcnNjcmlwdDogJ1N1cGVyc2NyaXB0JyxcbiAgICAgICAgICAgIHJlbW92ZUZvcm1hdDogJ1JlbW92ZSBGb3JtYXQnLFxuICAgICAgICAgICAgZm9udENvbG9yOiAnRm9udCBDb2xvcicsXG4gICAgICAgICAgICBoaWxpdGVDb2xvcjogJ0hpZ2hsaWdodCBDb2xvcicsXG4gICAgICAgICAgICBpbmRlbnQ6ICdJbmRlbnQnLFxuICAgICAgICAgICAgb3V0ZGVudDogJ091dGRlbnQnLFxuICAgICAgICAgICAgYWxpZ246ICdBbGlnbicsXG4gICAgICAgICAgICBhbGlnbkxlZnQ6ICdBbGlnbiBsZWZ0JyxcbiAgICAgICAgICAgIGFsaWduUmlnaHQ6ICdBbGlnbiByaWdodCcsXG4gICAgICAgICAgICBhbGlnbkNlbnRlcjogJ0FsaWduIGNlbnRlcicsXG4gICAgICAgICAgICBhbGlnbkp1c3RpZnk6ICdBbGlnbiBqdXN0aWZ5JyxcbiAgICAgICAgICAgIGxpc3Q6ICdMaXN0JyxcbiAgICAgICAgICAgIG9yZGVyTGlzdDogJ09yZGVyZWQgbGlzdCcsXG4gICAgICAgICAgICB1bm9yZGVyTGlzdDogJ1Vub3JkZXJlZCBsaXN0JyxcbiAgICAgICAgICAgIGhvcml6b250YWxSdWxlOiAnSG9yaXpvbnRhbCBsaW5lJyxcbiAgICAgICAgICAgIGhyX3NvbGlkOiAnU29saWQnLFxuICAgICAgICAgICAgaHJfZG90dGVkOiAnRG90dGVkJyxcbiAgICAgICAgICAgIGhyX2Rhc2hlZDogJ0Rhc2hlZCcsXG4gICAgICAgICAgICB0YWJsZTogJ1RhYmxlJyxcbiAgICAgICAgICAgIGxpbms6ICdMaW5rJyxcbiAgICAgICAgICAgIG1hdGg6ICdNYXRoJyxcbiAgICAgICAgICAgIGltYWdlOiAnSW1hZ2UnLFxuICAgICAgICAgICAgdmlkZW86ICdWaWRlbycsXG4gICAgICAgICAgICBhdWRpbzogJ0F1ZGlvJyxcbiAgICAgICAgICAgIGZ1bGxTY3JlZW46ICdGdWxsIHNjcmVlbicsXG4gICAgICAgICAgICBzaG93QmxvY2tzOiAnU2hvdyBibG9ja3MnLFxuICAgICAgICAgICAgY29kZVZpZXc6ICdDb2RlIHZpZXcnLFxuICAgICAgICAgICAgdW5kbzogJ1VuZG8nLFxuICAgICAgICAgICAgcmVkbzogJ1JlZG8nLFxuICAgICAgICAgICAgcHJldmlldzogJ1ByZXZpZXcnLFxuICAgICAgICAgICAgcHJpbnQ6ICdwcmludCcsXG4gICAgICAgICAgICB0YWdfcDogJ1BhcmFncmFwaCcsXG4gICAgICAgICAgICB0YWdfZGl2OiAnTm9ybWFsIChESVYpJyxcbiAgICAgICAgICAgIHRhZ19oOiAnSGVhZGVyJyxcbiAgICAgICAgICAgIHRhZ19ibG9ja3F1b3RlOiAnUXVvdGUnLFxuICAgICAgICAgICAgdGFnX3ByZTogJ0NvZGUnLFxuICAgICAgICAgICAgdGVtcGxhdGU6ICdUZW1wbGF0ZScsXG4gICAgICAgICAgICBsaW5lSGVpZ2h0OiAnTGluZSBoZWlnaHQnLFxuICAgICAgICAgICAgcGFyYWdyYXBoU3R5bGU6ICdQYXJhZ3JhcGggc3R5bGUnLFxuICAgICAgICAgICAgdGV4dFN0eWxlOiAnVGV4dCBzdHlsZScsXG4gICAgICAgICAgICBpbWFnZUdhbGxlcnk6ICdJbWFnZSBnYWxsZXJ5JyxcbiAgICAgICAgICAgIG1lbnRpb246ICdNZW50aW9uJ1xuICAgICAgICB9LFxuICAgICAgICBkaWFsb2dCb3g6IHtcbiAgICAgICAgICAgIGxpbmtCb3g6IHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ0luc2VydCBMaW5rJyxcbiAgICAgICAgICAgICAgICB1cmw6ICdVUkwgdG8gbGluaycsXG4gICAgICAgICAgICAgICAgdGV4dDogJ1RleHQgdG8gZGlzcGxheScsXG4gICAgICAgICAgICAgICAgbmV3V2luZG93Q2hlY2s6ICdPcGVuIGluIG5ldyB3aW5kb3cnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbWF0aEJveDoge1xuICAgICAgICAgICAgICAgIHRpdGxlOiAnTWF0aCcsXG4gICAgICAgICAgICAgICAgaW5wdXRMYWJlbDogJ01hdGhlbWF0aWNhbCBOb3RhdGlvbicsXG4gICAgICAgICAgICAgICAgZm9udFNpemVMYWJlbDogJ0ZvbnQgU2l6ZScsXG4gICAgICAgICAgICAgICAgcHJldmlld0xhYmVsOiAnUHJldmlldydcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpbWFnZUJveDoge1xuICAgICAgICAgICAgICAgIHRpdGxlOiAnSW5zZXJ0IGltYWdlJyxcbiAgICAgICAgICAgICAgICBmaWxlOiAnU2VsZWN0IGZyb20gZmlsZXMnLFxuICAgICAgICAgICAgICAgIHVybDogJ0ltYWdlIFVSTCcsXG4gICAgICAgICAgICAgICAgYWx0VGV4dDogJ0FsdGVybmF0aXZlIHRleHQnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmlkZW9Cb3g6IHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ0luc2VydCBWaWRlbycsXG4gICAgICAgICAgICAgICAgZmlsZTogJ1NlbGVjdCBmcm9tIGZpbGVzJyxcbiAgICAgICAgICAgICAgICB1cmw6ICdNZWRpYSBlbWJlZCBVUkwsIFlvdVR1YmUvVmltZW8nXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXVkaW9Cb3g6IHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ0luc2VydCBBdWRpbycsXG4gICAgICAgICAgICAgICAgZmlsZTogJ1NlbGVjdCBmcm9tIGZpbGVzJyxcbiAgICAgICAgICAgICAgICB1cmw6ICdBdWRpbyBVUkwnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYnJvd3Nlcjoge1xuICAgICAgICAgICAgICAgIHRhZ3M6ICdUYWdzJyxcbiAgICAgICAgICAgICAgICBzZWFyY2g6ICdTZWFyY2gnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNhcHRpb246ICdJbnNlcnQgZGVzY3JpcHRpb24nLFxuICAgICAgICAgICAgY2xvc2U6ICdDbG9zZScsXG4gICAgICAgICAgICBzdWJtaXRCdXR0b246ICdTdWJtaXQnLFxuICAgICAgICAgICAgcmV2ZXJ0QnV0dG9uOiAnUmV2ZXJ0JyxcbiAgICAgICAgICAgIHByb3BvcnRpb246ICdDb25zdHJhaW4gcHJvcG9ydGlvbnMnLFxuICAgICAgICAgICAgYmFzaWM6ICdCYXNpYycsXG4gICAgICAgICAgICBsZWZ0OiAnTGVmdCcsXG4gICAgICAgICAgICByaWdodDogJ1JpZ2h0JyxcbiAgICAgICAgICAgIGNlbnRlcjogJ0NlbnRlcicsXG4gICAgICAgICAgICB3aWR0aDogJ1dpZHRoJyxcbiAgICAgICAgICAgIGhlaWdodDogJ0hlaWdodCcsXG4gICAgICAgICAgICBzaXplOiAnU2l6ZScsXG4gICAgICAgICAgICByYXRpbzogJ1JhdGlvJ1xuICAgICAgICB9LFxuICAgICAgICBjb250cm9sbGVyOiB7XG4gICAgICAgICAgICBlZGl0OiAnRWRpdCcsXG4gICAgICAgICAgICB1bmxpbms6ICdVbmxpbmsnLFxuICAgICAgICAgICAgcmVtb3ZlOiAnUmVtb3ZlJyxcbiAgICAgICAgICAgIGluc2VydFJvd0Fib3ZlOiAnSW5zZXJ0IHJvdyBhYm92ZScsXG4gICAgICAgICAgICBpbnNlcnRSb3dCZWxvdzogJ0luc2VydCByb3cgYmVsb3cnLFxuICAgICAgICAgICAgZGVsZXRlUm93OiAnRGVsZXRlIHJvdycsXG4gICAgICAgICAgICBpbnNlcnRDb2x1bW5CZWZvcmU6ICdJbnNlcnQgY29sdW1uIGJlZm9yZScsXG4gICAgICAgICAgICBpbnNlcnRDb2x1bW5BZnRlcjogJ0luc2VydCBjb2x1bW4gYWZ0ZXInLFxuICAgICAgICAgICAgZGVsZXRlQ29sdW1uOiAnRGVsZXRlIGNvbHVtbicsXG4gICAgICAgICAgICBmaXhlZENvbHVtbldpZHRoOiAnRml4ZWQgY29sdW1uIHdpZHRoJyxcbiAgICAgICAgICAgIHJlc2l6ZTEwMDogJ1Jlc2l6ZSAxMDAlJyxcbiAgICAgICAgICAgIHJlc2l6ZTc1OiAnUmVzaXplIDc1JScsXG4gICAgICAgICAgICByZXNpemU1MDogJ1Jlc2l6ZSA1MCUnLFxuICAgICAgICAgICAgcmVzaXplMjU6ICdSZXNpemUgMjUlJyxcbiAgICAgICAgICAgIGF1dG9TaXplOiAnQXV0byBzaXplJyxcbiAgICAgICAgICAgIG1pcnJvckhvcml6b250YWw6ICdNaXJyb3IsIEhvcml6b250YWwnLFxuICAgICAgICAgICAgbWlycm9yVmVydGljYWw6ICdNaXJyb3IsIFZlcnRpY2FsJyxcbiAgICAgICAgICAgIHJvdGF0ZUxlZnQ6ICdSb3RhdGUgbGVmdCcsXG4gICAgICAgICAgICByb3RhdGVSaWdodDogJ1JvdGF0ZSByaWdodCcsXG4gICAgICAgICAgICBtYXhTaXplOiAnTWF4IHNpemUnLFxuICAgICAgICAgICAgbWluU2l6ZTogJ01pbiBzaXplJyxcbiAgICAgICAgICAgIHRhYmxlSGVhZGVyOiAnVGFibGUgaGVhZGVyJyxcbiAgICAgICAgICAgIG1lcmdlQ2VsbHM6ICdNZXJnZSBjZWxscycsXG4gICAgICAgICAgICBzcGxpdENlbGxzOiAnU3BsaXQgQ2VsbHMnLFxuICAgICAgICAgICAgSG9yaXpvbnRhbFNwbGl0OiAnSG9yaXpvbnRhbCBzcGxpdCcsXG4gICAgICAgICAgICBWZXJ0aWNhbFNwbGl0OiAnVmVydGljYWwgc3BsaXQnXG4gICAgICAgIH0sXG4gICAgICAgIG1lbnU6IHtcbiAgICAgICAgICAgIHNwYWNlZDogJ1NwYWNlZCcsXG4gICAgICAgICAgICBib3JkZXJlZDogJ0JvcmRlcmVkJyxcbiAgICAgICAgICAgIG5lb246ICdOZW9uJyxcbiAgICAgICAgICAgIHRyYW5zbHVjZW50OiAnVHJhbnNsdWNlbnQnLFxuICAgICAgICAgICAgc2hhZG93OiAnU2hhZG93JyxcbiAgICAgICAgICAgIGNvZGU6ICdDb2RlJ1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGlmICh0eXBlb2Ygbm9HbG9iYWwgPT09IHR5cGVvZiB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCF3aW5kb3cuU1VORURJVE9SX0xBTkcpIHtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3csICdTVU5FRElUT1JfTEFORycsIHtcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB7fVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LlNVTkVESVRPUl9MQU5HLCAnZW4nLCB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICB2YWx1ZTogbGFuZ1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbGFuZztcbn0pKTsiLCIvKlxyXG4gKiB3eXNpd3lnIHdlYiBlZGl0b3JcclxuICpcclxuICogc3VuZWRpdG9yLmpzXHJcbiAqIENvcHlyaWdodCAyMDE4IEppSG9uZyBMZWUuXHJcbiAqIE1JVCBsaWNlbnNlLlxyXG4gKi9cclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgbmFtZTogJ2NvbG9yUGlja2VyJyxcclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIENvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gY29yZSBDb3JlIG9iamVjdCBcclxuICAgICAqL1xyXG4gICAgYWRkOiBmdW5jdGlvbiAoY29yZSkge1xyXG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBjb3JlLmNvbnRleHQ7XHJcbiAgICAgICAgY29udGV4dC5jb2xvclBpY2tlciA9IHtcclxuICAgICAgICAgICAgY29sb3JMaXN0SFRNTDogJycsXHJcbiAgICAgICAgICAgIF9jb2xvcklucHV0OiAnJyxcclxuICAgICAgICAgICAgX2RlZmF1bHRDb2xvcjogJyMwMDAnLFxyXG4gICAgICAgICAgICBfc3R5bGVQcm9wZXJ0eTogJ2NvbG9yJyxcclxuICAgICAgICAgICAgX2N1cnJlbnRDb2xvcjogJycsXHJcbiAgICAgICAgICAgIF9jb2xvckxpc3Q6IFtdXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqIHNldCBzdWJtZW51ICovXHJcbiAgICAgICAgbGV0IGxpc3REaXYgPSB0aGlzLmNyZWF0ZUNvbG9yTGlzdChjb3JlLCB0aGlzLl9tYWtlQ29sb3JMaXN0KTtcclxuXHJcbiAgICAgICAgLyoqIGNhY2hpbmcgKi9cclxuICAgICAgICBjb250ZXh0LmNvbG9yUGlja2VyLmNvbG9yTGlzdEhUTUwgPSBsaXN0RGl2O1xyXG5cclxuICAgICAgICAvKiogZW1wdHkgbWVtb3J5ICovXHJcbiAgICAgICAgbGlzdERpdiA9IG51bGw7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIENyZWF0ZSBjb2xvciBsaXN0XHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gY29yZSBDb3JlIG9iamVjdCBcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG1ha2VDb2xvciB0aGlzLl9tYWtlQ29sb3JMaXN0XHJcbiAgICAgKiBAcmV0dXJucyB7U3RyaW5nfSBIVE1MIHN0cmluZ1xyXG4gICAgICovXHJcbiAgICBjcmVhdGVDb2xvckxpc3Q6IGZ1bmN0aW9uIChjb3JlLCBtYWtlQ29sb3IpIHtcclxuICAgICAgICBjb25zdCBvcHRpb24gPSBjb3JlLmNvbnRleHQub3B0aW9uO1xyXG4gICAgICAgIGNvbnN0IGxhbmcgPSBjb3JlLmxhbmc7XHJcbiAgICAgICAgY29uc3QgY29sb3JMaXN0ID0gIW9wdGlvbi5jb2xvckxpc3QgfHwgb3B0aW9uLmNvbG9yTGlzdC5sZW5ndGggPT09IDAgP1xyXG4gICAgICAgICAgICBbXHJcbiAgICAgICAgICAgICAgICAnI2ZmMDAwMCcsICcjZmY1ZTAwJywgJyNmZmU0MDAnLCAnI2FiZjIwMCcsICcjMDBkOGZmJywgJyMwMDU1ZmYnLCAnIzY2MDBmZicsICcjZmYwMGRkJywgJyMwMDAwMDAnLFxyXG4gICAgICAgICAgICAgICAgJyNmZmQ4ZDgnLCAnI2ZhZTBkNCcsICcjZmFmNGMwJywgJyNlNGY3YmEnLCAnI2Q0ZjRmYScsICcjZDllNWZmJywgJyNlOGQ5ZmYnLCAnI2ZmZDlmYScsICcjZjFmMWYxJyxcclxuICAgICAgICAgICAgICAgICcjZmZhN2E3JywgJyNmZmMxOWUnLCAnI2ZhZWQ3ZCcsICcjY2VmMjc5JywgJyNiMmViZjQnLCAnI2IyY2NmZicsICcjZDFiMmZmJywgJyNmZmIyZjUnLCAnI2JkYmRiZCcsXHJcbiAgICAgICAgICAgICAgICAnI2YxNWY1ZicsICcjZjI5NjYxJywgJyNlNWQ4NWMnLCAnI2JjZTU1YycsICcjNWNkMWU1JywgJyM2Njk5ZmYnLCAnI2EzNjZmZicsICcjZjI2MWRmJywgJyM4YzhjOGMnLFxyXG4gICAgICAgICAgICAgICAgJyM5ODAwMDAnLCAnIzk5MzgwMCcsICcjOTk4YTAwJywgJyM2Yjk5MDAnLCAnIzAwODI5OScsICcjMDAzMzk5JywgJyMzZDAwOTknLCAnIzk5MDA4NScsICcjMzUzNTM1JyxcclxuICAgICAgICAgICAgICAgICcjNjcwMDAwJywgJyM2NjI1MDAnLCAnIzY2NWMwMCcsICcjNDc2NjAwJywgJyMwMDU3NjYnLCAnIzAwMjI2NicsICcjMjkwMDY2JywgJyM2NjAwNTgnLCAnIzIyMjIyMidcclxuICAgICAgICAgICAgXSA6IG9wdGlvbi5jb2xvckxpc3Q7XHJcblxyXG4gICAgICAgIGxldCBjb2xvckFyciA9IFtdO1xyXG4gICAgICAgIGxldCBsaXN0ID0gJzxkaXYgY2xhc3M9XCJzZS1saXN0LWlubmVyXCI+JztcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNvbG9yTGlzdC5sZW5ndGgsIGNvbG9yOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGNvbG9yID0gY29sb3JMaXN0W2ldO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFjb2xvcikgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29sb3IgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29sb3JBcnIucHVzaChjb2xvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCBsZW4gLSAxKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChjb2xvckFyci5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGlzdCArPSAnPGRpdiBjbGFzcz1cInNlLXNlbGVjdG9yLWNvbG9yXCI+JyArIG1ha2VDb2xvcihjb2xvckFycikgKyAnPC9kaXY+JztcclxuICAgICAgICAgICAgICAgICAgICBjb2xvckFyciA9IFtdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjb2xvciA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgICAgICAgICAgICBsaXN0ICs9ICc8ZGl2IGNsYXNzPVwic2Utc2VsZWN0b3ItY29sb3JcIj4nICsgbWFrZUNvbG9yKGNvbG9yKSArICc8L2Rpdj4nO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGxpc3QgKz0gJycgK1xyXG4gICAgICAgICAgICAnPGZvcm0gY2xhc3M9XCJzZS1zdWJtZW51LWZvcm0tZ3JvdXBcIj4nICtcclxuICAgICAgICAgICAgICAgICc8aW5wdXQgdHlwZT1cInRleHRcIiBtYXhsZW5ndGg9XCI5XCIgY2xhc3M9XCJfc2VfY29sb3JfcGlja2VyX2lucHV0IHNlLWNvbG9yLWlucHV0XCIvPicgK1xyXG4gICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cInN1Ym1pdFwiIGNsYXNzPVwic2UtYnRuLXByaW1hcnkgX3NlX2NvbG9yX3BpY2tlcl9zdWJtaXRcIiB0aXRsZT1cIicgKyBsYW5nLmRpYWxvZ0JveC5zdWJtaXRCdXR0b24gKyAnXCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgY29yZS5pY29ucy5jaGVja2VkICtcclxuICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcclxuICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNlLWJ0biBfc2VfY29sb3JfcGlja2VyX3JlbW92ZVwiIHRpdGxlPVwiJyArIGxhbmcudG9vbGJhci5yZW1vdmVGb3JtYXQgKyAnXCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgY29yZS5pY29ucy5lcmFzZSArXHJcbiAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXHJcbiAgICAgICAgICAgICc8L2Zvcm0+JyArXHJcbiAgICAgICAgICAgICc8L2Rpdj4nO1xyXG5cclxuICAgICAgICByZXR1cm4gbGlzdDtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gSW50ZXJuYWwgZnVuY3Rpb24gdXNlZCBieSB0aGlzLmNyZWF0ZUNvbG9yTGlzdFxyXG4gICAgICogQHBhcmFtIHtBcnJheX0gY29sb3JMaXN0IENvbG9yIGxpc3RcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9tYWtlQ29sb3JMaXN0OiBmdW5jdGlvbiAoY29sb3JMaXN0KSB7XHJcbiAgICAgICAgbGV0IGxpc3QgPSAnJztcclxuXHJcbiAgICAgICAgbGlzdCArPSAnPHVsIGNsYXNzPVwic2UtY29sb3ItcGFsbGV0XCI+JztcclxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gY29sb3JMaXN0Lmxlbmd0aCwgY29sb3I7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICBjb2xvciA9IGNvbG9yTGlzdFtpXTtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBjb2xvciA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgICAgIGxpc3QgKz0gJzxsaT4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLXZhbHVlPVwiJyArIGNvbG9yICsgJ1wiIHRpdGxlPVwiJyArIGNvbG9yICsgJ1wiIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjonICsgY29sb3IgKyAnO1wiPjwvYnV0dG9uPicgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAnPC9saT4nO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxpc3QgKz0gJzwvdWw+JztcclxuXHJcbiAgICAgICAgcmV0dXJuIGxpc3Q7XHJcbiAgICB9LFxyXG4gICAgXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBEaXNwbGF5cyBvciByZXNldHMgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBjb2xvciBhdCBjb2xvciBsaXN0LlxyXG4gICAgICogQHBhcmFtIHtOb2RlfSBub2RlIEN1cnJlbnQgU2VsZWN0ZWQgbm9kZVxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd8bnVsbH0gY29sb3IgQ29sb3IgdmFsdWVcclxuICAgICAqL1xyXG4gICAgaW5pdDogZnVuY3Rpb24gKG5vZGUsIGNvbG9yKSB7XHJcbiAgICAgICAgY29uc3QgY29sb3JQaWNrZXIgPSB0aGlzLnBsdWdpbnMuY29sb3JQaWNrZXI7XHJcbiAgICAgICAgbGV0IGZpbGxDb2xvciA9IGNvbG9yID8gY29sb3IgOiBjb2xvclBpY2tlci5nZXRDb2xvckluTm9kZS5jYWxsKHRoaXMsIG5vZGUpIHx8IHRoaXMuY29udGV4dC5jb2xvclBpY2tlci5fZGVmYXVsdENvbG9yO1xyXG4gICAgICAgIGZpbGxDb2xvciA9IGNvbG9yUGlja2VyLmlzSGV4Q29sb3IoZmlsbENvbG9yKSA/IGZpbGxDb2xvciA6IGNvbG9yUGlja2VyLnJnYjJoZXgoZmlsbENvbG9yKSB8fCBmaWxsQ29sb3I7XHJcblxyXG4gICAgICAgIGNvbnN0IGNvbG9yTGlzdCA9IHRoaXMuY29udGV4dC5jb2xvclBpY2tlci5fY29sb3JMaXN0O1xyXG4gICAgICAgIGlmIChjb2xvckxpc3QpIHtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNvbG9yTGlzdC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgaWYgKGZpbGxDb2xvci50b0xvd2VyQ2FzZSgpID09PSBjb2xvckxpc3RbaV0uZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJykudG9Mb3dlckNhc2UoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbC5hZGRDbGFzcyhjb2xvckxpc3RbaV0sICdhY3RpdmUnKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUNsYXNzKGNvbG9yTGlzdFtpXSwgJ2FjdGl2ZScpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb2xvclBpY2tlci5zZXRJbnB1dFRleHQuY2FsbCh0aGlzLCBjb2xvclBpY2tlci5jb2xvck5hbWUyaGV4LmNhbGwodGhpcywgZmlsbENvbG9yKSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFN0b3JlIGNvbG9yIHZhbHVlc1xyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGhleENvbG9yU3RyIEhheCBjb2xvciB2YWx1ZVxyXG4gICAgICovXHJcbiAgICBzZXRDdXJyZW50Q29sb3I6IGZ1bmN0aW9uIChoZXhDb2xvclN0cikge1xyXG4gICAgICAgIHRoaXMuY29udGV4dC5jb2xvclBpY2tlci5fY3VycmVudENvbG9yID0gaGV4Q29sb3JTdHI7XHJcbiAgICAgICAgdGhpcy5jb250ZXh0LmNvbG9yUGlja2VyLl9jb2xvcklucHV0LnN0eWxlLmJvcmRlckNvbG9yID0gaGV4Q29sb3JTdHI7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFNldCBjb2xvciBhdCBpbnB1dCBlbGVtZW50XHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gaGV4Q29sb3JTdHIgSGF4IGNvbG9yIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIHNldElucHV0VGV4dDogZnVuY3Rpb24gKGhleENvbG9yU3RyKSB7XHJcbiAgICAgICAgaGV4Q29sb3JTdHIgPSAvXiMvLnRlc3QoaGV4Q29sb3JTdHIpID8gaGV4Q29sb3JTdHIgOiAnIycgKyBoZXhDb2xvclN0cjtcclxuICAgICAgICB0aGlzLmNvbnRleHQuY29sb3JQaWNrZXIuX2NvbG9ySW5wdXQudmFsdWUgPSBoZXhDb2xvclN0cjtcclxuICAgICAgICB0aGlzLnBsdWdpbnMuY29sb3JQaWNrZXIuc2V0Q3VycmVudENvbG9yLmNhbGwodGhpcywgaGV4Q29sb3JTdHIpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBHZXRzIGNvbG9yIHZhbHVlIGF0IGNvbG9yIHByb3BlcnR5IG9mIG5vZGVcclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBTZWxlY3RlZCBub2RlIFxyXG4gICAgICogQHJldHVybnMge1N0cmluZ31cclxuICAgICAqL1xyXG4gICAgZ2V0Q29sb3JJbk5vZGU6IGZ1bmN0aW9uIChub2RlKSB7XHJcbiAgICAgICAgbGV0IGZpbmRDb2xvciA9ICcnO1xyXG4gICAgICAgIGNvbnN0IHN0eWxlUHJvcGVydHkgPSB0aGlzLmNvbnRleHQuY29sb3JQaWNrZXIuX3N0eWxlUHJvcGVydHk7XHJcblxyXG4gICAgICAgIHdoaWxlIChub2RlICYmICF0aGlzLnV0aWwuaXNXeXNpd3lnRGl2KG5vZGUpICYmIGZpbmRDb2xvci5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IDEgJiYgbm9kZS5zdHlsZVtzdHlsZVByb3BlcnR5XSkgZmluZENvbG9yID0gbm9kZS5zdHlsZVtzdHlsZVByb3BlcnR5XTtcclxuICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBmaW5kQ29sb3I7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIEZ1bmN0aW9uIHRvIGNoZWNrIGhleCBmb3JtYXQgY29sb3JcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgQ29sb3IgdmFsdWVcclxuICAgICAqL1xyXG4gICAgaXNIZXhDb2xvcjogZnVuY3Rpb24gKHN0cikge1xyXG4gICAgICAgIHJldHVybiAvXiNbMC05YS1mXXszfSg/OlswLTlhLWZdezN9KT8kL2kudGVzdChzdHIpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBGdW5jdGlvbiB0byBjb252ZXJ0IGhleCBmb3JtYXQgdG8gYSByZ2IgY29sb3JcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSByZ2IgUkdCIGNvbG9yIGZvcm1hdFxyXG4gICAgICogQHJldHVybnMge1N0cmluZ31cclxuICAgICAqL1xyXG4gICAgcmdiMmhleDogZnVuY3Rpb24gKHJnYikge1xyXG4gICAgICAgIGNvbnN0IHJnYk1hdGNoID0gcmdiLm1hdGNoKC9ecmdiYT9bXFxzK10/XFwoW1xccytdPyhcXGQrKVtcXHMrXT8sW1xccytdPyhcXGQrKVtcXHMrXT8sW1xccytdPyhcXGQrKVtcXHMrXT8vaSk7XHJcblxyXG4gICAgICAgIHJldHVybiAocmdiTWF0Y2ggJiYgcmdiTWF0Y2gubGVuZ3RoID09PSA0KSA/IFwiI1wiICtcclxuICAgICAgICAgICAgKFwiMFwiICsgcGFyc2VJbnQocmdiTWF0Y2hbMV0sMTApLnRvU3RyaW5nKDE2KSkuc2xpY2UoLTIpICtcclxuICAgICAgICAgICAgKFwiMFwiICsgcGFyc2VJbnQocmdiTWF0Y2hbMl0sMTApLnRvU3RyaW5nKDE2KSkuc2xpY2UoLTIpICtcclxuICAgICAgICAgICAgKFwiMFwiICsgcGFyc2VJbnQocmdiTWF0Y2hbM10sMTApLnRvU3RyaW5nKDE2KSkuc2xpY2UoLTIpIDogJyc7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIENvbnZlcnRzIGNvbG9yIHZhbHVlcyBvZiBvdGhlciBmb3JtYXRzIHRvIGhleCBjb2xvciB2YWx1ZXMgYW5kIHJldHVybnMuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gY29sb3JOYW1lIENvbG9yIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7U3RyaW5nfVxyXG4gICAgICovXHJcbiAgICBjb2xvck5hbWUyaGV4OiBmdW5jdGlvbiAoY29sb3JOYW1lKSB7XHJcbiAgICAgICAgaWYgKC9eIy8udGVzdChjb2xvck5hbWUpKSByZXR1cm4gY29sb3JOYW1lO1xyXG4gICAgICAgIHZhciB0ZW1wID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xyXG4gICAgICAgIHRlbXAuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICB0ZW1wLnN0eWxlLmNvbG9yID0gY29sb3JOYW1lO1xyXG4gICAgICAgIHZhciBjb2xvcnMgPSB0aGlzLl93LmdldENvbXB1dGVkU3R5bGUodGhpcy5fZC5ib2R5LmFwcGVuZENoaWxkKHRlbXApKS5jb2xvci5tYXRjaCgvXFxkKy9nKS5tYXAoZnVuY3Rpb24gKGEpIHsgcmV0dXJuIHBhcnNlSW50KGEsMTApOyB9KTtcclxuICAgICAgICB0aGlzLnV0aWwucmVtb3ZlSXRlbSh0ZW1wKTtcclxuICAgICAgICByZXR1cm4gKGNvbG9ycy5sZW5ndGggPj0gMykgPyAnIycgKyAoKCgxIDw8IDI0KSArIChjb2xvcnNbMF0gPDwgMTYpICsgKGNvbG9yc1sxXSA8PCA4KSArIGNvbG9yc1syXSkudG9TdHJpbmcoMTYpLnN1YnN0cigxKSkgOiBmYWxzZTtcclxuICAgIH1cclxufTsiLCIvKlxyXG4gKiB3eXNpd3lnIHdlYiBlZGl0b3JcclxuICpcclxuICogc3VuZWRpdG9yLmpzXHJcbiAqIENvcHlyaWdodCAyMDE3IEppSG9uZyBMZWUuXHJcbiAqIE1JVCBsaWNlbnNlLlxyXG4gKi9cclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuaW1wb3J0IGNvbG9yUGlja2VyIGZyb20gJy4uL21vZHVsZXMvX2NvbG9yUGlja2VyJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIG5hbWU6ICdmb250Q29sb3InLFxyXG4gICAgZGlzcGxheTogJ3N1Ym1lbnUnLFxyXG4gICAgYWRkOiBmdW5jdGlvbiAoY29yZSwgdGFyZ2V0RWxlbWVudCkge1xyXG4gICAgICAgIGNvcmUuYWRkTW9kdWxlKFtjb2xvclBpY2tlcl0pO1xyXG5cclxuICAgICAgICBjb25zdCBjb250ZXh0ID0gY29yZS5jb250ZXh0O1xyXG4gICAgICAgIGNvbnRleHQuZm9udENvbG9yID0ge1xyXG4gICAgICAgICAgICBwcmV2aWV3RWw6IG51bGwsXHJcbiAgICAgICAgICAgIGNvbG9ySW5wdXQ6IG51bGwsXHJcbiAgICAgICAgICAgIGNvbG9yTGlzdDogbnVsbFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKiBzZXQgc3VibWVudSAqL1xyXG4gICAgICAgIGxldCBsaXN0RGl2ID0gdGhpcy5zZXRTdWJtZW51LmNhbGwoY29yZSk7XHJcbiAgICAgICAgY29udGV4dC5mb250Q29sb3IuY29sb3JJbnB1dCA9IGxpc3REaXYucXVlcnlTZWxlY3RvcignLl9zZV9jb2xvcl9waWNrZXJfaW5wdXQnKTtcclxuXHJcbiAgICAgICAgLyoqIGFkZCBldmVudCBsaXN0ZW5lcnMgKi9cclxuICAgICAgICBjb250ZXh0LmZvbnRDb2xvci5jb2xvcklucHV0LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgdGhpcy5vbkNoYW5nZUlucHV0LmJpbmQoY29yZSkpO1xyXG4gICAgICAgIGxpc3REaXYucXVlcnlTZWxlY3RvcignLl9zZV9jb2xvcl9waWNrZXJfc3VibWl0JykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLnN1Ym1pdC5iaW5kKGNvcmUpKTtcclxuICAgICAgICBsaXN0RGl2LnF1ZXJ5U2VsZWN0b3IoJy5fc2VfY29sb3JfcGlja2VyX3JlbW92ZScpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5yZW1vdmUuYmluZChjb3JlKSk7XHJcbiAgICAgICAgbGlzdERpdi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMucGlja3VwLmJpbmQoY29yZSkpO1xyXG4gICAgICAgIGNvbnRleHQuZm9udENvbG9yLmNvbG9yTGlzdCA9IGxpc3REaXYucXVlcnlTZWxlY3RvckFsbCgnbGkgYnV0dG9uJyk7XHJcblxyXG4gICAgICAgIC8qKiBhcHBlbmQgdGFyZ2V0IGJ1dHRvbiBtZW51ICovXHJcbiAgICAgICAgY29yZS5pbml0TWVudVRhcmdldCh0aGlzLm5hbWUsIHRhcmdldEVsZW1lbnQsIGxpc3REaXYpO1xyXG5cclxuICAgICAgICAvKiogZW1wdHkgbWVtb3J5ICovXHJcbiAgICAgICAgbGlzdERpdiA9IG51bGw7XHJcbiAgICB9LFxyXG5cclxuICAgIHNldFN1Ym1lbnU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBjb25zdCBjb2xvckFyZWEgPSB0aGlzLmNvbnRleHQuY29sb3JQaWNrZXIuY29sb3JMaXN0SFRNTDtcclxuICAgICAgICBjb25zdCBsaXN0RGl2ID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xyXG5cclxuICAgICAgICBsaXN0RGl2LmNsYXNzTmFtZSA9ICdzZS1zdWJtZW51IHNlLWxpc3QtbGF5ZXInO1xyXG4gICAgICAgIGxpc3REaXYuaW5uZXJIVE1MID0gY29sb3JBcmVhO1xyXG5cclxuICAgICAgICByZXR1cm4gbGlzdERpdjtcclxuICAgIH0sXHJcblxyXG4gICAgIC8qKlxyXG4gICAgICogQE92ZXJyaWRlIHN1Ym1lbnVcclxuICAgICAqL1xyXG4gICAgb246IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBjb25zdCBjb250ZXh0UGlja2VyID0gdGhpcy5jb250ZXh0LmNvbG9yUGlja2VyO1xyXG4gICAgICAgIGNvbnN0IGNvbnRleHRGb250Q29sb3IgPSB0aGlzLmNvbnRleHQuZm9udENvbG9yO1xyXG5cclxuICAgICAgICBjb250ZXh0UGlja2VyLl9jb2xvcklucHV0ID0gY29udGV4dEZvbnRDb2xvci5jb2xvcklucHV0O1xyXG4gICAgICAgIGNvbnRleHRQaWNrZXIuX2RlZmF1bHRDb2xvciA9ICcjMzMzMzMzJztcclxuICAgICAgICBjb250ZXh0UGlja2VyLl9zdHlsZVByb3BlcnR5ID0gJ2NvbG9yJztcclxuICAgICAgICBjb250ZXh0UGlja2VyLl9jb2xvckxpc3QgPSBjb250ZXh0Rm9udENvbG9yLmNvbG9yTGlzdDtcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLnBsdWdpbnMuY29sb3JQaWNrZXIuaW5pdC5jYWxsKHRoaXMsIHRoaXMuZ2V0U2VsZWN0aW9uTm9kZSgpLCBudWxsKTtcclxuICAgIH0sXHJcblxyXG4gICAgIC8qKlxyXG4gICAgICogQE92ZXJyaWRlIF9jb2xvclBpY2tlclxyXG4gICAgICovXHJcbiAgICBvbkNoYW5nZUlucHV0OiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgIHRoaXMucGx1Z2lucy5jb2xvclBpY2tlci5zZXRDdXJyZW50Q29sb3IuY2FsbCh0aGlzLCBlLnRhcmdldC52YWx1ZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHN1Ym1pdDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMucGx1Z2lucy5mb250Q29sb3IuYXBwbHlDb2xvci5jYWxsKHRoaXMsIHRoaXMuY29udGV4dC5jb2xvclBpY2tlci5fY3VycmVudENvbG9yKTtcclxuICAgIH0sXHJcblxyXG4gICAgcGlja3VwOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cclxuICAgICAgICB0aGlzLnBsdWdpbnMuZm9udENvbG9yLmFwcGx5Q29sb3IuY2FsbCh0aGlzLCBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnKSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHJlbW92ZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMubm9kZUNoYW5nZShudWxsLCBbJ2NvbG9yJ10sIFsnc3BhbiddLCB0cnVlKTtcclxuICAgICAgICB0aGlzLnN1Ym1lbnVPZmYoKTtcclxuICAgIH0sXHJcblxyXG4gICAgYXBwbHlDb2xvcjogZnVuY3Rpb24gKGNvbG9yKSB7XHJcbiAgICAgICAgaWYgKCFjb2xvcikgcmV0dXJuO1xyXG5cclxuICAgICAgICBjb25zdCBuZXdOb2RlID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ1NQQU4nKTtcclxuICAgICAgICBuZXdOb2RlLnN0eWxlLmNvbG9yID0gY29sb3I7XHJcbiAgICAgICAgdGhpcy5ub2RlQ2hhbmdlKG5ld05vZGUsIFsnY29sb3InXSwgbnVsbCwgbnVsbCk7XHJcblxyXG4gICAgICAgIHRoaXMuc3VibWVudU9mZigpO1xyXG4gICAgfVxyXG59O1xyXG4iLCIvKlxyXG4gKiB3eXNpd3lnIHdlYiBlZGl0b3JcclxuICpcclxuICogc3VuZWRpdG9yLmpzXHJcbiAqIENvcHlyaWdodCAyMDE3IEppSG9uZyBMZWUuXHJcbiAqIE1JVCBsaWNlbnNlLlxyXG4gKi9cclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuaW1wb3J0IGNvbG9yUGlja2VyIGZyb20gJy4uL21vZHVsZXMvX2NvbG9yUGlja2VyJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIG5hbWU6ICdoaWxpdGVDb2xvcicsXHJcbiAgICBkaXNwbGF5OiAnc3VibWVudScsXHJcbiAgICBhZGQ6IGZ1bmN0aW9uIChjb3JlLCB0YXJnZXRFbGVtZW50KSB7XHJcbiAgICAgICAgY29yZS5hZGRNb2R1bGUoW2NvbG9yUGlja2VyXSk7XHJcblxyXG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBjb3JlLmNvbnRleHQ7XHJcbiAgICAgICAgY29udGV4dC5oaWxpdGVDb2xvciA9IHtcclxuICAgICAgICAgICAgcHJldmlld0VsOiBudWxsLFxyXG4gICAgICAgICAgICBjb2xvcklucHV0OiBudWxsLFxyXG4gICAgICAgICAgICBjb2xvckxpc3Q6IG51bGxcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKiogc2V0IHN1Ym1lbnUgKi9cclxuICAgICAgICBsZXQgbGlzdERpdiA9IHRoaXMuc2V0U3VibWVudS5jYWxsKGNvcmUpO1xyXG4gICAgICAgIGNvbnRleHQuaGlsaXRlQ29sb3IuY29sb3JJbnB1dCA9IGxpc3REaXYucXVlcnlTZWxlY3RvcignLl9zZV9jb2xvcl9waWNrZXJfaW5wdXQnKTtcclxuXHJcbiAgICAgICAgLyoqIGFkZCBldmVudCBsaXN0ZW5lcnMgKi9cclxuICAgICAgICBjb250ZXh0LmhpbGl0ZUNvbG9yLmNvbG9ySW5wdXQuYWRkRXZlbnRMaXN0ZW5lcigna2V5dXAnLCB0aGlzLm9uQ2hhbmdlSW5wdXQuYmluZChjb3JlKSk7XHJcbiAgICAgICAgbGlzdERpdi5xdWVyeVNlbGVjdG9yKCcuX3NlX2NvbG9yX3BpY2tlcl9zdWJtaXQnKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuc3VibWl0LmJpbmQoY29yZSkpO1xyXG4gICAgICAgIGxpc3REaXYucXVlcnlTZWxlY3RvcignLl9zZV9jb2xvcl9waWNrZXJfcmVtb3ZlJykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLnJlbW92ZS5iaW5kKGNvcmUpKTtcclxuICAgICAgICBsaXN0RGl2LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5waWNrdXAuYmluZChjb3JlKSk7XHJcblxyXG4gICAgICAgIGNvbnRleHQuaGlsaXRlQ29sb3IuY29sb3JMaXN0ID0gbGlzdERpdi5xdWVyeVNlbGVjdG9yQWxsKCdsaSBidXR0b24nKTtcclxuXHJcbiAgICAgICAgLyoqIGFwcGVuZCB0YXJnZXQgYnV0dG9uIG1lbnUgKi9cclxuICAgICAgICBjb3JlLmluaXRNZW51VGFyZ2V0KHRoaXMubmFtZSwgdGFyZ2V0RWxlbWVudCwgbGlzdERpdik7XHJcblxyXG4gICAgICAgIC8qKiBlbXB0eSBtZW1vcnkgKi9cclxuICAgICAgICBsaXN0RGl2ID0gbnVsbDtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0U3VibWVudTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGNvbnN0IGNvbG9yQXJlYSA9IHRoaXMuY29udGV4dC5jb2xvclBpY2tlci5jb2xvckxpc3RIVE1MO1xyXG4gICAgICAgIGNvbnN0IGxpc3REaXYgPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XHJcblxyXG4gICAgICAgIGxpc3REaXYuY2xhc3NOYW1lID0gJ3NlLXN1Ym1lbnUgc2UtbGlzdC1sYXllcic7XHJcbiAgICAgICAgbGlzdERpdi5pbm5lckhUTUwgPSBjb2xvckFyZWE7XHJcblxyXG4gICAgICAgIHJldHVybiBsaXN0RGl2O1xyXG4gICAgfSxcclxuXHJcbiAgICAgLyoqXHJcbiAgICAgKiBAT3ZlcnJpZGUgc3VibWVudVxyXG4gICAgICovXHJcbiAgICBvbjogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGNvbnN0IGNvbnRleHRQaWNrZXIgPSB0aGlzLmNvbnRleHQuY29sb3JQaWNrZXI7XHJcbiAgICAgICAgY29uc3QgY29udGV4dEhpbGl0ZUNvbG9yID0gdGhpcy5jb250ZXh0LmhpbGl0ZUNvbG9yO1xyXG5cclxuICAgICAgICBjb250ZXh0UGlja2VyLl9jb2xvcklucHV0ID0gY29udGV4dEhpbGl0ZUNvbG9yLmNvbG9ySW5wdXQ7XHJcbiAgICAgICAgY29udGV4dFBpY2tlci5fZGVmYXVsdENvbG9yID0gJyNGRkZGRkYnO1xyXG4gICAgICAgIGNvbnRleHRQaWNrZXIuX3N0eWxlUHJvcGVydHkgPSAnYmFja2dyb3VuZENvbG9yJztcclxuICAgICAgICBjb250ZXh0UGlja2VyLl9jb2xvckxpc3QgPSBjb250ZXh0SGlsaXRlQ29sb3IuY29sb3JMaXN0O1xyXG4gICAgICAgIFxyXG4gICAgICAgIHRoaXMucGx1Z2lucy5jb2xvclBpY2tlci5pbml0LmNhbGwodGhpcywgdGhpcy5nZXRTZWxlY3Rpb25Ob2RlKCksIG51bGwpO1xyXG4gICAgfSxcclxuXHJcbiAgICAgLyoqXHJcbiAgICAgKiBAT3ZlcnJpZGUgX2NvbG9yUGlja2VyXHJcbiAgICAgKi9cclxuICAgIG9uQ2hhbmdlSW5wdXQ6IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgdGhpcy5wbHVnaW5zLmNvbG9yUGlja2VyLnNldEN1cnJlbnRDb2xvci5jYWxsKHRoaXMsIGUudGFyZ2V0LnZhbHVlKTtcclxuICAgIH0sXHJcblxyXG4gICAgc3VibWl0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5wbHVnaW5zLmhpbGl0ZUNvbG9yLmFwcGx5Q29sb3IuY2FsbCh0aGlzLCB0aGlzLmNvbnRleHQuY29sb3JQaWNrZXIuX2N1cnJlbnRDb2xvcik7XHJcbiAgICB9LFxyXG5cclxuICAgIHBpY2t1cDogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHJcbiAgICAgICAgdGhpcy5wbHVnaW5zLmhpbGl0ZUNvbG9yLmFwcGx5Q29sb3IuY2FsbCh0aGlzLCBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnKSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHJlbW92ZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMubm9kZUNoYW5nZShudWxsLCBbJ2JhY2tncm91bmQtY29sb3InXSwgWydzcGFuJ10sIHRydWUpO1xyXG4gICAgICAgIHRoaXMuc3VibWVudU9mZigpO1xyXG4gICAgfSxcclxuXHJcbiAgICBhcHBseUNvbG9yOiBmdW5jdGlvbiAoY29sb3IpIHtcclxuICAgICAgICBpZiAoIWNvbG9yKSByZXR1cm47XHJcbiAgICAgICAgXHJcbiAgICAgICAgY29uc3QgbmV3Tm9kZSA9IHRoaXMudXRpbC5jcmVhdGVFbGVtZW50KCdTUEFOJyk7XHJcbiAgICAgICAgbmV3Tm9kZS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBjb2xvcjtcclxuICAgICAgICB0aGlzLm5vZGVDaGFuZ2UobmV3Tm9kZSwgWydiYWNrZ3JvdW5kLWNvbG9yJ10sIG51bGwsIG51bGwpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHRoaXMuc3VibWVudU9mZigpO1xyXG4gICAgfVxyXG59O1xyXG4iLCIvKlxuICogd3lzaXd5ZyB3ZWIgZWRpdG9yXG4gKlxuICogc3VuZWRpdG9yLmpzXG4gKiBDb3B5cmlnaHQgMjAxNyBKaUhvbmcgTGVlLlxuICogTUlUIGxpY2Vuc2UuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIG5hbWU6ICd0ZW1wbGF0ZScsXG4gICAgZGlzcGxheTogJ3N1Ym1lbnUnLFxuICAgIGFkZDogZnVuY3Rpb24gKGNvcmUsIHRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IGNvcmUuY29udGV4dDtcbiAgICAgICAgY29udGV4dC50ZW1wbGF0ZSA9IHt9O1xuXG4gICAgICAgIC8qKiBzZXQgc3VibWVudSAqL1xuICAgICAgICBsZXQgdGVtcGxhdGVEaXYgPSB0aGlzLnNldFN1Ym1lbnUuY2FsbChjb3JlKTtcblxuICAgICAgICAvKiogYWRkIGV2ZW50IGxpc3RlbmVycyAqL1xuICAgICAgICB0ZW1wbGF0ZURpdi5xdWVyeVNlbGVjdG9yKCd1bCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5waWNrdXAuYmluZChjb3JlKSk7XG5cbiAgICAgICAgLyoqIGFwcGVuZCB0YXJnZXQgYnV0dG9uIG1lbnUgKi9cbiAgICAgICAgY29yZS5pbml0TWVudVRhcmdldCh0aGlzLm5hbWUsIHRhcmdldEVsZW1lbnQsIHRlbXBsYXRlRGl2KTtcblxuICAgICAgICAvKiogZW1wdHkgbWVtb3J5ICovXG4gICAgICAgIHRlbXBsYXRlRGl2ID0gbnVsbDtcbiAgICB9LFxuXG4gICAgc2V0U3VibWVudTogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0ZW1wbGF0ZUxpc3QgPSB0aGlzLmNvbnRleHQub3B0aW9uLnRlbXBsYXRlcztcbiAgICAgICAgaWYgKCF0ZW1wbGF0ZUxpc3QgfHwgdGVtcGxhdGVMaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1tTVU5FRElUT1IucGx1Z2lucy50ZW1wbGF0ZS5mYWlsXSBUbyB1c2UgdGhlIFwidGVtcGxhdGVcIiBwbHVnaW4sIHBsZWFzZSBkZWZpbmUgdGhlIFwidGVtcGxhdGVzXCIgb3B0aW9uLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGlzdERpdiA9IHRoaXMudXRpbC5jcmVhdGVFbGVtZW50KCdESVYnKTtcbiAgICAgICAgbGlzdERpdi5jbGFzc05hbWUgPSAnc2UtbGlzdC1sYXllcic7XG5cbiAgICAgICAgbGV0IGxpc3QgPSAnPGRpdiBjbGFzcz1cInNlLXN1Ym1lbnUgc2UtbGlzdC1pbm5lclwiPicgK1xuICAgICAgICAgICAgICAgICc8dWwgY2xhc3M9XCJzZS1saXN0LWJhc2ljXCI+JztcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHRlbXBsYXRlTGlzdC5sZW5ndGgsIHQ7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgdCA9IHRlbXBsYXRlTGlzdFtpXTtcbiAgICAgICAgICAgIGxpc3QgKz0gJzxsaT48YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNlLWJ0bi1saXN0XCIgZGF0YS12YWx1ZT1cIicgKyBpICsgJ1wiIHRpdGxlPVwiJyArIHQubmFtZSArICdcIj4nICsgdC5uYW1lICsgJzwvYnV0dG9uPjwvbGk+JztcbiAgICAgICAgfVxuICAgICAgICBsaXN0ICs9ICc8L3VsPjwvZGl2Pic7XG5cbiAgICAgICAgbGlzdERpdi5pbm5lckhUTUwgPSBsaXN0O1xuXG4gICAgICAgIHJldHVybiBsaXN0RGl2O1xuICAgIH0sXG5cbiAgICBwaWNrdXA6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGlmICghL15CVVRUT04kL2kudGVzdChlLnRhcmdldC50YWdOYW1lKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICBjb25zdCB0ZW1wID0gdGhpcy5jb250ZXh0Lm9wdGlvbi50ZW1wbGF0ZXNbZS50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJyldO1xuXG4gICAgICAgIGlmICh0ZW1wLmh0bWwpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0Q29udGVudHModGVtcC5odG1sKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc3VibWVudU9mZigpO1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1tTVU5FRElUT1IudGVtcGxhdGUuZmFpbF0gY2F1c2UgOiBcInRlbXBsYXRlc1tpXS5odG1sIG5vdCBmb3VuZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIHRoaXMuc3VibWVudU9mZigpO1xuICAgIH1cbn07IiwiLypcbiAqIHd5c2l3eWcgd2ViIGVkaXRvclxuICpcbiAqIHN1bmVkaXRvci5qc1xuICogQ29weXJpZ2h0IDIwMTcgSmlIb25nIExlZS5cbiAqIE1JVCBsaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCBkaWFsb2cgZnJvbSAnLi4vbW9kdWxlcy9kaWFsb2cnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gICAgbmFtZTogJ2xpbmsnLFxuICAgIGRpc3BsYXk6ICdkaWFsb2cnLFxuICAgIGFkZDogZnVuY3Rpb24gKGNvcmUpIHtcbiAgICAgICAgY29yZS5hZGRNb2R1bGUoW2RpYWxvZ10pO1xuXG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBjb3JlLmNvbnRleHQ7XG4gICAgICAgIGNvbnRleHQubGluayA9IHtcbiAgICAgICAgICAgIGZvY3VzRWxlbWVudDogbnVsbCxcbiAgICAgICAgICAgIGxpbmtOZXdXaW5kb3dDaGVjazogbnVsbCxcbiAgICAgICAgICAgIGxpbmtBbmNob3JUZXh0OiBudWxsLFxuICAgICAgICAgICAgX2xpbmtBbmNob3I6IG51bGwsXG4gICAgICAgICAgICBfbGlua1ZhbHVlOiAnJ1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKiBsaW5rIGRpYWxvZyAqL1xuICAgICAgICBsZXQgbGlua19kaWFsb2cgPSB0aGlzLnNldERpYWxvZy5jYWxsKGNvcmUpO1xuICAgICAgICBjb250ZXh0LmxpbmsubW9kYWwgPSBsaW5rX2RpYWxvZztcbiAgICAgICAgY29udGV4dC5saW5rLmZvY3VzRWxlbWVudCA9IGxpbmtfZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfbGlua191cmwnKTtcbiAgICAgICAgY29udGV4dC5saW5rLmxpbmtBbmNob3JUZXh0ID0gbGlua19kaWFsb2cucXVlcnlTZWxlY3RvcignLl9zZV9saW5rX3RleHQnKTtcbiAgICAgICAgY29udGV4dC5saW5rLmxpbmtOZXdXaW5kb3dDaGVjayA9IGxpbmtfZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfbGlua19jaGVjaycpO1xuICAgICAgICBjb250ZXh0LmxpbmsucHJldmlldyA9IGxpbmtfZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5zZS1saW5rLXByZXZpZXcnKTtcblxuICAgICAgICAvKiogbGluayBjb250cm9sbGVyICovXG4gICAgICAgIGxldCBsaW5rX2NvbnRyb2xsZXIgPSB0aGlzLnNldENvbnRyb2xsZXJfTGlua0J1dHRvbi5jYWxsKGNvcmUpO1xuICAgICAgICBjb250ZXh0LmxpbmsubGlua0NvbnRyb2xsZXIgPSBsaW5rX2NvbnRyb2xsZXI7XG4gICAgICAgIGNvbnRleHQubGluay5fbGlua0FuY2hvciA9IG51bGw7XG4gICAgICAgIGxpbmtfY29udHJvbGxlci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBjb3JlLmV2ZW50U3RvcCk7XG5cbiAgICAgICAgLyoqIGFkZCBldmVudCBsaXN0ZW5lcnMgKi9cbiAgICAgICAgbGlua19kaWFsb2cucXVlcnlTZWxlY3RvcignLnNlLWJ0bi1wcmltYXJ5JykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLnN1Ym1pdC5iaW5kKGNvcmUpKTtcbiAgICAgICAgbGlua19jb250cm9sbGVyLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5vbkNsaWNrX2xpbmtDb250cm9sbGVyLmJpbmQoY29yZSkpO1xuICAgICAgICBjb250ZXh0LmxpbmsuZm9jdXNFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgdGhpcy5fb25MaW5rUHJldmlldy5iaW5kKGNvbnRleHQubGluay5wcmV2aWV3LCBjb250ZXh0LmxpbmssIGNvbnRleHQub3B0aW9ucy5saW5rUHJvdG9jb2wpKTtcblxuICAgICAgICAvKiogYXBwZW5kIGh0bWwgKi9cbiAgICAgICAgY29udGV4dC5kaWFsb2cubW9kYWwuYXBwZW5kQ2hpbGQobGlua19kaWFsb2cpO1xuXG4gICAgICAgIC8qKiBhcHBlbmQgY29udHJvbGxlciAqL1xuICAgICAgICBjb250ZXh0LmVsZW1lbnQucmVsYXRpdmUuYXBwZW5kQ2hpbGQobGlua19jb250cm9sbGVyKTtcblxuICAgICAgICAvKiogZW1wdHkgbWVtb3J5ICovXG4gICAgICAgIGxpbmtfZGlhbG9nID0gbnVsbCwgbGlua19jb250cm9sbGVyID0gbnVsbDtcbiAgICB9LFxuXG4gICAgLyoqIGRpYWxvZyAqL1xuICAgIHNldERpYWxvZzogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBsYW5nID0gdGhpcy5sYW5nO1xuICAgICAgICBjb25zdCBkaWFsb2cgPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XG5cbiAgICAgICAgZGlhbG9nLmNsYXNzTmFtZSA9ICdzZS1kaWFsb2ctY29udGVudCc7XG4gICAgICAgIGRpYWxvZy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICBkaWFsb2cuaW5uZXJIVE1MID0gJycgK1xuICAgICAgICAgICAgJzxmb3JtIGNsYXNzPVwiZWRpdG9yX2xpbmtcIj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1oZWFkZXJcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtY29tbWFuZD1cImNsb3NlXCIgY2xhc3M9XCJzZS1idG4gc2UtZGlhbG9nLWNsb3NlXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCIgdGl0bGU9XCInICsgbGFuZy5kaWFsb2dCb3guY2xvc2UgKyAnXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmljb25zLmNhbmNlbCArXG4gICAgICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtbW9kYWwtdGl0bGVcIj4nICsgbGFuZy5kaWFsb2dCb3gubGlua0JveC50aXRsZSArICc8L3NwYW4+JyArXG4gICAgICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZGlhbG9nLWJvZHlcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1kaWFsb2ctZm9ybVwiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxsYWJlbD4nICsgbGFuZy5kaWFsb2dCb3gubGlua0JveC51cmwgKyAnPC9sYWJlbD4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8aW5wdXQgY2xhc3M9XCJzZS1pbnB1dC1mb3JtIHNlLWlucHV0LXVybCBfc2VfbGlua191cmxcIiB0eXBlPVwidGV4dFwiIC8+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPHByZSBjbGFzcz1cInNlLWxpbmstcHJldmlld1wiPjwvcHJlPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZGlhbG9nLWZvcm1cIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8bGFiZWw+JyArIGxhbmcuZGlhbG9nQm94LmxpbmtCb3gudGV4dCArICc8L2xhYmVsPjxpbnB1dCBjbGFzcz1cInNlLWlucHV0LWZvcm0gX3NlX2xpbmtfdGV4dFwiIHR5cGU9XCJ0ZXh0XCIgLz4nICtcbiAgICAgICAgICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1mb3JtLWZvb3RlclwiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxsYWJlbD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJzZS1kaWFsb2ctYnRuLWNoZWNrIF9zZV9saW5rX2NoZWNrXCIgLz4mbmJzcDsnICsgbGFuZy5kaWFsb2dCb3gubGlua0JveC5uZXdXaW5kb3dDaGVjayArICc8L2xhYmVsPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZGlhbG9nLWZvb3RlclwiPicgK1xuICAgICAgICAgICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwic3VibWl0XCIgY2xhc3M9XCJzZS1idG4tcHJpbWFyeVwiIHRpdGxlPVwiJyArIGxhbmcuZGlhbG9nQm94LnN1Ym1pdEJ1dHRvbiArICdcIj48c3Bhbj4nICsgbGFuZy5kaWFsb2dCb3guc3VibWl0QnV0dG9uICsgJzwvc3Bhbj48L2J1dHRvbj4nICtcbiAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAnPC9mb3JtPic7XG5cbiAgICAgICAgcmV0dXJuIGRpYWxvZztcbiAgICB9LFxuXG4gICAgLyoqIG1vZGlmeSBjb250cm9sbGVyIGJ1dHRvbiAqL1xuICAgIHNldENvbnRyb2xsZXJfTGlua0J1dHRvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBsYW5nID0gdGhpcy5sYW5nO1xuICAgICAgICBjb25zdCBpY29ucyA9IHRoaXMuaWNvbnM7XG4gICAgICAgIGNvbnN0IGxpbmtfYnRuID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xuXG4gICAgICAgIGxpbmtfYnRuLmNsYXNzTmFtZSA9ICdzZS1jb250cm9sbGVyIHNlLWNvbnRyb2xsZXItbGluayc7XG4gICAgICAgIGxpbmtfYnRuLmlubmVySFRNTCA9ICcnICtcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtYXJyb3cgc2UtYXJyb3ctdXBcIj48L2Rpdj4nICtcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwibGluay1jb250ZW50XCI+PHNwYW4+PGEgdGFyZ2V0PVwiX2JsYW5rXCIgaHJlZj1cIlwiPjwvYT4mbmJzcDs8L3NwYW4+JyArXG4gICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1idG4tZ3JvdXBcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtY29tbWFuZD1cInVwZGF0ZVwiIHRhYmluZGV4PVwiLTFcIiBjbGFzcz1cInNlLWJ0biBzZS10b29sdGlwXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICBpY29ucy5lZGl0ICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIuZWRpdCArICc8L3NwYW4+PC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJ1bmxpbmtcIiB0YWJpbmRleD1cIi0xXCIgY2xhc3M9XCJzZS1idG4gc2UtdG9vbHRpcFwiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgaWNvbnMudW5saW5rICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIudW5saW5rICsgJzwvc3Bhbj48L3NwYW4+JyArXG4gICAgICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtY29tbWFuZD1cImRlbGV0ZVwiIHRhYmluZGV4PVwiLTFcIiBjbGFzcz1cInNlLWJ0biBzZS10b29sdGlwXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICBpY29ucy5kZWxldGUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcuY29udHJvbGxlci5yZW1vdmUgKyAnPC9zcGFuPjwvc3Bhbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzwvYnV0dG9uPicgK1xuICAgICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICc8L2Rpdj4nO1xuXG4gICAgICAgIHJldHVybiBsaW5rX2J0bjtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIGRpYWxvZ1xuICAgICAqL1xuICAgIG9wZW46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5wbHVnaW5zLmRpYWxvZy5vcGVuLmNhbGwodGhpcywgJ2xpbmsnLCAnbGluaycgPT09IHRoaXMuY3VycmVudENvbnRyb2xsZXJOYW1lKTtcbiAgICB9LFxuXG4gICAgX29uTGlua1ByZXZpZXc6IGZ1bmN0aW9uIChjb250ZXh0LCBwcm90b2NvbCwgZSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGUudGFyZ2V0LnZhbHVlLnRyaW0oKTtcbiAgICAgICAgY29udGV4dC5fbGlua1ZhbHVlID0gdGhpcy50ZXh0Q29udGVudCA9ICF2YWx1ZSA/ICcnIDogKHByb3RvY29sICYmIHZhbHVlLmluZGV4T2YoJzovLycpID09PSAtMSAmJiB2YWx1ZS5pbmRleE9mKCcjJykgIT09IDApID8gcHJvdG9jb2wgKyB2YWx1ZSA6IHZhbHVlLmluZGV4T2YoJzovLycpID09PSAtMSA/ICcvJyArIHZhbHVlIDogdmFsdWU7XG4gICAgfSxcblxuICAgIHN1Ym1pdDogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdGhpcy5zaG93TG9hZGluZygpO1xuXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICBjb25zdCBzdWJtaXRBY3Rpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBjb250ZXh0TGluayA9IHRoaXMuY29udGV4dC5saW5rO1xuICAgICAgICAgICAgaWYgKGNvbnRleHRMaW5rLl9saW5rVmFsdWUubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IGNvbnRleHRMaW5rLl9saW5rVmFsdWU7XG4gICAgICAgICAgICBjb25zdCBhbmNob3IgPSBjb250ZXh0TGluay5saW5rQW5jaG9yVGV4dDtcbiAgICAgICAgICAgIGNvbnN0IGFuY2hvclRleHQgPSBhbmNob3IudmFsdWUubGVuZ3RoID09PSAwID8gdXJsIDogYW5jaG9yLnZhbHVlO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuY29udGV4dC5kaWFsb2cudXBkYXRlTW9kYWwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvQSA9IHRoaXMudXRpbC5jcmVhdGVFbGVtZW50KCdBJyk7XG4gICAgICAgICAgICAgICAgb0EuaHJlZiA9IHVybDtcbiAgICAgICAgICAgICAgICBvQS50ZXh0Q29udGVudCA9IGFuY2hvclRleHQ7XG4gICAgICAgICAgICAgICAgb0EudGFyZ2V0ID0gKGNvbnRleHRMaW5rLmxpbmtOZXdXaW5kb3dDaGVjay5jaGVja2VkID8gJ19ibGFuaycgOiAnJyk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBzZWxlY3RlZEZvcm1hdHMgPSB0aGlzLmdldFNlbGVjdGVkRWxlbWVudHMoKTtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWRGb3JtYXRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb0Zvcm1hdCA9IHRoaXMudXRpbC5jcmVhdGVFbGVtZW50KHNlbGVjdGVkRm9ybWF0c1swXS5ub2RlTmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIG9Gb3JtYXQuYXBwZW5kQ2hpbGQob0EpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaW5zZXJ0Tm9kZShvRm9ybWF0LCBudWxsLCB0cnVlKSkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5pbnNlcnROb2RlKG9BLCBudWxsLCB0cnVlKSkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuc2V0UmFuZ2Uob0EuY2hpbGROb2Rlc1swXSwgMCwgb0EuY2hpbGROb2Rlc1swXSwgb0EudGV4dENvbnRlbnQubGVuZ3RoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29udGV4dExpbmsuX2xpbmtBbmNob3IuaHJlZiA9IHVybDtcbiAgICAgICAgICAgICAgICBjb250ZXh0TGluay5fbGlua0FuY2hvci50ZXh0Q29udGVudCA9IGFuY2hvclRleHQ7XG4gICAgICAgICAgICAgICAgY29udGV4dExpbmsuX2xpbmtBbmNob3IudGFyZ2V0ID0gKGNvbnRleHRMaW5rLmxpbmtOZXdXaW5kb3dDaGVjay5jaGVja2VkID8gJ19ibGFuaycgOiAnJyk7XG5cbiAgICAgICAgICAgICAgICAvLyBzZXQgcmFuZ2VcbiAgICAgICAgICAgICAgICBjb25zdCB0ZXh0Tm9kZSA9IGNvbnRleHRMaW5rLl9saW5rQW5jaG9yLmNoaWxkTm9kZXNbMF07XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRSYW5nZSh0ZXh0Tm9kZSwgMCwgdGV4dE5vZGUsIHRleHROb2RlLnRleHRDb250ZW50Lmxlbmd0aCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnRleHRMaW5rLl9saW5rVmFsdWUgPSBjb250ZXh0TGluay5wcmV2aWV3LnRleHRDb250ZW50ID0gY29udGV4dExpbmsuZm9jdXNFbGVtZW50LnZhbHVlID0gY29udGV4dExpbmsubGlua0FuY2hvclRleHQudmFsdWUgPSAnJztcbiAgICAgICAgfS5iaW5kKHRoaXMpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzdWJtaXRBY3Rpb24oKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5kaWFsb2cuY2xvc2UuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgIHRoaXMuY2xvc2VMb2FkaW5nKCk7XG4gICAgICAgICAgICAvLyBoaXN0b3J5IHN0YWNrXG4gICAgICAgICAgICB0aGlzLmhpc3RvcnkucHVzaChmYWxzZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSBjb3JlXG4gICAgICovXG4gICAgYWN0aXZlOiBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbnRyb2xsZXJBcnJheS5pbmRleE9mKHRoaXMuY29udGV4dC5saW5rLmxpbmtDb250cm9sbGVyKSA+IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250cm9sbGVyc09mZigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudXRpbC5pc0FuY2hvcihlbGVtZW50KSAmJiBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1pbWFnZS1saW5rJykgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbnRyb2xsZXJBcnJheS5pbmRleE9mKHRoaXMuY29udGV4dC5saW5rLmxpbmtDb250cm9sbGVyKSA8IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMubGluay5jYWxsX2NvbnRyb2xsZXIuY2FsbCh0aGlzLCBlbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgZGlhbG9nXG4gICAgICovXG4gICAgb246IGZ1bmN0aW9uICh1cGRhdGUpIHtcbiAgICAgICAgY29uc3QgY29udGV4dExpbmsgPSB0aGlzLmNvbnRleHQubGluaztcbiAgICAgICAgaWYgKCF1cGRhdGUpIHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5saW5rLmluaXQuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgIGNvbnRleHRMaW5rLmxpbmtBbmNob3JUZXh0LnZhbHVlID0gdGhpcy5nZXRTZWxlY3Rpb24oKS50b1N0cmluZygpO1xuICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHRMaW5rLl9saW5rQW5jaG9yKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuZGlhbG9nLnVwZGF0ZU1vZGFsID0gdHJ1ZTtcbiAgICAgICAgICAgIGNvbnRleHRMaW5rLl9saW5rVmFsdWUgPSBjb250ZXh0TGluay5wcmV2aWV3LnRleHRDb250ZW50ID0gY29udGV4dExpbmsuZm9jdXNFbGVtZW50LnZhbHVlID0gY29udGV4dExpbmsuX2xpbmtBbmNob3IuaHJlZjtcbiAgICAgICAgICAgIGNvbnRleHRMaW5rLmxpbmtBbmNob3JUZXh0LnZhbHVlID0gY29udGV4dExpbmsuX2xpbmtBbmNob3IudGV4dENvbnRlbnQ7XG4gICAgICAgICAgICBjb250ZXh0TGluay5saW5rTmV3V2luZG93Q2hlY2suY2hlY2tlZCA9ICgvX2JsYW5rL2kudGVzdChjb250ZXh0TGluay5fbGlua0FuY2hvci50YXJnZXQpID8gdHJ1ZSA6IGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBjYWxsX2NvbnRyb2xsZXI6IGZ1bmN0aW9uIChzZWxlY3Rpb25BVGFnKSB7XG4gICAgICAgIHRoaXMuZWRpdExpbmsgPSB0aGlzLmNvbnRleHQubGluay5fbGlua0FuY2hvciA9IHNlbGVjdGlvbkFUYWc7XG4gICAgICAgIGNvbnN0IGxpbmtCdG4gPSB0aGlzLmNvbnRleHQubGluay5saW5rQ29udHJvbGxlcjtcbiAgICAgICAgY29uc3QgbGluayA9IGxpbmtCdG4ucXVlcnlTZWxlY3RvcignYScpO1xuXG4gICAgICAgIGxpbmsuaHJlZiA9IHNlbGVjdGlvbkFUYWcuaHJlZjtcbiAgICAgICAgbGluay50aXRsZSA9IHNlbGVjdGlvbkFUYWcudGV4dENvbnRlbnQ7XG4gICAgICAgIGxpbmsudGV4dENvbnRlbnQgPSBzZWxlY3Rpb25BVGFnLnRleHRDb250ZW50O1xuXG4gICAgICAgIHRoaXMuc2V0Q29udHJvbGxlclBvc2l0aW9uKGxpbmtCdG4sIHNlbGVjdGlvbkFUYWcsICdib3R0b20nLCB7bGVmdDogMCwgdG9wOiAwfSk7XG4gICAgICAgIHRoaXMuY29udHJvbGxlcnNPbihsaW5rQnRuLCBzZWxlY3Rpb25BVGFnLCAnbGluaycpO1xuICAgIH0sXG5cbiAgICBvbkNsaWNrX2xpbmtDb250cm9sbGVyOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIGNvbnN0IGNvbW1hbmQgPSBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY29tbWFuZCcpIHx8IGUudGFyZ2V0LnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKCdkYXRhLWNvbW1hbmQnKTtcbiAgICAgICAgaWYgKCFjb21tYW5kKSByZXR1cm47XG5cbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIGlmICgvdXBkYXRlLy50ZXN0KGNvbW1hbmQpKSB7XG4gICAgICAgICAgICBjb25zdCBjb250ZXh0TGluayA9IHRoaXMuY29udGV4dC5saW5rO1xuICAgICAgICAgICAgY29udGV4dExpbmsuX2xpbmtWYWx1ZSA9IGNvbnRleHRMaW5rLnByZXZpZXcudGV4dENvbnRlbnQgPSBjb250ZXh0TGluay5mb2N1c0VsZW1lbnQudmFsdWUgPSBjb250ZXh0TGluay5fbGlua0FuY2hvci5ocmVmO1xuICAgICAgICAgICAgY29udGV4dExpbmsubGlua0FuY2hvclRleHQudmFsdWUgPSBjb250ZXh0TGluay5fbGlua0FuY2hvci50ZXh0Q29udGVudDtcbiAgICAgICAgICAgIGNvbnRleHRMaW5rLmxpbmtOZXdXaW5kb3dDaGVjay5jaGVja2VkID0gKC9fYmxhbmsvaS50ZXN0KGNvbnRleHRMaW5rLl9saW5rQW5jaG9yLnRhcmdldCkgPyB0cnVlIDogZmFsc2UpO1xuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmRpYWxvZy5vcGVuLmNhbGwodGhpcywgJ2xpbmsnLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICgvdW5saW5rLy50ZXN0KGNvbW1hbmQpKSB7XG4gICAgICAgICAgICBjb25zdCBzYyA9IHRoaXMudXRpbC5nZXRDaGlsZEVsZW1lbnQodGhpcy5jb250ZXh0LmxpbmsuX2xpbmtBbmNob3IsIGZ1bmN0aW9uIChjdXJyZW50KSB7IHJldHVybiBjdXJyZW50LmNoaWxkTm9kZXMubGVuZ3RoID09PSAwIHx8IGN1cnJlbnQubm9kZVR5cGUgPT09IDM7IH0sIGZhbHNlKTtcbiAgICAgICAgICAgIGNvbnN0IGVjID0gdGhpcy51dGlsLmdldENoaWxkRWxlbWVudCh0aGlzLmNvbnRleHQubGluay5fbGlua0FuY2hvciwgZnVuY3Rpb24gKGN1cnJlbnQpIHsgcmV0dXJuIGN1cnJlbnQuY2hpbGROb2Rlcy5sZW5ndGggPT09IDAgfHwgY3VycmVudC5ub2RlVHlwZSA9PT0gMzsgfSwgdHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLnNldFJhbmdlKHNjLCAwLCBlYywgZWMudGV4dENvbnRlbnQubGVuZ3RoKTtcbiAgICAgICAgICAgIHRoaXMubm9kZUNoYW5nZShudWxsLCBudWxsLCBbJ0EnXSwgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLyoqIGRlbGV0ZSAqL1xuICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUl0ZW0odGhpcy5jb250ZXh0LmxpbmsuX2xpbmtBbmNob3IpO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmxpbmsuX2xpbmtBbmNob3IgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5mb2N1cygpO1xuXG4gICAgICAgICAgICAvLyBoaXN0b3J5IHN0YWNrXG4gICAgICAgICAgICB0aGlzLmhpc3RvcnkucHVzaChmYWxzZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbnRyb2xsZXJzT2ZmKCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSBkaWFsb2dcbiAgICAgKi9cbiAgICBpbml0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRMaW5rID0gdGhpcy5jb250ZXh0Lmxpbms7XG4gICAgICAgIGNvbnRleHRMaW5rLmxpbmtDb250cm9sbGVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIGNvbnRleHRMaW5rLl9saW5rQW5jaG9yID0gbnVsbDtcbiAgICAgICAgY29udGV4dExpbmsuX2xpbmtWYWx1ZSA9IGNvbnRleHRMaW5rLnByZXZpZXcudGV4dENvbnRlbnQgPSBjb250ZXh0TGluay5mb2N1c0VsZW1lbnQudmFsdWUgPSAnJztcbiAgICAgICAgY29udGV4dExpbmsubGlua0FuY2hvclRleHQudmFsdWUgPSAnJztcbiAgICAgICAgY29udGV4dExpbmsubGlua05ld1dpbmRvd0NoZWNrLmNoZWNrZWQgPSBmYWxzZTtcbiAgICB9XG59O1xuIiwiLypcbiAqIHd5c2l3eWcgd2ViIGVkaXRvclxuICpcbiAqIHN1bmVkaXRvci5qc1xuICogQ29weXJpZ2h0IDIwMTcgSmlIb25nIExlZS5cbiAqIE1JVCBsaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCBkaWFsb2cgZnJvbSAnLi4vbW9kdWxlcy9kaWFsb2cnO1xuaW1wb3J0IGNvbXBvbmVudCBmcm9tICcuLi9tb2R1bGVzL2NvbXBvbmVudCc7XG5pbXBvcnQgcmVzaXppbmcgZnJvbSAnLi4vbW9kdWxlcy9yZXNpemluZyc7XG5pbXBvcnQgZmlsZU1hbmFnZXIgZnJvbSAnLi4vbW9kdWxlcy9maWxlTWFuYWdlcic7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICBuYW1lOiAnaW1hZ2UnLFxuICAgIGRpc3BsYXk6ICdkaWFsb2cnLFxuICAgIGFkZDogZnVuY3Rpb24gKGNvcmUpIHtcbiAgICAgICAgY29yZS5hZGRNb2R1bGUoW2RpYWxvZywgY29tcG9uZW50LCByZXNpemluZywgZmlsZU1hbmFnZXJdKTtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBjb3JlLmNvbnRleHQ7XG4gICAgICAgIGNvbnN0IGNvbnRleHRJbWFnZSA9IGNvbnRleHQuaW1hZ2UgPSB7XG4gICAgICAgICAgICBfaW5mb0xpc3Q6IFtdLCAvLyBAT3ZlcnJpZGUgZmlsZU1hbmFnZXJcbiAgICAgICAgICAgIF9pbmZvSW5kZXg6IDAsIC8vIEBPdmVycmlkZSBmaWxlTWFuYWdlclxuICAgICAgICAgICAgX3VwbG9hZEZpbGVMZW5ndGg6IDAsIC8vIEBPdmVycmlkZSBmaWxlTWFuYWdlclxuICAgICAgICAgICAgc2l6ZVVuaXQ6IGNvbnRleHQub3B0aW9uLl9pbWFnZVNpemVVbml0LFxuICAgICAgICAgICAgX2FsdFRleHQ6ICcnLFxuICAgICAgICAgICAgX2xpbmtFbGVtZW50OiBudWxsLFxuICAgICAgICAgICAgX2FsaWduOiAnbm9uZScsXG4gICAgICAgICAgICBfZmxvYXRDbGFzc1JlZ0V4cDogJ19fc2VfX2Zsb2F0XFxcXC1bYS16XSsnLFxuICAgICAgICAgICAgX3ZfbGluazoge19saW5rVmFsdWU6ICcnfSxcbiAgICAgICAgICAgIF92X3NyYzoge19saW5rVmFsdWU6ICcnfSxcbiAgICAgICAgICAgIHN2Z0RlZmF1bHRTaXplOiAnMzAlJyxcbiAgICAgICAgICAgIGJhc2U2NFJlbmRlckluZGV4OiAwLFxuICAgICAgICAgICAgLy8gQHJlcXVpcmUgQE92ZXJyaWRlIGNvbXBvbmVudFxuICAgICAgICAgICAgX2VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgICBfY292ZXI6IG51bGwsXG4gICAgICAgICAgICBfY29udGFpbmVyOiBudWxsLFxuICAgICAgICAgICAgLy8gQE92ZXJyaWRlIHJlc2l6aW5nIHByb3BlcnRpZXNcbiAgICAgICAgICAgIGlucHV0WDogbnVsbCxcbiAgICAgICAgICAgIGlucHV0WTogbnVsbCxcbiAgICAgICAgICAgIF9lbGVtZW50X3c6IDEsXG4gICAgICAgICAgICBfZWxlbWVudF9oOiAxLFxuICAgICAgICAgICAgX2VsZW1lbnRfbDogMCxcbiAgICAgICAgICAgIF9lbGVtZW50X3Q6IDAsXG4gICAgICAgICAgICBfZGVmYXVsdFNpemVYOiAnYXV0bycsXG4gICAgICAgICAgICBfZGVmYXVsdFNpemVZOiAnYXV0bycsXG4gICAgICAgICAgICBfb3JpZ2luX3c6IGNvbnRleHQub3B0aW9uLmltYWdlV2lkdGggPT09ICdhdXRvJyA/ICcnIDogY29udGV4dC5vcHRpb24uaW1hZ2VXaWR0aCxcbiAgICAgICAgICAgIF9vcmlnaW5faDogY29udGV4dC5vcHRpb24uaW1hZ2VIZWlnaHQgPT09ICdhdXRvJyA/ICcnIDogY29udGV4dC5vcHRpb24uaW1hZ2VIZWlnaHQsXG4gICAgICAgICAgICBfcHJvcG9ydGlvbkNoZWNrZWQ6IHRydWUsXG4gICAgICAgICAgICBfcmVzaXppbmc6IGNvbnRleHQub3B0aW9uLmltYWdlUmVzaXppbmcsXG4gICAgICAgICAgICBfcmVzaXplRG90SGlkZTogIWNvbnRleHQub3B0aW9uLmltYWdlSGVpZ2h0U2hvdyxcbiAgICAgICAgICAgIF9yb3RhdGlvbjogY29udGV4dC5vcHRpb24uaW1hZ2VSb3RhdGlvbixcbiAgICAgICAgICAgIF9vbmx5UGVyY2VudGFnZTogY29udGV4dC5vcHRpb24uaW1hZ2VTaXplT25seVBlcmNlbnRhZ2UsXG4gICAgICAgICAgICBfcmF0aW86IGZhbHNlLFxuICAgICAgICAgICAgX3JhdGlvWDogMSxcbiAgICAgICAgICAgIF9yYXRpb1k6IDEsXG4gICAgICAgICAgICBfY2FwdGlvblNob3c6IHRydWUsXG4gICAgICAgICAgICBfY2FwdGlvbkNoZWNrZWQ6IGZhbHNlLFxuICAgICAgICAgICAgX2NhcHRpb246IG51bGwsXG4gICAgICAgICAgICBjYXB0aW9uQ2hlY2tFbDogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKiBpbWFnZSBkaWFsb2cgKi9cbiAgICAgICAgbGV0IGltYWdlX2RpYWxvZyA9IHRoaXMuc2V0RGlhbG9nLmNhbGwoY29yZSk7XG4gICAgICAgIGNvbnRleHRJbWFnZS5tb2RhbCA9IGltYWdlX2RpYWxvZztcbiAgICAgICAgY29udGV4dEltYWdlLmltZ0lucHV0RmlsZSA9IGltYWdlX2RpYWxvZy5xdWVyeVNlbGVjdG9yKCcuX3NlX2ltYWdlX2ZpbGUnKTtcbiAgICAgICAgY29udGV4dEltYWdlLmltZ1VybEZpbGUgPSBpbWFnZV9kaWFsb2cucXVlcnlTZWxlY3RvcignLl9zZV9pbWFnZV91cmwnKTtcbiAgICAgICAgY29udGV4dEltYWdlLmZvY3VzRWxlbWVudCA9IGNvbnRleHRJbWFnZS5pbWdJbnB1dEZpbGUgfHwgY29udGV4dEltYWdlLmltZ1VybEZpbGU7XG4gICAgICAgIGNvbnRleHRJbWFnZS5hbHRUZXh0ID0gaW1hZ2VfZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfaW1hZ2VfYWx0Jyk7XG4gICAgICAgIGNvbnRleHRJbWFnZS5pbWdMaW5rID0gaW1hZ2VfZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfaW1hZ2VfbGluaycpO1xuICAgICAgICBjb250ZXh0SW1hZ2UuaW1nTGlua05ld1dpbmRvd0NoZWNrID0gaW1hZ2VfZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfaW1hZ2VfbGlua19jaGVjaycpO1xuICAgICAgICBjb250ZXh0SW1hZ2UuY2FwdGlvbkNoZWNrRWwgPSBpbWFnZV9kaWFsb2cucXVlcnlTZWxlY3RvcignLl9zZV9pbWFnZV9jaGVja19jYXB0aW9uJyk7XG4gICAgICAgIGNvbnRleHRJbWFnZS5wcmV2aWV3TGluayA9IGltYWdlX2RpYWxvZy5xdWVyeVNlbGVjdG9yKCcuX3NlX3RhYl9jb250ZW50X3VybCAuc2UtbGluay1wcmV2aWV3Jyk7XG4gICAgICAgIGNvbnRleHRJbWFnZS5wcmV2aWV3U3JjID0gaW1hZ2VfZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfdGFiX2NvbnRlbnRfaW1hZ2UgLnNlLWxpbmstcHJldmlldycpO1xuXG4gICAgICAgIC8qKiBhZGQgZXZlbnQgbGlzdGVuZXJzICovXG4gICAgICAgIGltYWdlX2RpYWxvZy5xdWVyeVNlbGVjdG9yKCcuc2UtZGlhbG9nLXRhYnMnKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMub3BlblRhYi5iaW5kKGNvcmUpKTtcbiAgICAgICAgaW1hZ2VfZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5zZS1idG4tcHJpbWFyeScpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5zdWJtaXQuYmluZChjb3JlKSk7XG4gICAgICAgIGlmIChjb250ZXh0SW1hZ2UuaW1nSW5wdXRGaWxlKSBpbWFnZV9kaWFsb2cucXVlcnlTZWxlY3RvcignLnNlLWZpbGUtcmVtb3ZlJykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9yZW1vdmVTZWxlY3RlZEZpbGVzLmJpbmQoY29udGV4dEltYWdlLmltZ0lucHV0RmlsZSwgY29udGV4dEltYWdlLmltZ1VybEZpbGUsIGNvbnRleHRJbWFnZS5wcmV2aWV3U3JjKSk7XG4gICAgICAgIGlmIChjb250ZXh0SW1hZ2UuaW1nSW5wdXRGaWxlICYmIGNvbnRleHRJbWFnZS5pbWdVcmxGaWxlKSBjb250ZXh0SW1hZ2UuaW1nSW5wdXRGaWxlLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHRoaXMuX2ZpbGVJbnB1dENoYW5nZS5iaW5kKGNvbnRleHRJbWFnZSkpO1xuXG4gICAgICAgIGNvbnRleHRJbWFnZS5pbWdMaW5rLmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgdGhpcy5fb25MaW5rUHJldmlldy5iaW5kKGNvbnRleHRJbWFnZS5wcmV2aWV3TGluaywgY29udGV4dEltYWdlLl92X2xpbmssIGNvbnRleHQub3B0aW9ucy5saW5rUHJvdG9jb2wpKTtcbiAgICAgICAgaWYgKGNvbnRleHRJbWFnZS5pbWdVcmxGaWxlKSBjb250ZXh0SW1hZ2UuaW1nVXJsRmlsZS5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIHRoaXMuX29uTGlua1ByZXZpZXcuYmluZChjb250ZXh0SW1hZ2UucHJldmlld1NyYywgY29udGV4dEltYWdlLl92X3NyYywgY29udGV4dC5vcHRpb25zLmxpbmtQcm90b2NvbCkpO1xuXG4gICAgICAgIGNvbnN0IGltYWdlR2FsbGVyeUJ1dHRvbiA9IGltYWdlX2RpYWxvZy5xdWVyeVNlbGVjdG9yKCcuX19zZV9fZ2FsbGVyeScpO1xuICAgICAgICBpZiAoaW1hZ2VHYWxsZXJ5QnV0dG9uKSBpbWFnZUdhbGxlcnlCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9vcGVuR2FsbGVyeS5iaW5kKGNvcmUpKTtcbiAgICAgICAgXG4gICAgICAgIGNvbnRleHRJbWFnZS5wcm9wb3J0aW9uID0ge307XG4gICAgICAgIGNvbnRleHRJbWFnZS5pbnB1dFggPSB7fTtcbiAgICAgICAgY29udGV4dEltYWdlLmlucHV0WSA9IHt9O1xuICAgICAgICBpZiAoY29udGV4dC5vcHRpb24uaW1hZ2VSZXNpemluZykge1xuICAgICAgICAgICAgY29udGV4dEltYWdlLnByb3BvcnRpb24gPSBpbWFnZV9kaWFsb2cucXVlcnlTZWxlY3RvcignLl9zZV9pbWFnZV9jaGVja19wcm9wb3J0aW9uJyk7XG4gICAgICAgICAgICBjb250ZXh0SW1hZ2UuaW5wdXRYID0gaW1hZ2VfZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfaW1hZ2Vfc2l6ZV94Jyk7XG4gICAgICAgICAgICBjb250ZXh0SW1hZ2UuaW5wdXRZID0gaW1hZ2VfZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfaW1hZ2Vfc2l6ZV95Jyk7XG4gICAgICAgICAgICBjb250ZXh0SW1hZ2UuaW5wdXRYLnZhbHVlID0gY29udGV4dC5vcHRpb24uaW1hZ2VXaWR0aDtcbiAgICAgICAgICAgIGNvbnRleHRJbWFnZS5pbnB1dFkudmFsdWUgPSBjb250ZXh0Lm9wdGlvbi5pbWFnZUhlaWdodDtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29udGV4dEltYWdlLmlucHV0WC5hZGRFdmVudExpc3RlbmVyKCdrZXl1cCcsIHRoaXMuc2V0SW5wdXRTaXplLmJpbmQoY29yZSwgJ3gnKSk7XG4gICAgICAgICAgICBjb250ZXh0SW1hZ2UuaW5wdXRZLmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgdGhpcy5zZXRJbnB1dFNpemUuYmluZChjb3JlLCAneScpKTtcblxuICAgICAgICAgICAgY29udGV4dEltYWdlLmlucHV0WC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCB0aGlzLnNldFJhdGlvLmJpbmQoY29yZSkpO1xuICAgICAgICAgICAgY29udGV4dEltYWdlLmlucHV0WS5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCB0aGlzLnNldFJhdGlvLmJpbmQoY29yZSkpO1xuICAgICAgICAgICAgY29udGV4dEltYWdlLnByb3BvcnRpb24uYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5zZXRSYXRpby5iaW5kKGNvcmUpKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaW1hZ2VfZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5zZS1kaWFsb2ctYnRuLXJldmVydCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5zaXplUmV2ZXJ0LmJpbmQoY29yZSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqIGFwcGVuZCBodG1sICovXG4gICAgICAgIGNvbnRleHQuZGlhbG9nLm1vZGFsLmFwcGVuZENoaWxkKGltYWdlX2RpYWxvZyk7XG5cbiAgICAgICAgLyoqIGVtcHR5IG1lbW9yeSAqL1xuICAgICAgICBpbWFnZV9kaWFsb2cgPSBudWxsO1xuICAgIH0sXG5cbiAgICAvKiogZGlhbG9nICovXG4gICAgc2V0RGlhbG9nOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMuY29udGV4dC5vcHRpb247XG4gICAgICAgIGNvbnN0IGxhbmcgPSB0aGlzLmxhbmc7XG4gICAgICAgIGNvbnN0IGRpYWxvZyA9IHRoaXMudXRpbC5jcmVhdGVFbGVtZW50KCdESVYnKTtcblxuICAgICAgICBkaWFsb2cuY2xhc3NOYW1lID0gJ3NlLWRpYWxvZy1jb250ZW50JztcbiAgICAgICAgZGlhbG9nLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cbiAgICAgICAgbGV0IGh0bWwgPSAnJyArXG4gICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1oZWFkZXJcIj4nICtcbiAgICAgICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1jb21tYW5kPVwiY2xvc2VcIiBjbGFzcz1cInNlLWJ0biBzZS1kaWFsb2ctY2xvc2VcIiBjbGFzcz1cImNsb3NlXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCIgdGl0bGU9XCInICsgbGFuZy5kaWFsb2dCb3guY2xvc2UgKyAnXCI+JyArXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaWNvbnMuY2FuY2VsICtcbiAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtbW9kYWwtdGl0bGVcIj4nICsgbGFuZy5kaWFsb2dCb3guaW1hZ2VCb3gudGl0bGUgKyAnPC9zcGFuPicgK1xuICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1kaWFsb2ctdGFic1wiPicgK1xuICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIl9zZV90YWJfbGluayBhY3RpdmVcIiBkYXRhLXRhYi1saW5rPVwiaW1hZ2VcIj4nICsgbGFuZy50b29sYmFyLmltYWdlICsgJzwvYnV0dG9uPicgK1xuICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIl9zZV90YWJfbGlua1wiIGRhdGEtdGFiLWxpbms9XCJ1cmxcIj4nICsgbGFuZy50b29sYmFyLmxpbmsgKyAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAnPGZvcm0gbWV0aG9kPVwicG9zdFwiIGVuY3R5cGU9XCJtdWx0aXBhcnQvZm9ybS1kYXRhXCI+JyArXG4gICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJfc2VfdGFiX2NvbnRlbnQgX3NlX3RhYl9jb250ZW50X2ltYWdlXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZGlhbG9nLWJvZHlcIj48ZGl2IHN0eWxlPVwiYm9yZGVyLWJvdHRvbTogMXB4IGRhc2hlZCAjY2NjO1wiPic7XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9uLmltYWdlRmlsZUlucHV0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBodG1sICs9ICcnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1mb3JtXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8bGFiZWw+JyArIGxhbmcuZGlhbG9nQm94LmltYWdlQm94LmZpbGUgKyAnPC9sYWJlbD4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1kaWFsb2ctZm9ybS1maWxlc1wiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxpbnB1dCBjbGFzcz1cInNlLWlucHV0LWZvcm0gX3NlX2ltYWdlX2ZpbGVcIiB0eXBlPVwiZmlsZVwiIGFjY2VwdD1cIicgKyBvcHRpb24uaW1hZ2VBY2NlcHQgKyAnXCInICsgKG9wdGlvbi5pbWFnZU11bHRpcGxlRmlsZSA/ICcgbXVsdGlwbGU9XCJtdWx0aXBsZVwiJyA6ICcnKSArICcvPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2UtYnRuIHNlLWRpYWxvZy1maWxlcy1lZGdlLWJ1dHRvbiBzZS1maWxlLXJlbW92ZVwiIHRpdGxlPVwiJyArIGxhbmcuY29udHJvbGxlci5yZW1vdmUgKyAnXCI+JyArIHRoaXMuaWNvbnMuY2FuY2VsICsgJzwvYnV0dG9uPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvZGl2PicgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9uLmltYWdlVXJsSW5wdXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0bWwgKz0gJycgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZGlhbG9nLWZvcm1cIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxsYWJlbD4nICsgbGFuZy5kaWFsb2dCb3guaW1hZ2VCb3gudXJsICsgJzwvbGFiZWw+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZGlhbG9nLWZvcm0tZmlsZXNcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8aW5wdXQgY2xhc3M9XCJzZS1pbnB1dC1mb3JtIHNlLWlucHV0LXVybCBfc2VfaW1hZ2VfdXJsXCIgdHlwZT1cInRleHRcIiAvPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChvcHRpb24uaW1hZ2VHYWxsZXJ5VXJsICYmIHRoaXMucGx1Z2lucy5pbWFnZUdhbGxlcnkpID8gJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2UtYnRuIHNlLWRpYWxvZy1maWxlcy1lZGdlLWJ1dHRvbiBfX3NlX19nYWxsZXJ5XCIgdGl0bGU9XCInICsgbGFuZy50b29sYmFyLmltYWdlR2FsbGVyeSArICdcIj4nICsgdGhpcy5pY29ucy5pbWFnZV9nYWxsZXJ5ICsgJzwvYnV0dG9uPicgOiAnJykgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8cHJlIGNsYXNzPVwic2UtbGluay1wcmV2aWV3XCI+PC9wcmU+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvZGl2Pic7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIGh0bWwgKz0gJzwvZGl2PicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1kaWFsb2ctZm9ybVwiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8bGFiZWw+JyArIGxhbmcuZGlhbG9nQm94LmltYWdlQm94LmFsdFRleHQgKyAnPC9sYWJlbD48aW5wdXQgY2xhc3M9XCJzZS1pbnB1dC1mb3JtIF9zZV9pbWFnZV9hbHRcIiB0eXBlPVwidGV4dFwiIC8+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JztcblxuICAgICAgICAgICAgaWYgKG9wdGlvbi5pbWFnZVJlc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb25seVBlcmNlbnRhZ2UgPSBvcHRpb24uaW1hZ2VTaXplT25seVBlcmNlbnRhZ2U7XG4gICAgICAgICAgICAgICAgY29uc3Qgb25seVBlcmNlbnREaXNwbGF5ID0gb25seVBlcmNlbnRhZ2UgPyAnIHN0eWxlPVwiZGlzcGxheTogbm9uZSAhaW1wb3J0YW50O1wiJyA6ICcnO1xuICAgICAgICAgICAgICAgIGNvbnN0IGhlaWdodERpc3BsYXkgPSAhb3B0aW9uLmltYWdlSGVpZ2h0U2hvdyA/ICcgc3R5bGU9XCJkaXNwbGF5OiBub25lICFpbXBvcnRhbnQ7XCInIDogJyc7XG4gICAgICAgICAgICAgICAgaHRtbCArPSAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1mb3JtXCI+JztcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbmx5UGVyY2VudGFnZSB8fCAhb3B0aW9uLmltYWdlSGVpZ2h0U2hvdykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh0bWwgKz0gJycgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZGlhbG9nLXNpemUtdGV4dFwiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGxhYmVsIGNsYXNzPVwic2l6ZS13XCI+JyArIGxhbmcuZGlhbG9nQm94LnNpemUgKyAnPC9sYWJlbD4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaHRtbCArPSAnJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1kaWFsb2ctc2l6ZS10ZXh0XCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8bGFiZWwgY2xhc3M9XCJzaXplLXdcIj4nICsgbGFuZy5kaWFsb2dCb3gud2lkdGggKyAnPC9sYWJlbD4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxsYWJlbCBjbGFzcz1cInNlLWRpYWxvZy1zaXplLXhcIj4mbmJzcDs8L2xhYmVsPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGxhYmVsIGNsYXNzPVwic2l6ZS1oXCI+JyArIGxhbmcuZGlhbG9nQm94LmhlaWdodCArICc8L2xhYmVsPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaHRtbCArPSAnJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxpbnB1dCBjbGFzcz1cInNlLWlucHV0LWNvbnRyb2wgX3NlX2ltYWdlX3NpemVfeFwiIHBsYWNlaG9sZGVyPVwiYXV0b1wiJyArIChvbmx5UGVyY2VudGFnZSA/ICcgdHlwZT1cIm51bWJlclwiIG1pbj1cIjFcIicgOiAndHlwZT1cInRleHRcIicpICsgKG9ubHlQZXJjZW50YWdlID8gJyBtYXg9XCIxMDBcIicgOiAnJykgKyAnIC8+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxsYWJlbCBjbGFzcz1cInNlLWRpYWxvZy1zaXplLXhcIicgKyBoZWlnaHREaXNwbGF5ICsgJz4nICsgKG9ubHlQZXJjZW50YWdlID8gJyUnIDogJ3gnKSArICc8L2xhYmVsPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cInNlLWlucHV0LWNvbnRyb2wgX3NlX2ltYWdlX3NpemVfeVwiIHBsYWNlaG9sZGVyPVwiYXV0b1wiJyArIG9ubHlQZXJjZW50RGlzcGxheSArIChvbmx5UGVyY2VudGFnZSA/ICcgbWF4PVwiMTAwXCInIDogJycpICsgaGVpZ2h0RGlzcGxheSArICcvPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8bGFiZWwnICsgb25seVBlcmNlbnREaXNwbGF5ICsgaGVpZ2h0RGlzcGxheSArICc+PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwic2UtZGlhbG9nLWJ0bi1jaGVjayBfc2VfaW1hZ2VfY2hlY2tfcHJvcG9ydGlvblwiIGNoZWNrZWQvPiZuYnNwOycgKyBsYW5nLmRpYWxvZ0JveC5wcm9wb3J0aW9uICsgJzwvbGFiZWw+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIHRpdGxlPVwiJyArIGxhbmcuZGlhbG9nQm94LnJldmVydEJ1dHRvbiArICdcIiBjbGFzcz1cInNlLWJ0biBzZS1kaWFsb2ctYnRuLXJldmVydFwiIHN0eWxlPVwiZmxvYXQ6IHJpZ2h0O1wiPicgKyB0aGlzLmljb25zLnJldmVydCArICc8L2J1dHRvbj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nIDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaHRtbCArPSAnJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1mb3JtIHNlLWRpYWxvZy1mb3JtLWZvb3RlclwiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8bGFiZWw+PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwic2UtZGlhbG9nLWJ0bi1jaGVjayBfc2VfaW1hZ2VfY2hlY2tfY2FwdGlvblwiIC8+Jm5ic3A7JyArIGxhbmcuZGlhbG9nQm94LmNhcHRpb24gKyAnPC9sYWJlbD4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cIl9zZV90YWJfY29udGVudCBfc2VfdGFiX2NvbnRlbnRfdXJsXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZGlhbG9nLWJvZHlcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZGlhbG9nLWZvcm1cIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGxhYmVsPicgKyBsYW5nLmRpYWxvZ0JveC5saW5rQm94LnVybCArICc8L2xhYmVsPjxpbnB1dCBjbGFzcz1cInNlLWlucHV0LWZvcm0gc2UtaW5wdXQtdXJsIF9zZV9pbWFnZV9saW5rXCIgdHlwZT1cInRleHRcIiAvPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8cHJlIGNsYXNzPVwic2UtbGluay1wcmV2aWV3XCI+PC9wcmU+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGxhYmVsPjxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cIl9zZV9pbWFnZV9saW5rX2NoZWNrXCIvPiZuYnNwOycgKyBsYW5nLmRpYWxvZ0JveC5saW5rQm94Lm5ld1dpbmRvd0NoZWNrICsgJzwvbGFiZWw+JyArXG4gICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1kaWFsb2ctZm9vdGVyXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICc8ZGl2PicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxsYWJlbD48aW5wdXQgdHlwZT1cInJhZGlvXCIgbmFtZT1cInN1bmVkaXRvcl9pbWFnZV9yYWRpb1wiIGNsYXNzPVwic2UtZGlhbG9nLWJ0bi1yYWRpb1wiIHZhbHVlPVwibm9uZVwiIGNoZWNrZWQ+JyArIGxhbmcuZGlhbG9nQm94LmJhc2ljICsgJzwvbGFiZWw+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGxhYmVsPjxpbnB1dCB0eXBlPVwicmFkaW9cIiBuYW1lPVwic3VuZWRpdG9yX2ltYWdlX3JhZGlvXCIgY2xhc3M9XCJzZS1kaWFsb2ctYnRuLXJhZGlvXCIgdmFsdWU9XCJsZWZ0XCI+JyArIGxhbmcuZGlhbG9nQm94LmxlZnQgKyAnPC9sYWJlbD4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8bGFiZWw+PGlucHV0IHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJzdW5lZGl0b3JfaW1hZ2VfcmFkaW9cIiBjbGFzcz1cInNlLWRpYWxvZy1idG4tcmFkaW9cIiB2YWx1ZT1cImNlbnRlclwiPicgKyBsYW5nLmRpYWxvZ0JveC5jZW50ZXIgKyAnPC9sYWJlbD4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8bGFiZWw+PGlucHV0IHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJzdW5lZGl0b3JfaW1hZ2VfcmFkaW9cIiBjbGFzcz1cInNlLWRpYWxvZy1idG4tcmFkaW9cIiB2YWx1ZT1cInJpZ2h0XCI+JyArIGxhbmcuZGlhbG9nQm94LnJpZ2h0ICsgJzwvbGFiZWw+JyArXG4gICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cInN1Ym1pdFwiIGNsYXNzPVwic2UtYnRuLXByaW1hcnlcIiB0aXRsZT1cIicgKyBsYW5nLmRpYWxvZ0JveC5zdWJtaXRCdXR0b24gKyAnXCI+PHNwYW4+JyArIGxhbmcuZGlhbG9nQm94LnN1Ym1pdEJ1dHRvbiArICc8L3NwYW4+PC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgJzwvZm9ybT4nO1xuXG4gICAgICAgIGRpYWxvZy5pbm5lckhUTUwgPSBodG1sO1xuXG4gICAgICAgIHJldHVybiBkaWFsb2c7XG4gICAgfSxcblxuICAgIF9maWxlSW5wdXRDaGFuZ2U6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmltZ0lucHV0RmlsZS52YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5pbWdVcmxGaWxlLnJlbW92ZUF0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgICAgICAgICAgIHRoaXMucHJldmlld1NyYy5zdHlsZS50ZXh0RGVjb3JhdGlvbiA9ICcnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5pbWdVcmxGaWxlLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgICAgIHRoaXMucHJldmlld1NyYy5zdHlsZS50ZXh0RGVjb3JhdGlvbiA9ICdsaW5lLXRocm91Z2gnO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIF9yZW1vdmVTZWxlY3RlZEZpbGVzOiBmdW5jdGlvbiAodXJsSW5wdXQsIHByZXZpZXdTcmMpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9ICcnO1xuICAgICAgICBpZiAodXJsSW5wdXQpIHtcbiAgICAgICAgICAgIHVybElucHV0LnJlbW92ZUF0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgICAgICAgICAgIHByZXZpZXdTcmMuc3R5bGUudGV4dERlY29yYXRpb24gPSAnJztcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBfb3BlbkdhbGxlcnk6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jYWxsUGx1Z2luKCdpbWFnZUdhbGxlcnknLCB0aGlzLnBsdWdpbnMuaW1hZ2VHYWxsZXJ5Lm9wZW4uYmluZCh0aGlzLCB0aGlzLnBsdWdpbnMuaW1hZ2UuX3NldFVybElucHV0LmJpbmQodGhpcy5jb250ZXh0LmltYWdlKSksIG51bGwpO1xuICAgIH0sXG5cbiAgICBfc2V0VXJsSW5wdXQ6IGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICAgICAgdGhpcy5hbHRUZXh0LnZhbHVlID0gdGFyZ2V0LmFsdDtcbiAgICAgICAgdGhpcy5fdl9zcmMuX2xpbmtWYWx1ZSA9IHRoaXMucHJldmlld1NyYy50ZXh0Q29udGVudCA9IHRoaXMuaW1nVXJsRmlsZS52YWx1ZSA9IHRhcmdldC5zcmM7XG4gICAgICAgIHRoaXMuaW1nVXJsRmlsZS5mb2N1cygpO1xuICAgIH0sXG5cbiAgICBfb25MaW5rUHJldmlldzogZnVuY3Rpb24gKGNvbnRleHQsIHByb3RvY29sLCBlKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gZS50YXJnZXQudmFsdWUudHJpbSgpO1xuICAgICAgICBjb250ZXh0Ll9saW5rVmFsdWUgPSB0aGlzLnRleHRDb250ZW50ID0gIXZhbHVlID8gJycgOiAocHJvdG9jb2wgJiYgdmFsdWUuaW5kZXhPZignOi8vJykgPT09IC0xICYmIHZhbHVlLmluZGV4T2YoJyMnKSAhPT0gMCkgPyBwcm90b2NvbCArIHZhbHVlIDogdmFsdWUuaW5kZXhPZignOi8vJykgPT09IC0xID8gJy8nICsgdmFsdWUgOiB2YWx1ZTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIEBSZXF1aXJlZCBmaWxlTWFuYWdlclxuICAgICAqL1xuICAgIGZpbGVUYWdzOiBbJ2ltZyddLFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIGNvcmUsIGZpbGVNYW5hZ2VyLCByZXNpemluZ1xuICAgICAqIEBkZXNjcmlwdGlvbiBJdCBpcyBjYWxsZWQgZnJvbSBjb3JlLnNlbGVjdENvbXBvbmVudC5cbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgVGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBzZWxlY3Q6IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIHRoaXMucGx1Z2lucy5pbWFnZS5vbk1vZGlmeU1vZGUuY2FsbCh0aGlzLCBlbGVtZW50LCB0aGlzLnBsdWdpbnMucmVzaXppbmcuY2FsbF9jb250cm9sbGVyX3Jlc2l6ZS5jYWxsKHRoaXMsIGVsZW1lbnQsICdpbWFnZScpKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIGZpbGVNYW5hZ2VyLCByZXNpemluZ1xuICAgICAqL1xuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGltYWdlRWwgPSBlbGVtZW50IHx8IHRoaXMuY29udGV4dC5pbWFnZS5fZWxlbWVudDtcbiAgICAgICAgY29uc3QgaW1hZ2VDb250YWluZXIgPSB0aGlzLnV0aWwuZ2V0UGFyZW50RWxlbWVudChpbWFnZUVsLCB0aGlzLnV0aWwuaXNNZWRpYUNvbXBvbmVudCkgfHwgaW1hZ2VFbDtcbiAgICAgICAgY29uc3QgZGF0YUluZGV4ID0gaW1hZ2VFbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaW5kZXgnKSAqIDE7XG4gICAgICAgIGxldCBmb2N1c0VsID0gKGltYWdlQ29udGFpbmVyLnByZXZpb3VzRWxlbWVudFNpYmxpbmcgfHwgaW1hZ2VDb250YWluZXIubmV4dEVsZW1lbnRTaWJsaW5nKTtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGVtcHR5RGl2ID0gaW1hZ2VDb250YWluZXIucGFyZW50Tm9kZTtcbiAgICAgICAgdGhpcy51dGlsLnJlbW92ZUl0ZW0oaW1hZ2VDb250YWluZXIpO1xuICAgICAgICB0aGlzLnBsdWdpbnMuaW1hZ2UuaW5pdC5jYWxsKHRoaXMpO1xuICAgICAgICB0aGlzLmNvbnRyb2xsZXJzT2ZmKCk7XG5cbiAgICAgICAgaWYgKGVtcHR5RGl2ICE9PSB0aGlzLmNvbnRleHQuZWxlbWVudC53eXNpd3lnKSB0aGlzLnV0aWwucmVtb3ZlSXRlbUFsbFBhcmVudHMoZW1wdHlEaXYsIGZ1bmN0aW9uIChjdXJyZW50KSB7IHJldHVybiBjdXJyZW50LmNoaWxkTm9kZXMubGVuZ3RoID09PSAwOyB9LCBudWxsKTtcblxuICAgICAgICAvLyBmb2N1c1xuICAgICAgICB0aGlzLmZvY3VzRWRnZShmb2N1c0VsKTtcbiAgICAgICAgXG4gICAgICAgIC8vIGV2ZW50XG4gICAgICAgIHRoaXMucGx1Z2lucy5maWxlTWFuYWdlci5kZWxldGVJbmZvLmNhbGwodGhpcywgJ2ltYWdlJywgZGF0YUluZGV4LCB0aGlzLmZ1bmN0aW9ucy5vbkltYWdlVXBsb2FkKTtcblxuICAgICAgICAvLyBoaXN0b3J5IHN0YWNrXG4gICAgICAgIHRoaXMuaGlzdG9yeS5wdXNoKGZhbHNlKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQFJlcXVpcmVkIEBPdmVycmlkZSBkaWFsb2dcbiAgICAgKi9cbiAgICBvbjogZnVuY3Rpb24gKHVwZGF0ZSkge1xuICAgICAgICBjb25zdCBjb250ZXh0SW1hZ2UgPSB0aGlzLmNvbnRleHQuaW1hZ2U7XG4gICAgICAgIFxuICAgICAgICBpZiAoIXVwZGF0ZSkge1xuICAgICAgICAgICAgY29udGV4dEltYWdlLmlucHV0WC52YWx1ZSA9IGNvbnRleHRJbWFnZS5fb3JpZ2luX3cgPSB0aGlzLmNvbnRleHQub3B0aW9uLmltYWdlV2lkdGggPT09IGNvbnRleHRJbWFnZS5fZGVmYXVsdFNpemVYID8gJycgOiB0aGlzLmNvbnRleHQub3B0aW9uLmltYWdlV2lkdGg7XG4gICAgICAgICAgICBjb250ZXh0SW1hZ2UuaW5wdXRZLnZhbHVlID0gY29udGV4dEltYWdlLl9vcmlnaW5faCA9IHRoaXMuY29udGV4dC5vcHRpb24uaW1hZ2VIZWlnaHQgPT09IGNvbnRleHRJbWFnZS5fZGVmYXVsdFNpemVZID8gJycgOiB0aGlzLmNvbnRleHQub3B0aW9uLmltYWdlSGVpZ2h0O1xuICAgICAgICAgICAgaWYgKGNvbnRleHRJbWFnZS5pbWdJbnB1dEZpbGUgJiYgdGhpcy5jb250ZXh0Lm9wdGlvbnMuaW1hZ2VNdWx0aXBsZUZpbGUpIGNvbnRleHRJbWFnZS5pbWdJbnB1dEZpbGUuc2V0QXR0cmlidXRlKCdtdWx0aXBsZScsICdtdWx0aXBsZScpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNvbnRleHRJbWFnZS5pbWdJbnB1dEZpbGUgJiYgdGhpcy5jb250ZXh0Lm9wdGlvbnMuaW1hZ2VNdWx0aXBsZUZpbGUpIGNvbnRleHRJbWFnZS5pbWdJbnB1dEZpbGUucmVtb3ZlQXR0cmlidXRlKCdtdWx0aXBsZScpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBSZXF1aXJlZCBAT3ZlcnJpZGUgZGlhbG9nXG4gICAgICovXG4gICAgb3BlbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnBsdWdpbnMuZGlhbG9nLm9wZW4uY2FsbCh0aGlzLCAnaW1hZ2UnLCAnaW1hZ2UnID09PSB0aGlzLmN1cnJlbnRDb250cm9sbGVyTmFtZSk7XG4gICAgfSxcblxuICAgIG9wZW5UYWI6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGNvbnN0IG1vZGFsID0gdGhpcy5jb250ZXh0LmltYWdlLm1vZGFsO1xuICAgICAgICBjb25zdCB0YXJnZXRFbGVtZW50ID0gKGUgPT09ICdpbml0JyA/IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfdGFiX2xpbmsnKSA6IGUudGFyZ2V0KTtcblxuICAgICAgICBpZiAoIS9eQlVUVE9OJC9pLnRlc3QodGFyZ2V0RWxlbWVudC50YWdOYW1lKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGVjbGFyZSBhbGwgdmFyaWFibGVzXG4gICAgICAgIGNvbnN0IHRhYk5hbWUgPSB0YXJnZXRFbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS10YWItbGluaycpO1xuICAgICAgICBjb25zdCBjb250ZW50Q2xhc3NOYW1lID0gJ19zZV90YWJfY29udGVudCc7XG4gICAgICAgIGxldCBpLCB0YWJDb250ZW50LCB0YWJMaW5rcztcblxuICAgICAgICAvLyBHZXQgYWxsIGVsZW1lbnRzIHdpdGggY2xhc3M9XCJ0YWJjb250ZW50XCIgYW5kIGhpZGUgdGhlbVxuICAgICAgICB0YWJDb250ZW50ID0gbW9kYWwuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShjb250ZW50Q2xhc3NOYW1lKTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHRhYkNvbnRlbnQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRhYkNvbnRlbnRbaV0uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdldCBhbGwgZWxlbWVudHMgd2l0aCBjbGFzcz1cInRhYmxpbmtzXCIgYW5kIHJlbW92ZSB0aGUgY2xhc3MgXCJhY3RpdmVcIlxuICAgICAgICB0YWJMaW5rcyA9IG1vZGFsLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ19zZV90YWJfbGluaycpO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGFiTGlua3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMudXRpbC5yZW1vdmVDbGFzcyh0YWJMaW5rc1tpXSwgJ2FjdGl2ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2hvdyB0aGUgY3VycmVudCB0YWIsIGFuZCBhZGQgYW4gXCJhY3RpdmVcIiBjbGFzcyB0byB0aGUgYnV0dG9uIHRoYXQgb3BlbmVkIHRoZSB0YWJcbiAgICAgICAgbW9kYWwucXVlcnlTZWxlY3RvcignLicgKyBjb250ZW50Q2xhc3NOYW1lICsgJ18nICsgdGFiTmFtZSkuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgIHRoaXMudXRpbC5hZGRDbGFzcyh0YXJnZXRFbGVtZW50LCAnYWN0aXZlJyk7XG5cbiAgICAgICAgLy8gZm9jdXNcbiAgICAgICAgaWYgKHRhYk5hbWUgPT09ICdpbWFnZScgJiYgdGhpcy5jb250ZXh0LmltYWdlLmZvY3VzRWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmltYWdlLmZvY3VzRWxlbWVudC5mb2N1cygpO1xuICAgICAgICB9IGVsc2UgaWYgKHRhYk5hbWUgPT09ICd1cmwnICYmIHRoaXMuY29udGV4dC5pbWFnZS5pbWdMaW5rKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuaW1hZ2UuaW1nTGluay5mb2N1cygpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG5cbiAgICBzdWJtaXQ6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRJbWFnZSA9IHRoaXMuY29udGV4dC5pbWFnZTtcbiAgICAgICAgY29uc3QgaW1hZ2VQbHVnaW4gPSB0aGlzLnBsdWdpbnMuaW1hZ2U7XG5cbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIGNvbnRleHRJbWFnZS5fYWx0VGV4dCA9IGNvbnRleHRJbWFnZS5hbHRUZXh0LnZhbHVlO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2FsaWduID0gY29udGV4dEltYWdlLm1vZGFsLnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W25hbWU9XCJzdW5lZGl0b3JfaW1hZ2VfcmFkaW9cIl06Y2hlY2tlZCcpLnZhbHVlO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2NhcHRpb25DaGVja2VkID0gY29udGV4dEltYWdlLmNhcHRpb25DaGVja0VsLmNoZWNrZWQ7XG4gICAgICAgIGlmIChjb250ZXh0SW1hZ2UuX3Jlc2l6aW5nKSBjb250ZXh0SW1hZ2UuX3Byb3BvcnRpb25DaGVja2VkID0gY29udGV4dEltYWdlLnByb3BvcnRpb24uY2hlY2tlZDtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC5kaWFsb2cudXBkYXRlTW9kYWwpIHtcbiAgICAgICAgICAgICAgICBpbWFnZVBsdWdpbi51cGRhdGVfaW1hZ2UuY2FsbCh0aGlzLCBmYWxzZSwgdHJ1ZSwgZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiAoY29udGV4dEltYWdlLmltZ0lucHV0RmlsZSAmJiBjb250ZXh0SW1hZ2UuaW1nSW5wdXRGaWxlLmZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNob3dMb2FkaW5nKCk7XG4gICAgICAgICAgICAgICAgaW1hZ2VQbHVnaW4uc3VibWl0QWN0aW9uLmNhbGwodGhpcywgdGhpcy5jb250ZXh0LmltYWdlLmltZ0lucHV0RmlsZS5maWxlcyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHRJbWFnZS5pbWdVcmxGaWxlICYmIGNvbnRleHRJbWFnZS5fdl9zcmMuX2xpbmtWYWx1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zaG93TG9hZGluZygpO1xuICAgICAgICAgICAgICAgIGltYWdlUGx1Z2luLm9uUmVuZGVyX2ltZ1VybC5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdGhpcy5jbG9zZUxvYWRpbmcoKTtcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdbU1VORURJVE9SLmltYWdlLnN1Ym1pdC5mYWlsXSBjYXVzZSA6IFwiJyArIGVycm9yLm1lc3NhZ2UgKyAnXCInKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5kaWFsb2cuY2xvc2UuY2FsbCh0aGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9LFxuXG4gICAgc3VibWl0QWN0aW9uOiBmdW5jdGlvbiAoZmlsZUxpc3QpIHtcbiAgICAgICAgaWYgKGZpbGVMaXN0Lmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgICAgIGxldCBmaWxlU2l6ZSA9IDA7XG4gICAgICAgIGxldCBmaWxlcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gZmlsZUxpc3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGlmICgvaW1hZ2UvaS50ZXN0KGZpbGVMaXN0W2ldLnR5cGUpKSB7XG4gICAgICAgICAgICAgICAgZmlsZXMucHVzaChmaWxlTGlzdFtpXSk7XG4gICAgICAgICAgICAgICAgZmlsZVNpemUgKz0gZmlsZUxpc3RbaV0uc2l6ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxpbWl0U2l6ZSA9IHRoaXMuY29udGV4dC5vcHRpb24uaW1hZ2VVcGxvYWRTaXplTGltaXQ7XG4gICAgICAgIGlmIChsaW1pdFNpemUgPiAwKSB7XG4gICAgICAgICAgICBsZXQgaW5mb1NpemUgPSAwO1xuICAgICAgICAgICAgY29uc3QgaW1hZ2VzSW5mbyA9IHRoaXMuY29udGV4dC5pbWFnZS5faW5mb0xpc3Q7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gaW1hZ2VzSW5mby5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIGluZm9TaXplICs9IGltYWdlc0luZm9baV0uc2l6ZSAqIDE7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICgoZmlsZVNpemUgKyBpbmZvU2l6ZSkgPiBsaW1pdFNpemUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlTG9hZGluZygpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGVyciA9ICdbU1VORURJVE9SLmltYWdlVXBsb2FkLmZhaWxdIFNpemUgb2YgdXBsb2FkYWJsZSB0b3RhbCBpbWFnZXM6ICcgKyAobGltaXRTaXplLzEwMDApICsgJ0tCJztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5mdW5jdGlvbnMub25JbWFnZVVwbG9hZEVycm9yICE9PSAnZnVuY3Rpb24nIHx8IHRoaXMuZnVuY3Rpb25zLm9uSW1hZ2VVcGxvYWRFcnJvcihlcnIsIHsgJ2xpbWl0U2l6ZSc6IGxpbWl0U2l6ZSwgJ2N1cnJlbnRTaXplJzogaW5mb1NpemUsICd1cGxvYWRTaXplJzogZmlsZVNpemUgfSwgdGhpcykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mdW5jdGlvbnMubm90aWNlT3BlbihlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb250ZXh0SW1hZ2UgPSB0aGlzLmNvbnRleHQuaW1hZ2U7XG4gICAgICAgIGNvbnRleHRJbWFnZS5fdXBsb2FkRmlsZUxlbmd0aCA9IGZpbGVzLmxlbmd0aDtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGluZm8gPSB7XG4gICAgICAgICAgICBsaW5rVmFsdWU6IGNvbnRleHRJbWFnZS5fdl9saW5rLl9saW5rVmFsdWUsXG4gICAgICAgICAgICBsaW5rTmV3V2luZG93OiBjb250ZXh0SW1hZ2UuaW1nTGlua05ld1dpbmRvd0NoZWNrLmNoZWNrZWQsXG4gICAgICAgICAgICBpbnB1dFdpZHRoOiBjb250ZXh0SW1hZ2UuaW5wdXRYLnZhbHVlLFxuICAgICAgICAgICAgaW5wdXRIZWlnaHQ6IGNvbnRleHRJbWFnZS5pbnB1dFkudmFsdWUsXG4gICAgICAgICAgICBhbGlnbjogY29udGV4dEltYWdlLl9hbGlnbixcbiAgICAgICAgICAgIGlzVXBkYXRlOiB0aGlzLmNvbnRleHQuZGlhbG9nLnVwZGF0ZU1vZGFsLFxuICAgICAgICAgICAgZWxlbWVudDogY29udGV4dEltYWdlLl9lbGVtZW50XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmZ1bmN0aW9ucy5vbkltYWdlVXBsb2FkQmVmb3JlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmZ1bmN0aW9ucy5vbkltYWdlVXBsb2FkQmVmb3JlKGZpbGVzLCBpbmZvLCB0aGlzLCBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgICAgIGlmIChkYXRhICYmIHRoaXMuX3cuQXJyYXkuaXNBcnJheShkYXRhLnJlc3VsdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmltYWdlLnJlZ2lzdGVyLmNhbGwodGhpcywgaW5mbywgZGF0YSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmltYWdlLnVwbG9hZC5jYWxsKHRoaXMsIGluZm8sIGRhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzdWx0ID09PSAndW5kZWZpbmVkJykgcmV0dXJuO1xuICAgICAgICAgICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlTG9hZGluZygpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLl93LkFycmF5LmlzQXJyYXkocmVzdWx0KSAmJiByZXN1bHQubGVuZ3RoID4gMCkgZmlsZXMgPSByZXN1bHQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnBsdWdpbnMuaW1hZ2UudXBsb2FkLmNhbGwodGhpcywgaW5mbywgZmlsZXMpO1xuICAgIH0sXG5cbiAgICBlcnJvcjogZnVuY3Rpb24gKG1lc3NhZ2UsIHJlc3BvbnNlKSB7XG4gICAgICAgIHRoaXMuY2xvc2VMb2FkaW5nKCk7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5mdW5jdGlvbnMub25JbWFnZVVwbG9hZEVycm9yICE9PSAnZnVuY3Rpb24nIHx8IHRoaXMuZnVuY3Rpb25zLm9uSW1hZ2VVcGxvYWRFcnJvcihtZXNzYWdlLCByZXNwb25zZSwgdGhpcykpIHtcbiAgICAgICAgICAgIHRoaXMuZnVuY3Rpb25zLm5vdGljZU9wZW4obWVzc2FnZSk7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcignW1NVTkVESVRPUi5wbHVnaW4uaW1hZ2UuZXJyb3JdIHJlc3BvbnNlOiAnICsgbWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgdXBsb2FkOiBmdW5jdGlvbiAoaW5mbywgZmlsZXMpIHtcbiAgICAgICAgaWYgKCFmaWxlcykge1xuICAgICAgICAgICAgdGhpcy5jbG9zZUxvYWRpbmcoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGZpbGVzID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmltYWdlLmVycm9yLmNhbGwodGhpcywgZmlsZXMsIG51bGwpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaW1hZ2VVcGxvYWRVcmwgPSB0aGlzLmNvbnRleHQub3B0aW9uLmltYWdlVXBsb2FkVXJsO1xuICAgICAgICBjb25zdCBmaWxlc0xlbiA9IHRoaXMuY29udGV4dC5kaWFsb2cudXBkYXRlTW9kYWwgPyAxIDogZmlsZXMubGVuZ3RoO1xuXG4gICAgICAgIC8vIHNlcnZlciB1cGxvYWRcbiAgICAgICAgaWYgKHR5cGVvZiBpbWFnZVVwbG9hZFVybCA9PT0gJ3N0cmluZycgJiYgaW1hZ2VVcGxvYWRVcmwubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmlsZXNMZW47IGkrKykge1xuICAgICAgICAgICAgICAgIGZvcm1EYXRhLmFwcGVuZCgnZmlsZS0nICsgaSwgZmlsZXNbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmZpbGVNYW5hZ2VyLnVwbG9hZC5jYWxsKHRoaXMsIGltYWdlVXBsb2FkVXJsLCB0aGlzLmNvbnRleHQub3B0aW9uLmltYWdlVXBsb2FkSGVhZGVyLCBmb3JtRGF0YSwgdGhpcy5wbHVnaW5zLmltYWdlLmNhbGxCYWNrX2ltZ1VwbG9hZC5iaW5kKHRoaXMsIGluZm8pLCB0aGlzLmZ1bmN0aW9ucy5vbkltYWdlVXBsb2FkRXJyb3IpO1xuICAgICAgICB9IGVsc2UgeyAvLyBiYXNlNjRcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5pbWFnZS5zZXR1cF9yZWFkZXIuY2FsbCh0aGlzLCBmaWxlcywgaW5mby5saW5rVmFsdWUsIGluZm8ubGlua05ld1dpbmRvdywgaW5mby5pbnB1dFdpZHRoLCBpbmZvLmlucHV0SGVpZ2h0LCBpbmZvLmFsaWduLCBmaWxlc0xlbiwgaW5mby5pc1VwZGF0ZSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgY2FsbEJhY2tfaW1nVXBsb2FkOiBmdW5jdGlvbiAoaW5mbywgeG1sSHR0cCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuZnVuY3Rpb25zLmltYWdlVXBsb2FkSGFuZGxlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5mdW5jdGlvbnMuaW1hZ2VVcGxvYWRIYW5kbGVyKHhtbEh0dHAsIGluZm8sIHRoaXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBKU09OLnBhcnNlKHhtbEh0dHAucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5lcnJvck1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMuaW1hZ2UuZXJyb3IuY2FsbCh0aGlzLCByZXNwb25zZS5lcnJvck1lc3NhZ2UsIHJlc3BvbnNlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmltYWdlLnJlZ2lzdGVyLmNhbGwodGhpcywgaW5mbywgcmVzcG9uc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSxcblxuICAgIHJlZ2lzdGVyOiBmdW5jdGlvbiAoaW5mbywgcmVzcG9uc2UpIHtcbiAgICAgICAgY29uc3QgZmlsZUxpc3QgPSByZXNwb25zZS5yZXN1bHQ7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGZpbGVMaXN0Lmxlbmd0aCwgZmlsZTsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBmaWxlID0geyBuYW1lOiBmaWxlTGlzdFtpXS5uYW1lLCBzaXplOiBmaWxlTGlzdFtpXS5zaXplIH07XG4gICAgICAgICAgICBpZiAoaW5mby5pc1VwZGF0ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2lucy5pbWFnZS51cGRhdGVfc3JjLmNhbGwodGhpcywgZmlsZUxpc3RbaV0udXJsLCBpbmZvLmVsZW1lbnQsIGZpbGUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMuaW1hZ2UuY3JlYXRlX2ltYWdlLmNhbGwodGhpcywgZmlsZUxpc3RbaV0udXJsLCBpbmZvLmxpbmtWYWx1ZSwgaW5mby5saW5rTmV3V2luZG93LCBpbmZvLmlucHV0V2lkdGgsIGluZm8uaW5wdXRIZWlnaHQsIGluZm8uYWxpZ24sIGZpbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICB0aGlzLmNsb3NlTG9hZGluZygpO1xuICAgIH0sXG5cbiAgICBzZXR1cF9yZWFkZXI6IGZ1bmN0aW9uIChmaWxlcywgaW1nTGlua1ZhbHVlLCBuZXdXaW5kb3dDaGVjaywgd2lkdGgsIGhlaWdodCwgYWxpZ24sIGZpbGVzTGVuLCBpc1VwZGF0ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmltYWdlLmJhc2U2NFJlbmRlckluZGV4ID0gZmlsZXNMZW47XG4gICAgICAgICAgICBjb25zdCB3RmlsZVJlYWRlciA9IHRoaXMuX3cuRmlsZVJlYWRlcjtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVzU3RhY2sgPSBbZmlsZXNMZW5dO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmltYWdlLmlucHV0WC52YWx1ZSA9IHdpZHRoO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmltYWdlLmlucHV0WS52YWx1ZSA9IGhlaWdodDtcbiAgICBcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCByZWFkZXIsIGZpbGU7IGkgPCBmaWxlc0xlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3IHdGaWxlUmVhZGVyKCk7XG4gICAgICAgICAgICAgICAgZmlsZSA9IGZpbGVzW2ldO1xuICAgIFxuICAgICAgICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAocmVhZGVyLCB1cGRhdGUsIHVwZGF0ZUVsZW1lbnQsIGZpbGUsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIGZpbGVzU3RhY2tbaW5kZXhdID0geyByZXN1bHQ6IHJlYWRlci5yZXN1bHQsIGZpbGU6IGZpbGUgfTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoLS10aGlzLmNvbnRleHQuaW1hZ2UuYmFzZTY0UmVuZGVySW5kZXggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2lucy5pbWFnZS5vblJlbmRlcl9pbWdCYXNlNjQuY2FsbCh0aGlzLCB1cGRhdGUsIGZpbGVzU3RhY2ssIHVwZGF0ZUVsZW1lbnQsIGltZ0xpbmtWYWx1ZSwgbmV3V2luZG93Q2hlY2ssIHdpZHRoLCBoZWlnaHQsIGFsaWduKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2xvc2VMb2FkaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LmJpbmQodGhpcywgcmVhZGVyLCBpc1VwZGF0ZSwgdGhpcy5jb250ZXh0LmltYWdlLl9lbGVtZW50LCBmaWxlLCBpKTtcblxuICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlTG9hZGluZygpO1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1tTVU5FRElUT1IuaW1hZ2Uuc2V0dXBfcmVhZGVyLmZhaWxdIGNhdXNlIDogXCInICsgZS5tZXNzYWdlICsgJ1wiJyk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgb25SZW5kZXJfaW1nQmFzZTY0OiBmdW5jdGlvbiAodXBkYXRlLCBmaWxlc1N0YWNrLCB1cGRhdGVFbGVtZW50LCBpbWdMaW5rVmFsdWUsIG5ld1dpbmRvd0NoZWNrLCB3aWR0aCwgaGVpZ2h0LCBhbGlnbikge1xuICAgICAgICBjb25zdCB1cGRhdGVNZXRob2QgPSB0aGlzLnBsdWdpbnMuaW1hZ2UudXBkYXRlX3NyYztcbiAgICAgICAgY29uc3QgY3JlYXRlTWV0aG9kID0gdGhpcy5wbHVnaW5zLmltYWdlLmNyZWF0ZV9pbWFnZTtcbiAgICAgICAgXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBmaWxlc1N0YWNrLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodXBkYXRlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LmltYWdlLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1maWxlLW5hbWUnLCBmaWxlc1N0YWNrW2ldLmZpbGUubmFtZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LmltYWdlLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1maWxlLXNpemUnLCBmaWxlc1N0YWNrW2ldLmZpbGUuc2l6ZSk7XG4gICAgICAgICAgICAgICAgdXBkYXRlTWV0aG9kLmNhbGwodGhpcywgZmlsZXNTdGFja1tpXS5yZXN1bHQsIHVwZGF0ZUVsZW1lbnQsIGZpbGVzU3RhY2tbaV0uZmlsZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNyZWF0ZU1ldGhvZC5jYWxsKHRoaXMsIGZpbGVzU3RhY2tbaV0ucmVzdWx0LCBpbWdMaW5rVmFsdWUsIG5ld1dpbmRvd0NoZWNrLCB3aWR0aCwgaGVpZ2h0LCBhbGlnbiwgZmlsZXNTdGFja1tpXS5maWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBvblJlbmRlcl9pbWdVcmw6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29udGV4dEltYWdlID0gdGhpcy5jb250ZXh0LmltYWdlO1xuICAgICAgICBpZiAoY29udGV4dEltYWdlLl92X3NyYy5fbGlua1ZhbHVlLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBmaWxlID0ge25hbWU6IGNvbnRleHRJbWFnZS5fdl9zcmMuX2xpbmtWYWx1ZS5zcGxpdCgnLycpLnBvcCgpLCBzaXplOiAwfTtcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQuZGlhbG9nLnVwZGF0ZU1vZGFsKSB0aGlzLnBsdWdpbnMuaW1hZ2UudXBkYXRlX3NyYy5jYWxsKHRoaXMsIGNvbnRleHRJbWFnZS5fdl9zcmMuX2xpbmtWYWx1ZSwgY29udGV4dEltYWdlLl9lbGVtZW50LCBmaWxlKTtcbiAgICAgICAgICAgIGVsc2UgdGhpcy5wbHVnaW5zLmltYWdlLmNyZWF0ZV9pbWFnZS5jYWxsKHRoaXMsIGNvbnRleHRJbWFnZS5fdl9zcmMuX2xpbmtWYWx1ZSwgY29udGV4dEltYWdlLl92X2xpbmsuX2xpbmtWYWx1ZSwgY29udGV4dEltYWdlLmltZ0xpbmtOZXdXaW5kb3dDaGVjay5jaGVja2VkLCBjb250ZXh0SW1hZ2UuaW5wdXRYLnZhbHVlLCBjb250ZXh0SW1hZ2UuaW5wdXRZLnZhbHVlLCBjb250ZXh0SW1hZ2UuX2FsaWduLCBmaWxlKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1tTVU5FRElUT1IuaW1hZ2UuVVJMUmVuZGVyaW5nLmZhaWxdIGNhdXNlIDogXCInICsgZS5tZXNzYWdlICsgJ1wiJyk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlTG9hZGluZygpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIG9uUmVuZGVyX2xpbms6IGZ1bmN0aW9uIChpbWdUYWcsIGltZ0xpbmtWYWx1ZSwgbmV3V2luZG93Q2hlY2spIHtcbiAgICAgICAgaWYgKGltZ0xpbmtWYWx1ZS50cmltKCkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgbGluayA9IHRoaXMudXRpbC5jcmVhdGVFbGVtZW50KCdBJyk7XG4gICAgICAgICAgICBsaW5rLmhyZWYgPSAvXmh0dHBzPzpcXC9cXC8vLnRlc3QoaW1nTGlua1ZhbHVlKSA/IGltZ0xpbmtWYWx1ZSA6ICdodHRwOi8vJyArIGltZ0xpbmtWYWx1ZTtcbiAgICAgICAgICAgIGxpbmsudGFyZ2V0ID0gKG5ld1dpbmRvd0NoZWNrID8gJ19ibGFuaycgOiAnJyk7XG4gICAgICAgICAgICBsaW5rLnNldEF0dHJpYnV0ZSgnZGF0YS1pbWFnZS1saW5rJywgJ2ltYWdlJyk7XG4gICAgICAgICAgICBpbWdUYWcuc2V0QXR0cmlidXRlKCdkYXRhLWltYWdlLWxpbmsnLCBpbWdMaW5rVmFsdWUpO1xuXG4gICAgICAgICAgICBsaW5rLmFwcGVuZENoaWxkKGltZ1RhZyk7XG4gICAgICAgICAgICByZXR1cm4gbGluaztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpbWdUYWc7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSByZXNpemluZ1xuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB4eSAneCc6IHdpZHRoLCAneSc6IGhlaWdodFxuICAgICAqIEBwYXJhbSB7S2V5Ym9hcmRFdmVudH0gZSBFdmVudCBvYmplY3RcbiAgICAgKi9cbiAgICBzZXRJbnB1dFNpemU6IGZ1bmN0aW9uICh4eSwgZSkge1xuICAgICAgICBpZiAoZSAmJiBlLmtleUNvZGUgPT09IDMyKSB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnBsdWdpbnMucmVzaXppbmcuX21vZHVsZV9zZXRJbnB1dFNpemUuY2FsbCh0aGlzLCB0aGlzLmNvbnRleHQuaW1hZ2UsIHh5KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIHJlc2l6aW5nXG4gICAgICovXG4gICAgc2V0UmF0aW86IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5wbHVnaW5zLnJlc2l6aW5nLl9tb2R1bGVfc2V0UmF0aW8uY2FsbCh0aGlzLCB0aGlzLmNvbnRleHQuaW1hZ2UpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgZmlsZU1hbmFnZXJcbiAgICAgKi9cbiAgICBjaGVja0ZpbGVJbmZvOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGltYWdlUGx1Z2luID0gdGhpcy5wbHVnaW5zLmltYWdlO1xuXG4gICAgICAgIGNvbnN0IG1vZGlmeUhhbmRsZXIgPSBmdW5jdGlvbiAodGFnKSB7XG4gICAgICAgICAgICBpbWFnZVBsdWdpbi5vbk1vZGlmeU1vZGUuY2FsbCh0aGlzLCB0YWcsIG51bGwpO1xuICAgICAgICAgICAgaW1hZ2VQbHVnaW4ub3Blbk1vZGlmeS5jYWxsKHRoaXMsIHRydWUpO1xuICAgICAgICAgICAgaW1hZ2VQbHVnaW4udXBkYXRlX2ltYWdlLmNhbGwodGhpcywgdHJ1ZSwgZmFsc2UsIHRydWUpO1xuICAgICAgICB9LmJpbmQodGhpcyk7XG5cbiAgICAgICAgdGhpcy5wbHVnaW5zLmZpbGVNYW5hZ2VyLmNoZWNrSW5mby5jYWxsKHRoaXMsICdpbWFnZScsIFsnaW1nJ10sIHRoaXMuZnVuY3Rpb25zLm9uSW1hZ2VVcGxvYWQsIG1vZGlmeUhhbmRsZXIsIHRydWUpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgZmlsZU1hbmFnZXJcbiAgICAgKi9cbiAgICByZXNldEZpbGVJbmZvOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucGx1Z2lucy5maWxlTWFuYWdlci5yZXNldEluZm8uY2FsbCh0aGlzLCAnaW1hZ2UnLCB0aGlzLmZ1bmN0aW9ucy5vbkltYWdlVXBsb2FkKTtcbiAgICB9LFxuXG4gICAgY3JlYXRlX2ltYWdlOiBmdW5jdGlvbiAoc3JjLCBsaW5rVmFsdWUsIGxpbmtOZXdXaW5kb3csIHdpZHRoLCBoZWlnaHQsIGFsaWduLCBmaWxlKSB7XG4gICAgICAgIGNvbnN0IGltYWdlUGx1Z2luID0gdGhpcy5wbHVnaW5zLmltYWdlO1xuICAgICAgICBjb25zdCBjb250ZXh0SW1hZ2UgPSB0aGlzLmNvbnRleHQuaW1hZ2U7XG4gICAgICAgIHRoaXMuY29udGV4dC5yZXNpemluZy5fcmVzaXplX3BsdWdpbiA9ICdpbWFnZSc7XG5cbiAgICAgICAgbGV0IG9JbWcgPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudCgnSU1HJyk7XG4gICAgICAgIG9JbWcuc3JjID0gc3JjO1xuICAgICAgICBvSW1nLmFsdCA9IGNvbnRleHRJbWFnZS5fYWx0VGV4dDtcbiAgICAgICAgb0ltZyA9IGltYWdlUGx1Z2luLm9uUmVuZGVyX2xpbmsuY2FsbCh0aGlzLCBvSW1nLCBsaW5rVmFsdWUsIGxpbmtOZXdXaW5kb3cpO1xuICAgICAgICBvSW1nLnNldEF0dHJpYnV0ZSgnZGF0YS1yb3RhdGUnLCAnMCcpO1xuXG4gICAgICAgIGlmIChjb250ZXh0SW1hZ2UuX3Jlc2l6aW5nKSB7XG4gICAgICAgICAgICBvSW1nLnNldEF0dHJpYnV0ZSgnZGF0YS1wcm9wb3J0aW9uJywgY29udGV4dEltYWdlLl9wcm9wb3J0aW9uQ2hlY2tlZCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb3ZlciA9IHRoaXMucGx1Z2lucy5jb21wb25lbnQuc2V0X2NvdmVyLmNhbGwodGhpcywgb0ltZyk7XG4gICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMucGx1Z2lucy5jb21wb25lbnQuc2V0X2NvbnRhaW5lci5jYWxsKHRoaXMsIGNvdmVyLCAnc2UtaW1hZ2UtY29udGFpbmVyJyk7XG5cbiAgICAgICAgLy8gY2FwdGlvblxuICAgICAgICBpZiAoY29udGV4dEltYWdlLl9jYXB0aW9uQ2hlY2tlZCkge1xuICAgICAgICAgICAgY29udGV4dEltYWdlLl9jYXB0aW9uID0gdGhpcy5wbHVnaW5zLmNvbXBvbmVudC5jcmVhdGVfY2FwdGlvbi5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgY29udGV4dEltYWdlLl9jYXB0aW9uLnNldEF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJywgZmFsc2UpO1xuICAgICAgICAgICAgY292ZXIuYXBwZW5kQ2hpbGQoY29udGV4dEltYWdlLl9jYXB0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRleHRJbWFnZS5fZWxlbWVudCA9IG9JbWc7XG4gICAgICAgIGNvbnRleHRJbWFnZS5fY292ZXIgPSBjb3ZlcjtcbiAgICAgICAgY29udGV4dEltYWdlLl9jb250YWluZXIgPSBjb250YWluZXI7XG5cbiAgICAgICAgLy8gc2V0IHNpemVcbiAgICAgICAgaW1hZ2VQbHVnaW4uYXBwbHlTaXplLmNhbGwodGhpcywgd2lkdGgsIGhlaWdodCk7XG5cbiAgICAgICAgLy8gYWxpZ25cbiAgICAgICAgaW1hZ2VQbHVnaW4uc2V0QWxpZ24uY2FsbCh0aGlzLCBhbGlnbiwgb0ltZywgY292ZXIsIGNvbnRhaW5lcik7XG5cbiAgICAgICAgb0ltZy5vbmxvYWQgPSBpbWFnZVBsdWdpbi5faW1hZ2VfY3JlYXRlX29ubG9hZC5iaW5kKHRoaXMsIG9JbWcsIGNvbnRleHRJbWFnZS5zdmdEZWZhdWx0U2l6ZSk7XG4gICAgICAgIGlmICh0aGlzLmluc2VydENvbXBvbmVudChjb250YWluZXIsIHRydWUsIHRydWUsIHRydWUpKSB0aGlzLnBsdWdpbnMuZmlsZU1hbmFnZXIuc2V0SW5mby5jYWxsKHRoaXMsICdpbWFnZScsIG9JbWcsIHRoaXMuZnVuY3Rpb25zLm9uSW1hZ2VVcGxvYWQsIGZpbGUsIHRydWUpO1xuICAgICAgICB0aGlzLmNvbnRleHQucmVzaXppbmcuX3Jlc2l6ZV9wbHVnaW4gPSAnJztcbiAgICB9LFxuXG4gICAgX2ltYWdlX2NyZWF0ZV9vbmxvYWQ6IGZ1bmN0aW9uIChvSW1nLCBzdmdEZWZhdWx0U2l6ZSkge1xuICAgICAgICAvLyBzdmcgZXhjZXB0aW9uIGhhbmRsaW5nXG4gICAgICAgIGlmIChvSW1nLm9mZnNldFdpZHRoID09PSAwKSB0aGlzLnBsdWdpbnMuaW1hZ2UuYXBwbHlTaXplLmNhbGwodGhpcywgc3ZnRGVmYXVsdFNpemUsICcnKTtcbiAgICAgICAgdGhpcy5zZWxlY3RDb21wb25lbnQuY2FsbCh0aGlzLCBvSW1nLCAnaW1hZ2UnKTtcbiAgICB9LFxuXG4gICAgdXBkYXRlX2ltYWdlOiBmdW5jdGlvbiAoaW5pdCwgb3BlbkNvbnRyb2xsZXIsIG5vdEhpc3RvcnlQdXNoKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRJbWFnZSA9IHRoaXMuY29udGV4dC5pbWFnZTtcbiAgICAgICAgY29uc3QgbGlua1ZhbHVlID0gY29udGV4dEltYWdlLl92X2xpbmsuX2xpbmtWYWx1ZTtcbiAgICAgICAgbGV0IGltYWdlRWwgPSBjb250ZXh0SW1hZ2UuX2VsZW1lbnQ7XG4gICAgICAgIGxldCBjb3ZlciA9IGNvbnRleHRJbWFnZS5fY292ZXI7XG4gICAgICAgIGxldCBjb250YWluZXIgPSBjb250ZXh0SW1hZ2UuX2NvbnRhaW5lcjtcbiAgICAgICAgbGV0IGlzTmV3Q29udGFpbmVyID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKGNvdmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICBpc05ld0NvbnRhaW5lciA9IHRydWU7XG4gICAgICAgICAgICBpbWFnZUVsID0gY29udGV4dEltYWdlLl9lbGVtZW50LmNsb25lTm9kZSh0cnVlKTtcbiAgICAgICAgICAgIGNvdmVyID0gdGhpcy5wbHVnaW5zLmNvbXBvbmVudC5zZXRfY292ZXIuY2FsbCh0aGlzLCBpbWFnZUVsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb250YWluZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvdmVyID0gY292ZXIuY2xvbmVOb2RlKHRydWUpO1xuICAgICAgICAgICAgaW1hZ2VFbCA9IGNvdmVyLnF1ZXJ5U2VsZWN0b3IoJ2ltZycpO1xuICAgICAgICAgICAgaXNOZXdDb250YWluZXIgPSB0cnVlO1xuICAgICAgICAgICAgY29udGFpbmVyID0gdGhpcy5wbHVnaW5zLmNvbXBvbmVudC5zZXRfY29udGFpbmVyLmNhbGwodGhpcywgY292ZXIsICdzZS1pbWFnZS1jb250YWluZXInKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc05ld0NvbnRhaW5lcikge1xuICAgICAgICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9ICcnO1xuICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGNvdmVyKTtcbiAgICAgICAgICAgIGNvbnRleHRJbWFnZS5fY292ZXIgPSBjb3ZlcjtcbiAgICAgICAgICAgIGNvbnRleHRJbWFnZS5fZWxlbWVudCA9IGltYWdlRWw7XG4gICAgICAgICAgICBpc05ld0NvbnRhaW5lciA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY2hlY2sgc2l6ZVxuICAgICAgICBsZXQgY2hhbmdlU2l6ZTtcbiAgICAgICAgY29uc3QgeCA9IHRoaXMudXRpbC5pc051bWJlcihjb250ZXh0SW1hZ2UuaW5wdXRYLnZhbHVlKSA/IGNvbnRleHRJbWFnZS5pbnB1dFgudmFsdWUgKyBjb250ZXh0SW1hZ2Uuc2l6ZVVuaXQgOiBjb250ZXh0SW1hZ2UuaW5wdXRYLnZhbHVlO1xuICAgICAgICBjb25zdCB5ID0gdGhpcy51dGlsLmlzTnVtYmVyKGNvbnRleHRJbWFnZS5pbnB1dFkudmFsdWUpID8gY29udGV4dEltYWdlLmlucHV0WS52YWx1ZSArIGNvbnRleHRJbWFnZS5zaXplVW5pdCA6IGNvbnRleHRJbWFnZS5pbnB1dFkudmFsdWU7XG4gICAgICAgIGlmICgvJSQvLnRlc3QoaW1hZ2VFbC5zdHlsZS53aWR0aCkpIHtcbiAgICAgICAgICAgIGNoYW5nZVNpemUgPSB4ICE9PSBjb250YWluZXIuc3R5bGUud2lkdGggfHwgeSAhPT0gY29udGFpbmVyLnN0eWxlLmhlaWdodDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNoYW5nZVNpemUgPSB4ICE9PSBpbWFnZUVsLnN0eWxlLndpZHRoIHx8IHkgIT09IGltYWdlRWwuc3R5bGUuaGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYWx0XG4gICAgICAgIGltYWdlRWwuYWx0ID0gY29udGV4dEltYWdlLl9hbHRUZXh0O1xuICAgICAgICBcbiAgICAgICAgLy8gY2FwdGlvblxuICAgICAgICBsZXQgbW9kaWZpZWRDYXB0aW9uID0gZmFsc2U7XG4gICAgICAgIGlmIChjb250ZXh0SW1hZ2UuX2NhcHRpb25DaGVja2VkKSB7XG4gICAgICAgICAgICBpZiAoIWNvbnRleHRJbWFnZS5fY2FwdGlvbikge1xuICAgICAgICAgICAgICAgIGNvbnRleHRJbWFnZS5fY2FwdGlvbiA9IHRoaXMucGx1Z2lucy5jb21wb25lbnQuY3JlYXRlX2NhcHRpb24uY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICBjb3Zlci5hcHBlbmRDaGlsZChjb250ZXh0SW1hZ2UuX2NhcHRpb24pO1xuICAgICAgICAgICAgICAgIG1vZGlmaWVkQ2FwdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY29udGV4dEltYWdlLl9jYXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUl0ZW0oY29udGV4dEltYWdlLl9jYXB0aW9uKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0SW1hZ2UuX2NhcHRpb24gPSBudWxsO1xuICAgICAgICAgICAgICAgIG1vZGlmaWVkQ2FwdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBsaW5rXG4gICAgICAgIGlmIChsaW5rVmFsdWUudHJpbSgpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGlmIChjb250ZXh0SW1hZ2UuX2xpbmtFbGVtZW50ICE9PSBudWxsICYmIGNvdmVyLmNvbnRhaW5zKGNvbnRleHRJbWFnZS5fbGlua0VsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgY29udGV4dEltYWdlLl9saW5rRWxlbWVudC5ocmVmID0gbGlua1ZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnRleHRJbWFnZS5fbGlua0VsZW1lbnQudGFyZ2V0ID0gKGNvbnRleHRJbWFnZS5pbWdMaW5rTmV3V2luZG93Q2hlY2suY2hlY2tlZCA/ICdfYmxhbmsnIDogJycpO1xuICAgICAgICAgICAgICAgIGltYWdlRWwuc2V0QXR0cmlidXRlKCdkYXRhLWltYWdlLWxpbmsnLCBsaW5rVmFsdWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgbmV3RWwgPSB0aGlzLnBsdWdpbnMuaW1hZ2Uub25SZW5kZXJfbGluay5jYWxsKHRoaXMsIGltYWdlRWwsIGxpbmtWYWx1ZSwgdGhpcy5jb250ZXh0LmltYWdlLmltZ0xpbmtOZXdXaW5kb3dDaGVjay5jaGVja2VkKTtcbiAgICAgICAgICAgICAgICBjb3Zlci5pbnNlcnRCZWZvcmUobmV3RWwsIGNvbnRleHRJbWFnZS5fY2FwdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoY29udGV4dEltYWdlLl9saW5rRWxlbWVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gaW1hZ2VFbDtcblxuICAgICAgICAgICAgaW1hZ2VFbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1pbWFnZS1saW5rJywgJycpO1xuICAgICAgICAgICAgbGV0IG5ld0VsID0gaW1hZ2VFbGVtZW50LmNsb25lTm9kZSh0cnVlKTtcbiAgICAgICAgICAgIGNvdmVyLnJlbW92ZUNoaWxkKGNvbnRleHRJbWFnZS5fbGlua0VsZW1lbnQpO1xuICAgICAgICAgICAgY292ZXIuaW5zZXJ0QmVmb3JlKG5ld0VsLCBjb250ZXh0SW1hZ2UuX2NhcHRpb24pO1xuICAgICAgICAgICAgaW1hZ2VFbCA9IG5ld0VsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzTmV3Q29udGFpbmVyKSB7XG4gICAgICAgICAgICBjb25zdCBleGlzdEVsZW1lbnQgPSAodGhpcy51dGlsLmlzUmFuZ2VGb3JtYXRFbGVtZW50KGNvbnRleHRJbWFnZS5fZWxlbWVudC5wYXJlbnROb2RlKSB8fCB0aGlzLnV0aWwuaXNXeXNpd3lnRGl2KGNvbnRleHRJbWFnZS5fZWxlbWVudC5wYXJlbnROb2RlKSkgPyBcbiAgICAgICAgICAgICAgICBjb250ZXh0SW1hZ2UuX2VsZW1lbnQgOiBcbiAgICAgICAgICAgICAgICAvXkEkL2kudGVzdChjb250ZXh0SW1hZ2UuX2VsZW1lbnQucGFyZW50Tm9kZS5ub2RlTmFtZSkgPyBjb250ZXh0SW1hZ2UuX2VsZW1lbnQucGFyZW50Tm9kZSA6IHRoaXMudXRpbC5nZXRGb3JtYXRFbGVtZW50KGNvbnRleHRJbWFnZS5fZWxlbWVudCkgfHwgY29udGV4dEltYWdlLl9lbGVtZW50O1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgKHRoaXMudXRpbC5pc0Zvcm1hdEVsZW1lbnQoZXhpc3RFbGVtZW50KSAmJiBleGlzdEVsZW1lbnQudGV4dENvbnRlbnQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGV4aXN0RWxlbWVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShjb250YWluZXIsIGV4aXN0RWxlbWVudC5uZXh0RWxlbWVudFNpYmxpbmcpO1xuICAgICAgICAgICAgICAgIHRoaXMudXRpbC5yZW1vdmVJdGVtKGNvbnRleHRJbWFnZS5fZWxlbWVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGV4aXN0RWxlbWVudC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChjb250YWluZXIsIGV4aXN0RWxlbWVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGltYWdlRWwgPSBjb250YWluZXIucXVlcnlTZWxlY3RvcignaW1nJyk7XG5cbiAgICAgICAgICAgIGNvbnRleHRJbWFnZS5fZWxlbWVudCA9IGltYWdlRWw7XG4gICAgICAgICAgICBjb250ZXh0SW1hZ2UuX2NvdmVyID0gY292ZXI7XG4gICAgICAgICAgICBjb250ZXh0SW1hZ2UuX2NvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHRyYW5zZm9ybVxuICAgICAgICBpZiAobW9kaWZpZWRDYXB0aW9uIHx8ICghY29udGV4dEltYWdlLl9vbmx5UGVyY2VudGFnZSAmJiBjaGFuZ2VTaXplKSkge1xuICAgICAgICAgICAgaWYgKCFpbml0ICYmICgvXFxkKy8udGVzdChpbWFnZUVsLnN0eWxlLmhlaWdodCkgfHwgKHRoaXMuY29udGV4dC5yZXNpemluZy5fcm90YXRlVmVydGljYWwgJiYgY29udGV4dEltYWdlLl9jYXB0aW9uQ2hlY2tlZCkpKSB7XG4gICAgICAgICAgICAgICAgaWYgKC8lJC8udGVzdChjb250ZXh0SW1hZ2UuaW5wdXRYLnZhbHVlKSB8fCAvJSQvLnRlc3QoY29udGV4dEltYWdlLmlucHV0WS52YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnJlc2l6aW5nLnJlc2V0VHJhbnNmb3JtLmNhbGwodGhpcywgaW1hZ2VFbCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnJlc2l6aW5nLnNldFRyYW5zZm9ybVNpemUuY2FsbCh0aGlzLCBpbWFnZUVsLCB0aGlzLnV0aWwuZ2V0TnVtYmVyKGNvbnRleHRJbWFnZS5pbnB1dFgudmFsdWUsIDApLCB0aGlzLnV0aWwuZ2V0TnVtYmVyKGNvbnRleHRJbWFnZS5pbnB1dFkudmFsdWUsIDApKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzaXplXG4gICAgICAgIGxldCBpc1BlcmNlbnQgPSBmYWxzZTtcbiAgICAgICAgaWYgKGNvbnRleHRJbWFnZS5fcmVzaXppbmcpIHtcbiAgICAgICAgICAgIGltYWdlRWwuc2V0QXR0cmlidXRlKCdkYXRhLXByb3BvcnRpb24nLCBjb250ZXh0SW1hZ2UuX3Byb3BvcnRpb25DaGVja2VkKTtcbiAgICAgICAgICAgIGlmIChjaGFuZ2VTaXplKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmltYWdlLmFwcGx5U2l6ZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gYWxpZ25cbiAgICAgICAgaWYgKCEoaXNQZXJjZW50ICYmIGNvbnRleHRJbWFnZS5fYWxpZ24gPT09ICdjZW50ZXInKSkge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmltYWdlLnNldEFsaWduLmNhbGwodGhpcywgbnVsbCwgaW1hZ2VFbCwgbnVsbCwgbnVsbCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzZXQgaW1hZ2VzSW5mb1xuICAgICAgICBpZiAoaW5pdCkge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmZpbGVNYW5hZ2VyLnNldEluZm8uY2FsbCh0aGlzLCAnaW1hZ2UnLCBpbWFnZUVsLCB0aGlzLmZ1bmN0aW9ucy5vbkltYWdlVXBsb2FkLCBudWxsLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvcGVuQ29udHJvbGxlcikge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RDb21wb25lbnQoaW1hZ2VFbCwgJ2ltYWdlJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBoaXN0b3J5IHN0YWNrXG4gICAgICAgIGlmICghbm90SGlzdG9yeVB1c2gpIHRoaXMuaGlzdG9yeS5wdXNoKGZhbHNlKTtcbiAgICB9LFxuXG4gICAgdXBkYXRlX3NyYzogZnVuY3Rpb24gKHNyYywgZWxlbWVudCwgZmlsZSkge1xuICAgICAgICBlbGVtZW50LnNyYyA9IHNyYztcbiAgICAgICAgdGhpcy5fdy5zZXRUaW1lb3V0KHRoaXMucGx1Z2lucy5maWxlTWFuYWdlci5zZXRJbmZvLmJpbmQodGhpcywgJ2ltYWdlJywgZWxlbWVudCwgdGhpcy5mdW5jdGlvbnMub25JbWFnZVVwbG9hZCwgZmlsZSwgdHJ1ZSkpO1xuICAgICAgICB0aGlzLnNlbGVjdENvbXBvbmVudChlbGVtZW50LCAnaW1hZ2UnKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQFJlcXVpcmVkIEBPdmVycmlkZSBmaWxlTWFuYWdlciwgcmVzaXppbmdcbiAgICAgKi9cbiAgICBvbk1vZGlmeU1vZGU6IGZ1bmN0aW9uIChlbGVtZW50LCBzaXplKSB7XG4gICAgICAgIGlmICghZWxlbWVudCkgcmV0dXJuO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgY29udGV4dEltYWdlID0gdGhpcy5jb250ZXh0LmltYWdlO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2xpbmtFbGVtZW50ID0gL15BJC9pLnRlc3QoZWxlbWVudC5wYXJlbnROb2RlLm5vZGVOYW1lKSA/IGVsZW1lbnQucGFyZW50Tm9kZSA6IG51bGw7XG4gICAgICAgIGNvbnRleHRJbWFnZS5fZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgIGNvbnRleHRJbWFnZS5fY292ZXIgPSB0aGlzLnV0aWwuZ2V0UGFyZW50RWxlbWVudChlbGVtZW50LCAnRklHVVJFJyk7XG4gICAgICAgIGNvbnRleHRJbWFnZS5fY29udGFpbmVyID0gdGhpcy51dGlsLmdldFBhcmVudEVsZW1lbnQoZWxlbWVudCwgdGhpcy51dGlsLmlzTWVkaWFDb21wb25lbnQpO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2NhcHRpb24gPSB0aGlzLnV0aWwuZ2V0Q2hpbGRFbGVtZW50KGNvbnRleHRJbWFnZS5fY292ZXIsICdGSUdDQVBUSU9OJyk7XG4gICAgICAgIGNvbnRleHRJbWFnZS5fYWxpZ24gPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1hbGlnbicpIHx8ICdub25lJztcblxuICAgICAgICBpZiAoc2l6ZSkge1xuICAgICAgICAgICAgY29udGV4dEltYWdlLl9lbGVtZW50X3cgPSBzaXplLnc7XG4gICAgICAgICAgICBjb250ZXh0SW1hZ2UuX2VsZW1lbnRfaCA9IHNpemUuaDtcbiAgICAgICAgICAgIGNvbnRleHRJbWFnZS5fZWxlbWVudF90ID0gc2l6ZS50O1xuICAgICAgICAgICAgY29udGV4dEltYWdlLl9lbGVtZW50X2wgPSBzaXplLmw7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdXNlclNpemUgPSBjb250ZXh0SW1hZ2UuX2VsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXNpemUnKSB8fCBjb250ZXh0SW1hZ2UuX2VsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLW9yaWdpbicpO1xuICAgICAgICBpZiAodXNlclNpemUpIHtcbiAgICAgICAgICAgIHVzZXJTaXplID0gdXNlclNpemUuc3BsaXQoJywnKTtcbiAgICAgICAgICAgIGNvbnRleHRJbWFnZS5fb3JpZ2luX3cgPSB1c2VyU2l6ZVswXTtcbiAgICAgICAgICAgIGNvbnRleHRJbWFnZS5fb3JpZ2luX2ggPSB1c2VyU2l6ZVsxXTtcbiAgICAgICAgfSBlbHNlIGlmIChzaXplKSB7XG4gICAgICAgICAgICBjb250ZXh0SW1hZ2UuX29yaWdpbl93ID0gc2l6ZS53O1xuICAgICAgICAgICAgY29udGV4dEltYWdlLl9vcmlnaW5faCA9IHNpemUuaDtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAUmVxdWlyZWQgQE92ZXJyaWRlIGZpbGVNYW5hZ2VyLCByZXNpemluZ1xuICAgICAqL1xuICAgIG9wZW5Nb2RpZnk6IGZ1bmN0aW9uIChub3RPcGVuKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRJbWFnZSA9IHRoaXMuY29udGV4dC5pbWFnZTtcbiAgICAgICAgaWYgKGNvbnRleHRJbWFnZS5pbWdVcmxGaWxlKSB7XG4gICAgICAgICAgICBjb250ZXh0SW1hZ2UuX3Zfc3JjLl9saW5rVmFsdWUgPSBjb250ZXh0SW1hZ2UucHJldmlld1NyYy50ZXh0Q29udGVudCA9IGNvbnRleHRJbWFnZS5pbWdVcmxGaWxlLnZhbHVlID0gY29udGV4dEltYWdlLl9lbGVtZW50LnNyYztcbiAgICAgICAgfVxuICAgICAgICBjb250ZXh0SW1hZ2UuX2FsdFRleHQgPSBjb250ZXh0SW1hZ2UuYWx0VGV4dC52YWx1ZSA9IGNvbnRleHRJbWFnZS5fZWxlbWVudC5hbHQ7XG4gICAgICAgIGNvbnRleHRJbWFnZS5fdl9saW5rLl9saW5rVmFsdWUgPSBjb250ZXh0SW1hZ2UucHJldmlld0xpbmsudGV4dENvbnRlbnQgPSBjb250ZXh0SW1hZ2UuaW1nTGluay52YWx1ZSA9IGNvbnRleHRJbWFnZS5fbGlua0VsZW1lbnQgPT09IG51bGwgPyAnJyA6IGNvbnRleHRJbWFnZS5fbGlua0VsZW1lbnQuaHJlZjtcbiAgICAgICAgY29udGV4dEltYWdlLmltZ0xpbmtOZXdXaW5kb3dDaGVjay5jaGVja2VkID0gY29udGV4dEltYWdlLl9saW5rRWxlbWVudCAmJiBjb250ZXh0SW1hZ2UuX2xpbmtFbGVtZW50LnRhcmdldCA9PT0gJ19ibGFuayc7XG4gICAgICAgIGNvbnRleHRJbWFnZS5tb2RhbC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPVwic3VuZWRpdG9yX2ltYWdlX3JhZGlvXCJdW3ZhbHVlPVwiJyArIGNvbnRleHRJbWFnZS5fYWxpZ24gKyAnXCJdJykuY2hlY2tlZCA9IHRydWU7XG4gICAgICAgIGNvbnRleHRJbWFnZS5fYWxpZ24gPSBjb250ZXh0SW1hZ2UubW9kYWwucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT1cInN1bmVkaXRvcl9pbWFnZV9yYWRpb1wiXTpjaGVja2VkJykudmFsdWU7XG4gICAgICAgIGNvbnRleHRJbWFnZS5fY2FwdGlvbkNoZWNrZWQgPSBjb250ZXh0SW1hZ2UuY2FwdGlvbkNoZWNrRWwuY2hlY2tlZCA9ICEhY29udGV4dEltYWdlLl9jYXB0aW9uO1xuICAgICAgICBcbiAgICAgICAgaWYgKGNvbnRleHRJbWFnZS5fcmVzaXppbmcpIHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5yZXNpemluZy5fbW9kdWxlX3NldE1vZGlmeUlucHV0U2l6ZS5jYWxsKHRoaXMsIGNvbnRleHRJbWFnZSwgdGhpcy5wbHVnaW5zLmltYWdlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghbm90T3BlbikgdGhpcy5wbHVnaW5zLmRpYWxvZy5vcGVuLmNhbGwodGhpcywgJ2ltYWdlJywgdHJ1ZSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSByZXNpemluZ1xuICAgICAqL1xuICAgIHNpemVSZXZlcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5wbHVnaW5zLnJlc2l6aW5nLl9tb2R1bGVfc2l6ZVJldmVydC5jYWxsKHRoaXMsIHRoaXMuY29udGV4dC5pbWFnZSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSByZXNpemluZ1xuICAgICAqL1xuICAgIGFwcGx5U2l6ZTogZnVuY3Rpb24gKHcsIGgpIHtcbiAgICAgICAgY29uc3QgY29udGV4dEltYWdlID0gdGhpcy5jb250ZXh0LmltYWdlO1xuXG4gICAgICAgIGlmICghdykgdyA9IGNvbnRleHRJbWFnZS5pbnB1dFgudmFsdWUgfHwgdGhpcy5jb250ZXh0Lm9wdGlvbi5pbWFnZVdpZHRoO1xuICAgICAgICBpZiAoIWgpIGggPSBjb250ZXh0SW1hZ2UuaW5wdXRZLnZhbHVlIHx8IHRoaXMuY29udGV4dC5vcHRpb24uaW1hZ2VIZWlnaHQ7XG4gICAgICAgIFxuICAgICAgICBpZiAoKGNvbnRleHRJbWFnZS5fb25seVBlcmNlbnRhZ2UgJiYgISF3KSB8fCAvJSQvLnRlc3QodykpIHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5pbWFnZS5zZXRQZXJjZW50U2l6ZS5jYWxsKHRoaXMsIHcsIGgpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAoKCF3IHx8IHcgPT09ICdhdXRvJykgJiYgKCFoIHx8IGggPT09ICdhdXRvJykpIHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5pbWFnZS5zZXRBdXRvU2l6ZS5jYWxsKHRoaXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmltYWdlLnNldFNpemUuY2FsbCh0aGlzLCB3LCBoLCBmYWxzZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSByZXNpemluZ1xuICAgICAqL1xuICAgIHNldFNpemU6IGZ1bmN0aW9uICh3LCBoLCBub3RSZXNldFBlcmNlbnRhZ2UsIGRpcmVjdGlvbikge1xuICAgICAgICBjb25zdCBjb250ZXh0SW1hZ2UgPSB0aGlzLmNvbnRleHQuaW1hZ2U7XG4gICAgICAgIGNvbnN0IG9ubHlXID0gL14ocnd8bHcpJC8udGVzdChkaXJlY3Rpb24pO1xuICAgICAgICBjb25zdCBvbmx5SCA9IC9eKHRofGJoKSQvLnRlc3QoZGlyZWN0aW9uKTtcblxuICAgICAgICB0aGlzLnBsdWdpbnMuaW1hZ2UuY2FuY2VsUGVyY2VudEF0dHIuY2FsbCh0aGlzKTtcblxuICAgICAgICBpZiAoIW9ubHlIKSBjb250ZXh0SW1hZ2UuX2VsZW1lbnQuc3R5bGUud2lkdGggPSB0aGlzLnV0aWwuaXNOdW1iZXIodykgPyB3ICsgY29udGV4dEltYWdlLnNpemVVbml0IDogdztcbiAgICAgICAgaWYgKCFvbmx5VykgY29udGV4dEltYWdlLl9lbGVtZW50LnN0eWxlLmhlaWdodCA9IHRoaXMudXRpbC5pc051bWJlcihoKSA/IGggKyBjb250ZXh0SW1hZ2Uuc2l6ZVVuaXQgOiAvJSQvLnRlc3QoaCkgPyAnJyA6IGg7XG5cbiAgICAgICAgaWYgKGNvbnRleHRJbWFnZS5fYWxpZ24gPT09ICdjZW50ZXInKSB0aGlzLnBsdWdpbnMuaW1hZ2Uuc2V0QWxpZ24uY2FsbCh0aGlzLCBudWxsLCBudWxsLCBudWxsLCBudWxsKTtcbiAgICAgICAgaWYgKCFub3RSZXNldFBlcmNlbnRhZ2UpIGNvbnRleHRJbWFnZS5fZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ2RhdGEtcGVyY2VudGFnZScpO1xuXG4gICAgICAgIC8vIHNhdmUgY3VycmVudCBzaXplXG4gICAgICAgIHRoaXMucGx1Z2lucy5yZXNpemluZy5fbW9kdWxlX3NhdmVDdXJyZW50U2l6ZS5jYWxsKHRoaXMsIGNvbnRleHRJbWFnZSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSByZXNpemluZ1xuICAgICAqL1xuICAgIHNldEF1dG9TaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRJbWFnZSA9IHRoaXMuY29udGV4dC5pbWFnZTtcblxuICAgICAgICB0aGlzLnBsdWdpbnMucmVzaXppbmcucmVzZXRUcmFuc2Zvcm0uY2FsbCh0aGlzLCBjb250ZXh0SW1hZ2UuX2VsZW1lbnQpO1xuICAgICAgICB0aGlzLnBsdWdpbnMuaW1hZ2UuY2FuY2VsUGVyY2VudEF0dHIuY2FsbCh0aGlzKTtcblxuICAgICAgICBjb250ZXh0SW1hZ2UuX2VsZW1lbnQuc3R5bGUubWF4V2lkdGggPSAnJztcbiAgICAgICAgY29udGV4dEltYWdlLl9lbGVtZW50LnN0eWxlLndpZHRoID0gJyc7XG4gICAgICAgIGNvbnRleHRJbWFnZS5fZWxlbWVudC5zdHlsZS5oZWlnaHQgPSAnJztcbiAgICAgICAgY29udGV4dEltYWdlLl9jb3Zlci5zdHlsZS53aWR0aCA9ICcnO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2NvdmVyLnN0eWxlLmhlaWdodCA9ICcnO1xuXG4gICAgICAgIHRoaXMucGx1Z2lucy5pbWFnZS5zZXRBbGlnbi5jYWxsKHRoaXMsIG51bGwsIG51bGwsIG51bGwsIG51bGwpO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLXBlcmNlbnRhZ2UnLCAnYXV0byxhdXRvJyk7XG5cbiAgICAgICAgLy8gc2F2ZSBjdXJyZW50IHNpemVcbiAgICAgICAgdGhpcy5wbHVnaW5zLnJlc2l6aW5nLl9tb2R1bGVfc2F2ZUN1cnJlbnRTaXplLmNhbGwodGhpcywgY29udGV4dEltYWdlKTtcbiAgICB9LFxuICAgIFxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSByZXNpemluZ1xuICAgICAqL1xuICAgIHNldE9yaWdpblNpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29udGV4dEltYWdlID0gdGhpcy5jb250ZXh0LmltYWdlO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2VsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdkYXRhLXBlcmNlbnRhZ2UnKTtcblxuICAgICAgICB0aGlzLnBsdWdpbnMucmVzaXppbmcucmVzZXRUcmFuc2Zvcm0uY2FsbCh0aGlzLCBjb250ZXh0SW1hZ2UuX2VsZW1lbnQpO1xuICAgICAgICB0aGlzLnBsdWdpbnMuaW1hZ2UuY2FuY2VsUGVyY2VudEF0dHIuY2FsbCh0aGlzKTtcblxuICAgICAgICBjb25zdCBvcmlnaW5TaXplID0gKGNvbnRleHRJbWFnZS5fZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtb3JpZ2luJykgfHwgJycpLnNwbGl0KCcsJyk7XG4gICAgICAgIGNvbnN0IHcgPSBvcmlnaW5TaXplWzBdO1xuICAgICAgICBjb25zdCBoID0gb3JpZ2luU2l6ZVsxXTtcblxuICAgICAgICBpZiAob3JpZ2luU2l6ZSkge1xuICAgICAgICAgICAgaWYgKGNvbnRleHRJbWFnZS5fb25seVBlcmNlbnRhZ2UgfHwgKC8lJC8udGVzdCh3KSAmJiAoLyUkLy50ZXN0KGgpIHx8ICEvXFxkLy50ZXN0KGgpKSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMuaW1hZ2Uuc2V0UGVyY2VudFNpemUuY2FsbCh0aGlzLCB3LCBoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmltYWdlLnNldFNpemUuY2FsbCh0aGlzLCB3LCBoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gc2F2ZSBjdXJyZW50IHNpemVcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5yZXNpemluZy5fbW9kdWxlX3NhdmVDdXJyZW50U2l6ZS5jYWxsKHRoaXMsIGNvbnRleHRJbWFnZSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIHJlc2l6aW5nXG4gICAgICovXG4gICAgc2V0UGVyY2VudFNpemU6IGZ1bmN0aW9uICh3LCBoKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRJbWFnZSA9IHRoaXMuY29udGV4dC5pbWFnZTtcbiAgICAgICAgaCA9ICEhaCAmJiAhLyUkLy50ZXN0KGgpICYmICF0aGlzLnV0aWwuZ2V0TnVtYmVyKGgsIDApID8gdGhpcy51dGlsLmlzTnVtYmVyKGgpID8gaCArICclJyA6IGggOiB0aGlzLnV0aWwuaXNOdW1iZXIoaCkgPyBoICsgY29udGV4dEltYWdlLnNpemVVbml0IDogKGggfHwgJycpO1xuICAgICAgICBjb25zdCBoZWlnaHRQZXJjZW50YWdlID0gLyUkLy50ZXN0KGgpO1xuXG4gICAgICAgIGNvbnRleHRJbWFnZS5fY29udGFpbmVyLnN0eWxlLndpZHRoID0gdGhpcy51dGlsLmlzTnVtYmVyKHcpID8gdyArICclJyA6IHc7XG4gICAgICAgIGNvbnRleHRJbWFnZS5fY29udGFpbmVyLnN0eWxlLmhlaWdodCA9ICcnO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2NvdmVyLnN0eWxlLndpZHRoID0gJzEwMCUnO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2NvdmVyLnN0eWxlLmhlaWdodCA9ICFoZWlnaHRQZXJjZW50YWdlID8gJycgOiBoO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2VsZW1lbnQuc3R5bGUud2lkdGggPSAnMTAwJSc7XG4gICAgICAgIGNvbnRleHRJbWFnZS5fZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBoZWlnaHRQZXJjZW50YWdlID8gJycgOiBoO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2VsZW1lbnQuc3R5bGUubWF4V2lkdGggPSAnJztcblxuICAgICAgICBpZiAoY29udGV4dEltYWdlLl9hbGlnbiA9PT0gJ2NlbnRlcicpIHRoaXMucGx1Z2lucy5pbWFnZS5zZXRBbGlnbi5jYWxsKHRoaXMsIG51bGwsIG51bGwsIG51bGwsIG51bGwpO1xuXG4gICAgICAgIGNvbnRleHRJbWFnZS5fZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2RhdGEtcGVyY2VudGFnZScsIHcgKyAnLCcgKyBoKTtcbiAgICAgICAgdGhpcy5wbHVnaW5zLnJlc2l6aW5nLnNldENhcHRpb25Qb3NpdGlvbi5jYWxsKHRoaXMsIGNvbnRleHRJbWFnZS5fZWxlbWVudCk7XG5cbiAgICAgICAgLy8gc2F2ZSBjdXJyZW50IHNpemVcbiAgICAgICAgdGhpcy5wbHVnaW5zLnJlc2l6aW5nLl9tb2R1bGVfc2F2ZUN1cnJlbnRTaXplLmNhbGwodGhpcywgY29udGV4dEltYWdlKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIHJlc2l6aW5nXG4gICAgICovXG4gICAgY2FuY2VsUGVyY2VudEF0dHI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29udGV4dEltYWdlID0gdGhpcy5jb250ZXh0LmltYWdlO1xuICAgICAgICBcbiAgICAgICAgY29udGV4dEltYWdlLl9jb3Zlci5zdHlsZS53aWR0aCA9ICcnO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2NvdmVyLnN0eWxlLmhlaWdodCA9ICcnO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2NvbnRhaW5lci5zdHlsZS53aWR0aCA9ICcnO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2NvbnRhaW5lci5zdHlsZS5oZWlnaHQgPSAnJztcblxuICAgICAgICB0aGlzLnV0aWwucmVtb3ZlQ2xhc3MoY29udGV4dEltYWdlLl9jb250YWluZXIsIHRoaXMuY29udGV4dC5pbWFnZS5fZmxvYXRDbGFzc1JlZ0V4cCk7XG4gICAgICAgIHRoaXMudXRpbC5hZGRDbGFzcyhjb250ZXh0SW1hZ2UuX2NvbnRhaW5lciwgJ19fc2VfX2Zsb2F0LScgKyBjb250ZXh0SW1hZ2UuX2FsaWduKTtcblxuICAgICAgICBpZiAoY29udGV4dEltYWdlLl9hbGlnbiA9PT0gJ2NlbnRlcicpIHRoaXMucGx1Z2lucy5pbWFnZS5zZXRBbGlnbi5jYWxsKHRoaXMsIG51bGwsIG51bGwsIG51bGwsIG51bGwpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgcmVzaXppbmdcbiAgICAgKi9cbiAgICBzZXRBbGlnbjogZnVuY3Rpb24gKGFsaWduLCBlbGVtZW50LCBjb3ZlciwgY29udGFpbmVyKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRJbWFnZSA9IHRoaXMuY29udGV4dC5pbWFnZTtcbiAgICAgICAgXG4gICAgICAgIGlmICghYWxpZ24pIGFsaWduID0gY29udGV4dEltYWdlLl9hbGlnbjtcbiAgICAgICAgaWYgKCFlbGVtZW50KSBlbGVtZW50ID0gY29udGV4dEltYWdlLl9lbGVtZW50O1xuICAgICAgICBpZiAoIWNvdmVyKSBjb3ZlciA9IGNvbnRleHRJbWFnZS5fY292ZXI7XG4gICAgICAgIGlmICghY29udGFpbmVyKSBjb250YWluZXIgPSBjb250ZXh0SW1hZ2UuX2NvbnRhaW5lcjtcblxuICAgICAgICBpZiAoYWxpZ24gJiYgYWxpZ24gIT09ICdub25lJykge1xuICAgICAgICAgICAgY292ZXIuc3R5bGUubWFyZ2luID0gJ2F1dG8nO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY292ZXIuc3R5bGUubWFyZ2luID0gJzAnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKC8lJC8udGVzdChlbGVtZW50LnN0eWxlLndpZHRoKSAmJiBhbGlnbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5zdHlsZS5taW5XaWR0aCA9ICcxMDAlJztcbiAgICAgICAgICAgIGNvdmVyLnN0eWxlLndpZHRoID0gY29udGFpbmVyLnN0eWxlLndpZHRoO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udGFpbmVyLnN0eWxlLm1pbldpZHRoID0gJyc7XG4gICAgICAgICAgICBjb3Zlci5zdHlsZS53aWR0aCA9IHRoaXMuY29udGV4dC5yZXNpemluZy5fcm90YXRlVmVydGljYWwgPyAoZWxlbWVudC5zdHlsZS5oZWlnaHQgfHwgZWxlbWVudC5vZmZzZXRIZWlnaHQpIDogKCghZWxlbWVudC5zdHlsZS53aWR0aCB8fCBlbGVtZW50LnN0eWxlLndpZHRoID09PSAnYXV0bycpID8gJycgOiBlbGVtZW50LnN0eWxlLndpZHRoIHx8ICcxMDAlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMudXRpbC5oYXNDbGFzcyhjb250YWluZXIsICdfX3NlX19mbG9hdC0nICsgYWxpZ24pKSB7XG4gICAgICAgICAgICB0aGlzLnV0aWwucmVtb3ZlQ2xhc3MoY29udGFpbmVyLCBjb250ZXh0SW1hZ2UuX2Zsb2F0Q2xhc3NSZWdFeHApO1xuICAgICAgICAgICAgdGhpcy51dGlsLmFkZENsYXNzKGNvbnRhaW5lciwgJ19fc2VfX2Zsb2F0LScgKyBhbGlnbik7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLWFsaWduJywgYWxpZ24pO1xuICAgIH0sXG5cbiAgICByZXNldEFsaWduOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRJbWFnZSA9IHRoaXMuY29udGV4dC5pbWFnZTtcblxuICAgICAgICBjb250ZXh0SW1hZ2UuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLWFsaWduJywgJycpO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2FsaWduID0gJ25vbmUnO1xuICAgICAgICBjb250ZXh0SW1hZ2UuX2NvdmVyLnN0eWxlLm1hcmdpbiA9ICcwJztcbiAgICAgICAgdGhpcy51dGlsLnJlbW92ZUNsYXNzKGNvbnRleHRJbWFnZS5fY29udGFpbmVyLCBjb250ZXh0SW1hZ2UuX2Zsb2F0Q2xhc3NSZWdFeHApO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgZGlhbG9nXG4gICAgICovXG4gICAgaW5pdDogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb250ZXh0SW1hZ2UgPSB0aGlzLmNvbnRleHQuaW1hZ2U7XG4gICAgICAgIGlmIChjb250ZXh0SW1hZ2UuaW1nSW5wdXRGaWxlKSBjb250ZXh0SW1hZ2UuaW1nSW5wdXRGaWxlLnZhbHVlID0gJyc7XG4gICAgICAgIGlmIChjb250ZXh0SW1hZ2UuaW1nVXJsRmlsZSkgY29udGV4dEltYWdlLl92X3NyYy5fbGlua1ZhbHVlID0gY29udGV4dEltYWdlLnByZXZpZXdTcmMudGV4dENvbnRlbnQgPSBjb250ZXh0SW1hZ2UuaW1nVXJsRmlsZS52YWx1ZSA9ICcnO1xuICAgICAgICBpZiAoY29udGV4dEltYWdlLmltZ0lucHV0RmlsZSAmJiBjb250ZXh0SW1hZ2UuaW1nVXJsRmlsZSkge1xuICAgICAgICAgICAgY29udGV4dEltYWdlLmltZ1VybEZpbGUucmVtb3ZlQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xuICAgICAgICAgICAgY29udGV4dEltYWdlLnByZXZpZXdTcmMuc3R5bGUudGV4dERlY29yYXRpb24gPSAnJztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRleHRJbWFnZS5hbHRUZXh0LnZhbHVlID0gJyc7XG4gICAgICAgIGNvbnRleHRJbWFnZS5fdl9saW5rLl9saW5rVmFsdWUgPSBjb250ZXh0SW1hZ2UucHJldmlld0xpbmsudGV4dENvbnRlbnQgPSBjb250ZXh0SW1hZ2UuaW1nTGluay52YWx1ZSA9ICcnO1xuICAgICAgICBjb250ZXh0SW1hZ2UuaW1nTGlua05ld1dpbmRvd0NoZWNrLmNoZWNrZWQgPSBmYWxzZTtcbiAgICAgICAgY29udGV4dEltYWdlLm1vZGFsLnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W25hbWU9XCJzdW5lZGl0b3JfaW1hZ2VfcmFkaW9cIl1bdmFsdWU9XCJub25lXCJdJykuY2hlY2tlZCA9IHRydWU7XG4gICAgICAgIGNvbnRleHRJbWFnZS5jYXB0aW9uQ2hlY2tFbC5jaGVja2VkID0gZmFsc2U7XG4gICAgICAgIGNvbnRleHRJbWFnZS5fZWxlbWVudCA9IG51bGw7XG4gICAgICAgIHRoaXMucGx1Z2lucy5pbWFnZS5vcGVuVGFiLmNhbGwodGhpcywgJ2luaXQnKTtcblxuICAgICAgICBpZiAoY29udGV4dEltYWdlLl9yZXNpemluZykge1xuICAgICAgICAgICAgY29udGV4dEltYWdlLmlucHV0WC52YWx1ZSA9IHRoaXMuY29udGV4dC5vcHRpb24uaW1hZ2VXaWR0aCA9PT0gY29udGV4dEltYWdlLl9kZWZhdWx0U2l6ZVggPyAnJyA6IHRoaXMuY29udGV4dC5vcHRpb24uaW1hZ2VXaWR0aDtcbiAgICAgICAgICAgIGNvbnRleHRJbWFnZS5pbnB1dFkudmFsdWUgPSB0aGlzLmNvbnRleHQub3B0aW9uLmltYWdlSGVpZ2h0ID09PSBjb250ZXh0SW1hZ2UuX2RlZmF1bHRTaXplWSA/ICcnIDogdGhpcy5jb250ZXh0Lm9wdGlvbi5pbWFnZUhlaWdodDtcbiAgICAgICAgICAgIGNvbnRleHRJbWFnZS5wcm9wb3J0aW9uLmNoZWNrZWQgPSB0cnVlO1xuICAgICAgICAgICAgY29udGV4dEltYWdlLl9yYXRpbyA9IGZhbHNlO1xuICAgICAgICAgICAgY29udGV4dEltYWdlLl9yYXRpb1ggPSAxO1xuICAgICAgICAgICAgY29udGV4dEltYWdlLl9yYXRpb1kgPSAxO1xuICAgICAgICB9XG4gICAgfVxufTtcbiIsIi8qXG4gKiB3eXNpd3lnIHdlYiBlZGl0b3JcbiAqXG4gKiBzdW5lZGl0b3IuanNcbiAqIENvcHlyaWdodCAyMDE3IEppSG9uZyBMZWUuXG4gKiBNSVQgbGljZW5zZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgZGlhbG9nIGZyb20gJy4uL21vZHVsZXMvZGlhbG9nJztcbmltcG9ydCBjb21wb25lbnQgZnJvbSAnLi4vbW9kdWxlcy9jb21wb25lbnQnO1xuaW1wb3J0IHJlc2l6aW5nIGZyb20gJy4uL21vZHVsZXMvcmVzaXppbmcnO1xuaW1wb3J0IGZpbGVNYW5hZ2VyIGZyb20gJy4uL21vZHVsZXMvZmlsZU1hbmFnZXInO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gICAgbmFtZTogJ3ZpZGVvJyxcbiAgICBkaXNwbGF5OiAnZGlhbG9nJyxcbiAgICBhZGQ6IGZ1bmN0aW9uIChjb3JlKSB7XG4gICAgICAgIGNvcmUuYWRkTW9kdWxlKFtkaWFsb2csIGNvbXBvbmVudCwgcmVzaXppbmcsIGZpbGVNYW5hZ2VyXSk7XG5cbiAgICAgICAgY29uc3QgY29udGV4dCA9IGNvcmUuY29udGV4dDtcbiAgICAgICAgY29uc3QgY29udGV4dFZpZGVvID0gY29udGV4dC52aWRlbyA9IHtcbiAgICAgICAgICAgIF9pbmZvTGlzdDogW10sIC8vIEBPdmVycmlkZSBmaWxlTWFuYWdlclxuICAgICAgICAgICAgX2luZm9JbmRleDogMCwgLy8gQE92ZXJyaWRlIGZpbGVNYW5hZ2VyXG4gICAgICAgICAgICBfdXBsb2FkRmlsZUxlbmd0aDogMCwgLy8gQE92ZXJyaWRlIGZpbGVNYW5hZ2VyXG4gICAgICAgICAgICBzaXplVW5pdDogY29udGV4dC5vcHRpb24uX3ZpZGVvU2l6ZVVuaXQsXG4gICAgICAgICAgICBfYWxpZ246ICdub25lJyxcbiAgICAgICAgICAgIF9mbG9hdENsYXNzUmVnRXhwOiAnX19zZV9fZmxvYXRcXFxcLVthLXpdKycsXG4gICAgICAgICAgICBfeW91dHViZVF1ZXJ5OiBjb250ZXh0Lm9wdGlvbi55b3V0dWJlUXVlcnksXG4gICAgICAgICAgICBfdmlkZW9SYXRpbzogKGNvbnRleHQub3B0aW9uLnZpZGVvUmF0aW8gKiAxMDApICsgJyUnLFxuICAgICAgICAgICAgX2RlZmF1bHRSYXRpbzogKGNvbnRleHQub3B0aW9uLnZpZGVvUmF0aW8gKiAxMDApICsgJyUnLFxuICAgICAgICAgICAgX2xpbmtWYWx1ZTogJycsXG4gICAgICAgICAgICAvLyBAcmVxdWlyZSBAT3ZlcnJpZGUgY29tcG9uZW50XG4gICAgICAgICAgICBfZWxlbWVudDogbnVsbCxcbiAgICAgICAgICAgIF9jb3ZlcjogbnVsbCxcbiAgICAgICAgICAgIF9jb250YWluZXI6IG51bGwsXG4gICAgICAgICAgICAvLyBAT3ZlcnJpZGUgcmVzaXppbmcgcHJvcGVydGllc1xuICAgICAgICAgICAgaW5wdXRYOiBudWxsLFxuICAgICAgICAgICAgaW5wdXRZOiBudWxsLFxuICAgICAgICAgICAgX2VsZW1lbnRfdzogMSxcbiAgICAgICAgICAgIF9lbGVtZW50X2g6IDEsXG4gICAgICAgICAgICBfZWxlbWVudF9sOiAwLFxuICAgICAgICAgICAgX2VsZW1lbnRfdDogMCxcbiAgICAgICAgICAgIF9kZWZhdWx0U2l6ZVg6ICcxMDAlJyxcbiAgICAgICAgICAgIF9kZWZhdWx0U2l6ZVk6IChjb250ZXh0Lm9wdGlvbi52aWRlb1JhdGlvICogMTAwKSArICclJyxcbiAgICAgICAgICAgIF9vcmlnaW5fdzogY29udGV4dC5vcHRpb24udmlkZW9XaWR0aCA9PT0gJzEwMCUnID8gJycgOiBjb250ZXh0Lm9wdGlvbi52aWRlb1dpZHRoLFxuICAgICAgICAgICAgX29yaWdpbl9oOiBjb250ZXh0Lm9wdGlvbi52aWRlb0hlaWdodCA9PT0gJzU2LjI1JScgPyAnJyA6IGNvbnRleHQub3B0aW9uLnZpZGVvSGVpZ2h0LFxuICAgICAgICAgICAgX3Byb3BvcnRpb25DaGVja2VkOiB0cnVlLFxuICAgICAgICAgICAgX3Jlc2l6aW5nOiBjb250ZXh0Lm9wdGlvbi52aWRlb1Jlc2l6aW5nLFxuICAgICAgICAgICAgX3Jlc2l6ZURvdEhpZGU6ICFjb250ZXh0Lm9wdGlvbi52aWRlb0hlaWdodFNob3csXG4gICAgICAgICAgICBfcm90YXRpb246IGNvbnRleHQub3B0aW9uLnZpZGVvUm90YXRpb24sXG4gICAgICAgICAgICBfb25seVBlcmNlbnRhZ2U6IGNvbnRleHQub3B0aW9uLnZpZGVvU2l6ZU9ubHlQZXJjZW50YWdlLFxuICAgICAgICAgICAgX3JhdGlvOiBmYWxzZSxcbiAgICAgICAgICAgIF9yYXRpb1g6IDEsXG4gICAgICAgICAgICBfcmF0aW9ZOiAxLFxuICAgICAgICAgICAgX2NhcHRpb25TaG93OiBmYWxzZVxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKiB2aWRlbyBkaWFsb2cgKi9cbiAgICAgICAgbGV0IHZpZGVvX2RpYWxvZyA9IHRoaXMuc2V0RGlhbG9nLmNhbGwoY29yZSk7XG4gICAgICAgIGNvbnRleHRWaWRlby5tb2RhbCA9IHZpZGVvX2RpYWxvZztcbiAgICAgICAgY29udGV4dFZpZGVvLnZpZGVvSW5wdXRGaWxlID0gdmlkZW9fZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfdmlkZW9fZmlsZScpO1xuICAgICAgICBjb250ZXh0VmlkZW8udmlkZW9VcmxGaWxlID0gdmlkZW9fZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5zZS1pbnB1dC11cmwnKTtcbiAgICAgICAgY29udGV4dFZpZGVvLmZvY3VzRWxlbWVudCA9IGNvbnRleHRWaWRlby52aWRlb1VybEZpbGUgfHwgY29udGV4dFZpZGVvLnZpZGVvSW5wdXRGaWxlO1xuICAgICAgICBjb250ZXh0VmlkZW8ucHJldmlldyA9IHZpZGVvX2RpYWxvZy5xdWVyeVNlbGVjdG9yKCcuc2UtbGluay1wcmV2aWV3Jyk7XG5cbiAgICAgICAgLyoqIGFkZCBldmVudCBsaXN0ZW5lcnMgKi9cbiAgICAgICAgdmlkZW9fZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5zZS1idG4tcHJpbWFyeScpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5zdWJtaXQuYmluZChjb3JlKSk7XG4gICAgICAgIGlmIChjb250ZXh0VmlkZW8udmlkZW9JbnB1dEZpbGUpIHZpZGVvX2RpYWxvZy5xdWVyeVNlbGVjdG9yKCcuc2UtZGlhbG9nLWZpbGVzLWVkZ2UtYnV0dG9uJykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9yZW1vdmVTZWxlY3RlZEZpbGVzLmJpbmQoY29udGV4dFZpZGVvLnZpZGVvSW5wdXRGaWxlLCBjb250ZXh0VmlkZW8udmlkZW9VcmxGaWxlLCBjb250ZXh0VmlkZW8ucHJldmlldykpO1xuICAgICAgICBpZiAoY29udGV4dFZpZGVvLnZpZGVvSW5wdXRGaWxlICYmIGNvbnRleHRWaWRlby52aWRlb1VybEZpbGUpIGNvbnRleHRWaWRlby52aWRlb0lucHV0RmlsZS5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCB0aGlzLl9maWxlSW5wdXRDaGFuZ2UuYmluZChjb250ZXh0VmlkZW8pKTtcbiAgICAgICAgaWYgKGNvbnRleHRWaWRlby52aWRlb1VybEZpbGUpIGNvbnRleHRWaWRlby52aWRlb1VybEZpbGUuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCB0aGlzLl9vbkxpbmtQcmV2aWV3LmJpbmQoY29udGV4dFZpZGVvLnByZXZpZXcsIGNvbnRleHRWaWRlbywgY29udGV4dC5vcHRpb25zLmxpbmtQcm90b2NvbCkpO1xuXG4gICAgICAgIGNvbnRleHRWaWRlby5wcm9wb3J0aW9uID0ge307XG4gICAgICAgIGNvbnRleHRWaWRlby52aWRlb1JhdGlvT3B0aW9uID0ge307XG4gICAgICAgIGNvbnRleHRWaWRlby5pbnB1dFggPSB7fTtcbiAgICAgICAgY29udGV4dFZpZGVvLmlucHV0WSA9IHt9O1xuICAgICAgICBpZiAoY29udGV4dC5vcHRpb24udmlkZW9SZXNpemluZykge1xuICAgICAgICAgICAgY29udGV4dFZpZGVvLnByb3BvcnRpb24gPSB2aWRlb19kaWFsb2cucXVlcnlTZWxlY3RvcignLl9zZV92aWRlb19jaGVja19wcm9wb3J0aW9uJyk7XG4gICAgICAgICAgICBjb250ZXh0VmlkZW8udmlkZW9SYXRpb09wdGlvbiA9IHZpZGVvX2RpYWxvZy5xdWVyeVNlbGVjdG9yKCcuc2UtdmlkZW8tcmF0aW8nKTtcbiAgICAgICAgICAgIGNvbnRleHRWaWRlby5pbnB1dFggPSB2aWRlb19kaWFsb2cucXVlcnlTZWxlY3RvcignLl9zZV92aWRlb19zaXplX3gnKTtcbiAgICAgICAgICAgIGNvbnRleHRWaWRlby5pbnB1dFkgPSB2aWRlb19kaWFsb2cucXVlcnlTZWxlY3RvcignLl9zZV92aWRlb19zaXplX3knKTtcbiAgICAgICAgICAgIGNvbnRleHRWaWRlby5pbnB1dFgudmFsdWUgPSBjb250ZXh0Lm9wdGlvbi52aWRlb1dpZHRoO1xuICAgICAgICAgICAgY29udGV4dFZpZGVvLmlucHV0WS52YWx1ZSA9IGNvbnRleHQub3B0aW9uLnZpZGVvSGVpZ2h0O1xuXG4gICAgICAgICAgICBjb250ZXh0VmlkZW8uaW5wdXRYLmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgdGhpcy5zZXRJbnB1dFNpemUuYmluZChjb3JlLCAneCcpKTtcbiAgICAgICAgICAgIGNvbnRleHRWaWRlby5pbnB1dFkuYWRkRXZlbnRMaXN0ZW5lcigna2V5dXAnLCB0aGlzLnNldElucHV0U2l6ZS5iaW5kKGNvcmUsICd5JykpO1xuXG4gICAgICAgICAgICBjb250ZXh0VmlkZW8uaW5wdXRYLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHRoaXMuc2V0UmF0aW8uYmluZChjb3JlKSk7XG4gICAgICAgICAgICBjb250ZXh0VmlkZW8uaW5wdXRZLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHRoaXMuc2V0UmF0aW8uYmluZChjb3JlKSk7XG4gICAgICAgICAgICBjb250ZXh0VmlkZW8ucHJvcG9ydGlvbi5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCB0aGlzLnNldFJhdGlvLmJpbmQoY29yZSkpO1xuICAgICAgICAgICAgY29udGV4dFZpZGVvLnZpZGVvUmF0aW9PcHRpb24uYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5zZXRWaWRlb1JhdGlvLmJpbmQoY29yZSkpO1xuXG4gICAgICAgICAgICB2aWRlb19kaWFsb2cucXVlcnlTZWxlY3RvcignLnNlLWRpYWxvZy1idG4tcmV2ZXJ0JykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLnNpemVSZXZlcnQuYmluZChjb3JlKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiogYXBwZW5kIGh0bWwgKi9cbiAgICAgICAgY29udGV4dC5kaWFsb2cubW9kYWwuYXBwZW5kQ2hpbGQodmlkZW9fZGlhbG9nKTtcblxuICAgICAgICAvKiogZW1wdHkgbWVtb3J5ICovXG4gICAgICAgIHZpZGVvX2RpYWxvZyA9IG51bGw7XG4gICAgfSxcblxuICAgIC8qKiBkaWFsb2cgKi9cbiAgICBzZXREaWFsb2c6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9uID0gdGhpcy5jb250ZXh0Lm9wdGlvbjtcbiAgICAgICAgY29uc3QgbGFuZyA9IHRoaXMubGFuZztcbiAgICAgICAgY29uc3QgZGlhbG9nID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xuXG4gICAgICAgIGRpYWxvZy5jbGFzc05hbWUgPSAnc2UtZGlhbG9nLWNvbnRlbnQnO1xuICAgICAgICBkaWFsb2cuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgbGV0IGh0bWwgPSAnJyArXG4gICAgICAgICAgICAnPGZvcm0gbWV0aG9kPVwicG9zdFwiIGVuY3R5cGU9XCJtdWx0aXBhcnQvZm9ybS1kYXRhXCI+JyArXG4gICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1kaWFsb2ctaGVhZGVyXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJjbG9zZVwiIGNsYXNzPVwic2UtYnRuIHNlLWRpYWxvZy1jbG9zZVwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiIHRpdGxlPVwiJyArIGxhbmcuZGlhbG9nQm94LmNsb3NlICsgJ1wiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pY29ucy5jYW5jZWwgK1xuICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLW1vZGFsLXRpdGxlXCI+JyArIGxhbmcuZGlhbG9nQm94LnZpZGVvQm94LnRpdGxlICsgJzwvc3Bhbj4nICtcbiAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1kaWFsb2ctYm9keVwiPic7XG5cbiAgICAgICAgICAgICAgICBpZiAob3B0aW9uLnZpZGVvRmlsZUlucHV0KSB7XG4gICAgICAgICAgICAgICAgICAgIGh0bWwgKz0gJycgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1kaWFsb2ctZm9ybVwiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8bGFiZWw+JyArIGxhbmcuZGlhbG9nQm94LnZpZGVvQm94LmZpbGUgKyAnPC9sYWJlbD4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1mb3JtLWZpbGVzXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8aW5wdXQgY2xhc3M9XCJzZS1pbnB1dC1mb3JtIF9zZV92aWRlb19maWxlXCIgdHlwZT1cImZpbGVcIiBhY2NlcHQ9XCInICsgb3B0aW9uLnZpZGVvQWNjZXB0ICsgJ1wiJyArIChvcHRpb24udmlkZW9NdWx0aXBsZUZpbGUgPyAnIG11bHRpcGxlPVwibXVsdGlwbGVcIicgOiAnJykgKyAnLz4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtY29tbWFuZD1cImZpbGVzUmVtb3ZlXCIgY2xhc3M9XCJzZS1idG4gc2UtZGlhbG9nLWZpbGVzLWVkZ2UtYnV0dG9uIHNlLWZpbGUtcmVtb3ZlXCIgdGl0bGU9XCInICsgbGFuZy5jb250cm9sbGVyLnJlbW92ZSArICdcIj4nICsgdGhpcy5pY29ucy5jYW5jZWwgKyAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzwvZGl2PicgO1xuICAgICAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9uLnZpZGVvVXJsSW5wdXQpIHtcbiAgICAgICAgICAgICAgICAgICAgaHRtbCArPSAnJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1mb3JtXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxsYWJlbD4nICsgbGFuZy5kaWFsb2dCb3gudmlkZW9Cb3gudXJsICsgJzwvbGFiZWw+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxpbnB1dCBjbGFzcz1cInNlLWlucHV0LWZvcm0gc2UtaW5wdXQtdXJsXCIgdHlwZT1cInRleHRcIiAvPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8cHJlIGNsYXNzPVwic2UtbGluay1wcmV2aWV3XCI+PC9wcmU+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChvcHRpb24udmlkZW9SZXNpemluZykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJhdGlvTGlzdCA9IG9wdGlvbi52aWRlb1JhdGlvTGlzdCB8fCBbe25hbWU6ICcxNjo5JywgdmFsdWU6IDAuNTYyNX0sIHtuYW1lOiAnNDozJywgdmFsdWU6IDAuNzV9LCB7bmFtZTogJzIxOjknLCB2YWx1ZTogMC40Mjg1fV07XG4gICAgICAgICAgICAgICAgY29uc3QgcmF0aW8gPSBvcHRpb24udmlkZW9SYXRpbztcbiAgICAgICAgICAgICAgICBjb25zdCBvbmx5UGVyY2VudGFnZSA9IG9wdGlvbi52aWRlb1NpemVPbmx5UGVyY2VudGFnZTtcbiAgICAgICAgICAgICAgICBjb25zdCBvbmx5UGVyY2VudERpc3BsYXkgPSBvbmx5UGVyY2VudGFnZSA/ICcgc3R5bGU9XCJkaXNwbGF5OiBub25lICFpbXBvcnRhbnQ7XCInIDogJyc7XG4gICAgICAgICAgICAgICAgY29uc3QgaGVpZ2h0RGlzcGxheSA9ICFvcHRpb24udmlkZW9IZWlnaHRTaG93ID8gJyBzdHlsZT1cImRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcIicgOiAnJztcbiAgICAgICAgICAgICAgICBjb25zdCByYXRpb0Rpc3BsYXkgPSAhb3B0aW9uLnZpZGVvUmF0aW9TaG93ID8gJyBzdHlsZT1cImRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcIicgOiAnJztcbiAgICAgICAgICAgICAgICBjb25zdCBvbmx5V2lkdGhEaXNwbGF5ID0gIW9ubHlQZXJjZW50YWdlICYmICFvcHRpb24udmlkZW9IZWlnaHRTaG93ICYmICFvcHRpb24udmlkZW9SYXRpb1Nob3cgPyAnIHN0eWxlPVwiZGlzcGxheTogbm9uZSAhaW1wb3J0YW50O1wiJyA6ICcnO1xuICAgICAgICAgICAgICAgIGh0bWwgKz0gJycgK1xuICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1mb3JtXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1zaXplLXRleHRcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGxhYmVsIGNsYXNzPVwic2l6ZS13XCI+JyArIGxhbmcuZGlhbG9nQm94LndpZHRoICsgJzwvbGFiZWw+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxsYWJlbCBjbGFzcz1cInNlLWRpYWxvZy1zaXplLXhcIj4mbmJzcDs8L2xhYmVsPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8bGFiZWwgY2xhc3M9XCJzaXplLWhcIicgKyBoZWlnaHREaXNwbGF5ICsgJz4nICsgbGFuZy5kaWFsb2dCb3guaGVpZ2h0ICsgJzwvbGFiZWw+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxsYWJlbCBjbGFzcz1cInNpemUtaFwiJyArIHJhdGlvRGlzcGxheSArICc+KCcgKyBsYW5nLmRpYWxvZ0JveC5yYXRpbyArICcpPC9sYWJlbD4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8aW5wdXQgY2xhc3M9XCJzZS1pbnB1dC1jb250cm9sIF9zZV92aWRlb19zaXplX3hcIiBwbGFjZWhvbGRlcj1cIjEwMCVcIicgKyAob25seVBlcmNlbnRhZ2UgPyAnIHR5cGU9XCJudW1iZXJcIiBtaW49XCIxXCInIDogJ3R5cGU9XCJ0ZXh0XCInKSArIChvbmx5UGVyY2VudGFnZSA/ICcgbWF4PVwiMTAwXCInIDogJycpICsgJy8+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGxhYmVsIGNsYXNzPVwic2UtZGlhbG9nLXNpemUteFwiJyArIG9ubHlXaWR0aERpc3BsYXkgKyAnPicgKyAob25seVBlcmNlbnRhZ2UgPyAnJScgOiAneCcpICsgJzwvbGFiZWw+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGlucHV0IGNsYXNzPVwic2UtaW5wdXQtY29udHJvbCBfc2VfdmlkZW9fc2l6ZV95XCIgcGxhY2Vob2xkZXI9XCInICsgKG9wdGlvbi52aWRlb1JhdGlvICogMTAwKSArICclXCInICsgKG9ubHlQZXJjZW50YWdlID8gJyB0eXBlPVwibnVtYmVyXCIgbWluPVwiMVwiJyA6ICd0eXBlPVwidGV4dFwiJykgKyAob25seVBlcmNlbnRhZ2UgPyAnIG1heD1cIjEwMFwiJyA6ICcnKSArIGhlaWdodERpc3BsYXkgKyAnLz4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8c2VsZWN0IGNsYXNzPVwic2UtaW5wdXQtc2VsZWN0IHNlLXZpZGVvLXJhdGlvXCIgdGl0bGU9XCInICsgbGFuZy5kaWFsb2dCb3gucmF0aW8gKyAnXCInICsgcmF0aW9EaXNwbGF5ICsgJz4nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaGVpZ2h0RGlzcGxheSkgaHRtbCArPSAnPG9wdGlvbiB2YWx1ZT1cIlwiPiAtIDwvb3B0aW9uPic7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHJhdGlvTGlzdC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBodG1sICs9ICc8b3B0aW9uIHZhbHVlPVwiJyArIHJhdGlvTGlzdFtpXS52YWx1ZSArICdcIicgKyAocmF0aW8udG9TdHJpbmcoKSA9PT0gcmF0aW9MaXN0W2ldLnZhbHVlLnRvU3RyaW5nKCkgPyAnIHNlbGVjdGVkJyA6ICcnKSArICc+JyArIHJhdGlvTGlzdFtpXS5uYW1lICsgJzwvb3B0aW9uPic7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaHRtbCArPSAnPC9zZWxlY3Q+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCInICsgbGFuZy5kaWFsb2dCb3gucmV2ZXJ0QnV0dG9uICsgJ1wiIGNsYXNzPVwic2UtYnRuIHNlLWRpYWxvZy1idG4tcmV2ZXJ0XCIgc3R5bGU9XCJmbG9hdDogcmlnaHQ7XCI+JyArIHRoaXMuaWNvbnMucmV2ZXJ0ICsgJzwvYnV0dG9uPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZGlhbG9nLWZvcm0gc2UtZGlhbG9nLWZvcm0tZm9vdGVyXCInICsgb25seVBlcmNlbnREaXNwbGF5ICsgb25seVdpZHRoRGlzcGxheSArICc+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGxhYmVsPjxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cInNlLWRpYWxvZy1idG4tY2hlY2sgX3NlX3ZpZGVvX2NoZWNrX3Byb3BvcnRpb25cIiBjaGVja2VkLz4mbmJzcDsnICsgbGFuZy5kaWFsb2dCb3gucHJvcG9ydGlvbiArICc8L2xhYmVsPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaHRtbCArPSAnJyArXG4gICAgICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZGlhbG9nLWZvb3RlclwiPicgK1xuICAgICAgICAgICAgICAgICAgICAnPGRpdj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8bGFiZWw+PGlucHV0IHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJzdW5lZGl0b3JfdmlkZW9fcmFkaW9cIiBjbGFzcz1cInNlLWRpYWxvZy1idG4tcmFkaW9cIiB2YWx1ZT1cIm5vbmVcIiBjaGVja2VkPicgKyBsYW5nLmRpYWxvZ0JveC5iYXNpYyArICc8L2xhYmVsPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxsYWJlbD48aW5wdXQgdHlwZT1cInJhZGlvXCIgbmFtZT1cInN1bmVkaXRvcl92aWRlb19yYWRpb1wiIGNsYXNzPVwic2UtZGlhbG9nLWJ0bi1yYWRpb1wiIHZhbHVlPVwibGVmdFwiPicgKyBsYW5nLmRpYWxvZ0JveC5sZWZ0ICsgJzwvbGFiZWw+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGxhYmVsPjxpbnB1dCB0eXBlPVwicmFkaW9cIiBuYW1lPVwic3VuZWRpdG9yX3ZpZGVvX3JhZGlvXCIgY2xhc3M9XCJzZS1kaWFsb2ctYnRuLXJhZGlvXCIgdmFsdWU9XCJjZW50ZXJcIj4nICsgbGFuZy5kaWFsb2dCb3guY2VudGVyICsgJzwvbGFiZWw+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGxhYmVsPjxpbnB1dCB0eXBlPVwicmFkaW9cIiBuYW1lPVwic3VuZWRpdG9yX3ZpZGVvX3JhZGlvXCIgY2xhc3M9XCJzZS1kaWFsb2ctYnRuLXJhZGlvXCIgdmFsdWU9XCJyaWdodFwiPicgKyBsYW5nLmRpYWxvZ0JveC5yaWdodCArICc8L2xhYmVsPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJzdWJtaXRcIiBjbGFzcz1cInNlLWJ0bi1wcmltYXJ5XCIgdGl0bGU9XCInICsgbGFuZy5kaWFsb2dCb3guc3VibWl0QnV0dG9uICsgJ1wiPjxzcGFuPicgKyBsYW5nLmRpYWxvZ0JveC5zdWJtaXRCdXR0b24gKyAnPC9zcGFuPjwvYnV0dG9uPicgK1xuICAgICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICc8L2Zvcm0+JztcblxuICAgICAgICBkaWFsb2cuaW5uZXJIVE1MID0gaHRtbDtcblxuICAgICAgICByZXR1cm4gZGlhbG9nO1xuICAgIH0sXG5cbiAgICBfZmlsZUlucHV0Q2hhbmdlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy52aWRlb0lucHV0RmlsZS52YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy52aWRlb1VybEZpbGUucmVtb3ZlQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xuICAgICAgICAgICAgdGhpcy5wcmV2aWV3LnN0eWxlLnRleHREZWNvcmF0aW9uID0gJyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvVXJsRmlsZS5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLnByZXZpZXcuc3R5bGUudGV4dERlY29yYXRpb24gPSAnbGluZS10aHJvdWdoJztcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBfcmVtb3ZlU2VsZWN0ZWRGaWxlczogZnVuY3Rpb24gKHVybElucHV0LCBwcmV2aWV3KSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSAnJztcbiAgICAgICAgaWYgKHVybElucHV0KSB7XG4gICAgICAgICAgICB1cmxJbnB1dC5yZW1vdmVBdHRyaWJ1dGUoJ2Rpc2FibGVkJyk7XG4gICAgICAgICAgICBwcmV2aWV3LnN0eWxlLnRleHREZWNvcmF0aW9uID0gJyc7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgX29uTGlua1ByZXZpZXc6IGZ1bmN0aW9uIChjb250ZXh0LCBwcm90b2NvbCwgZSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGUudGFyZ2V0LnZhbHVlLnRyaW0oKTtcbiAgICAgICAgaWYgKC9ePGlmcmFtZS4qXFwvaWZyYW1lPiQvLnRlc3QodmFsdWUpKSB7XG4gICAgICAgICAgICBjb250ZXh0Ll9saW5rVmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICAgIHRoaXMudGV4dENvbnRlbnQgPSAnPElGcmFtZSA6c3JjPVwiLi5cIj48L0lGcmFtZT4nO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udGV4dC5fbGlua1ZhbHVlID0gdGhpcy50ZXh0Q29udGVudCA9ICF2YWx1ZSA/ICcnIDogKHByb3RvY29sICYmIHZhbHVlLmluZGV4T2YoJzovLycpID09PSAtMSAmJiB2YWx1ZS5pbmRleE9mKCcjJykgIT09IDApID8gcHJvdG9jb2wgKyB2YWx1ZSA6IHZhbHVlLmluZGV4T2YoJzovLycpID09PSAtMSA/ICcvJyArIHZhbHVlIDogdmFsdWU7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgX3NldFRhZ0F0dHJzOiBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnY29udHJvbHMnLCB0cnVlKTtcblxuICAgICAgICBjb25zdCBhdHRycyA9IHRoaXMuY29udGV4dC5vcHRpb25zLnZpZGVvVGFnQXR0cnM7XG4gICAgICAgIGlmICghYXR0cnMpIHJldHVybjtcblxuICAgICAgICBmb3IgKGxldCBrZXkgaW4gYXR0cnMpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy51dGlsLmhhc093bihhdHRycywga2V5KSkgY29udGludWU7XG4gICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShrZXksIGF0dHJzW2tleV0pO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGNyZWF0ZVZpZGVvVGFnOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHZpZGVvVGFnID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ1ZJREVPJyk7XG4gICAgICAgIHRoaXMucGx1Z2lucy52aWRlby5fc2V0VGFnQXR0cnMuY2FsbCh0aGlzLCB2aWRlb1RhZyk7XG4gICAgICAgIHJldHVybiB2aWRlb1RhZztcbiAgICB9LFxuXG4gICAgX3NldElmcmFtZUF0dHJzOiBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICBlbGVtZW50LmZyYW1lQm9yZGVyID0gJzAnO1xuICAgICAgICBlbGVtZW50LmFsbG93RnVsbHNjcmVlbiA9IHRydWU7XG5cbiAgICAgICAgY29uc3QgYXR0cnMgPSB0aGlzLmNvbnRleHQub3B0aW9ucy52aWRlb0lmcmFtZUF0dHJzO1xuICAgICAgICBpZiAoIWF0dHJzKSByZXR1cm47XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIGF0dHJzKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMudXRpbC5oYXNPd24oYXR0cnMsIGtleSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoa2V5LCBhdHRyc1trZXldKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBjcmVhdGVJZnJhbWVUYWc6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaWZyYW1lVGFnID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ0lGUkFNRScpO1xuICAgICAgICB0aGlzLnBsdWdpbnMudmlkZW8uX3NldElmcmFtZUF0dHJzLmNhbGwodGhpcywgaWZyYW1lVGFnKTtcbiAgICAgICAgcmV0dXJuIGlmcmFtZVRhZztcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIEBSZXF1aXJlZCBmaWxlTWFuYWdlclxuICAgICAqL1xuICAgIGZpbGVUYWdzOiBbJ2lmcmFtZScsICd2aWRlbyddLFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIGNvcmUsIHJlc2l6aW5nLCBmaWxlTWFuYWdlclxuICAgICAqIEBkZXNjcmlwdGlvbiBJdCBpcyBjYWxsZWQgZnJvbSBjb3JlLnNlbGVjdENvbXBvbmVudC5cbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgVGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBzZWxlY3Q6IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIHRoaXMucGx1Z2lucy52aWRlby5vbk1vZGlmeU1vZGUuY2FsbCh0aGlzLCBlbGVtZW50LCB0aGlzLnBsdWdpbnMucmVzaXppbmcuY2FsbF9jb250cm9sbGVyX3Jlc2l6ZS5jYWxsKHRoaXMsIGVsZW1lbnQsICd2aWRlbycpKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIGZpbGVNYW5hZ2VyLCByZXNpemluZ1xuICAgICAqL1xuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGZyYW1lID0gZWxlbWVudCB8fCB0aGlzLmNvbnRleHQudmlkZW8uX2VsZW1lbnQ7XG4gICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuY29udGV4dC52aWRlby5fY29udGFpbmVyO1xuICAgICAgICBjb25zdCBkYXRhSW5kZXggPSBmcmFtZS5nZXRBdHRyaWJ1dGUoJ2RhdGEtaW5kZXgnKSAqIDE7XG4gICAgICAgIGxldCBmb2N1c0VsID0gKGNvbnRhaW5lci5wcmV2aW91c0VsZW1lbnRTaWJsaW5nIHx8IGNvbnRhaW5lci5uZXh0RWxlbWVudFNpYmxpbmcpO1xuXG4gICAgICAgIGNvbnN0IGVtcHR5RGl2ID0gY29udGFpbmVyLnBhcmVudE5vZGU7XG4gICAgICAgIHRoaXMudXRpbC5yZW1vdmVJdGVtKGNvbnRhaW5lcik7XG4gICAgICAgIHRoaXMucGx1Z2lucy52aWRlby5pbml0LmNhbGwodGhpcyk7XG4gICAgICAgIHRoaXMuY29udHJvbGxlcnNPZmYoKTtcblxuICAgICAgICBpZiAoZW1wdHlEaXYgIT09IHRoaXMuY29udGV4dC5lbGVtZW50Lnd5c2l3eWcpIHRoaXMudXRpbC5yZW1vdmVJdGVtQWxsUGFyZW50cyhlbXB0eURpdiwgZnVuY3Rpb24gKGN1cnJlbnQpIHsgcmV0dXJuIGN1cnJlbnQuY2hpbGROb2Rlcy5sZW5ndGggPT09IDA7IH0sIG51bGwpO1xuXG4gICAgICAgIC8vIGZvY3VzXG4gICAgICAgIHRoaXMuZm9jdXNFZGdlKGZvY3VzRWwpO1xuXG4gICAgICAgIC8vIGV2ZW50XG4gICAgICAgIHRoaXMucGx1Z2lucy5maWxlTWFuYWdlci5kZWxldGVJbmZvLmNhbGwodGhpcywgJ3ZpZGVvJywgZGF0YUluZGV4LCB0aGlzLmZ1bmN0aW9ucy5vblZpZGVvVXBsb2FkKTtcblxuICAgICAgICAvLyBoaXN0b3J5IHN0YWNrXG4gICAgICAgIHRoaXMuaGlzdG9yeS5wdXNoKGZhbHNlKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQFJlcXVpcmVkIEBPdmVycmlkZSBkaWFsb2dcbiAgICAgKi9cbiAgICBvbjogZnVuY3Rpb24gKHVwZGF0ZSkge1xuICAgICAgICBjb25zdCBjb250ZXh0VmlkZW8gPSB0aGlzLmNvbnRleHQudmlkZW87XG5cbiAgICAgICAgaWYgKCF1cGRhdGUpIHtcbiAgICAgICAgICAgIGNvbnRleHRWaWRlby5pbnB1dFgudmFsdWUgPSBjb250ZXh0VmlkZW8uX29yaWdpbl93ID0gdGhpcy5jb250ZXh0Lm9wdGlvbi52aWRlb1dpZHRoID09PSBjb250ZXh0VmlkZW8uX2RlZmF1bHRTaXplWCA/ICcnIDogdGhpcy5jb250ZXh0Lm9wdGlvbi52aWRlb1dpZHRoO1xuICAgICAgICAgICAgY29udGV4dFZpZGVvLmlucHV0WS52YWx1ZSA9IGNvbnRleHRWaWRlby5fb3JpZ2luX2ggPSB0aGlzLmNvbnRleHQub3B0aW9uLnZpZGVvSGVpZ2h0ID09PSBjb250ZXh0VmlkZW8uX2RlZmF1bHRTaXplWSA/ICcnIDogdGhpcy5jb250ZXh0Lm9wdGlvbi52aWRlb0hlaWdodDtcbiAgICAgICAgICAgIGNvbnRleHRWaWRlby5wcm9wb3J0aW9uLmRpc2FibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChjb250ZXh0VmlkZW8udmlkZW9JbnB1dEZpbGUgJiYgdGhpcy5jb250ZXh0Lm9wdGlvbnMudmlkZW9NdWx0aXBsZUZpbGUpIGNvbnRleHRWaWRlby52aWRlb0lucHV0RmlsZS5zZXRBdHRyaWJ1dGUoJ211bHRpcGxlJywgJ211bHRpcGxlJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY29udGV4dFZpZGVvLnZpZGVvSW5wdXRGaWxlICYmIHRoaXMuY29udGV4dC5vcHRpb25zLnZpZGVvTXVsdGlwbGVGaWxlKSBjb250ZXh0VmlkZW8udmlkZW9JbnB1dEZpbGUucmVtb3ZlQXR0cmlidXRlKCdtdWx0aXBsZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbnRleHRWaWRlby5fcmVzaXppbmcpIHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy52aWRlby5zZXRWaWRlb1JhdGlvU2VsZWN0LmNhbGwodGhpcywgY29udGV4dFZpZGVvLl9vcmlnaW5faCB8fCBjb250ZXh0VmlkZW8uX2RlZmF1bHRSYXRpbyk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQFJlcXVpcmVkIEBPdmVycmlkZSBkaWFsb2dcbiAgICAgKi9cbiAgICBvcGVuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucGx1Z2lucy5kaWFsb2cub3Blbi5jYWxsKHRoaXMsICd2aWRlbycsICd2aWRlbycgPT09IHRoaXMuY3VycmVudENvbnRyb2xsZXJOYW1lKTtcbiAgICB9LFxuICAgIFxuICAgIHNldFZpZGVvUmF0aW86IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRWaWRlbyA9IHRoaXMuY29udGV4dC52aWRlbztcbiAgICAgICAgY29uc3QgdmFsdWUgPSBlLnRhcmdldC5vcHRpb25zW2UudGFyZ2V0LnNlbGVjdGVkSW5kZXhdLnZhbHVlO1xuXG4gICAgICAgIGNvbnRleHRWaWRlby5fZGVmYXVsdFNpemVZID0gY29udGV4dFZpZGVvLl92aWRlb1JhdGlvID0gIXZhbHVlID8gY29udGV4dFZpZGVvLl9kZWZhdWx0U2l6ZVkgOiAodmFsdWUgKiAxMDApICsgJyUnO1xuICAgICAgICBjb250ZXh0VmlkZW8uaW5wdXRZLnBsYWNlaG9sZGVyID0gIXZhbHVlID8gJycgOiAodmFsdWUgKiAxMDApICsgJyUnO1xuICAgICAgICBjb250ZXh0VmlkZW8uaW5wdXRZLnZhbHVlID0gJyc7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSByZXNpemluZ1xuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB4eSAneCc6IHdpZHRoLCAneSc6IGhlaWdodFxuICAgICAqIEBwYXJhbSB7S2V5Ym9hcmRFdmVudH0gZSBFdmVudCBvYmplY3RcbiAgICAgKi9cbiAgICBzZXRJbnB1dFNpemU6IGZ1bmN0aW9uICh4eSwgZSkge1xuICAgICAgICBpZiAoZSAmJiBlLmtleUNvZGUgPT09IDMyKSB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb250ZXh0VmlkZW8gPSB0aGlzLmNvbnRleHQudmlkZW87XG4gICAgICAgIHRoaXMucGx1Z2lucy5yZXNpemluZy5fbW9kdWxlX3NldElucHV0U2l6ZS5jYWxsKHRoaXMsIGNvbnRleHRWaWRlbywgeHkpO1xuXG4gICAgICAgIGlmICh4eSA9PT0gJ3knKSB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMudmlkZW8uc2V0VmlkZW9SYXRpb1NlbGVjdC5jYWxsKHRoaXMsIGUudGFyZ2V0LnZhbHVlIHx8IGNvbnRleHRWaWRlby5fZGVmYXVsdFJhdGlvKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgcmVzaXppbmdcbiAgICAgKi9cbiAgICBzZXRSYXRpbzogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnBsdWdpbnMucmVzaXppbmcuX21vZHVsZV9zZXRSYXRpby5jYWxsKHRoaXMsIHRoaXMuY29udGV4dC52aWRlbyk7XG4gICAgfSxcblxuICAgIHN1Ym1pdDogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgY29uc3QgY29udGV4dFZpZGVvID0gdGhpcy5jb250ZXh0LnZpZGVvO1xuICAgICAgICBjb25zdCB2aWRlb1BsdWdpbiA9IHRoaXMucGx1Z2lucy52aWRlbztcblxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgY29udGV4dFZpZGVvLl9hbGlnbiA9IGNvbnRleHRWaWRlby5tb2RhbC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPVwic3VuZWRpdG9yX3ZpZGVvX3JhZGlvXCJdOmNoZWNrZWQnKS52YWx1ZTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKGNvbnRleHRWaWRlby52aWRlb0lucHV0RmlsZSAmJiBjb250ZXh0VmlkZW8udmlkZW9JbnB1dEZpbGUuZmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0xvYWRpbmcoKTtcbiAgICAgICAgICAgICAgICB2aWRlb1BsdWdpbi5zdWJtaXRBY3Rpb24uY2FsbCh0aGlzLCB0aGlzLmNvbnRleHQudmlkZW8udmlkZW9JbnB1dEZpbGUuZmlsZXMpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0VmlkZW8udmlkZW9VcmxGaWxlICYmIGNvbnRleHRWaWRlby5fbGlua1ZhbHVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNob3dMb2FkaW5nKCk7XG4gICAgICAgICAgICAgICAgdmlkZW9QbHVnaW4uc2V0dXBfdXJsLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlTG9hZGluZygpO1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1tTVU5FRElUT1IudmlkZW8uc3VibWl0LmZhaWxdIGNhdXNlIDogXCInICsgZXJyb3IubWVzc2FnZSArICdcIicpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmRpYWxvZy5jbG9zZS5jYWxsKHRoaXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG5cbiAgICBzdWJtaXRBY3Rpb246IGZ1bmN0aW9uIChmaWxlTGlzdCkge1xuICAgICAgICBpZiAoZmlsZUxpc3QubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAgICAgbGV0IGZpbGVTaXplID0gMDtcbiAgICAgICAgbGV0IGZpbGVzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBmaWxlTGlzdC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgaWYgKC92aWRlby9pLnRlc3QoZmlsZUxpc3RbaV0udHlwZSkpIHtcbiAgICAgICAgICAgICAgICBmaWxlcy5wdXNoKGZpbGVMaXN0W2ldKTtcbiAgICAgICAgICAgICAgICBmaWxlU2l6ZSArPSBmaWxlTGlzdFtpXS5zaXplO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGltaXRTaXplID0gdGhpcy5jb250ZXh0Lm9wdGlvbi52aWRlb1VwbG9hZFNpemVMaW1pdDtcbiAgICAgICAgaWYgKGxpbWl0U2l6ZSA+IDApIHtcbiAgICAgICAgICAgIGxldCBpbmZvU2l6ZSA9IDA7XG4gICAgICAgICAgICBjb25zdCB2aWRlb3NJbmZvID0gdGhpcy5jb250ZXh0LnZpZGVvLl9pbmZvTGlzdDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSB2aWRlb3NJbmZvLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaW5mb1NpemUgKz0gdmlkZW9zSW5mb1tpXS5zaXplICogMTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKChmaWxlU2l6ZSArIGluZm9TaXplKSA+IGxpbWl0U2l6ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2VMb2FkaW5nKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyID0gJ1tTVU5FRElUT1IudmlkZW9VcGxvYWQuZmFpbF0gU2l6ZSBvZiB1cGxvYWRhYmxlIHRvdGFsIHZpZGVvczogJyArIChsaW1pdFNpemUvMTAwMCkgKyAnS0InO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmZ1bmN0aW9ucy5vblZpZGVvVXBsb2FkRXJyb3IgIT09ICdmdW5jdGlvbicgfHwgdGhpcy5mdW5jdGlvbnMub25WaWRlb1VwbG9hZEVycm9yKGVyciwgeyAnbGltaXRTaXplJzogbGltaXRTaXplLCAnY3VycmVudFNpemUnOiBpbmZvU2l6ZSwgJ3VwbG9hZFNpemUnOiBmaWxlU2l6ZSB9LCB0aGlzKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZ1bmN0aW9ucy5ub3RpY2VPcGVuKGVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNvbnRleHRWaWRlbyA9IHRoaXMuY29udGV4dC52aWRlbztcbiAgICAgICAgY29udGV4dFZpZGVvLl91cGxvYWRGaWxlTGVuZ3RoID0gZmlsZXMubGVuZ3RoO1xuXG4gICAgICAgIGNvbnN0IGluZm8gPSB7XG4gICAgICAgICAgICBpbnB1dFdpZHRoOiBjb250ZXh0VmlkZW8uaW5wdXRYLnZhbHVlLFxuICAgICAgICAgICAgaW5wdXRIZWlnaHQ6IGNvbnRleHRWaWRlby5pbnB1dFkudmFsdWUsXG4gICAgICAgICAgICBhbGlnbjogY29udGV4dFZpZGVvLl9hbGlnbixcbiAgICAgICAgICAgIGlzVXBkYXRlOiB0aGlzLmNvbnRleHQuZGlhbG9nLnVwZGF0ZU1vZGFsLFxuICAgICAgICAgICAgZWxlbWVudDogY29udGV4dFZpZGVvLl9lbGVtZW50XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmZ1bmN0aW9ucy5vblZpZGVvVXBsb2FkQmVmb3JlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmZ1bmN0aW9ucy5vblZpZGVvVXBsb2FkQmVmb3JlKGZpbGVzLCBpbmZvLCB0aGlzLCBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgICAgIGlmIChkYXRhICYmIHRoaXMuX3cuQXJyYXkuaXNBcnJheShkYXRhLnJlc3VsdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnZpZGVvLnJlZ2lzdGVyLmNhbGwodGhpcywgaW5mbywgZGF0YSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnZpZGVvLnVwbG9hZC5jYWxsKHRoaXMsIGluZm8sIGRhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0uYmluZCh0aGlzKSk7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzdWx0ID09PSAndW5kZWZpbmVkJykgcmV0dXJuO1xuICAgICAgICAgICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlTG9hZGluZygpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzdWx0ID09PSAnb2JqZWN0JyAmJiByZXN1bHQubGVuZ3RoID4gMCkgZmlsZXMgPSByZXN1bHQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnBsdWdpbnMudmlkZW8udXBsb2FkLmNhbGwodGhpcywgaW5mbywgZmlsZXMpO1xuICAgIH0sXG5cbiAgICBlcnJvcjogZnVuY3Rpb24gKG1lc3NhZ2UsIHJlc3BvbnNlKSB7XG4gICAgICAgIHRoaXMuY2xvc2VMb2FkaW5nKCk7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5mdW5jdGlvbnMub25WaWRlb1VwbG9hZEVycm9yICE9PSAnZnVuY3Rpb24nIHx8IHRoaXMuZnVuY3Rpb25zLm9uVmlkZW9VcGxvYWRFcnJvcihtZXNzYWdlLCByZXNwb25zZSwgdGhpcykpIHtcbiAgICAgICAgICAgIHRoaXMuZnVuY3Rpb25zLm5vdGljZU9wZW4obWVzc2FnZSk7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcignW1NVTkVESVRPUi5wbHVnaW4udmlkZW8uZXJyb3JdIHJlc3BvbnNlOiAnICsgbWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgdXBsb2FkOiBmdW5jdGlvbiAoaW5mbywgZmlsZXMpIHtcbiAgICAgICAgaWYgKCFmaWxlcykge1xuICAgICAgICAgICAgdGhpcy5jbG9zZUxvYWRpbmcoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGZpbGVzID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnZpZGVvLmVycm9yLmNhbGwodGhpcywgZmlsZXMsIG51bGwpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdmlkZW9VcGxvYWRVcmwgPSB0aGlzLmNvbnRleHQub3B0aW9uLnZpZGVvVXBsb2FkVXJsO1xuICAgICAgICBjb25zdCBmaWxlc0xlbiA9IHRoaXMuY29udGV4dC5kaWFsb2cudXBkYXRlTW9kYWwgPyAxIDogZmlsZXMubGVuZ3RoO1xuXG4gICAgICAgIC8vIHNlcnZlciB1cGxvYWRcbiAgICAgICAgaWYgKHR5cGVvZiB2aWRlb1VwbG9hZFVybCA9PT0gJ3N0cmluZycgJiYgdmlkZW9VcGxvYWRVcmwubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmlsZXNMZW47IGkrKykge1xuICAgICAgICAgICAgICAgIGZvcm1EYXRhLmFwcGVuZCgnZmlsZS0nICsgaSwgZmlsZXNbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmZpbGVNYW5hZ2VyLnVwbG9hZC5jYWxsKHRoaXMsIHZpZGVvVXBsb2FkVXJsLCB0aGlzLmNvbnRleHQub3B0aW9uLnZpZGVvVXBsb2FkSGVhZGVyLCBmb3JtRGF0YSwgdGhpcy5wbHVnaW5zLnZpZGVvLmNhbGxCYWNrX3ZpZGVvVXBsb2FkLmJpbmQodGhpcywgaW5mbyksIHRoaXMuZnVuY3Rpb25zLm9uVmlkZW9VcGxvYWRFcnJvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcignW1NVTkVESVRPUi52aWRlb1VwbG9hZC5mYWlsXSBjYXVzZSA6IFRoZXJlIGlzIG5vIFwidmlkZW9VcGxvYWRVcmxcIiBvcHRpb24uJyk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgY2FsbEJhY2tfdmlkZW9VcGxvYWQ6IGZ1bmN0aW9uIChpbmZvLCB4bWxIdHRwKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5mdW5jdGlvbnMudmlkZW9VcGxvYWRIYW5kbGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLmZ1bmN0aW9ucy52aWRlb1VwbG9hZEhhbmRsZXIoeG1sSHR0cCwgaW5mbywgdGhpcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IEpTT04ucGFyc2UoeG1sSHR0cC5yZXNwb25zZVRleHQpO1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmVycm9yTWVzc2FnZSkge1xuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2lucy52aWRlby5lcnJvci5jYWxsKHRoaXMsIHJlc3BvbnNlLmVycm9yTWVzc2FnZSwgcmVzcG9uc2UpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMudmlkZW8ucmVnaXN0ZXIuY2FsbCh0aGlzLCBpbmZvLCByZXNwb25zZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgcmVnaXN0ZXI6IGZ1bmN0aW9uIChpbmZvLCByZXNwb25zZSkge1xuICAgICAgICBjb25zdCBmaWxlTGlzdCA9IHJlc3BvbnNlLnJlc3VsdDtcbiAgICAgICAgY29uc3QgdmlkZW9UYWcgPSB0aGlzLnBsdWdpbnMudmlkZW8uY3JlYXRlVmlkZW9UYWcuY2FsbCh0aGlzKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gZmlsZUxpc3QubGVuZ3RoLCBmaWxlOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGZpbGUgPSB7IG5hbWU6IGZpbGVMaXN0W2ldLm5hbWUsIHNpemU6IGZpbGVMaXN0W2ldLnNpemUgfTtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy52aWRlby5jcmVhdGVfdmlkZW8uY2FsbCh0aGlzLCAoaW5mby5pc1VwZGF0ZSA/IGluZm8uZWxlbWVudCA6IHZpZGVvVGFnLmNsb25lTm9kZShmYWxzZSkpLCBmaWxlTGlzdFtpXS51cmwsIGluZm8uaW5wdXRXaWR0aCwgaW5mby5pbnB1dEhlaWdodCwgaW5mby5hbGlnbiwgZmlsZSwgaW5mby5pc1VwZGF0ZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNsb3NlTG9hZGluZygpO1xuICAgIH0sXG5cbiAgICBzZXR1cF91cmw6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHRWaWRlbyA9IHRoaXMuY29udGV4dC52aWRlbztcbiAgICAgICAgICAgIGxldCB1cmwgPSBjb250ZXh0VmlkZW8uX2xpbmtWYWx1ZTtcblxuICAgICAgICAgICAgaWYgKHVybC5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcblxuICAgICAgICAgICAgLyoqIGlmcmFtZSBzb3VyY2UgKi9cbiAgICAgICAgICAgIGlmICgvXjxpZnJhbWUuKlxcL2lmcmFtZT4kLy50ZXN0KHVybCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvSWZyYW1lID0gKG5ldyB0aGlzLl93LkRPTVBhcnNlcigpKS5wYXJzZUZyb21TdHJpbmcodXJsLCAndGV4dC9odG1sJykucXVlcnlTZWxlY3RvcignaWZyYW1lJyk7XG4gICAgICAgICAgICAgICAgdXJsID0gb0lmcmFtZS5zcmM7XG4gICAgICAgICAgICAgICAgaWYgKHVybC5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLyoqIHlvdXR1YmUgKi9cbiAgICAgICAgICAgIGlmICgveW91dHVcXC4/YmUvLnRlc3QodXJsKSkge1xuICAgICAgICAgICAgICAgIGlmICghL15odHRwLy50ZXN0KHVybCkpIHVybCA9ICdodHRwczovLycgKyB1cmw7XG4gICAgICAgICAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UoJ3dhdGNoP3Y9JywgJycpO1xuICAgICAgICAgICAgICAgIGlmICghL15cXC9cXC8uK1xcL2VtYmVkXFwvLy50ZXN0KHVybCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UodXJsLm1hdGNoKC9cXC9cXC8uK1xcLy8pWzBdLCAnLy93d3cueW91dHViZS5jb20vZW1iZWQvJykucmVwbGFjZSgnJicsICc/JicpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChjb250ZXh0VmlkZW8uX3lvdXR1YmVRdWVyeS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgvXFw/Ly50ZXN0KHVybCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwbGl0VXJsID0gdXJsLnNwbGl0KCc/Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cmwgPSBzcGxpdFVybFswXSArICc/JyArIGNvbnRleHRWaWRlby5feW91dHViZVF1ZXJ5ICsgJyYnICsgc3BsaXRVcmxbMV07XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cmwgKz0gJz8nICsgY29udGV4dFZpZGVvLl95b3V0dWJlUXVlcnk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKC92aW1lb1xcLmNvbS8udGVzdCh1cmwpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHVybC5lbmRzV2l0aCgnLycpKSB7XG4gICAgICAgICAgICAgICAgICAgIHVybCA9IHVybC5zbGljZSgwLCAtMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHVybCA9ICdodHRwczovL3BsYXllci52aW1lby5jb20vdmlkZW8vJyArIHVybC5zbGljZSh1cmwubGFzdEluZGV4T2YoJy8nKSArIDEpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMudmlkZW8uY3JlYXRlX3ZpZGVvLmNhbGwodGhpcywgdGhpcy5wbHVnaW5zLnZpZGVvLmNyZWF0ZUlmcmFtZVRhZy5jYWxsKHRoaXMpLCB1cmwsIGNvbnRleHRWaWRlby5pbnB1dFgudmFsdWUsIGNvbnRleHRWaWRlby5pbnB1dFkudmFsdWUsIGNvbnRleHRWaWRlby5fYWxpZ24sIG51bGwsIHRoaXMuY29udGV4dC5kaWFsb2cudXBkYXRlTW9kYWwpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1tTVU5FRElUT1IudmlkZW8udXBsb2FkLmZhaWxdIGNhdXNlIDogXCInICsgZXJyb3IubWVzc2FnZSArICdcIicpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5jbG9zZUxvYWRpbmcoKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBjcmVhdGVfdmlkZW86IGZ1bmN0aW9uIChvRnJhbWUsIHNyYywgd2lkdGgsIGhlaWdodCwgYWxpZ24sIGZpbGUsIGlzVXBkYXRlKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC5yZXNpemluZy5fcmVzaXplX3BsdWdpbiA9ICd2aWRlbyc7XG4gICAgICAgIGNvbnN0IGNvbnRleHRWaWRlbyA9IHRoaXMuY29udGV4dC52aWRlbztcbiAgICAgICAgXG4gICAgICAgIGxldCBjb3ZlciA9IG51bGw7XG4gICAgICAgIGxldCBjb250YWluZXIgPSBudWxsO1xuICAgICAgICBsZXQgaW5pdCA9IGZhbHNlO1xuXG4gICAgICAgIC8qKiB1cGRhdGUgKi9cbiAgICAgICAgaWYgKGlzVXBkYXRlKSB7XG4gICAgICAgICAgICBvRnJhbWUgPSBjb250ZXh0VmlkZW8uX2VsZW1lbnQ7XG4gICAgICAgICAgICBpZiAob0ZyYW1lLnNyYyAhPT0gc3JjKSB7XG4gICAgICAgICAgICAgICAgaW5pdCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uc3QgaXNZb3V0dWJlID0gL3lvdXR1XFwuP2JlLy50ZXN0KHNyYyk7XG4gICAgICAgICAgICAgICAgY29uc3QgaXNWaW1lbyA9IC92aW1lb1xcLmNvbS8udGVzdChzcmMpO1xuICAgICAgICAgICAgICAgIGlmICgoaXNZb3V0dWJlIHx8IGlzVmltZW8pICYmICEvXmlmcmFtZSQvaS50ZXN0KG9GcmFtZS5ub2RlTmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3VGFnID0gdGhpcy5wbHVnaW5zLnZpZGVvLmNyZWF0ZUlmcmFtZVRhZy5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBuZXdUYWcuc3JjID0gc3JjO1xuICAgICAgICAgICAgICAgICAgICBvRnJhbWUucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQobmV3VGFnLCBvRnJhbWUpO1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0VmlkZW8uX2VsZW1lbnQgPSBvRnJhbWUgPSBuZXdUYWc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNZb3V0dWJlICYmICFpc1ZpbWVvICYmICEvXnZpZGVvbyQvaS50ZXN0KG9GcmFtZS5ub2RlTmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3VGFnID0gdGhpcy5wbHVnaW5zLnZpZGVvLmNyZWF0ZVZpZGVvVGFnLmNhbGwodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIG5ld1RhZy5zcmMgPSBzcmM7XG4gICAgICAgICAgICAgICAgICAgIG9GcmFtZS5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChuZXdUYWcsIG9GcmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHRWaWRlby5fZWxlbWVudCA9IG9GcmFtZSA9IG5ld1RhZztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBvRnJhbWUuc3JjID0gc3JjO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRhaW5lciA9IGNvbnRleHRWaWRlby5fY29udGFpbmVyO1xuICAgICAgICAgICAgY292ZXIgPSB0aGlzLnV0aWwuZ2V0UGFyZW50RWxlbWVudChvRnJhbWUsICdGSUdVUkUnKTtcbiAgICAgICAgfVxuICAgICAgICAvKiogY3JlYXRlICovXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5pdCA9IHRydWU7XG4gICAgICAgICAgICBvRnJhbWUuc3JjID0gc3JjO1xuICAgICAgICAgICAgY29udGV4dFZpZGVvLl9lbGVtZW50ID0gb0ZyYW1lO1xuICAgICAgICAgICAgY292ZXIgPSB0aGlzLnBsdWdpbnMuY29tcG9uZW50LnNldF9jb3Zlci5jYWxsKHRoaXMsIG9GcmFtZSk7XG4gICAgICAgICAgICBjb250YWluZXIgPSB0aGlzLnBsdWdpbnMuY29tcG9uZW50LnNldF9jb250YWluZXIuY2FsbCh0aGlzLCBjb3ZlciwgJ3NlLXZpZGVvLWNvbnRhaW5lcicpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqIHJlbmRlcmluZyAqL1xuICAgICAgICBjb250ZXh0VmlkZW8uX2NvdmVyID0gY292ZXI7XG4gICAgICAgIGNvbnRleHRWaWRlby5fY29udGFpbmVyID0gY29udGFpbmVyO1xuXG4gICAgICAgIGNvbnN0IGlucHV0VXBkYXRlID0gKHRoaXMucGx1Z2lucy5yZXNpemluZy5fbW9kdWxlX2dldFNpemVYLmNhbGwodGhpcywgY29udGV4dFZpZGVvKSAhPT0gKHdpZHRoIHx8IGNvbnRleHRWaWRlby5fZGVmYXVsdFNpemVYKSkgfHwgKHRoaXMucGx1Z2lucy5yZXNpemluZy5fbW9kdWxlX2dldFNpemVZLmNhbGwodGhpcywgY29udGV4dFZpZGVvKSAhPT0gKGhlaWdodCB8fCBjb250ZXh0VmlkZW8uX3ZpZGVvUmF0aW8pKTtcbiAgICAgICAgY29uc3QgY2hhbmdlU2l6ZSA9ICFpc1VwZGF0ZSB8fCBpbnB1dFVwZGF0ZTtcblxuICAgICAgICBpZiAoY29udGV4dFZpZGVvLl9yZXNpemluZykge1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnZpZGVvLl9wcm9wb3J0aW9uQ2hlY2tlZCA9IGNvbnRleHRWaWRlby5wcm9wb3J0aW9uLmNoZWNrZWQ7XG4gICAgICAgICAgICBvRnJhbWUuc2V0QXR0cmlidXRlKCdkYXRhLXByb3BvcnRpb24nLCBjb250ZXh0VmlkZW8uX3Byb3BvcnRpb25DaGVja2VkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHNpemVcbiAgICAgICAgbGV0IGlzUGVyY2VudCA9IGZhbHNlO1xuICAgICAgICBpZiAoY2hhbmdlU2l6ZSkge1xuICAgICAgICAgICAgaXNQZXJjZW50ID0gdGhpcy5wbHVnaW5zLnZpZGVvLmFwcGx5U2l6ZS5jYWxsKHRoaXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYWxpZ25cbiAgICAgICAgaWYgKCEoaXNQZXJjZW50ICYmIGFsaWduID09PSAnY2VudGVyJykpIHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy52aWRlby5zZXRBbGlnbi5jYWxsKHRoaXMsIG51bGwsIG9GcmFtZSwgY292ZXIsIGNvbnRhaW5lcik7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgY2hhbmdlZCA9IHRydWU7XG4gICAgICAgIGlmICghaXNVcGRhdGUpIHtcbiAgICAgICAgICAgIGNoYW5nZWQgPSB0aGlzLmluc2VydENvbXBvbmVudChjb250YWluZXIsIGZhbHNlLCB0cnVlLCBmYWxzZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoY29udGV4dFZpZGVvLl9yZXNpemluZyAmJiB0aGlzLmNvbnRleHQucmVzaXppbmcuX3JvdGF0ZVZlcnRpY2FsICYmIGNoYW5nZVNpemUpIHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5yZXNpemluZy5zZXRUcmFuc2Zvcm1TaXplLmNhbGwodGhpcywgb0ZyYW1lLCBudWxsLCBudWxsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjaGFuZ2VkKSB7XG4gICAgICAgICAgICBpZiAoaW5pdCkge1xuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2lucy5maWxlTWFuYWdlci5zZXRJbmZvLmNhbGwodGhpcywgJ3ZpZGVvJywgb0ZyYW1lLCB0aGlzLmZ1bmN0aW9ucy5vblZpZGVvVXBsb2FkLCBmaWxlLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc1VwZGF0ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0Q29tcG9uZW50KG9GcmFtZSwgJ3ZpZGVvJyk7XG4gICAgICAgICAgICAgICAgLy8gaGlzdG9yeSBzdGFja1xuICAgICAgICAgICAgICAgIHRoaXMuaGlzdG9yeS5wdXNoKGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29udGV4dC5yZXNpemluZy5fcmVzaXplX3BsdWdpbiA9ICcnO1xuICAgIH0sXG5cbiAgICBfdXBkYXRlX3ZpZGVvQ292ZXI6IGZ1bmN0aW9uIChvRnJhbWUpIHtcbiAgICAgICAgaWYgKCFvRnJhbWUpIHJldHVybjtcblxuICAgICAgICBjb25zdCBjb250ZXh0VmlkZW8gPSB0aGlzLmNvbnRleHQudmlkZW87XG4gICAgICAgIFxuICAgICAgICBpZiAoL152aWRlbyQvaS50ZXN0KG9GcmFtZS5ub2RlTmFtZSkpIHRoaXMucGx1Z2lucy52aWRlby5fc2V0VGFnQXR0cnMuY2FsbCh0aGlzLCBvRnJhbWUpO1xuICAgICAgICBlbHNlIHRoaXMucGx1Z2lucy52aWRlby5fc2V0SWZyYW1lQXR0cnMuY2FsbCh0aGlzLCBvRnJhbWUpO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgZXhpc3RFbGVtZW50ID0gdGhpcy51dGlsLmdldFBhcmVudEVsZW1lbnQob0ZyYW1lLCB0aGlzLnV0aWwuaXNNZWRpYUNvbXBvbmVudCkgfHwgXG4gICAgICAgICAgICB0aGlzLnV0aWwuZ2V0UGFyZW50RWxlbWVudChvRnJhbWUsIGZ1bmN0aW9uIChjdXJyZW50KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaXNXeXNpd3lnRGl2KGN1cnJlbnQucGFyZW50Tm9kZSk7XG4gICAgICAgICAgICB9LmJpbmQodGhpcy51dGlsKSk7XG5cbiAgICAgICAgb0ZyYW1lID0gb0ZyYW1lLmNsb25lTm9kZSh0cnVlKTtcbiAgICAgICAgY29uc3QgY292ZXIgPSBjb250ZXh0VmlkZW8uX2NvdmVyID0gdGhpcy5wbHVnaW5zLmNvbXBvbmVudC5zZXRfY292ZXIuY2FsbCh0aGlzLCBvRnJhbWUpO1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSBjb250ZXh0VmlkZW8uX2NvbnRhaW5lciA9IHRoaXMucGx1Z2lucy5jb21wb25lbnQuc2V0X2NvbnRhaW5lci5jYWxsKHRoaXMsIGNvdmVyLCAnc2UtdmlkZW8tY29udGFpbmVyJyk7XG5cbiAgICAgICAgY29uc3QgZmlnY2FwdGlvbiA9IGV4aXN0RWxlbWVudC5xdWVyeVNlbGVjdG9yKCdmaWdjYXB0aW9uJyk7XG4gICAgICAgIGxldCBjYXB0aW9uID0gbnVsbDtcbiAgICAgICAgaWYgKCEhZmlnY2FwdGlvbikge1xuICAgICAgICAgICAgY2FwdGlvbiA9IHRoaXMudXRpbC5jcmVhdGVFbGVtZW50KCdESVYnKTtcbiAgICAgICAgICAgIGNhcHRpb24uaW5uZXJIVE1MID0gZmlnY2FwdGlvbi5pbm5lckhUTUw7XG4gICAgICAgICAgICB0aGlzLnV0aWwucmVtb3ZlSXRlbShmaWdjYXB0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNpemUgPSAob0ZyYW1lLmdldEF0dHJpYnV0ZSgnZGF0YS1zaXplJykgfHwgb0ZyYW1lLmdldEF0dHJpYnV0ZSgnZGF0YS1vcmlnaW4nKSB8fCAnJykuc3BsaXQoJywnKTtcbiAgICAgICAgdGhpcy5wbHVnaW5zLnZpZGVvLmFwcGx5U2l6ZS5jYWxsKHRoaXMsIHNpemVbMF0sIHNpemVbMV0pO1xuXG4gICAgICAgIGlmICh0aGlzLnV0aWwuaXNGb3JtYXRFbGVtZW50KGV4aXN0RWxlbWVudCkgJiYgZXhpc3RFbGVtZW50LnRleHRDb250ZW50Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGV4aXN0RWxlbWVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShjb250YWluZXIsIGV4aXN0RWxlbWVudC5uZXh0RWxlbWVudFNpYmxpbmcpO1xuICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUl0ZW0oY29udGV4dFZpZGVvLl9lbGVtZW50KTtcbiAgICAgICAgICAgIGNvbnRleHRWaWRlby5fZWxlbWVudCA9IG9GcmFtZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4aXN0RWxlbWVudC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChjb250YWluZXIsIGV4aXN0RWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISFjYXB0aW9uKSBleGlzdEVsZW1lbnQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoY2FwdGlvbiwgY29udGFpbmVyLm5leHRFbGVtZW50U2libGluZyk7XG4gICAgICAgIHRoaXMucGx1Z2lucy5maWxlTWFuYWdlci5zZXRJbmZvLmNhbGwodGhpcywgJ3ZpZGVvJywgb0ZyYW1lLCB0aGlzLmZ1bmN0aW9ucy5vblZpZGVvVXBsb2FkLCBudWxsLCB0cnVlKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQFJlcXVpcmVkIEBPdmVycmlkZSBmaWxlTWFuYWdlciwgcmVzaXppbmdcbiAgICAgKi9cbiAgICBvbk1vZGlmeU1vZGU6IGZ1bmN0aW9uIChlbGVtZW50LCBzaXplKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRWaWRlbyA9IHRoaXMuY29udGV4dC52aWRlbztcbiAgICAgICAgY29udGV4dFZpZGVvLl9lbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgY29udGV4dFZpZGVvLl9jb3ZlciA9IHRoaXMudXRpbC5nZXRQYXJlbnRFbGVtZW50KGVsZW1lbnQsICdGSUdVUkUnKTtcbiAgICAgICAgY29udGV4dFZpZGVvLl9jb250YWluZXIgPSB0aGlzLnV0aWwuZ2V0UGFyZW50RWxlbWVudChlbGVtZW50LCB0aGlzLnV0aWwuaXNNZWRpYUNvbXBvbmVudCk7XG4gICAgICAgIGNvbnRleHRWaWRlby5fYWxpZ24gPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1hbGlnbicpIHx8ICdub25lJztcblxuICAgICAgICBpZiAoc2l6ZSkge1xuICAgICAgICAgICAgY29udGV4dFZpZGVvLl9lbGVtZW50X3cgPSBzaXplLnc7XG4gICAgICAgICAgICBjb250ZXh0VmlkZW8uX2VsZW1lbnRfaCA9IHNpemUuaDtcbiAgICAgICAgICAgIGNvbnRleHRWaWRlby5fZWxlbWVudF90ID0gc2l6ZS50O1xuICAgICAgICAgICAgY29udGV4dFZpZGVvLl9lbGVtZW50X2wgPSBzaXplLmw7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgb3JpZ2luID0gY29udGV4dFZpZGVvLl9lbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1zaXplJykgfHwgY29udGV4dFZpZGVvLl9lbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1vcmlnaW4nKTtcbiAgICAgICAgaWYgKG9yaWdpbikge1xuICAgICAgICAgICAgb3JpZ2luID0gb3JpZ2luLnNwbGl0KCcsJyk7XG4gICAgICAgICAgICBjb250ZXh0VmlkZW8uX29yaWdpbl93ID0gb3JpZ2luWzBdO1xuICAgICAgICAgICAgY29udGV4dFZpZGVvLl9vcmlnaW5faCA9IG9yaWdpblsxXTtcbiAgICAgICAgfSBlbHNlIGlmIChzaXplKSB7XG4gICAgICAgICAgICBjb250ZXh0VmlkZW8uX29yaWdpbl93ID0gc2l6ZS53O1xuICAgICAgICAgICAgY29udGV4dFZpZGVvLl9vcmlnaW5faCA9IHNpemUuaDtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAUmVxdWlyZWQgQE92ZXJyaWRlIGZpbGVNYW5hZ2VyLCByZXNpemluZ1xuICAgICAqL1xuICAgIG9wZW5Nb2RpZnk6IGZ1bmN0aW9uIChub3RPcGVuKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRWaWRlbyA9IHRoaXMuY29udGV4dC52aWRlbztcblxuICAgICAgICBpZiAoY29udGV4dFZpZGVvLnZpZGVvVXJsRmlsZSkgY29udGV4dFZpZGVvLl9saW5rVmFsdWUgPSBjb250ZXh0VmlkZW8ucHJldmlldy50ZXh0Q29udGVudCA9IGNvbnRleHRWaWRlby52aWRlb1VybEZpbGUudmFsdWUgPSAoY29udGV4dFZpZGVvLl9lbGVtZW50LnNyYyB8fCAoY29udGV4dFZpZGVvLl9lbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ3NvdXJjZScpIHx8ICcnKS5zcmMgfHwgJycpO1xuICAgICAgICBjb250ZXh0VmlkZW8ubW9kYWwucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT1cInN1bmVkaXRvcl92aWRlb19yYWRpb1wiXVt2YWx1ZT1cIicgKyBjb250ZXh0VmlkZW8uX2FsaWduICsgJ1wiXScpLmNoZWNrZWQgPSB0cnVlO1xuXG4gICAgICAgIGlmIChjb250ZXh0VmlkZW8uX3Jlc2l6aW5nKSB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMucmVzaXppbmcuX21vZHVsZV9zZXRNb2RpZnlJbnB1dFNpemUuY2FsbCh0aGlzLCBjb250ZXh0VmlkZW8sIHRoaXMucGx1Z2lucy52aWRlbyk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGNvbnN0IHkgPSBjb250ZXh0VmlkZW8uX3ZpZGVvUmF0aW8gPSB0aGlzLnBsdWdpbnMucmVzaXppbmcuX21vZHVsZV9nZXRTaXplWS5jYWxsKHRoaXMsIGNvbnRleHRWaWRlbyk7XG4gICAgICAgICAgICBjb25zdCByYXRpb1NlbGVjdGVkID0gdGhpcy5wbHVnaW5zLnZpZGVvLnNldFZpZGVvUmF0aW9TZWxlY3QuY2FsbCh0aGlzLCB5KTtcbiAgICAgICAgICAgIGlmICghcmF0aW9TZWxlY3RlZCkgY29udGV4dFZpZGVvLmlucHV0WS52YWx1ZSA9IGNvbnRleHRWaWRlby5fb25seVBlcmNlbnRhZ2UgPyB0aGlzLnV0aWwuZ2V0TnVtYmVyKHksIDIpIDogeTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghbm90T3BlbikgdGhpcy5wbHVnaW5zLmRpYWxvZy5vcGVuLmNhbGwodGhpcywgJ3ZpZGVvJywgdHJ1ZSk7XG4gICAgfSxcbiAgICBcbiAgICBzZXRWaWRlb1JhdGlvU2VsZWN0OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgbGV0IHJhdGlvU2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgY29uc3QgY29udGV4dFZpZGVvID0gdGhpcy5jb250ZXh0LnZpZGVvO1xuICAgICAgICBjb25zdCByYXRpb09wdGlvbnMgPSBjb250ZXh0VmlkZW8udmlkZW9SYXRpb09wdGlvbi5vcHRpb25zO1xuXG4gICAgICAgIGlmICgvJSQvLnRlc3QodmFsdWUpIHx8IGNvbnRleHRWaWRlby5fb25seVBlcmNlbnRhZ2UpIHZhbHVlID0gKHRoaXMudXRpbC5nZXROdW1iZXIodmFsdWUsIDIpIC8gMTAwKSArICcnO1xuICAgICAgICBlbHNlIGlmICghdGhpcy51dGlsLmlzTnVtYmVyKHZhbHVlKSB8fCAodmFsdWUgKiAxKSA+PSAxKSB2YWx1ZSA9ICcnO1xuXG4gICAgICAgIGNvbnRleHRWaWRlby5pbnB1dFkucGxhY2Vob2xkZXIgPSAnJztcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHJhdGlvT3B0aW9ucy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgaWYgKHJhdGlvT3B0aW9uc1tpXS52YWx1ZSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICByYXRpb1NlbGVjdGVkID0gcmF0aW9PcHRpb25zW2ldLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb250ZXh0VmlkZW8uaW5wdXRZLnBsYWNlaG9sZGVyID0gIXZhbHVlID8gJycgOiAodmFsdWUgKiAxMDApICsgJyUnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSByYXRpb09wdGlvbnNbaV0uc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByYXRpb1NlbGVjdGVkO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgZmlsZU1hbmFnZXJcbiAgICAgKi9cbiAgICBjaGVja0ZpbGVJbmZvOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucGx1Z2lucy5maWxlTWFuYWdlci5jaGVja0luZm8uY2FsbCh0aGlzLCAndmlkZW8nLCBbJ2lmcmFtZScsICd2aWRlbyddLCB0aGlzLmZ1bmN0aW9ucy5vblZpZGVvVXBsb2FkLCB0aGlzLnBsdWdpbnMudmlkZW8uX3VwZGF0ZV92aWRlb0NvdmVyLmJpbmQodGhpcyksIHRydWUpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgZmlsZU1hbmFnZXJcbiAgICAgKi9cbiAgICByZXNldEZpbGVJbmZvOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucGx1Z2lucy5maWxlTWFuYWdlci5yZXNldEluZm8uY2FsbCh0aGlzLCAndmlkZW8nLCB0aGlzLmZ1bmN0aW9ucy5vblZpZGVvVXBsb2FkKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIHJlc2l6aW5nXG4gICAgICovXG4gICAgc2l6ZVJldmVydDogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnBsdWdpbnMucmVzaXppbmcuX21vZHVsZV9zaXplUmV2ZXJ0LmNhbGwodGhpcywgdGhpcy5jb250ZXh0LnZpZGVvKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIHJlc2l6aW5nXG4gICAgICovXG4gICAgYXBwbHlTaXplOiBmdW5jdGlvbiAodywgaCkge1xuICAgICAgICBjb25zdCBjb250ZXh0VmlkZW8gPSB0aGlzLmNvbnRleHQudmlkZW87XG5cbiAgICAgICAgaWYgKCF3KSB3ID0gY29udGV4dFZpZGVvLmlucHV0WC52YWx1ZSB8fCB0aGlzLmNvbnRleHQub3B0aW9uLnZpZGVvV2lkdGg7XG4gICAgICAgIGlmICghaCkgaCA9IGNvbnRleHRWaWRlby5pbnB1dFkudmFsdWUgfHwgdGhpcy5jb250ZXh0Lm9wdGlvbi52aWRlb0hlaWdodDtcbiAgICAgICAgXG4gICAgICAgIGlmIChjb250ZXh0VmlkZW8uX29ubHlQZXJjZW50YWdlIHx8IC8lJC8udGVzdCh3KSB8fCAhdykge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnZpZGVvLnNldFBlcmNlbnRTaXplLmNhbGwodGhpcywgKHcgfHwgJzEwMCUnKSwgKGggfHwgKC8lJC8udGVzdChjb250ZXh0VmlkZW8uX3ZpZGVvUmF0aW8pID8gY29udGV4dFZpZGVvLl92aWRlb1JhdGlvIDogY29udGV4dFZpZGVvLl9kZWZhdWx0UmF0aW8pKSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmICgoIXcgfHwgdyA9PT0gJ2F1dG8nKSAmJiAoIWggfHwgaCA9PT0gJ2F1dG8nKSkge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnZpZGVvLnNldEF1dG9TaXplLmNhbGwodGhpcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMudmlkZW8uc2V0U2l6ZS5jYWxsKHRoaXMsIHcsIChoIHx8IGNvbnRleHRWaWRlby5fdmlkZW9SYXRpbyB8fCBjb250ZXh0VmlkZW8uX2RlZmF1bHRSYXRpbyksIGZhbHNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIHJlc2l6aW5nXG4gICAgICovXG4gICAgc2V0U2l6ZTogZnVuY3Rpb24gKHcsIGgsIG5vdFJlc2V0UGVyY2VudGFnZSwgZGlyZWN0aW9uKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRWaWRlbyA9IHRoaXMuY29udGV4dC52aWRlbztcbiAgICAgICAgY29uc3Qgb25seVcgPSAvXihyd3xsdykkLy50ZXN0KGRpcmVjdGlvbik7XG4gICAgICAgIGNvbnN0IG9ubHlIID0gL14odGh8YmgpJC8udGVzdChkaXJlY3Rpb24pO1xuXG4gICAgICAgIGlmICghb25seUgpIHcgPSB0aGlzLnV0aWwuZ2V0TnVtYmVyKHcsIDApO1xuICAgICAgICBpZiAoIW9ubHlXKSBoID0gdGhpcy51dGlsLmlzTnVtYmVyKGgpID8gaCArIGNvbnRleHRWaWRlby5zaXplVW5pdCA6ICFoID8gJycgOiBoO1xuXG4gICAgICAgIGlmICghb25seUgpIGNvbnRleHRWaWRlby5fZWxlbWVudC5zdHlsZS53aWR0aCA9IHcgPyB3ICsgY29udGV4dFZpZGVvLnNpemVVbml0IDogJyc7XG4gICAgICAgIGlmICghb25seVcpIGNvbnRleHRWaWRlby5fY292ZXIuc3R5bGUucGFkZGluZ0JvdHRvbSA9IGNvbnRleHRWaWRlby5fY292ZXIuc3R5bGUuaGVpZ2h0ID0gaDtcblxuICAgICAgICBpZiAoIW9ubHlIICYmICEvJSQvLnRlc3QodykpIHtcbiAgICAgICAgICAgIGNvbnRleHRWaWRlby5fY292ZXIuc3R5bGUud2lkdGggPSAnJztcbiAgICAgICAgICAgIGNvbnRleHRWaWRlby5fY29udGFpbmVyLnN0eWxlLndpZHRoID0gJyc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW9ubHlXICYmICEvJSQvLnRlc3QoaCkpIHtcbiAgICAgICAgICAgIGNvbnRleHRWaWRlby5fZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBoO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udGV4dFZpZGVvLl9lbGVtZW50LnN0eWxlLmhlaWdodCA9ICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFub3RSZXNldFBlcmNlbnRhZ2UpIGNvbnRleHRWaWRlby5fZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ2RhdGEtcGVyY2VudGFnZScpO1xuXG4gICAgICAgIC8vIHNhdmUgY3VycmVudCBzaXplXG4gICAgICAgIHRoaXMucGx1Z2lucy5yZXNpemluZy5fbW9kdWxlX3NhdmVDdXJyZW50U2l6ZS5jYWxsKHRoaXMsIGNvbnRleHRWaWRlbyk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSByZXNpemluZ1xuICAgICAqL1xuICAgIHNldEF1dG9TaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucGx1Z2lucy52aWRlby5zZXRQZXJjZW50U2l6ZS5jYWxsKHRoaXMsIDEwMCwgdGhpcy5jb250ZXh0LnZpZGVvLl9kZWZhdWx0UmF0aW8pO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgcmVzaXppbmdcbiAgICAgKi9cbiAgICBzZXRPcmlnaW5TaXplOiBmdW5jdGlvbiAoZGF0YVNpemUpIHtcbiAgICAgICAgY29uc3QgY29udGV4dFZpZGVvID0gdGhpcy5jb250ZXh0LnZpZGVvO1xuICAgICAgICBjb250ZXh0VmlkZW8uX2VsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdkYXRhLXBlcmNlbnRhZ2UnKTtcblxuICAgICAgICB0aGlzLnBsdWdpbnMucmVzaXppbmcucmVzZXRUcmFuc2Zvcm0uY2FsbCh0aGlzLCBjb250ZXh0VmlkZW8uX2VsZW1lbnQpO1xuICAgICAgICB0aGlzLnBsdWdpbnMudmlkZW8uY2FuY2VsUGVyY2VudEF0dHIuY2FsbCh0aGlzKTtcblxuICAgICAgICBjb25zdCBvcmlnaW5TaXplID0gKChkYXRhU2l6ZSA/IGNvbnRleHRWaWRlby5fZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtc2l6ZScpIDogJycpIHx8IGNvbnRleHRWaWRlby5fZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtb3JpZ2luJykgfHwgJycpLnNwbGl0KCcsJyk7XG4gICAgICAgIFxuICAgICAgICBpZiAob3JpZ2luU2l6ZSkge1xuICAgICAgICAgICAgY29uc3QgdyA9IG9yaWdpblNpemVbMF07XG4gICAgICAgICAgICBjb25zdCBoID0gb3JpZ2luU2l6ZVsxXTtcblxuICAgICAgICAgICAgaWYgKGNvbnRleHRWaWRlby5fb25seVBlcmNlbnRhZ2UgfHwgKC8lJC8udGVzdCh3KSAmJiAoLyUkLy50ZXN0KGgpIHx8ICEvXFxkLy50ZXN0KGgpKSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMudmlkZW8uc2V0UGVyY2VudFNpemUuY2FsbCh0aGlzLCB3LCBoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnZpZGVvLnNldFNpemUuY2FsbCh0aGlzLCB3LCBoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gc2F2ZSBjdXJyZW50IHNpemVcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5yZXNpemluZy5fbW9kdWxlX3NhdmVDdXJyZW50U2l6ZS5jYWxsKHRoaXMsIGNvbnRleHRWaWRlbyk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIHJlc2l6aW5nXG4gICAgICovXG4gICAgc2V0UGVyY2VudFNpemU6IGZ1bmN0aW9uICh3LCBoKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRWaWRlbyA9IHRoaXMuY29udGV4dC52aWRlbztcbiAgICAgICAgaCA9ICEhaCAmJiAhLyUkLy50ZXN0KGgpICYmICF0aGlzLnV0aWwuZ2V0TnVtYmVyKGgsIDApID8gdGhpcy51dGlsLmlzTnVtYmVyKGgpID8gaCArICclJyA6IGggOiB0aGlzLnV0aWwuaXNOdW1iZXIoaCkgPyBoICsgY29udGV4dFZpZGVvLnNpemVVbml0IDogKGggfHwgY29udGV4dFZpZGVvLl9kZWZhdWx0UmF0aW8pO1xuXG4gICAgICAgIGNvbnRleHRWaWRlby5fY29udGFpbmVyLnN0eWxlLndpZHRoID0gdGhpcy51dGlsLmlzTnVtYmVyKHcpID8gdyArICclJyA6IHc7XG4gICAgICAgIGNvbnRleHRWaWRlby5fY29udGFpbmVyLnN0eWxlLmhlaWdodCA9ICcnO1xuICAgICAgICBjb250ZXh0VmlkZW8uX2NvdmVyLnN0eWxlLndpZHRoID0gJzEwMCUnO1xuICAgICAgICBjb250ZXh0VmlkZW8uX2NvdmVyLnN0eWxlLmhlaWdodCA9IGg7XG4gICAgICAgIGNvbnRleHRWaWRlby5fY292ZXIuc3R5bGUucGFkZGluZ0JvdHRvbSA9IGg7XG4gICAgICAgIGNvbnRleHRWaWRlby5fZWxlbWVudC5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICAgICAgY29udGV4dFZpZGVvLl9lbGVtZW50LnN0eWxlLmhlaWdodCA9ICcxMDAlJztcbiAgICAgICAgY29udGV4dFZpZGVvLl9lbGVtZW50LnN0eWxlLm1heFdpZHRoID0gJyc7XG5cbiAgICAgICAgaWYgKGNvbnRleHRWaWRlby5fYWxpZ24gPT09ICdjZW50ZXInKSB0aGlzLnBsdWdpbnMudmlkZW8uc2V0QWxpZ24uY2FsbCh0aGlzLCBudWxsLCBudWxsLCBudWxsLCBudWxsKTtcbiAgICAgICAgY29udGV4dFZpZGVvLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1wZXJjZW50YWdlJywgdyArICcsJyArIGgpO1xuXG4gICAgICAgIC8vIHNhdmUgY3VycmVudCBzaXplXG4gICAgICAgIHRoaXMucGx1Z2lucy5yZXNpemluZy5fbW9kdWxlX3NhdmVDdXJyZW50U2l6ZS5jYWxsKHRoaXMsIGNvbnRleHRWaWRlbyk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSByZXNpemluZ1xuICAgICAqL1xuICAgIGNhbmNlbFBlcmNlbnRBdHRyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRWaWRlbyA9IHRoaXMuY29udGV4dC52aWRlbztcbiAgICAgICAgXG4gICAgICAgIGNvbnRleHRWaWRlby5fY292ZXIuc3R5bGUud2lkdGggPSAnJztcbiAgICAgICAgY29udGV4dFZpZGVvLl9jb3Zlci5zdHlsZS5oZWlnaHQgPSAnJztcbiAgICAgICAgY29udGV4dFZpZGVvLl9jb3Zlci5zdHlsZS5wYWRkaW5nQm90dG9tID0gJyc7XG4gICAgICAgIGNvbnRleHRWaWRlby5fY29udGFpbmVyLnN0eWxlLndpZHRoID0gJyc7XG4gICAgICAgIGNvbnRleHRWaWRlby5fY29udGFpbmVyLnN0eWxlLmhlaWdodCA9ICcnO1xuXG4gICAgICAgIHRoaXMudXRpbC5yZW1vdmVDbGFzcyhjb250ZXh0VmlkZW8uX2NvbnRhaW5lciwgdGhpcy5jb250ZXh0LnZpZGVvLl9mbG9hdENsYXNzUmVnRXhwKTtcbiAgICAgICAgdGhpcy51dGlsLmFkZENsYXNzKGNvbnRleHRWaWRlby5fY29udGFpbmVyLCAnX19zZV9fZmxvYXQtJyArIGNvbnRleHRWaWRlby5fYWxpZ24pO1xuXG4gICAgICAgIGlmIChjb250ZXh0VmlkZW8uX2FsaWduID09PSAnY2VudGVyJykgdGhpcy5wbHVnaW5zLnZpZGVvLnNldEFsaWduLmNhbGwodGhpcywgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSByZXNpemluZ1xuICAgICAqL1xuICAgIHNldEFsaWduOiBmdW5jdGlvbiAoYWxpZ24sIGVsZW1lbnQsIGNvdmVyLCBjb250YWluZXIpIHtcbiAgICAgICAgY29uc3QgY29udGV4dFZpZGVvID0gdGhpcy5jb250ZXh0LnZpZGVvO1xuICAgICAgICBcbiAgICAgICAgaWYgKCFhbGlnbikgYWxpZ24gPSBjb250ZXh0VmlkZW8uX2FsaWduO1xuICAgICAgICBpZiAoIWVsZW1lbnQpIGVsZW1lbnQgPSBjb250ZXh0VmlkZW8uX2VsZW1lbnQ7XG4gICAgICAgIGlmICghY292ZXIpIGNvdmVyID0gY29udGV4dFZpZGVvLl9jb3ZlcjtcbiAgICAgICAgaWYgKCFjb250YWluZXIpIGNvbnRhaW5lciA9IGNvbnRleHRWaWRlby5fY29udGFpbmVyO1xuXG4gICAgICAgIGlmIChhbGlnbiAmJiBhbGlnbiAhPT0gJ25vbmUnKSB7XG4gICAgICAgICAgICBjb3Zlci5zdHlsZS5tYXJnaW4gPSAnYXV0byc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb3Zlci5zdHlsZS5tYXJnaW4gPSAnMCc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoLyUkLy50ZXN0KGVsZW1lbnQuc3R5bGUud2lkdGgpICYmIGFsaWduID09PSAnY2VudGVyJykge1xuICAgICAgICAgICAgY29udGFpbmVyLnN0eWxlLm1pbldpZHRoID0gJzEwMCUnO1xuICAgICAgICAgICAgY292ZXIuc3R5bGUud2lkdGggPSBjb250YWluZXIuc3R5bGUud2lkdGg7XG4gICAgICAgICAgICBjb3Zlci5zdHlsZS5oZWlnaHQgPSBjb3Zlci5zdHlsZS5oZWlnaHQ7XG4gICAgICAgICAgICBjb3Zlci5zdHlsZS5wYWRkaW5nQm90dG9tID0gIS8lJC8udGVzdChjb3Zlci5zdHlsZS5oZWlnaHQpID8gY292ZXIuc3R5bGUuaGVpZ2h0IDogdGhpcy51dGlsLmdldE51bWJlcigodGhpcy51dGlsLmdldE51bWJlcihjb3Zlci5zdHlsZS5oZWlnaHQsIDIpIC8gMTAwKSAqIHRoaXMudXRpbC5nZXROdW1iZXIoY292ZXIuc3R5bGUud2lkdGgsIDIpLCAyKSArICclJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5zdHlsZS5taW5XaWR0aCA9ICcnO1xuICAgICAgICAgICAgY292ZXIuc3R5bGUud2lkdGggPSB0aGlzLmNvbnRleHQucmVzaXppbmcuX3JvdGF0ZVZlcnRpY2FsID8gKGVsZW1lbnQuc3R5bGUuaGVpZ2h0IHx8IGVsZW1lbnQub2Zmc2V0SGVpZ2h0KSA6IChlbGVtZW50LnN0eWxlLndpZHRoIHx8ICcxMDAlJyk7XG4gICAgICAgICAgICBjb3Zlci5zdHlsZS5wYWRkaW5nQm90dG9tID0gY292ZXIuc3R5bGUuaGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLnV0aWwuaGFzQ2xhc3MoY29udGFpbmVyLCAnX19zZV9fZmxvYXQtJyArIGFsaWduKSkge1xuICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUNsYXNzKGNvbnRhaW5lciwgY29udGV4dFZpZGVvLl9mbG9hdENsYXNzUmVnRXhwKTtcbiAgICAgICAgICAgIHRoaXMudXRpbC5hZGRDbGFzcyhjb250YWluZXIsICdfX3NlX19mbG9hdC0nICsgYWxpZ24pO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1hbGlnbicsIGFsaWduKTtcbiAgICB9LFxuXG4gICAgcmVzZXRBbGlnbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb250ZXh0VmlkZW8gPSB0aGlzLmNvbnRleHQudmlkZW87XG5cbiAgICAgICAgY29udGV4dFZpZGVvLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1hbGlnbicsICcnKTtcbiAgICAgICAgY29udGV4dFZpZGVvLl9hbGlnbiA9ICdub25lJztcbiAgICAgICAgY29udGV4dFZpZGVvLl9jb3Zlci5zdHlsZS5tYXJnaW4gPSAnMCc7XG4gICAgICAgIHRoaXMudXRpbC5yZW1vdmVDbGFzcyhjb250ZXh0VmlkZW8uX2NvbnRhaW5lciwgY29udGV4dFZpZGVvLl9mbG9hdENsYXNzUmVnRXhwKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIGRpYWxvZ1xuICAgICAqL1xuICAgIGluaXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29udGV4dFZpZGVvID0gdGhpcy5jb250ZXh0LnZpZGVvO1xuICAgICAgICBpZiAoY29udGV4dFZpZGVvLnZpZGVvSW5wdXRGaWxlKSBjb250ZXh0VmlkZW8udmlkZW9JbnB1dEZpbGUudmFsdWUgPSAnJztcbiAgICAgICAgaWYgKGNvbnRleHRWaWRlby52aWRlb1VybEZpbGUpIGNvbnRleHRWaWRlby5fbGlua1ZhbHVlID0gY29udGV4dFZpZGVvLnByZXZpZXcudGV4dENvbnRlbnQgPSBjb250ZXh0VmlkZW8udmlkZW9VcmxGaWxlLnZhbHVlID0gJyc7XG4gICAgICAgIGlmIChjb250ZXh0VmlkZW8udmlkZW9JbnB1dEZpbGUgJiYgY29udGV4dFZpZGVvLnZpZGVvVXJsRmlsZSkge1xuICAgICAgICAgICAgY29udGV4dFZpZGVvLnZpZGVvVXJsRmlsZS5yZW1vdmVBdHRyaWJ1dGUoJ2Rpc2FibGVkJyk7XG4gICAgICAgICAgICBjb250ZXh0VmlkZW8ucHJldmlldy5zdHlsZS50ZXh0RGVjb3JhdGlvbiA9ICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgY29udGV4dFZpZGVvLl9vcmlnaW5fdyA9IHRoaXMuY29udGV4dC5vcHRpb24udmlkZW9XaWR0aDtcbiAgICAgICAgY29udGV4dFZpZGVvLl9vcmlnaW5faCA9IHRoaXMuY29udGV4dC5vcHRpb24udmlkZW9IZWlnaHQ7XG4gICAgICAgIGNvbnRleHRWaWRlby5tb2RhbC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPVwic3VuZWRpdG9yX3ZpZGVvX3JhZGlvXCJdW3ZhbHVlPVwibm9uZVwiXScpLmNoZWNrZWQgPSB0cnVlO1xuICAgICAgICBcbiAgICAgICAgaWYgKGNvbnRleHRWaWRlby5fcmVzaXppbmcpIHtcbiAgICAgICAgICAgIGNvbnRleHRWaWRlby5pbnB1dFgudmFsdWUgPSB0aGlzLmNvbnRleHQub3B0aW9uLnZpZGVvV2lkdGggPT09IGNvbnRleHRWaWRlby5fZGVmYXVsdFNpemVYID8gJycgOiB0aGlzLmNvbnRleHQub3B0aW9uLnZpZGVvV2lkdGg7XG4gICAgICAgICAgICBjb250ZXh0VmlkZW8uaW5wdXRZLnZhbHVlID0gdGhpcy5jb250ZXh0Lm9wdGlvbi52aWRlb0hlaWdodCA9PT0gY29udGV4dFZpZGVvLl9kZWZhdWx0U2l6ZVkgPyAnJyA6IHRoaXMuY29udGV4dC5vcHRpb24udmlkZW9IZWlnaHQ7XG4gICAgICAgICAgICBjb250ZXh0VmlkZW8ucHJvcG9ydGlvbi5jaGVja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIGNvbnRleHRWaWRlby5wcm9wb3J0aW9uLmRpc2FibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy52aWRlby5zZXRWaWRlb1JhdGlvU2VsZWN0LmNhbGwodGhpcywgY29udGV4dFZpZGVvLl9kZWZhdWx0UmF0aW8pO1xuICAgICAgICB9XG4gICAgfVxufTtcbiIsIi8qXG4gKiB3eXNpd3lnIHdlYiBlZGl0b3JcbiAqXG4gKiBzdW5lZGl0b3IuanNcbiAqIENvcHlyaWdodCAyMDE3IEppSG9uZyBMZWUuXG4gKiBNSVQgbGljZW5zZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgZGlhbG9nIGZyb20gJy4uL21vZHVsZXMvZGlhbG9nJztcbmltcG9ydCBjb21wb25lbnQgZnJvbSAnLi4vbW9kdWxlcy9jb21wb25lbnQnO1xuaW1wb3J0IGZpbGVNYW5hZ2VyIGZyb20gJy4uL21vZHVsZXMvZmlsZU1hbmFnZXInO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gICAgbmFtZTogJ2F1ZGlvJyxcbiAgICBkaXNwbGF5OiAnZGlhbG9nJyxcbiAgICBhZGQ6IGZ1bmN0aW9uIChjb3JlKSB7XG4gICAgICAgIGNvcmUuYWRkTW9kdWxlKFtkaWFsb2csIGNvbXBvbmVudCwgZmlsZU1hbmFnZXJdKTtcblxuICAgICAgICBjb25zdCBjb250ZXh0ID0gY29yZS5jb250ZXh0O1xuICAgICAgICBjb25zdCBjb250ZXh0QXVkaW8gPSBjb250ZXh0LmF1ZGlvID0ge1xuICAgICAgICAgICAgX2luZm9MaXN0OiBbXSwgLy8gQE92ZXJyaWRlIGZpbGVNYW5hZ2VyXG4gICAgICAgICAgICBfaW5mb0luZGV4OiAwLCAvLyBAT3ZlcnJpZGUgZmlsZU1hbmFnZXJcbiAgICAgICAgICAgIF91cGxvYWRGaWxlTGVuZ3RoOiAwLCAvLyBAT3ZlcnJpZGUgZmlsZU1hbmFnZXJcbiAgICAgICAgICAgIGZvY3VzRWxlbWVudDogbnVsbCwgLy8gQE92ZXJyaWRlIC8vIFRoaXMgZWxlbWVudCBoYXMgZm9jdXMgd2hlbiB0aGUgZGlhbG9nIGlzIG9wZW5lZC5cbiAgICAgICAgICAgIHRhcmdldFNlbGVjdDogbnVsbCxcbiAgICAgICAgICAgIF9vcmlnaW5fdzogY29udGV4dC5vcHRpb24uYXVkaW9XaWR0aCxcbiAgICAgICAgICAgIF9vcmlnaW5faDogY29udGV4dC5vcHRpb24uYXVkaW9IZWlnaHQsXG4gICAgICAgICAgICBfbGlua1ZhbHVlOiAnJyxcbiAgICAgICAgICAgIC8vIEByZXF1aXJlIEBPdmVycmlkZSBjb21wb25lbnRcbiAgICAgICAgICAgIF9lbGVtZW50OiBudWxsLFxuICAgICAgICAgICAgX2NvdmVyOiBudWxsLFxuICAgICAgICAgICAgX2NvbnRhaW5lcjogbnVsbCxcbiAgICAgICAgfTtcblxuICAgICAgICAvKiogZGlhbG9nICovXG4gICAgICAgIGxldCBhdWRpb19kaWFsb2cgPSB0aGlzLnNldERpYWxvZy5jYWxsKGNvcmUpO1xuICAgICAgICBjb250ZXh0QXVkaW8ubW9kYWwgPSBhdWRpb19kaWFsb2c7XG4gICAgICAgIGNvbnRleHRBdWRpby5hdWRpb0lucHV0RmlsZSA9IGF1ZGlvX2RpYWxvZy5xdWVyeVNlbGVjdG9yKCcuX3NlX2F1ZGlvX2ZpbGVzJyk7XG4gICAgICAgIGNvbnRleHRBdWRpby5hdWRpb1VybEZpbGUgPSBhdWRpb19kaWFsb2cucXVlcnlTZWxlY3RvcignLnNlLWlucHV0LXVybCcpO1xuICAgICAgICBjb250ZXh0QXVkaW8uZm9jdXNFbGVtZW50ID0gY29udGV4dEF1ZGlvLmF1ZGlvSW5wdXRGaWxlIHx8IGNvbnRleHRBdWRpby5hdWRpb1VybEZpbGU7XG4gICAgICAgIGNvbnRleHRBdWRpby5wcmV2aWV3ID0gYXVkaW9fZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5zZS1saW5rLXByZXZpZXcnKTtcblxuICAgICAgICAvKiogY29udHJvbGxlciAqL1xuICAgICAgICBsZXQgYXVkaW9fY29udHJvbGxlciA9IHRoaXMuc2V0Q29udHJvbGxlci5jYWxsKGNvcmUpO1xuICAgICAgICBjb250ZXh0QXVkaW8uY29udHJvbGxlciA9IGF1ZGlvX2NvbnRyb2xsZXI7XG5cbiAgICAgICAgYXVkaW9fY29udHJvbGxlci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBjb3JlLmV2ZW50U3RvcCk7XG5cbiAgICAgICAgLyoqIGFkZCBldmVudCBsaXN0ZW5lcnMgKi9cbiAgICAgICAgYXVkaW9fZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy5zZS1idG4tcHJpbWFyeScpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5zdWJtaXQuYmluZChjb3JlKSk7XG4gICAgICAgIGlmIChjb250ZXh0QXVkaW8uYXVkaW9JbnB1dEZpbGUpIGF1ZGlvX2RpYWxvZy5xdWVyeVNlbGVjdG9yKCcuc2UtZGlhbG9nLWZpbGVzLWVkZ2UtYnV0dG9uJykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9yZW1vdmVTZWxlY3RlZEZpbGVzLmJpbmQoY29udGV4dEF1ZGlvLmF1ZGlvSW5wdXRGaWxlLCBjb250ZXh0QXVkaW8uYXVkaW9VcmxGaWxlLCBjb250ZXh0QXVkaW8ucHJldmlldykpO1xuICAgICAgICBpZiAoY29udGV4dEF1ZGlvLmF1ZGlvSW5wdXRGaWxlICYmIGNvbnRleHRBdWRpby5hdWRpb1VybEZpbGUpIGNvbnRleHRBdWRpby5hdWRpb0lucHV0RmlsZS5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCB0aGlzLl9maWxlSW5wdXRDaGFuZ2UuYmluZChjb250ZXh0QXVkaW8pKTtcbiAgICAgICAgYXVkaW9fY29udHJvbGxlci5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMub25DbGlja19jb250cm9sbGVyLmJpbmQoY29yZSkpO1xuICAgICAgICBpZiAoY29udGV4dEF1ZGlvLmF1ZGlvVXJsRmlsZSkgY29udGV4dEF1ZGlvLmF1ZGlvVXJsRmlsZS5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIHRoaXMuX29uTGlua1ByZXZpZXcuYmluZChjb250ZXh0QXVkaW8ucHJldmlldywgY29udGV4dEF1ZGlvLCBjb250ZXh0Lm9wdGlvbnMubGlua1Byb3RvY29sKSk7XG5cbiAgICAgICAgLyoqIGFwcGVuZCBodG1sICovXG4gICAgICAgIGNvbnRleHQuZGlhbG9nLm1vZGFsLmFwcGVuZENoaWxkKGF1ZGlvX2RpYWxvZyk7XG5cbiAgICAgICAgLyoqIGFwcGVuZCBjb250cm9sbGVyICovXG4gICAgICAgIGNvbnRleHQuZWxlbWVudC5yZWxhdGl2ZS5hcHBlbmRDaGlsZChhdWRpb19jb250cm9sbGVyKTtcblxuICAgICAgICAvKiogZW1wdHkgbWVtb3J5ICovXG4gICAgICAgIGF1ZGlvX2RpYWxvZyA9IG51bGwsIGF1ZGlvX2NvbnRyb2xsZXIgPSBudWxsO1xuICAgIH0sXG5cbiAgICAvKiogSFRNTCAtIGRpYWxvZyAqL1xuICAgIHNldERpYWxvZzogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBvcHRpb24gPSB0aGlzLmNvbnRleHQub3B0aW9uO1xuICAgICAgICBjb25zdCBsYW5nID0gdGhpcy5sYW5nO1xuICAgICAgICBjb25zdCBkaWFsb2cgPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XG5cbiAgICAgICAgZGlhbG9nLmNsYXNzTmFtZSA9ICdzZS1kaWFsb2ctY29udGVudCc7XG4gICAgICAgIGRpYWxvZy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICBsZXQgaHRtbCA9ICcnICtcbiAgICAgICAgICAgICc8Zm9ybSBtZXRob2Q9XCJwb3N0XCIgZW5jdHlwZT1cIm11bHRpcGFydC9mb3JtLWRhdGFcIj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1oZWFkZXJcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtY29tbWFuZD1cImNsb3NlXCIgY2xhc3M9XCJzZS1idG4gc2UtZGlhbG9nLWNsb3NlXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCIgdGl0bGU9XCInICsgbGFuZy5kaWFsb2dCb3guY2xvc2UgKyAnXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmljb25zLmNhbmNlbCArXG4gICAgICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtbW9kYWwtdGl0bGVcIj4nICsgbGFuZy5kaWFsb2dCb3guYXVkaW9Cb3gudGl0bGUgKyAnPC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1ib2R5XCI+JztcblxuICAgICAgICAgICAgICAgIGlmIChvcHRpb24uYXVkaW9GaWxlSW5wdXQpIHtcbiAgICAgICAgICAgICAgICAgICAgaHRtbCArPSAnJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1mb3JtXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxsYWJlbD4nICsgbGFuZy5kaWFsb2dCb3guYXVkaW9Cb3guZmlsZSArICc8L2xhYmVsPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZGlhbG9nLWZvcm0tZmlsZXNcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxpbnB1dCBjbGFzcz1cInNlLWlucHV0LWZvcm0gX3NlX2F1ZGlvX2ZpbGVzXCIgdHlwZT1cImZpbGVcIiBhY2NlcHQ9XCInICsgb3B0aW9uLmF1ZGlvQWNjZXB0ICsgJ1wiJyArIChvcHRpb24uYXVkaW9NdWx0aXBsZUZpbGUgPyAnIG11bHRpcGxlPVwibXVsdGlwbGVcIicgOiAnJykgKyAnLz4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtY29tbWFuZD1cImZpbGVzUmVtb3ZlXCIgY2xhc3M9XCJzZS1idG4gc2UtZGlhbG9nLWZpbGVzLWVkZ2UtYnV0dG9uIHNlLWZpbGUtcmVtb3ZlXCIgdGl0bGU9XCInICsgbGFuZy5jb250cm9sbGVyLnJlbW92ZSArICdcIj4nICsgdGhpcy5pY29ucy5jYW5jZWwgKyAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzwvZGl2Pic7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9uLmF1ZGlvVXJsSW5wdXQpIHtcbiAgICAgICAgICAgICAgICAgICAgaHRtbCArPSAnJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1mb3JtXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxsYWJlbD4nICsgbGFuZy5kaWFsb2dCb3guYXVkaW9Cb3gudXJsICsgJzwvbGFiZWw+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxpbnB1dCBjbGFzcz1cInNlLWlucHV0LWZvcm0gc2UtaW5wdXQtdXJsXCIgdHlwZT1cInRleHRcIiAvPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8cHJlIGNsYXNzPVwic2UtbGluay1wcmV2aWV3XCI+PC9wcmU+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGh0bWwgKz0gJycgK1xuICAgICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1mb290ZXJcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cInN1Ym1pdFwiIGNsYXNzPVwic2UtYnRuLXByaW1hcnlcIiB0aXRsZT1cIicgKyBsYW5nLmRpYWxvZ0JveC5zdWJtaXRCdXR0b24gKyAnXCI+PHNwYW4+JyArIGxhbmcuZGlhbG9nQm94LnN1Ym1pdEJ1dHRvbiArICc8L3NwYW4+PC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgJzwvZm9ybT4nO1xuXG4gICAgICAgIGRpYWxvZy5pbm5lckhUTUwgPSBodG1sO1xuXG4gICAgICAgIHJldHVybiBkaWFsb2c7XG4gICAgfSxcblxuICAgIC8qKiBIVE1MIC0gY29udHJvbGxlciAqL1xuICAgIHNldENvbnRyb2xsZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgbGFuZyA9IHRoaXMubGFuZztcbiAgICAgICAgY29uc3QgaWNvbnMgPSB0aGlzLmljb25zO1xuICAgICAgICBjb25zdCBsaW5rX2J0biA9IHRoaXMudXRpbC5jcmVhdGVFbGVtZW50KCdESVYnKTtcblxuICAgICAgICBsaW5rX2J0bi5jbGFzc05hbWUgPSAnc2UtY29udHJvbGxlciBzZS1jb250cm9sbGVyLWxpbmsnO1xuICAgICAgICBsaW5rX2J0bi5pbm5lckhUTUwgPSAnJyArXG4gICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWFycm93IHNlLWFycm93LXVwXCI+PC9kaXY+JyArXG4gICAgICAgICAgICAnPGRpdiBjbGFzcz1cImxpbmstY29udGVudFwiPicgK1xuICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtYnRuLWdyb3VwXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJ1cGRhdGVcIiB0YWJpbmRleD1cIi0xXCIgY2xhc3M9XCJzZS10b29sdGlwXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICBpY29ucy5lZGl0ICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIuZWRpdCArICc8L3NwYW4+PC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJkZWxldGVcIiB0YWJpbmRleD1cIi0xXCIgY2xhc3M9XCJzZS10b29sdGlwXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICBpY29ucy5kZWxldGUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcuY29udHJvbGxlci5yZW1vdmUgKyAnPC9zcGFuPjwvc3Bhbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzwvYnV0dG9uPicgK1xuICAgICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICc8L2Rpdj4nO1xuXG4gICAgICAgIHJldHVybiBsaW5rX2J0bjtcbiAgICB9LFxuXG4gICAgLy8gRGlzYWJsZSB1cmwgaW5wdXQgd2hlbiB1cGxvYWRpbmcgZmlsZXNcbiAgICBfZmlsZUlucHV0Q2hhbmdlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy5hdWRpb0lucHV0RmlsZS52YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hdWRpb1VybEZpbGUucmVtb3ZlQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xuICAgICAgICAgICAgdGhpcy5wcmV2aWV3LnN0eWxlLnRleHREZWNvcmF0aW9uID0gJyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmF1ZGlvVXJsRmlsZS5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLnByZXZpZXcuc3R5bGUudGV4dERlY29yYXRpb24gPSAnbGluZS10aHJvdWdoJztcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvLyBEaXNhYmxlIHVybCBpbnB1dCB3aGVuIHVwbG9hZGluZyBmaWxlc1xuICAgIF9yZW1vdmVTZWxlY3RlZEZpbGVzOiBmdW5jdGlvbiAodXJsSW5wdXQsIHByZXZpZXcpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9ICcnO1xuICAgICAgICBpZiAodXJsSW5wdXQpIHtcbiAgICAgICAgICAgIHVybElucHV0LnJlbW92ZUF0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgICAgICAgICAgIHByZXZpZXcuc3R5bGUudGV4dERlY29yYXRpb24gPSAnJztcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvLyBjcmVhdGUgbmV3IGF1ZGlvIHRhZ1xuICAgIF9jcmVhdGVBdWRpb1RhZzogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBvQXVkaW8gPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudCgnQVVESU8nKTtcbiAgICAgICAgdGhpcy5wbHVnaW5zLmF1ZGlvLl9zZXRUYWdBdHRycy5jYWxsKHRoaXMsIG9BdWRpbyk7XG5cbiAgICAgICAgY29uc3QgdyA9IHRoaXMuY29udGV4dC5hdWRpby5fb3JpZ2luX3c7XG4gICAgICAgIGNvbnN0IGggPSB0aGlzLmNvbnRleHQuYXVkaW8uX29yaWdpbl9oO1xuICAgICAgICBvQXVkaW8uc2V0QXR0cmlidXRlKCdvcmlnaW4tc2l6ZScsIHcgKyAnLCcgKyBoKTtcbiAgICAgICAgb0F1ZGlvLnN0eWxlLmNzc1RleHQgPSAodyA/ICgnd2lkdGg6JyArIHcgKyAnOyAnKSA6ICcnKSArIChoID8gKCdoZWlnaHQ6JyArIGggKyAnOycpIDogJycpO1xuXG4gICAgICAgIHJldHVybiBvQXVkaW87XG4gICAgfSxcblxuICAgIF9zZXRUYWdBdHRyczogZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2NvbnRyb2xzJywgdHJ1ZSk7XG5cbiAgICAgICAgY29uc3QgYXR0cnMgPSB0aGlzLmNvbnRleHQub3B0aW9ucy5hdWRpb1RhZ0F0dHJzO1xuICAgICAgICBpZiAoIWF0dHJzKSByZXR1cm47XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIGF0dHJzKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMudXRpbC5oYXNPd24oYXR0cnMsIGtleSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoa2V5LCBhdHRyc1trZXldKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBfb25MaW5rUHJldmlldzogZnVuY3Rpb24gKGNvbnRleHQsIHByb3RvY29sLCBlKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gZS50YXJnZXQudmFsdWUudHJpbSgpO1xuICAgICAgICBjb250ZXh0Ll9saW5rVmFsdWUgPSB0aGlzLnRleHRDb250ZW50ID0gIXZhbHVlID8gJycgOiAocHJvdG9jb2wgJiYgdmFsdWUuaW5kZXhPZignOi8vJykgPT09IC0xICYmIHZhbHVlLmluZGV4T2YoJyMnKSAhPT0gMCkgPyBwcm90b2NvbCArIHZhbHVlIDogdmFsdWUuaW5kZXhPZignOi8vJykgPT09IC0xID8gJy8nICsgdmFsdWUgOiB2YWx1ZTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQFJlcXVpcmVkIEBPdmVycmlkZSBmaWxlTWFuYWdlclxuICAgICAqL1xuICAgIGZpbGVUYWdzOiBbJ2F1ZGlvJ10sXG5cbiAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgY29yZSwgZmlsZU1hbmFnZXIsIHJlc2l6aW5nXG4gICAgICogQGRlc2NyaXB0aW9uIEl0IGlzIGNhbGxlZCBmcm9tIGNvcmUuc2VsZWN0Q29tcG9uZW50LlxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBUYXJnZXQgZWxlbWVudFxuICAgICAqL1xuICAgIHNlbGVjdDogZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5wbHVnaW5zLmF1ZGlvLm9uTW9kaWZ5TW9kZS5jYWxsKHRoaXMsIGVsZW1lbnQpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgZmlsZU1hbmFnZXIsIHJlc2l6aW5nIFxuICAgICAqL1xuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIGVsZW1lbnQgPSBlbGVtZW50IHx8IHRoaXMuY29udGV4dC5hdWRpby5fZWxlbWVudDtcbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gdGhpcy51dGlsLmdldFBhcmVudEVsZW1lbnQoZWxlbWVudCwgdGhpcy51dGlsLmlzQ29tcG9uZW50KSB8fCBlbGVtZW50O1xuICAgICAgICBjb25zdCBkYXRhSW5kZXggPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1pbmRleCcpICogMTtcbiAgICAgICAgY29uc3QgZm9jdXNFbCA9IChjb250YWluZXIucHJldmlvdXNFbGVtZW50U2libGluZyB8fCBjb250YWluZXIubmV4dEVsZW1lbnRTaWJsaW5nKTtcblxuICAgICAgICBjb25zdCBlbXB0eURpdiA9IGNvbnRhaW5lci5wYXJlbnROb2RlO1xuICAgICAgICB0aGlzLnV0aWwucmVtb3ZlSXRlbShjb250YWluZXIpO1xuICAgICAgICB0aGlzLnBsdWdpbnMuYXVkaW8uaW5pdC5jYWxsKHRoaXMpO1xuICAgICAgICB0aGlzLmNvbnRyb2xsZXJzT2ZmKCk7XG5cbiAgICAgICAgaWYgKGVtcHR5RGl2ICE9PSB0aGlzLmNvbnRleHQuZWxlbWVudC53eXNpd3lnKSB0aGlzLnV0aWwucmVtb3ZlSXRlbUFsbFBhcmVudHMoZW1wdHlEaXYsIGZ1bmN0aW9uIChjdXJyZW50KSB7IHJldHVybiBjdXJyZW50LmNoaWxkTm9kZXMubGVuZ3RoID09PSAwOyB9LCBudWxsKTtcblxuICAgICAgICAvLyBmb2N1c1xuICAgICAgICB0aGlzLmZvY3VzRWRnZShmb2N1c0VsKTtcblxuICAgICAgICAvLyBmaWxlTWFuYWdlciBldmVudFxuICAgICAgICB0aGlzLnBsdWdpbnMuZmlsZU1hbmFnZXIuZGVsZXRlSW5mby5jYWxsKHRoaXMsICdhdWRpbycsIGRhdGFJbmRleCwgdGhpcy5mdW5jdGlvbnMub25BdWRpb1VwbG9hZCk7XG5cbiAgICAgICAgLy8gaGlzdG9yeSBzdGFja1xuICAgICAgICB0aGlzLmhpc3RvcnkucHVzaChmYWxzZSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSBmaWxlTWFuYWdlclxuICAgICAqL1xuICAgIGNoZWNrRmlsZUluZm86IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5wbHVnaW5zLmZpbGVNYW5hZ2VyLmNoZWNrSW5mby5jYWxsKHRoaXMsICdhdWRpbycsIFsnYXVkaW8nXSwgdGhpcy5mdW5jdGlvbnMub25BdWRpb1VwbG9hZCwgdGhpcy5wbHVnaW5zLmF1ZGlvLnVwZGF0ZUNvdmVyLmJpbmQodGhpcyksIGZhbHNlKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIGZpbGVNYW5hZ2VyXG4gICAgICovXG4gICAgcmVzZXRGaWxlSW5mbzogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnBsdWdpbnMuZmlsZU1hbmFnZXIucmVzZXRJbmZvLmNhbGwodGhpcywgJ2F1ZGlvJywgdGhpcy5mdW5jdGlvbnMub25BdWRpb1VwbG9hZCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBSZXF1aXJlZCBAT3ZlcnJpZGUgZGlhbG9nXG4gICAgICovXG4gICAgb246IGZ1bmN0aW9uICh1cGRhdGUpIHtcbiAgICAgICAgY29uc3QgY29udGV4dEF1ZGlvID0gdGhpcy5jb250ZXh0LmF1ZGlvO1xuXG4gICAgICAgIGlmICghdXBkYXRlKSB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMuYXVkaW8uaW5pdC5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgaWYgKGNvbnRleHRBdWRpby5hdWRpb0lucHV0RmlsZSAmJiB0aGlzLmNvbnRleHQub3B0aW9ucy5hdWRpb011bHRpcGxlRmlsZSkgY29udGV4dEF1ZGlvLmF1ZGlvSW5wdXRGaWxlLnNldEF0dHJpYnV0ZSgnbXVsdGlwbGUnLCAnbXVsdGlwbGUnKTtcbiAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0QXVkaW8uX2VsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5kaWFsb2cudXBkYXRlTW9kYWwgPSB0cnVlO1xuICAgICAgICAgICAgY29udGV4dEF1ZGlvLl9saW5rVmFsdWUgPSBjb250ZXh0QXVkaW8ucHJldmlldy50ZXh0Q29udGVudCA9IGNvbnRleHRBdWRpby5hdWRpb1VybEZpbGUudmFsdWUgPSBjb250ZXh0QXVkaW8uX2VsZW1lbnQuc3JjO1xuICAgICAgICAgICAgaWYgKGNvbnRleHRBdWRpby5hdWRpb0lucHV0RmlsZSAmJiB0aGlzLmNvbnRleHQub3B0aW9ucy5hdWRpb011bHRpcGxlRmlsZSkgY29udGV4dEF1ZGlvLmF1ZGlvSW5wdXRGaWxlLnJlbW92ZUF0dHJpYnV0ZSgnbXVsdGlwbGUnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjb250ZXh0QXVkaW8uYXVkaW9JbnB1dEZpbGUgJiYgdGhpcy5jb250ZXh0Lm9wdGlvbnMuYXVkaW9NdWx0aXBsZUZpbGUpIGNvbnRleHRBdWRpby5hdWRpb0lucHV0RmlsZS5yZW1vdmVBdHRyaWJ1dGUoJ211bHRpcGxlJyk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQFJlcXVpcmVkIEBPdmVycmlkZSBkaWFsb2dcbiAgICAgKi9cbiAgICBvcGVuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucGx1Z2lucy5kaWFsb2cub3Blbi5jYWxsKHRoaXMsICdhdWRpbycsICdhdWRpbycgPT09IHRoaXMuY3VycmVudENvbnRyb2xsZXJOYW1lKTtcbiAgICB9LFxuXG4gICAgc3VibWl0OiBmdW5jdGlvbiAoZSkge1xuICAgICAgICBjb25zdCBjb250ZXh0QXVkaW8gPSB0aGlzLmNvbnRleHQuYXVkaW87XG5cbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoY29udGV4dEF1ZGlvLmF1ZGlvSW5wdXRGaWxlICYmIGNvbnRleHRBdWRpby5hdWRpb0lucHV0RmlsZS5maWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zaG93TG9hZGluZygpO1xuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2lucy5hdWRpby5zdWJtaXRBY3Rpb24uY2FsbCh0aGlzLCBjb250ZXh0QXVkaW8uYXVkaW9JbnB1dEZpbGUuZmlsZXMpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0QXVkaW8uYXVkaW9VcmxGaWxlICYmIGNvbnRleHRBdWRpby5fbGlua1ZhbHVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNob3dMb2FkaW5nKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmF1ZGlvLnNldHVwVXJsLmNhbGwodGhpcywgY29udGV4dEF1ZGlvLl9saW5rVmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdGhpcy5jbG9zZUxvYWRpbmcoKTtcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdbU1VORURJVE9SLmF1ZGlvLnN1Ym1pdC5mYWlsXSBjYXVzZSA6IFwiJyArIGVycm9yLm1lc3NhZ2UgKyAnXCInKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5kaWFsb2cuY2xvc2UuY2FsbCh0aGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9LFxuXG4gICAgc3VibWl0QWN0aW9uOiBmdW5jdGlvbiAoZmlsZUxpc3QpIHtcbiAgICAgICAgaWYgKGZpbGVMaXN0Lmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgICAgIGxldCBmaWxlU2l6ZSA9IDA7XG4gICAgICAgIGxldCBmaWxlcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gZmlsZUxpc3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGlmICgvYXVkaW8vaS50ZXN0KGZpbGVMaXN0W2ldLnR5cGUpKSB7XG4gICAgICAgICAgICAgICAgZmlsZXMucHVzaChmaWxlTGlzdFtpXSk7XG4gICAgICAgICAgICAgICAgZmlsZVNpemUgKz0gZmlsZUxpc3RbaV0uc2l6ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxpbWl0U2l6ZSA9IHRoaXMuY29udGV4dC5vcHRpb24uYXVkaW9VcGxvYWRTaXplTGltaXQ7XG4gICAgICAgIGlmIChsaW1pdFNpemUgPiAwKSB7XG4gICAgICAgICAgICBsZXQgaW5mb1NpemUgPSAwO1xuICAgICAgICAgICAgY29uc3QgYXVkaW9zSW5mbyA9IHRoaXMuY29udGV4dC5hdWRpby5faW5mb0xpc3Q7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gYXVkaW9zSW5mby5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIGluZm9TaXplICs9IGF1ZGlvc0luZm9baV0uc2l6ZSAqIDE7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICgoZmlsZVNpemUgKyBpbmZvU2l6ZSkgPiBsaW1pdFNpemUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlTG9hZGluZygpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGVyciA9ICdbU1VORURJVE9SLmF1ZGlvVXBsb2FkLmZhaWxdIFNpemUgb2YgdXBsb2FkYWJsZSB0b3RhbCBhdWRpb3M6ICcgKyAobGltaXRTaXplLzEwMDApICsgJ0tCJztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5mdW5jdGlvbnMub25BdWRpb1VwbG9hZEVycm9yICE9PSAnZnVuY3Rpb24nIHx8IHRoaXMuZnVuY3Rpb25zLm9uQXVkaW9VcGxvYWRFcnJvcihlcnIsIHsgJ2xpbWl0U2l6ZSc6IGxpbWl0U2l6ZSwgJ2N1cnJlbnRTaXplJzogaW5mb1NpemUsICd1cGxvYWRTaXplJzogZmlsZVNpemUgfSwgdGhpcykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mdW5jdGlvbnMubm90aWNlT3BlbihlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb250ZXh0QXVkaW8gPSB0aGlzLmNvbnRleHQuYXVkaW87XG4gICAgICAgIGNvbnRleHRBdWRpby5fdXBsb2FkRmlsZUxlbmd0aCA9IGZpbGVzLmxlbmd0aDtcblxuICAgICAgICBjb25zdCBpbmZvID0ge1xuICAgICAgICAgICAgaXNVcGRhdGU6IHRoaXMuY29udGV4dC5kaWFsb2cudXBkYXRlTW9kYWwsXG4gICAgICAgICAgICBlbGVtZW50OiBjb250ZXh0QXVkaW8uX2VsZW1lbnRcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAodHlwZW9mIHRoaXMuZnVuY3Rpb25zLm9uQXVkaW9VcGxvYWRCZWZvcmUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuZnVuY3Rpb25zLm9uQXVkaW9VcGxvYWRCZWZvcmUoZmlsZXMsIGluZm8sIHRoaXMsIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEgJiYgdGhpcy5fdy5BcnJheS5pc0FycmF5KGRhdGEucmVzdWx0KSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMuYXVkaW8ucmVnaXN0ZXIuY2FsbCh0aGlzLCBpbmZvLCBkYXRhKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMuYXVkaW8udXBsb2FkLmNhbGwodGhpcywgaW5mbywgZGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfS5iaW5kKHRoaXMpKTtcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICd1bmRlZmluZWQnKSByZXR1cm47XG4gICAgICAgICAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2VMb2FkaW5nKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdvYmplY3QnICYmIHJlc3VsdC5sZW5ndGggPiAwKSBmaWxlcyA9IHJlc3VsdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucGx1Z2lucy5hdWRpby51cGxvYWQuY2FsbCh0aGlzLCBpbmZvLCBmaWxlcyk7XG4gICAgfSxcblxuICAgIGVycm9yOiBmdW5jdGlvbiAobWVzc2FnZSwgcmVzcG9uc2UpIHtcbiAgICAgICAgdGhpcy5jbG9zZUxvYWRpbmcoKTtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmZ1bmN0aW9ucy5vbkF1ZGlvVXBsb2FkRXJyb3IgIT09ICdmdW5jdGlvbicgfHwgdGhpcy5mdW5jdGlvbnMub25BdWRpb1VwbG9hZEVycm9yKG1lc3NhZ2UsIHJlc3BvbnNlLCB0aGlzKSkge1xuICAgICAgICAgICAgdGhpcy5mdW5jdGlvbnMubm90aWNlT3BlbihtZXNzYWdlKTtcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdbU1VORURJVE9SLnBsdWdpbi5hdWRpby5leGNlcHRpb25dIHJlc3BvbnNlOiAnICsgbWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgdXBsb2FkOiBmdW5jdGlvbiAoaW5mbywgZmlsZXMpIHtcbiAgICAgICAgaWYgKCFmaWxlcykge1xuICAgICAgICAgICAgdGhpcy5jbG9zZUxvYWRpbmcoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGZpbGVzID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmF1ZGlvLmVycm9yLmNhbGwodGhpcywgZmlsZXMsIG51bGwpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYXVkaW9VcGxvYWRVcmwgPSB0aGlzLmNvbnRleHQub3B0aW9uLmF1ZGlvVXBsb2FkVXJsO1xuICAgICAgICBjb25zdCBmaWxlc0xlbiA9IHRoaXMuY29udGV4dC5kaWFsb2cudXBkYXRlTW9kYWwgPyAxIDogZmlsZXMubGVuZ3RoO1xuXG4gICAgICAgIC8vIGNyZWF0ZSBmb3JtRGF0YVxuICAgICAgICBjb25zdCBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZpbGVzTGVuOyBpKyspIHtcbiAgICAgICAgICAgIGZvcm1EYXRhLmFwcGVuZCgnZmlsZS0nICsgaSwgZmlsZXNbaV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gc2VydmVyIHVwbG9hZFxuICAgICAgICB0aGlzLnBsdWdpbnMuZmlsZU1hbmFnZXIudXBsb2FkLmNhbGwodGhpcywgYXVkaW9VcGxvYWRVcmwsIHRoaXMuY29udGV4dC5vcHRpb24uYXVkaW9VcGxvYWRIZWFkZXIsIGZvcm1EYXRhLCB0aGlzLnBsdWdpbnMuYXVkaW8uY2FsbEJhY2tfdXBsb2FkLmJpbmQodGhpcywgaW5mbyksIHRoaXMuZnVuY3Rpb25zLm9uQXVkaW9VcGxvYWRFcnJvcik7XG4gICAgfSxcblxuICAgIGNhbGxCYWNrX3VwbG9hZDogZnVuY3Rpb24gKGluZm8sIHhtbEh0dHApIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmZ1bmN0aW9ucy5hdWRpb1VwbG9hZEhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuZnVuY3Rpb25zLmF1ZGlvVXBsb2FkSGFuZGxlcih4bWxIdHRwLCBpbmZvLCB0aGlzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gSlNPTi5wYXJzZSh4bWxIdHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICBpZiAocmVzcG9uc2UuZXJyb3JNZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmF1ZGlvLmVycm9yLmNhbGwodGhpcywgcmVzcG9uc2UuZXJyb3JNZXNzYWdlLCByZXNwb25zZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2lucy5hdWRpby5yZWdpc3Rlci5jYWxsKHRoaXMsIGluZm8sIHJlc3BvbnNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICByZWdpc3RlcjogZnVuY3Rpb24gKGluZm8sIHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnN0IGZpbGVMaXN0ID0gcmVzcG9uc2UucmVzdWx0O1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBmaWxlTGlzdC5sZW5ndGgsIGZpbGUsIG9BdWRpbzsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoaW5mby5pc1VwZGF0ZSkgb0F1ZGlvID0gaW5mby5lbGVtZW50O1xuICAgICAgICAgICAgZWxzZSBvQXVkaW8gPSB0aGlzLnBsdWdpbnMuYXVkaW8uX2NyZWF0ZUF1ZGlvVGFnLmNhbGwodGhpcyk7XG5cbiAgICAgICAgICAgIGZpbGUgPSB7IG5hbWU6IGZpbGVMaXN0W2ldLm5hbWUsIHNpemU6IGZpbGVMaXN0W2ldLnNpemUgfTtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5hdWRpby5jcmVhdGVfYXVkaW8uY2FsbCh0aGlzLCBvQXVkaW8sIGZpbGVMaXN0W2ldLnVybCwgZmlsZSwgaW5mby5pc1VwZGF0ZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNsb3NlTG9hZGluZygpO1xuICAgIH0sXG5cbiAgICBzZXR1cFVybDogZnVuY3Rpb24gKHNyYykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHNyYy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5hdWRpby5jcmVhdGVfYXVkaW8uY2FsbCh0aGlzLCB0aGlzLnBsdWdpbnMuYXVkaW8uX2NyZWF0ZUF1ZGlvVGFnLmNhbGwodGhpcyksIHNyYywgbnVsbCwgdGhpcy5jb250ZXh0LmRpYWxvZy51cGRhdGVNb2RhbCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcignW1NVTkVESVRPUi5hdWRpby5hdWRpby5mYWlsXSBjYXVzZSA6IFwiJyArIGVycm9yLm1lc3NhZ2UgKyAnXCInKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2VMb2FkaW5nKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgY3JlYXRlX2F1ZGlvOiBmdW5jdGlvbiAoZWxlbWVudCwgc3JjLCBmaWxlLCBpc1VwZGF0ZSkge1xuICAgICAgICBjb25zdCBjb250ZXh0QXVkaW8gPSB0aGlzLmNvbnRleHQuYXVkaW87XG4gICAgICAgIFxuICAgICAgICAvLyBjcmVhdGUgbmV3IHRhZ1xuICAgICAgICBpZiAoIWlzVXBkYXRlKSB7XG4gICAgICAgICAgICBlbGVtZW50LnNyYyA9IHNyYztcbiAgICAgICAgICAgIGNvbnN0IGNvdmVyID0gdGhpcy5wbHVnaW5zLmNvbXBvbmVudC5zZXRfY292ZXIuY2FsbCh0aGlzLCBlbGVtZW50KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMucGx1Z2lucy5jb21wb25lbnQuc2V0X2NvbnRhaW5lci5jYWxsKHRoaXMsIGNvdmVyLCAnJyk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaW5zZXJ0Q29tcG9uZW50KGNvbnRhaW5lciwgZmFsc2UsIHRydWUsIGZhbHNlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZm9jdXMoKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gLy8gdXBkYXRlXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNvbnRleHRBdWRpby5fZWxlbWVudCkgZWxlbWVudCA9IGNvbnRleHRBdWRpby5fZWxlbWVudDtcbiAgICAgICAgICAgIGlmIChlbGVtZW50ICYmIGVsZW1lbnQuc3JjICE9PSBzcmMpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LnNyYyA9IHNyYztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RDb21wb25lbnQoZWxlbWVudCwgJ2F1ZGlvJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5wbHVnaW5zLmZpbGVNYW5hZ2VyLnNldEluZm8uY2FsbCh0aGlzLCAnYXVkaW8nLCBlbGVtZW50LCB0aGlzLmZ1bmN0aW9ucy5vbkF1ZGlvVXBsb2FkLCBmaWxlLCBmYWxzZSk7XG4gICAgICAgIHRoaXMuc2VsZWN0Q29tcG9uZW50KGVsZW1lbnQsICdhdWRpbycpO1xuICAgICAgICBpZiAoaXNVcGRhdGUpIHRoaXMuaGlzdG9yeS5wdXNoKGZhbHNlKTtcbiAgICB9LFxuXG4gICAgdXBkYXRlQ292ZXI6IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHRBdWRpbyA9IHRoaXMuY29udGV4dC5hdWRpbztcbiAgICAgICAgdGhpcy5wbHVnaW5zLmF1ZGlvLl9zZXRUYWdBdHRycy5jYWxsKHRoaXMsIGVsZW1lbnQpO1xuICAgICAgICBcbiAgICAgICAgLy8gZmluZCBjb21wb25lbnQgZWxlbWVudFxuICAgICAgICBjb25zdCBleGlzdEVsZW1lbnQgPSB0aGlzLnV0aWwuZ2V0UGFyZW50RWxlbWVudChlbGVtZW50LCB0aGlzLnV0aWwuaXNNZWRpYUNvbXBvbmVudCkgfHwgXG4gICAgICAgICAgICB0aGlzLnV0aWwuZ2V0UGFyZW50RWxlbWVudChlbGVtZW50LCBmdW5jdGlvbiAoY3VycmVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmlzV3lzaXd5Z0RpdihjdXJyZW50LnBhcmVudE5vZGUpO1xuICAgICAgICAgICAgfS5iaW5kKHRoaXMudXRpbCkpO1xuXG4gICAgICAgIC8vIGNsb25lIGVsZW1lbnRcbiAgICAgICAgY29udGV4dEF1ZGlvLl9lbGVtZW50ID0gZWxlbWVudCA9IGVsZW1lbnQuY2xvbmVOb2RlKGZhbHNlKTtcbiAgICAgICAgY29uc3QgY292ZXIgPSB0aGlzLnBsdWdpbnMuY29tcG9uZW50LnNldF9jb3Zlci5jYWxsKHRoaXMsIGVsZW1lbnQpO1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLnBsdWdpbnMuY29tcG9uZW50LnNldF9jb250YWluZXIuY2FsbCh0aGlzLCBjb3ZlciwgJ3NlLWF1ZGlvLWNvbnRhaW5lcicpO1xuXG4gICAgICAgIGV4aXN0RWxlbWVudC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChjb250YWluZXIsIGV4aXN0RWxlbWVudCk7XG4gICAgICAgIHRoaXMucGx1Z2lucy5maWxlTWFuYWdlci5zZXRJbmZvLmNhbGwodGhpcywgJ2F1ZGlvJywgZWxlbWVudCwgdGhpcy5mdW5jdGlvbnMub25BdWRpb1VwbG9hZCwgbnVsbCwgZmFsc2UpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAUmVxdWlyZWQgQE92ZXJyaWRlIGZpbGVNYW5hZ2VyLCByZXNpemluZ1xuICAgICAqL1xuICAgIG9uTW9kaWZ5TW9kZTogZnVuY3Rpb24gKHNlbGVjdGlvblRhZykge1xuICAgICAgICBjb25zdCBjb250ZXh0QXVkaW8gPSB0aGlzLmNvbnRleHQuYXVkaW87XG4gICAgICAgIFxuICAgICAgICB0aGlzLnNldENvbnRyb2xsZXJQb3NpdGlvbihjb250ZXh0QXVkaW8uY29udHJvbGxlciwgc2VsZWN0aW9uVGFnLCAnYm90dG9tJywge2xlZnQ6IDAsIHRvcDogMH0pO1xuICAgICAgICB0aGlzLmNvbnRyb2xsZXJzT24oY29udGV4dEF1ZGlvLmNvbnRyb2xsZXIsIHNlbGVjdGlvblRhZywgdGhpcy5wbHVnaW5zLmF1ZGlvLm9uQ29udHJvbGxlck9mZi5iaW5kKHRoaXMsIHNlbGVjdGlvblRhZyksICdhdWRpbycpO1xuXG4gICAgICAgIHRoaXMudXRpbC5hZGRDbGFzcyhzZWxlY3Rpb25UYWcsICdhY3RpdmUnKTtcbiAgICAgICAgY29udGV4dEF1ZGlvLl9lbGVtZW50ID0gc2VsZWN0aW9uVGFnO1xuICAgICAgICBjb250ZXh0QXVkaW8uX2NvdmVyID0gdGhpcy51dGlsLmdldFBhcmVudEVsZW1lbnQoc2VsZWN0aW9uVGFnLCAnRklHVVJFJyk7XG4gICAgICAgIGNvbnRleHRBdWRpby5fY29udGFpbmVyID0gdGhpcy51dGlsLmdldFBhcmVudEVsZW1lbnQoc2VsZWN0aW9uVGFnLCB0aGlzLnV0aWwuaXNDb21wb25lbnQpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAUmVxdWlyZWQgQE92ZXJyaWRlIGZpbGVNYW5hZ2VyLCByZXNpemluZ1xuICAgICAqL1xuICAgIG9wZW5Nb2RpZnk6IGZ1bmN0aW9uIChub3RPcGVuKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRleHQuYXVkaW8uYXVkaW9VcmxGaWxlKSB7XG4gICAgICAgICAgICBjb25zdCBjb250ZXh0QXVkaW8gPSB0aGlzLmNvbnRleHQuYXVkaW87XG4gICAgICAgICAgICBjb250ZXh0QXVkaW8uX2xpbmtWYWx1ZSA9IGNvbnRleHRBdWRpby5wcmV2aWV3LnRleHRDb250ZW50ID0gY29udGV4dEF1ZGlvLmF1ZGlvVXJsRmlsZS52YWx1ZSA9IGNvbnRleHRBdWRpby5fZWxlbWVudC5zcmM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFub3RPcGVuKSB0aGlzLnBsdWdpbnMuZGlhbG9nLm9wZW4uY2FsbCh0aGlzLCAnYXVkaW8nLCB0cnVlKTtcbiAgICB9LFxuXG4gICAgb25DbGlja19jb250cm9sbGVyOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIGNvbnN0IGNvbW1hbmQgPSBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY29tbWFuZCcpO1xuICAgICAgICBpZiAoIWNvbW1hbmQpIHJldHVybjtcblxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgaWYgKC91cGRhdGUvLnRlc3QoY29tbWFuZCkpIHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5hdWRpby5vcGVuTW9kaWZ5LmNhbGwodGhpcywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgeyAvKiogZGVsZXRlICovXG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMuYXVkaW8uZGVzdHJveS5jYWxsKHRoaXMsIHRoaXMuY29udGV4dC5hdWRpby5fZWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbnRyb2xsZXJzT2ZmKCk7XG4gICAgfSxcblxuICAgIG9uQ29udHJvbGxlck9mZjogZnVuY3Rpb24gKHNlbGVjdGlvblRhZykge1xuICAgICAgICB0aGlzLnV0aWwucmVtb3ZlQ2xhc3Moc2VsZWN0aW9uVGFnLCAnYWN0aXZlJyk7XG4gICAgICAgIHRoaXMuY29udGV4dC5hdWRpby5jb250cm9sbGVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBSZXF1aXJlZCBAT3ZlcnJpZGUgZGlhbG9nXG4gICAgICovXG4gICAgaW5pdDogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5jb250ZXh0LmRpYWxvZy51cGRhdGVNb2RhbCkgcmV0dXJuO1xuICAgICAgICBjb25zdCBjb250ZXh0QXVkaW8gPSB0aGlzLmNvbnRleHQuYXVkaW87XG5cbiAgICAgICAgaWYgKGNvbnRleHRBdWRpby5hdWRpb0lucHV0RmlsZSkgY29udGV4dEF1ZGlvLmF1ZGlvSW5wdXRGaWxlLnZhbHVlID0gJyc7XG4gICAgICAgIGlmIChjb250ZXh0QXVkaW8uYXVkaW9VcmxGaWxlKSBjb250ZXh0QXVkaW8uX2xpbmtWYWx1ZSA9IGNvbnRleHRBdWRpby5wcmV2aWV3LnRleHRDb250ZW50ID0gY29udGV4dEF1ZGlvLmF1ZGlvVXJsRmlsZS52YWx1ZSA9ICcnO1xuICAgICAgICBpZiAoY29udGV4dEF1ZGlvLmF1ZGlvSW5wdXRGaWxlICYmIGNvbnRleHRBdWRpby5hdWRpb1VybEZpbGUpIHtcbiAgICAgICAgICAgIGNvbnRleHRBdWRpby5hdWRpb1VybEZpbGUucmVtb3ZlQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xuICAgICAgICAgICAgY29udGV4dEF1ZGlvLnByZXZpZXcuc3R5bGUudGV4dERlY29yYXRpb24gPSAnJztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRleHRBdWRpby5fZWxlbWVudCA9IG51bGw7XG4gICAgfVxufTsiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBkaWFsb2cgZnJvbSAnLi4vbW9kdWxlcy9kaWFsb2cnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gICAgbmFtZTogJ21hdGgnLFxuICAgIGRpc3BsYXk6ICdkaWFsb2cnLFxuICAgIGFkZDogZnVuY3Rpb24gKGNvcmUpIHtcbiAgICAgICAgY29yZS5hZGRNb2R1bGUoW2RpYWxvZ10pO1xuXG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBjb3JlLmNvbnRleHQ7XG4gICAgICAgIGNvbnRleHQubWF0aCA9IHtcbiAgICAgICAgICAgIGZvY3VzRWxlbWVudDogbnVsbCxcbiAgICAgICAgICAgIHByZXZpZXdFbGVtZW50OiBudWxsLFxuICAgICAgICAgICAgZm9udFNpemVFbGVtZW50OiBudWxsLFxuICAgICAgICAgICAgX21hdGhFeHA6IG51bGxcbiAgICAgICAgfTtcblxuICAgICAgICAvKiogbWF0aCBkaWFsb2cgKi9cbiAgICAgICAgbGV0IG1hdGhfZGlhbG9nID0gdGhpcy5zZXREaWFsb2cuY2FsbChjb3JlKTtcbiAgICAgICAgY29udGV4dC5tYXRoLm1vZGFsID0gbWF0aF9kaWFsb2c7XG4gICAgICAgIGNvbnRleHQubWF0aC5mb2N1c0VsZW1lbnQgPSBtYXRoX2RpYWxvZy5xdWVyeVNlbGVjdG9yKCcuc2UtbWF0aC1leHAnKTtcbiAgICAgICAgY29udGV4dC5tYXRoLnByZXZpZXdFbGVtZW50ID0gbWF0aF9kaWFsb2cucXVlcnlTZWxlY3RvcignLnNlLW1hdGgtcHJldmlldycpO1xuICAgICAgICBjb250ZXh0Lm1hdGguZm9udFNpemVFbGVtZW50ID0gbWF0aF9kaWFsb2cucXVlcnlTZWxlY3RvcignLnNlLW1hdGgtc2l6ZScpO1xuICAgICAgICBjb250ZXh0Lm1hdGguZm9jdXNFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgdGhpcy5fcmVuZGVyTWF0aEV4cC5iaW5kKGNvcmUsIGNvbnRleHQubWF0aCksIGZhbHNlKTtcbiAgICAgICAgY29udGV4dC5tYXRoLmZvY3VzRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCB0aGlzLl9yZW5kZXJNYXRoRXhwLmJpbmQoY29yZSwgY29udGV4dC5tYXRoKSwgZmFsc2UpO1xuICAgICAgICBjb250ZXh0Lm1hdGguZm9udFNpemVFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGZ1bmN0aW9uIChlKSB7IHRoaXMuZm9udFNpemUgPSBlLnRhcmdldC52YWx1ZTsgfS5iaW5kKGNvbnRleHQubWF0aC5wcmV2aWV3RWxlbWVudC5zdHlsZSksIGZhbHNlKTtcblxuICAgICAgICAvKiogbWF0aCBjb250cm9sbGVyICovXG4gICAgICAgIGxldCBtYXRoX2NvbnRyb2xsZXIgPSB0aGlzLnNldENvbnRyb2xsZXJfTWF0aEJ1dHRvbi5jYWxsKGNvcmUpO1xuICAgICAgICBjb250ZXh0Lm1hdGgubWF0aENvbnRyb2xsZXIgPSBtYXRoX2NvbnRyb2xsZXI7XG4gICAgICAgIGNvbnRleHQubWF0aC5fbWF0aEV4cCA9IG51bGw7XG4gICAgICAgIG1hdGhfY29udHJvbGxlci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBjb3JlLmV2ZW50U3RvcCk7XG5cbiAgICAgICAgLyoqIGFkZCBldmVudCBsaXN0ZW5lcnMgKi9cbiAgICAgICAgbWF0aF9kaWFsb2cucXVlcnlTZWxlY3RvcignLnNlLWJ0bi1wcmltYXJ5JykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLnN1Ym1pdC5iaW5kKGNvcmUpLCBmYWxzZSk7XG4gICAgICAgIG1hdGhfY29udHJvbGxlci5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMub25DbGlja19tYXRoQ29udHJvbGxlci5iaW5kKGNvcmUpKTtcblxuICAgICAgICAvKiogYXBwZW5kIGh0bWwgKi9cbiAgICAgICAgY29udGV4dC5kaWFsb2cubW9kYWwuYXBwZW5kQ2hpbGQobWF0aF9kaWFsb2cpO1xuICAgICAgICBjb250ZXh0LmVsZW1lbnQucmVsYXRpdmUuYXBwZW5kQ2hpbGQobWF0aF9jb250cm9sbGVyKTtcblxuICAgICAgICAvKiogZW1wdHkgbWVtb3J5ICovXG4gICAgICAgIG1hdGhfZGlhbG9nID0gbnVsbCwgbWF0aF9jb250cm9sbGVyID0gbnVsbDtcbiAgICB9LFxuXG4gICAgLyoqIGRpYWxvZyAqL1xuICAgIHNldERpYWxvZzogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBsYW5nID0gdGhpcy5sYW5nO1xuICAgICAgICBjb25zdCBkaWFsb2cgPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XG5cbiAgICAgICAgZGlhbG9nLmNsYXNzTmFtZSA9ICdzZS1kaWFsb2ctY29udGVudCc7XG4gICAgICAgIGRpYWxvZy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICBkaWFsb2cuaW5uZXJIVE1MID0gJycgK1xuICAgICAgICAnPGZvcm0+JyArXG4gICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1oZWFkZXJcIj4nICtcbiAgICAgICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1jb21tYW5kPVwiY2xvc2VcIiBjbGFzcz1cInNlLWJ0biBzZS1kaWFsb2ctY2xvc2VcIiBhcmlhLWxhYmVsPVwiQ2xvc2VcIiB0aXRsZT1cIicgKyBsYW5nLmRpYWxvZ0JveC5jbG9zZSArICdcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pY29ucy5jYW5jZWwgK1xuICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcbiAgICAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJzZS1tb2RhbC10aXRsZVwiPicgKyBsYW5nLmRpYWxvZ0JveC5tYXRoQm94LnRpdGxlICsgJzwvc3Bhbj4nICtcbiAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZGlhbG9nLWJvZHlcIj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1mb3JtXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICc8bGFiZWw+JyArIGxhbmcuZGlhbG9nQm94Lm1hdGhCb3guaW5wdXRMYWJlbCArICcgKDxhIGhyZWY9XCJodHRwczovL2thdGV4Lm9yZy9kb2NzL3N1cHBvcnRlZC5odG1sXCIgdGFyZ2V0PVwiX2JsYW5rXCI+S2FUZVg8L2E+KTwvbGFiZWw+JyArXG4gICAgICAgICAgICAgICAgICAgICc8dGV4dGFyZWEgY2xhc3M9XCJzZS1pbnB1dC1mb3JtIHNlLW1hdGgtZXhwXCIgdHlwZT1cInRleHRcIj48L3RleHRhcmVhPicgK1xuICAgICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWRpYWxvZy1mb3JtXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICc8bGFiZWw+JyArIGxhbmcuZGlhbG9nQm94Lm1hdGhCb3guZm9udFNpemVMYWJlbCArICc8L2xhYmVsPicgK1xuICAgICAgICAgICAgICAgICAgICAnPHNlbGVjdCBjbGFzcz1cInNlLWlucHV0LXNlbGVjdCBzZS1tYXRoLXNpemVcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8b3B0aW9uIHZhbHVlPVwiMWVtXCI+MTwvb3B0aW9uPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxvcHRpb24gdmFsdWU9XCIxLjVlbVwiPjEuNTwvb3B0aW9uPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxvcHRpb24gdmFsdWU9XCIyZW1cIj4yPC9vcHRpb24+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPG9wdGlvbiB2YWx1ZT1cIjIuNWVtXCI+Mi41PC9vcHRpb24+JyArXG4gICAgICAgICAgICAgICAgICAgICc8L3NlbGVjdD4nICtcbiAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1kaWFsb2ctZm9ybVwiPicgK1xuICAgICAgICAgICAgICAgICAgICAnPGxhYmVsPicgKyBsYW5nLmRpYWxvZ0JveC5tYXRoQm94LnByZXZpZXdMYWJlbCArICc8L2xhYmVsPicgK1xuICAgICAgICAgICAgICAgICAgICAnPHAgY2xhc3M9XCJzZS1tYXRoLXByZXZpZXdcIj48L3A+JyArXG4gICAgICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1kaWFsb2ctZm9vdGVyXCI+JyArXG4gICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cInN1Ym1pdFwiIGNsYXNzPVwic2UtYnRuLXByaW1hcnlcIiB0aXRsZT1cIicgKyBsYW5nLmRpYWxvZ0JveC5zdWJtaXRCdXR0b24gKyAnXCI+PHNwYW4+JyArIGxhbmcuZGlhbG9nQm94LnN1Ym1pdEJ1dHRvbiArICc8L3NwYW4+PC9idXR0b24+JyArXG4gICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICc8L2Zvcm0+JztcblxuICAgICAgICByZXR1cm4gZGlhbG9nO1xuICAgIH0sXG5cbiAgICAvKiogbW9kaWZ5IGNvbnRyb2xsZXIgYnV0dG9uICovXG4gICAgc2V0Q29udHJvbGxlcl9NYXRoQnV0dG9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGxhbmcgPSB0aGlzLmxhbmc7XG4gICAgICAgIGNvbnN0IG1hdGhfYnRuID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xuXG4gICAgICAgIG1hdGhfYnRuLmNsYXNzTmFtZSA9ICdzZS1jb250cm9sbGVyIHNlLWNvbnRyb2xsZXItbGluayc7XG4gICAgICAgIG1hdGhfYnRuLmlubmVySFRNTCA9ICcnICtcbiAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1hcnJvdyBzZS1hcnJvdy11cFwiPjwvZGl2PicgK1xuICAgICAgICAnPGRpdiBjbGFzcz1cImxpbmstY29udGVudFwiPicgK1xuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1idG4tZ3JvdXBcIj4nICtcbiAgICAgICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1jb21tYW5kPVwidXBkYXRlXCIgdGFiaW5kZXg9XCItMVwiIGNsYXNzPVwic2UtYnRuIHNlLXRvb2x0aXBcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pY29ucy5lZGl0ICtcbiAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcuY29udHJvbGxlci5lZGl0ICsgJzwvc3Bhbj48L3NwYW4+JyArXG4gICAgICAgICAgICAgICAgJzwvYnV0dG9uPicgK1xuICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJkZWxldGVcIiB0YWJpbmRleD1cIi0xXCIgY2xhc3M9XCJzZS1idG4gc2UtdG9vbHRpcFwiPicgK1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmljb25zLmRlbGV0ZSArXG4gICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIucmVtb3ZlICsgJzwvc3Bhbj48L3NwYW4+JyArXG4gICAgICAgICAgICAgICAgJzwvYnV0dG9uPicgK1xuICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICcnO1xuXG4gICAgICAgIHJldHVybiBtYXRoX2J0bjtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQFJlcXVpcmVkIEBPdmVycmlkZSBkaWFsb2dcbiAgICAgKi9cbiAgICBvcGVuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucGx1Z2lucy5kaWFsb2cub3Blbi5jYWxsKHRoaXMsICdtYXRoJywgJ21hdGgnID09PSB0aGlzLmN1cnJlbnRDb250cm9sbGVyTmFtZSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSBjb3JlIC0gbWFuYWdlZFRhZ3NJbmZvXG4gICAgICovXG4gICAgbWFuYWdlZFRhZ3M6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZTogJ2thdGV4JyxcbiAgICAgICAgICAgIG1ldGhvZDogZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWV4cCcpKSByZXR1cm47XG4gICAgICAgICAgICAgICAgY29uc3QgZG9tID0gdGhpcy5fZC5jcmVhdGVSYW5nZSgpLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCh0aGlzLnBsdWdpbnMubWF0aC5fcmVuZGVyZXIuY2FsbCh0aGlzLCB0aGlzLnV0aWwuSFRNTERlY29kZXIoZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtZXhwJykpKSk7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBkb20ucXVlcnlTZWxlY3RvcignLmthdGV4JykuaW5uZXJIVE1MO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBfcmVuZGVyZXI6IGZ1bmN0aW9uIChleHApIHtcbiAgICAgICAgY29uc3Qga2F0ZXggPSB0aGlzLmNvbnRleHQub3B0aW9uLmthdGV4O1xuICAgICAgICByZXR1cm4ga2F0ZXguc3JjLnJlbmRlclRvU3RyaW5nKGV4cCwga2F0ZXgub3B0aW9ucyk7XG4gICAgfSxcblxuICAgIF9yZW5kZXJNYXRoRXhwOiBmdW5jdGlvbiAoY29udGV4dE1hdGgsIGUpIHtcbiAgICAgICAgY29udGV4dE1hdGgucHJldmlld0VsZW1lbnQuaW5uZXJIVE1MID0gdGhpcy5wbHVnaW5zLm1hdGguX3JlbmRlcmVyLmNhbGwodGhpcywgZS50YXJnZXQudmFsdWUpO1xuICAgIH0sXG5cbiAgICBzdWJtaXQ6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHRoaXMuc2hvd0xvYWRpbmcoKTtcblxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgY29uc3Qgc3VibWl0QWN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC5tYXRoLmZvY3VzRWxlbWVudC52YWx1ZS50cmltKCkubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHRNYXRoID0gdGhpcy5jb250ZXh0Lm1hdGg7XG4gICAgICAgICAgICBjb25zdCBtYXRoRXhwID0gY29udGV4dE1hdGguZm9jdXNFbGVtZW50LnZhbHVlO1xuICAgICAgICAgICAgY29uc3Qga2F0ZXhFbCA9IGNvbnRleHRNYXRoLnByZXZpZXdFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5rYXRleCcpO1xuXG4gICAgICAgICAgICBpZiAoIWthdGV4RWwpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIGthdGV4RWwuY2xhc3NOYW1lID0gJ19fc2VfX2thdGV4ICcgKyBrYXRleEVsLmNsYXNzTmFtZTtcbiAgICAgICAgICAgIGthdGV4RWwuc2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnLCBmYWxzZSk7XG4gICAgICAgICAgICBrYXRleEVsLnNldEF0dHJpYnV0ZSgnZGF0YS1leHAnLCB0aGlzLnV0aWwuSFRNTEVuY29kZXIobWF0aEV4cCkpO1xuICAgICAgICAgICAga2F0ZXhFbC5zZXRBdHRyaWJ1dGUoJ2RhdGEtZm9udC1zaXplJywgY29udGV4dE1hdGguZm9udFNpemVFbGVtZW50LnZhbHVlKTtcbiAgICAgICAgICAgIGthdGV4RWwuc3R5bGUuZm9udFNpemUgPSBjb250ZXh0TWF0aC5mb250U2l6ZUVsZW1lbnQudmFsdWU7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5jb250ZXh0LmRpYWxvZy51cGRhdGVNb2RhbCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRm9ybWF0cyA9IHRoaXMuZ2V0U2VsZWN0ZWRFbGVtZW50cygpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkRm9ybWF0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9Gb3JtYXQgPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudChzZWxlY3RlZEZvcm1hdHNbMF0ubm9kZU5hbWUpO1xuICAgICAgICAgICAgICAgICAgICBvRm9ybWF0LmFwcGVuZENoaWxkKGthdGV4RWwpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaW5zZXJ0Tm9kZShvRm9ybWF0LCBudWxsLCB0cnVlKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5pbnNlcnROb2RlKGthdGV4RWwsIG51bGwsIHRydWUpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgZW1wdHkgPSB0aGlzLnV0aWwuY3JlYXRlVGV4dE5vZGUodGhpcy51dGlsLnplcm9XaWR0aFNwYWNlKTtcbiAgICAgICAgICAgICAgICBrYXRleEVsLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVtcHR5LCBrYXRleEVsLm5leHRTaWJsaW5nKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFJhbmdlKGthdGV4RWwsIDAsIGthdGV4RWwsIDEpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb250YWluZXJFbCA9IHRoaXMudXRpbC5nZXRQYXJlbnRFbGVtZW50KGNvbnRleHRNYXRoLl9tYXRoRXhwLCAnLmthdGV4Jyk7XG4gICAgICAgICAgICAgICAgY29udGFpbmVyRWwucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoa2F0ZXhFbCwgY29udGFpbmVyRWwpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0UmFuZ2Uoa2F0ZXhFbCwgMCwga2F0ZXhFbCwgMSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnRleHRNYXRoLmZvY3VzRWxlbWVudC52YWx1ZSA9ICcnO1xuICAgICAgICAgICAgY29udGV4dE1hdGguZm9udFNpemVFbGVtZW50LnZhbHVlID0gJzFlbSc7XG4gICAgICAgICAgICBjb250ZXh0TWF0aC5wcmV2aWV3RWxlbWVudC5zdHlsZS5mb250U2l6ZSA9ICcxZW0nO1xuICAgICAgICAgICAgY29udGV4dE1hdGgucHJldmlld0VsZW1lbnQuaW5uZXJIVE1MID0gJyc7XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9LmJpbmQodGhpcyk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChzdWJtaXRBY3Rpb24oKSkge1xuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2lucy5kaWFsb2cuY2xvc2UuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICAvLyBoaXN0b3J5IHN0YWNrXG4gICAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnB1c2goZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMuZGlhbG9nLmNsb3NlLmNhbGwodGhpcyk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlTG9hZGluZygpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG5cbiAgICBhY3RpdmU6IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIGlmICghZWxlbWVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuY29udHJvbGxlckFycmF5LmluZGV4T2YodGhpcy5jb250ZXh0Lm1hdGgubWF0aENvbnRyb2xsZXIpID4gLTEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRyb2xsZXJzT2ZmKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtZXhwJykpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbnRyb2xsZXJBcnJheS5pbmRleE9mKHRoaXMuY29udGV4dC5tYXRoLm1hdGhDb250cm9sbGVyKSA8IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFJhbmdlKGVsZW1lbnQsIDAsIGVsZW1lbnQsIDEpO1xuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2lucy5tYXRoLmNhbGxfY29udHJvbGxlci5jYWxsKHRoaXMsIGVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSxcblxuICAgIG9uOiBmdW5jdGlvbiAodXBkYXRlKSB7XG4gICAgICAgIGlmICghdXBkYXRlKSB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMubWF0aC5pbml0LmNhbGwodGhpcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBjb250ZXh0TWF0aCA9IHRoaXMuY29udGV4dC5tYXRoO1xuICAgICAgICAgICAgaWYgKGNvbnRleHRNYXRoLl9tYXRoRXhwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXhwID0gdGhpcy51dGlsLkhUTUxEZWNvZGVyKGNvbnRleHRNYXRoLl9tYXRoRXhwLmdldEF0dHJpYnV0ZSgnZGF0YS1leHAnKSk7XG4gICAgICAgICAgICAgICAgY29uc3QgZm9udFNpemUgPSBjb250ZXh0TWF0aC5fbWF0aEV4cC5nZXRBdHRyaWJ1dGUoJ2RhdGEtZm9udC1zaXplJykgfHwgJzFlbSc7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LmRpYWxvZy51cGRhdGVNb2RhbCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29udGV4dE1hdGguZm9jdXNFbGVtZW50LnZhbHVlID0gZXhwO1xuICAgICAgICAgICAgICAgIGNvbnRleHRNYXRoLmZvbnRTaXplRWxlbWVudC52YWx1ZSA9IGZvbnRTaXplO1xuICAgICAgICAgICAgICAgIGNvbnRleHRNYXRoLnByZXZpZXdFbGVtZW50LmlubmVySFRNTCA9IHRoaXMucGx1Z2lucy5tYXRoLl9yZW5kZXJlci5jYWxsKHRoaXMsIGV4cCk7XG4gICAgICAgICAgICAgICAgY29udGV4dE1hdGgucHJldmlld0VsZW1lbnQuc3R5bGUuZm9udFNpemUgPSBmb250U2l6ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBjYWxsX2NvbnRyb2xsZXI6IGZ1bmN0aW9uIChtYXRoVGFnKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC5tYXRoLl9tYXRoRXhwID0gbWF0aFRhZztcbiAgICAgICAgY29uc3QgbWF0aEJ0biA9IHRoaXMuY29udGV4dC5tYXRoLm1hdGhDb250cm9sbGVyO1xuXG4gICAgICAgIHRoaXMuc2V0Q29udHJvbGxlclBvc2l0aW9uKG1hdGhCdG4sIG1hdGhUYWcsICdib3R0b20nLCB7bGVmdDogMCwgdG9wOiAwfSk7XG4gICAgICAgIHRoaXMuY29udHJvbGxlcnNPbihtYXRoQnRuLCBtYXRoVGFnLCAnbWF0aCcpO1xuICAgIH0sXG5cbiAgICBvbkNsaWNrX21hdGhDb250cm9sbGVyOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIGNvbnN0IGNvbW1hbmQgPSBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY29tbWFuZCcpIHx8IGUudGFyZ2V0LnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKCdkYXRhLWNvbW1hbmQnKTtcbiAgICAgICAgaWYgKCFjb21tYW5kKSByZXR1cm47XG5cbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIGlmICgvdXBkYXRlLy50ZXN0KGNvbW1hbmQpKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQubWF0aC5mb2N1c0VsZW1lbnQudmFsdWUgPSB0aGlzLnV0aWwuSFRNTERlY29kZXIodGhpcy5jb250ZXh0Lm1hdGguX21hdGhFeHAuZ2V0QXR0cmlidXRlKCdkYXRhLWV4cCcpKTtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5kaWFsb2cub3Blbi5jYWxsKHRoaXMsICdtYXRoJywgdHJ1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvKiogZGVsZXRlICovXG4gICAgICAgICAgICB0aGlzLnV0aWwucmVtb3ZlSXRlbSh0aGlzLmNvbnRleHQubWF0aC5fbWF0aEV4cCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQubWF0aC5fbWF0aEV4cCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLmZvY3VzKCk7XG5cbiAgICAgICAgICAgIC8vIGhpc3Rvcnkgc3RhY2tcbiAgICAgICAgICAgIHRoaXMuaGlzdG9yeS5wdXNoKGZhbHNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29udHJvbGxlcnNPZmYoKTtcbiAgICB9LFxuXG4gICAgaW5pdDogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb250ZXh0TWF0aCA9IHRoaXMuY29udGV4dC5tYXRoO1xuICAgICAgICBjb250ZXh0TWF0aC5tYXRoQ29udHJvbGxlci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICBjb250ZXh0TWF0aC5fbWF0aEV4cCA9IG51bGw7XG4gICAgICAgIGNvbnRleHRNYXRoLmZvY3VzRWxlbWVudC52YWx1ZSA9ICcnO1xuICAgICAgICBjb250ZXh0TWF0aC5wcmV2aWV3RWxlbWVudC5pbm5lckhUTUwgPSAnJztcbiAgICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyBjb21tYW5kXG5pbXBvcnQgYmxvY2txdW90ZSBmcm9tICcuL2NvbW1hbmQvYmxvY2txdW90ZSc7XG5cbi8vIHN1Ym1lbnVcbmltcG9ydCBhbGlnbiBmcm9tICcuL3N1Ym1lbnUvYWxpZ24nO1xuaW1wb3J0IGZvbnQgZnJvbSAnLi9zdWJtZW51L2ZvbnQnO1xuaW1wb3J0IGZvbnRTaXplIGZyb20gJy4vc3VibWVudS9mb250U2l6ZSc7XG5pbXBvcnQgZm9udENvbG9yIGZyb20gJy4vc3VibWVudS9mb250Q29sb3InO1xuaW1wb3J0IGhpbGl0ZUNvbG9yIGZyb20gJy4vc3VibWVudS9oaWxpdGVDb2xvcic7XG5pbXBvcnQgaG9yaXpvbnRhbFJ1bGUgZnJvbSAnLi9zdWJtZW51L2hvcml6b250YWxSdWxlJztcbmltcG9ydCBsaXN0IGZyb20gJy4vc3VibWVudS9saXN0JztcbmltcG9ydCB0YWJsZSBmcm9tICcuL3N1Ym1lbnUvdGFibGUnO1xuaW1wb3J0IGZvcm1hdEJsb2NrIGZyb20gJy4vc3VibWVudS9mb3JtYXRCbG9jayc7XG5pbXBvcnQgbGluZUhlaWdodCBmcm9tICcuL3N1Ym1lbnUvbGluZUhlaWdodCc7XG5pbXBvcnQgdGVtcGxhdGUgZnJvbSAnLi9zdWJtZW51L3RlbXBsYXRlJztcbmltcG9ydCBwYXJhZ3JhcGhTdHlsZSBmcm9tICcuL3N1Ym1lbnUvcGFyYWdyYXBoU3R5bGUnO1xuaW1wb3J0IHRleHRTdHlsZSBmcm9tICcuL3N1Ym1lbnUvdGV4dFN0eWxlJztcblxuLy8gZGlhbG9nXG5pbXBvcnQgbGluayBmcm9tICcuL2RpYWxvZy9saW5rJztcbmltcG9ydCBpbWFnZSBmcm9tICcuL2RpYWxvZy9pbWFnZSc7XG5pbXBvcnQgdmlkZW8gZnJvbSAnLi9kaWFsb2cvdmlkZW8nO1xuaW1wb3J0IGF1ZGlvIGZyb20gJy4vZGlhbG9nL2F1ZGlvJztcbmltcG9ydCBtYXRoIGZyb20gJy4vZGlhbG9nL21hdGgnO1xuXG4vLyBmaWxlIGJyb3dzZXJcbmltcG9ydCBpbWFnZUdhbGxlcnkgZnJvbSAnLi9maWxlQnJvd3Nlci9pbWFnZUdhbGxlcnknO1xuXG5leHBvcnQgeyBibG9ja3F1b3RlLCBhbGlnbiwgZm9udCwgZm9udFNpemUsIGZvbnRDb2xvciwgaGlsaXRlQ29sb3IsIGhvcml6b250YWxSdWxlLCBsaXN0LCB0YWJsZSwgZm9ybWF0QmxvY2ssIGxpbmVIZWlnaHQsIHRlbXBsYXRlLCBwYXJhZ3JhcGhTdHlsZSwgdGV4dFN0eWxlLCBsaW5rLCBpbWFnZSwgdmlkZW8sIGF1ZGlvLCBtYXRoLCBpbWFnZUdhbGxlcnkgfTtcbmV4cG9ydCBkZWZhdWx0IHsgYmxvY2txdW90ZSwgYWxpZ24sIGZvbnQsIGZvbnRTaXplLCBmb250Q29sb3IsIGhpbGl0ZUNvbG9yLCBob3Jpem9udGFsUnVsZSwgbGlzdCwgdGFibGUsIGZvcm1hdEJsb2NrLCBsaW5lSGVpZ2h0LCB0ZW1wbGF0ZSwgcGFyYWdyYXBoU3R5bGUsIHRleHRTdHlsZSwgbGluaywgaW1hZ2UsIHZpZGVvLCBhdWRpbywgbWF0aCwgaW1hZ2VHYWxsZXJ5IH07XG4iLCIvKlxuICogd3lzaXd5ZyB3ZWIgZWRpdG9yXG4gKlxuICogc3VuZWRpdG9yLmpzXG4gKiBDb3B5cmlnaHQgMjAxNyBKaUhvbmcgTGVlLlxuICogTUlUIGxpY2Vuc2UuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIG5hbWU6ICdibG9ja3F1b3RlJyxcbiAgICBkaXNwbGF5OiAnY29tbWFuZCcsXG4gICAgYWRkOiBmdW5jdGlvbiAoY29yZSwgdGFyZ2V0RWxlbWVudCkge1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gY29yZS5jb250ZXh0O1xuICAgICAgICBjb250ZXh0LmJsb2NrcXVvdGUgPSB7XG4gICAgICAgICAgICB0YXJnZXRCdXR0b246IHRhcmdldEVsZW1lbnQsXG4gICAgICAgICAgICB0YWc6IGNvcmUudXRpbC5jcmVhdGVFbGVtZW50KCdCTE9DS1FVT1RFJylcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIGNvcmVcbiAgICAgKi9cbiAgICBhY3RpdmU6IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIGlmICghZWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUNsYXNzKHRoaXMuY29udGV4dC5ibG9ja3F1b3RlLnRhcmdldEJ1dHRvbiwgJ2FjdGl2ZScpO1xuICAgICAgICB9IGVsc2UgaWYgKC9ibG9ja3F1b3RlL2kudGVzdChlbGVtZW50Lm5vZGVOYW1lKSkge1xuICAgICAgICAgICAgdGhpcy51dGlsLmFkZENsYXNzKHRoaXMuY29udGV4dC5ibG9ja3F1b3RlLnRhcmdldEJ1dHRvbiwgJ2FjdGl2ZScpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQE92ZXJyaWRlIGNvcmVcbiAgICAgKi9cbiAgICBhY3Rpb246IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY3VycmVudEJsb2NrcXVvdGUgPSB0aGlzLnV0aWwuZ2V0UGFyZW50RWxlbWVudCh0aGlzLmdldFNlbGVjdGlvbk5vZGUoKSwgJ2Jsb2NrcXVvdGUnKTtcblxuICAgICAgICBpZiAoY3VycmVudEJsb2NrcXVvdGUpIHtcbiAgICAgICAgICAgIHRoaXMuZGV0YWNoUmFuZ2VGb3JtYXRFbGVtZW50KGN1cnJlbnRCbG9ja3F1b3RlLCBudWxsLCBudWxsLCBmYWxzZSwgZmFsc2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hcHBseVJhbmdlRm9ybWF0RWxlbWVudCh0aGlzLmNvbnRleHQuYmxvY2txdW90ZS50YWcuY2xvbmVOb2RlKGZhbHNlKSk7XG4gICAgICAgIH1cbiAgICB9XG59OyIsIi8qXG4gKiB3eXNpd3lnIHdlYiBlZGl0b3JcbiAqXG4gKiBzdW5lZGl0b3IuanNcbiAqIENvcHlyaWdodCAyMDE3IEppSG9uZyBMZWUuXG4gKiBNSVQgbGljZW5zZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gICAgbmFtZTogJ2FsaWduJyxcbiAgICBkaXNwbGF5OiAnc3VibWVudScsXG4gICAgYWRkOiBmdW5jdGlvbiAoY29yZSwgdGFyZ2V0RWxlbWVudCkge1xuICAgICAgICBjb25zdCBpY29ucyA9IGNvcmUuaWNvbnM7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBjb3JlLmNvbnRleHQ7XG4gICAgICAgIGNvbnRleHQuYWxpZ24gPSB7XG4gICAgICAgICAgICB0YXJnZXRCdXR0b246IHRhcmdldEVsZW1lbnQsXG4gICAgICAgICAgICBfYWxpZ25MaXN0OiBudWxsLFxuICAgICAgICAgICAgY3VycmVudEFsaWduOiAnJyxcbiAgICAgICAgICAgIGRlZmF1bHREaXI6IGNvbnRleHQub3B0aW9ucy5ydGwgPyAncmlnaHQnIDogJ2xlZnQnLCBcbiAgICAgICAgICAgIGljb25zOiB7XG4gICAgICAgICAgICAgICAganVzdGlmeTogaWNvbnMuYWxpZ25fanVzdGlmeSxcbiAgICAgICAgICAgICAgICBsZWZ0OiBpY29ucy5hbGlnbl9sZWZ0LFxuICAgICAgICAgICAgICAgIHJpZ2h0OiBpY29ucy5hbGlnbl9yaWdodCxcbiAgICAgICAgICAgICAgICBjZW50ZXI6IGljb25zLmFsaWduX2NlbnRlclxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKiBzZXQgc3VibWVudSAqL1xuICAgICAgICBsZXQgbGlzdERpdiA9IHRoaXMuc2V0U3VibWVudS5jYWxsKGNvcmUpO1xuICAgICAgICBsZXQgbGlzdFVsID0gbGlzdERpdi5xdWVyeVNlbGVjdG9yKCd1bCcpO1xuXG4gICAgICAgIC8qKiBhZGQgZXZlbnQgbGlzdGVuZXJzICovXG4gICAgICAgIGxpc3RVbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMucGlja3VwLmJpbmQoY29yZSkpO1xuICAgICAgICBjb250ZXh0LmFsaWduLl9hbGlnbkxpc3QgPSBsaXN0VWwucXVlcnlTZWxlY3RvckFsbCgnbGkgYnV0dG9uJyk7XG5cbiAgICAgICAgLyoqIGFwcGVuZCB0YXJnZXQgYnV0dG9uIG1lbnUgKi9cbiAgICAgICAgY29yZS5pbml0TWVudVRhcmdldCh0aGlzLm5hbWUsIHRhcmdldEVsZW1lbnQsIGxpc3REaXYpO1xuXG4gICAgICAgIC8qKiBlbXB0eSBtZW1vcnkgKi9cbiAgICAgICAgbGlzdERpdiA9IG51bGwsIGxpc3RVbCA9IG51bGw7XG4gICAgfSxcblxuICAgIHNldFN1Ym1lbnU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgbGFuZyA9IHRoaXMubGFuZztcbiAgICAgICAgY29uc3QgaWNvbnMgPSB0aGlzLmljb25zO1xuICAgICAgICBjb25zdCBsaXN0RGl2ID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xuICAgICAgICBjb25zdCBsZWZ0RGlyID0gdGhpcy5jb250ZXh0LmFsaWduLmRlZmF1bHREaXIgPT09ICdsZWZ0JztcblxuICAgICAgICBjb25zdCBsZWZ0TWVudSA9ICc8bGk+JyArXG4gICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzZS1idG4tbGlzdCBzZS1idG4tYWxpZ25cIiBkYXRhLWNvbW1hbmQ9XCJqdXN0aWZ5bGVmdFwiIGRhdGEtdmFsdWU9XCJsZWZ0XCIgdGl0bGU9XCInICsgbGFuZy50b29sYmFyLmFsaWduTGVmdCArICdcIj4nICtcbiAgICAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJzZS1saXN0LWljb25cIj4nICsgaWNvbnMuYWxpZ25fbGVmdCArICc8L3NwYW4+JyArIGxhbmcudG9vbGJhci5hbGlnbkxlZnQgK1xuICAgICAgICAgICAgJzwvYnV0dG9uPicgK1xuICAgICAgICAnPC9saT4nO1xuXG4gICAgICAgIGNvbnN0IHJpZ2h0TWVudSA9ICc8bGk+JyArXG4gICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzZS1idG4tbGlzdCBzZS1idG4tYWxpZ25cIiBkYXRhLWNvbW1hbmQ9XCJqdXN0aWZ5cmlnaHRcIiBkYXRhLXZhbHVlPVwicmlnaHRcIiB0aXRsZT1cIicgKyBsYW5nLnRvb2xiYXIuYWxpZ25SaWdodCArICdcIj4nICtcbiAgICAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJzZS1saXN0LWljb25cIj4nICsgaWNvbnMuYWxpZ25fcmlnaHQgKyc8L3NwYW4+JyArIGxhbmcudG9vbGJhci5hbGlnblJpZ2h0ICtcbiAgICAgICAgICAgICc8L2J1dHRvbj4nICtcbiAgICAgICAgJzwvbGk+JztcblxuICAgICAgICBsaXN0RGl2LmNsYXNzTmFtZSA9ICdzZS1zdWJtZW51IHNlLWxpc3QtbGF5ZXIgc2UtbGlzdC1hbGlnbic7XG4gICAgICAgIGxpc3REaXYuaW5uZXJIVE1MID0gJycgK1xuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1saXN0LWlubmVyXCI+JyArXG4gICAgICAgICAgICAgICAgJzx1bCBjbGFzcz1cInNlLWxpc3QtYmFzaWNcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgKGxlZnREaXIgPyBsZWZ0TWVudSA6IHJpZ2h0TWVudSkgK1xuICAgICAgICAgICAgICAgICAgICAnPGxpPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2UtYnRuLWxpc3Qgc2UtYnRuLWFsaWduXCIgZGF0YS1jb21tYW5kPVwianVzdGlmeWNlbnRlclwiIGRhdGEtdmFsdWU9XCJjZW50ZXJcIiB0aXRsZT1cIicgKyBsYW5nLnRvb2xiYXIuYWxpZ25DZW50ZXIgKyAnXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtbGlzdC1pY29uXCI+JyArIGljb25zLmFsaWduX2NlbnRlciArICc8L3NwYW4+JyArIGxhbmcudG9vbGJhci5hbGlnbkNlbnRlciArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICc8L2xpPicgK1xuICAgICAgICAgICAgICAgICAgICAobGVmdERpcj8gcmlnaHRNZW51IDogbGVmdE1lbnUpICtcbiAgICAgICAgICAgICAgICAgICAgJzxsaT4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNlLWJ0bi1saXN0IHNlLWJ0bi1hbGlnblwiIGRhdGEtY29tbWFuZD1cImp1c3RpZnlmdWxsXCIgZGF0YS12YWx1ZT1cImp1c3RpZnlcIiB0aXRsZT1cIicgKyBsYW5nLnRvb2xiYXIuYWxpZ25KdXN0aWZ5ICsgJ1wiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLWxpc3QtaWNvblwiPicgKyBpY29ucy5hbGlnbl9qdXN0aWZ5ICsgJzwvc3Bhbj4nICsgbGFuZy50b29sYmFyLmFsaWduSnVzdGlmeSArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICc8L2xpPicgK1xuICAgICAgICAgICAgICAgICc8L3VsPicgK1xuICAgICAgICAgICAgJzwvZGl2Pic7XG5cbiAgICAgICAgcmV0dXJuIGxpc3REaXY7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSBjb3JlXG4gICAgICovXG4gICAgYWN0aXZlOiBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICBjb25zdCBhbGlnbkNvbnRleHQgPSB0aGlzLmNvbnRleHQuYWxpZ247XG4gICAgICAgIGNvbnN0IHRhcmdldEJ1dHRvbiA9IGFsaWduQ29udGV4dC50YXJnZXRCdXR0b247XG4gICAgICAgIGNvbnN0IHRhcmdldCA9IHRhcmdldEJ1dHRvbi5maXJzdEVsZW1lbnRDaGlsZDtcblxuICAgICAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMudXRpbC5jaGFuZ2VFbGVtZW50KHRhcmdldCwgYWxpZ25Db250ZXh0Lmljb25zW2FsaWduQ29udGV4dC5kZWZhdWx0RGlyXSk7XG4gICAgICAgICAgICB0YXJnZXRCdXR0b24ucmVtb3ZlQXR0cmlidXRlKCdkYXRhLWZvY3VzJyk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy51dGlsLmlzRm9ybWF0RWxlbWVudChlbGVtZW50KSkge1xuICAgICAgICAgICAgY29uc3QgdGV4dEFsaWduID0gZWxlbWVudC5zdHlsZS50ZXh0QWxpZ247XG4gICAgICAgICAgICBpZiAodGV4dEFsaWduKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51dGlsLmNoYW5nZUVsZW1lbnQodGFyZ2V0LCBhbGlnbkNvbnRleHQuaWNvbnNbdGV4dEFsaWduXSk7XG4gICAgICAgICAgICAgICAgdGFyZ2V0QnV0dG9uLnNldEF0dHJpYnV0ZSgnZGF0YS1mb2N1cycsIHRleHRBbGlnbik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSBzdWJtZW51XG4gICAgICovXG4gICAgb246IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgYWxpZ25Db250ZXh0ID0gdGhpcy5jb250ZXh0LmFsaWduO1xuICAgICAgICBjb25zdCBhbGlnbkxpc3QgPSBhbGlnbkNvbnRleHQuX2FsaWduTGlzdDtcbiAgICAgICAgY29uc3QgY3VycmVudEFsaWduID0gYWxpZ25Db250ZXh0LnRhcmdldEJ1dHRvbi5nZXRBdHRyaWJ1dGUoJ2RhdGEtZm9jdXMnKSB8fCBhbGlnbkNvbnRleHQuZGVmYXVsdERpcjtcblxuICAgICAgICBpZiAoY3VycmVudEFsaWduICE9PSBhbGlnbkNvbnRleHQuY3VycmVudEFsaWduKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gYWxpZ25MaXN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRBbGlnbiA9PT0gYWxpZ25MaXN0W2ldLmdldEF0dHJpYnV0ZSgnZGF0YS12YWx1ZScpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbC5hZGRDbGFzcyhhbGlnbkxpc3RbaV0sICdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnV0aWwucmVtb3ZlQ2xhc3MoYWxpZ25MaXN0W2ldLCAnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBhbGlnbkNvbnRleHQuY3VycmVudEFsaWduID0gY3VycmVudEFsaWduO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHBpY2t1cDogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIGxldCB0YXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgbGV0IHZhbHVlID0gbnVsbDtcblxuICAgICAgICB3aGlsZSAoIXZhbHVlICYmICEvVUwvaS50ZXN0KHRhcmdldC50YWdOYW1lKSkge1xuICAgICAgICAgICAgdmFsdWUgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJyk7XG4gICAgICAgICAgICB0YXJnZXQgPSB0YXJnZXQucGFyZW50Tm9kZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdmFsdWUpIHJldHVybjtcblxuICAgICAgICBjb25zdCBkZWZhdWx0RGlyID0gdGhpcy5jb250ZXh0LmFsaWduLmRlZmF1bHREaXI7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRm9ybXN0cyA9IHRoaXMuZ2V0U2VsZWN0ZWRFbGVtZW50cygpO1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gc2VsZWN0ZWRGb3Jtc3RzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLnV0aWwuc2V0U3R5bGUoc2VsZWN0ZWRGb3Jtc3RzW2ldLCAndGV4dEFsaWduJywgKHZhbHVlID09PSBkZWZhdWx0RGlyID8gJycgOiB2YWx1ZSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5lZmZlY3ROb2RlID0gbnVsbDtcbiAgICAgICAgdGhpcy5zdWJtZW51T2ZmKCk7XG4gICAgICAgIHRoaXMuZm9jdXMoKTtcbiAgICAgICAgXG4gICAgICAgIC8vIGhpc3Rvcnkgc3RhY2tcbiAgICAgICAgdGhpcy5oaXN0b3J5LnB1c2goZmFsc2UpO1xuICAgIH1cbn07XG4iLCIvKlxuICogd3lzaXd5ZyB3ZWIgZWRpdG9yXG4gKlxuICogc3VuZWRpdG9yLmpzXG4gKiBDb3B5cmlnaHQgMjAxNyBKaUhvbmcgTGVlLlxuICogTUlUIGxpY2Vuc2UuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIG5hbWU6ICdmb250JyxcbiAgICBkaXNwbGF5OiAnc3VibWVudScsXG4gICAgYWRkOiBmdW5jdGlvbiAoY29yZSwgdGFyZ2V0RWxlbWVudCkge1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gY29yZS5jb250ZXh0O1xuICAgICAgICBjb250ZXh0LmZvbnQgPSB7XG4gICAgICAgICAgICB0YXJnZXRUZXh0OiB0YXJnZXRFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy50eHQnKSxcbiAgICAgICAgICAgIHRhcmdldFRvb2x0aXA6IHRhcmdldEVsZW1lbnQucGFyZW50Tm9kZS5xdWVyeVNlbGVjdG9yKCcuc2UtdG9vbHRpcC10ZXh0JyksXG4gICAgICAgICAgICBfZm9udExpc3Q6IG51bGwsXG4gICAgICAgICAgICBjdXJyZW50Rm9udDogJydcbiAgICAgICAgfTtcblxuICAgICAgICAvKiogc2V0IHN1Ym1lbnUgKi9cbiAgICAgICAgbGV0IGxpc3REaXYgPSB0aGlzLnNldFN1Ym1lbnUuY2FsbChjb3JlKTtcblxuICAgICAgICAvKiogYWRkIGV2ZW50IGxpc3RlbmVycyAqL1xuICAgICAgICBsaXN0RGl2LnF1ZXJ5U2VsZWN0b3IoJy5zZS1saXN0LWlubmVyJykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLnBpY2t1cC5iaW5kKGNvcmUpKTtcblxuICAgICAgICBjb250ZXh0LmZvbnQuX2ZvbnRMaXN0ID0gbGlzdERpdi5xdWVyeVNlbGVjdG9yQWxsKCd1bCBsaSBidXR0b24nKTtcblxuICAgICAgICAvKiogYXBwZW5kIHRhcmdldCBidXR0b24gbWVudSAqL1xuICAgICAgICBjb3JlLmluaXRNZW51VGFyZ2V0KHRoaXMubmFtZSwgdGFyZ2V0RWxlbWVudCwgbGlzdERpdik7XG5cbiAgICAgICAgLyoqIGVtcHR5IG1lbW9yeSAqL1xuICAgICAgICBsaXN0RGl2ID0gbnVsbDtcbiAgICB9LFxuXG4gICAgc2V0U3VibWVudTogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBvcHRpb24gPSB0aGlzLmNvbnRleHQub3B0aW9uO1xuICAgICAgICBjb25zdCBsYW5nID0gdGhpcy5sYW5nO1xuICAgICAgICBjb25zdCBsaXN0RGl2ID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xuXG4gICAgICAgIGxpc3REaXYuY2xhc3NOYW1lID0gJ3NlLXN1Ym1lbnUgc2UtbGlzdC1sYXllciBzZS1saXN0LWZvbnQtZmFtaWx5JztcblxuICAgICAgICBsZXQgZm9udCwgdGV4dCwgaSwgbGVuO1xuICAgICAgICBsZXQgZm9udExpc3QgPSAhb3B0aW9uLmZvbnQgP1xuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICdBcmlhbCcsXG4gICAgICAgICAgICAgICAgJ0NvbWljIFNhbnMgTVMnLFxuICAgICAgICAgICAgICAgICdDb3VyaWVyIE5ldycsXG4gICAgICAgICAgICAgICAgJ0ltcGFjdCcsXG4gICAgICAgICAgICAgICAgJ0dlb3JnaWEnLFxuICAgICAgICAgICAgICAgICd0YWhvbWEnLFxuICAgICAgICAgICAgICAgICdUcmVidWNoZXQgTVMnLFxuICAgICAgICAgICAgICAgICdWZXJkYW5hJ1xuICAgICAgICAgICAgXSA6IG9wdGlvbi5mb250O1xuXG4gICAgICAgIGxldCBsaXN0ID0gJzxkaXYgY2xhc3M9XCJzZS1saXN0LWlubmVyXCI+JyArXG4gICAgICAgICAgICAgICAgJzx1bCBjbGFzcz1cInNlLWxpc3QtYmFzaWNcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxsaT48YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImRlZmF1bHRfdmFsdWUgc2UtYnRuLWxpc3RcIiB0aXRsZT1cIicgKyBsYW5nLnRvb2xiYXIuZGVmYXVsdCArICdcIj4oJyArIGxhbmcudG9vbGJhci5kZWZhdWx0ICsgJyk8L2J1dHRvbj48L2xpPic7XG4gICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGZvbnRMaXN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBmb250ID0gZm9udExpc3RbaV07XG4gICAgICAgICAgICB0ZXh0ID0gZm9udC5zcGxpdCgnLCcpWzBdO1xuICAgICAgICAgICAgbGlzdCArPSAnPGxpPjxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2UtYnRuLWxpc3RcIiBkYXRhLXZhbHVlPVwiJyArIGZvbnQgKyAnXCIgZGF0YS10eHQ9XCInICsgdGV4dCArICdcIiB0aXRsZT1cIicgKyB0ZXh0ICsgJ1wiIHN0eWxlPVwiZm9udC1mYW1pbHk6JyArIGZvbnQgKyAnO1wiPicgKyB0ZXh0ICsgJzwvYnV0dG9uPjwvbGk+JztcbiAgICAgICAgfVxuICAgICAgICBsaXN0ICs9ICc8L3VsPjwvZGl2Pic7XG4gICAgICAgIGxpc3REaXYuaW5uZXJIVE1MID0gbGlzdDtcblxuICAgICAgICByZXR1cm4gbGlzdERpdjtcbiAgICB9LFxuXG4gICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSBjb3JlXG4gICAgICovXG4gICAgYWN0aXZlOiBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmNvbnRleHQuZm9udC50YXJnZXRUZXh0O1xuICAgICAgICBjb25zdCB0b29sdGlwID0gdGhpcy5jb250ZXh0LmZvbnQudGFyZ2V0VG9vbHRpcDtcblxuICAgICAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IGZvbnQgPSB0aGlzLmxhbmcudG9vbGJhci5mb250O1xuICAgICAgICAgICAgdGhpcy51dGlsLmNoYW5nZVR4dCh0YXJnZXQsIGZvbnQpO1xuICAgICAgICAgICAgdGhpcy51dGlsLmNoYW5nZVR4dCh0b29sdGlwLCBmb250KTtcbiAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50LnN0eWxlICYmIGVsZW1lbnQuc3R5bGUuZm9udEZhbWlseS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RGb250ID0gZWxlbWVudC5zdHlsZS5mb250RmFtaWx5LnJlcGxhY2UoL1tcIiddL2csJycpO1xuICAgICAgICAgICAgdGhpcy51dGlsLmNoYW5nZVR4dCh0YXJnZXQsIHNlbGVjdEZvbnQpO1xuICAgICAgICAgICAgdGhpcy51dGlsLmNoYW5nZVR4dCh0b29sdGlwLCBzZWxlY3RGb250KTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG5cbiAgICAgLyoqXG4gICAgICogQE92ZXJyaWRlIHN1Ym1lbnVcbiAgICAgKi9cbiAgICBvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBmb250Q29udGV4dCA9IHRoaXMuY29udGV4dC5mb250O1xuICAgICAgICBjb25zdCBmb250TGlzdCA9IGZvbnRDb250ZXh0Ll9mb250TGlzdDtcbiAgICAgICAgY29uc3QgY3VycmVudEZvbnQgPSBmb250Q29udGV4dC50YXJnZXRUZXh0LnRleHRDb250ZW50O1xuXG4gICAgICAgIGlmIChjdXJyZW50Rm9udCAhPT0gZm9udENvbnRleHQuY3VycmVudEZvbnQpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBmb250TGlzdC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50Rm9udCA9PT0gZm9udExpc3RbaV0uZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51dGlsLmFkZENsYXNzKGZvbnRMaXN0W2ldLCAnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUNsYXNzKGZvbnRMaXN0W2ldLCAnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb250Q29udGV4dC5jdXJyZW50Rm9udCA9IGN1cnJlbnRGb250O1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHBpY2t1cDogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgaWYgKCEvXkJVVFRPTiQvaS50ZXN0KGUudGFyZ2V0LnRhZ05hbWUpKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIGNvbnN0IHZhbHVlID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJyk7XG5cbiAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCBuZXdOb2RlID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ1NQQU4nKTtcbiAgICAgICAgICAgIG5ld05vZGUuc3R5bGUuZm9udEZhbWlseSA9IHZhbHVlO1xuICAgICAgICAgICAgdGhpcy5ub2RlQ2hhbmdlKG5ld05vZGUsIFsnZm9udC1mYW1pbHknXSwgbnVsbCwgbnVsbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm5vZGVDaGFuZ2UobnVsbCwgWydmb250LWZhbWlseSddLCBbJ3NwYW4nXSwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIHRoaXMuc3VibWVudU9mZigpO1xuICAgIH1cbn07XG4iLCIvKlxuICogd3lzaXd5ZyB3ZWIgZWRpdG9yXG4gKlxuICogc3VuZWRpdG9yLmpzXG4gKiBDb3B5cmlnaHQgMjAxNyBKaUhvbmcgTGVlLlxuICogTUlUIGxpY2Vuc2UuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIG5hbWU6ICdmb250U2l6ZScsXG4gICAgZGlzcGxheTogJ3N1Ym1lbnUnLFxuICAgIGFkZDogZnVuY3Rpb24gKGNvcmUsIHRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IGNvcmUuY29udGV4dDtcbiAgICAgICAgY29udGV4dC5mb250U2l6ZSA9IHtcbiAgICAgICAgICAgIHRhcmdldFRleHQ6IHRhcmdldEVsZW1lbnQucXVlcnlTZWxlY3RvcignLnR4dCcpLFxuICAgICAgICAgICAgX3NpemVMaXN0OiBudWxsLFxuICAgICAgICAgICAgY3VycmVudFNpemU6ICcnXG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqIHNldCBzdWJtZW51ICovXG4gICAgICAgIGxldCBsaXN0RGl2ID0gdGhpcy5zZXRTdWJtZW51LmNhbGwoY29yZSk7XG4gICAgICAgIGxldCBsaXN0VWwgPSBsaXN0RGl2LnF1ZXJ5U2VsZWN0b3IoJ3VsJyk7XG5cbiAgICAgICAgLyoqIGFkZCBldmVudCBsaXN0ZW5lcnMgKi9cbiAgICAgICAgbGlzdFVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5waWNrdXAuYmluZChjb3JlKSk7XG4gICAgICAgIGNvbnRleHQuZm9udFNpemUuX3NpemVMaXN0ID0gbGlzdFVsLnF1ZXJ5U2VsZWN0b3JBbGwoJ2xpIGJ1dHRvbicpO1xuXG4gICAgICAgIC8qKiBhcHBlbmQgdGFyZ2V0IGJ1dHRvbiBtZW51ICovXG4gICAgICAgIGNvcmUuaW5pdE1lbnVUYXJnZXQodGhpcy5uYW1lLCB0YXJnZXRFbGVtZW50LCBsaXN0RGl2KTtcblxuICAgICAgICAvKiogZW1wdHkgbWVtb3J5ICovXG4gICAgICAgIGxpc3REaXYgPSBudWxsLCBsaXN0VWwgPSBudWxsO1xuICAgIH0sXG5cbiAgICBzZXRTdWJtZW51OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMuY29udGV4dC5vcHRpb247XG4gICAgICAgIGNvbnN0IGxhbmcgPSB0aGlzLmxhbmc7XG4gICAgICAgIGNvbnN0IGxpc3REaXYgPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XG5cbiAgICAgICAgbGlzdERpdi5jbGFzc05hbWUgPSAnc2Utc3VibWVudSBzZS1saXN0LWxheWVyIHNlLWxpc3QtZm9udC1zaXplJztcblxuICAgICAgICBjb25zdCBzaXplTGlzdCA9ICFvcHRpb24uZm9udFNpemUgPyBbOCwgOSwgMTAsIDExLCAxMiwgMTQsIDE2LCAxOCwgMjAsIDIyLCAyNCwgMjYsIDI4LCAzNiwgNDgsIDcyXSA6IG9wdGlvbi5mb250U2l6ZTtcblxuICAgICAgICBsZXQgbGlzdCA9ICc8ZGl2IGNsYXNzPVwic2UtbGlzdC1pbm5lclwiPicgK1xuICAgICAgICAgICAgICAgICc8dWwgY2xhc3M9XCJzZS1saXN0LWJhc2ljXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICc8bGk+PGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJkZWZhdWx0X3ZhbHVlIHNlLWJ0bi1saXN0XCIgdGl0bGU9XCInICsgbGFuZy50b29sYmFyLmRlZmF1bHQgKyAnXCI+KCcgKyBsYW5nLnRvb2xiYXIuZGVmYXVsdCArICcpPC9idXR0b24+PC9saT4nO1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgdW5pdCA9IG9wdGlvbi5mb250U2l6ZVVuaXQsIGxlbiA9IHNpemVMaXN0Lmxlbmd0aCwgc2l6ZTsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBzaXplID0gc2l6ZUxpc3RbaV07XG4gICAgICAgICAgICBsaXN0ICs9ICc8bGk+PGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzZS1idG4tbGlzdFwiIGRhdGEtdmFsdWU9XCInICsgc2l6ZSArIHVuaXQgKyAnXCIgdGl0bGU9XCInICsgc2l6ZSArIHVuaXQgKyAnXCIgc3R5bGU9XCJmb250LXNpemU6JyArIHNpemUgKyB1bml0ICsgJztcIj4nICsgc2l6ZSArICc8L2J1dHRvbj48L2xpPic7XG4gICAgICAgIH1cbiAgICAgICAgbGlzdCArPSAnPC91bD48L2Rpdj4nO1xuXG4gICAgICAgIGxpc3REaXYuaW5uZXJIVE1MID0gbGlzdDtcblxuICAgICAgICByZXR1cm4gbGlzdERpdjtcbiAgICB9LFxuXG4gICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSBjb3JlXG4gICAgICovXG4gICAgYWN0aXZlOiBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMudXRpbC5jaGFuZ2VUeHQodGhpcy5jb250ZXh0LmZvbnRTaXplLnRhcmdldFRleHQsIHRoaXMubGFuZy50b29sYmFyLmZvbnRTaXplKTtcbiAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50LnN0eWxlICYmIGVsZW1lbnQuc3R5bGUuZm9udFNpemUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy51dGlsLmNoYW5nZVR4dCh0aGlzLmNvbnRleHQuZm9udFNpemUudGFyZ2V0VGV4dCwgZWxlbWVudC5zdHlsZS5mb250U2l6ZSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9LFxuXG4gICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSBzdWJtZW51XG4gICAgICovXG4gICAgb246IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZm9udFNpemVDb250ZXh0ID0gdGhpcy5jb250ZXh0LmZvbnRTaXplO1xuICAgICAgICBjb25zdCBzaXplTGlzdCA9IGZvbnRTaXplQ29udGV4dC5fc2l6ZUxpc3Q7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRTaXplID0gZm9udFNpemVDb250ZXh0LnRhcmdldFRleHQudGV4dENvbnRlbnQ7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRTaXplICE9PSBmb250U2l6ZUNvbnRleHQuY3VycmVudFNpemUpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBzaXplTGlzdC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50U2l6ZSA9PT0gc2l6ZUxpc3RbaV0uZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51dGlsLmFkZENsYXNzKHNpemVMaXN0W2ldLCAnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUNsYXNzKHNpemVMaXN0W2ldLCAnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb250U2l6ZUNvbnRleHQuY3VycmVudFNpemUgPSBjdXJyZW50U2l6ZTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBwaWNrdXA6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGlmICghL15CVVRUT04kL2kudGVzdChlLnRhcmdldC50YWdOYW1lKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIGNvbnN0IHZhbHVlID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJyk7XG5cbiAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCBuZXdOb2RlID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ1NQQU4nKTtcbiAgICAgICAgICAgIG5ld05vZGUuc3R5bGUuZm9udFNpemUgPSB2YWx1ZTtcbiAgICAgICAgICAgIHRoaXMubm9kZUNoYW5nZShuZXdOb2RlLCBbJ2ZvbnQtc2l6ZSddLCBudWxsLCBudWxsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubm9kZUNoYW5nZShudWxsLCBbJ2ZvbnQtc2l6ZSddLCBbJ3NwYW4nXSwgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN1Ym1lbnVPZmYoKTtcbiAgICB9XG59O1xuIiwiLypcbiAqIHd5c2l3eWcgd2ViIGVkaXRvclxuICpcbiAqIHN1bmVkaXRvci5qc1xuICogQ29weXJpZ2h0IDIwMTcgSmlIb25nIExlZS5cbiAqIE1JVCBsaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICBuYW1lOiAnaG9yaXpvbnRhbFJ1bGUnLFxuICAgIGRpc3BsYXk6ICdzdWJtZW51JyxcbiAgICBhZGQ6IGZ1bmN0aW9uIChjb3JlLCB0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgIC8qKiBzZXQgc3VibWVudSAqL1xuICAgICAgICBsZXQgbGlzdERpdiA9IHRoaXMuc2V0U3VibWVudS5jYWxsKGNvcmUpO1xuXG4gICAgICAgIC8qKiBhZGQgZXZlbnQgbGlzdGVuZXJzICovXG4gICAgICAgIGxpc3REaXYucXVlcnlTZWxlY3RvcigndWwnKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuaG9yaXpvbnRhbFJ1bGVQaWNrLmJpbmQoY29yZSkpO1xuXG4gICAgICAgIC8qKiBhcHBlbmQgdGFyZ2V0IGJ1dHRvbiBtZW51ICovXG4gICAgICAgIGNvcmUuaW5pdE1lbnVUYXJnZXQodGhpcy5uYW1lLCB0YXJnZXRFbGVtZW50LCBsaXN0RGl2KTtcblxuICAgICAgICAvKiogZW1wdHkgbWVtb3J5ICovXG4gICAgICAgIGxpc3REaXYgPSBudWxsO1xuICAgIH0sXG5cbiAgICBzZXRTdWJtZW51OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGxhbmcgPSB0aGlzLmxhbmc7XG4gICAgICAgIGNvbnN0IGxpc3REaXYgPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XG5cbiAgICAgICAgbGlzdERpdi5jbGFzc05hbWUgPSAnc2Utc3VibWVudSBzZS1saXN0LWxheWVyIHNlLWxpc3QtbGluZSc7XG4gICAgICAgIGxpc3REaXYuaW5uZXJIVE1MID0gJycgK1xuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1saXN0LWlubmVyXCI+JyArXG4gICAgICAgICAgICAgICAgJzx1bCBjbGFzcz1cInNlLWxpc3QtYmFzaWNcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxsaT4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNlLWJ0bi1saXN0IGJ0bl9saW5lXCIgZGF0YS1jb21tYW5kPVwiaG9yaXpvbnRhbFJ1bGVcIiBkYXRhLXZhbHVlPVwic29saWRcIiB0aXRsZT1cIicgKyBsYW5nLnRvb2xiYXIuaHJfc29saWQgKyAnXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxociBzdHlsZT1cImJvcmRlci13aWR0aDogMXB4IDAgMDsgYm9yZGVyLXN0eWxlOiBzb2xpZCBub25lIG5vbmU7IGJvcmRlci1jb2xvcjogYmxhY2s7IGJvcmRlci1pbWFnZTogaW5pdGlhbDsgaGVpZ2h0OiAxcHg7XCIgLz4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzwvbGk+JyArXG4gICAgICAgICAgICAgICAgICAgICc8bGk+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzZS1idG4tbGlzdCBidG5fbGluZVwiIGRhdGEtY29tbWFuZD1cImhvcml6b250YWxSdWxlXCIgZGF0YS12YWx1ZT1cImRvdHRlZFwiIHRpdGxlPVwiJyArIGxhbmcudG9vbGJhci5ocl9kb3R0ZWQgKyAnXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxociBzdHlsZT1cImJvcmRlci13aWR0aDogMXB4IDAgMDsgYm9yZGVyLXN0eWxlOiBkb3R0ZWQgbm9uZSBub25lOyBib3JkZXItY29sb3I6IGJsYWNrOyBib3JkZXItaW1hZ2U6IGluaXRpYWw7IGhlaWdodDogMXB4O1wiIC8+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICc8L2xpPicgK1xuICAgICAgICAgICAgICAgICAgICAnPGxpPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2UtYnRuLWxpc3QgYnRuX2xpbmVcIiBkYXRhLWNvbW1hbmQ9XCJob3Jpem9udGFsUnVsZVwiIGRhdGEtdmFsdWU9XCJkYXNoZWRcIiB0aXRsZT1cIicgKyBsYW5nLnRvb2xiYXIuaHJfZGFzaGVkICsgJ1wiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8aHIgc3R5bGU9XCJib3JkZXItd2lkdGg6IDFweCAwIDA7IGJvcmRlci1zdHlsZTogZGFzaGVkIG5vbmUgbm9uZTsgYm9yZGVyLWNvbG9yOiBibGFjazsgYm9yZGVyLWltYWdlOiBpbml0aWFsOyBoZWlnaHQ6IDFweDtcIiAvPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzwvYnV0dG9uPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9saT4nICtcbiAgICAgICAgICAgICAgICAnPC91bD4nICtcbiAgICAgICAgICAgICc8L2Rpdj4nO1xuXG4gICAgICAgIHJldHVybiBsaXN0RGl2O1xuICAgIH0sXG5cbiAgICBhcHBlbmRIcjogZnVuY3Rpb24gKGNsYXNzTmFtZSkge1xuICAgICAgICBjb25zdCBvSHIgPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudCgnSFInKTtcbiAgICAgICAgb0hyLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcbiAgICAgICAgdGhpcy5mb2N1cygpO1xuICAgICAgICByZXR1cm4gdGhpcy5pbnNlcnRDb21wb25lbnQob0hyLCBmYWxzZSwgdHJ1ZSwgZmFsc2UpO1xuICAgIH0sXG5cbiAgICBob3Jpem9udGFsUnVsZVBpY2s6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICBsZXQgdGFyZ2V0ID0gZS50YXJnZXQ7XG4gICAgICAgIGxldCB2YWx1ZSA9IG51bGw7XG4gICAgICAgIFxuICAgICAgICB3aGlsZSAoIXZhbHVlICYmICEvVUwvaS50ZXN0KHRhcmdldC50YWdOYW1lKSkge1xuICAgICAgICAgICAgdmFsdWUgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJyk7XG4gICAgICAgICAgICB0YXJnZXQgPSB0YXJnZXQucGFyZW50Tm9kZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdmFsdWUpIHJldHVybjtcblxuICAgICAgICBjb25zdCBvTm9kZSA9IHRoaXMucGx1Z2lucy5ob3Jpem9udGFsUnVsZS5hcHBlbmRIci5jYWxsKHRoaXMsICdfX3NlX18nICsgdmFsdWUpO1xuICAgICAgICBpZiAob05vZGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0UmFuZ2Uob05vZGUsIDAsIG9Ob2RlLCAwKTtcbiAgICAgICAgICAgIHRoaXMuc3VibWVudU9mZigpO1xuICAgICAgICB9XG4gICAgfVxufTtcbiIsIi8qXG4gKiB3eXNpd3lnIHdlYiBlZGl0b3JcbiAqXG4gKiBzdW5lZGl0b3IuanNcbiAqIENvcHlyaWdodCAyMDE3IEppSG9uZyBMZWUuXG4gKiBNSVQgbGljZW5zZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gICAgbmFtZTogJ2xpc3QnLFxuICAgIGRpc3BsYXk6ICdzdWJtZW51JyxcbiAgICBhZGQ6IGZ1bmN0aW9uIChjb3JlLCB0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBjb3JlLmNvbnRleHQ7XG4gICAgICAgIGNvbnRleHQubGlzdCA9IHtcbiAgICAgICAgICAgIHRhcmdldEJ1dHRvbjogdGFyZ2V0RWxlbWVudCxcbiAgICAgICAgICAgIF9saXN0OiBudWxsLFxuICAgICAgICAgICAgY3VycmVudExpc3Q6ICcnLFxuICAgICAgICAgICAgaWNvbnM6IHtcbiAgICAgICAgICAgICAgICBidWxsZXRzOiBjb3JlLmljb25zLmxpc3RfYnVsbGV0cyxcbiAgICAgICAgICAgICAgICBudW1iZXI6IGNvcmUuaWNvbnMubGlzdF9udW1iZXJcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvKiogc2V0IHN1Ym1lbnUgKi9cbiAgICAgICAgbGV0IGxpc3REaXYgPSB0aGlzLnNldFN1Ym1lbnUuY2FsbChjb3JlKTtcbiAgICAgICAgbGV0IGxpc3RVbCA9IGxpc3REaXYucXVlcnlTZWxlY3RvcigndWwnKTtcblxuICAgICAgICAvKiogYWRkIGV2ZW50IGxpc3RlbmVycyAqL1xuICAgICAgICBsaXN0VWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLnBpY2t1cC5iaW5kKGNvcmUpKTtcbiAgICAgICAgY29udGV4dC5saXN0Ll9saXN0ID0gbGlzdFVsLnF1ZXJ5U2VsZWN0b3JBbGwoJ2xpIGJ1dHRvbicpO1xuXG4gICAgICAgIC8qKiBhcHBlbmQgdGFyZ2V0IGJ1dHRvbiBtZW51ICovXG4gICAgICAgIGNvcmUuaW5pdE1lbnVUYXJnZXQodGhpcy5uYW1lLCB0YXJnZXRFbGVtZW50LCBsaXN0RGl2KTtcblxuICAgICAgICAvKiogZW1wdHkgbWVtb3J5ICovXG4gICAgICAgIGxpc3REaXYgPSBudWxsLCBsaXN0VWwgPSBudWxsO1xuICAgIH0sXG5cbiAgICBzZXRTdWJtZW51OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGxhbmcgPSB0aGlzLmxhbmc7XG4gICAgICAgIGNvbnN0IGxpc3REaXYgPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XG5cbiAgICAgICAgbGlzdERpdi5jbGFzc05hbWUgPSAnc2Utc3VibWVudSBzZS1saXN0LWxheWVyJztcbiAgICAgICAgbGlzdERpdi5pbm5lckhUTUwgPSAnJyArXG4gICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWxpc3QtaW5uZXJcIj4nICtcbiAgICAgICAgICAgICAgICAnPHVsIGNsYXNzPVwic2UtbGlzdC1iYXNpY1wiPicgK1xuICAgICAgICAgICAgICAgICAgICAnPGxpPjxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2UtYnRuLWxpc3Qgc2UtdG9vbHRpcFwiIGRhdGEtY29tbWFuZD1cIk9MXCIgdGl0bGU9XCInICsgbGFuZy50b29sYmFyLm9yZGVyTGlzdCArICdcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWNvbnMubGlzdF9udW1iZXIgK1xuICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+PC9saT4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxsaT48YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNlLWJ0bi1saXN0IHNlLXRvb2x0aXBcIiBkYXRhLWNvbW1hbmQ9XCJVTFwiIHRpdGxlPVwiJyArIGxhbmcudG9vbGJhci51bm9yZGVyTGlzdCArICdcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWNvbnMubGlzdF9idWxsZXRzICtcbiAgICAgICAgICAgICAgICAgICAgJzwvYnV0dG9uPjwvbGk+JyArXG4gICAgICAgICAgICAgICAgJzwvdWw+JyArXG4gICAgICAgICAgICAnPC9kaXY+JztcblxuICAgICAgICByZXR1cm4gbGlzdERpdjtcbiAgICB9LFxuXG4gICAgIC8qKlxuICAgICAqIEBPdmVycmlkZSBjb3JlXG4gICAgICovXG4gICAgYWN0aXZlOiBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICBjb25zdCBidXR0b24gPSB0aGlzLmNvbnRleHQubGlzdC50YXJnZXRCdXR0b247XG4gICAgICAgIGNvbnN0IGljb24gPSBidXR0b24uZmlyc3RFbGVtZW50Q2hpbGQ7XG4gICAgICAgIGNvbnN0IHV0aWwgPSB0aGlzLnV0aWw7XG5cbiAgICAgICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICAgICAgICBidXR0b24ucmVtb3ZlQXR0cmlidXRlKCdkYXRhLWZvY3VzJyk7XG4gICAgICAgICAgICB1dGlsLmNoYW5nZUVsZW1lbnQoaWNvbiwgdGhpcy5jb250ZXh0Lmxpc3QuaWNvbnMubnVtYmVyKTtcbiAgICAgICAgICAgIHV0aWwucmVtb3ZlQ2xhc3MoYnV0dG9uLCAnYWN0aXZlJyk7XG4gICAgICAgIH0gZWxzZSBpZiAodXRpbC5pc0xpc3QoZWxlbWVudCkpIHtcbiAgICAgICAgICAgIGNvbnN0IG5vZGVOYW1lID0gZWxlbWVudC5ub2RlTmFtZTtcbiAgICAgICAgICAgIGJ1dHRvbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtZm9jdXMnLCBub2RlTmFtZSk7XG4gICAgICAgICAgICB1dGlsLmFkZENsYXNzKGJ1dHRvbiwgJ2FjdGl2ZScpO1xuICAgICAgICAgICAgaWYgKC9VTC9pLnRlc3Qobm9kZU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgdXRpbC5jaGFuZ2VFbGVtZW50KGljb24sIHRoaXMuY29udGV4dC5saXN0Lmljb25zLmJ1bGxldHMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB1dGlsLmNoYW5nZUVsZW1lbnQoaWNvbiwgdGhpcy5jb250ZXh0Lmxpc3QuaWNvbnMubnVtYmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSxcblxuICAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgc3VibWVudVxuICAgICAqL1xuICAgIG9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGxpc3RDb250ZXh0ID0gdGhpcy5jb250ZXh0Lmxpc3Q7XG4gICAgICAgIGNvbnN0IGxpc3QgPSBsaXN0Q29udGV4dC5fbGlzdDtcbiAgICAgICAgY29uc3QgY3VycmVudExpc3QgPSBsaXN0Q29udGV4dC50YXJnZXRCdXR0b24uZ2V0QXR0cmlidXRlKCdkYXRhLWZvY3VzJykgfHwgJyc7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRMaXN0ICE9PSBsaXN0Q29udGV4dC5jdXJyZW50TGlzdCkge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxpc3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudExpc3QgPT09IGxpc3RbaV0uZ2V0QXR0cmlidXRlKCdkYXRhLWNvbW1hbmQnKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnV0aWwuYWRkQ2xhc3MobGlzdFtpXSwgJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbC5yZW1vdmVDbGFzcyhsaXN0W2ldLCAnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsaXN0Q29udGV4dC5jdXJyZW50TGlzdCA9IGN1cnJlbnRMaXN0O1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGVkaXRMaXN0OiBmdW5jdGlvbiAoY29tbWFuZCwgc2VsZWN0ZWRDZWxscywgZGV0YWNoKSB7XG4gICAgICAgIGxldCByYW5nZSA9IHRoaXMuZ2V0UmFuZ2UoKTtcbiAgICAgICAgbGV0IHNlbGVjdGVkRm9ybWF0cyA9ICFzZWxlY3RlZENlbGxzID8gdGhpcy5nZXRTZWxlY3RlZEVsZW1lbnRzQW5kQ29tcG9uZW50cyhmYWxzZSkgOiBzZWxlY3RlZENlbGxzO1xuXG4gICAgICAgIGlmIChzZWxlY3RlZEZvcm1hdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBpZiAoc2VsZWN0ZWRDZWxscykgcmV0dXJuO1xuICAgICAgICAgICAgcmFuZ2UgPSB0aGlzLmdldFJhbmdlX2FkZExpbmUocmFuZ2UsIG51bGwpO1xuICAgICAgICAgICAgc2VsZWN0ZWRGb3JtYXRzID0gdGhpcy5nZXRTZWxlY3RlZEVsZW1lbnRzQW5kQ29tcG9uZW50cyhmYWxzZSk7XG4gICAgICAgICAgICBpZiAoc2VsZWN0ZWRGb3JtYXRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBjb25zdCB1dGlsID0gdGhpcy51dGlsO1xuICAgICAgICB1dGlsLnNvcnRCeURlcHRoKHNlbGVjdGVkRm9ybWF0cywgdHJ1ZSk7XG5cbiAgICAgICAgLy8gbWVyZ2VcbiAgICAgICAgbGV0IGZpcnN0U2VsID0gc2VsZWN0ZWRGb3JtYXRzWzBdO1xuICAgICAgICBsZXQgbGFzdFNlbCA9IHNlbGVjdGVkRm9ybWF0c1tzZWxlY3RlZEZvcm1hdHMubGVuZ3RoIC0gMV07XG4gICAgICAgIGxldCB0b3BFbCA9ICh1dGlsLmlzTGlzdENlbGwoZmlyc3RTZWwpIHx8IHV0aWwuaXNDb21wb25lbnQoZmlyc3RTZWwpKSAmJiAhZmlyc3RTZWwucHJldmlvdXNFbGVtZW50U2libGluZyA/IGZpcnN0U2VsLnBhcmVudE5vZGUucHJldmlvdXNFbGVtZW50U2libGluZyA6IGZpcnN0U2VsLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7XG4gICAgICAgIGxldCBib3R0b21FbCA9ICh1dGlsLmlzTGlzdENlbGwobGFzdFNlbCkgfHwgdXRpbC5pc0NvbXBvbmVudChsYXN0U2VsKSkgJiYgIWxhc3RTZWwubmV4dEVsZW1lbnRTaWJsaW5nID8gbGFzdFNlbC5wYXJlbnROb2RlLm5leHRFbGVtZW50U2libGluZyA6IGxhc3RTZWwubmV4dEVsZW1lbnRTaWJsaW5nO1xuXG4gICAgICAgIGNvbnN0IG9yaWdpblJhbmdlID0ge1xuICAgICAgICAgICAgc2M6IHJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgICAgICAgc286IHJhbmdlLnN0YXJ0T2Zmc2V0LFxuICAgICAgICAgICAgZWM6IHJhbmdlLmVuZENvbnRhaW5lcixcbiAgICAgICAgICAgIGVvOiByYW5nZS5lbmRPZmZzZXRcbiAgICAgICAgfTtcblxuICAgICAgICBsZXQgaXNSZW1vdmUgPSB0cnVlO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBzZWxlY3RlZEZvcm1hdHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghdXRpbC5pc0xpc3QodXRpbC5nZXRSYW5nZUZvcm1hdEVsZW1lbnQoc2VsZWN0ZWRGb3JtYXRzW2ldLCBmdW5jdGlvbiAoY3VycmVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldFJhbmdlRm9ybWF0RWxlbWVudChjdXJyZW50KSAmJiBjdXJyZW50ICE9PSBzZWxlY3RlZEZvcm1hdHNbaV07XG4gICAgICAgICAgICB9LmJpbmQodXRpbCkpKSkge1xuICAgICAgICAgICAgICAgIGlzUmVtb3ZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNSZW1vdmUgJiYgKCF0b3BFbCB8fCAoZmlyc3RTZWwudGFnTmFtZSAhPT0gdG9wRWwudGFnTmFtZSB8fCBjb21tYW5kICE9PSB0b3BFbC50YWdOYW1lLnRvVXBwZXJDYXNlKCkpKSAmJiAoIWJvdHRvbUVsIHx8IChsYXN0U2VsLnRhZ05hbWUgIT09IGJvdHRvbUVsLnRhZ05hbWUgfHwgY29tbWFuZCAhPT0gYm90dG9tRWwudGFnTmFtZS50b1VwcGVyQ2FzZSgpKSkpIHtcbiAgICAgICAgICAgIGlmIChkZXRhY2gpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gc2VsZWN0ZWRGb3JtYXRzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSBpIC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZEZvcm1hdHNbal0uY29udGFpbnMoc2VsZWN0ZWRGb3JtYXRzW2ldKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRm9ybWF0cy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaS0tOyBsZW4tLTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgY3VycmVudEZvcm1hdCA9IHV0aWwuZ2V0UmFuZ2VGb3JtYXRFbGVtZW50KGZpcnN0U2VsKTtcbiAgICAgICAgICAgIGNvbnN0IGNhbmNlbCA9IGN1cnJlbnRGb3JtYXQgJiYgY3VycmVudEZvcm1hdC50YWdOYW1lID09PSBjb21tYW5kO1xuICAgICAgICAgICAgbGV0IHJhbmdlQXJyLCB0ZW1wTGlzdDtcbiAgICAgICAgICAgIGNvbnN0IHBhc3NDb21wb25lbnQgPSBmdW5jdGlvbiAoY3VycmVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAhdGhpcy5pc0NvbXBvbmVudChjdXJyZW50KTtcbiAgICAgICAgICAgIH0uYmluZCh1dGlsKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgKCFjYW5jZWwpIHRlbXBMaXN0ID0gdXRpbC5jcmVhdGVFbGVtZW50KGNvbW1hbmQpO1xuXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gc2VsZWN0ZWRGb3JtYXRzLmxlbmd0aCwgciwgbzsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbyA9IHV0aWwuZ2V0UmFuZ2VGb3JtYXRFbGVtZW50KHNlbGVjdGVkRm9ybWF0c1tpXSwgcGFzc0NvbXBvbmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKCFvIHx8ICF1dGlsLmlzTGlzdChvKSkgY29udGludWU7XG5cbiAgICAgICAgICAgICAgICBpZiAoIXIpIHtcbiAgICAgICAgICAgICAgICAgICAgciA9IG87XG4gICAgICAgICAgICAgICAgICAgIHJhbmdlQXJyID0ge3I6IHIsIGY6IFt1dGlsLmdldFBhcmVudEVsZW1lbnQoc2VsZWN0ZWRGb3JtYXRzW2ldLCAnTEknKV19O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyICE9PSBvKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGV0YWNoICYmIHV0aWwuaXNMaXN0Q2VsbChvLnBhcmVudE5vZGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmxpc3QuX2RldGFjaE5lc3RlZC5jYWxsKHRoaXMsIHJhbmdlQXJyLmYpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRldGFjaFJhbmdlRm9ybWF0RWxlbWVudChyYW5nZUFyci5mWzBdLnBhcmVudE5vZGUsIHJhbmdlQXJyLmYsIHRlbXBMaXN0LCBmYWxzZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIG8gPSBzZWxlY3RlZEZvcm1hdHNbaV0ucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2FuY2VsKSB0ZW1wTGlzdCA9IHV0aWwuY3JlYXRlRWxlbWVudChjb21tYW5kKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgciA9IG87XG4gICAgICAgICAgICAgICAgICAgICAgICByYW5nZUFyciA9IHtyOiByLCBmOiBbdXRpbC5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkRm9ybWF0c1tpXSwgJ0xJJyldfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlQXJyLmYucHVzaCh1dGlsLmdldFBhcmVudEVsZW1lbnQoc2VsZWN0ZWRGb3JtYXRzW2ldLCAnTEknKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgaWYgKGkgPT09IGxlbiAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRldGFjaCAmJiB1dGlsLmlzTGlzdENlbGwoby5wYXJlbnROb2RlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmxpc3QuX2RldGFjaE5lc3RlZC5jYWxsKHRoaXMsIHJhbmdlQXJyLmYpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXRhY2hSYW5nZUZvcm1hdEVsZW1lbnQocmFuZ2VBcnIuZlswXS5wYXJlbnROb2RlLCByYW5nZUFyci5mLCB0ZW1wTGlzdCwgZmFsc2UsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgdG9wRWxQYXJlbnQgPSB0b3BFbCA/IHRvcEVsLnBhcmVudE5vZGUgOiB0b3BFbDtcbiAgICAgICAgICAgIGNvbnN0IGJvdHRvbUVsUGFyZW50ID0gYm90dG9tRWwgPyBib3R0b21FbC5wYXJlbnROb2RlIDogYm90dG9tRWw7XG4gICAgICAgICAgICB0b3BFbCA9IHRvcEVsUGFyZW50ICYmICF1dGlsLmlzV3lzaXd5Z0Rpdih0b3BFbFBhcmVudCkgJiYgdG9wRWxQYXJlbnQubm9kZU5hbWUgPT09IGNvbW1hbmQgPyB0b3BFbFBhcmVudCA6IHRvcEVsO1xuICAgICAgICAgICAgYm90dG9tRWwgPSBib3R0b21FbFBhcmVudCAmJiAhdXRpbC5pc1d5c2l3eWdEaXYoYm90dG9tRWxQYXJlbnQpICYmIGJvdHRvbUVsUGFyZW50Lm5vZGVOYW1lID09PSBjb21tYW5kID8gYm90dG9tRWxQYXJlbnQgOiBib3R0b21FbDtcblxuICAgICAgICAgICAgY29uc3QgbWVyZ2VUb3AgPSB0b3BFbCAmJiB0b3BFbC50YWdOYW1lID09PSBjb21tYW5kO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VCb3R0b20gPSBib3R0b21FbCAmJiBib3R0b21FbC50YWdOYW1lID09PSBjb21tYW5kO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBsZXQgbGlzdCA9IG1lcmdlVG9wID8gdG9wRWwgOiB1dGlsLmNyZWF0ZUVsZW1lbnQoY29tbWFuZCk7XG4gICAgICAgICAgICBsZXQgZmlyc3RMaXN0ID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBsYXN0TGlzdCA9IG51bGw7XG4gICAgICAgICAgICBsZXQgdG9wTnVtYmVyID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBib3R0b21OdW1iZXIgPSBudWxsO1xuXG4gICAgICAgICAgICBjb25zdCBwYXNzQ29tcG9uZW50ID0gZnVuY3Rpb24gKGN1cnJlbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gIXRoaXMuaXNDb21wb25lbnQoY3VycmVudCkgJiYgIXRoaXMuaXNMaXN0KGN1cnJlbnQpO1xuICAgICAgICAgICAgfS5iaW5kKHV0aWwpO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gc2VsZWN0ZWRGb3JtYXRzLmxlbmd0aCwgbmV3Q2VsbCwgZlRhZywgaXNDZWxsLCBuZXh0LCBvcmlnaW5QYXJlbnQsIG5leHRQYXJlbnQsIHBhcmVudFRhZywgc2libGluZ1RhZywgcmFuZ2VUYWc7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIGZUYWcgPSBzZWxlY3RlZEZvcm1hdHNbaV07XG4gICAgICAgICAgICAgICAgaWYgKGZUYWcuY2hpbGROb2Rlcy5sZW5ndGggPT09IDAgJiYgIXV0aWwuX2lzSWdub3JlTm9kZUNoYW5nZShmVGFnKSkge1xuICAgICAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW0oZlRhZyk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBuZXh0ID0gc2VsZWN0ZWRGb3JtYXRzW2kgKyAxXTtcbiAgICAgICAgICAgICAgICBvcmlnaW5QYXJlbnQgPSBmVGFnLnBhcmVudE5vZGU7XG4gICAgICAgICAgICAgICAgbmV4dFBhcmVudCA9IG5leHQgPyBuZXh0LnBhcmVudE5vZGUgOiBudWxsO1xuICAgICAgICAgICAgICAgIGlzQ2VsbCA9IHV0aWwuaXNMaXN0Q2VsbChmVGFnKTtcbiAgICAgICAgICAgICAgICByYW5nZVRhZyA9IHV0aWwuaXNSYW5nZUZvcm1hdEVsZW1lbnQob3JpZ2luUGFyZW50KSA/IG9yaWdpblBhcmVudCA6IG51bGw7XG4gICAgICAgICAgICAgICAgcGFyZW50VGFnID0gaXNDZWxsICYmICF1dGlsLmlzV3lzaXd5Z0RpdihvcmlnaW5QYXJlbnQpID8gb3JpZ2luUGFyZW50LnBhcmVudE5vZGUgOiBvcmlnaW5QYXJlbnQ7XG4gICAgICAgICAgICAgICAgc2libGluZ1RhZyA9IGlzQ2VsbCAmJiAhdXRpbC5pc1d5c2l3eWdEaXYob3JpZ2luUGFyZW50KSA/ICghbmV4dCB8fCB1dGlsLmlzTGlzdENlbGwocGFyZW50VGFnKSkgPyBvcmlnaW5QYXJlbnQgOiBvcmlnaW5QYXJlbnQubmV4dFNpYmxpbmcgOiBmVGFnLm5leHRTaWJsaW5nO1xuXG4gICAgICAgICAgICAgICAgbmV3Q2VsbCA9IHV0aWwuY3JlYXRlRWxlbWVudCgnTEknKTtcbiAgICAgICAgICAgICAgICB1dGlsLmNvcHlGb3JtYXRBdHRyaWJ1dGVzKG5ld0NlbGwsIGZUYWcpO1xuICAgICAgICAgICAgICAgIGlmICh1dGlsLmlzQ29tcG9uZW50KGZUYWcpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlzSFIgPSAvXkhSJC9pLnRlc3QoZlRhZy5ub2RlTmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghaXNIUikgbmV3Q2VsbC5pbm5lckhUTUwgPSAnPGJyPic7XG4gICAgICAgICAgICAgICAgICAgIG5ld0NlbGwuaW5uZXJIVE1MICs9IGZUYWcub3V0ZXJIVE1MO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNIUikgbmV3Q2VsbC5pbm5lckhUTUwgKz0gJzxicj4nO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZDaGlsZHJlbiA9IGZUYWcuY2hpbGROb2RlcztcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGZDaGlsZHJlblswXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3Q2VsbC5hcHBlbmRDaGlsZChmQ2hpbGRyZW5bMF0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxpc3QuYXBwZW5kQ2hpbGQobmV3Q2VsbCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoIW5leHQpIGxhc3RMaXN0ID0gbGlzdDtcbiAgICAgICAgICAgICAgICBpZiAoIW5leHQgfHwgcGFyZW50VGFnICE9PSBuZXh0UGFyZW50IHx8IHV0aWwuaXNSYW5nZUZvcm1hdEVsZW1lbnQoc2libGluZ1RhZykpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFmaXJzdExpc3QpIGZpcnN0TGlzdCA9IGxpc3Q7XG4gICAgICAgICAgICAgICAgICAgIGlmICgoIW1lcmdlVG9wIHx8ICFuZXh0IHx8IHBhcmVudFRhZyAhPT0gbmV4dFBhcmVudCkgJiYgIShuZXh0ICYmIHV0aWwuaXNMaXN0KG5leHRQYXJlbnQpICYmIG5leHRQYXJlbnQgPT09IG9yaWdpblBhcmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsaXN0LnBhcmVudE5vZGUgIT09IHBhcmVudFRhZykgcGFyZW50VGFnLmluc2VydEJlZm9yZShsaXN0LCBzaWJsaW5nVGFnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlSXRlbShmVGFnKTtcbiAgICAgICAgICAgICAgICBpZiAobWVyZ2VUb3AgJiYgdG9wTnVtYmVyID09PSBudWxsKSB0b3BOdW1iZXIgPSBsaXN0LmNoaWxkcmVuLmxlbmd0aCAtIDE7XG4gICAgICAgICAgICAgICAgaWYgKG5leHQgJiYgKHV0aWwuZ2V0UmFuZ2VGb3JtYXRFbGVtZW50KG5leHRQYXJlbnQsIHBhc3NDb21wb25lbnQpICE9PSB1dGlsLmdldFJhbmdlRm9ybWF0RWxlbWVudChvcmlnaW5QYXJlbnQsIHBhc3NDb21wb25lbnQpIHx8ICh1dGlsLmlzTGlzdChuZXh0UGFyZW50KSAmJiB1dGlsLmlzTGlzdChvcmlnaW5QYXJlbnQpICYmIHV0aWwuZ2V0RWxlbWVudERlcHRoKG5leHRQYXJlbnQpICE9PSB1dGlsLmdldEVsZW1lbnREZXB0aChvcmlnaW5QYXJlbnQpKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdCA9IHV0aWwuY3JlYXRlRWxlbWVudChjb21tYW5kKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAocmFuZ2VUYWcgJiYgcmFuZ2VUYWcuY2hpbGRyZW4ubGVuZ3RoID09PSAwKSB1dGlsLnJlbW92ZUl0ZW0ocmFuZ2VUYWcpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodG9wTnVtYmVyKSB7XG4gICAgICAgICAgICAgICAgZmlyc3RMaXN0ID0gZmlyc3RMaXN0LmNoaWxkcmVuW3RvcE51bWJlcl07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChtZXJnZUJvdHRvbSkge1xuICAgICAgICAgICAgICAgIGJvdHRvbU51bWJlciA9IGxpc3QuY2hpbGRyZW4ubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgICAgICBsaXN0LmlubmVySFRNTCArPSBib3R0b21FbC5pbm5lckhUTUw7XG4gICAgICAgICAgICAgICAgbGFzdExpc3QgPSBsaXN0LmNoaWxkcmVuW2JvdHRvbU51bWJlcl07XG4gICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVJdGVtKGJvdHRvbUVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgdGhpcy5lZmZlY3ROb2RlID0gbnVsbDtcbiAgICAgICAgcmV0dXJuIG9yaWdpblJhbmdlO1xuICAgIH0sXG5cbiAgICBfZGV0YWNoTmVzdGVkOiBmdW5jdGlvbiAoY2VsbHMpIHtcbiAgICAgICAgY29uc3QgZmlyc3QgPSBjZWxsc1swXTtcbiAgICAgICAgY29uc3QgbGFzdCA9IGNlbGxzW2NlbGxzLmxlbmd0aCAtIDFdO1xuICAgICAgICBjb25zdCBuZXh0ID0gbGFzdC5uZXh0RWxlbWVudFNpYmxpbmc7XG4gICAgICAgIGNvbnN0IG9yaWdpbkxpc3QgPSBmaXJzdC5wYXJlbnROb2RlO1xuICAgICAgICBjb25zdCBzaWJsaW5nID0gb3JpZ2luTGlzdC5wYXJlbnROb2RlLm5leHRFbGVtZW50U2libGluZztcbiAgICAgICAgY29uc3QgcGFyZW50Tm9kZSA9IG9yaWdpbkxpc3QucGFyZW50Tm9kZS5wYXJlbnROb2RlO1xuXG4gICAgICAgIGZvciAobGV0IGMgPSAwLCBjTGVuID0gY2VsbHMubGVuZ3RoOyBjIDwgY0xlbjsgYysrKSB7XG4gICAgICAgICAgICBwYXJlbnROb2RlLmluc2VydEJlZm9yZShjZWxsc1tjXSwgc2libGluZyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobmV4dCAmJiBvcmlnaW5MaXN0LmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IG5ld0xpc3QgPSBvcmlnaW5MaXN0LmNsb25lTm9kZShmYWxzZSk7XG4gICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IG9yaWdpbkxpc3QuY2hpbGROb2RlcztcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy51dGlsLmdldFBvc2l0aW9uSW5kZXgobmV4dCk7XG4gICAgICAgICAgICB3aGlsZSAoY2hpbGRyZW5baW5kZXhdKSB7XG4gICAgICAgICAgICAgICAgbmV3TGlzdC5hcHBlbmRDaGlsZChjaGlsZHJlbltpbmRleF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGFzdC5hcHBlbmRDaGlsZChuZXdMaXN0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvcmlnaW5MaXN0LmNoaWxkcmVuLmxlbmd0aCA9PT0gMCkgdGhpcy51dGlsLnJlbW92ZUl0ZW0ob3JpZ2luTGlzdCk7XG4gICAgICAgIHRoaXMudXRpbC5tZXJnZVNhbWVUYWdzKHBhcmVudE5vZGUpO1xuXG4gICAgICAgIGNvbnN0IGVkZ2UgPSB0aGlzLnV0aWwuZ2V0RWRnZUNoaWxkTm9kZXMoZmlyc3QsIGxhc3QpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjYzogZmlyc3QucGFyZW50Tm9kZSxcbiAgICAgICAgICAgIHNjOiBlZGdlLnNjLFxuICAgICAgICAgICAgZWM6IGVkZ2UuZWNcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgZWRpdEluc2lkZUxpc3Q6IGZ1bmN0aW9uIChyZW1vdmUsIHNlbGVjdGVkQ2VsbHMpIHtcbiAgICAgICAgc2VsZWN0ZWRDZWxscyA9ICFzZWxlY3RlZENlbGxzID8gdGhpcy5nZXRTZWxlY3RlZEVsZW1lbnRzKCkuZmlsdGVyKGZ1bmN0aW9uIChlbCkgeyByZXR1cm4gdGhpcy5pc0xpc3RDZWxsKGVsKTsgfS5iaW5kKHRoaXMudXRpbCkpIDogc2VsZWN0ZWRDZWxscztcbiAgICAgICAgY29uc3QgY2VsbHNMZW4gPSBzZWxlY3RlZENlbGxzLmxlbmd0aDtcbiAgICAgICAgaWYgKGNlbGxzTGVuID09PSAwIHx8ICghcmVtb3ZlICYmICghdGhpcy51dGlsLmlzTGlzdENlbGwoc2VsZWN0ZWRDZWxsc1swXS5wcmV2aW91c0VsZW1lbnRTaWJsaW5nKSAmJiAhdGhpcy51dGlsLmlzTGlzdENlbGwoc2VsZWN0ZWRDZWxsc1tjZWxsc0xlbiAtIDFdLm5leHRFbGVtZW50U2libGluZykpKSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzYzogc2VsZWN0ZWRDZWxsc1swXSxcbiAgICAgICAgICAgICAgICBzbzogMCxcbiAgICAgICAgICAgICAgICBlYzogc2VsZWN0ZWRDZWxsc1tjZWxsc0xlbiAtIDFdLFxuICAgICAgICAgICAgICAgIGVvOiAxXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG9yaWdpbkxpc3QgPSBzZWxlY3RlZENlbGxzWzBdLnBhcmVudE5vZGU7XG4gICAgICAgIGxldCBsYXN0Q2VsbCA9IHNlbGVjdGVkQ2VsbHNbY2VsbHNMZW4gLSAxXTtcbiAgICAgICAgbGV0IHJhbmdlID0gbnVsbDtcblxuICAgICAgICBpZiAocmVtb3ZlKSB7XG4gICAgICAgICAgICBpZiAob3JpZ2luTGlzdCAhPT0gbGFzdENlbGwucGFyZW50Tm9kZSAmJiB0aGlzLnV0aWwuaXNMaXN0KGxhc3RDZWxsLnBhcmVudE5vZGUucGFyZW50Tm9kZSkgJiYgbGFzdENlbGwubmV4dEVsZW1lbnRTaWJsaW5nKSB7XG4gICAgICAgICAgICAgICAgbGFzdENlbGwgPSBsYXN0Q2VsbC5uZXh0RWxlbWVudFNpYmxpbmc7XG4gICAgICAgICAgICAgICAgd2hpbGUgKGxhc3RDZWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkQ2VsbHMucHVzaChsYXN0Q2VsbCk7XG4gICAgICAgICAgICAgICAgICAgIGxhc3RDZWxsID0gbGFzdENlbGwubmV4dEVsZW1lbnRTaWJsaW5nO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJhbmdlID0gdGhpcy5wbHVnaW5zLmxpc3QuZWRpdExpc3QuY2FsbCh0aGlzLCBvcmlnaW5MaXN0Lm5vZGVOYW1lLnRvVXBwZXJDYXNlKCksIHNlbGVjdGVkQ2VsbHMsIHRydWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IGlubmVyTGlzdCA9IHRoaXMudXRpbC5jcmVhdGVFbGVtZW50KG9yaWdpbkxpc3Qubm9kZU5hbWUpO1xuICAgICAgICAgICAgbGV0IHByZXYgPSBzZWxlY3RlZENlbGxzWzBdLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7XG4gICAgICAgICAgICBsZXQgbmV4dCA9IGxhc3RDZWxsLm5leHRFbGVtZW50U2libGluZztcbiAgICAgICAgICAgIGNvbnN0IG5vZGVQYXRoID0geyBzOiBudWxsLCBlOiBudWxsLCBzbDogb3JpZ2luTGlzdCwgZWw6IG9yaWdpbkxpc3QgfTtcblxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNlbGxzTGVuLCBjOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjID0gc2VsZWN0ZWRDZWxsc1tpXTtcbiAgICAgICAgICAgICAgICBpZiAoYy5wYXJlbnROb2RlICE9PSBvcmlnaW5MaXN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2lucy5saXN0Ll9pbnNpZWRMaXN0LmNhbGwodGhpcywgb3JpZ2luTGlzdCwgaW5uZXJMaXN0LCBwcmV2LCBuZXh0LCBub2RlUGF0aCk7XG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbkxpc3QgPSBjLnBhcmVudE5vZGU7XG4gICAgICAgICAgICAgICAgICAgIGlubmVyTGlzdCA9IHRoaXMudXRpbC5jcmVhdGVFbGVtZW50KG9yaWdpbkxpc3Qubm9kZU5hbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBwcmV2ID0gYy5wcmV2aW91c0VsZW1lbnRTaWJsaW5nO1xuICAgICAgICAgICAgICAgIG5leHQgPSBjLm5leHRFbGVtZW50U2libGluZztcbiAgICAgICAgICAgICAgICBpbm5lckxpc3QuYXBwZW5kQ2hpbGQoYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5saXN0Ll9pbnNpZWRMaXN0LmNhbGwodGhpcywgb3JpZ2luTGlzdCwgaW5uZXJMaXN0LCBwcmV2LCBuZXh0LCBub2RlUGF0aCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNjID0gdGhpcy51dGlsLmdldE5vZGVGcm9tUGF0aChub2RlUGF0aC5zLCBub2RlUGF0aC5zbCk7XG4gICAgICAgICAgICBjb25zdCBlYyA9IHRoaXMudXRpbC5nZXROb2RlRnJvbVBhdGgobm9kZVBhdGguZSwgbm9kZVBhdGguZWwpO1xuICAgICAgICAgICAgcmFuZ2UgPSB7XG4gICAgICAgICAgICAgICAgc2M6IHNjLFxuICAgICAgICAgICAgICAgIHNvOiAwLFxuICAgICAgICAgICAgICAgIGVjOiBlYyxcbiAgICAgICAgICAgICAgICBlbzogZWMudGV4dENvbnRlbnQubGVuZ3RoXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJhbmdlO1xuICAgIH0sXG5cbiAgICBfaW5zaWVkTGlzdDogZnVuY3Rpb24gKG9yaWdpbkxpc3QsIGlubmVyTGlzdCwgcHJldiwgbmV4dCwgbm9kZVBhdGgpIHtcbiAgICAgICAgbGV0IGluc2VydFByZXYgPSBmYWxzZTtcblxuICAgICAgICBpZiAocHJldiAmJiBpbm5lckxpc3QudGFnTmFtZSA9PT0gcHJldi50YWdOYW1lKSB7XG4gICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IGlubmVyTGlzdC5jaGlsZHJlbjtcbiAgICAgICAgICAgIHdoaWxlIChjaGlsZHJlblswXSkge1xuICAgICAgICAgICAgICAgIHByZXYuYXBwZW5kQ2hpbGQoY2hpbGRyZW5bMF0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpbm5lckxpc3QgPSBwcmV2O1xuICAgICAgICAgICAgaW5zZXJ0UHJldiA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobmV4dCAmJiBpbm5lckxpc3QudGFnTmFtZSA9PT0gbmV4dC50YWdOYW1lKSB7XG4gICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IG5leHQuY2hpbGRyZW47XG4gICAgICAgICAgICB3aGlsZSAoY2hpbGRyZW5bMF0pIHtcbiAgICAgICAgICAgICAgICBpbm5lckxpc3QuYXBwZW5kQ2hpbGQoY2hpbGRyZW5bMF0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB0ZW1wID0gbmV4dC5uZXh0RWxlbWVudFNpYmxpbmc7XG4gICAgICAgICAgICBuZXh0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobmV4dCk7XG4gICAgICAgICAgICBuZXh0ID0gdGVtcDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaW5zZXJ0UHJldikge1xuICAgICAgICAgICAgaWYgKHRoaXMudXRpbC5pc0xpc3RDZWxsKHByZXYpKSB7XG4gICAgICAgICAgICAgICAgb3JpZ2luTGlzdCA9IHByZXY7XG4gICAgICAgICAgICAgICAgbmV4dCA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG9yaWdpbkxpc3QuaW5zZXJ0QmVmb3JlKGlubmVyTGlzdCwgbmV4dCk7XG5cbiAgICAgICAgICAgIGlmICghbm9kZVBhdGgucykge1xuICAgICAgICAgICAgICAgIG5vZGVQYXRoLnMgPSB0aGlzLnV0aWwuZ2V0Tm9kZVBhdGgoaW5uZXJMaXN0LmZpcnN0RWxlbWVudENoaWxkLmZpcnN0Q2hpbGQsIG9yaWdpbkxpc3QsIG51bGwpO1xuICAgICAgICAgICAgICAgIG5vZGVQYXRoLnNsID0gb3JpZ2luTGlzdDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgc2xQYXRoID0gb3JpZ2luTGlzdC5jb250YWlucyhub2RlUGF0aC5zbCkgPyB0aGlzLnV0aWwuZ2V0Tm9kZVBhdGgobm9kZVBhdGguc2wsIG9yaWdpbkxpc3QpIDogbnVsbDtcbiAgICAgICAgICAgIG5vZGVQYXRoLmUgPSB0aGlzLnV0aWwuZ2V0Tm9kZVBhdGgoaW5uZXJMaXN0Lmxhc3RFbGVtZW50Q2hpbGQuZmlyc3RDaGlsZCwgb3JpZ2luTGlzdCwgbnVsbCk7XG4gICAgICAgICAgICBub2RlUGF0aC5lbCA9IG9yaWdpbkxpc3Q7XG5cbiAgICAgICAgICAgIHRoaXMudXRpbC5tZXJnZVNhbWVUYWdzKG9yaWdpbkxpc3QsIFtub2RlUGF0aC5zLCBub2RlUGF0aC5lLCBzbFBhdGhdLCBmYWxzZSk7XG4gICAgICAgICAgICB0aGlzLnV0aWwubWVyZ2VOZXN0ZWRUYWdzKG9yaWdpbkxpc3QpO1xuICAgICAgICAgICAgaWYgKHNsUGF0aCkgbm9kZVBhdGguc2wgPSB0aGlzLnV0aWwuZ2V0Tm9kZUZyb21QYXRoKHNsUGF0aCwgb3JpZ2luTGlzdCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaW5uZXJMaXN0O1xuICAgIH0sXG5cbiAgICBwaWNrdXA6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICBsZXQgdGFyZ2V0ID0gZS50YXJnZXQ7XG4gICAgICAgIGxldCBjb21tYW5kID0gJyc7XG5cbiAgICAgICAgd2hpbGUgKCFjb21tYW5kICYmICEvXlVMJC9pLnRlc3QodGFyZ2V0LnRhZ05hbWUpKSB7XG4gICAgICAgICAgICBjb21tYW5kID0gdGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS1jb21tYW5kJyk7XG4gICAgICAgICAgICB0YXJnZXQgPSB0YXJnZXQucGFyZW50Tm9kZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghY29tbWFuZCkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHJhbmdlID0gdGhpcy5wbHVnaW5zLmxpc3QuZWRpdExpc3QuY2FsbCh0aGlzLCBjb21tYW5kLCBudWxsLCBmYWxzZSk7XG4gICAgICAgIGlmIChyYW5nZSkgdGhpcy5zZXRSYW5nZShyYW5nZS5zYywgcmFuZ2Uuc28sIHJhbmdlLmVjLCByYW5nZS5lbyk7XG5cbiAgICAgICAgdGhpcy5zdWJtZW51T2ZmKCk7XG5cbiAgICAgICAgLy8gaGlzdG9yeSBzdGFja1xuICAgICAgICB0aGlzLmhpc3RvcnkucHVzaChmYWxzZSk7XG4gICAgfVxufTtcbiIsIi8qXHJcbiAqIHd5c2l3eWcgd2ViIGVkaXRvclxyXG4gKlxyXG4gKiBzdW5lZGl0b3IuanNcclxuICogQ29weXJpZ2h0IDIwMTcgSmlIb25nIExlZS5cclxuICogTUlUIGxpY2Vuc2UuXHJcbiAqL1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCB7XHJcbiAgICBuYW1lOiAndGFibGUnLFxyXG4gICAgZGlzcGxheTogJ3N1Ym1lbnUnLFxyXG4gICAgYWRkOiBmdW5jdGlvbiAoY29yZSwgdGFyZ2V0RWxlbWVudCkge1xyXG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBjb3JlLmNvbnRleHQ7XHJcbiAgICAgICAgbGV0IGNvbnRleHRUYWJsZSA9IGNvbnRleHQudGFibGUgPSB7XHJcbiAgICAgICAgICAgIF9lbGVtZW50OiBudWxsLFxyXG4gICAgICAgICAgICBfdGRFbGVtZW50OiBudWxsLFxyXG4gICAgICAgICAgICBfdHJFbGVtZW50OiBudWxsLFxyXG4gICAgICAgICAgICBfdHJFbGVtZW50czogbnVsbCxcclxuICAgICAgICAgICAgX3RhYmxlWFk6IFtdLFxyXG4gICAgICAgICAgICBfbWF4V2lkdGg6IHRydWUsXHJcbiAgICAgICAgICAgIF9maXhlZENvbHVtbjogZmFsc2UsXHJcbiAgICAgICAgICAgIF9ydGw6IGNvbnRleHQub3B0aW9ucy5ydGwsXHJcbiAgICAgICAgICAgIGNlbGxDb250cm9sbGVyVG9wOiBjb250ZXh0Lm9wdGlvbnMudGFibGVDZWxsQ29udHJvbGxlclBvc2l0aW9uID09PSAndG9wJyxcclxuICAgICAgICAgICAgcmVzaXplVGV4dDogbnVsbCxcclxuICAgICAgICAgICAgaGVhZGVyQnV0dG9uOiBudWxsLFxyXG4gICAgICAgICAgICBtZXJnZUJ1dHRvbjogbnVsbCxcclxuICAgICAgICAgICAgc3BsaXRCdXR0b246IG51bGwsXHJcbiAgICAgICAgICAgIHNwbGl0TWVudTogbnVsbCxcclxuICAgICAgICAgICAgbWF4VGV4dDogY29yZS5sYW5nLmNvbnRyb2xsZXIubWF4U2l6ZSxcclxuICAgICAgICAgICAgbWluVGV4dDogY29yZS5sYW5nLmNvbnRyb2xsZXIubWluU2l6ZSxcclxuICAgICAgICAgICAgX3BoeXNpY2FsX2NlbGxDbnQ6IDAsXHJcbiAgICAgICAgICAgIF9sb2dpY2FsX2NlbGxDbnQ6IDAsXHJcbiAgICAgICAgICAgIF9yb3dDbnQ6IDAsXHJcbiAgICAgICAgICAgIF9yb3dJbmRleDogMCxcclxuICAgICAgICAgICAgX3BoeXNpY2FsX2NlbGxJbmRleDogMCxcclxuICAgICAgICAgICAgX2xvZ2ljYWxfY2VsbEluZGV4OiAwLFxyXG4gICAgICAgICAgICBfY3VycmVudF9jb2xTcGFuOiAwLFxyXG4gICAgICAgICAgICBfY3VycmVudF9yb3dTcGFuOiAwLFxyXG4gICAgICAgICAgICBpY29uczoge1xyXG4gICAgICAgICAgICAgICAgZXhwYW5zaW9uOiBjb3JlLmljb25zLmV4cGFuc2lvbixcclxuICAgICAgICAgICAgICAgIHJlZHVjdGlvbjogY29yZS5pY29ucy5yZWR1Y3Rpb25cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKiBzZXQgc3VibWVudSAqL1xyXG4gICAgICAgIGxldCBsaXN0RGl2ID0gdGhpcy5zZXRTdWJtZW51LmNhbGwoY29yZSk7XHJcbiAgICAgICAgbGV0IHRhYmxlUGlja2VyID0gbGlzdERpdi5xdWVyeVNlbGVjdG9yKCcuc2UtY29udHJvbGxlci10YWJsZS1waWNrZXInKTtcclxuXHJcbiAgICAgICAgY29udGV4dFRhYmxlLnRhYmxlSGlnaGxpZ2h0ID0gbGlzdERpdi5xdWVyeVNlbGVjdG9yKCcuc2UtdGFibGUtc2l6ZS1oaWdobGlnaHRlZCcpO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS50YWJsZVVuSGlnaGxpZ2h0ID0gbGlzdERpdi5xdWVyeVNlbGVjdG9yKCcuc2UtdGFibGUtc2l6ZS11bmhpZ2hsaWdodGVkJyk7XHJcbiAgICAgICAgY29udGV4dFRhYmxlLnRhYmxlRGlzcGxheSA9IGxpc3REaXYucXVlcnlTZWxlY3RvcignLnNlLXRhYmxlLXNpemUtZGlzcGxheScpO1xyXG4gICAgICAgIGlmIChjb250ZXh0Lm9wdGlvbnMucnRsKSBjb250ZXh0VGFibGUudGFibGVIaWdobGlnaHQuc3R5bGUubGVmdCA9ICgxMCAqIDE4IC0gMTMpICsgJ3B4JztcclxuXHJcbiAgICAgICAgLyoqIHNldCB0YWJsZSBjb250cm9sbGVyICovXHJcbiAgICAgICAgbGV0IHRhYmxlQ29udHJvbGxlciA9IHRoaXMuc2V0Q29udHJvbGxlcl90YWJsZS5jYWxsKGNvcmUpO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS50YWJsZUNvbnRyb2xsZXIgPSB0YWJsZUNvbnRyb2xsZXI7XHJcbiAgICAgICAgY29udGV4dFRhYmxlLnJlc2l6ZUJ1dHRvbiA9IHRhYmxlQ29udHJvbGxlci5xdWVyeVNlbGVjdG9yKCcuX3NlX3RhYmxlX3Jlc2l6ZScpO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS5yZXNpemVUZXh0ID0gdGFibGVDb250cm9sbGVyLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfdGFibGVfcmVzaXplID4gc3BhbiA+IHNwYW4nKTtcclxuICAgICAgICBjb250ZXh0VGFibGUuY29sdW1uRml4ZWRCdXR0b24gPSB0YWJsZUNvbnRyb2xsZXIucXVlcnlTZWxlY3RvcignLl9zZV90YWJsZV9maXhlZF9jb2x1bW4nKTtcclxuICAgICAgICBjb250ZXh0VGFibGUuaGVhZGVyQnV0dG9uID0gdGFibGVDb250cm9sbGVyLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfdGFibGVfaGVhZGVyJyk7XHJcbiAgICAgICAgdGFibGVDb250cm9sbGVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGNvcmUuZXZlbnRTdG9wKTtcclxuXHJcbiAgICAgICAgLyoqIHNldCByZXNpemluZyAqL1xyXG4gICAgICAgIGxldCByZXNpemVEaXYgPSB0aGlzLnNldENvbnRyb2xsZXJfdGFibGVFZGl0b3IuY2FsbChjb3JlLCBjb250ZXh0VGFibGUuY2VsbENvbnRyb2xsZXJUb3ApO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS5yZXNpemVEaXYgPSByZXNpemVEaXY7XHJcbiAgICAgICAgY29udGV4dFRhYmxlLnNwbGl0TWVudSA9IHJlc2l6ZURpdi5xdWVyeVNlbGVjdG9yKCcuc2UtYnRuLWdyb3VwLXN1YicpO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS5tZXJnZUJ1dHRvbiA9IHJlc2l6ZURpdi5xdWVyeVNlbGVjdG9yKCcuX3NlX3RhYmxlX21lcmdlX2J1dHRvbicpO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS5zcGxpdEJ1dHRvbiA9IHJlc2l6ZURpdi5xdWVyeVNlbGVjdG9yKCcuX3NlX3RhYmxlX3NwbGl0X2J1dHRvbicpO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS5pbnNlcnRSb3dBYm92ZUJ1dHRvbiA9IHJlc2l6ZURpdi5xdWVyeVNlbGVjdG9yKCcuX3NlX3RhYmxlX2luc2VydF9yb3dfYScpO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS5pbnNlcnRSb3dCZWxvd0J1dHRvbiA9IHJlc2l6ZURpdi5xdWVyeVNlbGVjdG9yKCcuX3NlX3RhYmxlX2luc2VydF9yb3dfYicpO1xyXG4gICAgICAgIHJlc2l6ZURpdi5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBjb3JlLmV2ZW50U3RvcCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLyoqIGFkZCBldmVudCBsaXN0ZW5lcnMgKi9cclxuICAgICAgICB0YWJsZVBpY2tlci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLm9uTW91c2VNb3ZlX3RhYmxlUGlja2VyLmJpbmQoY29yZSwgY29udGV4dFRhYmxlKSk7XHJcbiAgICAgICAgdGFibGVQaWNrZXIuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLmFwcGVuZFRhYmxlLmJpbmQoY29yZSkpO1xyXG4gICAgICAgIHJlc2l6ZURpdi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMub25DbGlja190YWJsZUNvbnRyb2xsZXIuYmluZChjb3JlKSk7XHJcbiAgICAgICAgdGFibGVDb250cm9sbGVyLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5vbkNsaWNrX3RhYmxlQ29udHJvbGxlci5iaW5kKGNvcmUpKTtcclxuXHJcbiAgICAgICAgLyoqIGFwcGVuZCB0YXJnZXQgYnV0dG9uIG1lbnUgKi9cclxuICAgICAgICBjb3JlLmluaXRNZW51VGFyZ2V0KHRoaXMubmFtZSwgdGFyZ2V0RWxlbWVudCwgbGlzdERpdik7XHJcblxyXG4gICAgICAgIC8qKiBhcHBlbmQgY29udHJvbGxlciAqL1xyXG4gICAgICAgIGNvbnRleHQuZWxlbWVudC5yZWxhdGl2ZS5hcHBlbmRDaGlsZChyZXNpemVEaXYpO1xyXG4gICAgICAgIGNvbnRleHQuZWxlbWVudC5yZWxhdGl2ZS5hcHBlbmRDaGlsZCh0YWJsZUNvbnRyb2xsZXIpO1xyXG5cclxuICAgICAgICAvKiogZW1wdHkgbWVtb3J5ICovXHJcbiAgICAgICAgbGlzdERpdiA9IG51bGwsIHRhYmxlUGlja2VyID0gbnVsbCwgcmVzaXplRGl2ID0gbnVsbCwgdGFibGVDb250cm9sbGVyID0gbnVsbCwgY29udGV4dFRhYmxlID0gbnVsbDtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0U3VibWVudTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGNvbnN0IGxpc3REaXYgPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XHJcbiAgICAgICAgbGlzdERpdi5jbGFzc05hbWUgPSAnc2Utc3VibWVudSBzZS1zZWxlY3Rvci10YWJsZSc7XHJcbiAgICAgICAgbGlzdERpdi5pbm5lckhUTUwgPSAnJyArXHJcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtdGFibGUtc2l6ZVwiPicgK1xyXG4gICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS10YWJsZS1zaXplLXBpY2tlciBzZS1jb250cm9sbGVyLXRhYmxlLXBpY2tlclwiPjwvZGl2PicgK1xyXG4gICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS10YWJsZS1zaXplLWhpZ2hsaWdodGVkXCI+PC9kaXY+JyArXHJcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLXRhYmxlLXNpemUtdW5oaWdobGlnaHRlZFwiPjwvZGl2PicgK1xyXG4gICAgICAgICAgICAnPC9kaXY+JyArXHJcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtdGFibGUtc2l6ZS1kaXNwbGF5XCI+MSB4IDE8L2Rpdj4nO1xyXG5cclxuICAgICAgICByZXR1cm4gbGlzdERpdjtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0Q29udHJvbGxlcl90YWJsZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGNvbnN0IGxhbmcgPSB0aGlzLmxhbmc7XHJcbiAgICAgICAgY29uc3QgaWNvbnMgPSB0aGlzLmljb25zO1xyXG4gICAgICAgIGNvbnN0IHRhYmxlUmVzaXplID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xyXG5cclxuICAgICAgICB0YWJsZVJlc2l6ZS5jbGFzc05hbWUgPSAnc2UtY29udHJvbGxlciBzZS1jb250cm9sbGVyLXRhYmxlJztcclxuICAgICAgICB0YWJsZVJlc2l6ZS5pbm5lckhUTUwgPSAnJyArXHJcbiAgICAgICAgICAgICc8ZGl2PicgK1xyXG4gICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1idG4tZ3JvdXBcIj4nICtcclxuICAgICAgICAgICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1jb21tYW5kPVwicmVzaXplXCIgY2xhc3M9XCJzZS1idG4gc2UtdG9vbHRpcCBfc2VfdGFibGVfcmVzaXplXCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb25zLmV4cGFuc2lvbiArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIubWF4U2l6ZSArICc8L3NwYW4+PC9zcGFuPicgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcclxuICAgICAgICAgICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1jb21tYW5kPVwibGF5b3V0XCIgY2xhc3M9XCJzZS1idG4gc2UtdG9vbHRpcCBfc2VfdGFibGVfZml4ZWRfY29sdW1uXCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb25zLmZpeGVkX2NvbHVtbl93aWR0aCArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIuZml4ZWRDb2x1bW5XaWR0aCArICc8L3NwYW4+PC9zcGFuPicgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcclxuICAgICAgICAgICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1jb21tYW5kPVwiaGVhZGVyXCIgY2xhc3M9XCJzZS1idG4gc2UtdG9vbHRpcCBfc2VfdGFibGVfaGVhZGVyXCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb25zLnRhYmxlX2hlYWRlciArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIudGFibGVIZWFkZXIgKyAnPC9zcGFuPjwvc3Bhbj4nICtcclxuICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtY29tbWFuZD1cInJlbW92ZVwiIGNsYXNzPVwic2UtYnRuIHNlLXRvb2x0aXBcIj4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWNvbnMuZGVsZXRlICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcuY29udHJvbGxlci5yZW1vdmUgKyAnPC9zcGFuPjwvc3Bhbj4nICtcclxuICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXHJcbiAgICAgICAgICAgICAgICAnPC9kaXY+JyArXHJcbiAgICAgICAgICAgICc8L2Rpdj4nO1xyXG5cclxuICAgICAgICByZXR1cm4gdGFibGVSZXNpemU7XHJcbiAgICB9LFxyXG5cclxuICAgIHNldENvbnRyb2xsZXJfdGFibGVFZGl0b3I6IGZ1bmN0aW9uIChjZWxsQ29udHJvbGxlclRvcCkge1xyXG4gICAgICAgIGNvbnN0IGxhbmcgPSB0aGlzLmxhbmc7XHJcbiAgICAgICAgY29uc3QgaWNvbnMgPSB0aGlzLmljb25zO1xyXG4gICAgICAgIGNvbnN0IHRhYmxlUmVzaXplID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xyXG5cclxuICAgICAgICB0YWJsZVJlc2l6ZS5jbGFzc05hbWUgPSAnc2UtY29udHJvbGxlciBzZS1jb250cm9sbGVyLXRhYmxlLWNlbGwnO1xyXG4gICAgICAgIHRhYmxlUmVzaXplLmlubmVySFRNTCA9IChjZWxsQ29udHJvbGxlclRvcCA/ICcnIDogJzxkaXYgY2xhc3M9XCJzZS1hcnJvdyBzZS1hcnJvdy11cFwiPjwvZGl2PicpICtcclxuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1idG4tZ3JvdXBcIj4nICtcclxuICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJpbnNlcnRcIiBkYXRhLXZhbHVlPVwicm93XCIgZGF0YS1vcHRpb249XCJ1cFwiIGNsYXNzPVwic2UtYnRuIHNlLXRvb2x0aXAgX3NlX3RhYmxlX2luc2VydF9yb3dfYVwiPicgK1xyXG4gICAgICAgICAgICAgICAgICAgIGljb25zLmluc2VydF9yb3dfYWJvdmUgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIuaW5zZXJ0Um93QWJvdmUgKyAnPC9zcGFuPjwvc3Bhbj4nICtcclxuICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcclxuICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJpbnNlcnRcIiBkYXRhLXZhbHVlPVwicm93XCIgZGF0YS1vcHRpb249XCJkb3duXCIgY2xhc3M9XCJzZS1idG4gc2UtdG9vbHRpcCBfc2VfdGFibGVfaW5zZXJ0X3Jvd19iXCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgaWNvbnMuaW5zZXJ0X3Jvd19iZWxvdyArXHJcbiAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcuY29udHJvbGxlci5pbnNlcnRSb3dCZWxvdyArICc8L3NwYW4+PC9zcGFuPicgK1xyXG4gICAgICAgICAgICAgICAgJzwvYnV0dG9uPicgK1xyXG4gICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtY29tbWFuZD1cImRlbGV0ZVwiIGRhdGEtdmFsdWU9XCJyb3dcIiBjbGFzcz1cInNlLWJ0biBzZS10b29sdGlwXCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgaWNvbnMuZGVsZXRlX3JvdyArXHJcbiAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcuY29udHJvbGxlci5kZWxldGVSb3cgKyAnPC9zcGFuPjwvc3Bhbj4nICtcclxuICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcclxuICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJtZXJnZVwiIGNsYXNzPVwiX3NlX3RhYmxlX21lcmdlX2J1dHRvbiBzZS1idG4gc2UtdG9vbHRpcFwiIGRpc2FibGVkPicgK1xyXG4gICAgICAgICAgICAgICAgICAgIGljb25zLm1lcmdlX2NlbGwgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIubWVyZ2VDZWxscyArICc8L3NwYW4+PC9zcGFuPicgK1xyXG4gICAgICAgICAgICAgICAgJzwvYnV0dG9uPicgK1xyXG4gICAgICAgICAgICAnPC9kaXY+JyArXHJcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtYnRuLWdyb3VwXCIgc3R5bGU9XCJwYWRkaW5nLXRvcDogMDtcIj4nICtcclxuICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJpbnNlcnRcIiBkYXRhLXZhbHVlPVwiY2VsbFwiIGRhdGEtb3B0aW9uPVwibGVmdFwiIGNsYXNzPVwic2UtYnRuIHNlLXRvb2x0aXBcIj4nICtcclxuICAgICAgICAgICAgICAgICAgICBpY29ucy5pbnNlcnRfY29sdW1uX2xlZnQgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIuaW5zZXJ0Q29sdW1uQmVmb3JlICsgJzwvc3Bhbj48L3NwYW4+JyArXHJcbiAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXHJcbiAgICAgICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1jb21tYW5kPVwiaW5zZXJ0XCIgZGF0YS12YWx1ZT1cImNlbGxcIiBkYXRhLW9wdGlvbj1cInJpZ2h0XCIgY2xhc3M9XCJzZS1idG4gc2UtdG9vbHRpcFwiPicgK1xyXG4gICAgICAgICAgICAgICAgICAgIGljb25zLmluc2VydF9jb2x1bW5fcmlnaHQgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIuaW5zZXJ0Q29sdW1uQWZ0ZXIgKyAnPC9zcGFuPjwvc3Bhbj4nICtcclxuICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcclxuICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJkZWxldGVcIiBkYXRhLXZhbHVlPVwiY2VsbFwiIGNsYXNzPVwic2UtYnRuIHNlLXRvb2x0aXBcIj4nICtcclxuICAgICAgICAgICAgICAgICAgICBpY29ucy5kZWxldGVfY29sdW1uICtcclxuICAgICAgICAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJzZS10b29sdGlwLWlubmVyXCI+PHNwYW4gY2xhc3M9XCJzZS10b29sdGlwLXRleHRcIj4nICsgbGFuZy5jb250cm9sbGVyLmRlbGV0ZUNvbHVtbiArICc8L3NwYW4+PC9zcGFuPicgK1xyXG4gICAgICAgICAgICAgICAgJzwvYnV0dG9uPicgK1xyXG4gICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtY29tbWFuZD1cIm9uc3BsaXRcIiBjbGFzcz1cIl9zZV90YWJsZV9zcGxpdF9idXR0b24gc2UtYnRuIHNlLXRvb2x0aXBcIj4nICtcclxuICAgICAgICAgICAgICAgICAgICBpY29ucy5zcGxpdF9jZWxsICtcclxuICAgICAgICAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJzZS10b29sdGlwLWlubmVyXCI+PHNwYW4gY2xhc3M9XCJzZS10b29sdGlwLXRleHRcIj4nICsgbGFuZy5jb250cm9sbGVyLnNwbGl0Q2VsbHMgKyAnPC9zcGFuPjwvc3Bhbj4nICtcclxuICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcclxuICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtYnRuLWdyb3VwLXN1YiBzdW4tZWRpdG9yLWNvbW1vbiBzZS1saXN0LWxheWVyXCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1saXN0LWlubmVyXCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICc8dWwgY2xhc3M9XCJzZS1saXN0LWJhc2ljXCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGxpIGNsYXNzPVwic2UtYnRuLWxpc3RcIiBkYXRhLWNvbW1hbmQ9XCJzcGxpdFwiIGRhdGEtdmFsdWU9XCJ2ZXJ0aWNhbFwiIHN0eWxlPVwibGluZS1oZWlnaHQ6MzJweDtcIiB0aXRsZT1cIicgKyBsYW5nLmNvbnRyb2xsZXIuVmVydGljYWxTcGxpdCArICdcIj4nICsgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFuZy5jb250cm9sbGVyLlZlcnRpY2FsU3BsaXQgKyAnPC9saT4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8bGkgY2xhc3M9XCJzZS1idG4tbGlzdFwiIGRhdGEtY29tbWFuZD1cInNwbGl0XCIgZGF0YS12YWx1ZT1cImhvcml6b250YWxcIiBzdHlsZT1cImxpbmUtaGVpZ2h0OjMycHg7XCIgdGl0bGU9XCInICsgbGFuZy5jb250cm9sbGVyLkhvcml6b250YWxTcGxpdCArICdcIj4nICsgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFuZy5jb250cm9sbGVyLkhvcml6b250YWxTcGxpdCArICc8L2xpPicgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAnPC91bD4nICtcclxuICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JyArXHJcbiAgICAgICAgICAgICAgICAnPC9kaXY+JyArXHJcbiAgICAgICAgICAgICc8L2Rpdj4nO1xyXG5cclxuICAgICAgICByZXR1cm4gdGFibGVSZXNpemU7XHJcbiAgICB9LFxyXG5cclxuICAgIGFwcGVuZFRhYmxlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgY29uc3Qgb1RhYmxlID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ1RBQkxFJyk7XHJcbiAgICAgICAgY29uc3QgY3JlYXRlQ2VsbHMgPSB0aGlzLnBsdWdpbnMudGFibGUuY3JlYXRlQ2VsbHM7XHJcblxyXG4gICAgICAgIGNvbnN0IHggPSB0aGlzLmNvbnRleHQudGFibGUuX3RhYmxlWFlbMF07XHJcbiAgICAgICAgbGV0IHkgPSB0aGlzLmNvbnRleHQudGFibGUuX3RhYmxlWFlbMV07XHJcbiAgICAgICAgbGV0IHRhYmxlSFRNTCA9ICc8dGJvZHk+JztcclxuICAgICAgICB3aGlsZSAoeSA+IDApIHtcclxuICAgICAgICAgICAgdGFibGVIVE1MICs9ICc8dHI+JyArIGNyZWF0ZUNlbGxzLmNhbGwodGhpcywgJ3RkJywgeCkgKyAnPC90cj4nO1xyXG4gICAgICAgICAgICAtLXk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRhYmxlSFRNTCArPSAnPC90Ym9keT4nO1xyXG4gICAgICAgIG9UYWJsZS5pbm5lckhUTUwgPSB0YWJsZUhUTUw7XHJcblxyXG4gICAgICAgIGNvbnN0IGNoYW5nZWQgPSB0aGlzLmluc2VydENvbXBvbmVudChvVGFibGUsIGZhbHNlLCB0cnVlLCBmYWxzZSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKGNoYW5nZWQpIHtcclxuICAgICAgICAgICAgY29uc3QgZmlyc3RUZCA9IG9UYWJsZS5xdWVyeVNlbGVjdG9yKCd0ZCBkaXYnKTtcclxuICAgICAgICAgICAgdGhpcy5zZXRSYW5nZShmaXJzdFRkLCAwLCBmaXJzdFRkLCAwKTtcclxuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnRhYmxlLnJlc2V0X3RhYmxlX3BpY2tlci5jYWxsKHRoaXMpO1xyXG4gICAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgY3JlYXRlQ2VsbHM6IGZ1bmN0aW9uIChub2RlTmFtZSwgY250LCByZXR1cm5FbGVtZW50KSB7XHJcbiAgICAgICAgbm9kZU5hbWUgPSBub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xyXG5cclxuICAgICAgICBpZiAoIXJldHVybkVsZW1lbnQpIHtcclxuICAgICAgICAgICAgbGV0IGNlbGxzSFRNTCA9ICcnO1xyXG4gICAgICAgICAgICB3aGlsZSAoY250ID4gMCkge1xyXG4gICAgICAgICAgICAgICAgY2VsbHNIVE1MICs9ICc8JyArbm9kZU5hbWUgKyAnPjxkaXY+PGJyPjwvZGl2PjwvJyArIG5vZGVOYW1lICsgJz4nO1xyXG4gICAgICAgICAgICAgICAgY250LS07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGNlbGxzSFRNTDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBjZWxsID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQobm9kZU5hbWUpO1xyXG4gICAgICAgICAgICBjZWxsLmlubmVySFRNTCA9ICc8ZGl2Pjxicj48L2Rpdj4nO1xyXG4gICAgICAgICAgICByZXR1cm4gY2VsbDtcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIG9uTW91c2VNb3ZlX3RhYmxlUGlja2VyOiBmdW5jdGlvbiAoY29udGV4dFRhYmxlLCBlKSB7XHJcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHJcbiAgICAgICAgbGV0IHggPSB0aGlzLl93Lk1hdGguY2VpbChlLm9mZnNldFggLyAxOCk7XHJcbiAgICAgICAgbGV0IHkgPSB0aGlzLl93Lk1hdGguY2VpbChlLm9mZnNldFkgLyAxOCk7XHJcbiAgICAgICAgeCA9IHggPCAxID8gMSA6IHg7XHJcbiAgICAgICAgeSA9IHkgPCAxID8gMSA6IHk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKGNvbnRleHRUYWJsZS5fcnRsKSB7XHJcbiAgICAgICAgICAgIGNvbnRleHRUYWJsZS50YWJsZUhpZ2hsaWdodC5zdHlsZS5sZWZ0ID0gKHggKiAxOCAtIDEzKSArICdweCc7XHJcbiAgICAgICAgICAgIHggPSAxMSAtIHg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIGNvbnRleHRUYWJsZS50YWJsZUhpZ2hsaWdodC5zdHlsZS53aWR0aCA9IHggKyAnZW0nO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS50YWJsZUhpZ2hsaWdodC5zdHlsZS5oZWlnaHQgPSB5ICsgJ2VtJztcclxuXHJcbiAgICAgICAgLy8gbGV0IHhfdSA9IHggPCA1ID8gNSA6ICh4ID4gOSA/IDEwIDogeCArIDEpO1xyXG4gICAgICAgIC8vIGxldCB5X3UgPSB5IDwgNSA/IDUgOiAoeSA+IDkgPyAxMCA6IHkgKyAxKTtcclxuICAgICAgICAvLyBjb250ZXh0VGFibGUudGFibGVVbkhpZ2hsaWdodC5zdHlsZS53aWR0aCA9IHhfdSArICdlbSc7XHJcbiAgICAgICAgLy8gY29udGV4dFRhYmxlLnRhYmxlVW5IaWdobGlnaHQuc3R5bGUuaGVpZ2h0ID0geV91ICsgJ2VtJztcclxuXHJcbiAgICAgICAgdGhpcy51dGlsLmNoYW5nZVR4dChjb250ZXh0VGFibGUudGFibGVEaXNwbGF5LCB4ICsgJyB4ICcgKyB5KTtcclxuICAgICAgICBjb250ZXh0VGFibGUuX3RhYmxlWFkgPSBbeCwgeV07XHJcbiAgICB9LFxyXG5cclxuICAgIHJlc2V0X3RhYmxlX3BpY2tlcjogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5jb250ZXh0LnRhYmxlLnRhYmxlSGlnaGxpZ2h0KSByZXR1cm47XHJcblxyXG4gICAgICAgIGNvbnN0IGhpZ2hsaWdodCA9IHRoaXMuY29udGV4dC50YWJsZS50YWJsZUhpZ2hsaWdodC5zdHlsZTtcclxuICAgICAgICBjb25zdCB1bkhpZ2hsaWdodCA9IHRoaXMuY29udGV4dC50YWJsZS50YWJsZVVuSGlnaGxpZ2h0LnN0eWxlO1xyXG5cclxuICAgICAgICBoaWdobGlnaHQud2lkdGggPSAnMWVtJztcclxuICAgICAgICBoaWdobGlnaHQuaGVpZ2h0ID0gJzFlbSc7XHJcbiAgICAgICAgdW5IaWdobGlnaHQud2lkdGggPSAnMTBlbSc7XHJcbiAgICAgICAgdW5IaWdobGlnaHQuaGVpZ2h0ID0gJzEwZW0nO1xyXG5cclxuICAgICAgICB0aGlzLnV0aWwuY2hhbmdlVHh0KHRoaXMuY29udGV4dC50YWJsZS50YWJsZURpc3BsYXksICcxIHggMScpO1xyXG4gICAgICAgIHRoaXMuc3VibWVudU9mZigpO1xyXG4gICAgfSxcclxuXHJcbiAgICBpbml0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgY29uc3QgY29udGV4dFRhYmxlID0gdGhpcy5jb250ZXh0LnRhYmxlO1xyXG4gICAgICAgIGNvbnN0IHRhYmxlUGx1Z2luID0gdGhpcy5wbHVnaW5zLnRhYmxlO1xyXG5cclxuICAgICAgICB0YWJsZVBsdWdpbi5fcmVtb3ZlRXZlbnRzLmNhbGwodGhpcyk7XHJcblxyXG4gICAgICAgIGlmICh0YWJsZVBsdWdpbi5fc2VsZWN0ZWRUYWJsZSkge1xyXG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZENlbGxzID0gdGFibGVQbHVnaW4uX3NlbGVjdGVkVGFibGUucXVlcnlTZWxlY3RvckFsbCgnLnNlLXRhYmxlLXNlbGVjdGVkLWNlbGwnKTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHNlbGVjdGVkQ2VsbHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudXRpbC5yZW1vdmVDbGFzcyhzZWxlY3RlZENlbGxzW2ldLCAnc2UtdGFibGUtc2VsZWN0ZWQtY2VsbCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0YWJsZVBsdWdpbi5fdG9nZ2xlRWRpdG9yLmNhbGwodGhpcywgdHJ1ZSk7XHJcblxyXG4gICAgICAgIGNvbnRleHRUYWJsZS5fZWxlbWVudCA9IG51bGw7XHJcbiAgICAgICAgY29udGV4dFRhYmxlLl90ZEVsZW1lbnQgPSBudWxsO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS5fdHJFbGVtZW50ID0gbnVsbDtcclxuICAgICAgICBjb250ZXh0VGFibGUuX3RyRWxlbWVudHMgPSBudWxsO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS5fdGFibGVYWSA9IFtdO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS5fbWF4V2lkdGggPSB0cnVlO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS5fZml4ZWRDb2x1bW4gPSBmYWxzZTtcclxuICAgICAgICBjb250ZXh0VGFibGUuX3BoeXNpY2FsX2NlbGxDbnQgPSAwO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS5fbG9naWNhbF9jZWxsQ250ID0gMDtcclxuICAgICAgICBjb250ZXh0VGFibGUuX3Jvd0NudCA9IDA7XHJcbiAgICAgICAgY29udGV4dFRhYmxlLl9yb3dJbmRleCA9IDA7XHJcbiAgICAgICAgY29udGV4dFRhYmxlLl9waHlzaWNhbF9jZWxsSW5kZXggPSAwO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS5fbG9naWNhbF9jZWxsSW5kZXggPSAwO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS5fY3VycmVudF9jb2xTcGFuID0gMDtcclxuICAgICAgICBjb250ZXh0VGFibGUuX2N1cnJlbnRfcm93U3BhbiA9IDA7XHJcblxyXG4gICAgICAgIHRhYmxlUGx1Z2luLl9zaGlmdCA9IGZhbHNlO1xyXG4gICAgICAgIHRhYmxlUGx1Z2luLl9zZWxlY3RlZENlbGxzID0gbnVsbDtcclxuICAgICAgICB0YWJsZVBsdWdpbi5fc2VsZWN0ZWRUYWJsZSA9IG51bGw7XHJcbiAgICAgICAgdGFibGVQbHVnaW4uX3JlZiA9IG51bGw7XHJcblxyXG4gICAgICAgIHRhYmxlUGx1Z2luLl9maXhlZENlbGwgPSBudWxsO1xyXG4gICAgICAgIHRhYmxlUGx1Z2luLl9zZWxlY3RlZENlbGwgPSBudWxsO1xyXG4gICAgICAgIHRhYmxlUGx1Z2luLl9maXhlZENlbGxOYW1lID0gbnVsbDtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqIHRhYmxlIGVkaXQgY29udHJvbGxlciAqL1xyXG4gICAgY2FsbF9jb250cm9sbGVyX3RhYmxlRWRpdDogZnVuY3Rpb24gKHRkRWxlbWVudCkge1xyXG4gICAgICAgIGNvbnN0IHRhYmxlUGx1Z2luID0gdGhpcy5wbHVnaW5zLnRhYmxlO1xyXG4gICAgICAgIGNvbnN0IGNvbnRleHRUYWJsZSA9IHRoaXMuY29udGV4dC50YWJsZTtcclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLmdldFNlbGVjdGlvbigpLmlzQ29sbGFwc2VkICYmICF0YWJsZVBsdWdpbi5fc2VsZWN0ZWRDZWxsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29udHJvbGxlcnNPZmYoKTtcclxuICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUNsYXNzKHRkRWxlbWVudCwgJ3NlLXRhYmxlLXNlbGVjdGVkLWNlbGwnKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgdGFibGVFbGVtZW50ID0gY29udGV4dFRhYmxlLl9lbGVtZW50IHx8IHRoaXMucGx1Z2lucy50YWJsZS5fc2VsZWN0ZWRUYWJsZSB8fCB0aGlzLnV0aWwuZ2V0UGFyZW50RWxlbWVudCh0ZEVsZW1lbnQsICdUQUJMRScpO1xyXG4gICAgICAgIGNvbnRleHRUYWJsZS5fbWF4V2lkdGggPSB0aGlzLnV0aWwuaGFzQ2xhc3ModGFibGVFbGVtZW50LCAnc2UtdGFibGUtc2l6ZS0xMDAnKSB8fCB0YWJsZUVsZW1lbnQuc3R5bGUud2lkdGggPT09ICcxMDAlJyB8fCAoIXRhYmxlRWxlbWVudC5zdHlsZS53aWR0aCAmJiAhdGhpcy51dGlsLmhhc0NsYXNzKHRhYmxlRWxlbWVudCwgJ3NlLXRhYmxlLXNpemUtYXV0bycpKTtcclxuICAgICAgICBjb250ZXh0VGFibGUuX2ZpeGVkQ29sdW1uID0gdGhpcy51dGlsLmhhc0NsYXNzKHRhYmxlRWxlbWVudCwgJ3NlLXRhYmxlLWxheW91dC1maXhlZCcpIHx8IHRhYmxlRWxlbWVudC5zdHlsZS50YWJsZUxheW91dCA9PT0gJ2ZpeGVkJztcclxuICAgICAgICB0YWJsZVBsdWdpbi5zZXRUYWJsZVN0eWxlLmNhbGwodGhpcywgY29udGV4dFRhYmxlLl9tYXhXaWR0aCA/ICd3aWR0aHxjb2x1bW4nIDogJ3dpZHRoJyk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdGFibGVQbHVnaW4uc2V0UG9zaXRpb25Db250cm9sbGVyVG9wLmNhbGwodGhpcywgdGFibGVFbGVtZW50KTtcclxuICAgICAgICB0YWJsZVBsdWdpbi5zZXRQb3NpdGlvbkNvbnRyb2xsZXJEaXYuY2FsbCh0aGlzLCB0ZEVsZW1lbnQsIHRhYmxlUGx1Z2luLl9zaGlmdCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKCF0YWJsZVBsdWdpbi5fc2hpZnQpIHRoaXMuY29udHJvbGxlcnNPbihjb250ZXh0VGFibGUucmVzaXplRGl2LCBjb250ZXh0VGFibGUudGFibGVDb250cm9sbGVyLCB0YWJsZVBsdWdpbi5pbml0LmJpbmQodGhpcyksIHRkRWxlbWVudCwgJ3RhYmxlJyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHNldFBvc2l0aW9uQ29udHJvbGxlclRvcDogZnVuY3Rpb24gKHRhYmxlRWxlbWVudCkge1xyXG4gICAgICAgIHRoaXMuc2V0Q29udHJvbGxlclBvc2l0aW9uKHRoaXMuY29udGV4dC50YWJsZS50YWJsZUNvbnRyb2xsZXIsIHRhYmxlRWxlbWVudCwgJ3RvcCcsIHtsZWZ0OiAwLCB0b3A6IDB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0UG9zaXRpb25Db250cm9sbGVyRGl2OiBmdW5jdGlvbiAodGRFbGVtZW50LCByZXNldCkge1xyXG4gICAgICAgIGNvbnN0IGNvbnRleHRUYWJsZSA9IHRoaXMuY29udGV4dC50YWJsZTtcclxuICAgICAgICBjb25zdCByZXNpemVEaXYgPSBjb250ZXh0VGFibGUucmVzaXplRGl2O1xyXG4gICAgICAgIFxyXG4gICAgICAgIHRoaXMucGx1Z2lucy50YWJsZS5zZXRDZWxsSW5mby5jYWxsKHRoaXMsIHRkRWxlbWVudCwgcmVzZXQpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmIChjb250ZXh0VGFibGUuY2VsbENvbnRyb2xsZXJUb3ApIHtcclxuICAgICAgICAgICAgdGhpcy5zZXRDb250cm9sbGVyUG9zaXRpb24ocmVzaXplRGl2LCBjb250ZXh0VGFibGUuX2VsZW1lbnQsICd0b3AnLCB7bGVmdDogY29udGV4dFRhYmxlLnRhYmxlQ29udHJvbGxlci5vZmZzZXRXaWR0aCwgdG9wOiAwfSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5zZXRDb250cm9sbGVyUG9zaXRpb24ocmVzaXplRGl2LCB0ZEVsZW1lbnQsICdib3R0b20nLCB7bGVmdDogMCwgdG9wOiAwfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBzZXRDZWxsSW5mbzogZnVuY3Rpb24gKHRkRWxlbWVudCwgcmVzZXQpIHtcclxuICAgICAgICBjb25zdCBjb250ZXh0VGFibGUgPSB0aGlzLmNvbnRleHQudGFibGU7XHJcbiAgICAgICAgY29uc3QgdGFibGUgPSBjb250ZXh0VGFibGUuX2VsZW1lbnQgPSB0aGlzLnBsdWdpbnMudGFibGUuX3NlbGVjdGVkVGFibGUgfHwgdGhpcy51dGlsLmdldFBhcmVudEVsZW1lbnQodGRFbGVtZW50LCAnVEFCTEUnKTtcclxuXHJcbiAgICAgICAgaWYgKC9USEVBRC9pLnRlc3QodGFibGUuZmlyc3RFbGVtZW50Q2hpbGQubm9kZU5hbWUpKSB7XHJcbiAgICAgICAgICAgIHRoaXMudXRpbC5hZGRDbGFzcyhjb250ZXh0VGFibGUuaGVhZGVyQnV0dG9uLCAnYWN0aXZlJyk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUNsYXNzKGNvbnRleHRUYWJsZS5oZWFkZXJCdXR0b24sICdhY3RpdmUnKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChyZXNldCB8fCBjb250ZXh0VGFibGUuX3BoeXNpY2FsX2NlbGxDbnQgPT09IDApIHtcclxuICAgICAgICAgICAgaWYgKGNvbnRleHRUYWJsZS5fdGRFbGVtZW50ICE9PSB0ZEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRleHRUYWJsZS5fdGRFbGVtZW50ID0gdGRFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgY29udGV4dFRhYmxlLl90ckVsZW1lbnQgPSB0ZEVsZW1lbnQucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3Qgcm93cyA9IGNvbnRleHRUYWJsZS5fdHJFbGVtZW50cyA9IHRhYmxlLnJvd3M7XHJcbiAgICAgICAgICAgIGNvbnN0IGNlbGxJbmRleCA9IHRkRWxlbWVudC5jZWxsSW5kZXg7XHJcblxyXG4gICAgICAgICAgICBsZXQgY2VsbENudCA9IDA7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBjZWxscyA9IHJvd3NbMF0uY2VsbHMsIGxlbiA9IHJvd3NbMF0uY2VsbHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGNlbGxDbnQgKz0gY2VsbHNbaV0uY29sU3BhbjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gcm93IGNudCwgcm93IGluZGV4XHJcbiAgICAgICAgICAgIGNvbnN0IHJvd0luZGV4ID0gY29udGV4dFRhYmxlLl9yb3dJbmRleCA9IGNvbnRleHRUYWJsZS5fdHJFbGVtZW50LnJvd0luZGV4O1xyXG4gICAgICAgICAgICBjb250ZXh0VGFibGUuX3Jvd0NudCA9IHJvd3MubGVuZ3RoO1xyXG5cclxuICAgICAgICAgICAgLy8gY2VsbCBjbnQsIHBoeXNpY2FsIGNlbGwgaW5kZXhcclxuICAgICAgICAgICAgY29udGV4dFRhYmxlLl9waHlzaWNhbF9jZWxsQ250ID0gY29udGV4dFRhYmxlLl90ckVsZW1lbnQuY2VsbHMubGVuZ3RoO1xyXG4gICAgICAgICAgICBjb250ZXh0VGFibGUuX2xvZ2ljYWxfY2VsbENudCA9IGNlbGxDbnQ7XHJcbiAgICAgICAgICAgIGNvbnRleHRUYWJsZS5fcGh5c2ljYWxfY2VsbEluZGV4ID0gY2VsbEluZGV4O1xyXG5cclxuICAgICAgICAgICAgLy8gc3BhblxyXG4gICAgICAgICAgICBjb250ZXh0VGFibGUuX2N1cnJlbnRfY29sU3BhbiA9IGNvbnRleHRUYWJsZS5fdGRFbGVtZW50LmNvbFNwYW4gLSAxO1xyXG4gICAgICAgICAgICBjb250ZXh0VGFibGUuX2N1cnJlbnRfcm93U3BhbiAtIGNvbnRleHRUYWJsZS5fdHJFbGVtZW50LmNlbGxzW2NlbGxJbmRleF0ucm93U3BhbiAtIDE7XHJcblxyXG4gICAgICAgICAgICAvLyBmaW5kIGxvZ2NhbCBjZWxsIGluZGV4XHJcbiAgICAgICAgICAgIGxldCByb3dTcGFuQXJyID0gW107XHJcbiAgICAgICAgICAgIGxldCBzcGFuSW5kZXggPSBbXTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGNlbGxzLCBjb2xTcGFuOyBpIDw9IHJvd0luZGV4OyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGNlbGxzID0gcm93c1tpXS5jZWxscztcclxuICAgICAgICAgICAgICAgIGNvbFNwYW4gPSAwO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgYyA9IDAsIGNMZW4gPSBjZWxscy5sZW5ndGgsIGNlbGwsIGNzLCBycywgbG9nY2FsSW5kZXg7IGMgPCBjTGVuOyBjKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBjZWxsID0gY2VsbHNbY107XHJcbiAgICAgICAgICAgICAgICAgICAgY3MgPSBjZWxsLmNvbFNwYW4gLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gY2VsbC5yb3dTcGFuIC0gMTtcclxuICAgICAgICAgICAgICAgICAgICBsb2djYWxJbmRleCA9IGMgKyBjb2xTcGFuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc3BhbkluZGV4Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgciA9IDAsIGFycjsgciA8IHNwYW5JbmRleC5sZW5ndGg7IHIrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyID0gc3BhbkluZGV4W3JdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyci5yb3cgPiBpKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb2djYWxJbmRleCA+PSBhcnIuaW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xTcGFuICs9IGFyci5jcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2djYWxJbmRleCArPSBhcnIuY3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyLnJzIC09IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyLnJvdyA9IGkgKyAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcnIucnMgPCAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYW5JbmRleC5zcGxpY2UociwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHItLTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PT0gY0xlbiAtIDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucnMgLT0gMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucm93ID0gaSArIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyci5ycyA8IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BhbkluZGV4LnNwbGljZShyLCAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgci0tO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gbG9nY2FsIGNlbGwgaW5kZXhcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PT0gcm93SW5kZXggJiYgYyA9PT0gY2VsbEluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHRUYWJsZS5fbG9naWNhbF9jZWxsSW5kZXggPSBsb2djYWxJbmRleDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAocnMgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJvd1NwYW5BcnIucHVzaCh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleDogbG9nY2FsSW5kZXgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjczogY3MgKyAxLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcnM6IHJzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcm93OiAtMVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgY29sU3BhbiArPSBjcztcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBzcGFuSW5kZXggPSBzcGFuSW5kZXguY29uY2F0KHJvd1NwYW5BcnIpLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtyZXR1cm4gYS5pbmRleCAtIGIuaW5kZXg7fSk7XHJcbiAgICAgICAgICAgICAgICByb3dTcGFuQXJyID0gW107XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJvd1NwYW5BcnIgPSBudWxsO1xyXG4gICAgICAgICAgICBzcGFuSW5kZXggPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgZWRpdFRhYmxlOiBmdW5jdGlvbiAodHlwZSwgb3B0aW9uKSB7XHJcbiAgICAgICAgY29uc3QgdGFibGVQbHVnaW4gPSB0aGlzLnBsdWdpbnMudGFibGU7XHJcbiAgICAgICAgY29uc3QgY29udGV4dFRhYmxlID0gdGhpcy5jb250ZXh0LnRhYmxlO1xyXG4gICAgICAgIGNvbnN0IHRhYmxlID0gY29udGV4dFRhYmxlLl9lbGVtZW50O1xyXG4gICAgICAgIGNvbnN0IGlzUm93ID0gdHlwZSA9PT0gJ3Jvdyc7XHJcblxyXG4gICAgICAgIGlmIChpc1Jvdykge1xyXG4gICAgICAgICAgICBjb25zdCB0YWJsZUF0dHIgPSBjb250ZXh0VGFibGUuX3RyRWxlbWVudC5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICBpZiAoL15USEVBRCQvaS50ZXN0KHRhYmxlQXR0ci5ub2RlTmFtZSkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChvcHRpb24gPT09ICd1cCcpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCF0YWJsZUF0dHIubmV4dEVsZW1lbnRTaWJsaW5nIHx8ICEvXlRCT0RZJC9pLnRlc3QodGFibGVBdHRyLm5leHRFbGVtZW50U2libGluZy5ub2RlTmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0YWJsZS5pbm5lckhUTUwgKz0gJzx0Ym9keT48dHI+JyArIHRhYmxlUGx1Z2luLmNyZWF0ZUNlbGxzLmNhbGwodGhpcywgJ3RkJywgY29udGV4dFRhYmxlLl9sb2dpY2FsX2NlbGxDbnQsIGZhbHNlKSArICc8L3RyPjwvdGJvZHk+JztcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIG11bHRpXHJcbiAgICAgICAgaWYgKHRhYmxlUGx1Z2luLl9yZWYpIHtcclxuICAgICAgICAgICAgY29uc3QgcG9zaXRpb25DZWxsID0gY29udGV4dFRhYmxlLl90ZEVsZW1lbnQ7XHJcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkQ2VsbHMgPSB0YWJsZVBsdWdpbi5fc2VsZWN0ZWRDZWxscztcclxuICAgICAgICAgICAgLy8gbXVsdGkgLSByb3dcclxuICAgICAgICAgICAgaWYgKGlzUm93KSB7XHJcbiAgICAgICAgICAgICAgICAvLyByZW1vdmUgcm93XHJcbiAgICAgICAgICAgICAgICBpZiAoIW9wdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCByb3cgPSBzZWxlY3RlZENlbGxzWzBdLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVtb3ZlQ2VsbHMgPSBbc2VsZWN0ZWRDZWxsc1swXV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAxLCBsZW4gPSBzZWxlY3RlZENlbGxzLmxlbmd0aCwgY2VsbDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwgPSBzZWxlY3RlZENlbGxzW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocm93ICE9PSBjZWxsLnBhcmVudE5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNlbGxzLnB1c2goY2VsbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3cgPSBjZWxsLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSByZW1vdmVDZWxscy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0YWJsZVBsdWdpbi5zZXRDZWxsSW5mby5jYWxsKHRoaXMsIHJlbW92ZUNlbGxzW2ldLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVQbHVnaW4uZWRpdFJvdy5jYWxsKHRoaXMsIG9wdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gZWRpdCByb3dcclxuICAgICAgICAgICAgICAgICAgICB0YWJsZVBsdWdpbi5zZXRDZWxsSW5mby5jYWxsKHRoaXMsIG9wdGlvbiA9PT0gJ3VwJyA/IHNlbGVjdGVkQ2VsbHNbMF0gOiBzZWxlY3RlZENlbGxzW3NlbGVjdGVkQ2VsbHMubGVuZ3RoIC0gMV0sIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRhYmxlUGx1Z2luLmVkaXRSb3cuY2FsbCh0aGlzLCBvcHRpb24sIHBvc2l0aW9uQ2VsbCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7IC8vIG11bHRpIC0gY2VsbFxyXG4gICAgICAgICAgICAgICAgY29uc3QgZmlyc3RSb3cgPSBzZWxlY3RlZENlbGxzWzBdLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAvLyByZW1vdmUgY2VsbFxyXG4gICAgICAgICAgICAgICAgaWYgKCFvcHRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZW1vdmVDZWxscyA9IFtzZWxlY3RlZENlbGxzWzBdXTtcclxuICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMSwgbGVuID0gc2VsZWN0ZWRDZWxscy5sZW5ndGgsIGNlbGw7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjZWxsID0gc2VsZWN0ZWRDZWxsc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpcnN0Um93ID09PSBjZWxsLnBhcmVudE5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNlbGxzLnB1c2goY2VsbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHJlbW92ZUNlbGxzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlUGx1Z2luLnNldENlbGxJbmZvLmNhbGwodGhpcywgcmVtb3ZlQ2VsbHNbaV0sIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0YWJsZVBsdWdpbi5lZGl0Q2VsbC5jYWxsKHRoaXMsIG9wdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gZWRpdCBjZWxsXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJpZ2h0Q2VsbCA9IG51bGw7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBzZWxlY3RlZENlbGxzLmxlbmd0aCAtIDE7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlyc3RSb3cgIT09IHNlbGVjdGVkQ2VsbHNbaSArIDFdLnBhcmVudE5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0Q2VsbCA9IHNlbGVjdGVkQ2VsbHNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGFibGVQbHVnaW4uc2V0Q2VsbEluZm8uY2FsbCh0aGlzLCBvcHRpb24gPT09ICdsZWZ0JyA/IHNlbGVjdGVkQ2VsbHNbMF0gOiByaWdodENlbGwgfHwgc2VsZWN0ZWRDZWxsc1swXSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGFibGVQbHVnaW4uZWRpdENlbGwuY2FsbCh0aGlzLCBvcHRpb24sIHBvc2l0aW9uQ2VsbCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghb3B0aW9uKSB0YWJsZVBsdWdpbi5pbml0LmNhbGwodGhpcyk7XHJcbiAgICAgICAgfSAvLyBvbmVcclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGFibGVQbHVnaW5baXNSb3cgPyAnZWRpdFJvdycgOiAnZWRpdENlbGwnXS5jYWxsKHRoaXMsIG9wdGlvbik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBhZnRlciByZW1vdmVcclxuICAgICAgICBpZiAoIW9wdGlvbikge1xyXG4gICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IHRhYmxlLmNoaWxkcmVuO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGRyZW5baV0uY2hpbGRyZW4ubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUl0ZW0oY2hpbGRyZW5baV0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGktLTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHRhYmxlLmNoaWxkcmVuLmxlbmd0aCA9PT0gMCkgdGhpcy51dGlsLnJlbW92ZUl0ZW0odGFibGUpO1xyXG4gICAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgZWRpdFJvdzogZnVuY3Rpb24gKG9wdGlvbiwgcG9zaXRpb25SZXNldEVsZW1lbnQpIHtcclxuICAgICAgICBjb25zdCBjb250ZXh0VGFibGUgPSB0aGlzLmNvbnRleHQudGFibGU7XHJcbiAgICAgICAgY29uc3QgcmVtb3ZlID0gIW9wdGlvbjtcclxuXHJcbiAgICAgICAgY29uc3QgdXAgPSBvcHRpb24gPT09ICd1cCc7XHJcbiAgICAgICAgY29uc3Qgb3JpZ2luUm93SW5kZXggPSBjb250ZXh0VGFibGUuX3Jvd0luZGV4O1xyXG4gICAgICAgIGNvbnN0IHJvd0luZGV4ID0gcmVtb3ZlIHx8IHVwID8gb3JpZ2luUm93SW5kZXggOiBvcmlnaW5Sb3dJbmRleCArIGNvbnRleHRUYWJsZS5fY3VycmVudF9yb3dTcGFuICsgMTtcclxuICAgICAgICBjb25zdCBzaWduID0gcmVtb3ZlID8gLTEgOiAxO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGNvbnN0IHJvd3MgPSBjb250ZXh0VGFibGUuX3RyRWxlbWVudHM7XHJcbiAgICAgICAgbGV0IGNlbGxDbnQgPSBjb250ZXh0VGFibGUuX2xvZ2ljYWxfY2VsbENudDtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IG9yaWdpblJvd0luZGV4ICsgKHJlbW92ZSA/IC0xIDogMCksIGNlbGw7IGkgPD0gbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgY2VsbCA9IHJvd3NbaV0uY2VsbHM7XHJcbiAgICAgICAgICAgIGlmIChjZWxsLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgZm9yIChsZXQgYyA9IDAsIGNMZW4gPSBjZWxsLmxlbmd0aCwgcnMsIGNzOyBjIDwgY0xlbjsgYysrKSB7XHJcbiAgICAgICAgICAgICAgICBycyA9IGNlbGxbY10ucm93U3BhbjtcclxuICAgICAgICAgICAgICAgIGNzID0gY2VsbFtjXS5jb2xTcGFuO1xyXG4gICAgICAgICAgICAgICAgaWYgKHJzIDwgMiAmJiBjcyA8IDIpIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChycyArIGkgPiByb3dJbmRleCAmJiByb3dJbmRleCA+IGkpIHtcclxuICAgICAgICAgICAgICAgICAgICBjZWxsW2NdLnJvd1NwYW4gPSBycyArIHNpZ247XHJcbiAgICAgICAgICAgICAgICAgICAgY2VsbENudCAtPSBjcztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHJlbW92ZSkge1xyXG4gICAgICAgICAgICBjb25zdCBuZXh0ID0gcm93c1tvcmlnaW5Sb3dJbmRleCArIDFdO1xyXG4gICAgICAgICAgICBpZiAobmV4dCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc3BhbkNlbGxzID0gW107XHJcbiAgICAgICAgICAgICAgICBsZXQgY2VsbHMgPSByb3dzW29yaWdpblJvd0luZGV4XS5jZWxscztcclxuICAgICAgICAgICAgICAgIGxldCBjb2xTcGFuID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gY2VsbHMubGVuZ3RoLCBjZWxsLCBsb2djYWxJbmRleDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2VsbCA9IGNlbGxzW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgIGxvZ2NhbEluZGV4ID0gaSArIGNvbFNwYW47XHJcbiAgICAgICAgICAgICAgICAgICAgY29sU3BhbiArPSBjZWxsLmNvbFNwYW4gLSAxO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2VsbC5yb3dTcGFuID4gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnJvd1NwYW4gLT0gMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3BhbkNlbGxzLnB1c2goe2NlbGw6IGNlbGwuY2xvbmVOb2RlKGZhbHNlKSwgaW5kZXg6IGxvZ2NhbEluZGV4fSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChzcGFuQ2VsbHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBzcGFuQ2VsbCA9IHNwYW5DZWxscy5zaGlmdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNlbGxzID0gbmV4dC5jZWxscztcclxuICAgICAgICAgICAgICAgICAgICBjb2xTcGFuID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNlbGxzLmxlbmd0aCwgY2VsbCwgbG9nY2FsSW5kZXg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjZWxsID0gY2VsbHNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2NhbEluZGV4ID0gaSArIGNvbFNwYW47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbFNwYW4gKz0gY2VsbC5jb2xTcGFuIC0gMTtcclxuICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobG9nY2FsSW5kZXggPj0gc3BhbkNlbGwuaW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGktLSwgY29sU3Bhbi0tO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sU3BhbiArPSBzcGFuQ2VsbC5jZWxsLmNvbFNwYW4gLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dC5pbnNlcnRCZWZvcmUoc3BhbkNlbGwuY2VsbCwgY2VsbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFuQ2VsbCA9IHNwYW5DZWxscy5zaGlmdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzcGFuQ2VsbCkgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzcGFuQ2VsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXh0LmFwcGVuZENoaWxkKHNwYW5DZWxsLmNlbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gc3BhbkNlbGxzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0LmFwcGVuZENoaWxkKHNwYW5DZWxsc1tpXS5jZWxsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29udGV4dFRhYmxlLl9lbGVtZW50LmRlbGV0ZVJvdyhyb3dJbmRleCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgbmV3Um93ID0gY29udGV4dFRhYmxlLl9lbGVtZW50Lmluc2VydFJvdyhyb3dJbmRleCk7XHJcbiAgICAgICAgICAgIG5ld1Jvdy5pbm5lckhUTUwgPSB0aGlzLnBsdWdpbnMudGFibGUuY3JlYXRlQ2VsbHMuY2FsbCh0aGlzLCAndGQnLCBjZWxsQ250LCBmYWxzZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXJlbW92ZSkge1xyXG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMudGFibGUuc2V0UG9zaXRpb25Db250cm9sbGVyRGl2LmNhbGwodGhpcywgcG9zaXRpb25SZXNldEVsZW1lbnQgfHwgY29udGV4dFRhYmxlLl90ZEVsZW1lbnQsIHRydWUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29udHJvbGxlcnNPZmYoKTtcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIGVkaXRDZWxsOiBmdW5jdGlvbiAob3B0aW9uLCBwb3NpdGlvblJlc2V0RWxlbWVudCkge1xyXG4gICAgICAgIGNvbnN0IGNvbnRleHRUYWJsZSA9IHRoaXMuY29udGV4dC50YWJsZTtcclxuICAgICAgICBjb25zdCB1dGlsID0gdGhpcy51dGlsO1xyXG4gICAgICAgIGNvbnN0IHJlbW92ZSA9ICFvcHRpb247XHJcblxyXG4gICAgICAgIGNvbnN0IGxlZnQgPSBvcHRpb24gPT09ICdsZWZ0JztcclxuICAgICAgICBjb25zdCBjb2xTcGFuID0gY29udGV4dFRhYmxlLl9jdXJyZW50X2NvbFNwYW47XHJcbiAgICAgICAgY29uc3QgY2VsbEluZGV4ID0gcmVtb3ZlIHx8IGxlZnQgPyBjb250ZXh0VGFibGUuX2xvZ2ljYWxfY2VsbEluZGV4IDogY29udGV4dFRhYmxlLl9sb2dpY2FsX2NlbGxJbmRleCArIGNvbFNwYW4gKyAxO1xyXG5cclxuICAgICAgICBjb25zdCByb3dzID0gY29udGV4dFRhYmxlLl90ckVsZW1lbnRzO1xyXG4gICAgICAgIGxldCByb3dTcGFuQXJyID0gW107XHJcbiAgICAgICAgbGV0IHNwYW5JbmRleCA9IFtdO1xyXG4gICAgICAgIGxldCBwYXNzQ2VsbCA9IDA7XHJcbiAgICAgICAgY29uc3QgcmVtb3ZlQ2VsbCA9IFtdO1xyXG4gICAgICAgIGNvbnN0IHJlbW92ZVNwYW5BcnIgPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNvbnRleHRUYWJsZS5fcm93Q250LCByb3csIGluc2VydEluZGV4LCBjZWxscywgbmV3Q2VsbCwgYXBwbHlTcGFuLCBjZWxsQ29sU3BhbjsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHJvdyA9IHJvd3NbaV07XHJcbiAgICAgICAgICAgIGluc2VydEluZGV4ID0gY2VsbEluZGV4O1xyXG4gICAgICAgICAgICBhcHBseVNwYW4gPSBmYWxzZTtcclxuICAgICAgICAgICAgY2VsbHMgPSByb3cuY2VsbHM7XHJcbiAgICAgICAgICAgIGNlbGxDb2xTcGFuID0gMDtcclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGMgPSAwLCBjZWxsLCBjTGVuID0gY2VsbHMubGVuZ3RoLCBycywgY3MsIHJlbW92ZUluZGV4OyBjIDwgY0xlbjsgYysrKSB7XHJcbiAgICAgICAgICAgICAgICBjZWxsID0gY2VsbHNbY107XHJcbiAgICAgICAgICAgICAgICBpZiAoIWNlbGwpIGJyZWFrO1xyXG5cclxuICAgICAgICAgICAgICAgIHJzID0gY2VsbC5yb3dTcGFuIC0gMTtcclxuICAgICAgICAgICAgICAgIGNzID0gY2VsbC5jb2xTcGFuIC0gMTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIXJlbW92ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjID49IGluc2VydEluZGV4KSBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY3MgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXNzQ2VsbCA8IDEgJiYgY3MgKyBjID49IGluc2VydEluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNvbFNwYW4gKz0gMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydEluZGV4ID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhc3NDZWxsID0gcnMgKyAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydEluZGV4IC09IGNzO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFhcHBseVNwYW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgciA9IDAsIGFycjsgciA8IHNwYW5JbmRleC5sZW5ndGg7IHIrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyID0gc3BhbkluZGV4W3JdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zZXJ0SW5kZXggLT0gYXJyLmNzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyLnJzIC09IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyLnJzIDwgMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYW5JbmRleC5zcGxpY2UociwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgci0tO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgYXBwbHlTcGFuID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZUluZGV4ID0gYyArIGNlbGxDb2xTcGFuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc3BhbkluZGV4Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbGFzdENlbGwgPSAhY2VsbHNbYyArIDFdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCByID0gMCwgYXJyOyByIDwgc3BhbkluZGV4Lmxlbmd0aDsgcisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIgPSBzcGFuSW5kZXhbcl07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyLnJvdyA+IGkpIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmVJbmRleCA+PSBhcnIuaW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsQ29sU3BhbiArPSBhcnIuY3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlSW5kZXggPSBjICsgY2VsbENvbFNwYW47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyLnJzIC09IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyLnJvdyA9IGkgKyAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcnIucnMgPCAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYW5JbmRleC5zcGxpY2UociwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHItLTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobGFzdENlbGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucnMgLT0gMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucm93ID0gaSArIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyci5ycyA8IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BhbkluZGV4LnNwbGljZShyLCAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgci0tO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJzID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByb3dTcGFuQXJyLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcnM6IHJzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3M6IGNzICsgMSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4OiByZW1vdmVJbmRleCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdzogLTFcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAocmVtb3ZlSW5kZXggPj0gaW5zZXJ0SW5kZXggJiYgcmVtb3ZlSW5kZXggKyBjcyA8PSBpbnNlcnRJbmRleCArIGNvbFNwYW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2VsbC5wdXNoKGNlbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVtb3ZlSW5kZXggPD0gaW5zZXJ0SW5kZXggKyBjb2xTcGFuICYmIHJlbW92ZUluZGV4ICsgY3MgPj0gaW5zZXJ0SW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jb2xTcGFuIC09IHV0aWwuZ2V0T3ZlcmxhcFJhbmdlQXRJbmRleChjZWxsSW5kZXgsIGNlbGxJbmRleCArIGNvbFNwYW4sIHJlbW92ZUluZGV4LCByZW1vdmVJbmRleCArIGNzKTsgXHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycyA+IDAgJiYgKHJlbW92ZUluZGV4IDwgaW5zZXJ0SW5kZXggfHwgcmVtb3ZlSW5kZXggKyBjcyA+IGluc2VydEluZGV4ICsgY29sU3BhbikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlU3BhbkFyci5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGw6IGNlbGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpOiBpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcnM6IGkgKyByc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNlbGxDb2xTcGFuICs9IGNzO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBzcGFuSW5kZXggPSBzcGFuSW5kZXguY29uY2F0KHJvd1NwYW5BcnIpLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtyZXR1cm4gYS5pbmRleCAtIGIuaW5kZXg7fSk7XHJcbiAgICAgICAgICAgIHJvd1NwYW5BcnIgPSBbXTtcclxuXHJcbiAgICAgICAgICAgIGlmICghcmVtb3ZlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocGFzc0NlbGwgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFzc0NlbGwgLT0gMTtcclxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoaW5zZXJ0SW5kZXggIT09IG51bGwgJiYgY2VsbHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG5ld0NlbGwgPSB0aGlzLnBsdWdpbnMudGFibGUuY3JlYXRlQ2VsbHMuY2FsbCh0aGlzLCBjZWxsc1swXS5ub2RlTmFtZSwgMCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3Q2VsbCA9IHJvdy5pbnNlcnRCZWZvcmUobmV3Q2VsbCwgY2VsbHNbaW5zZXJ0SW5kZXhdKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHJlbW92ZSkge1xyXG4gICAgICAgICAgICBsZXQgcmVtb3ZlRmlyc3QsIHJlbW92ZUVuZDtcclxuICAgICAgICAgICAgZm9yIChsZXQgciA9IDAsIHJMZW4gPSByZW1vdmVDZWxsLmxlbmd0aCwgcm93OyByIDwgckxlbjsgcisrKSB7XHJcbiAgICAgICAgICAgICAgICByb3cgPSByZW1vdmVDZWxsW3JdLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW0ocmVtb3ZlQ2VsbFtyXSk7XHJcbiAgICAgICAgICAgICAgICBpZiAocm93LmNlbGxzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghcmVtb3ZlRmlyc3QpIHJlbW92ZUZpcnN0ID0gdXRpbC5nZXRBcnJheUluZGV4KHJvd3MsIHJvdyk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlRW5kID0gdXRpbC5nZXRBcnJheUluZGV4KHJvd3MsIHJvdyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVJdGVtKHJvdyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGMgPSAwLCBjTGVuID0gcmVtb3ZlU3BhbkFyci5sZW5ndGgsIHJvd1NwYW5DZWxsOyBjIDwgY0xlbjsgYysrKSB7XHJcbiAgICAgICAgICAgICAgICByb3dTcGFuQ2VsbCA9IHJlbW92ZVNwYW5BcnJbY107XHJcbiAgICAgICAgICAgICAgICByb3dTcGFuQ2VsbC5jZWxsLnJvd1NwYW4gPSB1dGlsLmdldE92ZXJsYXBSYW5nZUF0SW5kZXgocmVtb3ZlRmlyc3QsIHJlbW92ZUVuZCwgcm93U3BhbkNlbGwuaSwgcm93U3BhbkNlbGwucnMpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmNvbnRyb2xsZXJzT2ZmKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnRhYmxlLnNldFBvc2l0aW9uQ29udHJvbGxlckRpdi5jYWxsKHRoaXMsIHBvc2l0aW9uUmVzZXRFbGVtZW50IHx8IGNvbnRleHRUYWJsZS5fdGRFbGVtZW50LCB0cnVlKTtcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIF9jbG9zZVNwbGl0TWVudTogbnVsbCxcclxuICAgIG9wZW5TcGxpdE1lbnU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLnV0aWwuYWRkQ2xhc3ModGhpcy5jb250ZXh0LnRhYmxlLnNwbGl0QnV0dG9uLCAnb24nKTtcclxuICAgICAgICB0aGlzLmNvbnRleHQudGFibGUuc3BsaXRNZW51LnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lLXRhYmxlJztcclxuXHJcbiAgICAgICAgdGhpcy5wbHVnaW5zLnRhYmxlLl9jbG9zZVNwbGl0TWVudSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUNsYXNzKHRoaXMuY29udGV4dC50YWJsZS5zcGxpdEJ1dHRvbiwgJ29uJyk7XHJcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50YWJsZS5zcGxpdE1lbnUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgdGhpcy5yZW1vdmVEb2NFdmVudCgnbW91c2Vkb3duJywgdGhpcy5wbHVnaW5zLnRhYmxlLl9jbG9zZVNwbGl0TWVudSk7XHJcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy50YWJsZS5fY2xvc2VTcGxpdE1lbnUgPSBudWxsO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKTtcclxuXHJcbiAgICAgICAgdGhpcy5hZGREb2NFdmVudCgnbW91c2Vkb3duJywgdGhpcy5wbHVnaW5zLnRhYmxlLl9jbG9zZVNwbGl0TWVudSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHNwbGl0Q2VsbHM6IGZ1bmN0aW9uIChkaXJlY3Rpb24pIHtcclxuICAgICAgICBjb25zdCB1dGlsID0gdGhpcy51dGlsO1xyXG4gICAgICAgIGNvbnN0IHZlcnRpY2FsID0gZGlyZWN0aW9uID09PSAndmVydGljYWwnO1xyXG4gICAgICAgIGNvbnN0IGNvbnRleHRUYWJsZSA9IHRoaXMuY29udGV4dC50YWJsZTtcclxuICAgICAgICBjb25zdCBjdXJyZW50Q2VsbCA9IGNvbnRleHRUYWJsZS5fdGRFbGVtZW50O1xyXG4gICAgICAgIGNvbnN0IHJvd3MgPSBjb250ZXh0VGFibGUuX3RyRWxlbWVudHM7XHJcbiAgICAgICAgY29uc3QgY3VycmVudFJvdyA9IGNvbnRleHRUYWJsZS5fdHJFbGVtZW50O1xyXG4gICAgICAgIGNvbnN0IGluZGV4ID0gY29udGV4dFRhYmxlLl9sb2dpY2FsX2NlbGxJbmRleDtcclxuICAgICAgICBjb25zdCByb3dJbmRleCA9IGNvbnRleHRUYWJsZS5fcm93SW5kZXg7XHJcbiAgICAgICAgY29uc3QgbmV3Q2VsbCA9IHRoaXMucGx1Z2lucy50YWJsZS5jcmVhdGVDZWxscy5jYWxsKHRoaXMsIGN1cnJlbnRDZWxsLm5vZGVOYW1lLCAwLCB0cnVlKTtcclxuXHJcbiAgICAgICAgLy8gdmVydGljYWxcclxuICAgICAgICBpZiAodmVydGljYWwpIHtcclxuICAgICAgICAgICAgY29uc3QgY3VycmVudENvbFNwYW4gPSBjdXJyZW50Q2VsbC5jb2xTcGFuO1xyXG4gICAgICAgICAgICBuZXdDZWxsLnJvd1NwYW4gPSBjdXJyZW50Q2VsbC5yb3dTcGFuO1xyXG5cclxuICAgICAgICAgICAgLy8gY29sc3BhbiA+IDFcclxuICAgICAgICAgICAgaWYgKGN1cnJlbnRDb2xTcGFuID4gMSkge1xyXG4gICAgICAgICAgICAgICAgbmV3Q2VsbC5jb2xTcGFuID0gdGhpcy5fdy5NYXRoLmZsb29yKGN1cnJlbnRDb2xTcGFuLzIpO1xyXG4gICAgICAgICAgICAgICAgY3VycmVudENlbGwuY29sU3BhbiA9IGN1cnJlbnRDb2xTcGFuIC0gbmV3Q2VsbC5jb2xTcGFuO1xyXG4gICAgICAgICAgICAgICAgY3VycmVudFJvdy5pbnNlcnRCZWZvcmUobmV3Q2VsbCwgY3VycmVudENlbGwubmV4dEVsZW1lbnRTaWJsaW5nKTtcclxuICAgICAgICAgICAgfSBlbHNlIHsgLy8gY29sc3BhbiAtIDFcclxuICAgICAgICAgICAgICAgIGxldCByb3dTcGFuQXJyID0gW107XHJcbiAgICAgICAgICAgICAgICBsZXQgc3BhbkluZGV4ID0gW107XHJcblxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNvbnRleHRUYWJsZS5fcm93Q250LCBjZWxscywgY29sU3BhbjsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2VsbHMgPSByb3dzW2ldLmNlbGxzO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbFNwYW4gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGMgPSAwLCBjTGVuID0gY2VsbHMubGVuZ3RoLCBjZWxsLCBjcywgcnMsIGxvZ2NhbEluZGV4OyBjIDwgY0xlbjsgYysrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwgPSBjZWxsc1tjXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3MgPSBjZWxsLmNvbFNwYW4gLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBycyA9IGNlbGwucm93U3BhbiAtIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2NhbEluZGV4ID0gYyArIGNvbFNwYW47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3BhbkluZGV4Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHIgPSAwLCBhcnI7IHIgPCBzcGFuSW5kZXgubGVuZ3RoOyByKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIgPSBzcGFuSW5kZXhbcl07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyci5yb3cgPiBpKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobG9nY2FsSW5kZXggPj0gYXJyLmluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbFNwYW4gKz0gYXJyLmNzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2djYWxJbmRleCArPSBhcnIuY3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyci5ycyAtPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucm93ID0gaSArIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcnIucnMgPCAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFuSW5kZXguc3BsaWNlKHIsIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgci0tO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGMgPT09IGNMZW4gLSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyci5ycyAtPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucm93ID0gaSArIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcnIucnMgPCAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFuSW5kZXguc3BsaWNlKHIsIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgci0tO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobG9nY2FsSW5kZXggPD0gaW5kZXggJiYgcnMgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3dTcGFuQXJyLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4OiBsb2djYWxJbmRleCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjczogY3MgKyAxLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJzOiBycyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3c6IC0xXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNlbGwgIT09IGN1cnJlbnRDZWxsICYmIGxvZ2NhbEluZGV4IDw9IGluZGV4ICYmIGxvZ2NhbEluZGV4ICsgY3MgPj0gaW5kZXggKyBjdXJyZW50Q29sU3BhbiAtIDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY29sU3BhbiArPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb2djYWxJbmRleCA+IGluZGV4KSBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbFNwYW4gKz0gY3M7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBzcGFuSW5kZXggPSBzcGFuSW5kZXguY29uY2F0KHJvd1NwYW5BcnIpLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtyZXR1cm4gYS5pbmRleCAtIGIuaW5kZXg7fSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcm93U3BhbkFyciA9IFtdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGN1cnJlbnRSb3cuaW5zZXJ0QmVmb3JlKG5ld0NlbGwsIGN1cnJlbnRDZWxsLm5leHRFbGVtZW50U2libGluZyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgeyAvLyBob3Jpem9udGFsXHJcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRSb3dTcGFuID0gY3VycmVudENlbGwucm93U3BhbjtcclxuICAgICAgICAgICAgbmV3Q2VsbC5jb2xTcGFuID0gY3VycmVudENlbGwuY29sU3BhbjtcclxuXHJcbiAgICAgICAgICAgIC8vIHJvd3NwYW4gPiAxXHJcbiAgICAgICAgICAgIGlmIChjdXJyZW50Um93U3BhbiA+IDEpIHtcclxuICAgICAgICAgICAgICAgIG5ld0NlbGwucm93U3BhbiA9IHRoaXMuX3cuTWF0aC5mbG9vcihjdXJyZW50Um93U3Bhbi8yKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1Jvd1NwYW4gPSBjdXJyZW50Um93U3BhbiAtIG5ld0NlbGwucm93U3BhbjtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCByb3dTcGFuQXJyID0gW107XHJcbiAgICAgICAgICAgICAgICBjb25zdCBuZXh0Um93SW5kZXggPSB1dGlsLmdldEFycmF5SW5kZXgocm93cywgY3VycmVudFJvdykgKyBuZXdSb3dTcGFuO1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBjZWxscywgY29sU3BhbjsgaSA8IG5leHRSb3dJbmRleDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2VsbHMgPSByb3dzW2ldLmNlbGxzO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbFNwYW4gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGMgPSAwLCBjTGVuID0gY2VsbHMubGVuZ3RoLCBjZWxsLCBjcywgbG9nY2FsSW5kZXg7IGMgPCBjTGVuOyBjKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbG9nY2FsSW5kZXggPSBjICsgY29sU3BhbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvZ2NhbEluZGV4ID49IGluZGV4KSBicmVhaztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwgPSBjZWxsc1tjXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3MgPSBjZWxsLnJvd1NwYW4gLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3MgPiAwICYmIGNzICsgaSA+PSBuZXh0Um93SW5kZXggJiYgbG9nY2FsSW5kZXggPCBpbmRleCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcm93U3BhbkFyci5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleDogbG9nY2FsSW5kZXgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3M6IGNlbGwuY29sU3BhblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY29sU3BhbiArPSBjZWxsLmNvbFNwYW4gLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBuZXh0Um93ID0gcm93c1tuZXh0Um93SW5kZXhdO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV4dENlbGxzID0gbmV4dFJvdy5jZWxscztcclxuICAgICAgICAgICAgICAgIGxldCBycyA9IHJvd1NwYW5BcnIuc2hpZnQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBjID0gMCwgY0xlbiA9IG5leHRDZWxscy5sZW5ndGgsIGNvbFNwYW4gPSAwLCBjZWxsLCBjcywgbG9nY2FsSW5kZXgsIGluc2VydEluZGV4OyBjIDwgY0xlbjsgYysrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9nY2FsSW5kZXggPSBjICsgY29sU3BhbjtcclxuICAgICAgICAgICAgICAgICAgICBjZWxsID0gbmV4dENlbGxzW2NdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNzID0gY2VsbC5jb2xTcGFuIC0gMTtcclxuICAgICAgICAgICAgICAgICAgICBpbnNlcnRJbmRleCA9IGxvZ2NhbEluZGV4ICsgY3MgKyAxO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAocnMgJiYgaW5zZXJ0SW5kZXggPj0gcnMuaW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29sU3BhbiArPSBycy5jcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5zZXJ0SW5kZXggKz0gcnMuY3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJzID0gcm93U3BhbkFyci5zaGlmdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaW5zZXJ0SW5kZXggPj0gaW5kZXggfHwgYyA9PT0gY0xlbiAtIDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dFJvdy5pbnNlcnRCZWZvcmUobmV3Q2VsbCwgY2VsbC5uZXh0RWxlbWVudFNpYmxpbmcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbFNwYW4gKz0gY3M7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgY3VycmVudENlbGwucm93U3BhbiA9IG5ld1Jvd1NwYW47XHJcbiAgICAgICAgICAgIH0gZWxzZSB7IC8vIHJvd3NwYW4gLSAxXHJcbiAgICAgICAgICAgICAgICBuZXdDZWxsLnJvd1NwYW4gPSBjdXJyZW50Q2VsbC5yb3dTcGFuO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3Um93ID0gdXRpbC5jcmVhdGVFbGVtZW50KCdUUicpO1xyXG4gICAgICAgICAgICAgICAgbmV3Um93LmFwcGVuZENoaWxkKG5ld0NlbGwpO1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBjZWxsczsgaSA8IHJvd0luZGV4OyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBjZWxscyA9IHJvd3NbaV0uY2VsbHM7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNlbGxzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBjID0gMCwgY0xlbiA9IGNlbGxzLmxlbmd0aDsgYyA8IGNMZW47IGMrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSArIGNlbGxzW2NdLnJvd1NwYW4gLSAxID49IHJvd0luZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsc1tjXS5yb3dTcGFuICs9IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgcGh5c2ljYWxJbmRleCA9IGNvbnRleHRUYWJsZS5fcGh5c2ljYWxfY2VsbEluZGV4O1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2VsbHMgPSBjdXJyZW50Um93LmNlbGxzO1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGMgPSAwLCBjTGVuID0gY2VsbHMubGVuZ3RoOyBjIDwgY0xlbjsgYysrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT09IHBoeXNpY2FsSW5kZXgpIGNvbnRpbnVlOyAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICBjZWxsc1tjXS5yb3dTcGFuICs9IDE7ICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjdXJyZW50Um93LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5ld1JvdywgY3VycmVudFJvdy5uZXh0RWxlbWVudFNpYmxpbmcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmZvY3VzRWRnZShjdXJyZW50Q2VsbCk7XHJcbiAgICAgICAgdGhpcy5wbHVnaW5zLnRhYmxlLnNldFBvc2l0aW9uQ29udHJvbGxlckRpdi5jYWxsKHRoaXMsIGN1cnJlbnRDZWxsLCB0cnVlKTtcclxuICAgIH0sXHJcblxyXG4gICAgbWVyZ2VDZWxsczogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGNvbnN0IHRhYmxlUGx1Z2luID0gdGhpcy5wbHVnaW5zLnRhYmxlO1xyXG4gICAgICAgIGNvbnN0IGNvbnRleHRUYWJsZSA9IHRoaXMuY29udGV4dC50YWJsZTtcclxuICAgICAgICBjb25zdCB1dGlsID0gdGhpcy51dGlsO1xyXG5cclxuICAgICAgICBjb25zdCByZWYgPSB0YWJsZVBsdWdpbi5fcmVmO1xyXG4gICAgICAgIGNvbnN0IHNlbGVjdGVkQ2VsbHMgPSB0YWJsZVBsdWdpbi5fc2VsZWN0ZWRDZWxscztcclxuICAgICAgICBjb25zdCBtZXJnZUNlbGwgPSBzZWxlY3RlZENlbGxzWzBdO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGxldCBlbXB0eVJvd0ZpcnN0ID0gbnVsbDtcclxuICAgICAgICBsZXQgZW1wdHlSb3dMYXN0ID0gbnVsbDtcclxuICAgICAgICBsZXQgY3MgPSAocmVmLmNlIC0gcmVmLmNzKSArIDE7XHJcbiAgICAgICAgbGV0IHJzID0gKHJlZi5yZSAtIHJlZi5ycykgKyAxO1xyXG4gICAgICAgIGxldCBtZXJnZUhUTUwgPSAnJztcclxuICAgICAgICBsZXQgcm93ID0gbnVsbDtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDEsIGxlbiA9IHNlbGVjdGVkQ2VsbHMubGVuZ3RoLCBjZWxsLCBjaDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNlbGwgPSBzZWxlY3RlZENlbGxzW2ldO1xyXG4gICAgICAgICAgICBpZiAocm93ICE9PSBjZWxsLnBhcmVudE5vZGUpIHJvdyA9IGNlbGwucGFyZW50Tm9kZTtcclxuXHJcbiAgICAgICAgICAgIGNoID0gY2VsbC5jaGlsZHJlbjtcclxuICAgICAgICAgICAgZm9yIChsZXQgYyA9IDAsIGNMZW4gPSBjaC5sZW5ndGg7IGMgPCBjTGVuOyBjKyspIHtcclxuICAgICAgICAgICAgICAgIGlmICh1dGlsLmlzRm9ybWF0RWxlbWVudChjaFtjXSkgJiYgdXRpbC5vbmx5WmVyb1dpZHRoU3BhY2UoY2hbY10udGV4dENvbnRlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVJdGVtKGNoW2NdKTtcclxuICAgICAgICAgICAgICAgIH0gIFxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBtZXJnZUhUTUwgKz0gY2VsbC5pbm5lckhUTUw7XHJcbiAgICAgICAgICAgIHV0aWwucmVtb3ZlSXRlbShjZWxsKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChyb3cuY2VsbHMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWVtcHR5Um93Rmlyc3QpIGVtcHR5Um93Rmlyc3QgPSByb3c7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGVtcHR5Um93TGFzdCA9IHJvdztcclxuICAgICAgICAgICAgICAgIHJzIC09IDE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChlbXB0eVJvd0ZpcnN0KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJvd3MgPSBjb250ZXh0VGFibGUuX3RyRWxlbWVudHM7XHJcbiAgICAgICAgICAgIGNvbnN0IHJvd0luZGV4Rmlyc3QgPSB1dGlsLmdldEFycmF5SW5kZXgocm93cywgZW1wdHlSb3dGaXJzdCk7XHJcbiAgICAgICAgICAgIGNvbnN0IHJvd0luZGV4TGFzdCA9IHV0aWwuZ2V0QXJyYXlJbmRleChyb3dzLCBlbXB0eVJvd0xhc3QgfHwgZW1wdHlSb3dGaXJzdCk7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlbW92ZVJvd3MgPSBbXTtcclxuICAgIFxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgY2VsbHM7IGkgPD0gcm93SW5kZXhMYXN0OyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGNlbGxzID0gcm93c1tpXS5jZWxscztcclxuICAgICAgICAgICAgICAgIGlmIChjZWxscy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICByZW1vdmVSb3dzLnB1c2gocm93c1tpXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICBcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGMgPSAwLCBjTGVuID0gY2VsbHMubGVuZ3RoLCBjZWxsLCByczsgYyA8IGNMZW47IGMrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNlbGwgPSBjZWxsc1tjXTtcclxuICAgICAgICAgICAgICAgICAgICBycyA9IGNlbGwucm93U3BhbiAtIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJzID4gMCAmJiBpICsgcnMgPj0gcm93SW5kZXhGaXJzdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnJvd1NwYW4gLT0gdXRpbC5nZXRPdmVybGFwUmFuZ2VBdEluZGV4KHJvd0luZGV4Rmlyc3QsIHJvd0luZGV4TGFzdCwgaSwgaSArIHJzKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSByZW1vdmVSb3dzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW0ocmVtb3ZlUm93c1tpXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIG1lcmdlQ2VsbC5pbm5lckhUTUwgKz0gbWVyZ2VIVE1MO1xyXG4gICAgICAgIG1lcmdlQ2VsbC5jb2xTcGFuID0gY3M7XHJcbiAgICAgICAgbWVyZ2VDZWxsLnJvd1NwYW4gPSBycztcclxuXHJcbiAgICAgICAgdGhpcy5jb250cm9sbGVyc09mZigpO1xyXG4gICAgICAgIHRhYmxlUGx1Z2luLnNldEFjdGl2ZUJ1dHRvbi5jYWxsKHRoaXMsIHRydWUsIGZhbHNlKTtcclxuICAgICAgICB0YWJsZVBsdWdpbi5jYWxsX2NvbnRyb2xsZXJfdGFibGVFZGl0LmNhbGwodGhpcywgbWVyZ2VDZWxsKTtcclxuXHJcbiAgICAgICAgdXRpbC5hZGRDbGFzcyhtZXJnZUNlbGwsICdzZS10YWJsZS1zZWxlY3RlZC1jZWxsJyk7XHJcbiAgICAgICAgdGhpcy5mb2N1c0VkZ2UobWVyZ2VDZWxsKTtcclxuICAgIH0sXHJcblxyXG4gICAgdG9nZ2xlSGVhZGVyOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgY29uc3QgdXRpbCA9IHRoaXMudXRpbDtcclxuICAgICAgICBjb25zdCBoZWFkZXJCdXR0b24gPSB0aGlzLmNvbnRleHQudGFibGUuaGVhZGVyQnV0dG9uO1xyXG4gICAgICAgIGNvbnN0IGFjdGl2ZSA9IHV0aWwuaGFzQ2xhc3MoaGVhZGVyQnV0dG9uLCAnYWN0aXZlJyk7XHJcbiAgICAgICAgY29uc3QgdGFibGUgPSB0aGlzLmNvbnRleHQudGFibGUuX2VsZW1lbnQ7XHJcblxyXG4gICAgICAgIGlmICghYWN0aXZlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGhlYWRlciA9IHV0aWwuY3JlYXRlRWxlbWVudCgnVEhFQUQnKTtcclxuICAgICAgICAgICAgaGVhZGVyLmlubmVySFRNTCA9ICc8dHI+JyArIHRoaXMucGx1Z2lucy50YWJsZS5jcmVhdGVDZWxscy5jYWxsKHRoaXMsICd0aCcsIHRoaXMuY29udGV4dC50YWJsZS5fbG9naWNhbF9jZWxsQ250LCBmYWxzZSkgKyAnPC90cj4nO1xyXG4gICAgICAgICAgICB0YWJsZS5pbnNlcnRCZWZvcmUoaGVhZGVyLCB0YWJsZS5maXJzdEVsZW1lbnRDaGlsZCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdXRpbC5yZW1vdmVJdGVtKHRhYmxlLnF1ZXJ5U2VsZWN0b3IoJ3RoZWFkJykpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdXRpbC50b2dnbGVDbGFzcyhoZWFkZXJCdXR0b24sICdhY3RpdmUnKTtcclxuXHJcbiAgICAgICAgaWYgKC9USC9pLnRlc3QodGhpcy5jb250ZXh0LnRhYmxlLl90ZEVsZW1lbnQubm9kZU5hbWUpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29udHJvbGxlcnNPZmYoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMudGFibGUuc2V0UG9zaXRpb25Db250cm9sbGVyRGl2LmNhbGwodGhpcywgdGhpcy5jb250ZXh0LnRhYmxlLl90ZEVsZW1lbnQsIGZhbHNlKTtcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIHNldFRhYmxlU3R5bGU6IGZ1bmN0aW9uIChzdHlsZXMpIHtcclxuICAgICAgICBjb25zdCBjb250ZXh0VGFibGUgPSB0aGlzLmNvbnRleHQudGFibGU7XHJcbiAgICAgICAgY29uc3QgdGFibGVFbGVtZW50ID0gY29udGV4dFRhYmxlLl9lbGVtZW50O1xyXG4gICAgICAgIGxldCBpY29uLCBzcGFuLCBzaXplSWNvbiwgdGV4dDtcclxuXHJcbiAgICAgICAgaWYgKHN0eWxlcy5pbmRleE9mKCd3aWR0aCcpID4gLTEpIHtcclxuICAgICAgICAgICAgaWNvbiA9ICBjb250ZXh0VGFibGUucmVzaXplQnV0dG9uLmZpcnN0RWxlbWVudENoaWxkO1xyXG4gICAgICAgICAgICBzcGFuID0gY29udGV4dFRhYmxlLnJlc2l6ZVRleHQ7XHJcblxyXG4gICAgICAgICAgICBpZiAoIWNvbnRleHRUYWJsZS5fbWF4V2lkdGgpIHtcclxuICAgICAgICAgICAgICAgIHNpemVJY29uID0gY29udGV4dFRhYmxlLmljb25zLmV4cGFuc2lvbjtcclxuICAgICAgICAgICAgICAgIHRleHQgPSBjb250ZXh0VGFibGUubWF4VGV4dDtcclxuICAgICAgICAgICAgICAgIGNvbnRleHRUYWJsZS5jb2x1bW5GaXhlZEJ1dHRvbi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUNsYXNzKHRhYmxlRWxlbWVudCwgJ3NlLXRhYmxlLXNpemUtMTAwJyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnV0aWwuYWRkQ2xhc3ModGFibGVFbGVtZW50LCAnc2UtdGFibGUtc2l6ZS1hdXRvJyk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBzaXplSWNvbiA9IGNvbnRleHRUYWJsZS5pY29ucy5yZWR1Y3Rpb247XHJcbiAgICAgICAgICAgICAgICB0ZXh0ID0gY29udGV4dFRhYmxlLm1pblRleHQ7XHJcbiAgICAgICAgICAgICAgICBjb250ZXh0VGFibGUuY29sdW1uRml4ZWRCdXR0b24uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnV0aWwucmVtb3ZlQ2xhc3ModGFibGVFbGVtZW50LCAnc2UtdGFibGUtc2l6ZS1hdXRvJyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnV0aWwuYWRkQ2xhc3ModGFibGVFbGVtZW50LCAnc2UtdGFibGUtc2l6ZS0xMDAnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgdGhpcy51dGlsLmNoYW5nZUVsZW1lbnQoaWNvbiwgc2l6ZUljb24pO1xyXG4gICAgICAgICAgICB0aGlzLnV0aWwuY2hhbmdlVHh0KHNwYW4sIHRleHQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHN0eWxlcy5pbmRleE9mKCdjb2x1bW4nKSA+IC0xKSB7XHJcbiAgICAgICAgICAgIGlmICghY29udGV4dFRhYmxlLl9maXhlZENvbHVtbikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUNsYXNzKHRhYmxlRWxlbWVudCwgJ3NlLXRhYmxlLWxheW91dC1maXhlZCcpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy51dGlsLmFkZENsYXNzKHRhYmxlRWxlbWVudCwgJ3NlLXRhYmxlLWxheW91dC1hdXRvJyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnV0aWwucmVtb3ZlQ2xhc3MoY29udGV4dFRhYmxlLmNvbHVtbkZpeGVkQnV0dG9uLCAnYWN0aXZlJyk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnV0aWwucmVtb3ZlQ2xhc3ModGFibGVFbGVtZW50LCAnc2UtdGFibGUtbGF5b3V0LWF1dG8nKTtcclxuICAgICAgICAgICAgICAgIHRoaXMudXRpbC5hZGRDbGFzcyh0YWJsZUVsZW1lbnQsICdzZS10YWJsZS1sYXlvdXQtZml4ZWQnKTtcclxuICAgICAgICAgICAgICAgIHRoaXMudXRpbC5hZGRDbGFzcyhjb250ZXh0VGFibGUuY29sdW1uRml4ZWRCdXR0b24sICdhY3RpdmUnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIHNldEFjdGl2ZUJ1dHRvbjogZnVuY3Rpb24gKGZpeGVkQ2VsbCwgc2VsZWN0ZWRDZWxsKSB7XHJcbiAgICAgICAgY29uc3QgY29udGV4dFRhYmxlID0gdGhpcy5jb250ZXh0LnRhYmxlO1xyXG5cclxuICAgICAgICBpZiAoL15USCQvaS50ZXN0KGZpeGVkQ2VsbC5ub2RlTmFtZSkpIHtcclxuICAgICAgICAgICAgY29udGV4dFRhYmxlLmluc2VydFJvd0Fib3ZlQnV0dG9uLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCB0cnVlKTtcclxuICAgICAgICAgICAgY29udGV4dFRhYmxlLmluc2VydFJvd0JlbG93QnV0dG9uLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCB0cnVlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb250ZXh0VGFibGUuaW5zZXJ0Um93QWJvdmVCdXR0b24ucmVtb3ZlQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xyXG4gICAgICAgICAgICBjb250ZXh0VGFibGUuaW5zZXJ0Um93QmVsb3dCdXR0b24ucmVtb3ZlQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFzZWxlY3RlZENlbGwgfHwgZml4ZWRDZWxsID09PSBzZWxlY3RlZENlbGwpIHtcclxuICAgICAgICAgICAgY29udGV4dFRhYmxlLnNwbGl0QnV0dG9uLnJlbW92ZUF0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcclxuICAgICAgICAgICAgY29udGV4dFRhYmxlLm1lcmdlQnV0dG9uLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCB0cnVlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb250ZXh0VGFibGUuc3BsaXRCdXR0b24uc2V0QXR0cmlidXRlKCdkaXNhYmxlZCcsIHRydWUpO1xyXG4gICAgICAgICAgICBjb250ZXh0VGFibGUubWVyZ2VCdXR0b24ucmVtb3ZlQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xyXG4gICAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgLy8gbXVsdGkgc2VsZWN0ZVxyXG4gICAgX2JpbmRPblNlbGVjdDogbnVsbCxcclxuICAgIF9iaW5kT2ZmU2VsZWN0OiBudWxsLFxyXG4gICAgX2JpbmRPZmZTaGlmdDogbnVsbCxcclxuICAgIF9zZWxlY3RlZENlbGxzOiBudWxsLFxyXG4gICAgX3NoaWZ0OiBmYWxzZSxcclxuICAgIF9maXhlZENlbGw6IG51bGwsXHJcbiAgICBfZml4ZWRDZWxsTmFtZTogbnVsbCxcclxuICAgIF9zZWxlY3RlZENlbGw6IG51bGwsXHJcbiAgICBfc2VsZWN0ZWRUYWJsZTogbnVsbCxcclxuICAgIF9yZWY6IG51bGwsXHJcbiAgICBfdG9nZ2xlRWRpdG9yOiBmdW5jdGlvbiAoZW5hYmxlZCkge1xyXG4gICAgICAgIHRoaXMuY29udGV4dC5lbGVtZW50Lnd5c2l3eWcuc2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnLCBlbmFibGVkKTtcclxuICAgICAgICBpZiAoZW5hYmxlZCkgdGhpcy51dGlsLnJlbW92ZUNsYXNzKHRoaXMuY29udGV4dC5lbGVtZW50Lnd5c2l3eWcsICdzZS1kaXNhYmxlZCcpO1xyXG4gICAgICAgIGVsc2UgdGhpcy51dGlsLmFkZENsYXNzKHRoaXMuY29udGV4dC5lbGVtZW50Lnd5c2l3eWcsICdzZS1kaXNhYmxlZCcpO1xyXG4gICAgfSxcclxuXHJcbiAgICBfb2ZmQ2VsbE11bHRpU2VsZWN0OiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgY29uc3QgdGFibGVQbHVnaW4gPSB0aGlzLnBsdWdpbnMudGFibGU7XHJcblxyXG4gICAgICAgIGlmICghdGFibGVQbHVnaW4uX3NoaWZ0KSB7XHJcbiAgICAgICAgICAgIHRhYmxlUGx1Z2luLl9yZW1vdmVFdmVudHMuY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgdGFibGVQbHVnaW4uX3RvZ2dsZUVkaXRvci5jYWxsKHRoaXMsIHRydWUpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAodGFibGVQbHVnaW4uX2luaXRCaW5kKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3dkLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRhYmxlUGx1Z2luLl9pbml0QmluZCk7XHJcbiAgICAgICAgICAgIHRhYmxlUGx1Z2luLl9pbml0QmluZCA9IG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXRhYmxlUGx1Z2luLl9maXhlZENlbGwgfHwgIXRhYmxlUGx1Z2luLl9zZWxlY3RlZFRhYmxlKSByZXR1cm47XHJcbiAgICAgICAgXHJcbiAgICAgICAgdGFibGVQbHVnaW4uc2V0QWN0aXZlQnV0dG9uLmNhbGwodGhpcywgdGFibGVQbHVnaW4uX2ZpeGVkQ2VsbCwgdGFibGVQbHVnaW4uX3NlbGVjdGVkQ2VsbCk7XHJcbiAgICAgICAgdGFibGVQbHVnaW4uY2FsbF9jb250cm9sbGVyX3RhYmxlRWRpdC5jYWxsKHRoaXMsIHRhYmxlUGx1Z2luLl9zZWxlY3RlZENlbGwgfHwgdGFibGVQbHVnaW4uX2ZpeGVkQ2VsbCk7XHJcblxyXG4gICAgICAgIHRhYmxlUGx1Z2luLl9zZWxlY3RlZENlbGxzID0gdGFibGVQbHVnaW4uX3NlbGVjdGVkVGFibGUucXVlcnlTZWxlY3RvckFsbCgnLnNlLXRhYmxlLXNlbGVjdGVkLWNlbGwnKTtcclxuICAgICAgICBpZiAodGFibGVQbHVnaW4uX3NlbGVjdGVkQ2VsbCAmJiB0YWJsZVBsdWdpbi5fZml4ZWRDZWxsKSB0aGlzLmZvY3VzRWRnZSh0YWJsZVBsdWdpbi5fc2VsZWN0ZWRDZWxsKTtcclxuXHJcbiAgICAgICAgaWYgKCF0YWJsZVBsdWdpbi5fc2hpZnQpIHtcclxuICAgICAgICAgICAgdGFibGVQbHVnaW4uX2ZpeGVkQ2VsbCA9IG51bGw7XHJcbiAgICAgICAgICAgIHRhYmxlUGx1Z2luLl9zZWxlY3RlZENlbGwgPSBudWxsO1xyXG4gICAgICAgICAgICB0YWJsZVBsdWdpbi5fZml4ZWRDZWxsTmFtZSA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBfb25DZWxsTXVsdGlTZWxlY3Q6IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgdGhpcy5fYW50aUJsdXIgPSB0cnVlO1xyXG4gICAgICAgIGNvbnN0IHRhYmxlUGx1Z2luID0gdGhpcy5wbHVnaW5zLnRhYmxlO1xyXG4gICAgICAgIGNvbnN0IHRhcmdldCA9IHRoaXMudXRpbC5nZXRQYXJlbnRFbGVtZW50KGUudGFyZ2V0LCB0aGlzLnV0aWwuaXNDZWxsKTtcclxuXHJcbiAgICAgICAgaWYgKHRhYmxlUGx1Z2luLl9zaGlmdCkge1xyXG4gICAgICAgICAgICBpZiAodGFyZ2V0ID09PSB0YWJsZVBsdWdpbi5fZml4ZWRDZWxsKSB0YWJsZVBsdWdpbi5fdG9nZ2xlRWRpdG9yLmNhbGwodGhpcywgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGVsc2UgdGFibGVQbHVnaW4uX3RvZ2dsZUVkaXRvci5jYWxsKHRoaXMsIGZhbHNlKTtcclxuICAgICAgICB9IGVsc2UgaWYgKCF0YWJsZVBsdWdpbi5fcmVmKSB7XHJcbiAgICAgICAgICAgIGlmICh0YXJnZXQgPT09IHRhYmxlUGx1Z2luLl9maXhlZENlbGwpIHJldHVybjtcclxuICAgICAgICAgICAgZWxzZSB0YWJsZVBsdWdpbi5fdG9nZ2xlRWRpdG9yLmNhbGwodGhpcywgZmFsc2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCF0YXJnZXQgfHwgdGFyZ2V0ID09PSB0YWJsZVBsdWdpbi5fc2VsZWN0ZWRDZWxsIHx8IHRhYmxlUGx1Z2luLl9maXhlZENlbGxOYW1lICE9PSB0YXJnZXQubm9kZU5hbWUgfHwgXHJcbiAgICAgICAgICAgIHRhYmxlUGx1Z2luLl9zZWxlY3RlZFRhYmxlICE9PSB0aGlzLnV0aWwuZ2V0UGFyZW50RWxlbWVudCh0YXJnZXQsICdUQUJMRScpKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRhYmxlUGx1Z2luLl9zZWxlY3RlZENlbGwgPSB0YXJnZXQ7XHJcbiAgICAgICAgdGFibGVQbHVnaW4uX3NldE11bHRpQ2VsbHMuY2FsbCh0aGlzLCB0YWJsZVBsdWdpbi5fZml4ZWRDZWxsLCB0YXJnZXQpO1xyXG4gICAgfSxcclxuXHJcbiAgICBfc2V0TXVsdGlDZWxsczogZnVuY3Rpb24gKHN0YXJ0Q2VsbCwgZW5kQ2VsbCkge1xyXG4gICAgICAgIGNvbnN0IHRhYmxlUGx1Z2luID0gdGhpcy5wbHVnaW5zLnRhYmxlO1xyXG4gICAgICAgIGNvbnN0IHJvd3MgPSB0YWJsZVBsdWdpbi5fc2VsZWN0ZWRUYWJsZS5yb3dzO1xyXG4gICAgICAgIGNvbnN0IHV0aWwgPSB0aGlzLnV0aWw7XHJcblxyXG4gICAgICAgIGNvbnN0IHNlbGVjdGVkQ2VsbHMgPSB0YWJsZVBsdWdpbi5fc2VsZWN0ZWRUYWJsZS5xdWVyeVNlbGVjdG9yQWxsKCcuc2UtdGFibGUtc2VsZWN0ZWQtY2VsbCcpO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBzZWxlY3RlZENlbGxzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHV0aWwucmVtb3ZlQ2xhc3Moc2VsZWN0ZWRDZWxsc1tpXSwgJ3NlLXRhYmxlLXNlbGVjdGVkLWNlbGwnKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChzdGFydENlbGwgPT09IGVuZENlbGwpIHtcclxuICAgICAgICAgICAgdXRpbC5hZGRDbGFzcyhzdGFydENlbGwsICdzZS10YWJsZS1zZWxlY3RlZC1jZWxsJyk7XHJcbiAgICAgICAgICAgIGlmICghdGFibGVQbHVnaW4uX3NoaWZ0KSByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgZmluZFNlbGVjdGVkQ2VsbCA9IHRydWU7XHJcbiAgICAgICAgbGV0IHNwYW5JbmRleCA9IFtdO1xyXG4gICAgICAgIGxldCByb3dTcGFuQXJyID0gW107XHJcbiAgICAgICAgY29uc3QgcmVmID0gdGFibGVQbHVnaW4uX3JlZiA9IHtfaTogMCwgY3M6IG51bGwsIGNlOiBudWxsLCByczogbnVsbCwgcmU6IG51bGx9O1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gcm93cy5sZW5ndGgsIGNlbGxzLCBjb2xTcGFuOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgY2VsbHMgPSByb3dzW2ldLmNlbGxzO1xyXG4gICAgICAgICAgICBjb2xTcGFuID0gMDtcclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGMgPSAwLCBjTGVuID0gY2VsbHMubGVuZ3RoLCBjZWxsLCBsb2djYWxJbmRleCwgY3MsIHJzOyBjIDwgY0xlbjsgYysrKSB7XHJcbiAgICAgICAgICAgICAgICBjZWxsID0gY2VsbHNbY107XHJcbiAgICAgICAgICAgICAgICBjcyA9IGNlbGwuY29sU3BhbiAtIDE7XHJcbiAgICAgICAgICAgICAgICBycyA9IGNlbGwucm93U3BhbiAtIDE7XHJcbiAgICAgICAgICAgICAgICBsb2djYWxJbmRleCA9IGMgKyBjb2xTcGFuO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChzcGFuSW5kZXgubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHIgPSAwLCBhcnI7IHIgPCBzcGFuSW5kZXgubGVuZ3RoOyByKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXJyID0gc3BhbkluZGV4W3JdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyLnJvdyA+IGkpIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobG9nY2FsSW5kZXggPj0gYXJyLmluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xTcGFuICs9IGFyci5jcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2NhbEluZGV4ICs9IGFyci5jcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyci5ycyAtPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyLnJvdyA9IGkgKyAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyci5ycyA8IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFuSW5kZXguc3BsaWNlKHIsIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHItLTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjID09PSBjTGVuIC0gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyLnJzIC09IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucm93ID0gaSArIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyLnJzIDwgMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYW5JbmRleC5zcGxpY2UociwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgci0tO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChmaW5kU2VsZWN0ZWRDZWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNlbGwgPT09IHN0YXJ0Q2VsbCB8fCBjZWxsID09PSBlbmRDZWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZi5jcyA9IHJlZi5jcyAhPT0gbnVsbCAmJiByZWYuY3MgPCBsb2djYWxJbmRleCA/IHJlZi5jcyA6IGxvZ2NhbEluZGV4O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWYuY2UgPSByZWYuY2UgIT09IG51bGwgJiYgcmVmLmNlID4gbG9nY2FsSW5kZXggKyBjcyA/IHJlZi5jZSA6IGxvZ2NhbEluZGV4ICsgY3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZi5ycyA9IHJlZi5ycyAhPT0gbnVsbCAmJiByZWYucnMgPCBpID8gcmVmLnJzIDogaTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmLnJlID0gcmVmLnJlICE9PSBudWxsICYmIHJlZi5yZSA+IGkgKyBycyA/IHJlZi5yZSA6IGkgKyBycztcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmLl9pICs9IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZWYuX2kgPT09IDIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmluZFNlbGVjdGVkQ2VsbCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzcGFuSW5kZXggPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcm93U3BhbkFyciA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpID0gLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodXRpbC5nZXRPdmVybGFwUmFuZ2VBdEluZGV4KHJlZi5jcywgcmVmLmNlLCBsb2djYWxJbmRleCwgbG9nY2FsSW5kZXggKyBjcykgJiYgdXRpbC5nZXRPdmVybGFwUmFuZ2VBdEluZGV4KHJlZi5ycywgcmVmLnJlLCBpLCBpICsgcnMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3Q3MgPSByZWYuY3MgPCBsb2djYWxJbmRleCA/IHJlZi5jcyA6IGxvZ2NhbEluZGV4O1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0NlID0gcmVmLmNlID4gbG9nY2FsSW5kZXggKyBjcyA/IHJlZi5jZSA6IGxvZ2NhbEluZGV4ICsgY3M7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3UnMgPSByZWYucnMgPCBpID8gcmVmLnJzIDogaTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdSZSA9IHJlZi5yZSA+IGkgKyBycyA/IHJlZi5yZSA6IGkgKyBycztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlZi5jcyAhPT0gbmV3Q3MgfHwgcmVmLmNlICE9PSBuZXdDZSB8fCByZWYucnMgIT09IG5ld1JzIHx8IHJlZi5yZSAhPT0gbmV3UmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmLmNzID0gbmV3Q3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZi5jZSA9IG5ld0NlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWYucnMgPSBuZXdScztcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmLnJlID0gbmV3UmU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGkgPSAtMTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNwYW5JbmRleCA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByb3dTcGFuQXJyID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5hZGRDbGFzcyhjZWxsLCAnc2UtdGFibGUtc2VsZWN0ZWQtY2VsbCcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChycyA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICByb3dTcGFuQXJyLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleDogbG9nY2FsSW5kZXgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzOiBjcyArIDEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJzOiBycyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcm93OiAtMVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbFNwYW4gKz0gY2VsbC5jb2xTcGFuIC0gMTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgc3BhbkluZGV4ID0gc3BhbkluZGV4LmNvbmNhdChyb3dTcGFuQXJyKS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7cmV0dXJuIGEuaW5kZXggLSBiLmluZGV4O30pO1xyXG4gICAgICAgICAgICByb3dTcGFuQXJyID0gW107XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBfcmVtb3ZlRXZlbnRzOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgY29uc3QgdGFibGVQbHVnaW4gPSB0aGlzLnBsdWdpbnMudGFibGU7XHJcblxyXG4gICAgICAgIGlmICh0YWJsZVBsdWdpbi5faW5pdEJpbmQpIHtcclxuICAgICAgICAgICAgdGhpcy5fd2QucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgdGFibGVQbHVnaW4uX2luaXRCaW5kKTtcclxuICAgICAgICAgICAgdGFibGVQbHVnaW4uX2luaXRCaW5kID0gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0YWJsZVBsdWdpbi5fYmluZE9uU2VsZWN0KSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3dkLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRhYmxlUGx1Z2luLl9iaW5kT25TZWxlY3QpO1xyXG4gICAgICAgICAgICB0aGlzLl93ZC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0YWJsZVBsdWdpbi5fYmluZE9uU2VsZWN0KTtcclxuICAgICAgICAgICAgdGFibGVQbHVnaW4uX2JpbmRPblNlbGVjdCA9IG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGFibGVQbHVnaW4uX2JpbmRPZmZTZWxlY3QpIHtcclxuICAgICAgICAgICAgdGhpcy5fd2QucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRhYmxlUGx1Z2luLl9iaW5kT2ZmU2VsZWN0KTtcclxuICAgICAgICAgICAgdGFibGVQbHVnaW4uX2JpbmRPZmZTZWxlY3QgPSBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRhYmxlUGx1Z2luLl9iaW5kT2ZmU2hpZnQpIHtcclxuICAgICAgICAgICAgdGhpcy5fd2QucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5dXAnLCB0YWJsZVBsdWdpbi5fYmluZE9mZlNoaWZ0KTtcclxuICAgICAgICAgICAgdGFibGVQbHVnaW4uX2JpbmRPZmZTaGlmdCA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBfaW5pdEJpbmQ6IG51bGwsXHJcbiAgICBvblRhYmxlQ2VsbE11bHRpU2VsZWN0OiBmdW5jdGlvbiAodGRFbGVtZW50LCBzaGlmdCkge1xyXG4gICAgICAgIGNvbnN0IHRhYmxlUGx1Z2luID0gdGhpcy5wbHVnaW5zLnRhYmxlO1xyXG5cclxuICAgICAgICB0YWJsZVBsdWdpbi5fcmVtb3ZlRXZlbnRzLmNhbGwodGhpcyk7XHJcbiAgICAgICAgdGhpcy5jb250cm9sbGVyc09mZigpO1xyXG5cclxuICAgICAgICB0YWJsZVBsdWdpbi5fc2hpZnQgPSBzaGlmdDtcclxuICAgICAgICB0YWJsZVBsdWdpbi5fZml4ZWRDZWxsID0gdGRFbGVtZW50O1xyXG4gICAgICAgIHRhYmxlUGx1Z2luLl9maXhlZENlbGxOYW1lID0gdGRFbGVtZW50Lm5vZGVOYW1lO1xyXG4gICAgICAgIHRhYmxlUGx1Z2luLl9zZWxlY3RlZFRhYmxlID0gdGhpcy51dGlsLmdldFBhcmVudEVsZW1lbnQodGRFbGVtZW50LCAnVEFCTEUnKTtcclxuXHJcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRDZWxscyA9IHRhYmxlUGx1Z2luLl9zZWxlY3RlZFRhYmxlLnF1ZXJ5U2VsZWN0b3JBbGwoJy5zZS10YWJsZS1zZWxlY3RlZC1jZWxsJyk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHNlbGVjdGVkQ2VsbHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUNsYXNzKHNlbGVjdGVkQ2VsbHNbaV0sICdzZS10YWJsZS1zZWxlY3RlZC1jZWxsJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnV0aWwuYWRkQ2xhc3ModGRFbGVtZW50LCAnc2UtdGFibGUtc2VsZWN0ZWQtY2VsbCcpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHRhYmxlUGx1Z2luLl9iaW5kT25TZWxlY3QgPSB0YWJsZVBsdWdpbi5fb25DZWxsTXVsdGlTZWxlY3QuYmluZCh0aGlzKTtcclxuICAgICAgICB0YWJsZVBsdWdpbi5fYmluZE9mZlNlbGVjdCA9IHRhYmxlUGx1Z2luLl9vZmZDZWxsTXVsdGlTZWxlY3QuYmluZCh0aGlzKTtcclxuXHJcbiAgICAgICAgaWYgKCFzaGlmdCkge1xyXG4gICAgICAgICAgICB0aGlzLl93ZC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0YWJsZVBsdWdpbi5fYmluZE9uU2VsZWN0LCBmYWxzZSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGFibGVQbHVnaW4uX2JpbmRPZmZTaGlmdCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29udHJvbGxlcnNPbih0aGlzLmNvbnRleHQudGFibGUucmVzaXplRGl2LCB0aGlzLmNvbnRleHQudGFibGUudGFibGVDb250cm9sbGVyLCB0aGlzLnBsdWdpbnMudGFibGUuaW5pdC5iaW5kKHRoaXMpLCB0ZEVsZW1lbnQsICd0YWJsZScpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0YWJsZVBsdWdpbi5fcmVmKSB0aGlzLmNvbnRyb2xsZXJzT2ZmKCk7XHJcbiAgICAgICAgICAgIH0uYmluZCh0aGlzKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX3dkLmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgdGFibGVQbHVnaW4uX2JpbmRPZmZTaGlmdCwgZmFsc2UpO1xyXG4gICAgICAgICAgICB0aGlzLl93ZC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB0YWJsZVBsdWdpbi5fYmluZE9uU2VsZWN0LCBmYWxzZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl93ZC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGFibGVQbHVnaW4uX2JpbmRPZmZTZWxlY3QsIGZhbHNlKTtcclxuICAgICAgICB0YWJsZVBsdWdpbi5faW5pdEJpbmQgPSB0YWJsZVBsdWdpbi5pbml0LmJpbmQodGhpcyk7XHJcbiAgICAgICAgdGhpcy5fd2QuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgdGFibGVQbHVnaW4uX2luaXRCaW5kLCBmYWxzZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIG9uQ2xpY2tfdGFibGVDb250cm9sbGVyOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLWNvbW1hbmQnKSA/IGUudGFyZ2V0IDogZS50YXJnZXQucGFyZW50Tm9kZTtcclxuXHJcbiAgICAgICAgaWYgKHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJykpIHJldHVybjtcclxuXHJcbiAgICAgICAgY29uc3QgY29tbWFuZCA9IHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY29tbWFuZCcpO1xyXG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS12YWx1ZScpO1xyXG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtb3B0aW9uJyk7XHJcbiAgICAgICAgY29uc3QgdGFibGVQbHVnaW4gPSB0aGlzLnBsdWdpbnMudGFibGU7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKHR5cGVvZiB0YWJsZVBsdWdpbi5fY2xvc2VTcGxpdE1lbnUgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgdGFibGVQbHVnaW4uX2Nsb3NlU3BsaXRNZW51KCk7XHJcbiAgICAgICAgICAgIGlmIChjb21tYW5kID09PSAnb25zcGxpdCcpIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghY29tbWFuZCkgcmV0dXJuO1xyXG5cclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgY29uc3QgY29udGV4dFRhYmxlID0gdGhpcy5jb250ZXh0LnRhYmxlO1xyXG5cclxuICAgICAgICBzd2l0Y2ggKGNvbW1hbmQpIHtcclxuICAgICAgICAgICAgY2FzZSAnaW5zZXJ0JzpcclxuICAgICAgICAgICAgY2FzZSAnZGVsZXRlJzpcclxuICAgICAgICAgICAgICAgIHRhYmxlUGx1Z2luLmVkaXRUYWJsZS5jYWxsKHRoaXMsIHZhbHVlLCBvcHRpb24pO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgJ2hlYWRlcic6XHJcbiAgICAgICAgICAgICAgICB0YWJsZVBsdWdpbi50b2dnbGVIZWFkZXIuY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlICdvbnNwbGl0JzpcclxuICAgICAgICAgICAgICAgIHRhYmxlUGx1Z2luLm9wZW5TcGxpdE1lbnUuY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlICdzcGxpdCc6XHJcbiAgICAgICAgICAgICAgICB0YWJsZVBsdWdpbi5zcGxpdENlbGxzLmNhbGwodGhpcywgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgJ21lcmdlJzpcclxuICAgICAgICAgICAgICAgIHRhYmxlUGx1Z2luLm1lcmdlQ2VsbHMuY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlICdyZXNpemUnOlxyXG4gICAgICAgICAgICAgICAgY29udGV4dFRhYmxlLl9tYXhXaWR0aCA9ICFjb250ZXh0VGFibGUuX21heFdpZHRoO1xyXG4gICAgICAgICAgICAgICAgdGFibGVQbHVnaW4uc2V0VGFibGVTdHlsZS5jYWxsKHRoaXMsICd3aWR0aCcpO1xyXG4gICAgICAgICAgICAgICAgdGFibGVQbHVnaW4uc2V0UG9zaXRpb25Db250cm9sbGVyVG9wLmNhbGwodGhpcywgY29udGV4dFRhYmxlLl9lbGVtZW50KTtcclxuICAgICAgICAgICAgICAgIHRhYmxlUGx1Z2luLnNldFBvc2l0aW9uQ29udHJvbGxlckRpdi5jYWxsKHRoaXMsIGNvbnRleHRUYWJsZS5fdGRFbGVtZW50LCB0YWJsZVBsdWdpbi5fc2hpZnQpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgJ2xheW91dCc6XHJcbiAgICAgICAgICAgICAgICBjb250ZXh0VGFibGUuX2ZpeGVkQ29sdW1uID0gIWNvbnRleHRUYWJsZS5fZml4ZWRDb2x1bW47XHJcbiAgICAgICAgICAgICAgICB0YWJsZVBsdWdpbi5zZXRUYWJsZVN0eWxlLmNhbGwodGhpcywgJ2NvbHVtbicpO1xyXG4gICAgICAgICAgICAgICAgdGFibGVQbHVnaW4uc2V0UG9zaXRpb25Db250cm9sbGVyVG9wLmNhbGwodGhpcywgY29udGV4dFRhYmxlLl9lbGVtZW50KTtcclxuICAgICAgICAgICAgICAgIHRhYmxlUGx1Z2luLnNldFBvc2l0aW9uQ29udHJvbGxlckRpdi5jYWxsKHRoaXMsIGNvbnRleHRUYWJsZS5fdGRFbGVtZW50LCB0YWJsZVBsdWdpbi5fc2hpZnQpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgJ3JlbW92ZSc6XHJcbiAgICAgICAgICAgICAgICBjb25zdCBlbXB0eURpdiA9IGNvbnRleHRUYWJsZS5fZWxlbWVudC5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUl0ZW0oY29udGV4dFRhYmxlLl9lbGVtZW50KTtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29udHJvbGxlcnNPZmYoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoZW1wdHlEaXYgIT09IHRoaXMuY29udGV4dC5lbGVtZW50Lnd5c2l3eWcpIHRoaXMudXRpbC5yZW1vdmVJdGVtQWxsUGFyZW50cyhlbXB0eURpdiwgZnVuY3Rpb24gKGN1cnJlbnQpIHsgcmV0dXJuIGN1cnJlbnQuY2hpbGROb2Rlcy5sZW5ndGggPT09IDA7IH0sIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5mb2N1cygpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gaGlzdG9yeSBzdGFja1xyXG4gICAgICAgIHRoaXMuaGlzdG9yeS5wdXNoKGZhbHNlKTtcclxuICAgIH1cclxufTtcclxuIiwiLypcbiAqIHd5c2l3eWcgd2ViIGVkaXRvclxuICpcbiAqIHN1bmVkaXRvci5qc1xuICogQ29weXJpZ2h0IDIwMTcgSmlIb25nIExlZS5cbiAqIE1JVCBsaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICBuYW1lOiAnZm9ybWF0QmxvY2snLFxuICAgIGRpc3BsYXk6ICdzdWJtZW51JyxcbiAgICBhZGQ6IGZ1bmN0aW9uIChjb3JlLCB0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBjb3JlLmNvbnRleHQ7XG4gICAgICAgIGNvbnRleHQuZm9ybWF0QmxvY2sgPSB7XG4gICAgICAgICAgICB0YXJnZXRUZXh0OiB0YXJnZXRFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy50eHQnKSxcbiAgICAgICAgICAgIHRhcmdldFRvb2x0aXA6IHRhcmdldEVsZW1lbnQucGFyZW50Tm9kZS5xdWVyeVNlbGVjdG9yKCcuc2UtdG9vbHRpcC10ZXh0JyksXG4gICAgICAgICAgICBfZm9ybWF0TGlzdDogbnVsbCxcbiAgICAgICAgICAgIGN1cnJlbnRGb3JtYXQ6ICcnXG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqIHNldCBzdWJtZW51ICovXG4gICAgICAgIGxldCBsaXN0RGl2ID0gdGhpcy5zZXRTdWJtZW51LmNhbGwoY29yZSk7XG5cbiAgICAgICAgLyoqIGFkZCBldmVudCBsaXN0ZW5lcnMgKi9cbiAgICAgICAgbGlzdERpdi5xdWVyeVNlbGVjdG9yKCd1bCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5waWNrVXAuYmluZChjb3JlKSk7XG4gICAgICAgIGNvbnRleHQuZm9ybWF0QmxvY2suX2Zvcm1hdExpc3QgPSBsaXN0RGl2LnF1ZXJ5U2VsZWN0b3JBbGwoJ2xpIGJ1dHRvbicpO1xuXG4gICAgICAgIC8qKiBhcHBlbmQgdGFyZ2V0IGJ1dHRvbiBtZW51ICovXG4gICAgICAgIGNvcmUuaW5pdE1lbnVUYXJnZXQodGhpcy5uYW1lLCB0YXJnZXRFbGVtZW50LCBsaXN0RGl2KTtcblxuICAgICAgICAvKiogZW1wdHkgbWVtb3J5ICovXG4gICAgICAgIGxpc3REaXYgPSBudWxsO1xuICAgIH0sXG5cbiAgICBzZXRTdWJtZW51OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMuY29udGV4dC5vcHRpb247XG4gICAgICAgIGNvbnN0IGxhbmdfdG9vbGJhciA9IHRoaXMubGFuZy50b29sYmFyO1xuICAgICAgICBjb25zdCBsaXN0RGl2ID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xuICAgICAgICBsaXN0RGl2LmNsYXNzTmFtZSA9ICdzZS1zdWJtZW51IHNlLWxpc3QtbGF5ZXIgc2UtbGlzdC1mb3JtYXQnO1xuXG4gICAgICAgIGNvbnN0IGRlZmF1bHRGb3JtYXRzID0gWydwJywgJ2RpdicsICdibG9ja3F1b3RlJywgJ3ByZScsICdoMScsICdoMicsICdoMycsICdoNCcsICdoNScsICdoNiddO1xuICAgICAgICBjb25zdCBmb3JtYXRMaXN0ID0gIW9wdGlvbi5mb3JtYXRzIHx8IG9wdGlvbi5mb3JtYXRzLmxlbmd0aCA9PT0gMCA/IGRlZmF1bHRGb3JtYXRzIDogb3B0aW9uLmZvcm1hdHM7XG5cbiAgICAgICAgbGV0IGxpc3QgPSAnPGRpdiBjbGFzcz1cInNlLWxpc3QtaW5uZXJcIj48dWwgY2xhc3M9XCJzZS1saXN0LWJhc2ljXCI+JztcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGZvcm1hdExpc3QubGVuZ3RoLCBmb3JtYXQsIHRhZ05hbWUsIGNvbW1hbmQsIG5hbWUsIGgsIGF0dHJzLCBjbGFzc05hbWU7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgZm9ybWF0ID0gZm9ybWF0TGlzdFtpXTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgKHR5cGVvZiBmb3JtYXQgPT09ICdzdHJpbmcnICYmIGRlZmF1bHRGb3JtYXRzLmluZGV4T2YoZm9ybWF0KSA+IC0xKSB7XG4gICAgICAgICAgICAgICAgdGFnTmFtZSA9IGZvcm1hdC50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgICAgIGNvbW1hbmQgPSB0YWdOYW1lID09PSAnYmxvY2txdW90ZScgPyAncmFuZ2UnIDogdGFnTmFtZSA9PT0gJ3ByZScgPyAnZnJlZScgOiAncmVwbGFjZSc7XG4gICAgICAgICAgICAgICAgaCA9IC9eaC8udGVzdCh0YWdOYW1lKSA/IHRhZ05hbWUubWF0Y2goL1xcZCsvKVswXSA6ICcnO1xuICAgICAgICAgICAgICAgIG5hbWUgPSBsYW5nX3Rvb2xiYXJbJ3RhZ18nICsgKGggPyAnaCcgOiB0YWdOYW1lKV0gKyBoO1xuICAgICAgICAgICAgICAgIGNsYXNzTmFtZSA9ICcnO1xuICAgICAgICAgICAgICAgIGF0dHJzID0gJyc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRhZ05hbWUgPSBmb3JtYXQudGFnLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgY29tbWFuZCA9IGZvcm1hdC5jb21tYW5kO1xuICAgICAgICAgICAgICAgIG5hbWUgPSBmb3JtYXQubmFtZSB8fCB0YWdOYW1lO1xuICAgICAgICAgICAgICAgIGNsYXNzTmFtZSA9IGZvcm1hdC5jbGFzcztcbiAgICAgICAgICAgICAgICBhdHRycyA9IGNsYXNzTmFtZSA/ICcgY2xhc3M9XCInICsgY2xhc3NOYW1lICsgJ1wiJyA6ICcnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsaXN0ICs9ICc8bGk+JyArXG4gICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2UtYnRuLWxpc3RcIiBkYXRhLWNvbW1hbmQ9XCInICsgY29tbWFuZCArICdcIiBkYXRhLXZhbHVlPVwiJyArIHRhZ05hbWUgKyAnXCIgZGF0YS1jbGFzcz1cIicgKyBjbGFzc05hbWUgKyAnXCIgdGl0bGU9XCInICsgbmFtZSArICdcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzwnICsgdGFnTmFtZSArIGF0dHJzICsgJz4nICsgbmFtZSArICc8LycgKyB0YWdOYW1lICsgJz4nICtcbiAgICAgICAgICAgICAgICAnPC9idXR0b24+PC9saT4nO1xuICAgICAgICB9XG4gICAgICAgIGxpc3QgKz0gJzwvdWw+PC9kaXY+JztcblxuICAgICAgICBsaXN0RGl2LmlubmVySFRNTCA9IGxpc3Q7XG5cbiAgICAgICAgcmV0dXJuIGxpc3REaXY7XG4gICAgfSxcblxuICAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgY29yZVxuICAgICAqL1xuICAgIGFjdGl2ZTogZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgbGV0IGZvcm1hdFRpdGxlID0gdGhpcy5sYW5nLnRvb2xiYXIuZm9ybWF0cztcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5jb250ZXh0LmZvcm1hdEJsb2NrLnRhcmdldFRleHQ7XG4gICAgICAgIGNvbnN0IHRvb2x0aXAgPSB0aGlzLmNvbnRleHQuZm9ybWF0QmxvY2sudGFyZ2V0VG9vbHRpcDtcblxuICAgICAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMudXRpbC5jaGFuZ2VUeHQodGFyZ2V0LCBmb3JtYXRUaXRsZSk7XG4gICAgICAgICAgICB0aGlzLnV0aWwuY2hhbmdlVHh0KHRvb2x0aXAsIGZvcm1hdFRpdGxlKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnV0aWwuaXNGb3JtYXRFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXRDb250ZXh0ID0gdGhpcy5jb250ZXh0LmZvcm1hdEJsb2NrO1xuICAgICAgICAgICAgY29uc3QgZm9ybWF0TGlzdCA9IGZvcm1hdENvbnRleHQuX2Zvcm1hdExpc3Q7XG4gICAgICAgICAgICBjb25zdCBub2RlTmFtZSA9IGVsZW1lbnQubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IChlbGVtZW50LmNsYXNzTmFtZS5tYXRjaCgvKFxcc3xeKV9fc2VfX2Zvcm1hdF9fW15cXHNdKy8pIHx8IFsnJ10pWzBdLnRyaW0oKTtcblxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGZvcm1hdExpc3QubGVuZ3RoLCBmOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICBmID0gZm9ybWF0TGlzdFtpXTtcbiAgICAgICAgICAgICAgICBpZiAobm9kZU5hbWUgPT09IGYuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJykgJiYgY2xhc3NOYW1lID09PSBmLmdldEF0dHJpYnV0ZSgnZGF0YS1jbGFzcycpKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvcm1hdFRpdGxlID0gZi50aXRsZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnV0aWwuY2hhbmdlVHh0KHRhcmdldCwgZm9ybWF0VGl0bGUpO1xuICAgICAgICAgICAgdGhpcy51dGlsLmNoYW5nZVR4dCh0b29sdGlwLCBmb3JtYXRUaXRsZSk7XG4gICAgICAgICAgICB0YXJnZXQuc2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJywgbm9kZU5hbWUpO1xuICAgICAgICAgICAgdGFyZ2V0LnNldEF0dHJpYnV0ZSgnZGF0YS1jbGFzcycsIGNsYXNzTmFtZSk7XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG5cbiAgICAgLyoqXG4gICAgICogQE92ZXJyaWRlIHN1Ym1lbnVcbiAgICAgKi9cbiAgICBvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBmb3JtYXRDb250ZXh0ID0gdGhpcy5jb250ZXh0LmZvcm1hdEJsb2NrO1xuICAgICAgICBjb25zdCBmb3JtYXRMaXN0ID0gZm9ybWF0Q29udGV4dC5fZm9ybWF0TGlzdDtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZm9ybWF0Q29udGV4dC50YXJnZXRUZXh0O1xuICAgICAgICBjb25zdCBjdXJyZW50Rm9ybWF0ID0gKHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnKSB8fCAnJykgKyAodGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS1jbGFzcycpIHx8ICcnKTtcblxuICAgICAgICBpZiAoY3VycmVudEZvcm1hdCAhPT0gZm9ybWF0Q29udGV4dC5jdXJyZW50Rm9ybWF0KSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gZm9ybWF0TGlzdC5sZW5ndGgsIGY7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIGYgPSBmb3JtYXRMaXN0W2ldO1xuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50Rm9ybWF0ID09PSBmLmdldEF0dHJpYnV0ZSgnZGF0YS12YWx1ZScpICsgZi5nZXRBdHRyaWJ1dGUoJ2RhdGEtY2xhc3MnKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnV0aWwuYWRkQ2xhc3MoZiwgJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbC5yZW1vdmVDbGFzcyhmLCAnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3JtYXRDb250ZXh0LmN1cnJlbnRGb3JtYXQgPSBjdXJyZW50Rm9ybWF0O1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHBpY2tVcDogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIGxldCB0YXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgbGV0IGNvbW1hbmQgPSBudWxsLCB2YWx1ZSA9IG51bGwsIHRhZyA9IG51bGwsIGNsYXNzTmFtZSA9ICcnO1xuICAgICAgICBcbiAgICAgICAgd2hpbGUgKCFjb21tYW5kICYmICEvVUwvaS50ZXN0KHRhcmdldC50YWdOYW1lKSkge1xuICAgICAgICAgICAgY29tbWFuZCA9IHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY29tbWFuZCcpO1xuICAgICAgICAgICAgdmFsdWUgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJyk7XG4gICAgICAgICAgICBjbGFzc05hbWUgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLWNsYXNzJyk7XG4gICAgICAgICAgICBpZiAoY29tbWFuZCkge1xuICAgICAgICAgICAgICAgIHRhZyA9IHRhcmdldC5maXJzdENoaWxkO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnBhcmVudE5vZGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWNvbW1hbmQpIHJldHVybjtcblxuICAgICAgICAvLyBibG9ja3F1b3RlXG4gICAgICAgIGlmIChjb21tYW5kID09PSAncmFuZ2UnKSB7XG4gICAgICAgICAgICBjb25zdCByYW5nZUVsZW1lbnQgPSB0YWcuY2xvbmVOb2RlKGZhbHNlKTtcbiAgICAgICAgICAgIHRoaXMuYXBwbHlSYW5nZUZvcm1hdEVsZW1lbnQocmFuZ2VFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBmcmVlLCByZXBsYWNlXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IHJhbmdlID0gdGhpcy5nZXRSYW5nZSgpO1xuICAgICAgICAgICAgbGV0IHNlbGVjdGVkRm9ybXN0cyA9IHRoaXMuZ2V0U2VsZWN0ZWRFbGVtZW50c0FuZENvbXBvbmVudHMoZmFsc2UpO1xuXG4gICAgICAgICAgICBpZiAoc2VsZWN0ZWRGb3Jtc3RzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJhbmdlID0gdGhpcy5nZXRSYW5nZV9hZGRMaW5lKHJhbmdlLCBudWxsKTtcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEZvcm1zdHMgPSB0aGlzLmdldFNlbGVjdGVkRWxlbWVudHNBbmRDb21wb25lbnRzKGZhbHNlKTtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWRGb3Jtc3RzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBzdGFydE9mZnNldCA9IHJhbmdlLnN0YXJ0T2Zmc2V0O1xuICAgICAgICAgICAgY29uc3QgZW5kT2Zmc2V0ID0gcmFuZ2UuZW5kT2Zmc2V0O1xuXG4gICAgICAgICAgICBjb25zdCB1dGlsID0gdGhpcy51dGlsO1xuICAgICAgICAgICAgbGV0IGZpcnN0ID0gc2VsZWN0ZWRGb3Jtc3RzWzBdO1xuICAgICAgICAgICAgbGV0IGxhc3QgPSBzZWxlY3RlZEZvcm1zdHNbc2VsZWN0ZWRGb3Jtc3RzLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgY29uc3QgZmlyc3RQYXRoID0gdXRpbC5nZXROb2RlUGF0aChyYW5nZS5zdGFydENvbnRhaW5lciwgZmlyc3QsIG51bGwsIG51bGwpO1xuICAgICAgICAgICAgY29uc3QgbGFzdFBhdGggPSB1dGlsLmdldE5vZGVQYXRoKHJhbmdlLmVuZENvbnRhaW5lciwgbGFzdCwgbnVsbCwgbnVsbCk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIC8vIHJlbW92ZSBzZWxlY3RlZCBsaXN0XG4gICAgICAgICAgICBjb25zdCBybGlzdCA9IHRoaXMuZGV0YWNoTGlzdChzZWxlY3RlZEZvcm1zdHMsIGZhbHNlKTtcbiAgICAgICAgICAgIGlmIChybGlzdC5zYykgZmlyc3QgPSBybGlzdC5zYztcbiAgICAgICAgICAgIGlmIChybGlzdC5lYykgbGFzdCA9IHJsaXN0LmVjO1xuXG4gICAgICAgICAgICAvLyBjaGFuZ2UgZm9ybWF0IHRhZ1xuICAgICAgICAgICAgdGhpcy5zZXRSYW5nZSh1dGlsLmdldE5vZGVGcm9tUGF0aChmaXJzdFBhdGgsIGZpcnN0KSwgc3RhcnRPZmZzZXQsIHV0aWwuZ2V0Tm9kZUZyb21QYXRoKGxhc3RQYXRoLCBsYXN0KSwgZW5kT2Zmc2V0KTtcbiAgICAgICAgICAgIGNvbnN0IG1vZGlmaWVkRm9ybXN0cyA9IHRoaXMuZ2V0U2VsZWN0ZWRFbGVtZW50c0FuZENvbXBvbmVudHMoZmFsc2UpO1xuXG4gICAgICAgICAgICAvLyBmcmVlIGZvcm1hdFxuICAgICAgICAgICAgaWYgKGNvbW1hbmQgPT09ICdmcmVlJykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxlbiA9IG1vZGlmaWVkRm9ybXN0cy5sZW5ndGggLSAxO1xuICAgICAgICAgICAgICAgIGxldCBwYXJlbnROb2RlID0gbW9kaWZpZWRGb3Jtc3RzW2xlbl0ucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICBsZXQgZnJlZUVsZW1lbnQgPSB0YWcuY2xvbmVOb2RlKGZhbHNlKTtcbiAgICAgICAgICAgICAgICBjb25zdCBmb2N1c0VsZW1lbnQgPSBmcmVlRWxlbWVudDtcbiAgICBcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gbGVuLCBmLCBodG1sLCBiZWZvcmUsIG5leHQsIGlubmVyLCBpc0NvbXAsIGZpcnN0ID0gdHJ1ZTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgZiA9IG1vZGlmaWVkRm9ybXN0c1tpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGYgPT09ICghbW9kaWZpZWRGb3Jtc3RzW2kgKyAxXSA/IG51bGwgOiBtb2RpZmllZEZvcm1zdHNbaSArIDFdLnBhcmVudE5vZGUpKSBjb250aW51ZTtcbiAgICBcbiAgICAgICAgICAgICAgICAgICAgaXNDb21wID0gdXRpbC5pc0NvbXBvbmVudChmKTtcbiAgICAgICAgICAgICAgICAgICAgaHRtbCA9IGlzQ29tcCA/ICcnIDogZi5pbm5lckhUTUwucmVwbGFjZSgvKD8hPilcXHMrKD89PCl8XFxuL2csICcgJyk7XG4gICAgICAgICAgICAgICAgICAgIGJlZm9yZSA9IHV0aWwuZ2V0UGFyZW50RWxlbWVudChmLCBmdW5jdGlvbiAoY3VycmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQucGFyZW50Tm9kZSA9PT0gcGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnROb2RlICE9PSBmLnBhcmVudE5vZGUgfHwgaXNDb21wKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5pc0Zvcm1hdEVsZW1lbnQocGFyZW50Tm9kZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGZyZWVFbGVtZW50LCBwYXJlbnROb2RlLm5leHRTaWJsaW5nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gcGFyZW50Tm9kZS5wYXJlbnROb2RlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlLmluc2VydEJlZm9yZShmcmVlRWxlbWVudCwgYmVmb3JlID8gYmVmb3JlLm5leHRTaWJsaW5nIDogbnVsbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZSA9IGYucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dCA9IGZyZWVFbGVtZW50Lm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQgJiYgZnJlZUVsZW1lbnQubm9kZU5hbWUgPT09IG5leHQubm9kZU5hbWUgJiYgdXRpbC5pc1NhbWVBdHRyaWJ1dGVzKGZyZWVFbGVtZW50LCBuZXh0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZWVFbGVtZW50LmlubmVySFRNTCArPSAnPEJSPicgKyBuZXh0LmlubmVySFRNTDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW0obmV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGZyZWVFbGVtZW50ID0gdGFnLmNsb25lTm9kZShmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaXJzdCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgICAgICAgICAgaW5uZXIgPSBmcmVlRWxlbWVudC5pbm5lckhUTUw7XG4gICAgICAgICAgICAgICAgICAgIGZyZWVFbGVtZW50LmlubmVySFRNTCA9ICgoZmlyc3QgfHwgIWh0bWwgfHwgIWlubmVyIHx8IC88YnI+JC9pLnRlc3QoaHRtbCkpID8gaHRtbCA6IGh0bWwgKyAnPEJSPicpICsgaW5uZXI7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGZyZWVFbGVtZW50LCBmKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgPSBmLm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQgJiYgZnJlZUVsZW1lbnQubm9kZU5hbWUgPT09IG5leHQubm9kZU5hbWUgJiYgdXRpbC5pc1NhbWVBdHRyaWJ1dGVzKGZyZWVFbGVtZW50LCBuZXh0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZWVFbGVtZW50LmlubmVySFRNTCArPSAnPEJSPicgKyBuZXh0LmlubmVySFRNTDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW0obmV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZXYgPSBmcmVlRWxlbWVudC5wcmV2aW91c1NpYmxpbmc7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJldiAmJiBmcmVlRWxlbWVudC5ub2RlTmFtZSA9PT0gcHJldi5ub2RlTmFtZSAmJiB1dGlsLmlzU2FtZUF0dHJpYnV0ZXMoZnJlZUVsZW1lbnQsIHByZXYpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldi5pbm5lckhUTUwgKz0gJzxCUj4nICsgZnJlZUVsZW1lbnQuaW5uZXJIVE1MO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlSXRlbShmcmVlRWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoIWlzQ29tcCkgdXRpbC5yZW1vdmVJdGVtKGYpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFodG1sKSBmaXJzdCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgICAgICB0aGlzLnNldFJhbmdlKGZvY3VzRWxlbWVudCwgMCwgZm9jdXNFbGVtZW50LCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHJlcGxhY2UgZm9ybWF0XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gbW9kaWZpZWRGb3Jtc3RzLmxlbmd0aCwgbm9kZSwgbmV3Rm9ybWF0OyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG1vZGlmaWVkRm9ybXN0c1tpXTtcbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIGlmICgobm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9PSB2YWx1ZS50b0xvd2VyQ2FzZSgpIHx8IChub2RlLmNsYXNzTmFtZS5tYXRjaCgvKFxcc3xeKV9fc2VfX2Zvcm1hdF9fW15cXHNdKy8pIHx8IFsnJ10pWzBdLnRyaW0oKSAhPT0gY2xhc3NOYW1lKSAmJiAhdXRpbC5pc0NvbXBvbmVudChub2RlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3Rm9ybWF0ID0gdGFnLmNsb25lTm9kZShmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB1dGlsLmNvcHlGb3JtYXRBdHRyaWJ1dGVzKG5ld0Zvcm1hdCwgbm9kZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdGb3JtYXQuaW5uZXJIVE1MID0gbm9kZS5pbm5lckhUTUw7XG4gICAgXG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG5ld0Zvcm1hdCwgbm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT09IDApIGZpcnN0ID0gbmV3Rm9ybWF0IHx8IG5vZGU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpID09PSBsZW4gLSAxKSBsYXN0ID0gbmV3Rm9ybWF0IHx8IG5vZGU7XG4gICAgICAgICAgICAgICAgICAgIG5ld0Zvcm1hdCA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgICAgIHRoaXMuc2V0UmFuZ2UodXRpbC5nZXROb2RlRnJvbVBhdGgoZmlyc3RQYXRoLCBmaXJzdCksIHN0YXJ0T2Zmc2V0LCB1dGlsLmdldE5vZGVGcm9tUGF0aChsYXN0UGF0aCwgbGFzdCksIGVuZE9mZnNldCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGhpc3Rvcnkgc3RhY2tcbiAgICAgICAgICAgIHRoaXMuaGlzdG9yeS5wdXNoKGZhbHNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3VibWVudU9mZigpO1xuICAgIH1cbn07XG4iLCIvKlxuICogd3lzaXd5ZyB3ZWIgZWRpdG9yXG4gKlxuICogc3VuZWRpdG9yLmpzXG4gKiBDb3B5cmlnaHQgMjAxOTcgSmlIb25nIExlZS5cbiAqIE1JVCBsaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICBuYW1lOiAnbGluZUhlaWdodCcsXG4gICAgZGlzcGxheTogJ3N1Ym1lbnUnLFxuICAgIGFkZDogZnVuY3Rpb24gKGNvcmUsIHRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IGNvcmUuY29udGV4dDtcbiAgICAgICAgY29udGV4dC5saW5lSGVpZ2h0ID0ge1xuICAgICAgICAgICAgX3NpemVMaXN0OiBudWxsLFxuICAgICAgICAgICAgY3VycmVudFNpemU6IC0xXG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqIHNldCBzdWJtZW51ICovXG4gICAgICAgIGxldCBsaXN0RGl2ID0gdGhpcy5zZXRTdWJtZW51LmNhbGwoY29yZSk7XG4gICAgICAgIGxldCBsaXN0VWwgPSBsaXN0RGl2LnF1ZXJ5U2VsZWN0b3IoJ3VsJyk7XG5cbiAgICAgICAgLyoqIGFkZCBldmVudCBsaXN0ZW5lcnMgKi9cbiAgICAgICAgbGlzdFVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5waWNrdXAuYmluZChjb3JlKSk7XG5cbiAgICAgICAgY29udGV4dC5saW5lSGVpZ2h0Ll9zaXplTGlzdCA9IGxpc3RVbC5xdWVyeVNlbGVjdG9yQWxsKCdsaSBidXR0b24nKTtcblxuICAgICAgICAvKiogYXBwZW5kIHRhcmdldCBidXR0b24gbWVudSAqL1xuICAgICAgICBjb3JlLmluaXRNZW51VGFyZ2V0KHRoaXMubmFtZSwgdGFyZ2V0RWxlbWVudCwgbGlzdERpdik7XG5cbiAgICAgICAgLyoqIGVtcHR5IG1lbW9yeSAqL1xuICAgICAgICBsaXN0RGl2ID0gbnVsbCwgbGlzdFVsID0gbnVsbDtcbiAgICB9LFxuXG4gICAgc2V0U3VibWVudTogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBvcHRpb24gPSB0aGlzLmNvbnRleHQub3B0aW9uO1xuICAgICAgICBjb25zdCBsYW5nID0gdGhpcy5sYW5nO1xuICAgICAgICBjb25zdCBsaXN0RGl2ID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xuXG4gICAgICAgIGxpc3REaXYuY2xhc3NOYW1lID0gJ3NlLXN1Ym1lbnUgc2UtbGlzdC1sYXllcic7XG5cbiAgICAgICAgY29uc3Qgc2l6ZUxpc3QgPSAhb3B0aW9uLmxpbmVIZWlnaHRzID8gW1xuICAgICAgICAgICAge3RleHQ6ICcxJywgdmFsdWU6IDF9LFxuICAgICAgICAgICAge3RleHQ6ICcxLjE1JywgdmFsdWU6IDEuMTV9LFxuICAgICAgICAgICAge3RleHQ6ICcxLjUnLCB2YWx1ZTogMS41fSxcbiAgICAgICAgICAgIHt0ZXh0OiAnMicsIHZhbHVlOiAyfVxuICAgICAgICBdIDogb3B0aW9uLmxpbmVIZWlnaHRzO1xuXG4gICAgICAgIGxldCBsaXN0ID0gJzxkaXYgY2xhc3M9XCJzZS1saXN0LWlubmVyXCI+JyArXG4gICAgICAgICAgICAgICAgJzx1bCBjbGFzcz1cInNlLWxpc3QtYmFzaWNcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxsaT48YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImRlZmF1bHRfdmFsdWUgc2UtYnRuLWxpc3RcIiB0aXRsZT1cIicgKyBsYW5nLnRvb2xiYXIuZGVmYXVsdCArICdcIj4oJyArIGxhbmcudG9vbGJhci5kZWZhdWx0ICsgJyk8L2J1dHRvbj48L2xpPic7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBzaXplTGlzdC5sZW5ndGgsIHRleHQsIHNpemU7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgc2l6ZSA9IHNpemVMaXN0W2ldO1xuICAgICAgICAgICAgbGlzdCArPSAnPGxpPjxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2UtYnRuLWxpc3RcIiBkYXRhLXZhbHVlPVwiJyArIHNpemUudmFsdWUgKyAnXCIgdGl0bGU9XCInICsgc2l6ZS50ZXh0ICsgJ1wiPicgKyBzaXplLnRleHQgKyAnPC9idXR0b24+PC9saT4nO1xuICAgICAgICB9XG4gICAgICAgIGxpc3QgKz0gJzwvdWw+PC9kaXY+JztcblxuICAgICAgICBsaXN0RGl2LmlubmVySFRNTCA9IGxpc3Q7XG5cbiAgICAgICAgcmV0dXJuIGxpc3REaXY7XG4gICAgfSxcblxuICAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgc3VibWVudVxuICAgICAqL1xuICAgIG9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGxpbmVIZWlnaHRDb250ZXh0ID0gdGhpcy5jb250ZXh0LmxpbmVIZWlnaHQ7XG4gICAgICAgIGNvbnN0IHNpemVMaXN0ID0gbGluZUhlaWdodENvbnRleHQuX3NpemVMaXN0O1xuICAgICAgICBjb25zdCBmb3JtYXQgPSB0aGlzLnV0aWwuZ2V0Rm9ybWF0RWxlbWVudCh0aGlzLmdldFNlbGVjdGlvbk5vZGUoKSk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRTaXplID0gIWZvcm1hdCA/ICcnIDogZm9ybWF0LnN0eWxlLmxpbmVIZWlnaHQgKyAnJztcblxuICAgICAgICBpZiAoY3VycmVudFNpemUgIT09IGxpbmVIZWlnaHRDb250ZXh0LmN1cnJlbnRTaXplKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gc2l6ZUxpc3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudFNpemUgPT09IHNpemVMaXN0W2ldLmdldEF0dHJpYnV0ZSgnZGF0YS12YWx1ZScpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbC5hZGRDbGFzcyhzaXplTGlzdFtpXSwgJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbC5yZW1vdmVDbGFzcyhzaXplTGlzdFtpXSwgJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGluZUhlaWdodENvbnRleHQuY3VycmVudFNpemUgPSBjdXJyZW50U2l6ZTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBwaWNrdXA6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGlmICghL15CVVRUT04kL2kudGVzdChlLnRhcmdldC50YWdOYW1lKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIGNvbnN0IHZhbHVlID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJykgfHwgJyc7XG4gICAgICAgIGNvbnN0IGZvcm1hdHMgPSB0aGlzLmdldFNlbGVjdGVkRWxlbWVudHMoKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gZm9ybWF0cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgZm9ybWF0c1tpXS5zdHlsZS5saW5lSGVpZ2h0ID0gdmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN1Ym1lbnVPZmYoKTtcblxuICAgICAgICAvLyBoaXN0b3J5IHN0YWNrXG4gICAgICAgIHRoaXMuaGlzdG9yeS5wdXNoKGZhbHNlKTtcbiAgICB9XG59O1xuIiwiLypcbiAqIHd5c2l3eWcgd2ViIGVkaXRvclxuICpcbiAqIHN1bmVkaXRvci5qc1xuICogQ29weXJpZ2h0IDIwMTcgSmlIb25nIExlZS5cbiAqIE1JVCBsaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICBuYW1lOiAncGFyYWdyYXBoU3R5bGUnLFxuICAgIGRpc3BsYXk6ICdzdWJtZW51JyxcbiAgICBhZGQ6IGZ1bmN0aW9uIChjb3JlLCB0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBjb3JlLmNvbnRleHQ7XG4gICAgICAgIGNvbnRleHQucGFyYWdyYXBoU3R5bGUgPSB7XG4gICAgICAgICAgICBfY2xhc3NMaXN0OiBudWxsXG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqIHNldCBzdWJtZW51ICovXG4gICAgICAgIGxldCBsaXN0RGl2ID0gdGhpcy5zZXRTdWJtZW51LmNhbGwoY29yZSk7XG5cbiAgICAgICAgLyoqIGFkZCBldmVudCBsaXN0ZW5lcnMgKi9cbiAgICAgICAgbGlzdERpdi5xdWVyeVNlbGVjdG9yKCd1bCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5waWNrVXAuYmluZChjb3JlKSk7XG5cbiAgICAgICAgY29udGV4dC5wYXJhZ3JhcGhTdHlsZS5fY2xhc3NMaXN0ID0gbGlzdERpdi5xdWVyeVNlbGVjdG9yQWxsKCdsaSBidXR0b24nKTtcblxuICAgICAgICAvKiogYXBwZW5kIHRhcmdldCBidXR0b24gbWVudSAqL1xuICAgICAgICBjb3JlLmluaXRNZW51VGFyZ2V0KHRoaXMubmFtZSwgdGFyZ2V0RWxlbWVudCwgbGlzdERpdik7XG5cbiAgICAgICAgLyoqIGVtcHR5IG1lbW9yeSAqL1xuICAgICAgICBsaXN0RGl2ID0gbnVsbDtcbiAgICB9LFxuXG4gICAgc2V0U3VibWVudTogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBvcHRpb24gPSB0aGlzLmNvbnRleHQub3B0aW9uO1xuICAgICAgICBjb25zdCBsaXN0RGl2ID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xuICAgICAgICBsaXN0RGl2LmNsYXNzTmFtZSA9ICdzZS1zdWJtZW51IHNlLWxpc3QtbGF5ZXIgc2UtbGlzdC1mb3JtYXQnO1xuXG4gICAgICAgIGNvbnN0IG1lbnVMYW5nID0gdGhpcy5sYW5nLm1lbnU7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRMaXN0ID0ge1xuICAgICAgICAgICAgc3BhY2VkOiB7XG4gICAgICAgICAgICAgICAgbmFtZTogbWVudUxhbmcuc3BhY2VkLFxuICAgICAgICAgICAgICAgIGNsYXNzOiAnX19zZV9fcC1zcGFjZWQnLFxuICAgICAgICAgICAgICAgIF9jbGFzczogJydcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBib3JkZXJlZDoge1xuICAgICAgICAgICAgICAgIG5hbWU6IG1lbnVMYW5nLmJvcmRlcmVkLFxuICAgICAgICAgICAgICAgIGNsYXNzOiAnX19zZV9fcC1ib3JkZXJlZCcsXG4gICAgICAgICAgICAgICAgX2NsYXNzOiAnJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG5lb246IHtcbiAgICAgICAgICAgICAgICBuYW1lOiBtZW51TGFuZy5uZW9uLFxuICAgICAgICAgICAgICAgIGNsYXNzOiAnX19zZV9fcC1uZW9uJyxcbiAgICAgICAgICAgICAgICBfY2xhc3M6ICcnXG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHBhcmFncmFwaFN0eWxlcyA9ICFvcHRpb24ucGFyYWdyYXBoU3R5bGVzIHx8IG9wdGlvbi5wYXJhZ3JhcGhTdHlsZXMubGVuZ3RoID09PSAwID8gWydzcGFjZWQnLCAnYm9yZGVyZWQnLCAnbmVvbiddIDogb3B0aW9uLnBhcmFncmFwaFN0eWxlcztcblxuICAgICAgICBsZXQgbGlzdCA9ICc8ZGl2IGNsYXNzPVwic2UtbGlzdC1pbm5lclwiPjx1bCBjbGFzcz1cInNlLWxpc3QtYmFzaWNcIj4nO1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gcGFyYWdyYXBoU3R5bGVzLmxlbmd0aCwgcCwgbmFtZSwgYXR0cnMsIF9jbGFzczsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBwID0gcGFyYWdyYXBoU3R5bGVzW2ldO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHAgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdFN0eWxlID0gZGVmYXVsdExpc3RbcC50b0xvd2VyQ2FzZSgpXTtcbiAgICAgICAgICAgICAgICBpZiAoIWRlZmF1bHRTdHlsZSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgcCA9IGRlZmF1bHRTdHlsZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbmFtZSA9IHAubmFtZTtcbiAgICAgICAgICAgIGF0dHJzID0gcC5jbGFzcyA/ICcgY2xhc3M9XCInICsgcC5jbGFzcyArICdcIicgOiAnJztcbiAgICAgICAgICAgIF9jbGFzcyA9IHAuX2NsYXNzO1xuXG4gICAgICAgICAgICBsaXN0ICs9ICc8bGk+JyArXG4gICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2UtYnRuLWxpc3QnICsgKF9jbGFzcyA/ICcgJyArIF9jbGFzczogJycpICsgJ1wiIGRhdGEtdmFsdWU9XCInICsgcC5jbGFzcyArICdcIiB0aXRsZT1cIicgKyBuYW1lICsgJ1wiPicgK1xuICAgICAgICAgICAgICAgICAgICAnPGRpdicgKyBhdHRycyArICc+JyArIG5hbWUgKyAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgJzwvYnV0dG9uPjwvbGk+JztcbiAgICAgICAgfVxuICAgICAgICBsaXN0ICs9ICc8L3VsPjwvZGl2Pic7XG5cbiAgICAgICAgbGlzdERpdi5pbm5lckhUTUwgPSBsaXN0O1xuXG4gICAgICAgIHJldHVybiBsaXN0RGl2O1xuICAgIH0sXG5cbiAgICAgLyoqXG4gICAgICogQE92ZXJyaWRlIHN1Ym1lbnVcbiAgICAgKi9cbiAgICBvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwYXJhZ3JhcGhDb250ZXh0ID0gdGhpcy5jb250ZXh0LnBhcmFncmFwaFN0eWxlO1xuICAgICAgICBjb25zdCBwYXJhZ3JhcGhMaXN0ID0gcGFyYWdyYXBoQ29udGV4dC5fY2xhc3NMaXN0O1xuICAgICAgICBjb25zdCBjdXJyZW50Rm9ybWF0ID0gdGhpcy51dGlsLmdldEZvcm1hdEVsZW1lbnQodGhpcy5nZXRTZWxlY3Rpb25Ob2RlKCkpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBwYXJhZ3JhcGhMaXN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy51dGlsLmhhc0NsYXNzKGN1cnJlbnRGb3JtYXQsIHBhcmFncmFwaExpc3RbaV0uZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJykpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51dGlsLmFkZENsYXNzKHBhcmFncmFwaExpc3RbaV0sICdhY3RpdmUnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy51dGlsLnJlbW92ZUNsYXNzKHBhcmFncmFwaExpc3RbaV0sICdhY3RpdmUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBwaWNrVXA6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICBsZXQgdGFyZ2V0ID0gZS50YXJnZXQ7XG4gICAgICAgIGxldCB2YWx1ZSA9IG51bGw7XG4gICAgICAgIFxuICAgICAgICB3aGlsZSAoIS9eVUwkL2kudGVzdCh0YXJnZXQudGFnTmFtZSkpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS12YWx1ZScpO1xuICAgICAgICAgICAgaWYgKHZhbHVlKSBicmVhaztcbiAgICAgICAgICAgIHRhcmdldCA9IHRhcmdldC5wYXJlbnROb2RlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF2YWx1ZSkgcmV0dXJuO1xuXG4gICAgICAgIGxldCBzZWxlY3RlZEZvcm1zdHMgPSB0aGlzLmdldFNlbGVjdGVkRWxlbWVudHMoKTtcbiAgICAgICAgaWYgKHNlbGVjdGVkRm9ybXN0cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmFuZ2VfYWRkTGluZSh0aGlzLmdldFJhbmdlKCksIG51bGwpO1xuICAgICAgICAgICAgc2VsZWN0ZWRGb3Jtc3RzID0gdGhpcy5nZXRTZWxlY3RlZEVsZW1lbnRzKCk7XG4gICAgICAgICAgICBpZiAoc2VsZWN0ZWRGb3Jtc3RzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY2hhbmdlIGZvcm1hdCBjbGFzc1xuICAgICAgICBjb25zdCB0b2dnbGVDbGFzcyA9IHRoaXMudXRpbC5oYXNDbGFzcyh0YXJnZXQsICdhY3RpdmUnKSA/IHRoaXMudXRpbC5yZW1vdmVDbGFzcy5iaW5kKHRoaXMudXRpbCkgOiB0aGlzLnV0aWwuYWRkQ2xhc3MuYmluZCh0aGlzLnV0aWwpO1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gc2VsZWN0ZWRGb3Jtc3RzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB0b2dnbGVDbGFzcyhzZWxlY3RlZEZvcm1zdHNbaV0sIHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3VibWVudU9mZigpO1xuXG4gICAgICAgIC8vIGhpc3Rvcnkgc3RhY2tcbiAgICAgICAgdGhpcy5oaXN0b3J5LnB1c2goZmFsc2UpO1xuICAgIH1cbn07XG4iLCIvKlxuICogd3lzaXd5ZyB3ZWIgZWRpdG9yXG4gKlxuICogc3VuZWRpdG9yLmpzXG4gKiBDb3B5cmlnaHQgMjAxNyBKaUhvbmcgTGVlLlxuICogTUlUIGxpY2Vuc2UuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIG5hbWU6ICd0ZXh0U3R5bGUnLFxuICAgIGRpc3BsYXk6ICdzdWJtZW51JyxcbiAgICBhZGQ6IGZ1bmN0aW9uIChjb3JlLCB0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBjb3JlLmNvbnRleHQ7XG4gICAgICAgIGNvbnRleHQudGV4dFN0eWxlID0ge1xuICAgICAgICAgICAgX3N0eWxlTGlzdDogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKiBzZXQgc3VibWVudSAqL1xuICAgICAgICBsZXQgbGlzdERpdiA9IHRoaXMuc2V0U3VibWVudS5jYWxsKGNvcmUpO1xuICAgICAgICBsZXQgbGlzdFVsID0gbGlzdERpdi5xdWVyeVNlbGVjdG9yKCd1bCcpO1xuXG4gICAgICAgIC8qKiBhZGQgZXZlbnQgbGlzdGVuZXJzICovXG4gICAgICAgIGxpc3RVbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMucGlja3VwLmJpbmQoY29yZSkpO1xuXG4gICAgICAgIGNvbnRleHQudGV4dFN0eWxlLl9zdHlsZUxpc3QgPSBsaXN0RGl2LnF1ZXJ5U2VsZWN0b3JBbGwoJ2xpIGJ1dHRvbicpO1xuXG4gICAgICAgIC8qKiBhcHBlbmQgdGFyZ2V0IGJ1dHRvbiBtZW51ICovXG4gICAgICAgIGNvcmUuaW5pdE1lbnVUYXJnZXQodGhpcy5uYW1lLCB0YXJnZXRFbGVtZW50LCBsaXN0RGl2KTtcblxuICAgICAgICAvKiogZW1wdHkgbWVtb3J5ICovXG4gICAgICAgIGxpc3REaXYgPSBudWxsLCBsaXN0VWwgPSBudWxsO1xuICAgIH0sXG5cbiAgICBzZXRTdWJtZW51OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMuY29udGV4dC5vcHRpb247XG4gICAgICAgIGNvbnN0IGxpc3REaXYgPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XG4gICAgICAgIGxpc3REaXYuY2xhc3NOYW1lID0gJ3NlLXN1Ym1lbnUgc2UtbGlzdC1sYXllciBzZS1saXN0LWZvcm1hdCc7XG5cbiAgICAgICAgY29uc3QgZGVmYXVsdExpc3QgPSB7XG4gICAgICAgICAgICBjb2RlOiB7XG4gICAgICAgICAgICAgICAgbmFtZTogdGhpcy5sYW5nLm1lbnUuY29kZSxcbiAgICAgICAgICAgICAgICBjbGFzczogJ19fc2VfX3QtY29kZScsXG4gICAgICAgICAgICAgICAgdGFnOiAnY29kZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdHJhbnNsdWNlbnQ6IHtcbiAgICAgICAgICAgICAgICBuYW1lOiB0aGlzLmxhbmcubWVudS50cmFuc2x1Y2VudCxcbiAgICAgICAgICAgICAgICBzdHlsZTogJ29wYWNpdHk6IDAuNTsnLFxuICAgICAgICAgICAgICAgIHRhZzogJ3NwYW4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNoYWRvdzoge1xuICAgICAgICAgICAgICAgIG5hbWU6IHRoaXMubGFuZy5tZW51LnNoYWRvdyxcbiAgICAgICAgICAgICAgICBjbGFzczogJ19fc2VfX3Qtc2hhZG93JyxcbiAgICAgICAgICAgICAgICB0YWc6ICdzcGFuJyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc3R5bGVMaXN0ID0gIW9wdGlvbi50ZXh0U3R5bGVzID8gdGhpcy5fdy5PYmplY3Qua2V5cyhkZWZhdWx0TGlzdCkgOiBvcHRpb24udGV4dFN0eWxlcztcblxuICAgICAgICBsZXQgbGlzdCA9ICc8ZGl2IGNsYXNzPVwic2UtbGlzdC1pbm5lclwiPjx1bCBjbGFzcz1cInNlLWxpc3QtYmFzaWNcIj4nO1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gc3R5bGVMaXN0Lmxlbmd0aCwgdCwgdGFnLCBuYW1lLCBhdHRycywgY29tbWFuZCwgdmFsdWUsIF9jbGFzczsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB0ID0gc3R5bGVMaXN0W2ldO1xuICAgICAgICAgICAgYXR0cnMgPSAnJywgdmFsdWUgPSAnJywgY29tbWFuZCA9IFtdO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdFN0eWxlID0gZGVmYXVsdExpc3RbdC50b0xvd2VyQ2FzZSgpXTtcbiAgICAgICAgICAgICAgICBpZiAoIWRlZmF1bHRTdHlsZSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgdCA9IGRlZmF1bHRTdHlsZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbmFtZSA9IHQubmFtZTtcbiAgICAgICAgICAgIHRhZyA9IHQudGFnIHx8ICdzcGFuJztcbiAgICAgICAgICAgIF9jbGFzcyA9IHQuX2NsYXNzO1xuXG4gICAgICAgICAgICBpZiAodC5zdHlsZSkge1xuICAgICAgICAgICAgICAgIGF0dHJzICs9ICcgc3R5bGU9XCInICsgdC5zdHlsZSArICdcIic7XG4gICAgICAgICAgICAgICAgdmFsdWUgKz0gdC5zdHlsZS5yZXBsYWNlKC86W147XSsoO3wkKVxccyovZywgJywnKTtcbiAgICAgICAgICAgICAgICBjb21tYW5kLnB1c2goJ3N0eWxlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodC5jbGFzcykge1xuICAgICAgICAgICAgICAgIGF0dHJzICs9ICcgY2xhc3M9XCInICsgdC5jbGFzcyArICdcIic7XG4gICAgICAgICAgICAgICAgdmFsdWUgKz0gJy4nICsgdC5jbGFzcy50cmltKCkucmVwbGFjZSgvXFxzKy9nLCAnLC4nKTtcbiAgICAgICAgICAgICAgICBjb21tYW5kLnB1c2goJ2NsYXNzJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvLCQvLCAnJyk7XG5cbiAgICAgICAgICAgIGxpc3QgKz0gJzxsaT4nICtcbiAgICAgICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzZS1idG4tbGlzdCcgKyAoX2NsYXNzID8gJyAnICsgX2NsYXNzOiAnJykgKyAnXCIgZGF0YS1jb21tYW5kPVwiJyArIHRhZyArICdcIiBkYXRhLXZhbHVlPVwiJyArIHZhbHVlICsgJ1wiIHRpdGxlPVwiJyArIG5hbWUgKyAnXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICc8JyArIHRhZyArIGF0dHJzICsgJz4nICsgbmFtZSArICAnPC8nICsgdGFnICsgJz4nICtcbiAgICAgICAgICAgICAgICAnPC9idXR0b24+PC9saT4nO1xuICAgICAgICB9XG4gICAgICAgIGxpc3QgKz0gJzwvdWw+PC9kaXY+JztcblxuICAgICAgICBsaXN0RGl2LmlubmVySFRNTCA9IGxpc3Q7XG5cbiAgICAgICAgcmV0dXJuIGxpc3REaXY7XG4gICAgfSxcblxuICAgICAvKipcbiAgICAgKiBAT3ZlcnJpZGUgc3VibWVudVxuICAgICAqL1xuICAgIG9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHV0aWwgPSB0aGlzLnV0aWw7XG4gICAgICAgIGNvbnN0IHRleHRTdHlsZUNvbnRleHQgPSB0aGlzLmNvbnRleHQudGV4dFN0eWxlO1xuICAgICAgICBjb25zdCBzdHlsZUJ1dHRvbkxpc3QgPSB0ZXh0U3R5bGVDb250ZXh0Ll9zdHlsZUxpc3Q7XG4gICAgICAgIGNvbnN0IHNlbGVjdGlvbk5vZGUgPSB0aGlzLmdldFNlbGVjdGlvbk5vZGUoKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gc3R5bGVCdXR0b25MaXN0Lmxlbmd0aCwgYnRuLCBkYXRhLCBhY3RpdmU7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgYnRuID0gc3R5bGVCdXR0b25MaXN0W2ldO1xuICAgICAgICAgICAgZGF0YSA9IGJ0bi5nZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnKS5zcGxpdCgnLCcpO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBmb3IgKGxldCB2ID0gMCwgbm9kZSwgdmFsdWU7IHYgPCBkYXRhLmxlbmd0aDsgdisrKSB7XG4gICAgICAgICAgICAgICAgbm9kZSA9IHNlbGVjdGlvbk5vZGU7XG4gICAgICAgICAgICAgICAgYWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgd2hpbGUgKG5vZGUgJiYgIXV0aWwuaXNGb3JtYXRFbGVtZW50KG5vZGUpICYmICF1dGlsLmlzQ29tcG9uZW50KG5vZGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IGJ0bi5nZXRBdHRyaWJ1dGUoJ2RhdGEtY29tbWFuZCcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gZGF0YVt2XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgvXlxcLi8udGVzdCh2YWx1ZSkgPyB1dGlsLmhhc0NsYXNzKG5vZGUsIHZhbHVlLnJlcGxhY2UoL15cXC4vLCAnJykpIDogISFub2RlLnN0eWxlW3ZhbHVlXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIWFjdGl2ZSkgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGFjdGl2ZSA/IHV0aWwuYWRkQ2xhc3MoYnRuLCAnYWN0aXZlJykgOiB1dGlsLnJlbW92ZUNsYXNzKGJ0biwgJ2FjdGl2ZScpO1xuICAgICAgICB9XG5cbiAgICB9LFxuXG4gICAgcGlja3VwOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgbGV0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICBsZXQgY29tbWFuZCA9IG51bGwsIHRhZyA9IG51bGw7XG4gICAgICAgIFxuICAgICAgICB3aGlsZSAoIWNvbW1hbmQgJiYgIS9VTC9pLnRlc3QodGFyZ2V0LnRhZ05hbWUpKSB7XG4gICAgICAgICAgICBjb21tYW5kID0gdGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS1jb21tYW5kJyk7XG4gICAgICAgICAgICBpZiAoY29tbWFuZCkge1xuICAgICAgICAgICAgICAgIHRhZyA9IHRhcmdldC5maXJzdENoaWxkO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnBhcmVudE5vZGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWNvbW1hbmQpIHJldHVybjtcblxuICAgICAgICBjb25zdCBjaGVja1N0eWxlcyA9IHRhZy5zdHlsZS5jc3NUZXh0LnJlcGxhY2UoLzouKyg7fCQpL2csICcsJykuc3BsaXQoJywnKTtcbiAgICAgICAgY2hlY2tTdHlsZXMucG9wKCk7XG5cbiAgICAgICAgY29uc3QgY2xhc3NlcyA9IHRhZy5jbGFzc0xpc3Q7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBjbGFzc2VzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBjaGVja1N0eWxlcy5wdXNoKCcuJyArIGNsYXNzZXNbaV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmV3Tm9kZSA9IHRoaXMudXRpbC5oYXNDbGFzcyh0YXJnZXQsICdhY3RpdmUnKSA/IG51bGwgOiB0YWcuY2xvbmVOb2RlKGZhbHNlKTtcbiAgICAgICAgY29uc3QgcmVtb3ZlTm9kZXMgPSBuZXdOb2RlID8gbnVsbCA6IFt0YWcubm9kZU5hbWVdO1xuICAgICAgICB0aGlzLm5vZGVDaGFuZ2UobmV3Tm9kZSwgY2hlY2tTdHlsZXMsIHJlbW92ZU5vZGVzLCB0cnVlKTtcblxuICAgICAgICB0aGlzLnN1Ym1lbnVPZmYoKTtcbiAgICB9XG59O1xuIiwiLypcbiAqIHd5c2l3eWcgd2ViIGVkaXRvclxuICpcbiAqIHN1bmVkaXRvci5qc1xuICogQ29weXJpZ2h0IDIwMTcgSmlIb25nIExlZS5cbiAqIE1JVCBsaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCBmaWxlQnJvd3NlciBmcm9tICcuLi9tb2R1bGVzL2ZpbGVCcm93c2VyJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIG5hbWU6ICdpbWFnZUdhbGxlcnknLFxuICAgIC8qKlxuICAgICAqIEBkZXNjcmlwdGlvbiBDb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb3JlIENvcmUgb2JqZWN0IFxuICAgICAqL1xuICAgIGFkZDogZnVuY3Rpb24gKGNvcmUpIHtcbiAgICAgICAgY29yZS5hZGRNb2R1bGUoW2ZpbGVCcm93c2VyXSk7XG5cbiAgICAgICAgY29uc3QgY29udGV4dCA9IGNvcmUuY29udGV4dDtcbiAgICAgICAgY29udGV4dC5pbWFnZUdhbGxlcnkgPSB7XG4gICAgICAgICAgICB0aXRsZTogY29yZS5sYW5nLnRvb2xiYXIuaW1hZ2VHYWxsZXJ5LCAvLyBAUmVxdWlyZWQgQE92ZXJyaWRlIGZpbGVCcm93c2VyIC0gRmlsZSBicm93c2VyIHdpbmRvdyB0aXRsZS5cbiAgICAgICAgICAgIHVybDogY29udGV4dC5vcHRpb25zLmltYWdlR2FsbGVyeVVybCwgLy8gQFJlcXVpcmVkIEBPdmVycmlkZSBmaWxlQnJvd3NlciAtIEZpbGUgc2VydmVyIHVybC5cbiAgICAgICAgICAgIGxpc3RDbGFzczogJ3NlLWltYWdlLWxpc3QnLCAvLyBAUmVxdWlyZWQgQE92ZXJyaWRlIGZpbGVCcm93c2VyIC0gQ2xhc3MgbmFtZSBvZiBsaXN0IGRpdi5cbiAgICAgICAgICAgIGl0ZW1UZW1wbGF0ZUhhbmRsZXI6IHRoaXMuZHJhd0l0ZW1zLCAvLyBAUmVxdWlyZWQgQE92ZXJyaWRlIGZpbGVCcm93c2VyIC0gRnVuY3Rpb24gdGhhdCBkZWZpbmVzIHRoZSBIVE1MIG9mIGFuIGZpbGUgaXRlbS5cbiAgICAgICAgICAgIHNlbGVjdG9ySGFuZGxlcjogdGhpcy5zZXRJbWFnZS5iaW5kKGNvcmUpLCAvLyBAUmVxdWlyZWQgQE92ZXJyaWRlIGZpbGVCcm93c2VyIC0gRnVuY3Rpb24gdGhhdCBhY3Rpb24gd2hlbiBpdGVtIGNsaWNrLlxuICAgICAgICAgICAgY29sdW1uU2l6ZTogNCAvLyBAT3B0aW9uIEBPdmVycmlkZSBmaWxlQnJvd3NlciAtIE51bWJlciBvZiBcImRpdi5zZS1maWxlLWl0ZW0tY29sdW1uXCIgdG8gYmUgY3JlYXRlZCAoZGVmYXVsdDogNClcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIFxuICAgIC8qKlxuICAgICAqIEBSZXF1aXJlZCBAT3ZlcnJpZGUgZmlsZUJyb3dzZXJcbiAgICAgKiBAZGVzY3JpcHRpb24gT3BlbiBhIGZpbGUgYnJvd3Nlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufG51bGx9IHNlbGVjdG9ySGFuZGxlciBXaGVuIHRoZSBmdW5jdGlvbiBjb21lcyBhcyBhbiBhcmd1bWVudCB2YWx1ZSwgaXQgc3Vic3RpdHV0ZXMgXCJjb250ZXh0LnNlbGVjdG9ySGFuZGxlclwiLlxuICAgICAqL1xuICAgIG9wZW46IGZ1bmN0aW9uIChzZWxlY3RvckhhbmRsZXIpIHtcbiAgICAgICAgdGhpcy5wbHVnaW5zLmZpbGVCcm93c2VyLm9wZW4uY2FsbCh0aGlzLCAnaW1hZ2VHYWxsZXJ5Jywgc2VsZWN0b3JIYW5kbGVyKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQFJlcXVpcmVkIEBPdmVycmlkZSBmaWxlQnJvd3NlclxuICAgICAqIEBkZXNjcmlwdGlvbiBEZWZpbmUgdGhlIEhUTUwgb2YgdGhlIGl0ZW0gdG8gYmUgcHV0IGluIFwiZGl2LnNlLWZpbGUtaXRlbS1jb2x1bW5cIi5cbiAgICAgKiBGb3JtYXQ6IFtcbiAgICAgKiAgICAgIHsgc3JjOiBcImltYWdlIHNyY1wiLCBuYW1lOiBcIm5hbWUoQG9wdGlvbilcIiwgYWx0OiBcImltYWdlIGFsdChAb3B0aW9uKVwiLCB0YWc6IFwidGFnIG5hbWUoQG9wdGlvbilcIiB9XG4gICAgICogXVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtIEl0ZW0gb2YgdGhlIHJlc3BvbnNlIGRhdGEncyBhcnJheVxuICAgICAqL1xuICAgIGRyYXdJdGVtczogZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgY29uc3Qgc3JjTmFtZSA9IGl0ZW0uc3JjLnNwbGl0KCcvJykucG9wKCk7XG4gICAgICAgIHJldHVybiAgJzxkaXYgY2xhc3M9XCJzZS1maWxlLWl0ZW0taW1nXCI+PGltZyBzcmM9XCInICsgaXRlbS5zcmMgKyAnXCIgYWx0PVwiJyArIChpdGVtLmFsdCB8fCBzcmNOYW1lKSArICdcIiBkYXRhLWNvbW1hbmQ9XCJwaWNrXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtZmlsZS1pbWctbmFtZSBzZS1maWxlLW5hbWUtYmFja1wiPjwvZGl2PicgK1xuICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWZpbGUtaW1nLW5hbWUgX19zZV9faW1nX25hbWVcIj4nICsgKGl0ZW0ubmFtZSB8fCBzcmNOYW1lKSArICc8L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPC9kaXY+JztcbiAgICB9LFxuXG4gICAgc2V0SW1hZ2U6IGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICAgICAgdGhpcy5jYWxsUGx1Z2luKCdpbWFnZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpbGUgPSB7bmFtZTogdGFyZ2V0LnBhcmVudE5vZGUucXVlcnlTZWxlY3RvcignLl9fc2VfX2ltZ19uYW1lJykudGV4dENvbnRlbnQsIHNpemU6IDB9O1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmltYWdlLl9hbHRUZXh0ID0gdGFyZ2V0LmFsdDtcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5pbWFnZS5jcmVhdGVfaW1hZ2UuY2FsbCh0aGlzLCB0YXJnZXQuc3JjLCAnJywgZmFsc2UsIHRoaXMuY29udGV4dC5pbWFnZS5fb3JpZ2luX3csIHRoaXMuY29udGV4dC5pbWFnZS5fb3JpZ2luX2gsICdub25lJywgZmlsZSk7XG4gICAgICAgIH0uYmluZCh0aGlzKSwgbnVsbCk7XG4gICAgfVxufTsiLCIvKlxuICogd3lzaXd5ZyB3ZWIgZWRpdG9yXG4gKlxuICogc3VuZWRpdG9yLmpzXG4gKiBDb3B5cmlnaHQgMjAyMCBKaUhvbmcgTGVlLlxuICogTUlUIGxpY2Vuc2UuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAgLy8gcnRsIGljb25cbiAgIHJ0bDoge1xuICAgICAgaXRhbGljOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxMC41IDE1LjhcIiB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiPjxnPjxwYXRoIGQ9XCJNMC4zLDAuMWMwLjMsMCwwLjUsMCwwLjcsMGMxLDAuMSwxLjcsMC4xLDIuMiwwLjFINEw3LjIsMGwwLjIsMS4xSDdjLTAuNSwwLTEsMC4xLTEuNSwwLjN2MC40bDAuMywxLjlMNiw0LjRMNi4zLDYgbDAuMSwwLjRsMC4xLDAuNWMwLjEsMC4yLDAuMSwwLjQsMC4yLDAuN3MwLjEsMC42LDAuMiwwLjlMNyw5LjFsMC42LDIuOGwwLjMsMS40YzAuMSwwLjQsMC4yLDAuNywwLjQsMWMwLjQsMC4yLDAuOCwwLjMsMS4yLDAuNCBsMC44LDAuMmwwLjIsMC45bC0xLjEsMGMtMC45LTAuMS0xLjUtMC4xLTEuOC0wLjFoLTJjLTAuOSwwLjEtMS40LDAuMi0xLjUsMC4yYy0wLjEsMC0wLjIsMC0wLjMsMEgzLjRjLTAuMSwwLTAuMiwwLTAuMiwwIGwtMC4xLTAuNGMwLTAuMi0wLjEtMC40LTAuMS0wLjZsMC43LTAuMWMwLjQsMCwwLjgtMC4xLDEuMi0wLjJjMC0wLjEsMC0wLjIsMC0wLjNsLTAuMS0wLjVsLTAuNC0yLjRMNCw5LjZMMy40LDYuNCBDMy4yLDUuNywzLDQuNywyLjcsMy4zYzAtMC4zLTAuMS0wLjUtMC4xLTAuOEMyLjUsMi4xLDIuNCwxLjksMi4zLDEuNkMyLDEuNCwxLjYsMS4zLDEuMywxLjJDMC45LDEuMiwwLjUsMS4xLDAuMiwwLjlMMCwwLjRMMCwwIEwwLjMsMC4xTDAuMywwLjF6XCIvPjwvZz48L3N2Zz4nLFxuICAgICAgaW5kZW50OiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS43IDEyLjRcIiB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiPjxnPjxnPjxwYXRoIGQ9XCJNMTUuNSwxMC4xTDE1LjUsMTAuMWMwLjEsMCwwLjMsMC4xLDAuMywwLjN2MS43YzAsMC4xLDAsMC4xLTAuMSwwLjJjLTAuMSwwLjEtMC4xLDAuMS0wLjIsMC4xbC0xNS4yLDAgYy0wLjEsMC0wLjEsMC0wLjItMC4xQzAsMTIuMiwwLDEyLjIsMCwxMi4xbDAtMS43YzAtMC4xLDAtMC4xLDAuMS0wLjJjMC4xLTAuMSwwLjEtMC4xLDAuMi0wLjFDMC4zLDEwLjEsMTUuNSwxMC4xLDE1LjUsMTAuMXogTTkuOCw2LjdjMC4xLDAsMC4xLDAsMC4yLDAuMUMxMC4xLDYuOSwxMC4xLDcsMTAuMSw3djEuN2MwLDAuMSwwLDAuMi0wLjEsMC4yQzEwLDksOS45LDksOS44LDlMMC4zLDlDMC4yLDksMC4xLDksMC4xLDguOSBDMCw4LjksMCw4LjgsMCw4LjdWN0MwLDcsMCw2LjksMC4xLDYuOGMwLjEtMC4xLDAuMS0wLjEsMC4yLTAuMUMwLjMsNi43LDkuOCw2LjcsOS44LDYuN3ogTTAuMywzLjRoOS42aDBjMC4xLDAsMC4zLDAuMSwwLjMsMC4zIHYxLjd2MGMwLDAuMS0wLjEsMC4zLTAuMywwLjNIMC4zYy0wLjEsMC0wLjEsMC0wLjItMC4xQzAsNS41LDAsNS40LDAsNS4zVjMuNmMwLTAuMSwwLTAuMSwwLjEtMC4yQzAuMSwzLjQsMC4yLDMuNCwwLjMsMy40IEwwLjMsMy40eiBNMC4zLDBsMTUuMiwwYzAuMSwwLDAuMSwwLDAuMiwwLjFjMC4xLDAuMSwwLjEsMC4xLDAuMSwwLjJWMmMwLDAuMSwwLDAuMi0wLjEsMC4yYy0wLjEsMC4xLTAuMSwwLjEtMC4yLDAuMUgwLjMgYy0wLjEsMC0wLjEsMC0wLjItMC4xQzAsMi4xLDAsMiwwLDJsMC0xLjdjMC0wLjEsMC0wLjEsMC4xLTAuMkMwLjEsMCwwLjIsMCwwLjMsMHpcIi8+PC9nPjxwYXRoIGQ9XCJNMTMuMSwzLjVMMTUuNyw2YzAuMSwwLjEsMC4xLDAuMywwLDAuNGwtMi41LDIuNUMxMy4xLDksMTMsOSwxMi45LDljLTAuMSwwLTAuMSwwLTAuMi0wLjFjLTAuMS0wLjEtMC4xLTAuMS0wLjEtMC4yVjMuNyBjMC0wLjEsMC0wLjIsMC4xLTAuMmMwLjEtMC4xLDAuMS0wLjEsMC4yLTAuMUMxMywzLjQsMTMuMSwzLjQsMTMuMSwzLjV6XCIvPjwvZz48L3N2Zz4nLFxuICAgICAgb3V0ZGVudDogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNyAxMi40XCIgeG1sOnNwYWNlPVwicHJlc2VydmVcIj48Zz48Zz48cGF0aCBkPVwiTTE1LjUsMTAuMUwxNS41LDEwLjFjMC4xLDAsMC4zLDAuMSwwLjMsMC4zdjEuN2MwLDAuMSwwLDAuMS0wLjEsMC4yYy0wLjEsMC4xLTAuMSwwLjEtMC4yLDAuMWwtMTUuMiwwIGMtMC4xLDAtMC4xLDAtMC4yLTAuMUMwLDEyLjIsMCwxMi4yLDAsMTIuMWwwLTEuN2MwLTAuMSwwLTAuMSwwLjEtMC4yYzAuMS0wLjEsMC4xLTAuMSwwLjItMC4xQzAuMywxMC4xLDE1LjUsMTAuMSwxNS41LDEwLjF6IE05LjgsNi43YzAuMSwwLDAuMSwwLDAuMiwwLjFDMTAuMSw2LjksMTAuMSw3LDEwLjEsN3YxLjdjMCwwLjEsMCwwLjItMC4xLDAuMkMxMCw5LDkuOSw5LDkuOCw5TDAuMyw5QzAuMiw5LDAuMSw5LDAuMSw4LjkgQzAsOC45LDAsOC44LDAsOC43VjdDMCw3LDAsNi45LDAuMSw2LjhjMC4xLTAuMSwwLjEtMC4xLDAuMi0wLjFDMC4zLDYuNyw5LjgsNi43LDkuOCw2Ljd6IE0wLjMsMy40aDkuNmgwYzAuMSwwLDAuMywwLjEsMC4zLDAuMyB2MS43djBjMCwwLjEtMC4xLDAuMy0wLjMsMC4zSDAuM2MtMC4xLDAtMC4xLDAtMC4yLTAuMUMwLDUuNSwwLDUuNCwwLDUuM1YzLjZjMC0wLjEsMC0wLjEsMC4xLTAuMkMwLjEsMy40LDAuMiwzLjQsMC4zLDMuNCBMMC4zLDMuNHogTTAuMywwbDE1LjIsMGMwLjEsMCwwLjEsMCwwLjIsMC4xYzAuMSwwLjEsMC4xLDAuMSwwLjEsMC4yVjJjMCwwLjEsMCwwLjItMC4xLDAuMmMtMC4xLDAuMS0wLjEsMC4xLTAuMiwwLjFIMC4zIGMtMC4xLDAtMC4xLDAtMC4yLTAuMUMwLDIuMSwwLDIsMCwybDAtMS43YzAtMC4xLDAtMC4xLDAuMS0wLjJDMC4xLDAsMC4yLDAsMC4zLDB6XCIvPjwvZz48cGF0aCBkPVwiTTE1LjUsMy40YzAuMSwwLDAuMSwwLDAuMiwwLjFjMC4xLDAuMSwwLjEsMC4xLDAuMSwwLjJ2NS4xYzAsMC4xLDAsMC4xLTAuMSwwLjJDMTUuNiw5LDE1LjUsOSwxNS41LDkgYy0wLjEsMC0wLjEsMC0wLjItMC4xbC0yLjUtMi41Yy0wLjEtMC4xLTAuMS0wLjMsMC0wLjRsMi41LTIuNUMxNS4zLDMuNCwxNS40LDMuNCwxNS41LDMuNHpcIi8+PC9nPjwvc3ZnPicsXG4gICAgICBsaXN0X2J1bGxldHM6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1LjcgMTIuNFwiIHhtbDpzcGFjZT1cInByZXNlcnZlXCI+PGc+PHBhdGggZD1cIk0xMi40LDEwLjdjMCwwLjksMC44LDEuNywxLjcsMS43YzAuOSwwLDEuNy0wLjgsMS43LTEuN0MxNS43LDkuOCwxNSw5LDE0LjEsOWMtMC40LDAtMC45LDAuMi0xLjIsMC41IEMxMi41LDkuOCwxMi40LDEwLjIsMTIuNCwxMC43QzEyLjQsMTAuNywxMi40LDEwLjcsMTIuNCwxMC43eiBNMTIuNCw2LjJjMCwwLjksMC44LDEuNywxLjcsMS43YzAuNCwwLDAuOS0wLjIsMS4yLTAuNSBjMC4zLTAuMywwLjQtMC43LDAuNC0xLjFjMC0wLjktMC43LTEuNy0xLjYtMS43QzEzLjEsNC42LDEyLjQsNS4zLDEyLjQsNi4yQzEyLjQsNi4yLDEyLjQsNi4yLDEyLjQsNi4yeiBNMCw5Ljh2MS43IGMwLDAuMSwwLDAuMSwwLjEsMC4yYzAuMSwwLjEsMC4xLDAuMSwwLjIsMC4xbDEwLjcsMGMwLDAsMCwwLDAsMGMwLjEsMCwwLjMtMC4xLDAuMy0wLjNWOS44YzAtMC4xLDAtMC4xLTAuMS0wLjIgQzExLjEsOS42LDExLDkuNiwxMSw5LjZsLTEwLjcsMGMtMC4xLDAtMC4xLDAtMC4yLDAuMUMwLDkuNywwLDkuOCwwLDkuOEwwLDkuOHogTTEyLjksMi45YzAuMywwLjMsMC43LDAuNSwxLjIsMC41IGMwLjQsMCwwLjktMC4yLDEuMi0wLjVjMC43LTAuNywwLjctMS43LDAtMi40QzE0LjksMC4yLDE0LjUsMCwxNC4xLDBjLTAuNCwwLTAuOSwwLjItMS4yLDAuNWMtMC4zLDAuMy0wLjUsMC43LTAuNSwxLjIgQzEyLjQsMi4xLDEyLjUsMi42LDEyLjksMi45eiBNMCw1LjNWN2MwLDAuMSwwLDAuMSwwLjEsMC4yYzAuMSwwLjEsMC4xLDAuMSwwLjIsMC4xSDExYzAuMSwwLDAuMSwwLDAuMi0wLjEgYzAuMS0wLjEsMC4xLTAuMSwwLjEtMC4yVjUuM2MwLDAsMCwwLDAsMGMwLTAuMS0wLjEtMC4zLTAuMy0wLjNIMC4zYy0wLjEsMC0wLjEsMC0wLjIsMC4xQzAsNS4yLDAsNS4zLDAsNS4zTDAsNS4zeiBNMCwwLjh2MS43IGMwLDAuMSwwLDAuMSwwLjEsMC4yYzAuMSwwLjEsMC4xLDAuMSwwLjIsMC4xaDEwLjdjMC4xLDAsMC4xLDAsMC4yLTAuMWMwLDAsMC4xLTAuMSwwLjEtMC4yVjAuOGMwLTAuMSwwLTAuMS0wLjEtMC4yIGMwLTAuMS0wLjEtMC4xLTAuMi0wLjFIMC4zYy0wLjEsMC0wLjEsMC0wLjIsMC4xQzAsMC43LDAsMC44LDAsMC44TDAsMC44elwiLz48L2c+PC9zdmc+JyxcbiAgICAgIGxpc3RfbnVtYmVyOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS43IDE1LjdcIiB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiPjxnPjxwYXRoIGQ9XCJNMCwxMS41bDAsMS43YzAsMC4xLDAsMC4xLDAuMSwwLjJjMC4xLDAuMSwwLjEsMC4xLDAuMiwwLjFIMTFjMC4xLDAsMC4yLDAsMC4yLTAuMWMwLjEtMC4xLDAuMS0wLjEsMC4xLTAuMnYtMS43IGMwLTAuMSwwLTAuMS0wLjEtMC4yYy0wLjEtMC4xLTAuMS0wLjEtMC4yLTAuMUgwLjNjLTAuMSwwLTAuMiwwLTAuMiwwLjFDMCwxMS40LDAsMTEuNCwwLDExLjVMMCwxMS41eiBNMCw4LjdjMCwwLjEsMCwwLjEsMC4xLDAuMiBDMC4xLDguOSwwLjIsOSwwLjMsOUgxMWMwLjEsMCwwLjIsMCwwLjItMC4xYzAuMS0wLjEsMC4xLTAuMSwwLjEtMC4yVjdjMC0wLjEsMC0wLjEtMC4xLTAuMmMtMC4xLTAuMS0wLjEtMC4xLTAuMi0wLjFsLTEwLjcsMCBjLTAuMSwwLTAuMiwwLTAuMiwwLjFDMCw2LjgsMCw2LjksMCw3QzAsNywwLDguNywwLDguN3ogTTAsMi41djEuN2MwLDAuMSwwLDAuMSwwLjEsMC4yYzAsMCwwLjEsMC4xLDAuMiwwLjFsMTAuNywwIGMwLjEsMCwwLjIsMCwwLjItMC4xYzAuMS0wLjEsMC4xLTAuMSwwLjEtMC4yVjIuNGMwLTAuMSwwLTAuMS0wLjEtMC4yYy0wLjEsMC0wLjEsMC0wLjIsMEgwLjNjLTAuMSwwLTAuMSwwLTAuMiwwIEMwLDIuMywwLDIuNCwwLDIuNUwwLDIuNXpcIi8+PC9nPjxwYXRoIGQ9XCJNMTUuNiwxNC4yYzAtMC4zLTAuMS0wLjYtMC4zLTAuOGMtMC4yLTAuMi0wLjQtMC40LTAuNy0wLjRsMC45LTF2LTAuOGgtMi45djEuM2gwLjl2LTAuNWgwLjlsMCwwYy0wLjEsMC4xLTAuMiwwLjItMC4zLDAuMyBzLTAuMiwwLjMtMC40LDAuNWwtMC4zLDAuM2wwLjIsMC41YzAuNiwwLDAuOSwwLjEsMC45LDAuNWMwLDAuMS0wLjEsMC4zLTAuMiwwLjRjLTAuMSwwLjEtMC4zLDAuMS0wLjQsMC4xYy0wLjMsMC0wLjctMC4xLTAuOS0wLjMgbC0wLjUsMC44YzAuNCwwLjQsMC45LDAuNiwxLjUsMC42YzAuNCwwLDAuOS0wLjEsMS4yLTAuNEMxNS41LDE1LjEsMTUuNiwxNC43LDE1LjYsMTQuMnpcIi8+PHBhdGggZD1cIk0xNS42LDguN2gtMC45djAuNWgtMS4xYzAtMC4yLDAuMi0wLjQsMC40LTAuNWMwLjItMC4yLDAuNC0wLjMsMC43LTAuNGMwLjMtMC4yLDAuNS0wLjMsMC43LTAuNmMwLjItMC4yLDAuMy0wLjUsMC4zLTAuOCBjMC0wLjQtMC4yLTAuOC0wLjUtMWMtMC42LTAuNC0xLjQtMC41LTItMC4xYy0wLjMsMC4yLTAuNSwwLjQtMC42LDAuN0wxMy4zLDdjMC4xLTAuMywwLjQtMC41LDAuNy0wLjVjMC4xLDAsMC4zLDAsMC4zLDAuMSBjMC4xLDAuMSwwLjEsMC4yLDAuMSwwLjNjMCwwLjItMC4xLDAuMy0wLjIsMC40Yy0wLjIsMC4xLTAuMywwLjMtMC41LDAuNGMtMC4yLDAuMS0wLjQsMC4zLTAuNiwwLjRjLTAuMiwwLjItMC40LDAuNC0wLjUsMC42IGMtMC4xLDAuMi0wLjIsMC41LTAuMiwwLjhjMCwwLjIsMCwwLjMsMCwwLjVoMy4yTDE1LjYsOC43TDE1LjYsOC43elwiLz48cGF0aCBkPVwiTTE1LjYsMy42aC0xVjBoLTAuOWwtMS4yLDEuMWwwLjYsMC43YzAuMi0wLjEsMC4zLTAuMywwLjQtMC41bDAsMHYyLjJoLTAuOXYwLjloM0wxNS42LDMuNkwxNS42LDMuNnpcIi8+PC9zdmc+JyxcbiAgICAgIGxpbms6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1LjcgMTUuN1wiIHhtbDpzcGFjZT1cInByZXNlcnZlXCI+PGc+PHBhdGggZD1cIk03LjQsOS45bDMuMSwzLjFjMC4zLDAuMywwLjgsMC41LDEuMywwLjVjMC41LDAsMC45LTAuMiwxLjMtMC41YzAsMCwwLDAsMCwwYzAuNy0wLjcsMC43LTEuOSwwLTIuNkw5LjksNy4zIGMwLTAuMSwwLTAuMiwwLTAuM0M5LjksNywxMCw3LDEwLjEsN2wyLjItMC4yYzAuMSwwLDAuMSwwLDAuMiwwLjFsMi4xLDIuMWMwLjQsMC40LDAuNywwLjgsMC45LDEuM2MwLjIsMC41LDAuMywxLDAuMywxLjUgYzAsMC41LTAuMSwxLTAuMywxLjVjLTAuOCwyLTMuMiwzLTUuMiwyLjJjLTAuNS0wLjItMC45LTAuNS0xLjMtMC45bC0yLjEtMi4xYy0wLjEsMC0wLjEtMC4xLTAuMS0wLjJMNywxMC4xQzcsMTAsNyw5LjksNy4xLDkuOSBDNy4yLDkuOCw3LjMsOS45LDcuNCw5Ljl6IE0xLjIsMS4xQzEuNiwwLjcsMiwwLjQsMi41LDAuM2MxLTAuNCwyLjEtMC40LDMuMSwwQzYsMC40LDYuNSwwLjcsNi44LDEuMUw5LDMuMkM5LDMuMyw5LjEsMy4zLDksMy40IEw4LjgsNS42YzAsMC4xLTAuMSwwLjItMC4yLDAuMmMtMC4xLDAuMS0wLjIsMC4xLTAuMywwTDUuMywyLjdDNSwyLjMsNC41LDIuMSw0LDIuMWMtMC41LDAtMC45LDAuMi0xLjMsMC41YzAsMCwwLDAsMCwwIEMyLDMuNCwyLDQuNSwyLjcsNS4ybDMuMSwzLjJjMC4xLDAuMSwwLjEsMC4yLDAsMC4zYzAsMC4xLTAuMSwwLjEtMC4yLDAuMUwzLjUsOUMzLjQsOSwzLjQsOSwzLjMsOC45TDEuMiw2LjhjMCwwLDAsMCwwLDAgQy0wLjQsNS4yLTAuNCwyLjcsMS4yLDEuMUwxLjIsMS4xeiBNMTQuMyw2aC0yLjZjMCwwLDAsMCwwLDBjLTAuMSwwLTAuMi0wLjEtMC4yLTAuMmMwLTAuMSwwLTAuMiwwLjEtMC4zbDIuNS0wLjcgYzAuMSwwLDAuMSwwLDAuMiwwYzAuMSwwLDAuMSwwLjEsMC4xLDAuMmwwLjEsMC44YzAsMC4xLDAsMC4xLTAuMSwwLjJDMTQuNSw2LDE0LjQsNiwxNC4zLDZMMTQuMyw2eiBNMTAuMiw0LjEgYzAsMC4xLTAuMSwwLjItMC4yLDAuMmwwLDBjMCwwLDAsMCwwLDBDOS44LDQuMiw5LjcsNC4xLDkuOCw0TDkuNywxLjRjMC0wLjEsMC0wLjEsMC4xLTAuMmMwLjEsMCwwLjEsMCwwLjIsMGgwLjggYzAuMSwwLDAuMSwwLDAuMiwwLjFjMCwwLjEsMCwwLjEsMCwwLjJMMTAuMiw0LjFMMTAuMiw0LjF6IE0xLjUsOS43aDEuM2gxLjNjMC4xLDAsMC4yLDAuMSwwLjIsMC4yYzAsMC4xLDAsMC4yLTAuMSwwLjNsLTIuNSwwLjYgSDEuNmMwLDAtMC4xLDAtMC4xLDBjLTAuMSwwLTAuMS0wLjEtMC4xLTAuMkwxLjIsOS45YzAtMC4xLDAtMC4xLDAuMS0wLjJjMC0wLjEsMC4xLTAuMSwwLjItMC4xTDEuNSw5Ljd6IE01LjYsMTEuNiBDNS42LDExLjYsNS42LDExLjYsNS42LDExLjZjMC0wLjEsMC4xLTAuMiwwLjMtMC4xYzAsMCwwLDAsMCwwYzAuMSwwLDAuMiwwLjEsMC4yLDAuMnYyLjZjMCwwLjEsMCwwLjEtMC4xLDAuMiBjMCwwLTAuMSwwLjEtMC4yLDAuMUw1LDE0LjVjLTAuMSwwLTAuMSwwLTAuMi0wLjFjMC0wLjEsMC0wLjEsMC0wLjJMNS42LDExLjZMNS42LDExLjZ6XCIvPjwvZz48L3N2Zz4nLFxuICAgICAgdW5saW5rOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS43IDE1LjdcIiB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiPjxnPjxwYXRoIGQ9XCJNMTQuNiwxNC42YzEuNi0xLjYsMS42LTQuMSwwLTUuN2wwLDBsLTMuMS0zLjFsLTEuMiwxLjZsMi45LDIuOWMwLjQsMC40LDAuNiwwLjksMC42LDEuNWMwLDEuMS0wLjksMi4xLTIuMSwyLjFsMCwwIGMtMC42LDAtMS4xLTAuMi0xLjUtMC42bC0wLjQtMC40bC0xLjcsMWwwLjgsMC44QzEwLjQsMTYuMiwxMywxNi4yLDE0LjYsMTQuNkwxNC42LDE0LjZMMTQuNiwxNC42eiBNMy42LDZDMyw1LjksMi42LDUuNSwyLjMsNSBTMS45LDQsMi4xLDMuNEMyLjMsMi45LDIuNiwyLjUsMywyLjJDMy41LDIsNC4xLDEuOSw0LjYsMmwzLjMsMS40bDAuNS0yTDUuMSwwLjFDNC0wLjEsMi45LDAsMiwwLjVDMS4xLDEuMSwwLjQsMS45LDAuMiwzIEMtMC4xLDQsMCw1LjEsMC42LDZDMS4xLDYuOSwxLjksNy42LDMsNy44bDUuNCwybDAuNS0yTDYuMiw2LjlMMy42LDZ6XCIvPjwvZz48L3N2Zz4nXG4gICB9LFxuICAgLy8gY29tbW9uLCBsdHIgaWNvblxuICAgcmVkbzogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNTkgMTQuMThcIj48Zz48cGF0aCBkPVwiTTExLjU4LDE4LjQ4YTYuODQsNi44NCwwLDEsMSw2Ljg1LTYuODVzMCwuMjYsMCwuNjdhOCw4LDAsMCwxLS4yMiwxLjQ0bC45MS0uNTVhLjUxLjUxLDAsMCwxLC4zNiwwLC40NS40NSwwLDAsMSwuMjkuMjIuNDcuNDcsMCwwLDEsLjA2LjM2LjQ1LjQ1LDAsMCwxLS4yMi4yOUwxNy40MiwxNS4zbC0uMTIsMGgtLjI1bC0uMTItLjA2LS4wOS0uMDktLjA2LS4wNywwLS4wNi0uODctMi4xMmEuNDMuNDMsMCwwLDEsMC0uMzcuNDkuNDksMCwwLDEsLjI3LS4yNi40MS40MSwwLDAsMSwuMzYsMCwuNTMuNTMsMCwwLDEsLjI3LjI2bC40NCwxLjA5YTYuNTEsNi41MSwwLDAsMCwuMjQtMS4zNiw0LjU4LDQuNTgsMCwwLDAsMC0uNjQsNS44Myw1LjgzLDAsMCwwLTEuNzMtNC4xNyw1Ljg4LDUuODgsMCwwLDAtOC4zNCwwLDUuOSw1LjksMCwwLDAsNC4xNywxMC4wNi41MS41MSwwLDAsMSwuMzMuMTUuNDguNDgsMCwwLDEsMCwuNjguNTMuNTMsMCwwLDEtLjMzLjEyWlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC40OCAtNC41NClcIi8+PC9nPjwvc3ZnPicsXG4gICB1bmRvOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS41OSAxNC4xOFwiPjxnPjxwYXRoIGQ9XCJNNSwxNGEuNDMuNDMsMCwwLDEtLjIyLS4yOS40Ni40NiwwLDAsMSwuMDYtLjM2LjQzLjQzLDAsMCwxLC4yOS0uMjIuNTYuNTYsMCwwLDEsLjM2LDBsLjkxLjU1YTguMjcsOC4yNywwLDAsMS0uMjItMS40NSw1LjA3LDUuMDcsMCwwLDEsMC0uNjdBNi44NSw2Ljg1LDAsMSwxLDEzLDE4LjQ3YS40NC40NCwwLDAsMS0uMzMtLjEzLjQ4LjQ4LDAsMCwxLDAtLjY4LjUxLjUxLDAsMCwxLC4zMy0uMTVBNS44OSw1Ljg5LDAsMCwwLDE3LjE1LDcuNDVhNS44OCw1Ljg4LDAsMCwwLTguMzMsMCw1Ljg0LDUuODQsMCwwLDAtMS43Myw0LjE3czAsLjI1LDAsLjY1YTYuNDksNi40OSwwLDAsMCwuMjQsMS4zN2wuNDQtMS4wOWEuNTcuNTcsMCwwLDEsLjI3LS4yNi40MS40MSwwLDAsMSwuMzYsMCwuNTMuNTMsMCwwLDEsLjI3LjI2LjQzLjQzLDAsMCwxLDAsLjM3TDcuODIsMTVsMCwuMDktLjA5LjA5LS4xLjA3LS4wNiwwSDcuMjhsLS4xMywwLTEuMDktLjYzYy0uNjUtLjM2LTEtLjU3LTEuMS0uNjNaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjQ5IC00LjUzKVwiLz48L2c+PC9zdmc+JyxcbiAgIGJvbGQ6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDExLjc2IDE1Ljc1XCI+PGc+PHBhdGggZD1cIk02LjQsMy43NlYxOS41aDYuNzZhNS41NSw1LjU1LDAsMCwwLDItLjMyLDQuOTMsNC45MywwLDAsMCwxLjUyLTEsNC4yNyw0LjI3LDAsMCwwLDEuNDgtMy4zNCwzLjg3LDMuODcsMCwwLDAtLjY5LTIuMzcsNS43NCw1Ljc0LDAsMCwwLS43MS0uODMsMy40NCwzLjQ0LDAsMCwwLTEuMS0uNjUsMy42LDMuNiwwLDAsMCwxLjU4LTEuMzYsMy42NiwzLjY2LDAsMCwwLC41My0xLjkzLDMuNywzLjcsMCwwLDAtMS4yMS0yLjg3LDQuNjUsNC42NSwwLDAsMC0zLjI1LTEuMUg2LjRabTIuNDYsNi42NVY1LjU3aDMuNTJhNC45MSw0LjkxLDAsMCwxLDEuMzYuMTUsMi4zLDIuMywwLDAsMSwuODUuNDUsMi4wNiwyLjA2LDAsMCwxLC43NCwxLjcxLDIuMywyLjMsMCwwLDEtLjc4LDEuOTIsMi41NCwyLjU0LDAsMCwxLS44Ni40Niw0LjcsNC43LDAsMCwxLTEuMzIuMTVIOC44NlptMCw3LjI3VjEyLjE1SDEyLjdhNC41Niw0LjU2LDAsMCwxLDEuMzguMTcsMy40MywzLjQzLDAsMCwxLC45NS40OSwyLjI5LDIuMjksMCwwLDEsLjkyLDIsMi43MywyLjczLDAsMCwxLS44MywyLjEsMi42NiwyLjY2LDAsMCwxLS44My41OCwzLjI1LDMuMjUsMCwwLDEtMS4yNi4ySDguODZaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC02LjQgLTMuNzUpXCIvPjwvZz48L3N2Zz4nLFxuICAgdW5kZXJsaW5lOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCA5Ljc4IDE1Ljc0XCI+PGc+PHBhdGggZD1cIk0xNC42NCwzLjc2aDIuNTJ2Ny43MmE0LjUxLDQuNTEsMCwwLDEtLjU5LDIuMzEsMy43NiwzLjc2LDAsMCwxLTEuNzEsMS41Myw2LjEyLDYuMTIsMCwwLDEtMi42NC41Myw1LDUsMCwwLDEtMy41Ny0xLjE4LDQuMTcsNC4xNywwLDAsMS0xLjI3LTMuMjRWMy43Nkg5Ljl2Ny4zYTMsMywwLDAsMCwuNTUsMiwyLjMsMi4zLDAsMCwwLDEuODMuNjUsMi4yNiwyLjI2LDAsMCwwLDEuOC0uNjUsMy4wOSwzLjA5LDAsMCwwLC41NS0yVjMuNzZabTIuNTIsMTMuMzFWMTkuNUg3LjM5VjE3LjA4aDkuNzdaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC03LjM4IC0zLjc2KVwiLz48L2c+PC9zdmc+JyxcbiAgIGl0YWxpYzogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTAuNDkgMTUuNzZcIj48Zz48cGF0aCBkPVwiTTE3LjE2LDMuNzlsLjM3LDAtLjA2LjM4LS4xNC41MkExMCwxMCwwLDAsMSwxNi4yMSw1YTkuMzcsOS4zNywwLDAsMC0xLC4zMiw2LjY4LDYuNjgsMCwwLDAtLjI1Ljg5Yy0uMDYuMzEtLjExLjU5LS4xNC44NS0uMywxLjM2LS41MiwyLjQxLS42OCwzLjE0bC0uNjEsMy4xOEwxMy4xLDE1bC0uNDMsMi40LS4xMi40NmEuNjIuNjIsMCwwLDAsMCwuMjhjLjQ0LjEuODUuMTcsMS4yMy4yMmwuNjguMTFhNC41MSw0LjUxLDAsMCwxLS4wOC42bC0uMDkuNDJhLjkyLjkyLDAsMCwwLS4yMywwbC0uNDMsMGExLjM3LDEuMzcsMCwwLDEtLjI5LDBjLS4xMywwLS42My0uMDgtMS40OS0uMTZsLTIsMGMtLjI4LDAtLjg3LDAtMS43OC4xMkw3LDE5LjVsLjE3LS44OC44LS4yQTYuNjEsNi42MSwwLDAsMCw5LjE5LDE4LDIuNjIsMi42MiwwLDAsMCw5LjYxLDE3bC4yOC0xLjQxLjU4LTIuNzUuMTItLjY2Yy4wNS0uMy4xMS0uNTguMTctLjg2cy4xMi0uNTEuMTctLjY5bC4xMi0uNDguMTItLjQzLjMxLTEuNi4xNS0uNjUuMzEtMS45MVY1LjE0YTMuODYsMy44NiwwLDAsMC0xLjQ4LS4yOWwtLjM4LDAsLjItMS4wNiwzLjI0LjE0Ljc1LDBjLjQ1LDAsMS4xOCwwLDIuMTgtLjA5LjIzLDAsLjQ2LDAsLjcxLDBaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC03LjA0IC0zLjc2KVwiLz48L2c+PC9zdmc+JyxcbiAgIHN0cmlrZTogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNzQgMTQuOVwiPjxnPjxwYXRoIGQ9XCJNMTIuOTQsMTNhNC4yNyw0LjI3LDAsMCwxLDEuMzIuNTgsMS40NiwxLjQ2LDAsMCwxLC41NSwxLjIsMS44NywxLjg3LDAsMCwxLS44OCwxLjY0LDQuMTcsNC4xNywwLDAsMS0yLjM1LjU5LDQuNDQsNC40NCwwLDAsMS0yLjc0LS43MSwyLjcyLDIuNzIsMCwwLDEtMS0yLjE3SDUuNTdhNC41Niw0LjU2LDAsMCwwLDEuNTUsMy43LDcsNywwLDAsMCw0LjQ3LDEuMjMsNiw2LDAsMCwwLDQuMDctMS4zLDQuMjQsNC4yNCwwLDAsMCwxLjUyLTMuMzcsNCw0LDAsMCwwLS4yNi0xLjRoLTRaTTYuMzcsMTAuMjRBMy4yNywzLjI3LDAsMCwxLDYsOC42OGE0LDQsMCwwLDEsMS40OC0zLjMsNS45Miw1LjkyLDAsMCwxLDMuODgtMS4yMSw1LjU4LDUuNTgsMCwwLDEsMy45MSwxLjI0LDQuMzYsNC4zNiwwLDAsMSwxLjQ1LDMuMTdIMTQuNDRhMi4xMiwyLjEyLDAsMCwwLS45MS0xLjgxLDQuNDUsNC40NSwwLDAsMC0yLjQ0LS41NSwzLjY5LDMuNjksMCwwLDAtMiwuNTFBMS42NCwxLjY0LDAsMCwwLDguMyw4LjIyYTEuMywxLjMsMCwwLDAsLjQ4LDEuMTEsNyw3LDAsMCwwLDIuMS43OGwuMjguMDYuMjguMDhINi4zN1ptMTMuMDkuNjhhLjczLjczLDAsMCwxLC40OS4yMS42Ni42NiwwLDAsMSwuMi40OC42NC42NCwwLDAsMS0uMi40OC43MS43MSwwLDAsMS0uNDkuMTlINS4xYS42Ny42NywwLDAsMS0uNDktLjE5LjY2LjY2LDAsMCwxLS4yLS40OC42NC42NCwwLDAsMSwuMi0uNDguNzMuNzMsMCwwLDEsLjQ5LS4yMUgxOS40NlpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNDEgLTQuMTcpXCIvPjwvZz48L3N2Zz4nLFxuICAgc3Vic2NyaXB0OiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS43NSAxNC42MVwiPjxnPjxwYXRoIGQ9XCJNMTUuMzgsNC4zM0gxMi43NEwxMS4xOSw3Yy0uMjguNDYtLjUxLjg3LS42OSwxLjIxTDEwLjA3LDloMGwtLjQ0LS44Yy0uMjItLjQtLjQ1LS44MS0uNzEtMS4yM0w3LjM0LDQuMzNINC42OEw4LjI2LDEwLDQuNCwxNi4wOEg3LjFsMS42OS0yLjgzYy4zOC0uNjMuNzItMS4yMiwxLTEuNzhsLjI1LS40NmgwbC40OS45MmMuMjQuNDUuNDguODkuNzQsMS4zMkwxMywxNi4wOGgyLjYxTDExLjg0LDEwbDEuNzctMi44NCwxLjc3LTIuODVabTQuNzcsMTMuNzVIMTd2LS4xNWMwLS40LjA1LS42NC4xNi0uNzJhNC40Miw0LjQyLDAsMCwxLDEuMTYtLjMxLDMuMywzLjMsMCwwLDAsMS41NC0uNTZBMS44NCwxLjg0LDAsMCwwLDIwLjE1LDE1YTEuNzgsMS43OCwwLDAsMC0uNDQtMS40MUEyLjgsMi44LDAsMCwwLDE4LDEzLjI1YTIuNzEsMi43MSwwLDAsMC0xLjY5LjM3LDEuODMsMS44MywwLDAsMC0uNDQsMS40M3YuMjNIMTd2LS4yM3EwLS42My4xOC0uNzhhMS42MiwxLjYyLDAsMCwxLC44OC0uMTUsMS41OSwxLjU5LDAsMCwxLC44OC4xNXEuMTguMTUuMTguNzV0LS4xOC43NWEzLjU4LDMuNTgsMCwwLDEtMS4xOC4zMywzLjMzLDMuMzMsMCwwLDAtMS41Mi41MSwxLjU3LDEuNTcsMCwwLDAtLjMyLDEuMTh2MS4xNWg0LjI3di0uODZaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjQgLTQuMzMpXCIvPjwvZz48L3N2Zz4nLFxuICAgc3VwZXJzY3JpcHQ6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc1IDE1LjQyXCI+PGc+PHBhdGggZD1cIk0xMiwxMy4xNGwzLjYxLTUuODFIMTIuOTRMMTEuMzMsMTBjLS4yOC40Ni0uNTEuODgtLjY5LDEuMjVsLS40NS44M2gwbC0uNDUtLjg1Yy0uMjItLjQxLS40NS0uODItLjcxLTEuMjRMNy40LDcuMzNINC42OGwzLjY2LDUuODFMNC40LDE5LjMzSDcuMTRsMS43NC0yLjg3cS41OC0xLDEtMS44M2wuMjUtLjQ4aDBsLjUxLjk0Ljc1LDEuMzcsMS43MiwyLjg3aDIuNjdsLTEuOTItMy4wOWMtMS4xMi0xLjgtMS43Ni0yLjgzLTEuOTItMy4xWm00Ljg0LTQuNDFoMGwwLC4xNWgzLjI3di44NkgxNS43N1Y4LjU4YTEuNjYsMS42NiwwLDAsMSwuMzMtMS4yMiwzLjUxLDMuNTEsMCwwLDEsMS41Ni0uNTEsMy42OCwzLjY4LDAsMCwwLDEuMjEtLjM0Yy4xMy0uMS4xOS0uMzYuMTktLjc3UzE5LDUuMDcsMTguODcsNUExLjYzLDEuNjMsMCwwLDAsMTgsNC44YTEuNTgsMS41OCwwLDAsMC0uOTEuMTdjLS4xMy4xMS0uMTkuMzgtLjE5LjhWNkgxNS43OFY1Ljc2YTEuODcsMS44NywwLDAsMSwuNDUtMS40N0EyLjg0LDIuODQsMCwwLDEsMTgsMy45MWEyLjgsMi44LDAsMCwxLDEuNzIuMzgsMS44NCwxLjg0LDAsMCwxLC40NSwxLjQ0LDEuOTEsMS45MSwwLDAsMS0uMzQsMS4zNSwzLjI0LDMuMjQsMCwwLDEtMS41OC41N0EzLjY5LDMuNjksMCwwLDAsMTcsOGMtLjEyLjEtLjE3LjM1LS4xNy43NlpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNCAtMy45MSlcIi8+PC9nPjwvc3ZnPicsXG4gICBlcmFzZTogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNzQgMTMuNzZcIj48Zz48cGF0aCBkPVwiTTEzLjY5LDE3LjJoNi40NnYxLjMxSDguNTZMNC40MSwxNC4zNywxNCw0Ljc1bDYuMDYsNi4wNkwxNi44OSwxNGwtMy4yLDMuMTlabS00LjYxLDBoMi43N0wxNC4wOSwxNSw5Ljg4LDEwLjc1LDYuMjUsMTQuMzhsMS40MSwxLjQxYy44NC44MiwxLjMxLDEuMjksMS40MiwxLjQxWlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC40MSAtNC43NSlcIi8+PC9nPjwvc3ZnPicsXG4gICBpbmRlbnQ6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc0IDEyLjM2XCI+PGc+PHBhdGggZD1cIk0xOS44NywxNS41N2EuMjcuMjcsMCwwLDEsLjE5LjA4LjI1LjI1LDAsMCwxLC4wOC4xOXYxLjY5YS4yNy4yNywwLDAsMS0uMDguMTkuMjUuMjUsMCwwLDEtLjE5LjA4SDQuNjhhLjI3LjI3LDAsMCwxLS4xOS0uMDguMjUuMjUsMCwwLDEtLjA4LS4xOVYxNS44NGEuMjcuMjcsMCwwLDEsLjI3LS4yN0gxOS44N1pNNy41LDE0LjQ1YS4yNS4yNSwwLDAsMS0uMi0uMDlMNC43NiwxMS44NGEuMjkuMjksMCwwLDEsMC0uNEw3LjMsOC45YS4yOS4yOSwwLDAsMSwuNCwwLC4zMS4zMSwwLDAsMSwuMDcuMnY1LjA2YS4zMi4zMiwwLDAsMS0uMDguMjEuMjYuMjYsMCwwLDEtLjE5LjA4Wk0xOS44Nyw4LjgyYS4yNy4yNywwLDAsMSwuMTkuMDguMjUuMjUsMCwwLDEsLjA4LjE5djEuNjlhLjI3LjI3LDAsMCwxLS4wOC4xOS4yNS4yNSwwLDAsMS0uMTkuMDhIMTAuMzFhLjI3LjI3LDAsMCwxLS4yNy0uMjdWOS4xYS4yNy4yNywwLDAsMSwuMjctLjI3aDkuNTZabTAsMy4zN2EuMjcuMjcsMCwwLDEsLjE5LjA4LjI4LjI4LDAsMCwxLC4wOC4yMXYxLjY4YS4zMi4zMiwwLDAsMS0uMDguMjEuMjUuMjUsMCwwLDEtLjE5LjA4SDEwLjMxYS4yNy4yNywwLDAsMS0uMTktLjA4LjMuMywwLDAsMS0uMDgtLjIxVjEyLjQ4YS4zMi4zMiwwLDAsMSwuMDgtLjIxLjI0LjI0LDAsMCwxLC4xOS0uMDhoOS41NlptLjItNi42NmEuMjguMjgsMCwwLDEsLjA4LjJWNy40MWEuMzIuMzIsMCwwLDEtLjA4LjIxLjI1LjI1LDAsMCwxLS4xOS4wOEg0LjY4YS4yNy4yNywwLDAsMS0uMTktLjA4LjMuMywwLDAsMS0uMDgtLjIxVjUuNzNhLjMyLjMyLDAsMCwxLC4wOC0uMjEuMjUuMjUsMCwwLDEsLjE5LS4wOEgxOS44N2EuMjguMjgsMCwwLDEsLjIuMDlaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjQxIC01LjQ0KVwiLz48L2c+PC9zdmc+JyxcbiAgIG91dGRlbnQ6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc0IDEyLjM2XCI+PGc+PHBhdGggZD1cIk00LjY4LDE0LjQ1YS4yNy4yNywwLDAsMS0uMTktLjA4LjMuMywwLDAsMS0uMDgtLjIxVjkuMWEuMjcuMjcsMCwwLDEsLjA4LS4xOS4yOC4yOCwwLDAsMSwuMi0uMDguMjUuMjUsMCwwLDEsLjE5LjA3bDIuNTQsMi41NGEuMjkuMjksMCwwLDEsMCwuNEw0Ljg4LDE0LjM2YS4yNC4yNCwwLDAsMS0uMi4wOVptMTUuMTksMS4xMmEuMjcuMjcsMCwwLDEsLjE5LjA4LjI1LjI1LDAsMCwxLC4wOC4xOXYxLjY5YS4yNy4yNywwLDAsMS0uMDguMTkuMjUuMjUsMCwwLDEtLjE5LjA4SDQuNjhhLjI3LjI3LDAsMCwxLS4xOS0uMDguMjUuMjUsMCwwLDEtLjA4LS4xOVYxNS44NGEuMjcuMjcsMCwwLDEsLjI3LS4yN0gxOS44N1ptMC0zLjM4YS4yNy4yNywwLDAsMSwuMTkuMDguMjguMjgsMCwwLDEsLjA4LjIxdjEuNjhhLjMyLjMyLDAsMCwxLS4wOC4yMS4yNS4yNSwwLDAsMS0uMTkuMDhIMTAuMzFhLjI3LjI3LDAsMCwxLS4xOS0uMDguMy4zLDAsMCwxLS4wOC0uMjFWMTIuNDhhLjMyLjMyLDAsMCwxLC4wOC0uMjEuMjQuMjQsMCwwLDEsLjE5LS4wOGg5LjU2Wm0wLTMuMzdhLjI3LjI3LDAsMCwxLC4xOS4wOC4yNS4yNSwwLDAsMSwuMDguMTl2MS42OWEuMjcuMjcsMCwwLDEtLjA4LjE5LjI1LjI1LDAsMCwxLS4xOS4wOEgxMC4zMWEuMjcuMjcsMCwwLDEtLjI3LS4yN1Y5LjFhLjI3LjI3LDAsMCwxLC4yNy0uMjdoOS41NlptLjItMy4yOWEuMjguMjgsMCwwLDEsLjA4LjJWNy40MWEuMzIuMzIsMCwwLDEtLjA4LjIxLjI1LjI1LDAsMCwxLS4xOS4wOEg0LjY4YS4yNy4yNywwLDAsMS0uMTktLjA4LjMuMywwLDAsMS0uMDgtLjIxVjUuNzNhLjMyLjMyLDAsMCwxLC4wOC0uMjEuMjUuMjUsMCwwLDEsLjE5LS4wOEgxOS44N2EuMjguMjgsMCwwLDEsLjIuMDlaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjQxIC01LjQ0KVwiLz48L2c+PC9zdmc+JyxcbiAgIGV4cGFuc2lvbjogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNzQgMTUuNzRcIj48Zz48cGF0aCBkPVwiTTExLjgsMTMuMDZsLTUuMSw1LjFIOS41MVYxOS41SDQuNDFWMTQuNEg1Ljc1djIuODFMOC4zLDE0LjY2cTIuMjUtMi4yMywyLjU1LTIuNTVabTguMzUtOS4zdjUuMUgxOC44MVY2LjA1bC01LjEsNS4xLTEtMSw1LjEtNS4xSDE1LjA1VjMuNzZaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjQxIC0zLjc2KVwiLz48L2c+PC9zdmc+JyxcbiAgIHJlZHVjdGlvbjogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNzQgMTUuNzRcIj48Zz48cGF0aCBkPVwiTTE0LjkxLDEwaDIuODd2MS4zOEgxMi41NVY2LjEyaDEuMzhWOWw1LjI0LTUuMjQuNDguNDkuNDkuNDhaTTYuNzcsMTEuOTJIMTJ2NS4yM0gxMC42MlYxNC4yNkw1LjM3LDE5LjVsLTEtMUw5LjYzLDEzLjNINi43N1pcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNCAtMy43NilcIi8+PC9nPjwvc3ZnPicsXG4gICBjb2RlX3ZpZXc6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1LjczIDExLjhcIj48Zz48cGF0aCBkPVwiTTguMDksNy45NGEuNzYuNzYsMCwwLDEsLjUzLjIyLjcyLjcyLDAsMCwxLC4yMS41Mi43Ni43NiwwLDAsMS0uMjIuNTRMNi4xOCwxMS42M2wyLjQzLDIuNDRhLjY5LjY5LDAsMCwxLC4yLjUxLjY2LjY2LDAsMCwxLS4yMS41MS43NS43NSwwLDAsMS0uNTEuMjIuNjMuNjMsMCwwLDEtLjUxLS4yMWgwTDQuNjMsMTIuMTVhLjcuNywwLDAsMS0uMjItLjUzLjY3LjY3LDAsMCwxLC4yNS0uNTVMNy41Nyw4LjE2YS44Mi44MiwwLDAsMSwuNTItLjIyWm0xMi4wNSwzLjY5YS43LjcsMCwwLDEtLjIzLjUyTDE3LDE1LjFoMGEuNjYuNjYsMCwwLDEtLjUxLjIxLjczLjczLDAsMCwxLS41MS0uMjIuNzUuNzUsMCwwLDEtLjIyLS41MS42My42MywwLDAsMSwuMjEtLjUxbDIuNDMtMi40NEwxNS45Miw5LjIyYS43My43MywwLDAsMS0uMjItLjUzQS43NC43NCwwLDAsMSwxNyw4LjE4aDBsMi45MSwyLjkxYS42Ny42NywwLDAsMSwuMjcuNTRabS01LjktNS45YS43My43MywwLDAsMSwuNjEuMzIuNzEuNzEsMCwwLDEsLjA3LjY4TDExLDE3YTEsMSwwLDAsMS0uMjIuMzIuNi42LDAsMCwxLS4zNS4xNi43NS43NSwwLDAsMS0uNjktLjI2LjY5LjY5LDAsMCwxLS4xMi0uNzJMMTMuNTYsNi4yM2EuNzUuNzUsMCwwLDEsLjI2LS4zNS43NC43NCwwLDAsMSwuNDItLjE1WlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC40MSAtNS43MylcIi8+PC9nPjwvc3ZnPicsXG4gICBwcmV2aWV3OiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS42NSAxNS42NlwiPjxnPjxwYXRoIGQ9XCJNMTYuMTksMTQuNDNsMi40OSwyLjQ5YS43My43MywwLDAsMSwuMjEuNTIuNjcuNjcsMCwwLDEtLjIyLjUxLjcuNywwLDAsMS0uNTIuMjIuNjkuNjksMCwwLDEtLjUxLS4yMWwtMi40OS0yLjQ4YTUuMTcsNS4xNywwLDAsMS0xLjM0LjY5LDQuNjQsNC42NCwwLDAsMS0xLjQ4LjI0LDQuNzgsNC43OCwwLDEsMSwwLTkuNTYsNC43OSw0Ljc5LDAsMCwxLDEuODQuMzYsNC45LDQuOSwwLDAsMSwxLjU2LDEsNC43Nyw0Ljc3LDAsMCwxLC40Niw2LjE4Wk0xMCwxNGEzLjMsMy4zLDAsMCwwLDIuMzQuOTNBMy4zNywzLjM3LDAsMCwwLDE0LjcsMTRhMy4zLDMuMywwLDAsMC0xLjA4LTUuNDEsMy40NywzLjQ3LDAsMCwwLTIuNTYsMEEzLDMsMCwwLDAsMTAsOS4yOCwzLjMxLDMuMzEsMCwwLDAsMTAsMTRaTTE2LDRhMy44NiwzLjg2LDAsMCwxLDIuNzcsMS4xNEEzLjksMy45LDAsMCwxLDIwLDcuODV2NGEuNzcuNzcsMCwwLDEtLjIyLjUzLjcuNywwLDAsMS0uNTIuMjEuNzIuNzIsMCwwLDEtLjc0LS43NHYtNGEyLjQ2LDIuNDYsMCwwLDAtLjcyLTEuNzNBMi4zNywyLjM3LDAsMCwwLDE2LDUuNDVIOC41M0EyLjQyLDIuNDIsMCwwLDAsNi4wOCw3Ljg5djcuNTJhMi40MSwyLjQxLDAsMCwwLC43MSwxLjczLDIuNDYsMi40NiwwLDAsMCwxLjc0LjcyaDQuMDhhLjczLjczLDAsMCwxLDAsMS40Nkg4LjUzYTMuODUsMy44NSwwLDAsMS0yLjc4LTEuMTRBMy45MywzLjkzLDAsMCwxLDQuNiwxNS40VjcuODdBMy45NCwzLjk0LDAsMCwxLDUuNzYsNS4wOSwzLjg4LDMuODgsMCwwLDEsOC41NCw0SDE2WlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC40NSAtMy44KVwiLz48L2c+PC9zdmc+JyxcbiAgIHByaW50OiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNi4wNSAxNi4wNFwiPjxnPjxwYXRoIGQ9XCJNMTkuNzYsMTUuODRhMS4yOSwxLjI5LDAsMCwwLC4zOS0uOTJWOC4zNUEyLjA1LDIuMDUsMCwwLDAsMTkuNTcsN2ExLjkzLDEuOTMsMCwwLDAtMS4zOC0uNTdINi4zN2ExLjk1LDEuOTUsMCwwLDAtMiwydjYuNTZhMS4yMywxLjIzLDAsMCwwLC4zOC45MiwxLjM1LDEuMzUsMCwwLDAsLjkzLjM4aDJWMTQuOWwtMiwwVjguMzVhLjY3LjY3LDAsMCwxLC4xOC0uNDcuNjIuNjIsMCwwLDEsLjQ4LS4xOUgxOC4xOGEuNi42LDAsMCwxLC40Ni4xOS42Ni42NiwwLDAsMSwuMTguNDdWMTQuOWgtMnYxLjMyaDJBMS4zNSwxLjM1LDAsMCwwLDE5Ljc2LDE1Ljg0Wk0xNy41Miw3LjY5VjUuMDZhMS4zMSwxLjMxLDAsMCwwLS4zOC0uOTIsMS4zNCwxLjM0LDAsMCwwLS45NC0uMzhIOC4zNEExLjMsMS4zLDAsMCwwLDcsNS4wNlY3LjY5SDguMzRWNS4wNmg3Ljg3VjcuNjloMS4zMVpNOC4zNCwxMi45M2g3Ljg3bDAsNS4yNkg4LjM0VjEyLjkzWm03Ljg3LDUuMjZ2MFptLjY1LDEuMzFhLjYuNiwwLDAsMCwuNDYtLjE5LjcyLjcyLDAsMCwwLC4yLS40N1YxMi4yOWEuNzQuNzQsMCwwLDAtLjItLjQ3LjYuNiwwLDAsMC0uNDYtLjE5SDcuNjhhLjYuNiwwLDAsMC0uNDYuMTkuNzIuNzIsMCwwLDAtLjIuNDd2Ni41NWEuNzQuNzQsMCwwLDAsLjIuNDcuNi42LDAsMCwwLC40Ni4xOWg5LjE4Wk0xNi42Nyw5LjI4YS43LjcsMCwwLDAtLjk0LDAsLjYzLjYzLDAsMCwwLS4xOC40Ni42Ny42NywwLDAsMCwuMTguNDcuNjguNjgsMCwwLDAsLjk0LDAsLjY2LjY2LDAsMCwwLC4xOC0uNDdBLjU4LjU4LDAsMCwwLDE2LjY3LDkuMjhaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjI1IC0zLjYxKVwiLz48L2c+PC9zdmc+JyxcbiAgIHRlbXBsYXRlOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNC4yNyAxNS42NFwiPjxnPjxwYXRoIGQ9XCJNMTguMTgsMTkuMTZhMSwxLDAsMCwwLDEtMVY1LjczYTEsMSwwLDAsMC0xLTFoLTJ2MWgyVjE4LjE5SDYuMzdWNS43M2gydi0xaC0yQS45NC45NCwwLDAsMCw1LjY4LDVhMSwxLDAsMCwwLS4yOS43VjE4LjE4YS45NC45NCwwLDAsMCwuMjkuNjksMSwxLDAsMCwwLC42OS4yOUgxOC4xOFpNOS44MiwxMC4zMWg0LjkyYS40OS40OSwwLDAsMCwuMzUtLjE1LjQ3LjQ3LDAsMCwwLC4xNS0uMzUuNDkuNDksMCwwLDAtLjE1LS4zNS40Ny40NywwLDAsMC0uMzUtLjE1SDkuODJhLjQ5LjQ5LDAsMCwwLS4zNS4xNS40Ny40NywwLDAsMC0uMTUuMzUuNDkuNDksMCwwLDAsLjE1LjM1LjQ3LjQ3LDAsMCwwLC4zNS4xNVptNS45LDQuOTJIOC44M2EuNDkuNDksMCwwLDAtLjM1LjE1LjQ3LjQ3LDAsMCwwLS4xNS4zNS40OS40OSwwLDAsMCwuMTUuMzUuNDcuNDcsMCwwLDAsLjM1LjE1aDYuODlhLjQ5LjQ5LDAsMCwwLC4zNS0uMTUuNDcuNDcsMCwwLDAsLjE1LS4zNS41MS41MSwwLDAsMC0uNS0uNVpNNy4zNiwxMi43N2EuNDkuNDksMCwwLDAsLjE1LjM1LjQ3LjQ3LDAsMCwwLC4zNS4xNWg4Ljg1YS40OS40OSwwLDAsMCwuMzUtLjE1LjQ3LjQ3LDAsMCwwLC4xNS0uMzUuNDkuNDksMCwwLDAtLjE1LS4zNS40Ny40NywwLDAsMC0uMzUtLjE1SDcuODVhLjQ5LjQ5LDAsMCwwLS4zNS4xNS41Mi41MiwwLDAsMC0uMTQuMzVaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC01LjE0IC0zLjc3KVwiLz48cGF0aCBkPVwiTTE0LjI0LDYuNzFhMSwxLDAsMCwwLDEtMSwxLDEsMCwwLDAtMS0xLDEsMSwwLDAsMC0xLTFoLTJhLjk0Ljk0LDAsMCwwLS42OS4yOCwxLDEsMCwwLDAtLjI5LjdBLjk0Ljk0LDAsMCwwLDkuNjIsNWEuOTEuOTEsMCwwLDAtLjI5LjY5LDEsMSwwLDAsMCwuMjkuNywxLDEsMCwwLDAsLjY5LjI5aDMuOTNaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC01LjE0IC0zLjc3KVwiLz48L2c+PC9zdmc+JyxcbiAgIGxpbmVfaGVpZ2h0OiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS43NiAxMy41NlwiPjxnPjxwYXRoIGQ9XCJNNC40LDQuODhWOC4yNmEyLDIsMCwwLDAsLjUuMzlzLjEsMCwuMTgtLjEyYS42Mi42MiwwLDAsMCwuMTctLjI4Yy4wNi0uMTkuMTMtLjQ0LjIxLS43NHMuMTQtLjUyLjE5LS42NmEuNTguNTgsMCwwLDEsLjIxLS4zLDIuNDEsMi40MSwwLDAsMSwuNjMtLjIxLDMuODMsMy44MywwLDAsMSwuODgtLjEyLDkuMTUsOS4xNSwwLDAsMSwxLjMxLjA2LjE2LjE2LDAsMCwxLC4xMSwwLC4yNi4yNiwwLDAsMSwuMDYuMTQsNCw0LDAsMCwxLDAsLjQ5djJsLjA1LDMuNzdjMCwxLjQxLDAsMi42OC0uMDUsMy44MWExLjc5LDEuNzksMCwwLDEtLjExLjQ5LDEwLjY4LDEwLjY4LDAsMCwxLTEuNC40NSwxLjEyLDEuMTIsMCwwLDAtLjY5LjQzdi4zMWwwLC4yMi42MSwwYy44NS0uMDgsMS41NC0uMTIsMi4wNi0uMTJhMTkuNzYsMTkuNzYsMCwwLDEsMi4wOS4wOCwxNS4wOCwxNS4wOCwwLDAsMCwxLjY0LjA4LDEuNCwxLjQsMCwwLDAsLjI5LDAsMS41OCwxLjU4LDAsMCwwLDAtLjI2bC0uMDUtLjQzYTIuMjYsMi4yNiwwLDAsMC0uNDMtLjE3bC0uNzctLjIyLS4xNSwwYTIuNTUsMi41NSwwLDAsMS0uNzgtLjI4LDIuNTYsMi41NiwwLDAsMS0uMTEtLjc1bDAtMS4yOSwwLTMuMTVWNy41M2ExMC41MSwxMC41MSwwLDAsMSwuMDYtMS4yLDMuODMsMy44MywwLDAsMSwuNiwwbDEuODgsMGEyLjE4LDIuMTgsMCwwLDEsLjM4LDAsLjQ1LjQ1LDAsMCwxLC4yMy4xNy45LjksMCwwLDEsLjA1LjI1YzAsLjE2LjA2LjM1LjEuNThhMy4zMywzLjMzLDAsMCwwLC4xNC41NUE2LjM5LDYuMzksMCwwLDAsMTUsOWEyLjkxLDIuOTEsMCwwLDAsLjYtLjE1LDIuNzcsMi43NywwLDAsMCwwLS40NmwwLS41MSwwLTIuOTUtLjI1LDAtLjM4LDBMMTUsNC45NGEuNzEuNzEsMCwwLDEtLjE4LjE1LjQ1LjQ1LDAsMCwxLS4yNS4wN2wtLjI5LDBIOC43NWwtLjE1LDBINy40NWExNywxNywwLDAsMS0xLjg2LDBMNS4zNiw1bC0uMjUtLjEzWk0xOS43NSwxNi4xNGgtLjY5di05aC42OUEuNC40LDAsMCwwLDIwLjEzLDdjLjA2LS4xMSwwLS4yNC0uMS0uMzlMMTguOTIsNS4xNWEuNTIuNTIsMCwwLDAtLjg2LDBMMTcsNi41OGMtLjEyLjE1LS4xNi4yOC0uMS4zOXMuMTguMTYuMzguMTZoLjY5djloLS42OWEuNC40LDAsMCwwLS4zOC4xNmMtLjA2LjExLDAsLjI0LjEuMzlsMS4xMSwxLjQzYS41Mi41MiwwLDAsMCwuODYsMEwyMCwxNi42OWMuMTItLjE1LjE2LS4yOC4xLS4zOWEuNC40LDAsMCwwLS4zOC0uMTZaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjQgLTQuODYpXCIvPjwvZz48L3N2Zz4nLFxuICAgcGFyYWdyYXBoX3N0eWxlOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxMS44MSAxNS43NFwiPjxnPjxwYXRoIGQ9XCJNMTguMTgsMy43NnYyaC0yVjE5LjVoLTJWNS43M2gtMlYxOS41aC0yVjExLjYzYTMuOTQsMy45NCwwLDAsMSwwLTcuODdoNy44N1pcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTYuMzcgLTMuNzYpXCIvPjwvZz48L3N2Zz4nLFxuICAgdGV4dF9zdHlsZTogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTMuNzYgMTUuNzRcIj48Zz48cGF0aCBkPVwiTTE3LjY4LDYuNzFhMi4yMiwyLjIyLDAsMCwwLDEuMDYtLjIyLjc0Ljc0LDAsMCwwLC40Mi0uNy43My43MywwLDAsMC0uMDgtLjMzLjY3LjY3LDAsMCwwLS4xNy0uMjIsMSwxLDAsMCwwLS4zMS0uMTVMMTguMjYsNWwtLjQ1LS4wOUExNS4yNywxNS4yNywwLDAsMCwxMy4yNiw1VjQuNzRjMC0uNjYtLjYzLTEtMS45Mi0xLS4yNCwwLS40My4xNS0uNTkuNDZhNCw0LDAsMCwwLS4zNiwxLjE0aDB2MGEyNi40NSwyNi40NSwwLDAsMS0zLjUuMzVBMiwyLDAsMCwwLDUuNzcsNmEuODQuODQsMCwwLDAtLjM3Ljc5LDIuMTQsMi4xNCwwLDAsMCwuNDEsMS4yOSwxLjIzLDEuMjMsMCwwLDAsMS4wNS42MywxNi42MiwxNi42MiwwLDAsMCwzLjI5LS40NWwtLjM0LDMuMzVjLS4xNiwxLjYxLS4yOSwyLjktLjM3LDMuODZzLS4xMiwxLjY2LS4xMiwyLjA5bDAsLjY1YTUuMTUsNS4xNSwwLDAsMCwuMDUuNiwxLjI4LDEuMjgsMCwwLDAsLjE2LjU0LjM0LjM0LDAsMCwwLC4yOC4xOCwxLjE2LDEuMTYsMCwwLDAsLjc5LS40NiwzLjY2LDMuNjYsMCwwLDAsLjY4LTEsMjIuMDgsMjIuMDgsMCwwLDAsMS00LjMzcS40OS0zLjEuNzgtNi4xNWEyNC42OSwyNC42OSwwLDAsMSw0LjYyLS44NFpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTUuNCAtMy43NilcIi8+PC9nPjwvc3ZnPicsXG4gICBzYXZlOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS43NCAxNS43NFwiPjxnPjxwYXRoIGQ9XCJNMTguNTMsMTkuNWwuMi0uMDVBMS43OCwxLjc4LDAsMCwwLDIwLjEzLDE4bDAtLjA5VjcuMTRhMiwyLDAsMCwwLS4yOC0uNjRBMy4xOCwzLjE4LDAsMCwwLDE5LjQzLDZjLS41LS41Mi0xLTEtMS41NS0xLjU0QTIuNTksMi41OSwwLDAsMCwxNy4zNyw0YTEuODMsMS44MywwLDAsMC0uNjEtLjI1SDZsLS4yMSwwYTEuNzgsMS43OCwwLDAsMC0xLjQsMS40OWwwLC4xVjE3Ljg3YTIuNDksMi40OSwwLDAsMCwuMDkuMzcsMS43OSwxLjc5LDAsMCwwLDEuNDQsMS4yM2wuMDksMFptLTYuMjUtLjZINi45MmEuNjEuNjEsMCwwLDEtLjY4LS40OC43OC43OCwwLDAsMSwwLS4yMlYxMi4zYS42Mi42MiwwLDAsMSwuNjktLjY4SDE3LjY0YS42Mi42MiwwLDAsMSwuNjkuNjlWMTguMmEuNjQuNjQsMCwwLDEtLjcxLjY5SDEyLjI4Wk0xMiw5LjgxSDguMTVhLjYzLjYzLDAsMCwxLS43Mi0uNzF2LTRhLjY0LjY0LDAsMCwxLC43Mi0uNzJoNy42NmEuNjQuNjQsMCwwLDEsLjcyLjcydjRhLjY1LjY1LDAsMCwxLS43NC43MlpNMTMuNSw1VjkuMThoMS43OFY1WlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC40MSAtMy43NilcIi8+PC9nPjwvc3ZnPicsXG4gICBibG9ja3F1b3RlOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCA0NzUuMDgyIDQ3NS4wODFcIj48Zz48cGF0aCBkPVwiTTE2NC40NSwyMTkuMjdoLTYzLjk1NGMtNy42MTQsMC0xNC4wODctMi42NjQtMTkuNDE3LTcuOTk0Yy01LjMyNy01LjMzLTcuOTk0LTExLjgwMS03Ljk5NC0xOS40MTd2LTkuMTMyYzAtMjAuMTc3LDcuMTM5LTM3LjQwMSwyMS40MTYtNTEuNjc4YzE0LjI3Ni0xNC4yNzIsMzEuNTAzLTIxLjQxMSw1MS42NzgtMjEuNDExaDE4LjI3MWM0Ljk0OCwwLDkuMjI5LTEuODA5LDEyLjg0Ny01LjQyNGMzLjYxNi0zLjYxNyw1LjQyNC03Ljg5OCw1LjQyNC0xMi44NDdWNTQuODE5YzAtNC45NDgtMS44MDktOS4yMzMtNS40MjQtMTIuODVjLTMuNjE3LTMuNjEyLTcuODk4LTUuNDI0LTEyLjg0Ny01LjQyNGgtMTguMjcxYy0xOS43OTcsMC0zOC42ODQsMy44NTgtNTYuNjczLDExLjU2M2MtMTcuOTg3LDcuNzEtMzMuNTQ1LDE4LjEzMi00Ni42OCwzMS4yNjdjLTEzLjEzNCwxMy4xMjktMjMuNTUzLDI4LjY4OC0zMS4yNjIsNDYuNjc3QzMuODU1LDE0NC4wMzksMCwxNjIuOTMxLDAsMTgyLjcyNnYyMDAuOTkxYzAsMTUuMjM1LDUuMzI3LDI4LjE3MSwxNS45ODYsMzguODM0YzEwLjY2LDEwLjY1NywyMy42MDYsMTUuOTg1LDM4LjgzMiwxNS45ODVoMTA5LjYzOWMxNS4yMjUsMCwyOC4xNjctNS4zMjgsMzguODI4LTE1Ljk4NWMxMC42NTctMTAuNjYzLDE1Ljk4Ny0yMy41OTksMTUuOTg3LTM4LjgzNFYyNzQuMDg4YzAtMTUuMjMyLTUuMzMtMjguMTY4LTE1Ljk5NC0zOC44MzJDMTkyLjYyMiwyMjQuNiwxNzkuNjc1LDIxOS4yNywxNjQuNDUsMjE5LjI3elwiLz48cGF0aCBkPVwiTTQ1OS4xMDMsMjM1LjI1NmMtMTAuNjU2LTEwLjY1Ni0yMy41OTktMTUuOTg2LTM4LjgyOC0xNS45ODZoLTYzLjk1M2MtNy42MSwwLTE0LjA4OS0yLjY2NC0xOS40MS03Ljk5NGMtNS4zMzItNS4zMy03Ljk5NC0xMS44MDEtNy45OTQtMTkuNDE3di05LjEzMmMwLTIwLjE3Nyw3LjEzOS0zNy40MDEsMjEuNDA5LTUxLjY3OGMxNC4yNzEtMTQuMjcyLDMxLjQ5Ny0yMS40MTEsNTEuNjgyLTIxLjQxMWgxOC4yNjdjNC45NDksMCw5LjIzMy0xLjgwOSwxMi44NDgtNS40MjRjMy42MTMtMy42MTcsNS40MjgtNy44OTgsNS40MjgtMTIuODQ3VjU0LjgxOWMwLTQuOTQ4LTEuODE0LTkuMjMzLTUuNDI4LTEyLjg1Yy0zLjYxNC0zLjYxMi03Ljg5OC01LjQyNC0xMi44NDgtNS40MjRoLTE4LjI2N2MtMTkuODA4LDAtMzguNjkxLDMuODU4LTU2LjY4NSwxMS41NjNjLTE3Ljk4NCw3LjcxLTMzLjUzNywxOC4xMzItNDYuNjcyLDMxLjI2N2MtMTMuMTM1LDEzLjEyOS0yMy41NTksMjguNjg4LTMxLjI2NSw0Ni42NzdjLTcuNzA3LDE3Ljk4Ny0xMS41NjcsMzYuODc5LTExLjU2Nyw1Ni42NzR2MjAwLjk5MWMwLDE1LjIzNSw1LjMzMiwyOC4xNzEsMTUuOTg4LDM4LjgzNGMxMC42NTcsMTAuNjU3LDIzLjYsMTUuOTg1LDM4LjgyOCwxNS45ODVoMTA5LjYzM2MxNS4yMjksMCwyOC4xNzEtNS4zMjgsMzguODI3LTE1Ljk4NWMxMC42NjQtMTAuNjYzLDE1Ljk4NS0yMy41OTksMTUuOTg1LTM4LjgzNFYyNzQuMDg4QzQ3NS4wODIsMjU4Ljg1NSw0NjkuNzYsMjQ1LjkyLDQ1OS4xMDMsMjM1LjI1NnpcIi8+PC9nPjwvc3ZnPicsXG4gICBhcnJvd19kb3duOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS43MyA4LjY3XCI+PGc+PHBhdGggZD1cIk0xOC43OSw3LjUyYS44LjgsMCwwLDEsLjU2LS4yMy44Mi44MiwwLDAsMSwuNzkuNzkuOC44LDAsMCwxLS4yMy41NmwtNy4wNyw3LjA3YS43OS43OSwwLDAsMS0uNTcuMjUuNzcuNzcsMCwwLDEtLjU3LS4yNWgwTDQuNjQsOC42NWEuOC44LDAsMCwxLS4yMy0uNTcuODIuODIsMCwwLDEsLjc5LS43OS44LjgsMCwwLDEsLjU2LjIzTDEyLjI4LDE0bDMuMjYtMy4yNiwzLjI1LTMuMjZaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjQxIC03LjI5KVwiLz48L2c+PC9zdmc+JyxcbiAgIGFsaWduX2p1c3RpZnk6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc0IDEzLjc3XCI+PGc+PHBhdGggZD1cIk00LjQxLDQuNzR2MkgyMC4xNXYtMkg0LjQxWm0wLDUuOUgyMC4xNXYtMkg0LjQxdjJabTAsMy45NEgyMC4xNXYtMkg0LjQxdjJabTAsMy45M2g3Ljg3di0ySDQuNDF2MlpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNDEgLTQuNzQpXCIvPjwvZz48L3N2Zz4nLFxuICAgYWxpZ25fbGVmdDogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNzQgMTMuNzdcIj48Zz48cGF0aCBkPVwiTTQuNDEsNC43NHYySDIwLjE1di0ySDQuNDFabTExLjgsMy45NEg0LjQxdjJIMTYuMjJ2LTJabS0xMS44LDUuOUgxOC4xOHYtMkg0LjQxdjJabTAsMy45M2g5Ljg0di0ySDQuNDF2MlpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNDEgLTQuNzQpXCIvPjwvZz48L3N2Zz4nLFxuICAgYWxpZ25fcmlnaHQ6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc0IDEzLjc3XCI+PGc+PHBhdGggZD1cIk00LjQxLDQuNzR2MkgyMC4xNXYtMkg0LjQxWm0zLjkzLDUuOUgyMC4xNXYtMkg4LjM0djJabS0yLDMuOTRIMjAuMTR2LTJINi4zN3YyWm0zLjk0LDMuOTNoOS44NHYtMkgxMC4zMXYyWlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC40MSAtNC43NClcIi8+PC9nPjwvc3ZnPicsXG4gICBhbGlnbl9jZW50ZXI6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc0IDEzLjc3XCI+PGc+PHBhdGggZD1cIk00LjQxLDQuNzR2MkgyMC4xNXYtMkg0LjQxWm0yLDMuOTR2MkgxOC4xOHYtMkg2LjM3Wm0tMSw1LjlIMTkuMTZ2LTJINS4zOXYyWm0yLDMuOTNIMTcuMnYtMkg3LjM2djJaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjQxIC00Ljc0KVwiLz48L2c+PC9zdmc+JyxcbiAgIGZvbnRfY29sb3I6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc0IDE0LjYxXCI+PGc+PHBhdGggZD1cIk0xOC41LDE1LjU3LDE0LjI4LDQuMzJoLTMuNEw2LjY1LDE1LjU3aDNsLjgtMi4yNmg0LjIzbC44LDIuMjZoM1pNMTQsMTEuMDdIMTEuMTRMMTIuNTQsNywxMy4yNSw5Yy40MSwxLjE4LjY0LDEuODYuNywyWk00LjQxLDE2LjY5djIuMjRIMjAuMTVWMTYuNjlINC40MVpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNDEgLTQuMzIpXCIvPjwvZz48L3N2Zz4nLFxuICAgaGlnaGxpZ2h0X2NvbG9yOic8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1LjY2IDE1Ljc0XCI+PGc+PHBhdGggZD1cIk0xMi4zMiw5LjMxLDEzLjM4LDEzSDExLjIxbC41Mi0xLjgzcS40Ni0xLjYxLjU0LTEuODNaTTQuNDQsMy43NkgyMC4xVjE5LjVINC40NFYzLjc2Wk0xNC43MSwxNy4zMmgyLjYzTDEzLjcsNkgxMC44OUw3LjI2LDE3LjMySDkuODlsLjYzLTIuMjRoMy41NWwuMzIsMS4xMmMuMTguNjUuMjksMSwuMzIsMS4xMlpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNDQgLTMuNzYpXCIvPjwvZz48L3N2Zz4nLFxuICAgbGlzdF9idWxsZXRzOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS43NCAxMi4zN1wiPjxnPjxwYXRoIGQ9XCJNNy43NywxNi4xMmExLjU5LDEuNTksMCwwLDAtLjQ5LTEuMTgsMS42MiwxLjYyLDAsMCwwLTEuMTktLjQ5LDEuNjgsMS42OCwwLDEsMCwwLDMuMzYsMS42NywxLjY3LDAsMCwwLDEuNjgtMS42OVptMC00LjQ4QTEuNjcsMS42NywwLDAsMCw2LjA5LDEwLDEuNjgsMS42OCwwLDAsMCw0LjksMTIuODJhMS42MiwxLjYyLDAsMCwwLDEuMTkuNDksMS42NywxLjY3LDAsMCwwLDEuNjgtMS42N1ptMTIuMzgsMy42NGEuMjcuMjcsMCwwLDAtLjA4LS4xOS4yOC4yOCwwLDAsMC0uMi0uMDlIOS4xOWEuMjguMjgsMCwwLDAtLjIuMDguMjkuMjksMCwwLDAtLjA4LjE5VjE3YS4yNy4yNywwLDAsMCwuMjguMjhIMTkuODdhLjI3LjI3LDAsMCwwLC4xOS0uMDguMjQuMjQsMCwwLDAsLjA4LS4yVjE1LjI4Wk03Ljc3LDcuMTNhMS42MywxLjYzLDAsMCwwLS40OS0xLjIsMS42MSwxLjYxLDAsMCwwLTEuMTktLjQ5LDEuNjEsMS42MSwwLDAsMC0xLjE5LjQ5LDEuNzEsMS43MSwwLDAsMCwwLDIuNCwxLjYyLDEuNjIsMCwwLDAsMS4xOS40OSwxLjYxLDEuNjEsMCwwLDAsMS4xOS0uNDksMS42MywxLjYzLDAsMCwwLC40OS0xLjJabTEyLjM4LDMuNjZhLjI4LjI4LDAsMCwwLS4wOC0uMi4yOS4yOSwwLDAsMC0uMTktLjA4SDkuMTlhLjI3LjI3LDAsMCwwLS4yOC4yOHYxLjY5YS4yNy4yNywwLDAsMCwuMDguMTkuMjQuMjQsMCwwLDAsLjIuMDhIMTkuODdhLjI3LjI3LDAsMCwwLC4xOS0uMDguMjUuMjUsMCwwLDAsLjA4LS4xOVYxMC43OVptMC00LjVhLjI3LjI3LDAsMCwwLS4wOC0uMTlBLjI1LjI1LDAsMCwwLDE5Ljg4LDZIOS4xOUEuMjguMjgsMCwwLDAsOSw2LjFhLjI2LjI2LDAsMCwwLS4wOC4xOVY4QS4yNy4yNywwLDAsMCw5LDguMTdhLjI0LjI0LDAsMCwwLC4yLjA4SDE5Ljg3YS4yNy4yNywwLDAsMCwuMTktLjA4QS4yNS4yNSwwLDAsMCwyMC4xNCw4VjYuMjlaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjQxIC01LjQ0KVwiLz48L2c+PC9zdmc+JyxcbiAgIGxpc3RfbnVtYmVyOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS42OSAxNS43NFwiPjxnPjxwYXRoIGQ9XCJNNy42NiwxOGExLjI0LDEuMjQsMCwwLDAtLjI2LS43OCwxLjE3LDEuMTcsMCwwLDAtLjcyLS40MmwuODUtMVYxNUg0LjU4djEuMzRoLjk0di0uNDZsLjg1LDBoMGMtLjExLjExLS4yMi4yMy0uMzIuMzVzLS4yMy4yNy0uMzcuNDdMNS4zOSwxN2wuMjMuNTFjLjYxLS4wNS45Mi4xMS45Mi40OWEuNDIuNDIsMCwwLDEtLjE4LjM3Ljc5Ljc5LDAsMCwxLS40NS4xMkExLjQxLDEuNDEsMCwwLDEsNSwxOC4xNWwtLjUxLjc3QTIuMDYsMi4wNiwwLDAsMCw2LDE5LjVhMS44LDEuOCwwLDAsMCwxLjItLjQxQTEuMzgsMS4zOCwwLDAsMCw3LjY2LDE4Wm0wLTUuNTRINi43NVYxM0g1LjYzQS43Mi43MiwwLDAsMSw2LDEyLjUxYTUuNDUsNS40NSwwLDAsMSwuNjYtLjQ1LDIuNzEsMi43MSwwLDAsMCwuNjctLjU3LDEuMTksMS4xOSwwLDAsMCwuMzEtLjgxLDEuMjksMS4yOSwwLDAsMC0uNDUtMSwxLjg2LDEuODYsMCwwLDAtMi0uMTEsMS41MSwxLjUxLDAsMCwwLS42Mi43bC43NC41MkEuODcuODcsMCwwLDEsNiwxMC4yOGEuNTEuNTEsMCwwLDEsLjM1LjEyLjQyLjQyLDAsMCwxLC4xMy4zMy41NS41NSwwLDAsMS0uMjEuNCwzLDMsMCwwLDEtLjUuMzhjLS4xOS4xMy0uMzkuMjctLjU4LjQyYTIsMiwwLDAsMC0uNS42LDEuNjMsMS42MywwLDAsMC0uMjEuODEsMy44OSwzLjg5LDAsMCwwLC4wNS40OGgzLjJWMTIuNDRabTEyLjQ1LDIuODJhLjI3LjI3LDAsMCwwLS4wOC0uMTkuMjguMjgsMCwwLDAtLjIxLS4wOEg5LjFhLjMyLjMyLDAsMCwwLS4yMS4wOC4yNC4yNCwwLDAsMC0uMDguMlYxN2EuMjcuMjcsMCwwLDAsLjA4LjE5LjMuMywwLDAsMCwuMjEuMDhIMTkuODNhLjMyLjMyLDAsMCwwLC4yMS0uMDguMjUuMjUsMCwwLDAsLjA4LS4xOVYxNS4yNlpNNy42OSw3LjMyaC0xVjMuNzZINS44TDQuNiw0Ljg4bC42My42OGExLjg1LDEuODUsMCwwLDAsLjQzLS40OGgwbDAsMi4yNEg0Ljc0VjguMmgzVjcuMzJabTEyLjQzLDMuNDJhLjI3LjI3LDAsMCwwLS4wOC0uMTkuMjguMjgsMCwwLDAtLjIxLS4wOEg5LjFhLjMyLjMyLDAsMCwwLS4yMS4wOC4yNC4yNCwwLDAsMC0uMDguMnYxLjcxYS4yNy4yNywwLDAsMCwuMDguMTkuMy4zLDAsMCwwLC4yMS4wOEgxOS44M2EuMzIuMzIsMCwwLDAsLjIxLS4wOC4yNS4yNSwwLDAsMCwuMDgtLjE5VjEwLjc0Wm0wLTQuNTJBLjI3LjI3LDAsMCwwLDIwLDYsLjI4LjI4LDAsMCwwLDE5LjgzLDZIOS4xQS4zMi4zMiwwLDAsMCw4Ljg5LDZhLjI0LjI0LDAsMCwwLS4wOC4xOVY3LjkzYS4yNy4yNywwLDAsMCwuMDguMTkuMzIuMzIsMCwwLDAsLjIxLjA4SDE5LjgzQS4zMi4zMiwwLDAsMCwyMCw4LjEyYS4yNi4yNiwwLDAsMCwuMDgtLjJWNi4yMlpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNDMgLTMuNzYpXCIvPjwvZz48L3N2Zz4nLFxuICAgdGFibGU6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc0IDE1Ljc0XCI+PGc+PHBhdGggZD1cIk00LjQxLDguMDVWMy43Nkg4LjdWOC4wNUg0LjQxWm01LjcxLDBWMy43Nmg0LjNWOC4wNWgtNC4zWm01Ljc0LTQuMjloNC4yOVY4LjA1SDE1Ljg2VjMuNzZabS0xMS40NSwxMFY5LjQ4SDguN3Y0LjNINC40MVptNS43MSwwVjkuNDhoNC4zdjQuM2gtNC4zWm01Ljc0LDBWOS40OGg0LjI5djQuM0gxNS44NlpNNC40MSwxOS41VjE1LjIxSDguN1YxOS41SDQuNDFabTUuNzEsMFYxNS4yMWg0LjNWMTkuNWgtNC4zWm01Ljc0LDBWMTUuMjFoNC4yOVYxOS41SDE1Ljg2WlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC40MSAtMy43NilcIi8+PC9nPjwvc3ZnPicsXG4gICBob3Jpem9udGFsX3J1bGU6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc0IDIuMjRcIj48Zz48cGF0aCBkPVwiTTIwLjE1LDEyLjc1VjEwLjUxSDQuNDF2Mi4yNEgyMC4xNVpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNDEgLTEwLjUxKVwiLz48L2c+PC9zdmc+JyxcbiAgIHNob3dfYmxvY2tzOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS42NiAxNS42N1wiPjxnPjxwYXRoIGQ9XCJNMTkuNzIsNS41OGExLjY0LDEuNjQsMCwwLDAtMS42NC0xLjY0SDYuMjNhMS42MiwxLjYyLDAsMCwwLTEuMTYuNDgsMS42MywxLjYzLDAsMCwwLS40OCwxLjE2VjkuNjNhMS42LDEuNiwwLDAsMCwuNDgsMS4xNiwxLjYyLDEuNjIsMCwwLDAsMS4xNi40N0gxOC4wOWExLjY3LDEuNjcsMCwwLDAsMS4xNi0uNDcsMS42MiwxLjYyLDAsMCwwLC40OC0xLjE2VjUuNThabS0uOTQsNC4wNWEuNjguNjgsMCwwLDEtLjcuN0g2LjIzYS42Ni42NiwwLDAsMS0uNDgtLjIuNzQuNzQsMCwwLDEtLjIxLS41VjUuNThhLjY2LjY2LDAsMCwxLC4yLS40OC43MS43MSwwLDAsMSwuNDgtLjIxSDE4LjA4YS43NC43NCwwLDAsMSwuNS4yMS42Ni42NiwwLDAsMSwuMi40OFpNNi40OCw3LjcyYS4yMS4yMSwwLDAsMCwuMTctLjA3LjIyLjIyLDAsMCwwLC4wNy0uMTdWNy4wNmExLjI3LDEuMjcsMCwwLDEsLjExLS41Mi4zNy4zNywwLDAsMSwuMzYtLjIzSDguNzdBLjI1LjI1LDAsMCwwLDksNi4xN2EuMTkuMTksMCwwLDAsMC0uMjMuMjcuMjcsMCwwLDAtLjItLjEySDcuMTlhLjg4Ljg4LDAsMCwwLS43Mi4zOSwxLjUxLDEuNTEsMCwwLDAtLjIzLjg1di40MmEuMjQuMjQsMCwwLDAsLjI0LjI0Wm0tLjE5LjgxYS4yMS4yMSwwLDAsMCwuMTctLjA3LjI2LjI2LDAsMCwwLC4wNy0uMTcuMjQuMjQsMCwwLDAtLjI0LS4yNC4yLjIsMCwwLDAtLjE2LjA5LjIuMiwwLDAsMC0uMDcuMTYuMjIuMjIsMCwwLDAsLjA3LjE3LjIzLjIzLDAsMCwwLC4xNi4wNlptOC40Niw1LjFhMS42MywxLjYzLDAsMCwwLS40Ny0xLjE2QTEuNjEsMS42MSwwLDAsMCwxMy4xMiwxMkg2LjIzYTEuNiwxLjYsMCwwLDAtMS4xNi40NiwxLjYyLDEuNjIsMCwwLDAtLjQ4LDEuMTZ2NC4wNWExLjY0LDEuNjQsMCwwLDAsMS42NCwxLjY0aDYuODlhMS42LDEuNiwwLDAsMCwxLjE2LS40OCwxLjYyLDEuNjIsMCwwLDAsLjQ3LTEuMTZabS0uOTQsNGEuNy43LDAsMCwxLS4yLjQ5LjY1LjY1LDAsMCwxLS41LjJINi4yM2EuNjYuNjYsMCwwLDEtLjQ4LS4yLjc1Ljc1LDAsMCwxLS4yMS0uNDl2LTRhLjc0Ljc0LDAsMCwxLC4yMS0uNS42Ni42NiwwLDAsMSwuNDgtLjJoNi44OWEuNjguNjgsMCwwLDEsLjcuN3Y0Wm02LjE1LDB2LTRhMS42LDEuNiwwLDAsMC0uNDgtMS4xNkExLjY3LDEuNjcsMCwwLDAsMTguMzIsMTJIMTcuMWExLjYzLDEuNjMsMCwwLDAtMS4xNi40NywxLjYxLDEuNjEsMCwwLDAtLjQ3LDEuMTZ2NGExLjY3LDEuNjcsMCwwLDAsLjQ3LDEuMTYsMS42MiwxLjYyLDAsMCwwLDEuMTYuNDhoMS4yMkExLjY0LDEuNjQsMCwwLDAsMjAsMTcuNjhabS0uOTQtNHY0YS43NS43NSwwLDAsMS0uMjEuNDkuNjIuNjIsMCwwLDEtLjQ4LjJIMTcuMTFhLjY5LjY5LDAsMCwxLS41LS4yLjcuNywwLDAsMS0uMi0uNDl2LTRhLjY4LjY4LDAsMCwxLC43LS43aDEuMjJhLjY2LjY2LDAsMCwxLC40OC4yLjcyLjcyLDAsMCwxLC4yMS41WlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC40NCAtMy43OSlcIi8+PC9nPjwvc3ZnPicsXG4gICBjYW5jZWw6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc0IDE1Ljc0XCI+PGc+PHBhdGggZD1cIk0xNC4xNSwxMS42M2w1LjYxLDUuNjFhMS4yOSwxLjI5LDAsMCwxLC4zOC45MywxLjI3LDEuMjcsMCwwLDEtLjQuOTMsMS4yNSwxLjI1LDAsMCwxLS45Mi40LDEuMzEsMS4zMSwwLDAsMS0uOTQtLjRsLTUuNjEtNS42MUw2LjY3LDE5LjFhMS4zMSwxLjMxLDAsMCwxLS45NC40LDEuMjQsMS4yNCwwLDAsMS0uOTItLjQsMS4yNywxLjI3LDAsMCwxLS40LS45MywxLjMzLDEuMzMsMCwwLDEsLjM4LS45M2w1LjYxLTUuNjNMNC43OSw2YTEuMjYsMS4yNiwwLDAsMS0uMzgtLjkzLDEuMjIsMS4yMiwwLDAsMSwuNC0uOTIsMS4yOCwxLjI4LDAsMCwxLC45Mi0uMzksMS4zOCwxLjM4LDAsMCwxLC45NC4zOGw1LjYxLDUuNjEsNS42MS01LjYxYTEuMzMsMS4zMywwLDAsMSwuOTQtLjM4LDEuMjYsMS4yNiwwLDAsMSwuOTIuMzksMS4yNCwxLjI0LDAsMCwxLC40LjkyLDEuMjksMS4yOSwwLDAsMS0uMzkuOTNMMTcsOC44MWwtMi44LDIuODJaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjQxIC0zLjc2KVwiLz48L2c+PC9zdmc+JyxcbiAgIGltYWdlOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS43NSAxNS43N1wiPjxnPjxwYXRoIGQ9XCJNOC43Nyw4LjcyYS44OC44OCwwLDAsMS0uNjEtLjI3LjgyLjgyLDAsMCwxLS4yNS0uNjEuODkuODksMCwwLDEsLjI1LS42MkEuODIuODIsMCwwLDEsOC43Nyw3YS44MS44MSwwLDAsMSwuNjEuMjUuODMuODMsMCwwLDEsLjI3LjYyLjgxLjgxLDAsMCwxLS4yNS42MS45MS45MSwwLDAsMS0uNjMuMjdabTkuNjItNWExLjc0LDEuNzQsMCwwLDEsMS43NiwxLjc2VjE3Ljc2YTEuNzQsMS43NCwwLDAsMS0xLjc2LDEuNzZINi4xNkExLjc0LDEuNzQsMCwwLDEsNC40LDE3Ljc2VjUuNTFBMS43NCwxLjc0LDAsMCwxLDYuMTYsMy43NUgxOC4zOVptMCwxLjc1SDYuMTZ2OEw4LjUzLDExLjhhLjk0Ljk0LDAsMCwxLC41NC0uMTcuODYuODYsMCwwLDEsLjU0LjJMMTEuMDksMTNsMy42NC00LjU1YS43OC43OCwwLDAsMSwuMzQtLjI1Ljg1Ljg1LDAsMCwxLC40Mi0uMDcuODkuODksMCwwLDEsLjM5LjEyLjc4Ljc4LDAsMCwxLC4yOC4yOWwyLjI0LDMuNjdWNS41MVptMCwxMi4yNFYxNS42TDE1LjMsMTAuNTMsMTEuODksMTQuOGEuODkuODksMCwwLDEtLjU5LjMyLjgyLjgyLDAsMCwxLS42NC0uMThMOSwxMy42Miw2LjE2LDE1Ljc0djJaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjQgLTMuNzUpXCIvPjwvZz48L3N2Zz4nLFxuICAgdmlkZW86ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc0IDE0LjU1XCI+PGc+PHBhdGggZD1cIk0yMC4xNSwxMC4yNlYxOC45bC0zLjk0LTEuNTd2MS4ySDQuNDFWMTAuNjZIMTYuMjJ2MS4yM2wyLS44MSwyLS44MlpNMTQuNjQsMTdoMFYxMi41NGgwdi0uMzFINlYxN2g4LjY3Wm0zLjk0LS4zN3YtNGwtMi4zNywxdjJsMS4xOC40OCwxLjE5LjQ4Wk03Ljk0LDkuODZBMi43NywyLjc3LDAsMCwxLDUuMTksNy4xMWEyLjc2LDIuNzYsMCwwLDEsNS41MSwwQTIuNzgsMi43OCwwLDAsMSw3Ljk0LDkuODZabTAtMy45M2ExLjIxLDEuMjEsMCwwLDAtLjgzLjM1LDEuMTUsMS4xNSwwLDAsMC0uMzQuODRBMS4wOSwxLjA5LDAsMCwwLDcuMTEsOCwxLjE1LDEuMTUsMCwwLDAsOCw4LjI4LDEuMTMsMS4xMywwLDAsMCw5LjExLDcuMTIsMS4xNiwxLjE2LDAsMCwwLDcuOTQsNS45M1ptNS45LDMuOTNhMi4zNCwyLjM0LDAsMCwxLTEuNjctLjY4LDIuMywyLjMsMCwwLDEtLjY4LTEuNjcsMi4zNSwyLjM1LDAsMCwxLDQtMS42NywyLjM3LDIuMzcsMCwwLDEsMCwzLjM0LDIuMzMsMi4zMywwLDAsMS0xLjY4LjY4Wm0wLTMuMTRhLjc1Ljc1LDAsMSwwLC41NS4yMi43My43MywwLDAsMC0uNTUtLjIyWlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC40MSAtNC4zNSlcIi8+PC9nPjwvc3ZnPicsXG4gICBsaW5rOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS43NCAxNS43MlwiPjxnPjxwYXRoIGQ9XCJNMTMuMDUsMTMuNjNhLjI0LjI0LDAsMCwxLC4xNS4yMkwxMy40MiwxNmEuMTkuMTksMCwwLDEtLjA4LjE4bC0yLjEyLDIuMTRhNC4wOCw0LjA4LDAsMCwxLTEuMjkuODVBNCw0LDAsMCwxLDQuNzEsMTdhMy45MiwzLjkyLDAsMCwxLS4zLTEuNTJBNCw0LDAsMCwxLDQuNzEsMTRhMy45MSwzLjkxLDAsMCwxLC44Ny0xLjNMNy43LDEwLjU2YS4yNS4yNSwwLDAsMSwuMi0uMDZsMi4xNy4yMmEuMjEuMjEsMCwwLDEsLjE5LjE1LjI0LjI0LDAsMCwxLDAsLjI1TDcuMTIsMTQuMjNhMS44MSwxLjgxLDAsMCwwLDAsMi41OCwxLjc4LDEuNzgsMCwwLDAsMS4yOS41MiwxLjc0LDEuNzQsMCwwLDAsMS4yOC0uNTJMMTIuOCwxMy43YS4yNC4yNCwwLDAsMSwuMjUtLjA3Wk0xOSw0LjkyYTQsNCwwLDAsMSwwLDUuNjZMMTYuODYsMTIuN2EuMjUuMjUsMCwwLDEtLjE3LjA4bC0yLjItLjIzYS4yMS4yMSwwLDAsMS0uMTktLjE1LjIyLjIyLDAsMCwxLDAtLjI1TDE3LjQ0LDlhMS44MSwxLjgxLDAsMCwwLDAtMi41OCwxLjc4LDEuNzgsMCwwLDAtMS4yOS0uNTIsMS43NCwxLjc0LDAsMCwwLTEuMjguNTJMMTEuNzYsOS41N2EuMjEuMjEsMCwwLDEtLjI1LDAsLjI0LjI0LDAsMCwxLS4xNi0uMjFsLS4yMi0yLjE3YS4xOS4xOSwwLDAsMSwuMDgtLjE4bDIuMTItMi4xNGE0LjA4LDQuMDgsMCwwLDEsMS4yOS0uODUsNC4wNSw0LjA1LDAsMCwxLDMuMDYsMCwzLjg1LDMuODUsMCwwLDEsMS4zLjg1Wk01Ljg0LDkuODJhLjI1LjI1LDAsMCwxLS4xOC0uMDguMTkuMTksMCwwLDEtLjA3LS4xOWwuMTEtLjc3YS4yLjIsMCwwLDEsLjExLS4xNy4yNC4yNCwwLDAsMSwuMiwwbDIuNS43MmEuMjUuMjUsMCwwLDEsLjE1LjI3LjIyLjIyLDAsMCwxLS4yMy4yMWwtMi41OSwwWm00LjEyLTItLjczLTIuNWEuMjcuMjcsMCwwLDEsMC0uMkEuMjEuMjEsMCwwLDEsOS40MSw1TDEwLjE5LDVhLjI1LjI1LDAsMCwxLC4xOSwwLC4yMy4yMywwLDAsMSwuMDguMThsLS4wNSwyLjYxYS4yLjIsMCwwLDEtLjE5LjIzaDBBLjIyLjIyLDAsMCwxLDEwLDcuODVabTguNzYsNS41OGEuMjUuMjUsMCwwLDEsLjE4LjA4LjIzLjIzLDAsMCwxLC4wNi4ybC0uMTEuNzdhLjI1LjI1LDAsMCwxLS4xMS4xNy4yMS4yMSwwLDAsMS0uMTIsMGwtLjA4LDBMMTYsMTRhLjI1LjI1LDAsMCwxLS4xNS0uMjcuMjIuMjIsMCwwLDEsLjIyLS4yMWwxLjI5LDAsMS4zMywwWm0tNC4xMiwyLC43NCwyLjUxYS4yOC4yOCwwLDAsMSwwLC4yLjIzLjIzLDAsMCwxLS4xOC4xMWwtLjguMTFhLjIzLjIzLDAsMCwxLS4xNy0uMDcuMjUuMjUsMCwwLDEtLjA4LS4xOGwwLTIuNjFhLjIyLjIyLDAsMCwxLC4yMi0uMjIuMjEuMjEsMCwwLDEsLjI2LjE1WlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC40MSAtMy43NylcIi8+PC9nPjwvc3ZnPicsXG4gICBtYXRoOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxMS44MSAxNS43M1wiPjxnPjxwYXRoIGQ9XCJNMTcuMTksNS43M2ExLDEsMCwwLDAsLjcxLS4yOSwxLDEsMCwwLDAsLjI4LS43LDEsMSwwLDAsMC0xLTFINy4zNWExLDEsMCwwLDAtMSwxLC43Ny43NywwLDAsMCwuMTMuNDdoMGw0LjU4LDYuNDNMNi42OCwxNy44MWExLjI1LDEuMjUsMCwwLDAtLjI5LjcxLjk0Ljk0LDAsMCwwLC4yOC43LjkyLjkyLDAsMCwwLC42OS4yOEgxNy4yYTEsMSwwLDAsMCwuNzEtLjI4LDEsMSwwLDAsMCwwLTEuMzkuOTIuOTIsMCwwLDAtLjcxLS4yOUg5LjI2bDMuODctNS40M2EuODYuODYsMCwwLDAsMC0uOTVMOS4yNiw1LjczaDcuOTNaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC02LjM4IC0zLjc3KVwiLz48L2c+PC9zdmc+JyxcbiAgIHVubGluazogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNzQgMTUuNzJcIj48Zz48cGF0aCBkPVwiTTE5LDE4LjMyYTQsNCwwLDAsMCwwLTUuNjhMMTUuODUsOS41bC0xLjE3LDEuNTVMMTcuNTcsMTRhMiwyLDAsMCwxLC42MSwxLjQ3LDIuMDgsMi4wOCwwLDAsMS0yLjA5LDIuMDksMiwyLDAsMCwxLTEuNDctLjYxbC0uMzgtLjM3LTEuNzQsMSwuOC43OGE0LDQsMCwwLDAsNS42OCwwWk04LDkuNzdhMiwyLDAsMCwxLTEuMjctMSwxLjg5LDEuODksMCwwLDEtLjIxLTEuNTdBMi4xLDIuMSwwLDAsMSw3LjQ1LDYsMiwyLDAsMCwxLDksNS43NkwxMi4yNyw3LjJsLjQ5LTJMOS40OCwzLjlhNCw0LDAsMCwwLTMuMDYuNDFBMy44MiwzLjgyLDAsMCwwLDQuNTYsNi43M2EzLjgsMy44LDAsMCwwLC40LDNBMy43OCwzLjc4LDAsMCwwLDcuMzksMTEuNmw1LjM4LDIsLjQ5LTItMi42NC0uOTRMOCw5Ljc3WlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC40MSAtMy43NilcIi8+PC9nPjwvc3ZnPicsXG4gICB0YWJsZV9oZWFkZXI6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc1IDE1Ljc0XCI+PGc+PHBhdGggZD1cIk0xNywxOS41di0uNzhIMTUuNXYuNzhIMTdabS0zLDB2LS43OEgxMi41di43OEgxNFptLTMsMHYtLjc4SDkuNTN2Ljc4SDExWm0tMywwdi0uNzhINi41M3YuNzhIOFptMTAuNTUsMGExLjczLDEuNzMsMCwwLDAsLjg1LS4zNSwxLjY3LDEuNjcsMCwwLDAsLjU2LS43NmwtLjcxLS4zMWExLjIxLDEuMjEsMCwwLDEtLjM1LjQsMS4zNCwxLjM0LDAsMCwxLS41My4yM2wuMDguMzhjLjA2LjI0LjA5LjM4LjEuNDFabS0xMy43LS42My41NS0uNTVBLjc3Ljc3LDAsMCwxLDUuMjUsMThhMS4zMSwxLjMxLDAsMCwxLS4wNi0uMzh2LS4zOEg0LjQxdi4zOGEyLDIsMCwwLDAsLjEyLjY4LDEuNiwxLjYsMCwwLDAsLjM1LjU3Wm0xNS4yNy0yLjEyVjE1LjI2aC0uNzh2MS40OWguNzhabS0xNS0xVjE0LjIzSDQuNDF2MS40OWguNzhabTE1LTJWMTIuMjZoLS43OHYxLjQ5aC43OFptLTE1LTFWMTEuMjJINC40MXYxLjUxaC43OFptMTUtMlY5LjI2aC0uNzh2MS41MWguNzhabS0xNS0xVjguMTdINC40MVY5Ljc0aC43OFptMTUtMlY2LjI4aC0uNzhWNy43N2guNzhabS0xNS0xLjExVjUuMzNMNC40OCw1LjFhLjc3Ljc3LDAsMCwwLS4wNy4yNywyLjcyLDIuNzIsMCwwLDAsMCwuMjh2MWguNzlaTTE5LjIxLDVsLjYzLS40QTEuNjIsMS42MiwwLDAsMCwxOS4xNiw0YTEuOTQsMS45NCwwLDAsMC0uOTEtLjIydi43OGExLjMxLDEuMzEsMCwwLDEsLjU2LjEyLjg4Ljg4LDAsMCwxLC40LjM2Wk02LDQuNTRINy43OFYzLjc2SDZhLjgyLjgyLDAsMCwwLS4yOC4wNmwuMTIuMzVjLjA3LjIxLjEuMzMuMTEuMzZabTEwLjgsMFYzLjc2SDE1LjI4di43OGgxLjQ5Wm0tMywwVjMuNzZIMTIuMjh2Ljc4aDEuNDlabS0zLDBWMy43Nkg5LjI4di43OGgxLjUxWk02LDEwLjg0aDEyLjZWNi45MUg2WlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC40IC0zLjc2KVwiLz48L2c+PC9zdmc+JyxcbiAgIG1lcmdlX2NlbGw6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc2IDE1Ljc0XCI+PGc+PHBhdGggZD1cIk0xOC45MiwxMy41aDEuMjN2NC4xNUExLjg0LDEuODQsMCwwLDEsMTguMywxOS41SDE0VjE4LjI3SDE4LjNhLjYuNiwwLDAsMCwuNDQtLjE4LjU5LjU5LDAsMCwwLC4xOC0uNDRWMTMuNVpNMTguMywzLjc2YTEuODQsMS44NCwwLDAsMSwxLjg1LDEuODVWOS44MkgxOC45MlY1LjZhLjYuNiwwLDAsMC0uMTgtLjQ0QS41OS41OSwwLDAsMCwxOC4zLDVIMTRWMy43NkgxOC4zWm0xLjg1LDguNTFIMTUuNkwxNy4yNiwxNGwtLjg2Ljg2LTMuMTQtMy4xN0wxNi40LDguNTFsLjg2Ljg2TDE1LjYyLDExaDQuNTR2MS4yNFptLTEzLjksNmg0LjI3VjE5LjVINi4yNUExLjg0LDEuODQsMCwwLDEsNC40LDE3LjY1VjEzLjVINS42M3Y0LjE1YS42MS42MSwwLDAsMCwuNjIuNjJabTAtMTQuNTFoNC4yN1Y1SDYuMjVhLjYuNiwwLDAsMC0uNDQuMTguNTcuNTcsMCwwLDAtLjE3LjQzVjkuODFINC40MVY1LjZBMS44MywxLjgzLDAsMCwxLDYuMjUsMy43NlptNSw3LjlMOC4xNSwxNC44Myw3LjMsMTQsOSwxMi4yN0g0LjQxVjExSDguOTRMNy4zLDkuMzgsNy43Myw5bC40My0uNDNaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjQgLTMuNzYpXCIvPjwvZz48L3N2Zz4nLFxuICAgc3BsaXRfY2VsbDogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNzUgMTUuNzRcIj48Zz48cGF0aCBkPVwiTTEwLjM3LDEyLjI1SDYuNzRMOC40LDEzLjk0bC0uODcuODZMNC40MSwxMS42Myw3LjUzLDguNWwuODcuODZMNi43NCwxMWgzLjYydjEuMjNabTkuNzgtLjYxTDE3LDE0LjgxLDE2LjEzLDE0bDEuNjYtMS42OUgxNC4xNlYxMWgzLjYzTDE2LjEzLDkuMzdsLjQzLS40M0E1LjI0LDUuMjQsMCwwLDEsMTcsOC41MVpNMTguOSw4LjIyVjUuNjFhLjU3LjU3LDAsMCwwLS4xOC0uNDNBLjY1LjY1LDAsMCwwLDE4LjI5LDVIMTIuODhWMTguMjhoNS40MWEuNy43LDAsMCwwLC40NC0uMTguNTcuNTcsMCwwLDAsLjE4LS40M1YxNWgxLjIzdjIuNjRhMS44NCwxLjg0LDAsMCwxLTEuODUsMS44M2gtMTJBMS44NCwxLjg0LDAsMCwxLDQuOTQsMTlhMS44MSwxLjgxLDAsMCwxLS41NC0xLjI5VjE1SDUuNjN2Mi42NGEuNTcuNTcsMCwwLDAsLjE4LjQzLjY3LjY3LDAsMCwwLC40NC4xOGg1LjQxVjVINi4yNWEuNy43LDAsMCwwLS40NC4xOC41Ni41NiwwLDAsMC0uMTcuNDNWOC4yMkg0LjQxVjUuNjFBMS44LDEuOCwwLDAsMSw1LDQuMzFhMS45MSwxLjkxLDAsMCwxLDEuMzEtLjU1aDEyYTEuODksMS44OSwwLDAsMSwxLjMxLjU1LDEuOCwxLjgsMCwwLDEsLjU0LDEuM1Y4LjIzSDE4LjlaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjQgLTMuNzYpXCIvPjwvZz48L3N2Zz4nLFxuICAgY2FwdGlvbjogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNzQgMTMuNzlcIj48Zz48cGF0aCBkPVwiTTQuNDEsMTguNTJIMjAuMTV2LTJINC40MVpNMjAsNC43M0gxOC4wN1Y2aC42NXYuNjVIMjBWNC43M1pNMTcsNlY0LjczSDE0LjU1VjZIMTdaTTEzLjQ5LDZWNC43M0gxMVY2aDIuNDdaTTEwLDZWNC43M0g3LjVWNkgxMFpNNS43OSw2aC42NVY0LjczSDQuNVY2LjY3SDUuOFY2Wk00LjUsMTEuMzRINS43OVY4LjQ4SDQuNVpNNi40NCwxMy44SDUuNzl2LS42NUg0LjV2MS45NEg2LjQ0Wk0xNywxNS4wOVYxMy44SDE0LjU1djEuMjlIMTdabS0zLjUyLDBWMTMuOEgxMXYxLjI5aDIuNDdabS0zLjUzLDBWMTMuOEg3LjV2MS4yOUgxMFpNMjAsMTMuMTZIMTguNzJ2LjY1aC0uNjVWMTUuMUgyMFptLTEuMjktMS44MkgyMFY4LjQ4aC0xLjN2Mi44NlpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNDEgLTQuNzMpXCIvPjwvZz48L3N2Zz4nLFxuICAgZWRpdDogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNzQgMTUuNzNcIj48Zz48cGF0aCBkPVwiTTcuNTEsNS42OGg2bDEuNTItMS41N0g2Ljk0YTIuNCwyLjQsMCwwLDAtMS43OS44MkEyLjgsMi44LDAsMCwwLDQuNDEsNi44VjE3YTIuNTUsMi41NSwwLDAsMCwuNzUsMS44QTIuNDgsMi40OCwwLDAsMCw3LDE5LjVIMTcuMjJhMi41NywyLjU3LDAsMCwwLDEuODMtLjc0LDIuNTIsMi41MiwwLDAsMCwuNzctMS44VjguODNsLTEuNTgsMS41NHY2YTEuNTQsMS41NCwwLDAsMS0xLjUzLDEuNTNINy41MUExLjU0LDEuNTQsMCwwLDEsNiwxNi40MVY3LjIxQTEuNTIsMS41MiwwLDAsMSw3LjUxLDUuNjhabTUuNjMsNy40N2gwTDEwLjcsMTAuNzRsLTEsMy4zOCwxLjcxLS40OCwxLjctLjQ5Wm0uMzQtLjM0aDBsNS4zNi01LjMyTDE2LjQsNS4wOCwxMSwxMC40bDEuMjMsMS4yMSwxLjIxLDEuMlpNMTkuOTMsNi40YS44Mi44MiwwLDAsMCwuMjItLjQ4QS41NC41NCwwLDAsMCwyMCw1LjQ3TDE4LjQ1LDRBLjY3LjY3LDAsMCwwLDE4LDMuNzdhLjcuNywwLDAsMC0uNDguMjFsLS43NC43MiwyLjQ0LDIuNDMuMzctLjM3LjM1LS4zNlpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNDEgLTMuNzcpXCIvPjwvZz48L3N2Zz4nLFxuICAgZGVsZXRlOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS43MyAxNS43NFwiPjxnPjxwYXRoIGQ9XCJNMTkuMTYsNi43MWEuOTQuOTQsMCwwLDAsLjY5LS4yOC45MS45MSwwLDAsMCwuMjktLjY4QTEsMSwwLDAsMCwxOS44NSw1YS45My45MywwLDAsMC0uNjktLjNIMTQuMjRBLjk0Ljk0LDAsMCwwLDE0LDQuMDZhLjkyLjkyLDAsMCwwLS43LS4zaC0yYTEsMSwwLDAsMC0uNy4zLjkzLjkzLDAsMCwwLS4yOC42OEg1LjM5QS45Mi45MiwwLDAsMCw0LjcsNWExLDEsMCwwLDAtLjI5LjcxLjkxLjkxLDAsMCwwLC4yOS42OCwxLDEsMCwwLDAsLjY5LjI4SDE5LjE2Wm0tMTIuNzksMWExLDEsMCwwLDAtLjcuMy45NC45NCwwLDAsMC0uMjguNjl2OC44NUExLjg4LDEuODgsMCwwLDAsNiwxOC45M2ExLjksMS45LDAsMCwwLDEuMzkuNTdIMTcuMmExLjg3LDEuODcsMCwwLDAsMS4zOS0uNTgsMS45MSwxLjkxLDAsMCwwLC41OC0xLjM5VjguNjhBMSwxLDAsMCwwLDE4Ljg4LDhhLjg5Ljg5LDAsMCwwLS43LS4yOSwxLDEsMCwwLDAtLjY5LjI5LjkyLjkyLDAsMCwwLS4yOS42OHY3Ljg3YTEsMSwwLDAsMS0xLDFIOC4zNGEuOTQuOTQsMCwwLDEtLjY5LS4yOCwxLDEsMCwwLDEtLjI5LS43MVY4LjY4YTEsMSwwLDAsMC0xLTFaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC00LjQxIC0zLjc2KVwiLz48L2c+PC9zdmc+JyxcbiAgIG1vZGlmeTogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNyAxNS43NFwiPjxnPjxwYXRoIGQ9XCJNMTkuNzksMTUuMjNhLjY2LjY2LDAsMCwxLC4zLjM4LjU5LjU5LDAsMCwxLS4wNy40OGwtLjgsMS4zOGEuNjYuNjYsMCwwLDEtLjM4LjMuNTkuNTksMCwwLDEtLjQ4LS4wN2wtLjY4LS4zOGE0LjU1LDQuNTUsMCwwLDEtMS4zNC43N3YuNzhhLjY0LjY0LDAsMCwxLS4xOC40NS42MS42MSwwLDAsMS0uNDUuMThoLTEuNmEuNi42LDAsMCwxLS40NC0uMTguNjYuNjYsMCwwLDEtLjE5LS40NXYtLjc4YTQuMzYsNC4zNiwwLDAsMS0xLjMyLS43N2wtLjY5LjM4YS41OC41OCwwLDAsMS0uNDguMDcuNjYuNjYsMCwwLDEtLjM4LS4zbC0uMzgtLjY2aC44M2ExLjc3LDEuNzcsMCwwLDAsMS4yMy0uNTIsMS43MiwxLjcyLDAsMCwwLC41MS0xLjIzdi0uMThhMywzLDAsMCwwLC40OS0uMjhsLjE1LjA5YTEuODMsMS44MywwLDAsMCwuODguMjNBMS43NSwxLjc1LDAsMCwwLDE1Ljg0LDE0bC44OC0xLjUyYTEuNywxLjcsMCwwLDAsLjE3LTEuMzIsMS42NiwxLjY2LDAsMCwwLS4zLS42MSwxLjg0LDEuODQsMCwwLDAtLjUxLS40NWwtLjE1LS4wOSwwLS4yOSwwLS4yOC4xNS0uMDlhMSwxLDAsMCwwLC4yNi0uMThsMCwuMDZ2Ljc4YTQuMzQsNC4zNCwwLDAsMSwxLjM0Ljc3bC42OC0uMzhhLjY4LjY4LDAsMCwxLC40OC0uMDYuNjQuNjQsMCwwLDEsLjM4LjI5bC44LDEuMzhhLjU4LjU4LDAsMCwxLC4wNy40OC42My42MywwLDAsMS0uMy4zOGwtLjY4LjRhMy44NCwzLjg0LDAsMCwxLC4wOC43Niw0LjEzLDQuMTMsMCwwLDEtLjA4Ljc4bC4zNC4xOC4zMi4yWk0xMC4xNyw3Ljg2YTEuOSwxLjksMCwwLDEsMS4zNSwzLjIzLDEuODUsMS44NSwwLDAsMS0xLjM1LjU1QTEuOSwxLjksMCwwLDEsOC44Myw4LjQxYTEuOTIsMS45MiwwLDAsMSwxLjM0LS41NVptMS41OCw3LjJhLjczLjczLDAsMCwxLS4yMS40OS42Ni42NiwwLDAsMS0uNDguMkg5LjI5YS42OC42OCwwLDAsMS0uNjktLjY5VjE0LjJhNC43NSw0Ljc1LDAsMCwxLTEuNDgtLjg2bC0uNzUuNDVhLjczLjczLDAsMCwxLS43LDAsLjYzLjYzLDAsMCwxLS4yNS0uMjZMNC41NCwxMmEuNjcuNjcsMCwwLDEtLjA4LS41My43MS43MSwwLDAsMSwuMzItLjQybC43NS0uNDNhNC44LDQuOCwwLDAsMS0uMDgtLjg1LDQuNzEsNC43MSwwLDAsMSwuMDgtLjg1bC0uNzQtLjQ0YS43MS43MSwwLDAsMS0uMzItLjQyLjY1LjY1LDAsMCwxLC4wNy0uNTRMNS40Miw2YS42Ni42NiwwLDAsMSwuNDItLjMybC4xOCwwYS43My43MywwLDAsMSwuMzUuMDlsLjc1LjQzQTQuNjgsNC42OCwwLDAsMSw4LjYsNS4zM1Y0LjQ1YS42OC42OCwwLDAsMSwuNjktLjY5aDEuNzdhLjY0LjY0LDAsMCwxLC40OC4yLjczLjczLDAsMCwxLC4yMS40OXYuODhhNC43NSw0Ljc1LDAsMCwxLDEuNDguODVMMTQsNS43NWEuNjcuNjcsMCwwLDEsLjM0LS4wOWwuMTgsMGEuNzEuNzEsMCwwLDEsLjQyLjMybC44OSwxLjU0YS42Ny42NywwLDAsMSwuMDYuNTIuNzMuNzMsMCwwLDEtLjMyLjQzbC0uNzUuNDJhNC44LDQuOCwwLDAsMSwuMDguODUsNC43MSw0LjcxLDAsMCwxLS4wOC44NWwuNzUuNDNhLjY2LjY2LDAsMCwxLC4zMi40Mi43My43MywwLDAsMS0uMDYuNTRsLS44OSwxLjUyYS42OS42OSwwLDAsMS0uMjUuMjYuNy43LDAsMCwxLS4zNS4wOS42NC42NCwwLDAsMS0uMzQtLjA5bC0uNzUtLjQ1YTQuODcsNC44NywwLDAsMS0xLjQ4Ljg2di44N1pNNy4yMyw5Ljc1YTMsMywwLDAsMCwuODYsMi4wOCwyLjk0LDIuOTQsMCwxLDAsNC4xNi00LjE2LDMsMywwLDAsMC0yLjA4LS44NUEyLjk0LDIuOTQsMCwwLDAsNy4yMyw5Ljc1WlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC40NCAtMy43NilcIi8+PC9nPjwvc3ZnPicsXG4gICByZXZlcnQ6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc2IDE0LjY5XCI+PGc+PHBhdGggZD1cIk0xOC4yNiwxNVYxMi4zbDEuODktMlYxNWEyLjU4LDIuNTgsMCwwLDEtLjI0LDFjLS4yLjU4LS43NS45Mi0xLjY1LDFINy41NnYyTDQuNDEsMTUuNjMsNy41NiwxM3YyaDEwLjdaTTYuMyw4LjI4VjExTDQuNDEsMTNWOC4yOGEyLjU4LDIuNTgsMCwwLDEsLjI0LTFjLjItLjU4Ljc1LS45MiwxLjY1LTFIMTd2LTJsMy4xNSwzLjM0TDE3LDEwLjN2LTJINi4zWlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC40IC00LjI4KVwiLz48L2c+PC9zdmc+JyxcbiAgIGF1dG9fc2l6ZTogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNzQgMTUuNzRcIj48Zz48cGF0aCBkPVwiTTYuNzEsMTcuMTksNi44OSwxNmwxLjIxLS4xNUE2LDYsMCwwLDEsNi44MSwxMy45YTUuNzgsNS43OCwwLDAsMS0uNDUtMi4yN0E2LDYsMCwwLDEsOC4xLDcuNDVhNS44Myw1LjgzLDAsMCwxLDQuMTctMS43M2wxLTEtMS0xQTcuODksNy44OSwwLDAsMCw1LDE0LjY0YTcuNzMsNy43MywwLDAsMCwxLjcxLDIuNTVabTUuNTcsMi4zMWgwQTcuODYsNy44NiwwLDAsMCwxNy44NSw2LjA3TDE3LjY3LDcuM2wtMS4yMS4xNWE1LjksNS45LDAsMCwxLDEuMjksMS45Miw1LjgxLDUuODEsMCwwLDEsLjQ1LDIuMjYsNS45MSw1LjkxLDAsMCwxLTUuOSw1LjlsLTEsMSwuNDkuNDkuNDcuNVpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNDEgLTMuNzYpXCIvPjwvZz48L3N2Zz4nLFxuICAgaW5zZXJ0X3Jvd19iZWxvdzogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuOCAxNS44XCI+PGc+PHBhdGggZD1cIk0xNS43LDEuM2MtMC4xLTAuMS0wLjEtMC4yLTAuMi0wLjJMMTUuMywxSDAuNEwwLjMsMS4xYzAsMC0wLjEsMC4xLTAuMSwwLjFjMCwwLTAuMSwwLjEtMC4xLDAuMUwwLDEuNHY3LjdsMC4xLDAuMWMwLDAuMSwwLjEsMC4xLDAuMiwwLjJsMC4xLDAuMWgyLjNWOS4zbDAuMS0wLjVMMyw4LjVsMC4xLTAuMmMtMC4xLDAtMC4yLDAtMC4zLDBIMS4ydi02aDEzLjN2NmgtMS42Yy0wLjEsMC0wLjIsMC0wLjMsMGwwLjEsMC4ybDAuMiwwLjRDMTIuOSw5LDEzLDkuMiwxMyw5LjN2MC4xaDIuM2wwLjItMC4xYzAuMSwwLDAuMS0wLjEsMC4yLTAuMmwwLjEtMC4xVjEuNEwxNS43LDEuM3pcIi8+PHBhdGggZD1cIk0xMC41LDcuNUM5LjksNy4xLDkuMyw2LjgsOC42LDYuN2MtMC4yLDAtMC41LTAuMS0wLjcsMGMtMC4yLDAtMC41LDAtMC43LDBDNi42LDYuNyw2LjEsNi45LDUuNiw3LjNDNS4yLDcuNiw0LjcsOCw0LjQsOC40QzQuMyw4LjYsNC4yLDguOCw0LjIsOC45QzQuMSw5LjEsNCw5LjMsMy45LDkuNEMzLjksOS42LDMuOCw5LjcsMy44LDkuOWMwLDAuMi0wLjEsMC4zLTAuMSwwLjV2LTAuMWMtMC4xLDAuOCwwLjEsMS42LDAuNSwyLjRjMC40LDAuNywxLDEuMywxLjcsMS43YzAuMywwLjIsMC42LDAuMywwLjksMC4zYzAuMywwLjEsMC43LDAuMSwxLDAuMWMwLjMsMCwwLjcsMCwxLTAuMWMwLjMtMC4xLDAuNi0wLjIsMC45LTAuM2MwLjUtMC4zLDAuOS0wLjYsMS4zLTFjMC4zLTAuNCwwLjYtMC44LDAuOC0xLjNjMC4xLTAuNCwwLjItMC45LDAuMi0xLjRjMC0wLjUtMC4xLTEtMC4zLTEuNEMxMS41LDguNiwxMS4xLDgsMTAuNSw3LjV6IE0xMC4xLDExLjNIOC41djEuNkg4SDcuOUg3LjN2MHYtMC4xdi0xLjRINS43di0wLjR2LTAuMnYtMC42aDBoMS41VjguNWgxLjJ2MS42aDEuNlYxMS4zelwiLz48L2c+PC9zdmc+JyxcbiAgIGluc2VydF9yb3dfYWJvdmU6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1LjggMTUuOFwiPjxnPjxwYXRoIGQ9XCJNMC4xLDE0LjVjMC4xLDAuMSwwLjEsMC4yLDAuMiwwLjJsMC4xLDAuMWgxNC45bDAuMS0wLjFjMCwwLDAuMS0wLjEsMC4xLTAuMWMwLDAsMC4xLTAuMSwwLjEtMC4xbDAuMS0wLjFWNi43bC0wLjEtMC4xYzAtMC4xLTAuMS0wLjEtMC4yLTAuMmwtMC4xLTAuMWgtMi4zdjAuMWwtMC4xLDAuNWwtMC4yLDAuNGwtMC4xLDAuMmMwLjEsMCwwLjIsMCwwLjMsMGgxLjZ2NkgxLjN2LTZoMS42YzAuMSwwLDAuMiwwLDAuMywwTDMuMSw3LjNMMi45LDYuOUMyLjgsNi44LDIuOCw2LjYsMi43LDYuNVY2LjNIMC40TDAuMyw2LjRjLTAuMSwwLTAuMSwwLjEtMC4yLDAuMkwwLDYuN3Y3LjdMMC4xLDE0LjV6XCIvPjxwYXRoIGQ9XCJNNS4zLDguM2MwLjYsMC41LDEuMiwwLjgsMS45LDAuOWMwLjIsMCwwLjUsMC4xLDAuNywwYzAuMiwwLDAuNSwwLDAuNywwYzAuNi0wLjEsMS4xLTAuMywxLjYtMC42YzAuNS0wLjMsMC45LTAuNywxLjItMS4yYzAuMS0wLjIsMC4yLTAuMywwLjMtMC41YzAuMS0wLjIsMC4yLTAuNCwwLjItMC41YzAuMS0wLjEsMC4xLTAuMywwLjEtMC40QzEyLDUuOCwxMiw1LjYsMTIsNS40djAuMWMwLjEtMC44LTAuMS0xLjYtMC41LTIuNGMtMC40LTAuNy0xLTEuMy0xLjctMS43QzkuNSwxLjMsOS4yLDEuMiw4LjksMS4xQzguNSwxLDguMiwxLDcuOSwxYy0wLjMsMC0wLjcsMC0xLDAuMUM2LjYsMS4yLDYuMywxLjMsNiwxLjRDNS41LDEuNyw1LjEsMiw0LjcsMi40QzQuNCwyLjgsNC4xLDMuMywzLjksMy44QzMuOCw0LjIsMy43LDQuNywzLjcsNS4yYzAsMC41LDAuMSwxLDAuMywxLjRDNC4zLDcuMiw0LjcsNy44LDUuMyw4LjN6IE01LjcsNC41aDEuNlYyLjloMC41aDAuMWgwLjZ2MHYwLjF2MS40SDEwdjAuNHYwLjJ2MC42aDBIOC41djEuNkg3LjNWNS43SDUuN1Y0LjV6XCIvPjwvZz48L3N2Zz4nLFxuICAgaW5zZXJ0X2NvbHVtbl9sZWZ0OiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS44IDE1LjhcIj48Zz48cGF0aCBkPVwiTTE0LjUsMTUuN2MwLjEtMC4xLDAuMi0wLjEsMC4yLTAuMmwwLjEtMC4xVjAuNGwtMC4xLTAuMWMwLDAtMC4xLTAuMS0wLjEtMC4xYzAsMC0wLjEtMC4xLTAuMS0wLjFMMTQuNCwwSDYuN0w2LjYsMC4xYy0wLjEsMC0wLjEsMC4xLTAuMiwwLjJMNi4zLDAuNHYyLjNoMC4xbDAuNSwwLjFMNy4zLDNsMC4yLDAuMWMwLTAuMSwwLTAuMiwwLTAuM1YxLjJoNnYxMy4zaC02di0xLjZjMC0wLjEsMC0wLjIsMC0wLjNsLTAuMiwwLjFsLTAuNCwwLjJDNi43LDEyLjksNi42LDEzLDYuNCwxM0g2LjN2Mi4zbDAuMSwwLjJjMCwwLjEsMC4xLDAuMSwwLjIsMC4ybDAuMSwwLjFoNy43TDE0LjUsMTUuN3pcIi8+PHBhdGggZD1cIk04LjMsMTAuNUM4LjcsMTAsOSw5LjMsOS4xLDguNmMwLTAuMiwwLjEtMC41LDAtMC43YzAtMC4yLDAtMC41LDAtMC43QzksNi43LDguOCw2LjEsOC41LDUuN0M4LjIsNS4yLDcuOCw0LjgsNy4zLDQuNUM3LjIsNC40LDcsNC4zLDYuOSw0LjJDNi43LDQuMSw2LjUsNCw2LjQsNEM2LjIsMy45LDYuMSwzLjksNS45LDMuOGMtMC4yLDAtMC4zLTAuMS0wLjUtMC4xaDAuMUM0LjcsMy43LDMuOCwzLjksMy4xLDQuM0MyLjQsNC43LDEuOCw1LjMsMS40LDZDMS4zLDYuMywxLjIsNi42LDEuMSw2LjlDMSw3LjIsMSw3LjYsMSw3LjljMCwwLjMsMCwwLjcsMC4xLDFjMC4xLDAuMywwLjIsMC42LDAuMywwLjljMC4zLDAuNSwwLjYsMC45LDEsMS4zYzAuNCwwLjMsMC44LDAuNiwxLjMsMC44QzQuMiwxMiw0LjcsMTIuMSw1LjEsMTJjMC41LDAsMS0wLjEsMS40LTAuM0M3LjIsMTEuNSw3LjgsMTEuMSw4LjMsMTAuNXpNNC41LDEwLjFWOC41SDIuOVY4VjcuOVY3LjNoMEgzaDEuNFY1LjdoMC40aDAuMmgwLjZ2MHYxLjVoMS42djEuMkg1Ljd2MS42SDQuNXpcIi8+PC9nPjwvc3ZnPicsXG4gICBpbnNlcnRfY29sdW1uX3JpZ2h0OiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS44IDE1LjhcIj48Zz48cGF0aCBkPVwiTTEuMywwLjFDMS4yLDAuMiwxLjEsMC4yLDEuMSwwLjNMMSwwLjR2MTQuOWwwLjEsMC4xYzAsMCwwLjEsMC4xLDAuMSwwLjFjMCwwLDAuMSwwLjEsMC4xLDAuMWwwLjEsMC4xaDcuN2wwLjEtMC4xYzAuMSwwLDAuMS0wLjEsMC4yLTAuMmwwLjEtMC4xdi0yLjNIOS4zbC0wLjUtMC4xbC0wLjQtMC4ybC0wLjItMC4xYzAsMC4xLDAsMC4yLDAsMC4zdjEuNmgtNlYxLjNoNnYxLjZjMCwwLjEsMCwwLjIsMCwwLjNsMC4yLTAuMWwwLjQtMC4yQzksMi45LDkuMiwyLjgsOS4zLDIuOGgwLjFWMC41TDkuNCwwLjNjMC0wLjEtMC4xLTAuMS0wLjItMC4yTDkuMSwwSDEuNEwxLjMsMC4xelwiLz48cGF0aCBkPVwiTTcuNSw1LjNDNyw1LjgsNi43LDYuNSw2LjYsNy4yYzAsMC4yLTAuMSwwLjUsMCwwLjdjMCwwLjIsMCwwLjUsMCwwLjdjMC4xLDAuNiwwLjMsMS4xLDAuNiwxLjZjMC4zLDAuNSwwLjcsMC45LDEuMiwxLjJjMC4yLDAuMSwwLjMsMC4yLDAuNSwwLjNjMC4yLDAuMSwwLjQsMC4yLDAuNSwwLjJjMC4xLDAuMSwwLjMsMC4xLDAuNCwwLjFjMC4yLDAsMC4zLDAuMSwwLjUsMC4xaC0wLjFjMC44LDAuMSwxLjYtMC4xLDIuNC0wLjVjMC43LTAuNCwxLjMtMSwxLjctMS43YzAuMi0wLjMsMC4zLTAuNiwwLjMtMC45YzAuMS0wLjMsMC4xLTAuNywwLjEtMWMwLTAuMywwLTAuNy0wLjEtMWMtMC4xLTAuMy0wLjItMC42LTAuMy0wLjljLTAuMy0wLjUtMC42LTAuOS0xLTEuM0MxMyw0LjQsMTIuNSw0LjIsMTIsNGMtMC40LTAuMS0wLjktMC4yLTEuNC0wLjJjLTAuNSwwLTEsMC4xLTEuNCwwLjJDOC41LDQuMyw3LjksNC43LDcuNSw1LjN6IE0xMS4zLDUuN3YxLjZoMS42djAuNXYwLjF2MC42aDBoLTAuMWgtMS40djEuNmgtMC40aC0wLjJoLTAuNnYwVjguNUg4LjVWNy4zaDEuNlY1LjdIMTEuM3pcIi8+PC9nPjwvc3ZnPicsXG4gICBkZWxldGVfcm93OiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS43NSAxMy44M1wiPjxnPjxwYXRoIGQ9XCJNNC43LDE4LjQ2bC4xMi4wOEgxOS43M2wuMTItLjA4YS41OC41OCwwLDAsMCwuMjItLjIybC4wOC0uMTIsMC03LjY5LS4wOC0uMTFhLjc3Ljc3LDAsMCwwLS4xOC0uMThsLS4xMS0uMDgtMi4zMSwwLS4wOC4yOC0uMS4yOWExLjU4LDEuNTgsMCwwLDEtLjEyLjI5bC0uMTQuMzRzMCwwLC4xOCwwSDE4Ljl2Nkg1LjY0di02SDcuMzVjLjE0LDAsLjIsMCwuMTgsMGwtLjE0LS4zNGEyLjg1LDIuODUsMCwwLDEtLjEyLS4yOWwtLjEtLjI5LS4wNy0uMjctMi4zMSwwLS4xMS4wOGEuNzcuNzcsMCwwLDAtLjE4LjE4bC0uMDguMTEsMCw3LjY5LjA4LjEyYS40Ny40NywwLDAsMCwuMDkuMTJsLjEzLjA5Wk0xMi4xMSwxM2E0LDQsMCwwLDAsMS40Ni0uMjEsNC41MSw0LjUxLDAsMCwwLDEuMzEtLjcxQTQsNCwwLDAsMCwxNi4yNiwxMGE0LjMyLDQuMzIsMCwwLDAtLjA4LTIuNTQsNC4zNCw0LjM0LDAsMCwwLTEtMS41Miw0LjE1LDQuMTUsMCwwLDAtMS41NC0xLDQuMzQsNC4zNCwwLDAsMC0xLjM1LS4yMkE0LjA3LDQuMDcsMCwwLDAsMTEsNC45MywzLjk0LDMuOTQsMCwwLDAsOS4yNCw2LjA3LDMuOTIsMy45MiwwLDAsMCw4LjE1LDguODhhMy45MSwzLjkxLDAsMCwwLC4xMi45NUE0LjE2LDQuMTYsMCwwLDAsMTIuMTEsMTNabTIuMzUtNC4xNHYuNThIMTAuMDlWOC4yN2g0LjM3di41OFpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNCAtNC43MSlcIi8+PC9nPjwvc3ZnPicsXG4gICBkZWxldGVfY29sdW1uOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxMy44MSAxNS43NFwiPjxnPjxwYXRoIGQ9XCJNNS42NiwxOS40MmwuMTIuMDgsNy42OSwwLC4xMS0uMDhhLjc3Ljc3LDAsMCwwLC4xOC0uMThsLjA4LS4xMSwwLTIuMzItLjE1LDAtLjQ1LS4xNS0uNDItLjE4LS4xNy0uMDdhMSwxLDAsMCwwLDAsLjI3djEuNjNoLTZWNWg2VjYuNjJhLjkuOSwwLDAsMCwwLC4yNmwuMTctLjA3LjQyLS4xN2EzLjkxLDMuOTEsMCwwLDEsLjQ1LS4xNWwuMTUsMCwwLTIuMzJMMTMuNzUsNGEuNzcuNzcsMCwwLDAtLjE4LS4xOGwtLjExLS4wOEg1Ljc5bC0uMTMuMDdhLjYzLjYzLDAsMCwwLS4yMS4yMmwtLjA4LjEyVjE5LjA4bC4wOC4xMmEuNDcuNDcsMCwwLDAsLjA5LjEyLjM1LjM1LDAsMCwwLC4xMi4xWm05LTMuNjdhNC4xNiw0LjE2LDAsMCwwLDIuMzYtLjUxLDQuMDgsNC4wOCwwLDAsMCwxLjY3LTEuNzIsNCw0LDAsMCwwLC4zNS0uOTEsMy43OSwzLjc5LDAsMCwwLC4xLTEsNC43MSw0LjcxLDAsMCwwLS4xMS0xLDUsNSwwLDAsMC0uMy0uODcsNC4yNSw0LjI1LDAsMCwwLTEtMS4yNSw0LjQ5LDQuNDksMCwwLDAtMS4zNC0uODFBNC4yNiw0LjI2LDAsMCwwLDE1LDcuNDhhMy44OCwzLjg4LDAsMCwwLTEuNDEuMjVBNC4zMiw0LjMyLDAsMCwwLDExLjg2LDksNCw0LDAsMCwwLDExLDEwLjk0YTQuNCw0LjQsMCwwLDAtLjA1LjY4LDQuNSw0LjUsMCwwLDAsLjA1LjY4LDMuOTMsMy45MywwLDAsMCwuNjEsMS41Nyw0LjIyLDQuMjIsMCwwLDAsMS4xOCwxLjIsNC41OSw0LjU5LDAsMCwwLC40OC4yN2MuMi4xLjM3LjE3LjUuMjJhMi40NCwyLjQ0LDAsMCwwLC40NS4xMiw0LjYxLDQuNjEsMCwwLDAsLjUuMDdabTIuNTQtNC4xMnYuNThIMTIuODdWMTFoNC4zN3YuNTlaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC01LjM3IC0zLjc2KVwiLz48L2c+PC9zdmc+JyxcbiAgIGZpeGVkX2NvbHVtbl93aWR0aDogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIj48cGF0aCBkPVwiTTYsNUgxOEExLDEgMCAwLDEgMTksNkExLDEgMCAwLDEgMTgsN0g2QTEsMSAwIDAsMSA1LDZBMSwxIDAgMCwxIDYsNU0yMSwyVjRIM1YySDIxTTE1LDhIMTdWMjJIMTVWOE03LDhIOVYyMkg3VjhNMTEsOEgxM1YyMkgxMVY4WlwiIC8+PC9zdmc+JyxcbiAgIHJvdGF0ZV9sZWZ0OiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS44IDE1LjhcIj48Zz48cGF0aCBkPVwiTTAuNSwxMC4yYzAsMC4xLDAsMC4yLDAsMC4zdjAuMmwwLDBjMC4xLDAuMywwLjMsMC42LDAuNCwwLjlsMCwwQzEsMTEuOCwxLjMsMTIsMS41LDExLjloMC4xaDAuMmgwLjFjMC4xLTAuMSwwLjMtMC4zLDAuNC0wLjV2LTAuMmMwLTAuMSwwLTAuMi0wLjEtMC4zbDAsMGMtMC4yLTAuMi0wLjMtMC40LTAuMy0wLjdsMCwwQzEuOCwxMCwxLjcsOS45LDEuNSw5LjhjLTAuMSwwLTAuMiwwLTAuMywwSDAuOUMwLjcsOS45LDAuNiwxMCwwLjUsMTAuMkwwLjUsMTAuMnpcIi8+PHBhdGggZD1cIk0yLjIsMTEuNUwyLjIsMTEuNUwyLjIsMTEuNXpcIi8+PHBhdGggZD1cIk01LjksMy42TDUuOSwzLjZMNS45LDMuNnpcIi8+PHBhdGggZD1cIk0wLjEsNy45YzAsMC4zLDAsMC42LDAsMC45bDAsMGwwLDBsMCwwbDAsMGMwLDAuMiwwLjEsMC4zLDAuMiwwLjRsMCwwYzAuMiwwLjEsMC4zLDAuMiwwLjUsMC4ybDAsMGwwLDBjMC4yLDAsMC40LTAuMSwwLjUtMC4zbDAsMGMwLTAuMSwwLjEtMC4zLDAuMS0wLjRWOC42bDAsMGMwLTAuMiwwLTAuNSwwLTAuN2wwLDBjMC0wLjItMC4xLTAuNC0wLjItMC41QzEuMSw3LjMsMC45LDcuMiwwLjcsNy4yUzAuMyw3LjMsMC4yLDcuNEMwLjEsNy41LDAsNy43LDAuMSw3Ljl6XCIvPjxwYXRoIGQ9XCJNMS45LDEyLjdMMS45LDEyLjdjMCwwLjIsMCwwLjQsMC4yLDAuNWwwLDBsMC4yLDAuM2wwLDBjMC4yLDAuMSwwLjMsMC4yLDAuNSwwLjRsMCwwbDAsMGwwLDBsMCwwQzIuOSwxNCwzLDE0LjEsMy4yLDE0LjFzMC40LTAuMSwwLjUtMC4yYzAuMS0wLjIsMC4yLTAuMywwLjItMC41di0wLjFjMC0wLjItMC4xLTAuNC0wLjItMC41bDAsMGwtMC40LTAuNGwtMC4yLTAuMmwwLDBDMywxMi4xLDIuOCwxMiwyLjYsMTJsMCwwYy0wLjIsMC0wLjQsMC4xLTAuNSwwLjJsMCwwQzIsMTIuMywxLjksMTIuNSwxLjksMTIuN3pcIi8+PHBhdGggZD1cIk02LjYsMTVjMCwwLjIsMC4xLDAuNCwwLjIsMC41YzAuMSwwLjEsMC4yLDAuMiwwLjQsMC4zbDAsMGMwLjMsMCwwLjUsMCwwLjcsMGgwLjNsMCwwYzAuMiwwLDAuNC0wLjEsMC41LTAuMmMwLjEtMC4yLDAuMi0wLjMsMC4yLTAuNWwwLDBsMCwwYzAtMC4yLTAuMS0wLjQtMC4yLTAuNWwwLDBjLTAuMS0wLjEtMC4zLTAuMi0wLjUtMC4ybDAsMEg3LjljLTAuMSwwLTAuMywwLTAuNSwwbDAsMEg3LjNjLTAuMi0wLjEtMC4zLDAtMC41LDAuMWwwLDBDNi43LDE0LjYsNi42LDE0LjgsNi42LDE1TDYuNiwxNUw2LjYsMTVMNi42LDE1elwiLz48cGF0aCBkPVwiTTQuMiw3LjRDNCw3LjUsNCw3LjcsNCw3LjljMCwwLjIsMCwwLjQsMC4yLDAuNWwwLDBsMy4yLDMuMmwwLDBjMC4xLDAuMSwwLjMsMC4yLDAuNSwwLjJzMC4zLTAuMSwwLjUtMC4ybDAsMGwzLjItMy4ybDAsMGMwLjEtMC4xLDAuMi0wLjMsMC4yLTAuNWMwLTAuMi0wLjEtMC40LTAuMi0wLjVsMCwwQzExLjUsNy4zLDExLDYuNywxMCw1LjhsMCwwTDguNCw0LjJsMCwwQzguMyw0LjEsOC4xLDQsNy45LDRTNy41LDQuMSw3LjQsNC4yTDQuMiw3LjRMNC4yLDcuNHogTTYuOCw5TDUuNyw3LjlsMi4yLTIuMmwyLjMsMi4ybC0yLjMsMi4yQzcuNyw5LjksNy4zLDkuNSw2LjgsOUw2LjgsOXpcIi8+PHBhdGggZD1cIk00LjEsMTQuMUM0LDE0LjIsNCwxNC4zLDQsMTQuNHYwLjJsMCwwYzAuMSwwLjEsMC4yLDAuMywwLjQsMC40bDAsMGMwLjMsMC4xLDAuNiwwLjIsMC45LDAuNGgwLjFoMC4xbDAsMGMwLjIsMCwwLjMtMC4xLDAuNS0wLjFsMCwwYzAuMi0wLjEsMC4zLTAuMywwLjMtMC40bDAsMGwwLDBsMCwwbDAsMHYtMC4yYzAtMC4xLTAuMS0wLjItMC4xLTAuM2wwLDBDNi4xLDE0LjIsNiwxNC4xLDUuOCwxNGwwLDBjLTAuMy0wLjEtMC41LTAuMi0wLjgtMC4ybDAsMGMtMC4xLTAuMS0wLjItMC4xLTAuMy0wLjFINC41QzQuMywxMy43LDQuMiwxMy45LDQuMSwxNC4xelwiLz48cGF0aCBkPVwiTTkuMywxNC40YzAsMC4xLTAuMSwwLjMsMCwwLjRWMTVsMCwwYzAsMC4xLDAuMSwwLjMsMC41LDAuNGMwLjEsMC4xLDAuMywwLjEsMC40LDAuMWwwLDBoMC4xbDAsMGMwLjMtMC4xLDAuNi0wLjIsMC45LTAuM2wwLDBjMC4xLTAuMSwwLjItMC4yLDAuMy0wLjRsMC4xLTAuM2MwLTAuMS0wLjEtMC4yLTAuMS0wLjNsMCwwYy0wLjEtMC4yLTAuMi0wLjMtMC40LTAuNGwwLDBoLTAuM2MtMC4xLDAtMC4yLDAtMC4zLDBsMCwwYy0wLjIsMC4xLTAuNSwwLjItMC44LDAuM2wwLDBDOS41LDE0LjEsOS40LDE0LjIsOS4zLDE0LjRMOS4zLDE0LjR6XCIvPjxwYXRoIGQ9XCJNMTEuNCwxNC43TDExLjQsMTQuN0wxMS40LDE0Ljd6XCIvPjxwYXRoIGQ9XCJNOS41LDE1LjNMOS41LDE1LjNMOS41LDE1LjN6XCIvPjxwYXRoIGQ9XCJNMTUuOSw3LjljMC0xLTAuMi0yLTAuNi0zbDAsMGMtMC40LTEtMS0xLjktMS43LTIuNkMxMi44LDEuNiwxMiwxLDExLDAuNmwwLDBDMTAuMSwwLjIsOSwwLDgsMEM3LjMsMCw2LjUsMC4xLDUuOCwwLjNsMCwwQzUuMiwwLjUsNC42LDAuOCw0LDEuMUwzLjEsMC4ybDAsMEMyLjksMC4xLDIuOCwwLDIuNiwwSDIuNGwwLDBDMi4yLDAsMiwwLjIsMS45LDAuNGwwLDBMMC4xLDQuOWwwLDBDMCw1LDAsNS4xLDAsNS4yYzAsMC4yLDAuMSwwLjQsMC4yLDAuNWwwLDBjMC4yLDAuMSwwLjMsMC4yLDAuNSwwLjJoMC4xSDFsMCwwbDQuNy0xLjhsMCwwQzUuOSw0LDYuMSwzLjgsNi4xLDMuNlYzLjRDNi4xLDMuMiw2LDMsNS45LDIuOWwwLDBMNS4xLDIuMWMwLjQtMC4yLDAuOC0wLjQsMS4zLTAuNWMwLjUtMC4xLDEuMS0wLjIsMS43LTAuMmMwLjksMCwxLjcsMC4yLDIuNSwwLjVsMCwwYzAuOCwwLjMsMS41LDAuOCwyLjEsMS40YzAuNiwwLjYsMS4xLDEuMywxLjQsMi4xbDAsMGMwLjMsMC44LDAuNSwxLjYsMC41LDIuNXMtMC4yLDEuNy0wLjUsMi41bDAsMGMtMC4zLDAuOC0wLjgsMS41LTEuNCwyLjFjLTAuMiwwLjItMC40LDAuMy0wLjYsMC41bDAsMGMtMC4yLDAuMS0wLjMsMC4zLTAuMywwLjV2MC4xYzAsMC4xLDAsMC4zLDAuMSwwLjRsMCwwYzAuMSwwLjIsMC4zLDAuMywwLjUsMC4zbDAsMGMwLjEsMCwwLjMtMC4xLDAuNC0wLjJsMCwwbDAsMGwwLDBsMCwwYzAuMi0wLjIsMC41LTAuNCwwLjctMC42bDAsMGwwLDBsMCwwbDAsMGMwLjctMC44LDEuMy0xLjYsMS43LTIuNkMxNS42LDEwLDE1LjgsOSwxNS45LDcuOXogTTEuOSw0QzIsMy44LDIuMSwzLjUsMi4zLDMuMWwwLDBMMi43LDJsMS4yLDEuMkwxLjksNHpcIi8+PHBhdGggZD1cIk02LjgsMTUuNUw2LjgsMTUuNUw2LjgsMTUuNXpcIi8+PC9nPjwvc3ZnPicsXG4gICByb3RhdGVfcmlnaHQ6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1LjggMTUuOFwiPjxnPjxwYXRoIGQ9XCJNOS45LDE1LjNMOS45LDE1LjNMOS45LDE1LjN6XCIvPjxwYXRoIGQ9XCJNNi45LDE1LjFMNi45LDE1LjFjMCwwLjEsMC4xLDAuMywwLjIsMC40bDAsMGMwLjEsMC4yLDAuMywwLjMsMC41LDAuM2wwLDBoMC4zYzAuMiwwLDAuNCwwLDAuNywwbDAsMGMwLjItMC4xLDAuMy0wLjIsMC40LTAuM2MwLjEtMC4xLDAuMi0wLjIsMC4yLTAuNFYxNWMwLTAuMi0wLjEtMC40LTAuMi0wLjRjLTAuMi0wLjEtMC4zLTAuMi0wLjUtMC4ySDguNGwwLDBjLTAuMSwwLTAuMywwLTAuNSwwSDcuNmwwLDBjLTAuMiwwLTAuNCwwLjEtMC41LDAuMkM3LDE0LjcsNi45LDE0LjksNi45LDE1LjF6XCIvPjxwYXRoIGQ9XCJNNi41LDE0LjRMNi41LDE0LjRMNi41LDE0LjR6XCIvPjxwYXRoIGQ9XCJNNS44LDUuOEw1LjgsNS44Yy0xLDAuOS0xLjUsMS41LTEuNywxLjZsMCwwQzQsNy41LDQsNy43LDQsNy45YzAsMC4yLDAsMC40LDAuMiwwLjVsMCwwbDMuMiwzLjJsMCwwYzAuMiwwLjEsMC4zLDAuMiwwLjUsMC4yczAuNC0wLjEsMC41LTAuMmwwLDBsMy4yLTMuMmwwLDBjMC4xLTAuMSwwLjItMC4zLDAuMi0wLjVjMC0wLjItMC4xLTAuNC0wLjItMC41bDAsMEw4LjQsNC4yQzguMyw0LjEsOC4xLDQsNy45LDRDNy43LDQsNy41LDQuMSw3LjQsNC4ybDAsMEw1LjgsNS44eiBNNS42LDcuOWwyLjMtMi4ybDIuMiwyLjJMOSw5bDAsMGwwLDBsMCwwbDAsMGMtMC41LDAuNi0wLjksMC45LTEuMSwxLjFMNS42LDcuOXpcIi8+PHBhdGggZD1cIk05LDE1LjVMOSwxNS41TDksMTUuNXpcIi8+PHBhdGggZD1cIk05LjYsMTQuN3YwLjJsMCwwbDAsMGwwLDBsMCwwYzAuMSwwLjIsMC4xLDAuMywwLjMsMC4zYzAuMSwwLjEsMC4zLDAuMSwwLjQsMC4xbDAsMGgwLjFoMC4xYzAuMy0wLjEsMC42LTAuMywwLjktMC40bDAsMGMwLjEtMC4xLDAuMi0wLjIsMC4zLTAuNGwwLDB2LTAuMmMwLTAuMSwwLTAuMi0wLjEtMC4zYy0wLjEtMC4yLTAuMi0wLjMtMC40LTAuNEgxMWMtMC4xLDAtMC4yLDAuMS0wLjMsMC4xbDAsMGMtMC4yLDAuMS0wLjQsMC4yLTAuNywwLjNsMCwwbDAsMGMtMC4xLDAuMS0wLjMsMC4yLTAuNCwwLjRDOS42LDE0LjUsOS42LDE0LjYsOS42LDE0Ljd6XCIvPjxwYXRoIGQ9XCJNOSwxNC41TDksMTQuNUw5LDE0LjV6XCIvPjxwYXRoIGQ9XCJNOS42LDE0LjRMOS42LDE0LjRMOS42LDE0LjR6XCIvPjxwYXRoIGQ9XCJNMTEuNywxNEwxMS43LDE0TDExLjcsMTR6XCIvPjxwYXRoIGQ9XCJNMTUuNiw3LjRMMTUuNiw3LjRMMTUuNiw3LjR6XCIvPjxwYXRoIGQ9XCJNMTUsOS40YzAuMiwwLDAuNCwwLDAuNi0wLjJsMCwwYzAuMS0wLjEsMC4yLTAuMiwwLjItMC40bDAsMGwwLDBsMCwwbDAsMGMwLTAuMywwLTAuNiwwLTAuOWMwLTAuMi0wLjEtMC40LTAuMi0wLjVjLTAuMS0wLjEtMC4zLTAuMi0wLjUtMC4ycy0wLjQsMC4xLTAuNSwwLjJjLTAuMSwwLjEtMC4yLDAuMy0wLjIsMC41bDAsMGMwLDAuMiwwLDAuNCwwLDAuN2wwLDB2MC4xYzAsMC4xLDAsMC4zLDAuMSwwLjRsMCwwQzE0LjYsOS4zLDE0LjgsOS40LDE1LDkuNEwxNSw5LjRMMTUsOS40elwiLz48cGF0aCBkPVwiTTE0LDEyaDAuMWgwLjJoMC4xYzAuMiwwLDAuNS0wLjIsMC42LTAuNGwwLDBjMC4yLTAuMywwLjMtMC42LDAuNC0wLjlsMCwwdi0wLjJjMC0wLjEtMC4xLTAuMi0wLjEtMC4zYy0wLjEtMC4yLTAuMi0wLjMtMC40LTAuNGgtMC4zYy0wLjEsMC0wLjIsMC0wLjMsMEMxNC4yLDkuOSwxNCwxMCwxNCwxMC4zbDAsMGMtMC4xLDAuMi0wLjIsMC41LTAuMywwLjdsMCwwYy0wLjEsMC4xLTAuMSwwLjItMC4xLDAuM3YwLjJsMCwwbDAsMEMxMy42LDExLjYsMTMuOCwxMS44LDE0LDEyelwiLz48cGF0aCBkPVwiTTE0LjYsNy40TDE0LjYsNy40TDE0LjYsNy40elwiLz48cGF0aCBkPVwiTTQuNCwxNC4yYy0wLjEsMC4xLTAuMSwwLjItMC4xLDAuM2wwLjEsMC4yYzAsMC4yLDAuMiwwLjMsMC4zLDAuNGwwLDBjMC4zLDAuMSwwLjYsMC4zLDEuMSwwLjRsMCwwaDAuMWwwLDBjMC4xLDAsMC4yLTAuMSwwLjQtMC4yYzAuMSwwLDAuMi0wLjIsMC4zLTAuM2wwLDB2LTAuMmMwLTAuMS0wLjEtMC4zLTAuMi0wLjRjLTAuMS0wLjEtMC4yLTAuMi0wLjQtMC4zbDAsMGMtMC4yLTAuMS0wLjUtMC4yLTAuNy0wLjNsMCwwYy0wLjEsMC0wLjIsMC0wLjMsMEg0LjdsMCwwQzQuNiwxMy45LDQuNCwxNCw0LjQsMTQuMkw0LjQsMTQuMnpcIi8+PHBhdGggZD1cIk0xMS45LDEzLjNjMCwwLjIsMC4xLDAuNCwwLjIsMC42YzAuMSwwLjEsMC4zLDAuMiwwLjUsMC4yczAuNC0wLjEsMC41LTAuMmwwLDBsMCwwbDAsMGwwLDBjMC4xLTAuMSwwLjMtMC4zLDAuNC0wLjRsMCwwbDAuMi0wLjNsMCwwYzAuMS0wLjIsMC4yLTAuMywwLjItMC41bDAsMGMwLTAuMi0wLjEtMC40LTAuMi0wLjVsMCwwYy0wLjEtMC4xLTAuMy0wLjItMC41LTAuMmwwLDBjLTAuMiwwLTAuNCwwLjEtMC41LDAuMmwwLDBsLTAuMiwwLjJsLTAuNCwwLjRsMCwwQzEyLDEzLDExLjksMTMuMSwxMS45LDEzLjNMMTEuOSwxMy4zelwiLz48cGF0aCBkPVwiTTEyLjEsMTMuOEwxMi4xLDEzLjhMMTIuMSwxMy44elwiLz48cGF0aCBkPVwiTTExLjksMTMuM0wxMS45LDEzLjNMMTEuOSwxMy4zelwiLz48cGF0aCBkPVwiTTE1LjksNS4yYzAtMC4xLTAuMS0wLjItMC4xLTAuM2wwLDBMMTQsMC40bDAsMEMxMy45LDAuMiwxMy43LDAsMTMuNSwwbDAsMGwwLDBoLTAuMmMtMC4yLDAtMC40LDAuMS0wLjUsMC4ybDAsMGwtMC45LDAuOWMtMC41LTAuMy0xLjEtMC42LTEuOC0wLjhsMCwwQzkuNCwwLjEsOC43LDAsNy45LDBjLTEsMC0yLDAuMi0zLDAuNlMzLDEuNiwyLjMsMi4zQzEuNiwzLjEsMSwzLjksMC42LDQuOWwwLDBDMC4yLDUuOCwwLDYuOCwwLDcuOWMwLDEsMC4yLDIsMC42LDNzMC45LDEuOCwxLjcsMi42bDAsMGwwLDBsMCwwbDAsMGMwLjIsMC4yLDAuNSwwLjQsMC43LDAuNmwwLDBsMCwwbDAsMGwwLDBjMC4yLDAuMSwwLjMsMC4yLDAuNSwwLjJsMCwwYzAuMiwwLDAuNC0wLjEsMC42LTAuM2wwLDBjMC4xLTAuMSwwLjEtMC4zLDAuMS0wLjR2LTAuMWwwLDBDNC4xLDEzLjMsNCwxMy4xLDMuOSwxM2wwLDBjLTAuMi0wLjEtMC40LTAuMy0wLjYtMC41Yy0wLjYtMC42LTEuMS0xLjMtMS40LTIuMWwwLDBDMS42LDkuNiwxLjQsOC44LDEuNCw3LjlzMC4yLTEuNywwLjUtMi41bDAsMGMwLjMtMC44LDAuOC0xLjUsMS40LTIuMWMwLjYtMC42LDEuMy0xLjEsMi4xLTEuNGwwLDBDNi4yLDEuNiw3LDEuNCw3LjksMS40YzAuNiwwLDEuMSwwLjEsMS43LDAuMmMwLjUsMC4xLDAuOSwwLjMsMS4zLDAuNWwtMC44LDAuOGwwLDBDMTAsMy4xLDkuOSwzLjIsOS45LDMuNHYwLjJsMCwwbDAsMGMwLDAuMiwwLjIsMC40LDAuNCwwLjVsMCwwbDQuNSwxLjhsMCwwSDE1aDAuMWMwLjIsMCwwLjQtMC4xLDAuNS0wLjJsMCwwQzE1LjcsNS42LDE1LjgsNS40LDE1LjksNS4yeiBNMTEuOCwzLjJMMTMsMmwwLjQsMS4xbDAsMGMwLjIsMC40LDAuMywwLjcsMC40LDAuOUwxMS44LDMuMnpcIi8+PC9nPjwvc3ZnPicsXG4gICBtaXJyb3JfaG9yaXpvbnRhbDogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTQuNzUgMTUuNzRcIj48Zz48cGF0aCBkPVwiTTEzLjc1LDMuNzZsNS45LDE1Ljc0aC01LjlWMy43NlpNNC45LDE5LjUsMTAuOCwzLjc2VjE5LjVINC45WlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNC45IC0zLjc2KVwiLz48L2c+PC9zdmc+JyxcbiAgIG1pcnJvcl92ZXJ0aWNhbDogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNzQgMTQuNzVcIj48Zz48cGF0aCBkPVwiTTIwLjE1LDEzLjEsNC40MSwxOVYxMy4xSDIwLjE1Wk00LjQxLDQuMjVsMTUuNzQsNS45SDQuNDFWNC4yNVpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNDEgLTQuMjUpXCIvPjwvZz48L3N2Zz4nLFxuICAgY2hlY2tlZDogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTUuNzUgMTIuMVwiPjxnPjxwYXRoIGQ9XCJNNC41OSwxMi4yM2wuMTIuMThMOS40MywxNy41YS41OC41OCwwLDAsMCwuODQsMEwyMCw3LjQ1aDBhLjU4LjU4LDAsMCwwLDAtLjg0bC0uODUtLjg1YS41OC41OCwwLDAsMC0uODQsMEgxOC4ybC04LjEyLDguNDFhLjI5LjI5LDAsMCwxLS40MiwwbC0zLjQtMy42M2EuNTguNTgsMCwwLDAtLjg0LDBsLS44NS44NWEuNi42LDAsMCwwLS4xNC4yMS41MS41MSwwLDAsMCwwLC40NGMuMDUuMDYuMS4xMy4xNi4xOVpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuMzggLTUuNTgpXCIvPjwvZz48L3N2Zz4nLFxuICAgbGluZV9icmVhazogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIj48cGF0aCBkPVwiTTE5LDZhMSwxLDAsMCwwLTEsMXY0YTEsMSwwLDAsMS0xLDFINy40MWwxLjMtMS4yOUExLDEsMCwwLDAsNy4yOSw5LjI5bC0zLDNhMSwxLDAsMCwwLS4yMS4zMywxLDEsMCwwLDAsMCwuNzYsMSwxLDAsMCwwLC4yMS4zM2wzLDNhMSwxLDAsMCwwLDEuNDIsMCwxLDEsMCwwLDAsMC0xLjQyTDcuNDEsMTRIMTdhMywzLDAsMCwwLDMtM1Y3QTEsMSwwLDAsMCwxOSw2WlwiLz48L3N2Zz4nLFxuICAgYXVkaW86ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+PHBhdGggZD1cIk0xNCwzLjIzVjUuMjlDMTYuODksNi4xNSAxOSw4LjgzIDE5LDEyQzE5LDE1LjE3IDE2Ljg5LDE3Ljg0IDE0LDE4LjdWMjAuNzdDMTgsMTkuODYgMjEsMTYuMjggMjEsMTJDMjEsNy43MiAxOCw0LjE0IDE0LDMuMjNNMTYuNSwxMkMxNi41LDEwLjIzIDE1LjUsOC43MSAxNCw3Ljk3VjE2QzE1LjUsMTUuMjkgMTYuNSwxMy43NiAxNi41LDEyTTMsOVYxNUg3TDEyLDIwVjRMNyw5SDNaXCIgLz48L3N2Zz4nLFxuICAgaW1hZ2VfZ2FsbGVyeTogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIzMCAzMCAxNTAgMTUwXCI+PGc+PHBhdGggZD1cIk0xNTIuNzc1LDEyMC41NDhWNTEuNjUxYzAtMTIuMjcxLTkuOTg0LTIyLjI1NC0yMi4yNTQtMjIuMjU0SDQzLjcyN2MtMTIuMjcxLDAtMjIuMjU0LDkuOTgzLTIyLjI1NCwyMi4yNTR2NjguODk2YzAsMTIuMjcsOS45ODMsMjIuMjU0LDIyLjI1NCwyMi4yNTRoODYuNzk1QzE0Mi43OTEsMTQyLjgwMiwxNTIuNzc1LDEzMi44MTcsMTUyLjc3NSwxMjAuNTQ4eiBNMzYuMzk0LDUxLjY1MWMwLTQuMDQyLDMuMjkxLTcuMzMzLDcuMzMzLTcuMzMzaDg2Ljc5NWM0LjA0MiwwLDcuMzMyLDMuMjkxLDcuMzMyLDcuMzMzdjIzLjkxN2wtMTQuOTM4LTE3Ljc2N2MtMS40MS0xLjY3OC0zLjQ4Ny0yLjY0OS01LjY4LTIuNjU4aC0wLjAyOWMtMi4xODQsMC00LjI1NSwwLjk1NC01LjY3NCwyLjYxM0w3Ni43MDksOTguNTE5bC05LjA5Ni05LjM5OGMtMS40MjctMS40NzQtMy4zOTItMi4yOTEtNS40NDgtMi4yNzNjLTIuMDUyLDAuMDI1LTQuMDA0LDAuODkzLTUuMzk2LDIuNEwzNi4zOTQsMTExLjMyVjUxLjY1MXogTTQxLjY4NCwxMjcuNTg1bDIwLjY5Ny0yMi40MTZsOS4zMTIsOS42MjJjMS40NjEsMS41MTEsMy40ODksMi4zMzQsNS41OTIsMi4yN2MyLjEwMS0wLjA2Niw0LjA3NS0xLjAxMyw1LjQ0LTIuNjEybDM0LjQzNi00MC4zMDhsMjAuNjkzLDI0LjYxM3YyMS43OTRjMCw0LjA0Mi0zLjI5LDcuMzMyLTcuMzMyLDcuMzMySDQzLjcyN0M0My4wMTgsMTI3Ljg4LDQyLjMzNCwxMjcuNzc1LDQxLjY4NCwxMjcuNTg1eiBNMTgyLjYxNiwxNTIuNVY3NS42NTdjMC00LjEyLTMuMzQtNy40Ni03LjQ2MS03LjQ2Yy00LjExOSwwLTcuNDYsMy4zNC03LjQ2LDcuNDZWMTUyLjVjMCw0LjExMi0zLjM0Nyw3LjQ2LTcuNDYxLDcuNDZoLTk0Yy00LjExOSwwLTcuNDYsMy4zMzktNy40Niw3LjQ1OWMwLDQuMTIzLDMuMzQxLDcuNDYyLDcuNDYsNy40NjJoOTRDMTcyLjU3NiwxNzQuODgxLDE4Mi42MTYsMTY0Ljg0MSwxODIuNjE2LDE1Mi41elwiLz48L2c+PC9zdmc+JyxcbiAgIC8vIE1vcmUgaWNvbnNcbiAgIG1vcmVfdGV4dDogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIxMCAxMCAxODAgMTgwXCI+PGc+PHBhdGggZD1cIk00OS43MTEsMTQyLjE4OGg0OS4wMjdjMi4zMjgsMC4wMDIsNC4zOTQsMS40OTIsNS4xMjksMy42OTlsOS43NDIsMjkuMjUyYzAuMzYzLDEuMDkyLDEuMzg1LDEuODI4LDIuNTM3LDEuODNsMTUuODgzLDAuMDFjMC44NTksMCwxLjY2Ny0wLjQxMiwyLjE3LTEuMTA5czAuNjQxLTEuNTk0LDAuMzctMi40MWwtMTYuNjI1LTUwLjA0NUw4Ni41MDMsMjguOTUzYy0wLjM2LTEuMDk3LTEuMzgzLTEuODM5LTIuNTM3LTEuODQySDY0LjUzMmMtMS4xNTMtMC4wMDEtMi4xNzgsMC43MzYtMi41NDIsMS44MzFMMTMuODQ3LDE3My40NTdjLTAuMjcxLDAuODE2LTAuMTM1LDEuNzEzLDAuMzY5LDIuNDEyYzAuNTAzLDAuNjk3LDEuMzExLDEuMTA5LDIuMTcxLDEuMTA5aDE1Ljg3MmMxLjE1MSwwLDIuMTczLTAuNzM2LDIuNTM3LTEuODI4bDkuNzkzLTI5LjI4N0M0NS4zMjUsMTQzLjY2LDQ3LjM5LDE0Mi4xOCw0OS43MTEsMTQyLjE4OEw0OS43MTEsMTQyLjE4OHogTTUzLjQ5MywxMTkuMDk4bDE1LjYwNy00Ni45YzAuNzQ0LTIuMTk2LDIuODA2LTMuNjc0LDUuMTI1LTMuNjc0czQuMzgxLDEuNDc4LDUuMTI1LDMuNjc0bDE1LjYwNyw0Ni45MDRjMC41MzcsMS42MjEsMC4yNjMsMy40MDItMC43MzYsNC43ODljLTEuMDE4LDEuNDA4LTIuNjQ5LDIuMjQtNC4zODYsMi4yNEg1OC42MTVjLTEuNzM2LDAtMy4zNjgtMC44MzItNC4zODYtMi4yNEM1My4yMywxMjIuNTA0LDUyLjk1NiwxMjAuNzIxLDUzLjQ5MywxMTkuMDk4TDUzLjQ5MywxMTkuMDk4eiBNMTkwLjQ2NSw2My4zMmMwLTIuOTE5LTEuMDE1LTUuMzk2LTMuMDU5LTcuNDI4Yy0yLjAyOS0yLjAzMS00LjQ5Ni0zLjA0Ny03LjM4My0zLjA0N2MtMi44ODksMC01LjM1NSwxLjAxNi03LjM4OCwzLjA0N2MtMi4wMjksMi4wMzItMy4wNTYsNC40OTgtMy4wNTYsNy4zODZjMCwyLjg4OSwxLjAyNiw1LjM1NCwzLjA1Niw3LjM4NWMyLjAzMiwyLjAzMiw0LjQ5OSwzLjA1OSw3LjM4OCwzLjA1OWMyLjg4NywwLDUuMzU0LTEuMDI2LDcuMzgzLTMuMDU5QzE4OS40NSw2OC42MzMsMTkwLjQ2NSw2Ni4xNzgsMTkwLjQ2NSw2My4zMkwxOTAuNDY1LDYzLjMyeiBNMTkwLjQ2NSwxMDEuOTk0YzAtMi44NTgtMS4wMTUtNS4zMTMtMy4wNTktNy4zMzNjLTIuMDI5LTIuMDQyLTQuNDk2LTMuMDQ3LTcuMzgzLTMuMDQ3Yy0yLjg4OSwwLTUuMzU1LDEuMDA1LTcuMzg4LDMuMDQ3Yy0yLjAyOSwyLjAyMS0zLjA1Niw0LjQ4Ni0zLjA1Niw3LjM3NmMwLDIuODg3LDEuMDI2LDUuMzUyLDMuMDU2LDcuMzk1YzIuMDMyLDIuMDIxLDQuNDk5LDMuMDQ3LDcuMzg4LDMuMDQ3YzIuODg3LDAsNS4zNTQtMS4wMjUsNy4zODMtMy4wNDdDMTg5LjQ1LDEwNy4zODksMTkwLjQ2NSwxMDQuOTE0LDE5MC40NjUsMTAxLjk5NEwxOTAuNDY1LDEwMS45OTR6IE0xOTAuNDY1LDE0MC43NmMwLTIuOTE4LTEuMDE1LTUuMzk1LTMuMDU5LTcuNDM4Yy0yLjAyOS0yLjA0MS00LjQ5Ni0zLjA0Ny03LjM4My0zLjA0N2MtMi44ODksMC01LjM1NSwxLjAwNi03LjM4OCwzLjA0N2MtMi4wMjksMi4wNDMtMy4wNTYsNC41Mi0zLjA1Niw3LjQzOGMwLDIuOTIyLDEuMDI2LDUuMzk4LDMuMDU2LDcuNDM5YzIuMDMyLDIuMDIxLDQuNDk5LDMuMDQ3LDcuMzg4LDMuMDQ3YzIuODg3LDAsNS4zNTQtMS4wMjUsNy4zODMtMy4wNDdDMTg5LjQ1LDE0Ni4xNTgsMTkwLjQ2NSwxNDMuNjgyLDE5MC40NjUsMTQwLjc2TDE5MC40NjUsMTQwLjc2elwiLz48L2c+PC9zdmc+JyxcbiAgIG1vcmVfcGFyYWdyYXBoOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjEwIDEwIDE4MCAxODBcIj48Zz48cGF0aCBkPVwiTTEyOC4zOSwyOC40OTlINjMuNDkzYy0yNS41NTgsMC00Ni4zNTQsMjAuNzk2LTQ2LjM1NCw0Ni4zNTRjMCwyNS41NTksMjAuNzk2LDQ2LjM1Myw0Ni4zNTQsNDYuMzUzaDkuMjcxdjU1LjYyNWgxOC41NDJWNDcuMDRoOS4yNzFWMTc2LjgzaDE4LjU0M1Y0Ny4wNGg5LjI3MVYyOC40OTl6IE03Mi43NjQsMTAyLjY2NGgtOS4yNzFjLTE1LjMzNywwLTI3LjgxMy0xMi40NzUtMjcuODEzLTI3LjgxMmMwLTE1LjMzNiwxMi40NzYtMjcuODEzLDI3LjgxMy0yNy44MTNoOS4yNzFWMTAyLjY2NHogTTE5MC40NjUsNjMuMzJjMC0yLjkxOS0xLjAxNS01LjM5Ni0zLjA1OS03LjQyOGMtMi4wMjktMi4wMzEtNC40OTYtMy4wNDctNy4zODMtMy4wNDdjLTIuODg5LDAtNS4zNTUsMS4wMTYtNy4zODgsMy4wNDdjLTIuMDI5LDIuMDMyLTMuMDU2LDQuNDk4LTMuMDU2LDcuMzg2YzAsMi44ODksMS4wMjYsNS4zNTQsMy4wNTYsNy4zODVjMi4wMzIsMi4wMzIsNC40OTksMy4wNTksNy4zODgsMy4wNTljMi44ODcsMCw1LjM1NC0xLjAyNiw3LjM4My0zLjA1OUMxODkuNDUsNjguNjMzLDE5MC40NjUsNjYuMTc4LDE5MC40NjUsNjMuMzJMMTkwLjQ2NSw2My4zMnogTTE5MC40NjUsMTAxLjk5NGMwLTIuODU4LTEuMDE1LTUuMzEzLTMuMDU5LTcuMzMzYy0yLjAyOS0yLjA0Mi00LjQ5Ni0zLjA0Ny03LjM4My0zLjA0N2MtMi44ODksMC01LjM1NSwxLjAwNS03LjM4OCwzLjA0N2MtMi4wMjksMi4wMjEtMy4wNTYsNC40ODYtMy4wNTYsNy4zNzZjMCwyLjg4NywxLjAyNiw1LjM1MiwzLjA1Niw3LjM5NWMyLjAzMiwyLjAyMSw0LjQ5OSwzLjA0Nyw3LjM4OCwzLjA0N2MyLjg4NywwLDUuMzU0LTEuMDI1LDcuMzgzLTMuMDQ3QzE4OS40NSwxMDcuMzg5LDE5MC40NjUsMTA0LjkxNCwxOTAuNDY1LDEwMS45OTRMMTkwLjQ2NSwxMDEuOTk0eiBNMTkwLjQ2NSwxNDAuNzZjMC0yLjkxOC0xLjAxNS01LjM5NS0zLjA1OS03LjQzOGMtMi4wMjktMi4wNDEtNC40OTYtMy4wNDctNy4zODMtMy4wNDdjLTIuODg5LDAtNS4zNTUsMS4wMDYtNy4zODgsMy4wNDdjLTIuMDI5LDIuMDQzLTMuMDU2LDQuNTItMy4wNTYsNy40MzhjMCwyLjkyMiwxLjAyNiw1LjM5OCwzLjA1Niw3LjQzOWMyLjAzMiwyLjAyMSw0LjQ5OSwzLjA0Nyw3LjM4OCwzLjA0N2MyLjg4NywwLDUuMzU0LTEuMDI1LDcuMzgzLTMuMDQ3QzE4OS40NSwxNDYuMTU4LDE5MC40NjUsMTQzLjY4MiwxOTAuNDY1LDE0MC43NkwxOTAuNDY1LDE0MC43NnpcIi8+PC9nPjwvc3ZnPicsXG4gICBtb3JlX3BsdXM6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMzUgMzAgMTQwIDE0MFwiPjxnPjxwYXRoIGQ9XCJNMTM3LjIxNSwxMDIuMDQ1YzAsMy40OTgtMi44MzUsNi4zMzItNi4zMzMsNi4zMzJIMjQuNTQ5Yy0zLjQ5OCwwLTYuMzM0LTIuODM0LTYuMzM0LTYuMzMybDAsMGMwLTMuNDk4LDIuODM2LTYuMzMzLDYuMzM0LTYuMzMzaDEwNi4zMzNDMTM0LjM4LDk1LjcxMSwxMzcuMjE1LDk4LjU0NywxMzcuMjE1LDEwMi4wNDVMMTM3LjIxNSwxMDIuMDQ1eiBNNzcuNzE1LDE2MS41NDVjLTMuNDk4LDAtNi4zMzMtMi44MzYtNi4zMzMtNi4zMzRWNDguODc4YzAtMy40OTgsMi44MzYtNi4zMzMsNi4zMzMtNi4zMzNsMCwwYzMuNDk4LDAsNi4zMzQsMi44MzUsNi4zMzQsNi4zMzN2MTA2LjMzM0M4NC4wNDksMTU4LjcwOSw4MS4yMTMsMTYxLjU0NSw3Ny43MTUsMTYxLjU0NUw3Ny43MTUsMTYxLjU0NXogTTE5MC40NjUsNjMuMzJjMC0yLjkxOS0xLjAxNS01LjM5Ni0zLjA1OS03LjQyOGMtMi4wMjktMi4wMzEtNC40OTYtMy4wNDctNy4zODMtMy4wNDdjLTIuODg5LDAtNS4zNTUsMS4wMTYtNy4zODgsMy4wNDdjLTIuMDI5LDIuMDMyLTMuMDU2LDQuNDk4LTMuMDU2LDcuMzg2YzAsMi44ODksMS4wMjYsNS4zNTQsMy4wNTYsNy4zODVjMi4wMzIsMi4wMzIsNC40OTksMy4wNTksNy4zODgsMy4wNTljMi44ODcsMCw1LjM1NC0xLjAyNiw3LjM4My0zLjA1OUMxODkuNDUsNjguNjMyLDE5MC40NjUsNjYuMTc3LDE5MC40NjUsNjMuMzJMMTkwLjQ2NSw2My4zMnogTTE5MC40NjUsMTAxLjk5M2MwLTIuODU4LTEuMDE1LTUuMzEzLTMuMDU5LTcuMzMzYy0yLjAyOS0yLjA0Mi00LjQ5Ni0zLjA0Ny03LjM4My0zLjA0N2MtMi44ODksMC01LjM1NSwxLjAwNS03LjM4OCwzLjA0N2MtMi4wMjksMi4wMjEtMy4wNTYsNC40ODYtMy4wNTYsNy4zNzZjMCwyLjg4OCwxLjAyNiw1LjM1MywzLjA1Niw3LjM5NmMyLjAzMiwyLjAyMSw0LjQ5OSwzLjA0Nyw3LjM4OCwzLjA0N2MyLjg4NywwLDUuMzU0LTEuMDI1LDcuMzgzLTMuMDQ3QzE4OS40NSwxMDcuMzg5LDE5MC40NjUsMTA0LjkxNCwxOTAuNDY1LDEwMS45OTNMMTkwLjQ2NSwxMDEuOTkzeiBNMTkwLjQ2NSwxNDAuNzZjMC0yLjkxOC0xLjAxNS01LjM5NS0zLjA1OS03LjQzOGMtMi4wMjktMi4wNDEtNC40OTYtMy4wNDctNy4zODMtMy4wNDdjLTIuODg5LDAtNS4zNTUsMS4wMDYtNy4zODgsMy4wNDdjLTIuMDI5LDIuMDQzLTMuMDU2LDQuNTItMy4wNTYsNy40MzhjMCwyLjkyMiwxLjAyNiw1LjM5OCwzLjA1Niw3LjQzOWMyLjAzMiwyLjAyMSw0LjQ5OSwzLjA0Nyw3LjM4OCwzLjA0N2MyLjg4NywwLDUuMzU0LTEuMDI1LDcuMzgzLTMuMDQ3QzE4OS40NSwxNDYuMTU4LDE5MC40NjUsMTQzLjY4MiwxOTAuNDY1LDE0MC43NkwxOTAuNDY1LDE0MC43NnpcIi8+PC9nPjwvc3ZnPicsXG4gICBtb3JlX2hvcml6b250YWw6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE1Ljc2IDMuNThcIj48Zz48cGF0aCBkPVwiTTQuNjQsMTAuNzNhMS44NCwxLjg0LDAsMCwxLC42NS0uNjUsMS43NiwxLjc2LDAsMCwxLDEuNzksMEExLjc5LDEuNzksMCwwLDEsOCwxMS42M2ExLjg0LDEuODQsMCwwLDEtLjI1LjksMS42OSwxLjY5LDAsMCwxLS42NS42NSwxLjgsMS44LDAsMCwxLTIuNjktMS41NUEyLjA4LDIuMDgsMCwwLDEsNC42NCwxMC43M1ptNi4wOSwwYTEuODQsMS44NCwwLDAsMSwuNjUtLjY1LDEuNzgsMS43OCwwLDAsMSwyLjY3LDEuNTUsMS43MywxLjczLDAsMCwxLS4yNC45LDEuODQsMS44NCwwLDAsMS0uNjUuNjUsMS43NiwxLjc2LDAsMCwxLTEuNzksMCwxLjc5LDEuNzksMCwwLDEtLjY0LTIuNDRabTYuMDgsMGExLjY5LDEuNjksMCwwLDEsLjY1LS42NSwxLjc2LDEuNzYsMCwwLDEsMS43OSwwLDEuNzksMS43OSwwLDAsMSwuOSwxLjU0LDEuNzMsMS43MywwLDAsMS0uMjQuOSwxLjg0LDEuODQsMCwwLDEtLjY1LjY1LDEuOCwxLjgsMCwwLDEtMi42OS0xLjU1QTIsMiwwLDAsMSwxNi44MSwxMC43M1pcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuMzkgLTkuODQpXCIvPjwvZz48L3N2Zz4nLFxuICAgbW9yZV92ZXJ0aWNhbDogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMy45NCAxNS43NVwiPjxnPjxwYXRoIGQ9XCJNMTIuMjgsNy42OWExLjkyLDEuOTIsMCwwLDEtMS4zOS0uNTgsMiwyLDAsMCwxLS41OC0xLjM5LDEuOTIsMS45MiwwLDAsMSwuNTgtMS4zOSwyLDIsMCwwLDEsMS4zOS0uNTgsMS45MiwxLjkyLDAsMCwxLDEuMzkuNTgsMiwyLDAsMCwxLC41OCwxLjM5LDEuOTIsMS45MiwwLDAsMS0uNTgsMS4zOSwyLDIsMCwwLDEtMS4zOS41OFptMCwyYTEuOTIsMS45MiwwLDAsMSwxLjM5LjU4LDIsMiwwLDAsMSwuNTgsMS4zOUExLjkyLDEuOTIsMCwwLDEsMTMuNjcsMTNhMiwyLDAsMCwxLTEuMzkuNThBMS45MiwxLjkyLDAsMCwxLDEwLjg5LDEzYTIsMiwwLDAsMS0uNTgtMS4zOSwyLDIsMCwwLDEsMi0yWm0wLDUuOWExLjkyLDEuOTIsMCwwLDEsMS4zOS41OCwyLDIsMCwwLDEsLjU4LDEuMzksMS45MiwxLjkyLDAsMCwxLS41OCwxLjM5LDIsMiwwLDAsMS0xLjM5LjU4LDEuOTIsMS45MiwwLDAsMS0xLjM5LS41OCwyLDIsMCwwLDEtLjU4LTEuMzksMS45MiwxLjkyLDAsMCwxLC41OC0xLjM5LDEuOTQsMS45NCwwLDAsMSwxLjM5LS41OFpcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTEwLjMxIC0zLjc1KVwiLz48L2c+PC9zdmc+JyxcbiAgIC8vIE5vdCBjdXJyZW50bHkgdXNlZFxuICAgYXR0YWNobWVudDogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgOC4zOCAxNS42OFwiPjxnPjxwYXRoIGQ9XCJNMTUuMjMsNmgxdjkuNzhhMy44OCwzLjg4LDAsMCwxLTEuMzEsMi40NSw0LDQsMCwwLDEtNi41Ny0yLjQ1VjdBMywzLDAsMCwxLDkuMiw0Ljg5YTMsMywwLDAsMSw1LDIuMDl2OC4zMWExLjkyLDEuOTIsMCwwLDEtLjU4LDEuMzksMiwyLDAsMCwxLTEuMzkuNTgsMS45MiwxLjkyLDAsMCwxLTEuMzktLjU4LDIsMiwwLDAsMS0uNTgtMS4zOVY4aDF2Ny4zMmExLDEsMCwwLDAsLjI5LjY5LDEsMSwwLDAsMCwuNjkuMjhBLjkuOSwwLDAsMCwxMywxNmExLDEsMCwwLDAsLjI5LS42OVY3YTEuOTIsMS45MiwwLDAsMC0uNTgtMS4zOUEyLDIsMCwwLDAsMTEuMjcsNWExLjkyLDEuOTIsMCwwLDAtMS4zOS41OEEyLDIsMCwwLDAsOS4zMyw3djguMzFhMywzLDAsMSwwLDUuOSwwVjZaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC04LjA4IC0zLjc4KVwiLz48L2c+PC9zdmc+JyxcbiAgIG1hcDogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTEuNyAxNS42MlwiPjxnPjxwYXRoIGQ9XCJNMTIuMDUsMTIuNDJhMi45MywyLjkzLDAsMSwxLDIuMDctNUEyLjg4LDIuODgsMCwwLDEsMTUsOS40OWEzLDMsMCwwLDEtLjg2LDIuMDcsMi44OSwyLjg5LDAsMCwxLTIuMDcuODZabTAtNS4zNmEyLjQzLDIuNDMsMCwwLDAtMS43Miw0LjE2LDIuNDgsMi40OCwwLDAsMCwxLjcyLjcyLDIuNDQsMi40NCwwLDAsMCwwLTQuODhabTAtMy4zQTUuODQsNS44NCwwLDAsMSwxNy45LDkuNjJhOS45NCw5Ljk0LDAsMCwxLTEuNzMsNUEzMy41OSwzMy41OSwwLDAsMSwxMi44NCwxOWExLjUyLDEuNTIsMCwwLDEtLjIzLjIsMSwxLDAsMCwxLS41NS4yaDBhMSwxLDAsMCwxLS41NS0uMiwxLjUyLDEuNTIsMCwwLDEtLjIzLS4yLDMzLjU5LDMzLjU5LDAsMCwxLTMuMzMtNC4zMiw5LjkzLDkuOTMsMCwwLDEtMS43Mi01LDUuODQsNS44NCwwLDAsMSw1Ljg1LTUuODZaTTEyLDE4LjM0bC4wOC4wNS4wNi0uMDZhMzUuNTgsMzUuNTgsMCwwLDAsMy4wNi0zLjkzLDkuMzUsOS4zNSwwLDAsMCwxLjc0LTQuNzcsNC44OCw0Ljg4LDAsMCwwLTQuODgtNC44OEE0Ljc5LDQuNzksMCwwLDAsOC42LDYuMTcsNC44NCw0Ljg0LDAsMCwwLDcuMTcsOS42Miw5LjI5LDkuMjksMCwwLDAsOC45MSwxNC40LDM2LDM2LDAsMCwwLDEyLDE4LjM0WlwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNi4yIC0zLjc2KVwiLz48L2c+PC9zdmc+JyxcbiAgIG1hZ2ljX3N0aWNrOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNS43MyAxNS43NVwiPjxnPjxwYXRoIGQ9XCJNMTkuODYsMTkuMjFhMSwxLDAsMCwwLC4yOC0uNjgsMSwxLDAsMCwwLS4yOC0uN0wxMywxMC45M2ExLDEsMCwwLDAtLjctLjI4LDEsMSwwLDAsMC0uNjgsMS42NWw2LjksNi45YTEsMSwwLDAsMCwuNjkuMjkuOTMuOTMsMCwwLDAsLjY5LS4yOFpNOS4xOSw4LjU1YTMsMywwLDAsMCwxLjY4LDAsMTQuMTIsMTQuMTIsMCwwLDAsMS40MS0uMzJBMTEuMjYsMTEuMjYsMCwwLDAsMTAuOCw3LjA2Yy0uNTYtLjM2LS44Ni0uNTYtLjkxLS41OFMxMCw1LjkxLDEwLDUuMTFzMC0xLjI2LS4xNS0xLjM3YTQuMzUsNC4zNSwwLDAsMC0xLjE5LjcxYy0uNTMuNC0uODEuNjItLjg3LjY4YTksOSwwLDAsMC0yLS42LDYuODQsNi44NCwwLDAsMC0uNzYtLjA5czAsLjI3LjA4Ljc3YTguNiw4LjYsMCwwLDAsLjYxLDJxLS4wOS4wOS0uNjkuODdhMy41OSwzLjU5LDAsMCwwLS42OCwxLjE3Yy4xMi4xNy41Ny4yMywxLjM2LjE1UzcsOS4yNiw3LjE1LDkuMjNzLjIxLjM2LjU3LjkxYTEwLjQ5LDEwLjQ5LDAsMCwwLDEuMTQsMS40OGMwLS4xLjE0LS41Ny4zMS0xLjRhMywzLDAsMCwwLDAtMS42N1pcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQuNDEgLTMuNzQpXCIvPjwvZz48L3N2Zz4nLFxuICAgZW1wdHlfZmlsZTogJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTIuNzggMTUuNzVcIj48Zz48cGF0aCBkPVwiTTE0LjczLDMuNzYsMTguNjcsNy43djkuODRhMiwyLDAsMCwxLTIsMkg3Ljg0YTEuODksMS44OSwwLDAsMS0xLjM4LS41OCwyLDIsMCwwLDEtLjU3LTEuMzlWNS43M2ExLjkzLDEuOTMsMCwwLDEsLjU3LTEuMzgsMiwyLDAsMCwxLDEuMzgtLjU4aDYuNjJsLjI2LDB2MFptMi45NSw0LjkyaC0yYTEuOTMsMS45MywwLDAsMS0xLjM4LS41NywyLDIsMCwwLDEtLjU4LTEuNFY2LjE3YzAtLjM2LDAtLjg0LDAtMS40M0g3Ljg1YTEsMSwwLDAsMC0uNy4yOSwxLDEsMCwwLDAtLjI5LjdWMTcuNTRhMSwxLDAsMCwwLC4yOS42OSwxLDEsMCwwLDAsLjY5LjI5aDguODVhMSwxLDAsMCwwLC43MS0uMjkuOTIuOTIsMCwwLDAsLjI4LS42OVptMC0xTDE0LjczLDQuNzR2MkExLDEsMCwwLDAsMTUsNy40YTEsMSwwLDAsMCwuNjkuMjlaXCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC01Ljg5IC0zLjc2KVwiLz48L2c+PC9zdmc+J1xufTtcbiIsIi8qXHJcbiAqIHd5c2l3eWcgd2ViIGVkaXRvclxyXG4gKlxyXG4gKiBzdW5lZGl0b3IuanNcclxuICogQ29weXJpZ2h0IDIwMTcgSmlIb25nIExlZS5cclxuICogTUlUIGxpY2Vuc2UuXHJcbiAqL1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG4vKipcclxuICogQGRlc2NyaXB0aW9uIHV0aWxpdHkgZnVuY3Rpb25cclxuICovXHJcbmNvbnN0IHV0aWwgPSB7XHJcbiAgICBfZDogbnVsbCxcclxuICAgIF93OiBudWxsLFxyXG4gICAgaXNJRTogbnVsbCxcclxuICAgIGlzSUVfRWRnZTogbnVsbCxcclxuICAgIGlzT1NYX0lPUzogbnVsbCxcclxuICAgIF9wcm9wZXJ0aWVzSW5pdDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9kKSByZXR1cm47XHJcbiAgICAgICAgdGhpcy5fZCA9ICBkb2N1bWVudDtcclxuICAgICAgICB0aGlzLl93ID0gd2luZG93O1xyXG4gICAgICAgIHRoaXMuaXNJRSA9IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignVHJpZGVudCcpID4gLTE7XHJcbiAgICAgICAgdGhpcy5pc0lFX0VkZ2UgPSAobmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdUcmlkZW50JykgPiAtMSkgfHwgKG5hdmlnYXRvci5hcHBWZXJzaW9uLmluZGV4T2YoJ0VkZ2UnKSA+IC0xKTtcclxuICAgICAgICB0aGlzLmlzT1NYX0lPUyA9IC8oTWFjfGlQaG9uZXxpUG9kfGlQYWQpLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIEhUTUwgUmVzZXJ2ZWQgV29yZCBDb252ZXJ0ZXIuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gY29udGVudHMgXHJcbiAgICAgKiBAcmV0dXJucyB7U3RyaW5nfSBIVE1MIHN0cmluZ1xyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX0hUTUxDb252ZXJ0b3I6IGZ1bmN0aW9uIChjb250ZW50cykge1xyXG4gICAgICAgIGNvbnN0IGVjID0geycmJzogJyZhbXA7JywgJ1xcdTAwQTAnOiAnJm5ic3A7JywgJ1xcJyc6ICcmYXBvczsnLCAnXCInOiAnJnF1b3Q7JywgJzwnOsKgJyZsdDsnLMKgJz4nOsKgJyZndDsnfTtcclxuICAgICAgICByZXR1cm4gY29udGVudHMucmVwbGFjZSgvJnxcXHUwMEEwfCd8XCJ8PHw+L2csIGZ1bmN0aW9uIChtKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAodHlwZW9mIGVjW21dID09PSAnc3RyaW5nJykgPyBlY1ttXSA6IG07XHJcbiAgICAgICAgfSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFVuaWNvZGUgQ2hhcmFjdGVyICdaRVJPIFdJRFRIIFNQQUNFJyAoXFx1MjAwQilcclxuICAgICAqL1xyXG4gICAgemVyb1dpZHRoU3BhY2U6IFN0cmluZy5mcm9tQ2hhckNvZGUoODIwMyksXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gUmVndWxhciBleHByZXNzaW9uIHRvIGZpbmQgJ3plcm8gd2lkdGggc3BhY2UnICgvXFx1MjAwQi9nKVxyXG4gICAgICovXHJcbiAgICB6ZXJvV2lkdGhSZWdFeHA6IG5ldyBSZWdFeHAoU3RyaW5nLmZyb21DaGFyQ29kZSg4MjAzKSwgJ2cnKSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZmluZCBvbmx5ICd6ZXJvIHdpZHRoIHNwYWNlJyAoL15cXHUyMDBCKyQvKVxyXG4gICAgICovXHJcbiAgICBvbmx5WmVyb1dpZHRoUmVnRXhwOiBuZXcgUmVnRXhwKCdeJyArIFN0cmluZy5mcm9tQ2hhckNvZGUoODIwMykgKyAnKyQnKSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBBIG1ldGhvZCB0aGF0IGNoZWNrcyBJZiB0aGUgdGV4dCBpcyBibGFuayBvciB0byBzZWUgaWYgaXQgY29udGFpbnMgJ1pFUk8gV0lEVEggU1BBQ0UnIG9yIGVtcHR5ICh1dGlsLnplcm9XaWR0aFNwYWNlKVxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd8Tm9kZX0gdGV4dCBTdHJpbmcgdmFsdWUgb3IgTm9kZVxyXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIG9ubHlaZXJvV2lkdGhTcGFjZTogZnVuY3Rpb24gKHRleHQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIHRleHQgIT09ICdzdHJpbmcnKSB0ZXh0ID0gdGV4dC50ZXh0Q29udGVudDtcclxuICAgICAgICByZXR1cm4gdGV4dCA9PT0gJycgfHwgdGhpcy5vbmx5WmVyb1dpZHRoUmVnRXhwLnRlc3QodGV4dCk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIEdldHMgWE1MSHR0cFJlcXVlc3Qgb2JqZWN0XHJcbiAgICAgKiBAcmV0dXJucyB7WE1MSHR0cFJlcXVlc3R8QWN0aXZlWE9iamVjdH1cclxuICAgICAqL1xyXG4gICAgZ2V0WE1MSHR0cFJlcXVlc3Q6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvKiogSUUgKi9cclxuICAgICAgICBpZiAodGhpcy5fdy5BY3RpdmVYT2JqZWN0KSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01zeG1sMi5YTUxIVFRQJyk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWE1MSFRUUCcpO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZTEpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICAvKiogbmV0c2NhcGUgKi9cclxuICAgICAgICBlbHNlIGlmICh0aGlzLl93LlhNTEh0dHBSZXF1ZXN0KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLyoqIGZhaWwgKi9cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBDcmVhdGUgRWxlbWVudCBub2RlXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZWxlbWVudE5hbWUgRWxlbWVudCBuYW1lXHJcbiAgICAgKiBAcmV0dXJucyB7RWxlbWVudH1cclxuICAgICAqL1xyXG4gICAgY3JlYXRlRWxlbWVudDogZnVuY3Rpb24gKGVsZW1lbnROYW1lKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2QuY3JlYXRlRWxlbWVudChlbGVtZW50TmFtZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIENyZWF0ZSB0ZXh0IG5vZGVcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IHRleHQgY29udGVudHNcclxuICAgICAqIEByZXR1cm5zIHtOb2RlfVxyXG4gICAgICovXHJcbiAgICBjcmVhdGVUZXh0Tm9kZTogZnVuY3Rpb24gKHRleHQpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZC5jcmVhdGVUZXh0Tm9kZSh0ZXh0IHx8ICcnKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gVGhlIGVkaXRvciBjaGVja3MgdGFncyBieSBzdHJpbmcuXHJcbiAgICAgKiBJZiB0aGVyZSBpcyBcIjxcIiBvciBcIj5cIiBpbiB0aGUgYXR0cmlidXRlIG9mIHRhZywgSFRNTCBpcyBicm9rZW4gd2hlbiBjaGVja2luZyB0aGUgdGFnLlxyXG4gICAgICogV2hlbiB1c2luZyBhbiBhdHRyaWJ1dGUgd2l0aCBcIjxcIiBvciBcIj5cIiwgdXNlIFwiSFRNTEVuY29kZXJcIiB0byBzYXZlLiAoZXg6IG1hdGgoa2F0ZXgpKVxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNvbnRlbnRzIEhUTUwgb3IgVGV4dCBzdHJpbmdcclxuICAgICAqIEByZXR1cm5zIHtTdHJpbmd9XHJcbiAgICAgKi9cclxuICAgIEhUTUxFbmNvZGVyOiBmdW5jdGlvbiAoY29udGVudHMpIHtcclxuICAgICAgICBjb25zdCBlYyA9IHsnPCc6wqAnJGx0OycswqAnPic6wqAnJGd0Oyd9O1xyXG4gICAgICAgIHJldHVybiBjb250ZW50cy5yZXBsYWNlKC88fD4vZywgZnVuY3Rpb24gKG0pIHtcclxuICAgICAgICAgICAgcmV0dXJuICh0eXBlb2YgZWNbbV0gPT09ICdzdHJpbmcnKSA/IGVjW21dIDogbTtcclxuICAgICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gVGhlIGVkaXRvciBjaGVja3MgdGFncyBieSBzdHJpbmcuXHJcbiAgICAgKiBJZiB0aGVyZSBpcyBcIjxcIiBvciBcIj5cIiBpbiB0aGUgYXR0cmlidXRlIG9mIHRhZywgSFRNTCBpcyBicm9rZW4gd2hlbiBjaGVja2luZyB0aGUgdGFnLlxyXG4gICAgICogRGVjb2RlciBvZiBkYXRhIHN0b3JlZCBhcyBcIkhUTUxFbmNvZGVyXCIgKGV4OiBtYXRoKGthdGV4KSlcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjb250ZW50cyBIVE1MIG9yIFRleHQgc3RyaW5nXHJcbiAgICAgKiBAcmV0dXJucyB7U3RyaW5nfVxyXG4gICAgICovXHJcbiAgICBIVE1MRGVjb2RlcjogZnVuY3Rpb24gKGNvbnRlbnRzKSB7XHJcbiAgICAgICAgY29uc3QgZWMgPSB7JyRsdDsnOsKgJzwnLMKgJyRndDsnOsKgJz4nfTtcclxuICAgICAgICByZXR1cm4gY29udGVudHMucmVwbGFjZSgvXFwkbHQ7fFxcJGd0Oy9nLCBmdW5jdGlvbiAobSkge1xyXG4gICAgICAgICAgICByZXR1cm4gKHR5cGVvZiBlY1ttXSA9PT0gJ3N0cmluZycpID8gZWNbbV0gOiBtO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBydW4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KVxyXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iaiBPYmplY3RcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgb2JqLmtleVxyXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIGhhc093bjogZnVuY3Rpb24gKG9iaiwga2V5KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hhc093bi5jYWxsKG9iaiwga2V5KTtcclxuICAgIH0sXHJcbiAgICBfaGFzT3duOiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlcHJlY2F0ZWRcclxuICAgICAqIEBkZXNjcmlwdGlvbiBHZXQgdGhlIHRoZSB0YWcgcGF0aCBvZiB0aGUgYXJndW1lbnRzIHZhbHVlXHJcbiAgICAgKiBJZiBub3QgZm91bmQsIHJldHVybiB0aGUgZmlyc3QgZm91bmQgdmFsdWVcclxuICAgICAqIEBwYXJhbSB7QXJyYXl9IG5hbWVBcnJheSBGaWxlIG5hbWUgYXJyYXlcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBleHRlbnNpb24ganMsIGNzc1xyXG4gICAgICogQHJldHVybnMge1N0cmluZ31cclxuICAgICAqL1xyXG4gICAgZ2V0SW5jbHVkZVBhdGg6IGZ1bmN0aW9uIChuYW1lQXJyYXksIGV4dGVuc2lvbikge1xyXG4gICAgICAgIGxldCBwYXRoID0gJyc7XHJcbiAgICAgICAgY29uc3QgcGF0aExpc3QgPSBbXTtcclxuICAgICAgICBjb25zdCB0YWdOYW1lID0gZXh0ZW5zaW9uID09PSAnanMnID8gJ3NjcmlwdCcgOiAnbGluayc7XHJcbiAgICAgICAgY29uc3Qgc3JjID0gZXh0ZW5zaW9uID09PSAnanMnID8gJ3NyYycgOiAnaHJlZic7XHJcbiAgICAgICAgXHJcbiAgICAgICAgbGV0IGZpbGVOYW1lID0gJyg/Oic7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IG5hbWVBcnJheS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICBmaWxlTmFtZSArPSBuYW1lQXJyYXlbaV0gKyAoaSA8IGxlbiAtIDEgPyAnfCcgOiAnKScpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcmVnRXhwID0gbmV3IHRoaXMuX3cuUmVnRXhwKCcoXnwuKltcXFxcL10pJyArIGZpbGVOYW1lICsgJyhcXFxcLlteXFxcXC9dKyk/XFwuJyArIGV4dGVuc2lvbiArICcoPzpcXFxcPy4qfDsuKik/JCcsICdpJyk7XHJcbiAgICAgICAgY29uc3QgZXh0UmVnRXhwID0gbmV3IHRoaXMuX3cuUmVnRXhwKCcuK1xcXFwuJyArIGV4dGVuc2lvbiArICcoPzpcXFxcPy4qfDsuKik/JCcsICdpJyk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgIGZvciAobGV0IGMgPSB0aGlzLl9kLmdldEVsZW1lbnRzQnlUYWdOYW1lKHRhZ05hbWUpLCBpID0gMDsgaSA8IGMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGV4dFJlZ0V4cC50ZXN0KGNbaV1bc3JjXSkpIHtcclxuICAgICAgICAgICAgICAgIHBhdGhMaXN0LnB1c2goY1tpXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGF0aExpc3QubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IGVkaXRvclRhZyA9IHBhdGhMaXN0W2ldW3NyY10ubWF0Y2gocmVnRXhwKTtcclxuICAgICAgICAgICAgaWYgKGVkaXRvclRhZykge1xyXG4gICAgICAgICAgICAgICAgcGF0aCA9IGVkaXRvclRhZ1swXTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGF0aCA9PT0gJycpIHBhdGggPSBwYXRoTGlzdC5sZW5ndGggPiAwID8gcGF0aExpc3RbMF1bc3JjXSA6ICcnO1xyXG5cclxuICAgICAgICAtMSA9PT0gcGF0aC5pbmRleE9mKCc6LycpICYmICcvLycgIT09IHBhdGguc2xpY2UoMCwgMikgJiYgKHBhdGggPSAwID09PSBwYXRoLmluZGV4T2YoJy8nKSA/IGxvY2F0aW9uLmhyZWYubWF0Y2goL14uKj86XFwvXFwvW15cXC9dKi8pWzBdICsgcGF0aCA6IGxvY2F0aW9uLmhyZWYubWF0Y2goL15bXlxcP10qXFwvKD86KS8pWzBdICsgcGF0aCk7XHJcblxyXG4gICAgICAgIGlmICghcGF0aCkgdGhyb3cgJ1tTVU5FRElUT1IudXRpbC5nZXRJbmNsdWRlUGF0aC5mYWlsXSBUaGUgU1VORURJVE9SIGluc3RhbGxhdGlvbiBwYXRoIGNvdWxkIG5vdCBiZSBhdXRvbWF0aWNhbGx5IGRldGVjdGVkLiAobmFtZTogKycgKyBuYW1lICsgJywgZXh0ZW5zaW9uOiAnICsgZXh0ZW5zaW9uICsgJyknO1xyXG5cclxuICAgICAgICByZXR1cm4gcGF0aDtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVwcmVjYXRlZFxyXG4gICAgICogQGRlc2NyaXB0aW9uIFJldHVybnMgdGhlIENTUyB0ZXh0IHRoYXQgaGFzIGJlZW4gYXBwbGllZCB0byB0aGUgY3VycmVudCBwYWdlLlxyXG4gICAgICogQHBhcmFtIHtEb2N1bWVudHxudWxsfSBkb2MgVG8gZ2V0IHRoZSBDU1MgdGV4dCBvZiBhbiBkb2N1bWVudChjb3JlLl93ZCkuIElmIG51bGwgZ2V0IHRoZSBjdXJyZW50IGRvY3VtZW50LlxyXG4gICAgICogQHJldHVybnMge1N0cmluZ30gU3R5bGVzIHN0cmluZ1xyXG4gICAgICovXHJcbiAgICBnZXRQYWdlU3R5bGU6IGZ1bmN0aW9uIChkb2MpIHtcclxuICAgICAgICBsZXQgY3NzVGV4dCA9ICcnO1xyXG4gICAgICAgIGNvbnN0IHNoZWV0cyA9IChkb2MgfHwgdGhpcy5fZCkuc3R5bGVTaGVldHM7XHJcbiAgICAgICAgXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHNoZWV0cy5sZW5ndGgsIHJ1bGVzOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHJ1bGVzID0gc2hlZXRzW2ldLmNzc1J1bGVzO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgZm9yIChsZXQgYyA9IDAsIGNMZW4gPSBydWxlcy5sZW5ndGg7IGMgPCBjTGVuOyBjKyspIHtcclxuICAgICAgICAgICAgICAgIGNzc1RleHQgKz0gcnVsZXNbY10uY3NzVGV4dDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGNzc1RleHQ7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIEdldCB0aGUgYXJndW1lbnQgaWZyYW1lJ3MgZG9jdW1lbnQgb2JqZWN0XHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGlmcmFtZSBJZnJhbWUgZWxlbWVudCAoY29udGV4dC5lbGVtZW50Lnd5c2l3eWdGcmFtZSlcclxuICAgICAqIEByZXR1cm5zIHtEb2N1bWVudH1cclxuICAgICAqL1xyXG4gICAgZ2V0SWZyYW1lRG9jdW1lbnQ6IGZ1bmN0aW9uIChpZnJhbWUpIHtcclxuICAgICAgICBsZXQgd0RvY3VtZW50ID0gaWZyYW1lLmNvbnRlbnRXaW5kb3cgfHwgaWZyYW1lLmNvbnRlbnREb2N1bWVudDtcclxuICAgICAgICBpZiAod0RvY3VtZW50LmRvY3VtZW50KSB3RG9jdW1lbnQgPSB3RG9jdW1lbnQuZG9jdW1lbnQ7XHJcbiAgICAgICAgcmV0dXJuIHdEb2N1bWVudDtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gR2V0IGF0dHJpYnV0ZXMgb2YgYXJndW1lbnQgZWxlbWVudCB0byBzdHJpbmcgKCdjbGFzcz1cIi0tLVwiIG5hbWU9XCItLS1cIiAnKVxyXG4gICAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IEVsZW1lbnQgb2JqZWN0XHJcbiAgICAgKiBAcGFyYW0ge0FycmF5fG51bGx9IGV4Y2VwdEF0dHJzIEFycmF5IG9mIGF0dHJpYnV0ZSBuYW1lcyB0byBleGNsdWRlIGZyb20gdGhlIHJlc3VsdFxyXG4gICAgICogQHJldHVybnMge1N0cmluZ31cclxuICAgICAqL1xyXG4gICAgZ2V0QXR0cmlidXRlc1RvU3RyaW5nOiBmdW5jdGlvbiAoZWxlbWVudCwgZXhjZXB0QXR0cnMpIHtcclxuICAgICAgICBpZiAoIWVsZW1lbnQuYXR0cmlidXRlcykgcmV0dXJuICcnO1xyXG5cclxuICAgICAgICBjb25zdCBhdHRycyA9IGVsZW1lbnQuYXR0cmlidXRlcztcclxuICAgICAgICBsZXQgYXR0clN0cmluZyA9ICcnO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gYXR0cnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGV4Y2VwdEF0dHJzICYmIGV4Y2VwdEF0dHJzLmluZGV4T2YoYXR0cnNbaV0ubmFtZSkgPiAtMSkgY29udGludWU7XHJcbiAgICAgICAgICAgIGF0dHJTdHJpbmcgKz0gYXR0cnNbaV0ubmFtZSArICc9XCInICsgYXR0cnNbaV0udmFsdWUgKyAnXCIgJztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBhdHRyU3RyaW5nO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbkdldHMgR2V0IHRoZSBsZW5ndGggaW4gYnl0ZXMgb2YgYSBzdHJpbmcuXHJcbiAgICAgKiByZWZlcmVuY2luZyBjb2RlOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9zaGFhbjE5NzQvbXlyZGluL2Jsb2IvbWFzdGVyL2V4cHJlc3Npb25zL3N0cmluZy5qcyNMMTFcIlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQgU3RyaW5nIHRleHRcclxuICAgICAqIEByZXR1cm5zIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIGdldEJ5dGVMZW5ndGg6IGZ1bmN0aW9uKHRleHQpIHtcclxuICAgICAgICBjb25zdCBlbmNvZGVyID0gdGhpcy5fdy5lbmNvZGVVUklDb21wb25lbnQ7XHJcbiAgICAgICAgbGV0IGNyLCBjbDtcclxuICAgICAgICBpZiAodGhpcy5pc0lFX0VkZ2UpIHtcclxuICAgICAgICAgICAgY2wgPSB0aGlzLl93LnVuZXNjYXBlKGVuY29kZXIodGV4dC50b1N0cmluZygpKSkubGVuZ3RoO1xyXG4gICAgICAgICAgICBjciA9IDA7XHJcblxyXG4gICAgICAgICAgICBpZiAoZW5jb2Rlcih0ZXh0LnRvU3RyaW5nKCkpLm1hdGNoKC8oJTBBfCUwRCkvZ2kpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBjciA9IGVuY29kZXIodGV4dC50b1N0cmluZygpKS5tYXRjaCgvKCUwQXwlMEQpL2dpKS5sZW5ndGg7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBjbCArIGNyO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNsID0gKG5ldyB0aGlzLl93LlRleHRFbmNvZGVyKCd1dGYtOCcpLmVuY29kZSh0ZXh0LnRvU3RyaW5nKCkpKS5sZW5ndGg7XHJcbiAgICAgICAgICAgIGNyID0gMDtcclxuXHJcbiAgICAgICAgICAgIGlmIChlbmNvZGVyKHRleHQudG9TdHJpbmcoKSkubWF0Y2goLyglMEF8JTBEKS9naSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIGNyID0gZW5jb2Rlcih0ZXh0LnRvU3RyaW5nKCkpLm1hdGNoKC8oJTBBfCUwRCkvZ2kpLmxlbmd0aDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGNsICsgY3I7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBJdCBpcyBqdWRnZWQgd2hldGhlciBpdCBpcyB0aGUgZWRpdCByZWdpb24gdG9wIGRpdiBlbGVtZW50IG9yIGlmcmFtZSdzIGJvZHkgdGFnLlxyXG4gICAgICogQHBhcmFtIHtOb2RlfSBlbGVtZW50IFRoZSBub2RlIHRvIGNoZWNrXHJcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgaXNXeXNpd3lnRGl2OiBmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgIHJldHVybiBlbGVtZW50ICYmIGVsZW1lbnQubm9kZVR5cGUgPT09IDEgJiYgKHRoaXMuaGFzQ2xhc3MoZWxlbWVudCwgJ3NlLXdyYXBwZXItd3lzaXd5ZycpIHx8IC9eQk9EWSQvaS50ZXN0KGVsZW1lbnQubm9kZU5hbWUpKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gSXQgaXMganVkZ2VkIHdoZXRoZXIgaXQgaXMgdGhlIGNvbnRlbnRlZGl0YWJsZSBwcm9wZXJ0eSBpcyBmYWxzZS5cclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gZWxlbWVudCBUaGUgbm9kZSB0byBjaGVja1xyXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIGlzTm9uRWRpdGFibGU6IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQgJiYgZWxlbWVudC5ub2RlVHlwZSA9PT0gMSAmJiBlbGVtZW50LmdldEF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJykgPT09ICdmYWxzZSc7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIEl0IGlzIGp1ZGdlZCB3aGV0aGVyIGl0IGlzIGEgbm9kZSByZWxhdGVkIHRvIHRoZSB0ZXh0IHN0eWxlLlxyXG4gICAgICogKHN0cm9uZ3xzcGFufGZvbnR8Ynx2YXJ8aXxlbXx1fGluc3xzfHN0cmlrZXxkZWx8c3VifHN1cHxtYXJrfGF8bGFiZWx8Y29kZSlcclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gZWxlbWVudCBUaGUgbm9kZSB0byBjaGVja1xyXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIGlzVGV4dFN0eWxlRWxlbWVudDogZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICByZXR1cm4gZWxlbWVudCAmJiBlbGVtZW50Lm5vZGVUeXBlICE9PSAzICYmIC9eKHN0cm9uZ3xzcGFufGZvbnR8Ynx2YXJ8aXxlbXx1fGluc3xzfHN0cmlrZXxkZWx8c3VifHN1cHxtYXJrfGF8bGFiZWx8Y29kZSkkL2kudGVzdChlbGVtZW50Lm5vZGVOYW1lKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gSXQgaXMganVkZ2VkIHdoZXRoZXIgaXQgaXMgdGhlIGZvcm1hdCBlbGVtZW50IChQLCBESVYsIEhbMS02XSwgUFJFLCBMSSB8IGNsYXNzPVwiX19zZV9fZm9ybWF0X19yZXBsYWNlX3h4eFwiKVxyXG4gICAgICogRm9ybWF0IGVsZW1lbnQgYWxzbyBjb250YWluIFwiZnJlZSBmb3JtYXQgRWxlbWVudFwiXHJcbiAgICAgKiBAcGFyYW0ge05vZGV9IGVsZW1lbnQgVGhlIG5vZGUgdG8gY2hlY2tcclxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxyXG4gICAgICovXHJcbiAgICBpc0Zvcm1hdEVsZW1lbnQ6IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQgJiYgZWxlbWVudC5ub2RlVHlwZSA9PT0gMSAmJiAoL14oUHxESVZ8SFsxLTZdfFBSRXxMSXxUSHxURCkkL2kudGVzdChlbGVtZW50Lm5vZGVOYW1lKSB8fCB0aGlzLmhhc0NsYXNzKGVsZW1lbnQsICcoXFxcXHN8XilfX3NlX19mb3JtYXRfX3JlcGxhY2VfLisoXFxcXHN8JCl8KFxcXFxzfF4pX19zZV9fZm9ybWF0X19mcmVlXy4rKFxcXFxzfCQpJykpICYmICF0aGlzLmlzQ29tcG9uZW50KGVsZW1lbnQpICYmICF0aGlzLmlzV3lzaXd5Z0RpdihlbGVtZW50KTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gSXQgaXMganVkZ2VkIHdoZXRoZXIgaXQgaXMgdGhlIHJhbmdlIGZvcm1hdCBlbGVtZW50LiAoQkxPQ0tRVU9URSwgT0wsIFVMLCBGSUdDQVBUSU9OLCBUQUJMRSwgVEhFQUQsIFRCT0RZLCBUUiwgVEgsIFREIHwgY2xhc3M9XCJfX3NlX19mb3JtYXRfX3JhbmdlX3h4eFwiKVxyXG4gICAgICogUmFuZ2UgZm9ybWF0IGVsZW1lbnQgaXMgd3JhcCB0aGUgXCJmb3JtYXQgZWxlbWVudFwiIGFuZCBcImNvbXBvbmVudFwiXHJcbiAgICAgKiBAcGFyYW0ge05vZGV9IGVsZW1lbnQgVGhlIG5vZGUgdG8gY2hlY2tcclxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxyXG4gICAgICovXHJcbiAgICBpc1JhbmdlRm9ybWF0RWxlbWVudDogZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICByZXR1cm4gZWxlbWVudCAmJiBlbGVtZW50Lm5vZGVUeXBlID09PSAxICYmICgvXihCTE9DS1FVT1RFfE9MfFVMfEZJR0NBUFRJT058VEFCTEV8VEhFQUR8VEJPRFl8VFJ8VEh8VEQpJC9pLnRlc3QoZWxlbWVudC5ub2RlTmFtZSkgfHwgdGhpcy5oYXNDbGFzcyhlbGVtZW50LCAnKFxcXFxzfF4pX19zZV9fZm9ybWF0X19yYW5nZV8uKyhcXFxcc3wkKScpKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gSXQgaXMganVkZ2VkIHdoZXRoZXIgaXQgaXMgdGhlIGNsb3N1cmUgcmFuZ2UgZm9ybWF0IGVsZW1lbnQuIChUSCwgVEQgfCBjbGFzcz1cIl9fc2VfX2Zvcm1hdF9fcmFuZ2VfX2Nsb3N1cmVfeHh4XCIpXHJcbiAgICAgKiBDbG9zdXJlIHJhbmdlIGZvcm1hdCBlbGVtZW50cyBpcyBpbmNsdWRlZCBpbiB0aGUgcmFuZ2UgZm9ybWF0IGVsZW1lbnQuXHJcbiAgICAgKiAgLSBDbG9zdXJlIHJhbmdlIGZvcm1hdCBlbGVtZW50IGlzIHdyYXAgdGhlIFwiZm9ybWF0IGVsZW1lbnRcIiBhbmQgXCJjb21wb25lbnRcIlxyXG4gICAgICog4oC7IFlvdSBjYW5ub3QgZXhpdCB0aGlzIGZvcm1hdCB3aXRoIHRoZSBFbnRlciBrZXkgb3IgQmFja3NwYWNlIGtleS5cclxuICAgICAqIOKAuyBVc2UgaXQgb25seSBpbiBzcGVjaWFsIGNhc2VzLiAoW2V4XSBmb3JtYXQgb2YgdGFibGUgY2VsbHMpXHJcbiAgICAgKiBAcGFyYW0ge05vZGV9IGVsZW1lbnQgVGhlIG5vZGUgdG8gY2hlY2tcclxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxyXG4gICAgICovXHJcbiAgICBpc0Nsb3N1cmVSYW5nZUZvcm1hdEVsZW1lbnQ6IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQgJiYgZWxlbWVudC5ub2RlVHlwZSA9PT0gMSAmJiAoL14oVEh8VEQpJC9pLnRlc3QoZWxlbWVudC5ub2RlTmFtZSkgfHwgdGhpcy5oYXNDbGFzcyhlbGVtZW50LCAnKFxcXFxzfF4pX19zZV9fZm9ybWF0X19yYW5nZV9fY2xvc3VyZV8uKyhcXFxcc3wkKScpKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gSXQgaXMganVkZ2VkIHdoZXRoZXIgaXQgaXMgdGhlIGZyZWUgZm9ybWF0IGVsZW1lbnQuIChQUkUgfCBjbGFzcz1cIl9fc2VfX2Zvcm1hdF9fZnJlZV94eHhcIilcclxuICAgICAqIEZyZWUgZm9ybWF0IGVsZW1lbnRzIGlzIGluY2x1ZGVkIGluIHRoZSBmb3JtYXQgZWxlbWVudC5cclxuICAgICAqIEZyZWUgZm9ybWF0IGVsZW1lbnRzJ3MgbGluZSBicmVhayBpcyBcIkJSXCIgdGFnLlxyXG4gICAgICog4oC7IEVudGVyaW5nIHRoZSBFbnRlciBrZXkgaW4gdGhlIHNwYWNlIG9uIHRoZSBsYXN0IGxpbmUgZW5kcyBcIkZyZWUgRm9ybWF0XCIgYW5kIGFwcGVuZHMgXCJGb3JtYXRcIi5cclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gZWxlbWVudCBUaGUgbm9kZSB0byBjaGVja1xyXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIGlzRnJlZUZvcm1hdEVsZW1lbnQ6IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQgJiYgZWxlbWVudC5ub2RlVHlwZSA9PT0gMSAmJiAoL15QUkUkL2kudGVzdChlbGVtZW50Lm5vZGVOYW1lKSB8fCB0aGlzLmhhc0NsYXNzKGVsZW1lbnQsICcoXFxcXHN8XilfX3NlX19mb3JtYXRfX2ZyZWVfLisoXFxcXHN8JCknKSkgJiYgIXRoaXMuaXNDb21wb25lbnQoZWxlbWVudCkgJiYgIXRoaXMuaXNXeXNpd3lnRGl2KGVsZW1lbnQpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBJdCBpcyBqdWRnZWQgd2hldGhlciBpdCBpcyB0aGUgY2xvc3VyZSBmcmVlIGZvcm1hdCBlbGVtZW50LiAoY2xhc3M9XCJfX3NlX19mb3JtYXRfX2ZyZWVfX2Nsb3N1cmVfeHh4XCIpXHJcbiAgICAgKiBDbG9zdXJlIGZyZWUgZm9ybWF0IGVsZW1lbnRzIGlzIGluY2x1ZGVkIGluIHRoZSBmcmVlIGZvcm1hdCBlbGVtZW50LlxyXG4gICAgICogIC0gQ2xvc3VyZSBmcmVlIGZvcm1hdCBlbGVtZW50cydzIGxpbmUgYnJlYWsgaXMgXCJCUlwiIHRhZy5cclxuICAgICAqIOKAuyBZb3UgY2Fubm90IGV4aXQgdGhpcyBmb3JtYXQgd2l0aCB0aGUgRW50ZXIga2V5IG9yIEJhY2tzcGFjZSBrZXkuXHJcbiAgICAgKiDigLsgVXNlIGl0IG9ubHkgaW4gc3BlY2lhbCBjYXNlcy4gKFtleF0gZm9ybWF0IG9mIHRhYmxlIGNlbGxzKVxyXG4gICAgICogQHBhcmFtIHtOb2RlfSBlbGVtZW50IFRoZSBub2RlIHRvIGNoZWNrXHJcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgaXNDbG9zdXJlRnJlZUZvcm1hdEVsZW1lbnQ6IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQgJiYgZWxlbWVudC5ub2RlVHlwZSA9PT0gMSAmJiB0aGlzLmhhc0NsYXNzKGVsZW1lbnQsICcoXFxcXHN8XilfX3NlX19mb3JtYXRfX2ZyZWVfX2Nsb3N1cmVfLisoXFxcXHN8JCknKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gSXQgaXMganVkZ2VkIHdoZXRoZXIgaXQgaXMgdGhlIGNvbXBvbmVudCBbaW1nLCBpZnJhbWUsIHZpZGVvLCBhdWRpb10gY292ZXIoY2xhc3M9XCJzZS1jb21wb25lbnRcIikgYW5kIHRhYmxlLCBoclxyXG4gICAgICogQHBhcmFtIHtOb2RlfSBlbGVtZW50IFRoZSBub2RlIHRvIGNoZWNrXHJcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgaXNDb21wb25lbnQ6IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQgJiYgKC9zZS1jb21wb25lbnQvLnRlc3QoZWxlbWVudC5jbGFzc05hbWUpIHx8IC9eKFRBQkxFfEhSKSQvLnRlc3QoZWxlbWVudC5ub2RlTmFtZSkpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBJdCBpcyBqdWRnZWQgd2hldGhlciBpdCBpcyB0aGUgY29tcG9uZW50IFtpbWcsIGlmcmFtZV0gY292ZXIoY2xhc3M9XCJzZS1jb21wb25lbnRcIilcclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gZWxlbWVudCBUaGUgbm9kZSB0byBjaGVja1xyXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIGlzTWVkaWFDb21wb25lbnQ6IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQgJiYgL3NlLWNvbXBvbmVudC8udGVzdChlbGVtZW50LmNsYXNzTmFtZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIEl0IGlzIGp1ZGdlZCB3aGV0aGVyIGl0IGlzIHRoZSBub3QgY2hlY2tpbmcgbm9kZS4gKGNsYXNzPVwia2F0ZXhcIiwgXCJfX3NlX190YWdcIilcclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gZWxlbWVudCBUaGUgbm9kZSB0byBjaGVja1xyXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIGlzTm90Q2hlY2tpbmdOb2RlOiBmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgIHJldHVybiBlbGVtZW50ICYmIC9rYXRleHxfX3NlX190YWcvLnRlc3QoZWxlbWVudC5jbGFzc05hbWUpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBJZiBhIHBhcmVudCBub2RlIHRoYXQgY29udGFpbnMgYW4gYXJndW1lbnQgbm9kZSBmaW5kcyBhIGZvcm1hdCBub2RlICh1dGlsLmlzRm9ybWF0RWxlbWVudCksIGl0IHJldHVybnMgdGhhdCBub2RlLlxyXG4gICAgICogQHBhcmFtIHtOb2RlfSBlbGVtZW50IFJlZmVyZW5jZSBub2RlLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxudWxsfSB2YWxpZGF0aW9uIEFkZGl0aW9uYWwgdmFsaWRhdGlvbiBmdW5jdGlvbi5cclxuICAgICAqIEByZXR1cm5zIHtFbGVtZW50fG51bGx9XHJcbiAgICAgKi9cclxuICAgIGdldEZvcm1hdEVsZW1lbnQ6IGZ1bmN0aW9uIChlbGVtZW50LCB2YWxpZGF0aW9uKSB7XHJcbiAgICAgICAgaWYgKCFlbGVtZW50KSByZXR1cm4gbnVsbDtcclxuICAgICAgICBpZiAoIXZhbGlkYXRpb24pIHtcclxuICAgICAgICAgICAgdmFsaWRhdGlvbiA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB3aGlsZSAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pc1d5c2l3eWdEaXYoZWxlbWVudCkpIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pc1JhbmdlRm9ybWF0RWxlbWVudChlbGVtZW50KSkgZWxlbWVudC5maXJzdEVsZW1lbnRDaGlsZDtcclxuICAgICAgICAgICAgaWYgKHRoaXMuaXNGb3JtYXRFbGVtZW50KGVsZW1lbnQpICYmIHZhbGlkYXRpb24oZWxlbWVudCkpIHJldHVybiBlbGVtZW50O1xyXG5cclxuICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50Tm9kZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIElmIGEgcGFyZW50IG5vZGUgdGhhdCBjb250YWlucyBhbiBhcmd1bWVudCBub2RlIGZpbmRzIGEgZm9ybWF0IG5vZGUgKHV0aWwuaXNSYW5nZUZvcm1hdEVsZW1lbnQpLCBpdCByZXR1cm5zIHRoYXQgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gZWxlbWVudCBSZWZlcmVuY2Ugbm9kZS5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258bnVsbH0gdmFsaWRhdGlvbiBBZGRpdGlvbmFsIHZhbGlkYXRpb24gZnVuY3Rpb24uXHJcbiAgICAgKiBAcmV0dXJucyB7RWxlbWVudHxudWxsfVxyXG4gICAgICovXHJcbiAgICBnZXRSYW5nZUZvcm1hdEVsZW1lbnQ6IGZ1bmN0aW9uIChlbGVtZW50LCB2YWxpZGF0aW9uKSB7XHJcbiAgICAgICAgaWYgKCFlbGVtZW50KSByZXR1cm4gbnVsbDtcclxuICAgICAgICBpZiAoIXZhbGlkYXRpb24pIHtcclxuICAgICAgICAgICAgdmFsaWRhdGlvbiA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB3aGlsZSAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pc1d5c2l3eWdEaXYoZWxlbWVudCkpIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pc1JhbmdlRm9ybWF0RWxlbWVudChlbGVtZW50KSAmJiAhL14oVEhFQUR8VEJPRFl8VFIpJC9pLnRlc3QoZWxlbWVudC5ub2RlTmFtZSkgJiYgdmFsaWRhdGlvbihlbGVtZW50KSkgcmV0dXJuIGVsZW1lbnQ7XHJcbiAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gSWYgYSBwYXJlbnQgbm9kZSB0aGF0IGNvbnRhaW5zIGFuIGFyZ3VtZW50IG5vZGUgZmluZHMgYSBmcmVlIGZvcm1hdCBub2RlICh1dGlsLmlzRnJlZUZvcm1hdEVsZW1lbnQpLCBpdCByZXR1cm5zIHRoYXQgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gZWxlbWVudCBSZWZlcmVuY2Ugbm9kZS5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258bnVsbH0gdmFsaWRhdGlvbiBBZGRpdGlvbmFsIHZhbGlkYXRpb24gZnVuY3Rpb24uXHJcbiAgICAgKiBAcmV0dXJucyB7RWxlbWVudHxudWxsfVxyXG4gICAgICovXHJcbiAgICBnZXRGcmVlRm9ybWF0RWxlbWVudDogZnVuY3Rpb24gKGVsZW1lbnQsIHZhbGlkYXRpb24pIHtcclxuICAgICAgICBpZiAoIWVsZW1lbnQpIHJldHVybiBudWxsO1xyXG4gICAgICAgIGlmICghdmFsaWRhdGlvbikge1xyXG4gICAgICAgICAgICB2YWxpZGF0aW9uID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdHJ1ZTsgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHdoaWxlIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzV3lzaXd5Z0RpdihlbGVtZW50KSkgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzRnJlZUZvcm1hdEVsZW1lbnQoZWxlbWVudCkgJiYgdmFsaWRhdGlvbihlbGVtZW50KSkgcmV0dXJuIGVsZW1lbnQ7XHJcblxyXG4gICAgICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gSWYgYSBwYXJlbnQgbm9kZSB0aGF0IGNvbnRhaW5zIGFuIGFyZ3VtZW50IG5vZGUgZmluZHMgYSBjbG9zdXJlIGZyZWUgZm9ybWF0IG5vZGUgKHV0aWwuaXNDbG9zdXJlRnJlZUZvcm1hdEVsZW1lbnQpLCBpdCByZXR1cm5zIHRoYXQgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gZWxlbWVudCBSZWZlcmVuY2Ugbm9kZS5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258bnVsbH0gdmFsaWRhdGlvbiBBZGRpdGlvbmFsIHZhbGlkYXRpb24gZnVuY3Rpb24uXHJcbiAgICAgKiBAcmV0dXJucyB7RWxlbWVudHxudWxsfVxyXG4gICAgICovXHJcbiAgICBnZXRDbG9zdXJlRnJlZUZvcm1hdEVsZW1lbnQ6IGZ1bmN0aW9uIChlbGVtZW50LCB2YWxpZGF0aW9uKSB7XHJcbiAgICAgICAgaWYgKCFlbGVtZW50KSByZXR1cm4gbnVsbDtcclxuICAgICAgICBpZiAoIXZhbGlkYXRpb24pIHtcclxuICAgICAgICAgICAgdmFsaWRhdGlvbiA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB3aGlsZSAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pc1d5c2l3eWdEaXYoZWxlbWVudCkpIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pc0Nsb3N1cmVGcmVlRm9ybWF0RWxlbWVudChlbGVtZW50KSAmJiB2YWxpZGF0aW9uKGVsZW1lbnQpKSByZXR1cm4gZWxlbWVudDtcclxuXHJcbiAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBBZGQgc3R5bGUgYW5kIGNsYXNzTmFtZSBvZiBjb3B5RWwgdG8gb3JpZ2luRWxcclxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gb3JpZ2luRWwgT3JpZ2luIGVsZW1lbnRcclxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gY29weUVsIEVsZW1lbnQgdG8gY29weVxyXG4gICAgICovXHJcbiAgICBjb3B5VGFnQXR0cmlidXRlczogZnVuY3Rpb24gKG9yaWdpbkVsLCBjb3B5RWwpIHtcclxuICAgICAgICBpZiAoY29weUVsLnN0eWxlLmNzc1RleHQpIHtcclxuICAgICAgICAgICAgb3JpZ2luRWwuc3R5bGUuY3NzVGV4dCArPSBjb3B5RWwuc3R5bGUuY3NzVGV4dDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGNsYXNzZXMgPSBjb3B5RWwuY2xhc3NMaXN0O1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBjbGFzc2VzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYWRkQ2xhc3Mob3JpZ2luRWwsIGNsYXNzZXNbaV0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFvcmlnaW5FbC5zdHlsZS5jc3NUZXh0KSBvcmlnaW5FbC5yZW1vdmVBdHRyaWJ1dGUoJ3N0eWxlJyk7XHJcbiAgICAgICAgaWYgKCFvcmlnaW5FbC5jbGFzc05hbWUudHJpbSgpKSBvcmlnaW5FbC5yZW1vdmVBdHRyaWJ1dGUoJ2NsYXNzJyk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIENvcHkgYW5kIGFwcGx5IGF0dHJpYnV0ZXMgb2YgZm9ybWF0IHRhZyB0aGF0IHNob3VsZCBiZSBtYWludGFpbmVkLiAoc3R5bGUsIGNsYXNzKSBJZ25vcmUgXCJfX3NlX19mb3JtYXRfX1wiIGNsYXNzXHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IG9yaWdpbkVsIE9yaWdpbiBlbGVtZW50XHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGNvcHlFbCBFbGVtZW50IHRvIGNvcHlcclxuICAgICAqL1xyXG4gICAgY29weUZvcm1hdEF0dHJpYnV0ZXM6IGZ1bmN0aW9uIChvcmlnaW5FbCwgY29weUVsKSB7XHJcbiAgICAgICAgY29weUVsID0gY29weUVsLmNsb25lTm9kZShmYWxzZSk7XHJcbiAgICAgICAgY29weUVsLmNsYXNzTmFtZSA9IGNvcHlFbC5jbGFzc05hbWUucmVwbGFjZSgvKFxcc3xeKV9fc2VfX2Zvcm1hdF9fW15cXHNdKy9nLCAnJyk7XHJcbiAgICAgICAgdGhpcy5jb3B5VGFnQXR0cmlidXRlcyhvcmlnaW5FbCwgY29weUVsKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gR2V0IHRoZSBpdGVtIGZyb20gdGhlIGFycmF5IHRoYXQgbWF0Y2hlcyB0aGUgY29uZGl0aW9uLlxyXG4gICAgICogQHBhcmFtIHtBcnJheXxIVE1MQ29sbGVjdGlvbnxOb2RlTGlzdH0gYXJyYXkgQXJyYXkgdG8gZ2V0IGl0ZW1cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258bnVsbH0gdmFsaWRhdGlvbiBDb25kaXRpb25hbCBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBtdWx0aSBJZiB0cnVlLCByZXR1cm5zIGFsbCBpdGVtcyB0aGF0IG1lZXQgdGhlIGNyaXRlcmlhIG90aGVyd2lzZSwgcmV0dXJucyBhbiBlbXB0eSBhcnJheS5cclxuICAgICAqIElmIGZhbHNlLCByZXR1cm5zIG9ubHkgb25lIGl0ZW0gdGhhdCBtZWV0IHRoZSBjcml0ZXJpYSBvdGhlcndpc2UgcmV0dXJuIG51bGwuXHJcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8Tm9kZXxudWxsfVxyXG4gICAgICovXHJcbiAgICBnZXRBcnJheUl0ZW06IGZ1bmN0aW9uIChhcnJheSwgdmFsaWRhdGlvbiwgbXVsdGkpIHtcclxuICAgICAgICBpZiAoIWFycmF5IHx8IGFycmF5Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgICAgIHZhbGlkYXRpb24gPSB2YWxpZGF0aW9uIHx8IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH07XHJcbiAgICAgICAgY29uc3QgYXJyID0gW107XHJcbiAgICAgICAgXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGFycmF5Lmxlbmd0aCwgYTsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIGEgPSBhcnJheVtpXTtcclxuICAgICAgICAgICAgaWYgKHZhbGlkYXRpb24oYSkpIHtcclxuICAgICAgICAgICAgICAgIGlmICghbXVsdGkpIHJldHVybiBhO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBhcnIucHVzaChhKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuICFtdWx0aSA/IG51bGwgOiBhcnI7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIEdldCB0aGUgaW5kZXggb2YgdGhlIGFyZ3VtZW50IHZhbHVlIGluIHRoZSBlbGVtZW50IGFycmF5XHJcbiAgICAgKiBAcGFyYW0ge0FycmF5fEhUTUxDb2xsZWN0aW9ufE5vZGVMaXN0fSBhcnJheSBlbGVtZW50IGFycmF5XHJcbiAgICAgKiBAcGFyYW0ge05vZGV9IGVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gZmluZCBpbmRleFxyXG4gICAgICogQHJldHVybnMge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgZ2V0QXJyYXlJbmRleDogZnVuY3Rpb24gKGFycmF5LCBlbGVtZW50KSB7XHJcbiAgICAgICAgbGV0IGlkeCA9IC0xO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBhcnJheS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoYXJyYXlbaV0gPT09IGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgIGlkeCA9IGk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGlkeDtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gR2V0IHRoZSBuZXh0IGluZGV4IG9mIHRoZSBhcmd1bWVudCB2YWx1ZSBpbiB0aGUgZWxlbWVudCBhcnJheVxyXG4gICAgICogQHBhcmFtIHtBcnJheXxIVE1MQ29sbGVjdGlvbnxOb2RlTGlzdH0gYXJyYXkgZWxlbWVudCBhcnJheVxyXG4gICAgICogQHBhcmFtIHtOb2RlfSBpdGVtIFRoZSBlbGVtZW50IHRvIGZpbmQgaW5kZXhcclxuICAgICAqIEByZXR1cm5zIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIG5leHRJZHg6IGZ1bmN0aW9uIChhcnJheSwgaXRlbSkge1xyXG4gICAgICAgIGxldCBpZHggPSB0aGlzLmdldEFycmF5SW5kZXgoYXJyYXksIGl0ZW0pO1xyXG4gICAgICAgIGlmIChpZHggPT09IC0xKSByZXR1cm4gLTE7XHJcbiAgICAgICAgcmV0dXJuIGlkeCArIDE7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIEdldCB0aGUgcHJldmlvdXMgaW5kZXggb2YgdGhlIGFyZ3VtZW50IHZhbHVlIGluIHRoZSBlbGVtZW50IGFycmF5XHJcbiAgICAgKiBAcGFyYW0ge0FycmF5fEhUTUxDb2xsZWN0aW9ufE5vZGVMaXN0fSBhcnJheSBFbGVtZW50IGFycmF5XHJcbiAgICAgKiBAcGFyYW0ge05vZGV9IGl0ZW0gVGhlIGVsZW1lbnQgdG8gZmluZCBpbmRleFxyXG4gICAgICogQHJldHVybnMge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgcHJldklkeDogZnVuY3Rpb24gKGFycmF5LCBpdGVtKSB7XHJcbiAgICAgICAgbGV0IGlkeCA9IHRoaXMuZ2V0QXJyYXlJbmRleChhcnJheSwgaXRlbSk7XHJcbiAgICAgICAgaWYgKGlkeCA9PT0gLTEpIHJldHVybiAtMTtcclxuICAgICAgICByZXR1cm4gaWR4IC0gMTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gUmV0dXJucyB0aGUgaW5kZXggY29tcGFyZWQgdG8gb3RoZXIgc2libGluZyBub2Rlcy5cclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBUaGUgTm9kZSB0byBmaW5kIGluZGV4XHJcbiAgICAgKiBAcmV0dXJucyB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBnZXRQb3NpdGlvbkluZGV4OiBmdW5jdGlvbiAobm9kZSkge1xyXG4gICAgICAgIGxldCBpZHggPSAwO1xyXG4gICAgICAgIHdoaWxlICgobm9kZSA9IG5vZGUucHJldmlvdXNTaWJsaW5nKSkge1xyXG4gICAgICAgICAgICBpZHggKz0gMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGlkeDtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gUmV0dXJucyB0aGUgcG9zaXRpb24gb2YgdGhlIFwibm9kZVwiIGluIHRoZSBcInBhcmVudE5vZGVcIiBpbiBhIG51bWVyaWNhbCBhcnJheS5cclxuICAgICAqIGV4KSA8cD48c3Bhbj5hYTwvc3Bhbj48c3Bhbj5iYjwvc3Bhbj48L3A+IDogZ2V0Tm9kZVBhdGgobm9kZTogXCJiYlwiLCBwYXJlbnROb2RlOiBcIjxQPlwiKSAtPiBbMSwgMF1cclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBUaGUgTm9kZSB0byBmaW5kIHBvc2l0aW9uIHBhdGhcclxuICAgICAqIEBwYXJhbSB7Tm9kZXxudWxsfSBwYXJlbnROb2RlIFBhcmVudCBub2RlLiBJZiBudWxsLCB3eXNpd3lnIGRpdiBhcmVhXHJcbiAgICAgKiBAcGFyYW0ge09iamVjdHxudWxsfSBfbmV3T2Zmc2V0cyBJZiB5b3Ugc2VuZCBhbiBvYmplY3Qgb2YgdGhlIGZvcm0gXCJ7czogMCwgZTogMH1cIiwgdGhlIHRleHQgbm9kZXMgdGhhdCBhcmUgYXR0YWNoZWQgdG9nZXRoZXIgYXJlIG1lcmdlZCBpbnRvIG9uZSwgY2VudGVyZWQgb24gdGhlIFwibm9kZVwiIGFyZ3VtZW50LlxyXG4gICAgICogXCJfbmV3T2Zmc2V0cy5zXCIgc3RvcmVzIHRoZSBsZW5ndGggb2YgdGhlIGNvbWJpbmVkIGNoYXJhY3RlcnMgYWZ0ZXIgXCJub2RlXCIgYW5kIFwiX25ld09mZnNldHMuZVwiIHN0b3JlcyB0aGUgbGVuZ3RoIG9mIHRoZSBjb21iaW5lZCBjaGFyYWN0ZXJzIGJlZm9yZSBcIm5vZGVcIi5cclxuICAgICAqIERvIG5vdCB1c2UgdW5sZXNzIGFic29sdXRlbHkgbmVjZXNzYXJ5LlxyXG4gICAgICogQHJldHVybnMge0FycmF5fVxyXG4gICAgICovXHJcbiAgICBnZXROb2RlUGF0aDogZnVuY3Rpb24gKG5vZGUsIHBhcmVudE5vZGUsIF9uZXdPZmZzZXRzKSB7XHJcbiAgICAgICAgY29uc3QgcGF0aCA9IFtdO1xyXG4gICAgICAgIGxldCBmaW5kcyA9IHRydWU7XHJcblxyXG4gICAgICAgIHRoaXMuZ2V0UGFyZW50RWxlbWVudChub2RlLCBmdW5jdGlvbiAoZWwpIHtcclxuICAgICAgICAgICAgaWYgKGVsID09PSBwYXJlbnROb2RlKSBmaW5kcyA9IGZhbHNlO1xyXG4gICAgICAgICAgICBpZiAoZmluZHMgJiYgIXRoaXMuaXNXeXNpd3lnRGl2KGVsKSkge1xyXG4gICAgICAgICAgICAgICAgLy8gbWVyZ2UgdGV4dCBub2Rlc1xyXG4gICAgICAgICAgICAgICAgaWYgKF9uZXdPZmZzZXRzICYmIGVsLm5vZGVUeXBlID09PSAzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRlbXAgPSBudWxsLCB0ZW1wVGV4dCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgX25ld09mZnNldHMucyA9IF9uZXdPZmZzZXRzLmUgPSAwO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBsZXQgcHJldmlvdXMgPSBlbC5wcmV2aW91c1NpYmxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHByZXZpb3VzICYmIHByZXZpb3VzLm5vZGVUeXBlID09PSAzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBUZXh0ID0gcHJldmlvdXMudGV4dENvbnRlbnQucmVwbGFjZSh0aGlzLnplcm9XaWR0aFJlZ0V4cCwgJycpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbmV3T2Zmc2V0cy5zICs9IHRlbXBUZXh0Lmxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwudGV4dENvbnRlbnQgPSB0ZW1wVGV4dCArIGVsLnRleHRDb250ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wID0gcHJldmlvdXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzID0gcHJldmlvdXMucHJldmlvdXNTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUl0ZW0odGVtcCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBsZXQgbmV4dCA9IGVsLm5leHRTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChuZXh0ICYmIG5leHQubm9kZVR5cGUgPT09IDMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGVtcFRleHQgPSBuZXh0LnRleHRDb250ZW50LnJlcGxhY2UodGhpcy56ZXJvV2lkdGhSZWdFeHAsICcnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX25ld09mZnNldHMuZSArPSB0ZW1wVGV4dC5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsLnRleHRDb250ZW50ICs9IHRlbXBUZXh0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wID0gbmV4dDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dCA9IG5leHQubmV4dFNpYmxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlSXRlbSh0ZW1wKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gaW5kZXggcHVzaFxyXG4gICAgICAgICAgICAgICAgcGF0aC5wdXNoKGVsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcclxuICAgICAgICBcclxuICAgICAgICByZXR1cm4gcGF0aC5tYXAodGhpcy5nZXRQb3NpdGlvbkluZGV4KS5yZXZlcnNlKCk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFJldHVybnMgdGhlIG5vZGUgaW4gdGhlIGxvY2F0aW9uIG9mIHRoZSBwYXRoIGFycmF5IG9idGFpbmVkIGZyb20gXCJ1dGlsLmdldE5vZGVQYXRoXCIuXHJcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBvZmZzZXRzIFBvc2l0aW9uIGFycmF5LCBhcnJheSBvYnRhaW5lZCBmcm9tIFwidXRpbC5nZXROb2RlUGF0aFwiXHJcbiAgICAgKiBAcGFyYW0ge05vZGV9IHBhcmVudE5vZGUgQmFzZSBwYXJlbnQgZWxlbWVudFxyXG4gICAgICogQHJldHVybnMge05vZGV9XHJcbiAgICAgKi9cclxuICAgIGdldE5vZGVGcm9tUGF0aDogZnVuY3Rpb24gKG9mZnNldHMsIHBhcmVudE5vZGUpIHtcclxuICAgICAgICBsZXQgY3VycmVudCA9IHBhcmVudE5vZGU7XHJcbiAgICAgICAgbGV0IG5vZGVzO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gb2Zmc2V0cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICBub2RlcyA9IGN1cnJlbnQuY2hpbGROb2RlcztcclxuICAgICAgICAgICAgaWYgKG5vZGVzLmxlbmd0aCA9PT0gMCkgYnJlYWs7XHJcbiAgICAgICAgICAgIGlmIChub2Rlcy5sZW5ndGggPD0gb2Zmc2V0c1tpXSkge1xyXG4gICAgICAgICAgICAgICAgY3VycmVudCA9IG5vZGVzW25vZGVzLmxlbmd0aCAtIDFdO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY3VycmVudCA9IG5vZGVzW29mZnNldHNbaV1dO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gY3VycmVudDtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gQ29tcGFyZXMgdGhlIHN0eWxlIGFuZCBjbGFzcyBmb3IgZXF1YWwgdmFsdWVzLlxyXG4gICAgICogUmV0dXJucyB0cnVlIGlmIGJvdGggYXJlIHRleHQgbm9kZXMuXHJcbiAgICAgKiBAcGFyYW0ge05vZGV9IGEgTm9kZSB0byBjb21wYXJlXHJcbiAgICAgKiBAcGFyYW0ge05vZGV9IGIgTm9kZSB0byBjb21wYXJlXHJcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgaXNTYW1lQXR0cmlidXRlczogZnVuY3Rpb24gKGEsIGIpIHtcclxuICAgICAgICBpZiAoYS5ub2RlVHlwZSA9PT0gMyAmJiBiLm5vZGVUeXBlID09PSAzKSByZXR1cm4gdHJ1ZTtcclxuICAgICAgICBpZiAoYS5ub2RlVHlwZSA9PT0gMyB8fCBiLm5vZGVUeXBlID09PSAzKSByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgICAgIGNvbnN0IHN0eWxlX2EgPSBhLnN0eWxlO1xyXG4gICAgICAgIGNvbnN0IHN0eWxlX2IgPSBiLnN0eWxlO1xyXG4gICAgICAgIGxldCBjb21wU3R5bGUgPSAwO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gc3R5bGVfYS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoc3R5bGVfYVtzdHlsZV9hW2ldXSA9PT0gc3R5bGVfYltzdHlsZV9hW2ldXSkgY29tcFN0eWxlKys7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBjbGFzc19hID0gYS5jbGFzc0xpc3Q7XHJcbiAgICAgICAgY29uc3QgY2xhc3NfYiA9IGIuY2xhc3NMaXN0O1xyXG4gICAgICAgIGNvbnN0IHJlZyA9IHRoaXMuX3cuUmVnRXhwO1xyXG4gICAgICAgIGxldCBjb21wQ2xhc3MgPSAwO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gY2xhc3NfYS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICBpZiAocmVnKCcoXFxzfF4pJyArIGNsYXNzX2FbaV0gKyAnKFxcc3wkKScpLnRlc3QoY2xhc3NfYi52YWx1ZSkpIGNvbXBDbGFzcysrO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIChjb21wU3R5bGUgPT09IHN0eWxlX2IubGVuZ3RoICYmIGNvbXBTdHlsZSA9PT0gc3R5bGVfYS5sZW5ndGgpICYmIChjb21wQ2xhc3MgPT09IGNsYXNzX2IubGVuZ3RoICYmIGNvbXBDbGFzcyA9PT0gY2xhc3NfYS5sZW5ndGgpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBDaGVjayB0aGUgbm9kZSBpcyBhIGxpc3QgKG9sLCB1bClcclxuICAgICAqIEBwYXJhbSB7Tm9kZXxTdHJpbmd9IG5vZGUgVGhlIGVsZW1lbnQgb3IgZWxlbWVudCBuYW1lIHRvIGNoZWNrXHJcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgaXNMaXN0OiBmdW5jdGlvbiAobm9kZSkge1xyXG4gICAgICAgIHJldHVybiBub2RlICYmIC9eKE9MfFVMKSQvaS50ZXN0KHR5cGVvZiBub2RlID09PSAnc3RyaW5nJyA/IG5vZGUgOiBub2RlLm5vZGVOYW1lKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gQ2hlY2sgdGhlIG5vZGUgaXMgYSBsaXN0IGNlbGwgKGxpKVxyXG4gICAgICogQHBhcmFtIHtOb2RlfFN0cmluZ30gbm9kZSBUaGUgZWxlbWVudCBvciBlbGVtZW50IG5hbWUgdG8gY2hlY2tcclxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxyXG4gICAgICovXHJcbiAgICBpc0xpc3RDZWxsOiBmdW5jdGlvbiAobm9kZSkge1xyXG4gICAgICAgIHJldHVybiBub2RlICYmIC9eTEkkL2kudGVzdCh0eXBlb2Ygbm9kZSA9PT0gJ3N0cmluZycgPyBub2RlIDogbm9kZS5ub2RlTmFtZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIENoZWNrIHRoZSBub2RlIGlzIGEgdGFibGUgKHRhYmxlLCB0aGVhZCwgdGJvZHksIHRyLCB0aCwgdGQpXHJcbiAgICAgKiBAcGFyYW0ge05vZGV8U3RyaW5nfSBub2RlIFRoZSBlbGVtZW50IG9yIGVsZW1lbnQgbmFtZSB0byBjaGVja1xyXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIGlzVGFibGU6IGZ1bmN0aW9uIChub2RlKSB7XHJcbiAgICAgICAgcmV0dXJuIG5vZGUgJiYgL14oVEFCTEV8VEhFQUR8VEJPRFl8VFJ8VEh8VEQpJC9pLnRlc3QodHlwZW9mIG5vZGUgPT09ICdzdHJpbmcnID8gbm9kZSA6IG5vZGUubm9kZU5hbWUpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBDaGVjayB0aGUgbm9kZSBpcyBhIHRhYmxlIGNlbGwgKHRkLCB0aClcclxuICAgICAqIEBwYXJhbSB7Tm9kZXxTdHJpbmd9IG5vZGUgVGhlIGVsZW1lbnQgb3IgZWxlbWVudCBuYW1lIHRvIGNoZWNrXHJcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgaXNDZWxsOiBmdW5jdGlvbiAobm9kZSkge1xyXG4gICAgICAgIHJldHVybiBub2RlICYmIC9eKFREfFRIKSQvaS50ZXN0KHR5cGVvZiBub2RlID09PSAnc3RyaW5nJyA/IG5vZGUgOiBub2RlLm5vZGVOYW1lKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gQ2hlY2sgdGhlIG5vZGUgaXMgYSBicmVhayBub2RlIChCUilcclxuICAgICAqIEBwYXJhbSB7Tm9kZXxTdHJpbmd9IG5vZGUgVGhlIGVsZW1lbnQgb3IgZWxlbWVudCBuYW1lIHRvIGNoZWNrXHJcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgaXNCcmVhazogZnVuY3Rpb24gKG5vZGUpIHtcclxuICAgICAgICByZXR1cm4gbm9kZSAmJiAvXkJSJC9pLnRlc3QodHlwZW9mIG5vZGUgPT09ICdzdHJpbmcnID8gbm9kZSA6IG5vZGUubm9kZU5hbWUpO1xyXG4gICAgfSxcclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gQ2hlY2sgdGhlIG5vZGUgaXMgYSBhbmNob3Igbm9kZSAoQSlcclxuICAgICAqIEBwYXJhbSB7Tm9kZXxTdHJpbmd9IG5vZGUgVGhlIGVsZW1lbnQgb3IgZWxlbWVudCBuYW1lIHRvIGNoZWNrXHJcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgaXNBbmNob3I6IGZ1bmN0aW9uIChub2RlKSB7XHJcbiAgICAgICAgcmV0dXJuIG5vZGUgJiYgL15BJC9pLnRlc3QodHlwZW9mIG5vZGUgPT09ICdzdHJpbmcnID8gbm9kZSA6IG5vZGUubm9kZU5hbWUpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBDaGVjayB0aGUgbm9kZSBpcyBhIG1lZGlhIG5vZGUgKGltZywgaWZyYW1lLCBhdWRpbywgdmlkZW8sIGNhbnZhcylcclxuICAgICAqIEBwYXJhbSB7Tm9kZXxTdHJpbmd9IG5vZGUgVGhlIGVsZW1lbnQgb3IgZWxlbWVudCBuYW1lIHRvIGNoZWNrXHJcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgaXNNZWRpYTogZnVuY3Rpb24gKG5vZGUpIHtcclxuICAgICAgICByZXR1cm4gbm9kZSAmJiAvXihJTUd8SUZSQU1FfEFVRElPfFZJREVPfENBTlZBUykkL2kudGVzdCh0eXBlb2Ygbm9kZSA9PT0gJ3N0cmluZycgPyBub2RlIDogbm9kZS5ub2RlTmFtZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIENoZWNrcyBmb3IgbnVtZXJpYyAod2l0aCBkZWNpbWFsIHBvaW50KS5cclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE51bWJlcn0gdGV4dCBUZXh0IHN0cmluZyBvciBudW1iZXJcclxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxyXG4gICAgICovXHJcbiAgICBpc051bWJlcjogZnVuY3Rpb24gKHRleHQpIHtcclxuICAgICAgICByZXR1cm4gISF0ZXh0ICYmIC9eLT9cXGQrKFxcLlxcZCspPyQvLnRlc3QodGV4dCArICcnKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gR2V0IGEgbnVtYmVyLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSB0ZXh0IFRleHQgc3RyaW5nIG9yIG51bWJlclxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG1heERlYyBNYXhpbXVtIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlcyAoLTEgOiBJbmZpbml0eSlcclxuICAgICAqIEByZXR1cm5zIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIGdldE51bWJlcjogZnVuY3Rpb24gKHRleHQsIG1heERlYykge1xyXG4gICAgICAgIGlmICghdGV4dCkgcmV0dXJuIDA7XHJcbiAgICAgICAgXHJcbiAgICAgICAgbGV0IG51bWJlciA9ICh0ZXh0ICsgJycpLm1hdGNoKC8tP1xcZCsoXFwuXFxkKyk/Lyk7XHJcbiAgICAgICAgaWYgKCFudW1iZXIgfHwgIW51bWJlclswXSkgcmV0dXJuIDA7XHJcblxyXG4gICAgICAgIG51bWJlciA9IG51bWJlclswXTtcclxuICAgICAgICByZXR1cm4gbWF4RGVjIDwgMCA/IG51bWJlciAqIDEgOiBtYXhEZWMgPT09IDAgPyB0aGlzLl93Lk1hdGgucm91bmQobnVtYmVyICogMSkgOiAobnVtYmVyICogMSkudG9GaXhlZChtYXhEZWMpICogMTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gR2V0IGFsbCBcImNoaWxkcmVuXCIgb2YgdGhlIGFyZ3VtZW50IHZhbHVlIGVsZW1lbnQgKFdpdGhvdXQgdGV4dCBub2RlcylcclxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBlbGVtZW50IHRvIGdldCBjaGlsZCBub2RlXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufG51bGx9IHZhbGlkYXRpb24gQ29uZGl0aW9uYWwgZnVuY3Rpb25cclxuICAgICAqIEByZXR1cm5zIHtBcnJheX1cclxuICAgICAqL1xyXG4gICAgZ2V0TGlzdENoaWxkcmVuOiBmdW5jdGlvbiAoZWxlbWVudCwgdmFsaWRhdGlvbikge1xyXG4gICAgICAgIGNvbnN0IGNoaWxkcmVuID0gW107XHJcbiAgICAgICAgaWYgKCFlbGVtZW50IHx8ICFlbGVtZW50LmNoaWxkcmVuIHx8IGVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoID09PSAwKSByZXR1cm4gY2hpbGRyZW47XHJcblxyXG4gICAgICAgIHZhbGlkYXRpb24gPSB2YWxpZGF0aW9uIHx8IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH07XHJcblxyXG4gICAgICAgIChmdW5jdGlvbiByZWN1cnNpb25GdW5jKGN1cnJlbnQpIHtcclxuICAgICAgICAgICAgaWYgKGVsZW1lbnQgIT09IGN1cnJlbnQgJiYgdmFsaWRhdGlvbihjdXJyZW50KSkge1xyXG4gICAgICAgICAgICAgICAgY2hpbGRyZW4ucHVzaChjdXJyZW50KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGN1cnJlbnQuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIHJlY3Vyc2lvbkZ1bmMoY3VycmVudC5jaGlsZHJlbltpXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KShlbGVtZW50KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGNoaWxkcmVuO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBHZXQgYWxsIFwiY2hpbGROb2Rlc1wiIG9mIHRoZSBhcmd1bWVudCB2YWx1ZSBlbGVtZW50IChJbmNsdWRlIHRleHQgbm9kZXMpXHJcbiAgICAgKiBAcGFyYW0ge05vZGV9IGVsZW1lbnQgZWxlbWVudCB0byBnZXQgY2hpbGQgbm9kZVxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxudWxsfSB2YWxpZGF0aW9uIENvbmRpdGlvbmFsIGZ1bmN0aW9uXHJcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9XHJcbiAgICAgKi9cclxuICAgIGdldExpc3RDaGlsZE5vZGVzOiBmdW5jdGlvbiAoZWxlbWVudCwgdmFsaWRhdGlvbikge1xyXG4gICAgICAgIGNvbnN0IGNoaWxkcmVuID0gW107XHJcbiAgICAgICAgaWYgKCFlbGVtZW50IHx8IGVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGggPT09IDApIHJldHVybiBjaGlsZHJlbjtcclxuXHJcbiAgICAgICAgdmFsaWRhdGlvbiA9IHZhbGlkYXRpb24gfHwgZnVuY3Rpb24gKCkgeyByZXR1cm4gdHJ1ZTsgfTtcclxuXHJcbiAgICAgICAgKGZ1bmN0aW9uIHJlY3Vyc2lvbkZ1bmMoY3VycmVudCkge1xyXG4gICAgICAgICAgICBpZiAoZWxlbWVudCAhPT0gY3VycmVudCAmJiB2YWxpZGF0aW9uKGN1cnJlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGN1cnJlbnQpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gY3VycmVudC5jaGlsZE5vZGVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICByZWN1cnNpb25GdW5jKGN1cnJlbnQuY2hpbGROb2Rlc1tpXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KShlbGVtZW50KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGNoaWxkcmVuO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgcGFyZW50cyBub2Rlcy5cclxuICAgICAqIFwiMFwiIHdoZW4gdGhlIHBhcmVudCBub2RlIGlzIHRoZSBXWVNJV1lHIGFyZWEuXHJcbiAgICAgKiBcIi0xXCIgd2hlbiB0aGUgZWxlbWVudCBhcmd1bWVudCBpcyB0aGUgV1lTSVdZRyBhcmVhLlxyXG4gICAgICogQHBhcmFtIHtOb2RlfSBlbGVtZW50IFRoZSBlbGVtZW50IHRvIGNoZWNrXHJcbiAgICAgKiBAcmV0dXJucyB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBnZXRFbGVtZW50RGVwdGg6IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgaWYgKCFlbGVtZW50IHx8IHRoaXMuaXNXeXNpd3lnRGl2KGVsZW1lbnQpKSByZXR1cm4gLTE7XHJcblxyXG4gICAgICAgIGxldCBkZXB0aCA9IDA7XHJcbiAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50Tm9kZTtcclxuXHJcbiAgICAgICAgd2hpbGUgKGVsZW1lbnQgJiYgIXRoaXMuaXNXeXNpd3lnRGl2KGVsZW1lbnQpKSB7XHJcbiAgICAgICAgICAgIGRlcHRoICs9IDE7XHJcbiAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZGVwdGg7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIENvbXBhcmVzIHR3byBlbGVtZW50cyB0byBmaW5kIGEgY29tbW9uIGFuY2VzdG9yLCBhbmQgcmV0dXJucyB0aGUgb3JkZXIgb2YgdGhlIHR3byBlbGVtZW50cy5cclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gYSBOb2RlIHRvIGNvbXBhcmUuXHJcbiAgICAgKiBAcGFyYW0ge05vZGV9IGIgTm9kZSB0byBjb21wYXJlLlxyXG4gICAgICogQHJldHVybnMge09iamVjdH0geyBhbmNlc3N0b3IsIGEsIGIsIHJlc3VsdDogKGEgPiBiID8gMSA6IGEgPCBiID8gLTEgOiAwKSB9O1xyXG4gICAgICovXHJcbiAgICBjb21wYXJlRWxlbWVudHM6IGZ1bmN0aW9uIChhLCBiKSB7XHJcbiAgICAgICAgbGV0IGFOb2RlID0gYSwgYk5vZGUgPSBiO1xyXG4gICAgICAgIHdoaWxlIChhTm9kZSAmJiBiTm9kZSAmJiBhTm9kZS5wYXJlbnROb2RlICE9PSBiTm9kZS5wYXJlbnROb2RlKSB7XHJcbiAgICAgICAgICAgIGFOb2RlID0gYU5vZGUucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgYk5vZGUgPSBiTm9kZS5wYXJlbnROb2RlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFhTm9kZSB8fCAhYk5vZGUpIHJldHVybiB7IGFuY2VzdG9yOiBudWxsLCBhOiBhLCBiOiBiLCByZXN1bHQ6IDAgfTtcclxuXHJcbiAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBhTm9kZS5wYXJlbnROb2RlLmNoaWxkTm9kZXM7XHJcbiAgICAgICAgY29uc3QgYUluZGV4ID0gdGhpcy5nZXRBcnJheUluZGV4KGNoaWxkcmVuLCBhTm9kZSk7XHJcbiAgICAgICAgY29uc3QgYkluZGV4ID0gdGhpcy5nZXRBcnJheUluZGV4KGNoaWxkcmVuLCBiTm9kZSk7XHJcblxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGFuY2VzdG9yOiBhTm9kZS5wYXJlbnROb2RlLFxyXG4gICAgICAgICAgICBhOiBhTm9kZSxcclxuICAgICAgICAgICAgYjogYk5vZGUsXHJcbiAgICAgICAgICAgIHJlc3VsdDogYUluZGV4ID4gYkluZGV4ID8gMSA6IGFJbmRleCA8IGJJbmRleCA/IC0xIDogMFxyXG4gICAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIEdldCB0aGUgcGFyZW50IGVsZW1lbnQgb2YgdGhlIGFyZ3VtZW50IHZhbHVlLlxyXG4gICAgICogQSB0YWcgdGhhdCBzYXRpc2ZpZXMgdGhlIHF1ZXJ5IGNvbmRpdGlvbiBpcyBpbXBvcnRlZC5cclxuICAgICAqIFJldHVybnMgbnVsbCBpZiBub3QgZm91bmQuXHJcbiAgICAgKiBAcGFyYW0ge05vZGV9IGVsZW1lbnQgUmVmZXJlbmNlIGVsZW1lbnRcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSBxdWVyeSBRdWVyeSBTdHJpbmcgKG5vZGVOYW1lLCAuY2xhc3NOYW1lLCAjSUQsIDpuYW1lKSBvciB2YWxpZGF0aW9uIGZ1bmN0aW9uLlxyXG4gICAgICogTm90IHVzZSBpdCBsaWtlIGpxdWVyeS5cclxuICAgICAqIE9ubHkgb25lIGNvbmRpdGlvbiBjYW4gYmUgZW50ZXJlZCBhdCBhIHRpbWUuXHJcbiAgICAgKiBAcmV0dXJucyB7RWxlbWVudHxudWxsfVxyXG4gICAgICovXHJcbiAgICBnZXRQYXJlbnRFbGVtZW50OiBmdW5jdGlvbiAoZWxlbWVudCwgcXVlcnkpIHtcclxuICAgICAgICBsZXQgY2hlY2s7XHJcblxyXG4gICAgICAgIGlmICh0eXBlb2YgcXVlcnkgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgY2hlY2sgPSBxdWVyeTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBsZXQgYXR0cjtcclxuICAgICAgICAgICAgaWYgKC9eXFwuLy50ZXN0KHF1ZXJ5KSkge1xyXG4gICAgICAgICAgICAgICAgYXR0ciA9ICdjbGFzc05hbWUnO1xyXG4gICAgICAgICAgICAgICAgcXVlcnkgPSBxdWVyeS5zcGxpdCgnLicpWzFdO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKC9eIy8udGVzdChxdWVyeSkpIHtcclxuICAgICAgICAgICAgICAgIGF0dHIgPSAnaWQnO1xyXG4gICAgICAgICAgICAgICAgcXVlcnkgPSAnXicgKyBxdWVyeS5zcGxpdCgnIycpWzFdICsgJyQnO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKC9eOi8udGVzdChxdWVyeSkpIHtcclxuICAgICAgICAgICAgICAgIGF0dHIgPSAnbmFtZSc7XHJcbiAgICAgICAgICAgICAgICBxdWVyeSA9ICdeJyArIHF1ZXJ5LnNwbGl0KCc6JylbMV0gKyAnJCc7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBhdHRyID0gJ25vZGVOYW1lJztcclxuICAgICAgICAgICAgICAgIHF1ZXJ5ID0gJ14nICsgcXVlcnkgKyAnJCc7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHJlZ0V4cCA9IG5ldyB0aGlzLl93LlJlZ0V4cChxdWVyeSwgJ2knKTtcclxuICAgICAgICAgICAgY2hlY2sgPSBmdW5jdGlvbiAoZWwpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZWdFeHAudGVzdChlbFthdHRyXSk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB3aGlsZSAoZWxlbWVudCAmJiAhY2hlY2soZWxlbWVudCkpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuaXNXeXNpd3lnRGl2KGVsZW1lbnQpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIEdldCB0aGUgY2hpbGQgZWxlbWVudCBvZiB0aGUgYXJndW1lbnQgdmFsdWUuXHJcbiAgICAgKiBBIHRhZyB0aGF0IHNhdGlzZmllcyB0aGUgcXVlcnkgY29uZGl0aW9uIGlzIGltcG9ydGVkLlxyXG4gICAgICogUmV0dXJucyBudWxsIGlmIG5vdCBmb3VuZC5cclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gZWxlbWVudCBSZWZlcmVuY2UgZWxlbWVudFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IHF1ZXJ5IFF1ZXJ5IFN0cmluZyAobm9kZU5hbWUsIC5jbGFzc05hbWUsICNJRCwgOm5hbWUpIG9yIHZhbGlkYXRpb24gZnVuY3Rpb24uXHJcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGxhc3QgSWYgdHJ1ZSByZXR1cm5zIHRoZSBsYXN0IG5vZGUgYW1vbmcgdGhlIGZvdW5kIGNoaWxkIG5vZGVzLiAoZGVmYXVsdDogZmlyc3Qgbm9kZSlcclxuICAgICAqIE5vdCB1c2UgaXQgbGlrZSBqcXVlcnkuXHJcbiAgICAgKiBPbmx5IG9uZSBjb25kaXRpb24gY2FuIGJlIGVudGVyZWQgYXQgYSB0aW1lLlxyXG4gICAgICogQHJldHVybnMge0VsZW1lbnR8bnVsbH1cclxuICAgICAqL1xyXG4gICAgZ2V0Q2hpbGRFbGVtZW50OiBmdW5jdGlvbiAoZWxlbWVudCwgcXVlcnksIGxhc3QpIHtcclxuICAgICAgICBsZXQgY2hlY2s7XHJcblxyXG4gICAgICAgIGlmICh0eXBlb2YgcXVlcnkgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgY2hlY2sgPSBxdWVyeTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBsZXQgYXR0cjtcclxuICAgICAgICAgICAgaWYgKC9eXFwuLy50ZXN0KHF1ZXJ5KSkge1xyXG4gICAgICAgICAgICAgICAgYXR0ciA9ICdjbGFzc05hbWUnO1xyXG4gICAgICAgICAgICAgICAgcXVlcnkgPSBxdWVyeS5zcGxpdCgnLicpWzFdO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKC9eIy8udGVzdChxdWVyeSkpIHtcclxuICAgICAgICAgICAgICAgIGF0dHIgPSAnaWQnO1xyXG4gICAgICAgICAgICAgICAgcXVlcnkgPSAnXicgKyBxdWVyeS5zcGxpdCgnIycpWzFdICsgJyQnO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKC9eOi8udGVzdChxdWVyeSkpIHtcclxuICAgICAgICAgICAgICAgIGF0dHIgPSAnbmFtZSc7XHJcbiAgICAgICAgICAgICAgICBxdWVyeSA9ICdeJyArIHF1ZXJ5LnNwbGl0KCc6JylbMV0gKyAnJCc7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBhdHRyID0gJ25vZGVOYW1lJztcclxuICAgICAgICAgICAgICAgIHF1ZXJ5ID0gJ14nICsgKHF1ZXJ5ID09PSAndGV4dCcgPyAnIycgKyBxdWVyeSA6IHF1ZXJ5KSArICckJztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgcmVnRXhwID0gbmV3IHRoaXMuX3cuUmVnRXhwKHF1ZXJ5LCAnaScpO1xyXG4gICAgICAgICAgICBjaGVjayA9IGZ1bmN0aW9uIChlbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlZ0V4cC50ZXN0KGVsW2F0dHJdKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGNoaWxkTGlzdCA9IHRoaXMuZ2V0TGlzdENoaWxkTm9kZXMoZWxlbWVudCwgZnVuY3Rpb24gKGN1cnJlbnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGNoZWNrKGN1cnJlbnQpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gY2hpbGRMaXN0W2xhc3QgPyBjaGlsZExpc3QubGVuZ3RoIC0gMSA6IDBdO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiAxLiBUaGUgZmlyc3Qgbm9kZSBvZiBhbGwgdGhlIGNoaWxkIG5vZGVzIG9mIHRoZSBcImZpcnN0XCIgZWxlbWVudCBpcyByZXR1cm5lZC5cclxuICAgICAqIDIuIFRoZSBsYXN0IG5vZGUgb2YgYWxsIHRoZSBjaGlsZCBub2RlcyBvZiB0aGUgXCJsYXN0XCIgZWxlbWVudCBpcyByZXR1cm5lZC5cclxuICAgICAqIDMuIFdoZW4gdGhlcmUgaXMgbm8gXCJsYXN0XCIgZWxlbWVudCwgdGhlIGZpcnN0IGFuZCBsYXN0IG5vZGVzIG9mIGFsbCB0aGUgY2hpbGRyZW4gb2YgdGhlIFwiZmlyc3RcIiBlbGVtZW50IGFyZSByZXR1cm5lZC5cclxuICAgICAqIHsgc2M6IFwiZmlyc3RcIiwgZWM6IFwibGFzdFwiIH1cclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gZmlyc3QgRmlyc3QgZWxlbWVudFxyXG4gICAgICogQHBhcmFtIHtOb2RlfG51bGx9IGxhc3QgTGFzdCBlbGVtZW50XHJcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fVxyXG4gICAgICovXHJcbiAgICBnZXRFZGdlQ2hpbGROb2RlczogZnVuY3Rpb24gKGZpcnN0LCBsYXN0KSB7XHJcbiAgICAgICAgaWYgKCFmaXJzdCkgcmV0dXJuO1xyXG4gICAgICAgIGlmICghbGFzdCkgbGFzdCA9IGZpcnN0O1xyXG5cclxuICAgICAgICB3aGlsZSAoZmlyc3QgJiYgZmlyc3Qubm9kZVR5cGUgPT09IDEgJiYgZmlyc3QuY2hpbGROb2Rlcy5sZW5ndGggPiAwICYmICF0aGlzLmlzQnJlYWsoZmlyc3QpKSBmaXJzdCA9IGZpcnN0LmZpcnN0Q2hpbGQ7XHJcbiAgICAgICAgd2hpbGUgKGxhc3QgJiYgbGFzdC5ub2RlVHlwZSA9PT0gMSAmJiBsYXN0LmNoaWxkTm9kZXMubGVuZ3RoID4gMCAmJiAgIXRoaXMuaXNCcmVhayhsYXN0KSkgbGFzdCA9IGxhc3QubGFzdENoaWxkO1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBzYzogZmlyc3QsXHJcbiAgICAgICAgICAgIGVjOiBsYXN0IHx8IGZpcnN0XHJcbiAgICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gUmV0dXJucyB0aGUgcG9zaXRpb24gb2YgdGhlIGxlZnQgYW5kIHRvcCBvZiBhcmd1bWVudC4ge2xlZnQ6MCwgdG9wOjB9XHJcbiAgICAgKiBAcGFyYW0ge05vZGV9IGVsZW1lbnQgVGFyZ2V0IG5vZGVcclxuICAgICAqIEBwYXJhbSB7RWxlbWVudHxudWxsfSB3eXNpd3lnRnJhbWUgV2hlbiB1c2UgaWZyYW1lIG9wdGlvbiwgaWZyYW1lIG9iamVjdCBzaG91bGQgYmUgc2VudCAoY29udGV4dC5lbGVtZW50Lnd5c2l3eWdGcmFtZSlcclxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9XHJcbiAgICAgKi9cclxuICAgIGdldE9mZnNldDogZnVuY3Rpb24gKGVsZW1lbnQsIHd5c2l3eWdGcmFtZSkge1xyXG4gICAgICAgIGxldCBvZmZzZXRMZWZ0ID0gMDtcclxuICAgICAgICBsZXQgb2Zmc2V0VG9wID0gMDtcclxuICAgICAgICBsZXQgb2Zmc2V0RWxlbWVudCA9IGVsZW1lbnQubm9kZVR5cGUgPT09IDMgPyBlbGVtZW50LnBhcmVudEVsZW1lbnQgOiBlbGVtZW50O1xyXG4gICAgICAgIGNvbnN0IHd5c2l3eWcgPSB0aGlzLmdldFBhcmVudEVsZW1lbnQoZWxlbWVudCwgdGhpcy5pc1d5c2l3eWdEaXYuYmluZCh0aGlzKSk7XHJcblxyXG4gICAgICAgIHdoaWxlIChvZmZzZXRFbGVtZW50ICYmICF0aGlzLmhhc0NsYXNzKG9mZnNldEVsZW1lbnQsICdzZS1jb250YWluZXInKSAmJiBvZmZzZXRFbGVtZW50ICE9PSB3eXNpd3lnKSB7XHJcbiAgICAgICAgICAgIG9mZnNldExlZnQgKz0gb2Zmc2V0RWxlbWVudC5vZmZzZXRMZWZ0O1xyXG4gICAgICAgICAgICBvZmZzZXRUb3AgKz0gb2Zmc2V0RWxlbWVudC5vZmZzZXRUb3A7XHJcbiAgICAgICAgICAgIG9mZnNldEVsZW1lbnQgPSBvZmZzZXRFbGVtZW50Lm9mZnNldFBhcmVudDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGlmcmFtZSA9IHd5c2l3eWdGcmFtZSAmJiAvaWZyYW1lL2kudGVzdCh3eXNpd3lnRnJhbWUubm9kZU5hbWUpO1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBsZWZ0OiBvZmZzZXRMZWZ0ICsgKGlmcmFtZSA/IHd5c2l3eWdGcmFtZS5wYXJlbnRFbGVtZW50Lm9mZnNldExlZnQgOiAwKSxcclxuICAgICAgICAgICAgdG9wOiAob2Zmc2V0VG9wIC0gd3lzaXd5Zy5zY3JvbGxUb3ApICsgKGlmcmFtZSA/IHd5c2l3eWdGcmFtZS5wYXJlbnRFbGVtZW50Lm9mZnNldFRvcCA6IDApXHJcbiAgICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gSXQgY29tcGFyZXMgdGhlIHN0YXJ0IGFuZCBlbmQgaW5kZXhlcyBvZiBcImFcIiBhbmQgXCJiXCIgYW5kIHJldHVybnMgdGhlIG51bWJlciBvZiBvdmVybGFwcGluZyBpbmRleGVzIGluIHRoZSByYW5nZS5cclxuICAgICAqIGV4KSAxLCA1LCA0LCA2ID0+IFwiMlwiICg0IH4gNSlcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhU3RhcnQgU3RhcnQgaW5kZXggb2YgXCJhXCJcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhRW5kIEVuZCBpbmRleCBvZiBcImFcIlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGJTdGFydCBTdGFydCBpbmRleCBvZiBcImJcIlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGJFbmQgU3RhcnQgaW5kZXggb2YgXCJiXCJcclxuICAgICAqIEByZXR1cm5zIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIGdldE92ZXJsYXBSYW5nZUF0SW5kZXg6IGZ1bmN0aW9uIChhU3RhcnQsIGFFbmQsIGJTdGFydCwgYkVuZCkge1xyXG4gICAgICAgIGlmIChhU3RhcnQgPD0gYkVuZCA/IGFFbmQgPCBiU3RhcnQgOiBhRW5kID4gYlN0YXJ0KSByZXR1cm4gMDtcclxuXHJcbiAgICAgICAgY29uc3Qgb3ZlcmxhcCA9IChhU3RhcnQgPiBiU3RhcnQgPyBhU3RhcnQgOiBiU3RhcnQpIC0gKGFFbmQgPCBiRW5kID8gYUVuZCA6IGJFbmQpO1xyXG4gICAgICAgIHJldHVybiAob3ZlcmxhcCA8IDAgPyBvdmVybGFwICogLTEgOiBvdmVybGFwKSArIDE7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFNldCB0aGUgdGV4dCBjb250ZW50IHZhbHVlIG9mIHRoZSBhcmd1bWVudCB2YWx1ZSBlbGVtZW50XHJcbiAgICAgKiBAcGFyYW0ge05vZGV9IGVsZW1lbnQgRWxlbWVudCB0byByZXBsYWNlIHRleHQgY29udGVudFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHR4dCBUZXh0IHRvIGJlIGFwcGxpZWRcclxuICAgICAqL1xyXG4gICAgY2hhbmdlVHh0OiBmdW5jdGlvbiAoZWxlbWVudCwgdHh0KSB7XHJcbiAgICAgICAgaWYgKCFlbGVtZW50IHx8ICF0eHQpIHJldHVybjtcclxuICAgICAgICBlbGVtZW50LnRleHRDb250ZW50ID0gdHh0O1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBSZXBsYWNlIGVsZW1lbnRcclxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBUYXJnZXQgZWxlbWVudFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd8RWxlbWVudH0gbmV3RWxlbWVudCBTdHJpbmcgb3IgZWxlbWVudCBvZiB0aGUgbmV3IGVsZW1lbnQgdG8gYXBwbHlcclxuICAgICAqL1xyXG4gICAgY2hhbmdlRWxlbWVudDogZnVuY3Rpb24gKGVsZW1lbnQsIG5ld0VsZW1lbnQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIG5ld0VsZW1lbnQgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIGlmIChlbGVtZW50Lm91dGVySFRNTCkge1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudC5vdXRlckhUTUwgPSBuZXdFbGVtZW50O1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZG9jID0gdGhpcy5jcmVhdGVFbGVtZW50KCdESVYnKTtcclxuICAgICAgICAgICAgICAgIGRvYy5pbm5lckhUTUwgPSBuZXdFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgbmV3RWxlbWVudCA9IGRvYy5maXJzdENoaWxkO1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChuZXdFbGVtZW50LCBlbGVtZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAobmV3RWxlbWVudC5ub2RlVHlwZSA9PT0gMSkge1xyXG4gICAgICAgICAgICBlbGVtZW50LnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG5ld0VsZW1lbnQsIGVsZW1lbnQpO1xyXG4gICAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gU2V0IHN0eWxlLCBpZiBhbGwgc3R5bGVzIGFyZSBkZWxldGVkLCB0aGUgc3R5bGUgcHJvcGVydGllcyBhcmUgZGVsZXRlZC5cclxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBFbGVtZW50IHRvIHNldCBzdHlsZVxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHN0eWxlTmFtZSBTdHlsZSBhdHRyaWJ1dGUgbmFtZSAobWFyZ2luTGVmdCwgdGV4dEFsaWduLi4uKVxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSB2YWx1ZSBTdHlsZSB2YWx1ZVxyXG4gICAgICovXHJcbiAgICBzZXRTdHlsZTogZnVuY3Rpb24gKGVsZW1lbnQsIHN0eWxlTmFtZSwgdmFsdWUpIHtcclxuICAgICAgICBlbGVtZW50LnN0eWxlW3N0eWxlTmFtZV0gPSB2YWx1ZTtcclxuXHJcbiAgICAgICAgaWYgKCF2YWx1ZSAmJiAhZWxlbWVudC5zdHlsZS5jc3NUZXh0KSB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdzdHlsZScpO1xyXG4gICAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gRGV0ZXJtaW5lIHdoZXRoZXIgYW55IG9mIHRoZSBtYXRjaGVkIGVsZW1lbnRzIGFyZSBhc3NpZ25lZCB0aGUgZ2l2ZW4gY2xhc3NcclxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBFbGVtZW50cyB0byBzZWFyY2ggY2xhc3MgbmFtZVxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNsYXNzTmFtZSBDbGFzcyBuYW1lIHRvIHNlYXJjaCBmb3JcclxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxyXG4gICAgICovXHJcbiAgICBoYXNDbGFzczogZnVuY3Rpb24gKGVsZW1lbnQsIGNsYXNzTmFtZSkge1xyXG4gICAgICAgIGlmICghZWxlbWVudCkgcmV0dXJuO1xyXG5cclxuICAgICAgICByZXR1cm4gKG5ldyB0aGlzLl93LlJlZ0V4cChjbGFzc05hbWUpKS50ZXN0KGVsZW1lbnQuY2xhc3NOYW1lKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gQXBwZW5kIHRoZSBjbGFzc05hbWUgdmFsdWUgb2YgdGhlIGFyZ3VtZW50IHZhbHVlIGVsZW1lbnRcclxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBFbGVtZW50cyB0byBhZGQgY2xhc3MgbmFtZVxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNsYXNzTmFtZSBDbGFzcyBuYW1lIHRvIGJlIGFkZFxyXG4gICAgICovXHJcbiAgICBhZGRDbGFzczogZnVuY3Rpb24gKGVsZW1lbnQsIGNsYXNzTmFtZSkge1xyXG4gICAgICAgIGlmICghZWxlbWVudCkgcmV0dXJuO1xyXG5cclxuICAgICAgICBjb25zdCBjaGVjayA9IG5ldyB0aGlzLl93LlJlZ0V4cCgnKFxcXFxzfF4pJyArIGNsYXNzTmFtZSArICcoXFxcXHN8JCknKTtcclxuICAgICAgICBpZiAoY2hlY2sudGVzdChlbGVtZW50LmNsYXNzTmFtZSkpIHJldHVybjtcclxuXHJcbiAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgKz0gKGVsZW1lbnQuY2xhc3NOYW1lLmxlbmd0aCA+IDAgPyAnICcgOiAnJykgKyBjbGFzc05hbWU7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIERlbGV0ZSB0aGUgY2xhc3NOYW1lIHZhbHVlIG9mIHRoZSBhcmd1bWVudCB2YWx1ZSBlbGVtZW50XHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgRWxlbWVudHMgdG8gcmVtb3ZlIGNsYXNzIG5hbWVcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjbGFzc05hbWUgQ2xhc3MgbmFtZSB0byBiZSByZW1vdmVcclxuICAgICAqL1xyXG4gICAgcmVtb3ZlQ2xhc3M6IGZ1bmN0aW9uIChlbGVtZW50LCBjbGFzc05hbWUpIHtcclxuICAgICAgICBpZiAoIWVsZW1lbnQpIHJldHVybjtcclxuXHJcbiAgICAgICAgY29uc3QgY2hlY2sgPSBuZXcgdGhpcy5fdy5SZWdFeHAoJyhcXFxcc3xeKScgKyBjbGFzc05hbWUgKyAnKFxcXFxzfCQpJyk7XHJcbiAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSBlbGVtZW50LmNsYXNzTmFtZS5yZXBsYWNlKGNoZWNrLCAnICcpLnRyaW0oKTtcclxuXHJcbiAgICAgICAgaWYgKCFlbGVtZW50LmNsYXNzTmFtZS50cmltKCkpIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdjbGFzcycpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBBcmd1bWVudCB2YWx1ZSBJZiB0aGVyZSBpcyBubyBjbGFzcyBuYW1lLCBpbnNlcnQgaXQgYW5kIGRlbGV0ZSB0aGUgY2xhc3MgbmFtZSBpZiBpdCBleGlzdHNcclxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBFbGVtZW50cyB0byByZXBsYWNlIGNsYXNzIG5hbWVcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjbGFzc05hbWUgQ2xhc3MgbmFtZSB0byBiZSBjaGFuZ2VcclxuICAgICAqL1xyXG4gICAgdG9nZ2xlQ2xhc3M6IGZ1bmN0aW9uIChlbGVtZW50LCBjbGFzc05hbWUpIHtcclxuICAgICAgICBpZiAoIWVsZW1lbnQpIHJldHVybjtcclxuXHJcbiAgICAgICAgY29uc3QgY2hlY2sgPSBuZXcgdGhpcy5fdy5SZWdFeHAoJyhcXFxcc3xeKScgKyBjbGFzc05hbWUgKyAnKFxcXFxzfCQpJyk7XHJcbiAgICAgICAgaWYgKGNoZWNrLnRlc3QoZWxlbWVudC5jbGFzc05hbWUpKSB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gZWxlbWVudC5jbGFzc05hbWUucmVwbGFjZShjaGVjaywgJyAnKS50cmltKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBlbGVtZW50LmNsYXNzTmFtZSArPSAnICcgKyBjbGFzc05hbWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIWVsZW1lbnQuY2xhc3NOYW1lLnRyaW0oKSkgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ2NsYXNzJyk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIEluIHRoZSBwcmVkZWZpbmVkIGNvZGUgdmlldyBtb2RlLCB0aGUgYnV0dG9ucyBleGNlcHQgdGhlIGV4ZWN1dGFibGUgYnV0dG9uIGFyZSBjaGFuZ2VkIHRvIHRoZSAnZGlzYWJsZWQnIHN0YXRlLlxyXG4gICAgICogY29yZS5jb2RlVmlld0Rpc2FibGVkQnV0dG9ucyAoQW4gYXJyYXkgb2YgYnV0dG9ucyB3aG9zZSBjbGFzcyBuYW1lIGlzIG5vdCBcInNlLWNvZGUtdmlldy1lbmFibGVkXCIpXHJcbiAgICAgKiBjb3JlLnJlc2l6aW5nRGlzYWJsZWRCdXR0b25zIChBbiBhcnJheSBvZiBidXR0b25zIHdob3NlIGNsYXNzIG5hbWUgaXMgbm90IFwic2UtcmVzaXppbmctZW5hYmxlZFwiKVxyXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBkaXNhYmxlZCBEaXNhYmxlZCB2YWx1ZVxyXG4gICAgICogQHBhcmFtIHtBcnJheXxIVE1MQ29sbGVjdGlvbnxOb2RlTGlzdH0gYnV0dG9uTGlzdCBCdXR0b24gYXJyYXlcclxuICAgICAqL1xyXG4gICAgc2V0RGlzYWJsZWRCdXR0b25zOiBmdW5jdGlvbiAoZGlzYWJsZWQsIGJ1dHRvbkxpc3QpIHtcclxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gYnV0dG9uTGlzdC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICBidXR0b25MaXN0W2ldLmRpc2FibGVkID0gZGlzYWJsZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBEZWxldGUgYXJndW1lbnUgdmFsdWUgZWxlbWVudFxyXG4gICAgICogQHBhcmFtIHtOb2RlfSBpdGVtIE5vZGUgdG8gYmUgcmVtb3ZlXHJcbiAgICAgKi9cclxuICAgIHJlbW92ZUl0ZW06IGZ1bmN0aW9uIChpdGVtKSB7XHJcbiAgICAgICAgaWYgKCFpdGVtKSByZXR1cm47XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaXRlbS5yZW1vdmUoKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGlmIChpdGVtLnBhcmVudE5vZGUpIGl0ZW0ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChpdGVtKTtcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIERlbGV0ZSBhbGwgcGFyZW50IG5vZGVzIHRoYXQgbWF0Y2ggdGhlIGNvbmRpdGlvbi5cclxuICAgICAqIFJldHVybnMgYW4ge3NjOiBwcmV2aW91c1NpYmxpbmcsIGVjOiBuZXh0U2libGluZ30odGhlIGRlbGV0ZWQgbm9kZSByZWZlcmVuY2UpIG9yIG51bGwuXHJcbiAgICAgKiBAcGFyYW0ge05vZGV9IGl0ZW0gTm9kZSB0byBiZSByZW1vdmVcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258bnVsbH0gdmFsaWRhdGlvbiBWYWxpZGF0aW9uIGZ1bmN0aW9uLiBkZWZhdWx0KERlbGV0ZWQgaWYgaXQgb25seSBoYXZlIGJyZWFrTGluZSBhbmQgYmxhbmtzKVxyXG4gICAgICogQHBhcmFtIHtFbGVtZW50fG51bGx9IHN0b3BQYXJlbnQgU3RvcCB3aGVuIHRoZSBwYXJlbnQgbm9kZSByZWFjaGVzIHN0b3BQYXJlbnRcclxuICAgICAqIEByZXR1cm5zIHtPYmplY3R8bnVsbH0ge3NjOiBwcmV2aW91c1NpYmxpbmcsIGVjOiBuZXh0U2libGluZ31cclxuICAgICAqL1xyXG4gICAgcmVtb3ZlSXRlbUFsbFBhcmVudHM6IGZ1bmN0aW9uIChpdGVtLCB2YWxpZGF0aW9uLCBzdG9wUGFyZW50KSB7XHJcbiAgICAgICAgaWYgKCFpdGVtKSByZXR1cm4gbnVsbDtcclxuICAgICAgICBsZXQgY2MgPSBudWxsO1xyXG4gICAgICAgIGlmICghdmFsaWRhdGlvbikge1xyXG4gICAgICAgICAgICB2YWxpZGF0aW9uID0gZnVuY3Rpb24gKGN1cnJlbnQpIHtcclxuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50ID09PSBzdG9wUGFyZW50IHx8IHRoaXMuaXNDb21wb25lbnQoY3VycmVudCkpIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHRleHQgPSBjdXJyZW50LnRleHRDb250ZW50LnRyaW0oKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0Lmxlbmd0aCA9PT0gMCB8fCAvXihcXG58XFx1MjAwQikrJC8udGVzdCh0ZXh0KTtcclxuICAgICAgICAgICAgfS5iaW5kKHRoaXMpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgKGZ1bmN0aW9uIHJlY3Vyc2lvbkZ1bmMgKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgaWYgKCF1dGlsLmlzV3lzaXd5Z0RpdihlbGVtZW50KSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcGFyZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgaWYgKHBhcmVudCAmJiB2YWxpZGF0aW9uKGVsZW1lbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2MgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjOiBlbGVtZW50LnByZXZpb3VzRWxlbWVudFNpYmxpbmcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVjOiBlbGVtZW50Lm5leHRFbGVtZW50U2libGluZ1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVJdGVtKGVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlY3Vyc2lvbkZ1bmMocGFyZW50KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0oaXRlbSkpO1xyXG5cclxuICAgICAgICByZXR1cm4gY2M7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIERldGFjaCBOZXN0ZWQgYWxsIG5lc3RlZCBsaXN0cyB1bmRlciB0aGUgXCJiYXNlTm9kZVwiLlxyXG4gICAgICogUmV0dXJucyBhIGxpc3Qgd2l0aCBuZXN0ZWQgcmVtb3ZlZC5cclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gYmFzZU5vZGUgRWxlbWVudCBvbiB3aGljaCB0byBiYXNlLlxyXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhbGwgSWYgdHJ1ZSwgaXQgYWxzbyBkZXRhY2ggYWxsIG5lc3RlZCBsaXN0cyBvZiBhIHJldHVybmVkIGxpc3QuXHJcbiAgICAgKiBAcmV0dXJucyB7RWxlbWVudH1cclxuICAgICAqL1xyXG4gICAgZGV0YWNoTmVzdGVkTGlzdDogZnVuY3Rpb24gKGJhc2VOb2RlLCBhbGwpIHtcclxuICAgICAgICBjb25zdCByTm9kZSA9IHRoaXMuX2RlbGV0ZU5lc3RlZExpc3QoYmFzZU5vZGUpO1xyXG4gICAgICAgIGxldCByYW5nZUVsZW1lbnQsIGNOb2RlcztcclxuXHJcbiAgICAgICAgaWYgKHJOb2RlKSB7XHJcbiAgICAgICAgICAgIHJhbmdlRWxlbWVudCA9IHJOb2RlLmNsb25lTm9kZShmYWxzZSk7XHJcbiAgICAgICAgICAgIGNOb2RlcyA9IHJOb2RlLmNoaWxkTm9kZXM7XHJcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5nZXRQb3NpdGlvbkluZGV4KGJhc2VOb2RlKTtcclxuICAgICAgICAgICAgd2hpbGUgKGNOb2Rlc1tpbmRleF0pIHtcclxuICAgICAgICAgICAgICAgIHJhbmdlRWxlbWVudC5hcHBlbmRDaGlsZChjTm9kZXNbaW5kZXhdKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJhbmdlRWxlbWVudCA9IGJhc2VOb2RlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICBsZXQgckNoaWxkcmVuO1xyXG4gICAgICAgIGlmICghYWxsKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGRlcHRoID0gdGhpcy5nZXRFbGVtZW50RGVwdGgoYmFzZU5vZGUpICsgMjtcclxuICAgICAgICAgICAgckNoaWxkcmVuID0gdGhpcy5nZXRMaXN0Q2hpbGRyZW4oYmFzZU5vZGUsIGZ1bmN0aW9uIChjdXJyZW50KSB7IHJldHVybiB0aGlzLmlzTGlzdENlbGwoY3VycmVudCkgJiYgIWN1cnJlbnQucHJldmlvdXNFbGVtZW50U2libGluZyAmJiB0aGlzLmdldEVsZW1lbnREZXB0aChjdXJyZW50KSA9PT0gZGVwdGg7IH0uYmluZCh0aGlzKSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgckNoaWxkcmVuID0gdGhpcy5nZXRMaXN0Q2hpbGRyZW4ocmFuZ2VFbGVtZW50LCBmdW5jdGlvbiAoY3VycmVudCkgeyByZXR1cm4gdGhpcy5pc0xpc3RDZWxsKGN1cnJlbnQpICYmICFjdXJyZW50LnByZXZpb3VzRWxlbWVudFNpYmxpbmc7IH0uYmluZCh0aGlzKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gckNoaWxkcmVuLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2RlbGV0ZU5lc3RlZExpc3QockNoaWxkcmVuW2ldKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKHJOb2RlKSB7XHJcbiAgICAgICAgICAgIHJOb2RlLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHJhbmdlRWxlbWVudCwgck5vZGUubmV4dFNpYmxpbmcpO1xyXG4gICAgICAgICAgICBpZiAoY05vZGVzICYmIGNOb2Rlcy5sZW5ndGggPT09IDApIHRoaXMucmVtb3ZlSXRlbShyTm9kZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcmFuZ2VFbGVtZW50ID09PSBiYXNlTm9kZSA/IHJhbmdlRWxlbWVudC5wYXJlbnROb2RlIDogcmFuZ2VFbGVtZW50O1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBTdWIgZnVuY3Rpb24gb2YgdXRpbC5kZXRhY2hOZXN0ZWRMaXN0IG1ldGhvZC5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9kZWxldGVOZXN0ZWRMaXN0OiBmdW5jdGlvbiAoYmFzZU5vZGUpIHtcclxuICAgICAgICBjb25zdCBiYXNlUGFyZW50ID0gYmFzZU5vZGUucGFyZW50Tm9kZTtcclxuICAgICAgICBsZXQgc2libGluZyA9IGJhc2VQYXJlbnQ7XHJcbiAgICAgICAgbGV0IHBhcmVudCA9IHNpYmxpbmcucGFyZW50Tm9kZTtcclxuICAgICAgICBsZXQgbGlTaWJsaW5nLCBsaVBhcmVudCwgY2hpbGQsIGluZGV4LCBjO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHdoaWxlICh0aGlzLmlzTGlzdENlbGwocGFyZW50KSkge1xyXG4gICAgICAgICAgICBpbmRleCA9IHRoaXMuZ2V0UG9zaXRpb25JbmRleChiYXNlTm9kZSk7XHJcbiAgICAgICAgICAgIGxpU2libGluZyA9IHBhcmVudC5uZXh0RWxlbWVudFNpYmxpbmc7XHJcbiAgICAgICAgICAgIGxpUGFyZW50ID0gcGFyZW50LnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgIGNoaWxkID0gc2libGluZztcclxuICAgICAgICAgICAgd2hpbGUoY2hpbGQpIHtcclxuICAgICAgICAgICAgICAgIHNpYmxpbmcgPSBzaWJsaW5nLm5leHRTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNMaXN0KGNoaWxkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGMgPSBjaGlsZC5jaGlsZE5vZGVzO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChjW2luZGV4XSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsaVBhcmVudC5pbnNlcnRCZWZvcmUoY1tpbmRleF0sIGxpU2libGluZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjLmxlbmd0aCA9PT0gMCkgdGhpcy5yZW1vdmVJdGVtKGNoaWxkKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGlQYXJlbnQuYXBwZW5kQ2hpbGQoY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY2hpbGQgPSBzaWJsaW5nO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHNpYmxpbmcgPSBsaVBhcmVudDtcclxuICAgICAgICAgICAgcGFyZW50ID0gbGlQYXJlbnQucGFyZW50Tm9kZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChiYXNlUGFyZW50LmNoaWxkcmVuLmxlbmd0aCA9PT0gMCkgdGhpcy5yZW1vdmVJdGVtKGJhc2VQYXJlbnQpO1xyXG5cclxuICAgICAgICByZXR1cm4gbGlQYXJlbnQ7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFNwbGl0IGFsbCB0YWdzIGJhc2VkIG9uIFwiYmFzZU5vZGVcIlxyXG4gICAgICogUmV0dXJucyB0aGUgbGFzdCBlbGVtZW50IG9mIHRoZSBzcGxpdGVkIHRhZy5cclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gYmFzZU5vZGUgRWxlbWVudCBvciB0ZXh0IG5vZGUgb24gd2hpY2ggdG8gYmFzZVxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ8bnVsbH0gb2Zmc2V0IFRleHQgb2Zmc2V0IG9mIFwiYmFzZU5vZGVcIiAoT25seSB2YWxpZCB3aGVuIFwiYmFzZU5vZGVcIiBpcyBhIHRleHQgbm9kZSlcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkZXB0aCBUaGUgbmVzdGluZyBkZXB0aCBvZiB0aGUgZWxlbWVudCBiZWluZyBzcGxpdC4gKGRlZmF1bHQ6IDApXHJcbiAgICAgKiBAcmV0dXJucyB7RWxlbWVudH1cclxuICAgICAqL1xyXG4gICAgc3BsaXRFbGVtZW50OiBmdW5jdGlvbiAoYmFzZU5vZGUsIG9mZnNldCwgZGVwdGgpIHtcclxuICAgICAgICBjb25zdCBicCA9IGJhc2VOb2RlLnBhcmVudE5vZGU7XHJcbiAgICAgICAgbGV0IGluZGV4ID0gMCwgbmV3RWwsIGNoaWxkcmVuLCB0ZW1wO1xyXG4gICAgICAgIGxldCBuZXh0ID0gdHJ1ZTtcclxuICAgICAgICBpZiAoIWRlcHRoIHx8IGRlcHRoIDwgMCkgZGVwdGggPSAwO1xyXG5cclxuICAgICAgICBpZiAoYmFzZU5vZGUubm9kZVR5cGUgPT09IDMpIHtcclxuICAgICAgICAgICAgaW5kZXggPSB0aGlzLmdldFBvc2l0aW9uSW5kZXgoYmFzZU5vZGUpO1xyXG4gICAgICAgICAgICBpZiAob2Zmc2V0ID49IDApIHtcclxuICAgICAgICAgICAgICAgIGJhc2VOb2RlLnNwbGl0VGV4dChvZmZzZXQpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYWZ0ZXIgPSB0aGlzLmdldE5vZGVGcm9tUGF0aChbaW5kZXggKyAxXSwgYnApO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub25seVplcm9XaWR0aFNwYWNlKGFmdGVyKSkgYWZ0ZXIuZGF0YSA9IHRoaXMuemVyb1dpZHRoU3BhY2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKGJhc2VOb2RlLm5vZGVUeXBlID09PSAxKSB7XHJcbiAgICAgICAgICAgIGlmICghYmFzZU5vZGUucHJldmlvdXNTaWJsaW5nKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5nZXRFbGVtZW50RGVwdGgoYmFzZU5vZGUpID09PSBkZXB0aCkgbmV4dCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYmFzZU5vZGUgPSBiYXNlTm9kZS5wcmV2aW91c1NpYmxpbmc7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBkZXB0aEVsID0gYmFzZU5vZGU7XHJcbiAgICAgICAgd2hpbGUgKHRoaXMuZ2V0RWxlbWVudERlcHRoKGRlcHRoRWwpID4gZGVwdGgpIHtcclxuICAgICAgICAgICAgaW5kZXggPSB0aGlzLmdldFBvc2l0aW9uSW5kZXgoZGVwdGhFbCkgKyAxO1xyXG4gICAgICAgICAgICBkZXB0aEVsID0gZGVwdGhFbC5wYXJlbnROb2RlO1xyXG5cclxuICAgICAgICAgICAgdGVtcCA9IG5ld0VsO1xyXG4gICAgICAgICAgICBuZXdFbCA9IGRlcHRoRWwuY2xvbmVOb2RlKGZhbHNlKTtcclxuICAgICAgICAgICAgY2hpbGRyZW4gPSBkZXB0aEVsLmNoaWxkTm9kZXM7XHJcblxyXG4gICAgICAgICAgICBpZiAodGVtcCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNMaXN0Q2VsbChuZXdFbCkgJiYgdGhpcy5pc0xpc3QodGVtcCkgJiYgdGVtcC5maXJzdEVsZW1lbnRDaGlsZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG5ld0VsLmlubmVySFRNTCA9IHRlbXAuZmlyc3RFbGVtZW50Q2hpbGQuaW5uZXJIVE1MO1xyXG4gICAgICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlSXRlbSh0ZW1wLmZpcnN0RWxlbWVudENoaWxkKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGVtcC5jaGlsZHJlbi5sZW5ndGggPiAwKSBuZXdFbC5hcHBlbmRDaGlsZCh0ZW1wKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3RWwuYXBwZW5kQ2hpbGQodGVtcCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHdoaWxlIChjaGlsZHJlbltpbmRleF0pIHtcclxuICAgICAgICAgICAgICAgIG5ld0VsLmFwcGVuZENoaWxkKGNoaWxkcmVuW2luZGV4XSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChkZXB0aEVsLmNoaWxkTm9kZXMubGVuZ3RoIDw9IDEgJiYgKCFkZXB0aEVsLmZpcnN0Q2hpbGQgfHwgZGVwdGhFbC5maXJzdENoaWxkLnRleHRDb250ZW50Lmxlbmd0aCA9PT0gMCkpIGRlcHRoRWwuaW5uZXJIVE1MID0gJzxicj4nO1xyXG5cclxuICAgICAgICBjb25zdCBwRWxlbWVudCA9IGRlcHRoRWwucGFyZW50Tm9kZTtcclxuICAgICAgICBpZiAobmV4dCkgZGVwdGhFbCA9IGRlcHRoRWwubmV4dFNpYmxpbmc7XHJcbiAgICAgICAgaWYgKCFuZXdFbCkgcmV0dXJuIGRlcHRoRWw7XHJcblxyXG4gICAgICAgIHRoaXMubWVyZ2VTYW1lVGFncyhuZXdFbCwgbnVsbCwgZmFsc2UpO1xyXG4gICAgICAgIHRoaXMubWVyZ2VOZXN0ZWRUYWdzKG5ld0VsLCBmdW5jdGlvbiAoY3VycmVudCkgeyByZXR1cm4gdGhpcy5pc0xpc3QoY3VycmVudCk7IH0uYmluZCh0aGlzKSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKG5ld0VsLmNoaWxkTm9kZXMubGVuZ3RoID4gMCkgcEVsZW1lbnQuaW5zZXJ0QmVmb3JlKG5ld0VsLCBkZXB0aEVsKTtcclxuICAgICAgICBlbHNlIG5ld0VsID0gZGVwdGhFbDtcclxuXHJcbiAgICAgICAgaWYgKGJwLmNoaWxkTm9kZXMubGVuZ3RoID09PSAwKSB0aGlzLnJlbW92ZUl0ZW0oYnApO1xyXG5cclxuICAgICAgICByZXR1cm4gbmV3RWw7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFVzZSB3aXRoIFwibnBkZVBhdGggKHV0aWwuZ2V0Tm9kZVBhdGgpXCIgdG8gbWVyZ2UgdGhlIHNhbWUgYXR0cmlidXRlcyBhbmQgdGFncyBpZiB0aGV5IGFyZSBwcmVzZW50IGFuZCBtb2RpZnkgdGhlIG5vZGVwYXRoLlxyXG4gICAgICogSWYgXCJvZmZzZXRcIiBoYXMgYmVlbiBjaGFuZ2VkLCBpdCB3aWxsIHJldHVybiBhcyBtdWNoIFwib2Zmc2V0XCIgYXMgaXQgaGFzIGJlZW4gbW9kaWZpZWQuXHJcbiAgICAgKiBBbiBhcnJheSBjb250YWluaW5nIGNoYW5nZSBvZmZzZXRzIGlzIHJldHVybmVkIGluIHRoZSBvcmRlciBvZiB0aGUgXCJub2RlUGF0aEFycmF5XCIgYXJyYXkuXHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgRWxlbWVudFxyXG4gICAgICogQHBhcmFtIHtBcnJheXxudWxsfSBub2RlUGF0aEFycmF5IEFycmF5IG9mIE5vZGVQYXRoIG9iamVjdCAoW3V0aWwuZ2V0Tm9kZVBhdGgoKSwgLi5dKVxyXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBvbmx5VGV4dCBJZiB0cnVlLCBub24tdGV4dCBub2RlcyghdXRpbC5faXNJZ25vcmVOb2RlQ2hhbmdlKSBsaWtlICdzcGFuJywgJ3N0cm9uZycuLiBhcmUgaWdub3JlZC5cclxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gW29mZnNldCwgLi5dXHJcbiAgICAgKi9cclxuICAgIG1lcmdlU2FtZVRhZ3M6IGZ1bmN0aW9uIChlbGVtZW50LCBub2RlUGF0aEFycmF5LCBvbmx5VGV4dCkge1xyXG4gICAgICAgIGNvbnN0IGluc3QgPSB0aGlzO1xyXG4gICAgICAgIGNvbnN0IG5vZGVQYXRoTGVuID0gbm9kZVBhdGhBcnJheSA/IG5vZGVQYXRoQXJyYXkubGVuZ3RoIDogMDtcclxuICAgICAgICBsZXQgb2Zmc2V0cyA9IG51bGw7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKG5vZGVQYXRoTGVuKSB7XHJcbiAgICAgICAgICAgIG9mZnNldHMgPSB0aGlzLl93LkFycmF5LmFwcGx5KG51bGwsIG5ldyB0aGlzLl93LkFycmF5KG5vZGVQYXRoTGVuKSkubWFwKHRoaXMuX3cuTnVtYmVyLnByb3RvdHlwZS52YWx1ZU9mLCAwKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIChmdW5jdGlvbiByZWN1cnNpb25GdW5jKGN1cnJlbnQsIGRlcHRoLCBkZXB0aEluZGV4KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkcmVuID0gY3VycmVudC5jaGlsZE5vZGVzO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNoaWxkcmVuLmxlbmd0aCwgY2hpbGQsIG5leHQ7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTtcclxuICAgICAgICAgICAgICAgIG5leHQgPSBjaGlsZHJlbltpICsgMV07XHJcbiAgICAgICAgICAgICAgICBpZiAoIWNoaWxkKSBicmVhaztcclxuICAgICAgICAgICAgICAgIGlmKChvbmx5VGV4dCAmJiBpbnN0Ll9pc0lnbm9yZU5vZGVDaGFuZ2UoY2hpbGQpKSB8fCAoIW9ubHlUZXh0ICYmIChpbnN0LmlzVGFibGUoY2hpbGQpIHx8IGluc3QuaXNMaXN0Q2VsbChjaGlsZCkgfHwgKGluc3QuaXNGb3JtYXRFbGVtZW50KGNoaWxkKSAmJiAhaW5zdC5pc0ZyZWVGb3JtYXRFbGVtZW50KGNoaWxkKSkpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnN0LmlzVGFibGUoY2hpbGQpIHx8IGluc3QuaXNMaXN0Q2VsbChjaGlsZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjdXJzaW9uRnVuYyhjaGlsZCwgZGVwdGggKyAxLCBpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAobGVuID09PSAxICYmIGN1cnJlbnQubm9kZU5hbWUgPT09IGNoaWxkLm5vZGVOYW1lICYmIGN1cnJlbnQucGFyZW50Tm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSBub2RlUGF0aFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlUGF0aExlbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcGF0aCwgYywgcCwgY0RlcHRoLCBzcGxpY2VEZXB0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgbiA9IDA7IG4gPCBub2RlUGF0aExlbjsgbisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoID0gbm9kZVBhdGhBcnJheVtuXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXRoICYmIHBhdGhbZGVwdGhdID09PSBpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyA9IGNoaWxkLCBwID0gY3VycmVudCwgY0RlcHRoID0gZGVwdGgsIHNwbGljZURlcHRoID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY0RlcHRoID49IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluc3QuZ2V0QXJyYXlJbmRleChwLmNoaWxkTm9kZXMsIGMpICE9PSBwYXRoW2NEZXB0aF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwbGljZURlcHRoID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjID0gY2hpbGQucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcCA9IGMucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY0RlcHRoLS07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzcGxpY2VEZXB0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoLnNwbGljZShkZXB0aCwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGhbZGVwdGhdID0gaTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIG1lcmdlIHRhZ1xyXG4gICAgICAgICAgICAgICAgICAgIGluc3QuY29weVRhZ0F0dHJpYnV0ZXMoY2hpbGQsIGN1cnJlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoY2hpbGQsIGN1cnJlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGluc3QucmVtb3ZlSXRlbShjdXJyZW50KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmICghbmV4dCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZC5ub2RlVHlwZSA9PT0gMSkgcmVjdXJzaW9uRnVuYyhjaGlsZCwgZGVwdGggKyAxLCBpKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGQubm9kZU5hbWUgPT09IG5leHQubm9kZU5hbWUgJiYgaW5zdC5pc1NhbWVBdHRyaWJ1dGVzKGNoaWxkLCBuZXh0KSAmJiBjaGlsZC5ocmVmID09PSBuZXh0LmhyZWYpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGlsZHMgPSBjaGlsZC5jaGlsZE5vZGVzO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBjaGlsZExlbmd0aCA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgbiA9IDAsIG5MZW4gPSBjaGlsZHMubGVuZ3RoOyBuIDwgbkxlbjsgbisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZHNbbl0udGV4dENvbnRlbnQubGVuZ3RoID4gMCkgY2hpbGRMZW5ndGgrKztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGwgPSBjaGlsZC5sYXN0Q2hpbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgciA9IG5leHQuZmlyc3RDaGlsZDtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgYWRkT2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobCAmJiByKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRleHRPZmZzZXQgPSBsLm5vZGVUeXBlID09PSAzICYmIHIubm9kZVR5cGUgPT09IDM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZE9mZnNldCA9IGwudGV4dENvbnRlbnQubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgdGVtcEwgPSBsLnByZXZpb3VzU2libGluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUodGVtcEwgJiYgdGVtcEwubm9kZVR5cGUgPT09IDMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZE9mZnNldCArPSB0ZW1wTC50ZXh0Q29udGVudC5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wTCA9IHRlbXBMLnByZXZpb3VzU2libGluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkTGVuZ3RoID4gMCAmJiBsLm5vZGVUeXBlID09PSAzICYmIHIubm9kZVR5cGUgPT09IDMgJiYgKGwudGV4dENvbnRlbnQubGVuZ3RoID4gMCB8fCByLnRleHRDb250ZW50Lmxlbmd0aCA+IDApKSBjaGlsZExlbmd0aC0tO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVQYXRoTGVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcGF0aCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBuID0gMDsgbiA8IG5vZGVQYXRoTGVuOyBuKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoID0gbm9kZVBhdGhBcnJheVtuXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF0aCAmJiBwYXRoW2RlcHRoXSA+IGkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlcHRoID4gMCAmJiBwYXRoW2RlcHRoIC0gMV0gIT09IGRlcHRoSW5kZXgpIGNvbnRpbnVlO1xyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGhbZGVwdGhdIC09IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXRoW2RlcHRoICsgMV0gPj0gMCAmJiBwYXRoW2RlcHRoXSA9PT0gaSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aFtkZXB0aCArIDFdICs9IGNoaWxkTGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRleHRPZmZzZXQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobCAmJiBsLm5vZGVUeXBlID09PSAzICYmIHIgJiYgci5ub2RlVHlwZSA9PT0gMykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRzW25dICs9IGFkZE9mZnNldDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZC5ub2RlVHlwZSA9PT0gMykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRPZmZzZXQgPSBjaGlsZC50ZXh0Q29udGVudC5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnRleHRDb250ZW50ICs9IG5leHQudGV4dENvbnRlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlUGF0aExlbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHBhdGggPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgbiA9IDA7IG4gPCBub2RlUGF0aExlbjsgbisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IG5vZGVQYXRoQXJyYXlbbl07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhdGggJiYgcGF0aFtkZXB0aF0gPiBpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZXB0aCA+IDAgJiYgcGF0aFtkZXB0aCAtIDFdICE9PSBkZXB0aEluZGV4KSBjb250aW51ZTtcclxuICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoW2RlcHRoXSAtPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF0aFtkZXB0aCArIDFdID49IDAgJiYgcGF0aFtkZXB0aF0gPT09IGkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGhbZGVwdGggKyAxXSArPSBjaGlsZExlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHNbbl0gKz0gYWRkT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQuaW5uZXJIVE1MICs9IG5leHQuaW5uZXJIVE1MO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICBpbnN0LnJlbW92ZUl0ZW0obmV4dCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaS0tO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGlsZC5ub2RlVHlwZSA9PT0gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlY3Vyc2lvbkZ1bmMoY2hpbGQsIGRlcHRoICsgMSwgaSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KShlbGVtZW50LCAwLCAwKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG9mZnNldHM7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFJlbW92ZSBuZXN0ZWQgdGFncyB3aXRob3V0IG90aGVyIGNoaWxkIG5vZGVzLlxyXG4gICAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IEVsZW1lbnQgb2JqZWN0XHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufFN0cmluZ3xudWxsfSB2YWxpZGF0aW9uIFZhbGlkYXRpb24gZnVuY3Rpb24gLyBTdHJpbmcoXCJ0YWcxfHRhZzIuLlwiKSAvIElmIG51bGwsIGFsbCB0YWdzIGFyZSBhcHBsaWNhYmxlLlxyXG4gICAgICovXHJcbiAgICBtZXJnZU5lc3RlZFRhZ3M6IGZ1bmN0aW9uIChlbGVtZW50LCB2YWxpZGF0aW9uKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWxpZGF0aW9uID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICB2YWxpZGF0aW9uID0gZnVuY3Rpb24gKGN1cnJlbnQpIHsgcmV0dXJuIHRoaXMudGVzdChjdXJyZW50LnRhZ05hbWUpOyB9LmJpbmQobmV3IHRoaXMuX3cuUmVnRXhwKCdeKCcgKyAodmFsaWRhdGlvbiA/IHZhbGlkYXRpb24gOiAnLisnKSArICcpJCcsICdpJykpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbGlkYXRpb24gIT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgdmFsaWRhdGlvbiA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIChmdW5jdGlvbiByZWN1cnNpb25GdW5jKGN1cnJlbnQpIHtcclxuICAgICAgICAgICAgbGV0IGNoaWxkcmVuID0gY3VycmVudC5jaGlsZHJlbjtcclxuICAgICAgICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCA9PT0gMSAmJiBjaGlsZHJlblswXS5ub2RlTmFtZSA9PT0gY3VycmVudC5ub2RlTmFtZSAmJiB2YWxpZGF0aW9uKGN1cnJlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB0ZW1wID0gY2hpbGRyZW5bMF07XHJcbiAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IHRlbXAuY2hpbGRyZW47XHJcbiAgICAgICAgICAgICAgICB3aGlsZSAoY2hpbGRyZW5bMF0pIHtcclxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50LmFwcGVuZENoaWxkKGNoaWxkcmVuWzBdKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGN1cnJlbnQucmVtb3ZlQ2hpbGQodGVtcCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBjdXJyZW50LmNoaWxkcmVuLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICByZWN1cnNpb25GdW5jKGN1cnJlbnQuY2hpbGRyZW5baV0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSkoZWxlbWVudCk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIERlbGV0ZSBhIGVtcHR5IGNoaWxkIG5vZGUgb2YgYXJndW1lbnQgZWxlbWVudFxyXG4gICAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IEVsZW1lbnQgbm9kZVxyXG4gICAgICogQHBhcmFtIHtOb2RlfG51bGx9IG5vdFJlbW92ZU5vZGUgRG8gbm90IHJlbW92ZSBub2RlXHJcbiAgICAgKi9cclxuICAgIHJlbW92ZUVtcHR5Tm9kZTogZnVuY3Rpb24gKGVsZW1lbnQsIG5vdFJlbW92ZU5vZGUpIHtcclxuICAgICAgICBjb25zdCBpbnN0ID0gdGhpcztcclxuXHJcbiAgICAgICAgaWYgKG5vdFJlbW92ZU5vZGUpIHtcclxuICAgICAgICAgICAgbm90UmVtb3ZlTm9kZSA9IGluc3QuZ2V0UGFyZW50RWxlbWVudChub3RSZW1vdmVOb2RlLCBmdW5jdGlvbiAoY3VycmVudCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQgPT09IGN1cnJlbnQucGFyZW50RWxlbWVudDtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIChmdW5jdGlvbiByZWN1cnNpb25GdW5jKGN1cnJlbnQpIHtcclxuICAgICAgICAgICAgaWYgKGluc3QuX25vdFRleHROb2RlKGN1cnJlbnQpIHx8IGN1cnJlbnQgPT09IG5vdFJlbW92ZU5vZGUgfHwgaW5zdC5pc05vbkVkaXRhYmxlKGN1cnJlbnQpKSByZXR1cm4gMDtcclxuICAgICAgICAgICAgaWYgKGN1cnJlbnQgIT09IGVsZW1lbnQgJiYgaW5zdC5vbmx5WmVyb1dpZHRoU3BhY2UoY3VycmVudC50ZXh0Q29udGVudCkgJiYgKCFjdXJyZW50LmZpcnN0Q2hpbGQgfHwgIWluc3QuaXNCcmVhayhjdXJyZW50LmZpcnN0Q2hpbGQpKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnQucGFyZW50Tm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChjdXJyZW50KTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IGN1cnJlbnQuY2hpbGRyZW47XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gY2hpbGRyZW4ubGVuZ3RoLCByID0gMDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGlsZHJlbltpICsgcl0gfHwgaW5zdC5pc0NvbXBvbmVudChjaGlsZHJlbltpICsgcl0pKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICByICs9IHJlY3Vyc2lvbkZ1bmMoY2hpbGRyZW5baSArIHJdKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIDA7XHJcbiAgICAgICAgfSkoZWxlbWVudCk7XHJcblxyXG4gICAgICAgIGlmIChlbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoID09PSAwKSBlbGVtZW50LmlubmVySFRNTCA9ICc8YnI+JztcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gUmVtb3ZlIHdoaXRlc3BhY2UgYmV0d2VlbiB0YWdzIGluIEhUTUwgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGh0bWwgSFRNTCBzdHJpbmdcclxuICAgICAqIEByZXR1cm5zIHtTdHJpbmd9XHJcbiAgICAgKi9cclxuICAgIGh0bWxSZW1vdmVXaGl0ZVNwYWNlOiBmdW5jdGlvbiAoaHRtbCkge1xyXG4gICAgICAgIGlmICghaHRtbCkgcmV0dXJuICcnO1xyXG4gICAgICAgIHJldHVybiBodG1sLnRyaW0oKS5yZXBsYWNlKC88XFwvPyg/IXN0cm9uZ3xzcGFufGZvbnR8Ynx2YXJ8aXxlbXx1fGluc3xzfHN0cmlrZXxkZWx8c3VifHN1cHxtYXJrfGF8bGFiZWx8Y29kZSlbXj5ePF0rPlxccysoPz08KS9pZywgZnVuY3Rpb24gKG0pIHsgcmV0dXJuIG0udHJpbSgpOyB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gU29ydCBhIGVsZW1lbnQgYXJyYXkgYnkgZGVwdGggb2YgZWxlbWVudC5cclxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IEFycmF5IG9iamVjdFxyXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBkZXMgdHJ1ZTogZGVzY2VuZGluZyBvcmRlciAvIGZhbHNlOiBhc2NlbmRpbmcgb3JkZXJcclxuICAgICAqL1xyXG4gICAgc29ydEJ5RGVwdGg6IGZ1bmN0aW9uIChhcnJheSwgZGVzKSB7XHJcbiAgICAgICAgY29uc3QgdCA9ICFkZXMgPyAtMSA6IDE7XHJcbiAgICAgICAgY29uc3QgZiA9IHQgKiAtMTtcclxuXHJcbiAgICAgICAgYXJyYXkuc29ydChmdW5jdGlvbiAoYSwgYikge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNMaXN0Q2VsbChhKSB8fCAhdGhpcy5pc0xpc3RDZWxsKGIpKSByZXR1cm4gMDtcclxuICAgICAgICAgICAgYSA9IHRoaXMuZ2V0RWxlbWVudERlcHRoKGEpO1xyXG4gICAgICAgICAgICBiID0gdGhpcy5nZXRFbGVtZW50RGVwdGgoYik7XHJcbiAgICAgICAgICAgIHJldHVybiBhID4gYiA/IHQgOiBhIDwgYiA/IGYgOiAwO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIE5vZGVzIHRoYXQgbmVlZCB0byBiZSBhZGRlZCB3aXRob3V0IG1vZGlmaWNhdGlvbiB3aGVuIGNoYW5naW5nIHRleHQgbm9kZXNcclxuICAgICAqIEBwYXJhbSB7Tm9kZX0gZWxlbWVudCBFbGVtZW50IHRvIGNoZWNrXHJcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9pc0lnbm9yZU5vZGVDaGFuZ2U6IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQgJiYgZWxlbWVudC5ub2RlVHlwZSAhPT0gMyAmJiAodGhpcy5pc05vbkVkaXRhYmxlKGVsZW1lbnQpIHx8ICF0aGlzLmlzVGV4dFN0eWxlRWxlbWVudChlbGVtZW50KSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIE5vZGVzIHRoYXQgbXVzdCByZW1haW4gdW5kZXRhY2hlZCB3aGVuIGNoYW5naW5nIHRleHQgbm9kZXMgKEEsIExhYmVsLCBDb2RlKVxyXG4gICAgICogQHBhcmFtIHtOb2RlfFN0cmluZ30gZWxlbWVudCBFbGVtZW50IHRvIGNoZWNrXHJcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9pc01haW50YWluZWROb2RlOiBmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgIHJldHVybiBlbGVtZW50ICYmIGVsZW1lbnQubm9kZVR5cGUgIT09IDMgJiYgL14oYXxsYWJlbHxjb2RlKSQvaS50ZXN0KHR5cGVvZiBlbGVtZW50ID09PSAnc3RyaW5nJyA/IGVsZW1lbnQgOiBlbGVtZW50Lm5vZGVOYW1lKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gTm9kZSB3aXRoIGZvbnQtc2l6ZSBzdHlsZVxyXG4gICAgICogQHBhcmFtIHtOb2RlfSBlbGVtZW50IEVsZW1lbnQgdG8gY2hlY2tcclxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX2lzU2l6ZU5vZGU6IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQgJiYgZWxlbWVudC5ub2RlVHlwZSAhPT0gMyAmJiB0aGlzLmlzVGV4dFN0eWxlRWxlbWVudChlbGVtZW50KSAmJiAhIWVsZW1lbnQuc3R5bGUuZm9udFNpemU7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIE5vZGVzIHdpdGhvdXQgdGV4dFxyXG4gICAgICogQHBhcmFtIHtOb2RlfSBlbGVtZW50IEVsZW1lbnQgdG8gY2hlY2tcclxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX25vdFRleHROb2RlOiBmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgIHJldHVybiBlbGVtZW50ICYmIGVsZW1lbnQubm9kZVR5cGUgIT09IDMgJiYgKHRoaXMuaXNDb21wb25lbnQoZWxlbWVudCkgfHwgL14oYnJ8aW5wdXR8c2VsZWN0fGNhbnZhc3xpbWd8aWZyYW1lfGF1ZGlvfHZpZGVvKSQvaS50ZXN0KHR5cGVvZiBlbGVtZW50ID09PSAnc3RyaW5nJyA/IGVsZW1lbnQgOiBlbGVtZW50Lm5vZGVOYW1lKSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIENoZWNrIGRpc2FsbG93ZWQgdGFnc1xyXG4gICAgICogQHBhcmFtIHtOb2RlfSBlbGVtZW50IEVsZW1lbnQgdG8gY2hlY2tcclxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX2Rpc2FsbG93ZWRUYWdzOiBmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgIHJldHVybiAvXihtZXRhfHNjcmlwdHxsaW5rfHN0eWxlfFthLXpdK1xcOlthLXpdKykkL2kudGVzdChlbGVtZW50Lm5vZGVOYW1lKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlIHdoaXRlbGlzdCBSZWdFeHAgb2JqZWN0LlxyXG4gICAgICogUmV0dXJuIFJlZ0V4cCBmb3JtYXQ6IG5ldyBSZWdFeHAoXCI8XFxcXC8/XFxcXGIoPyFcIiArIGxpc3QgKyBcIilcXFxcYltePl48XSorPlwiLCBcImdpXCIpXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbGlzdCBUYWdzIGxpc3QgKFwiYnJ8cHxkaXZ8cHJlLi4uXCIpXHJcbiAgICAgKiBAcmV0dXJucyB7UmVnRXhwfVxyXG4gICAgICovXHJcbiAgICBjcmVhdGVUYWdzV2hpdGVsaXN0OiBmdW5jdGlvbiAobGlzdCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgUmVnRXhwKCc8XFxcXC8/XFxcXGIoPyFcXFxcYicgKyBsaXN0LnJlcGxhY2UoL1xcfC9nLCAnXFxcXGJ8XFxcXGInKSArICdcXFxcYilbXj5dKj4nLCAnZ2knKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gRml4IHRhZ3MgdGhhdCBkbyBub3QgZml0IHRoZSBlZGl0b3IgZm9ybWF0LlxyXG4gICAgICogQHBhcmFtIHtFbGVtZW50fSBkb2N1bWVudEZyYWdtZW50IERvY3VtZW50IGZyYWdtZW50IFwiRE9DVU1FTlRfRlJBR01FTlRfTk9ERVwiIChub2RlVHlwZSA9PT0gMTEpXHJcbiAgICAgKiBAcGFyYW0ge1JlZ0V4cH0gaHRtbENoZWNrV2hpdGVsaXN0UmVnRXhwIEVkaXRvciB0YWdzIHdoaXRlbGlzdCAoY29yZS5faHRtbENoZWNrV2hpdGVsaXN0UmVnRXhwKVxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX2NvbnNpc3RlbmN5Q2hlY2tPZkhUTUw6IGZ1bmN0aW9uIChkb2N1bWVudEZyYWdtZW50LCBodG1sQ2hlY2tXaGl0ZWxpc3RSZWdFeHApIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBJdCBpcyBjYW4gdXNlIFwiLmNoaWxkcmVuKHV0aWwuZ2V0TGlzdENoaWxkcmVuKVwiIHRvIGV4Y2x1ZGUgdGV4dCBub2RlcywgYnV0IFwiZG9jdW1lbnRGcmFnbWVudC5jaGlsZHJlblwiIGlzIG5vdCBzdXBwb3J0ZWQgaW4gSUUuXHJcbiAgICAgICAgICogU28gY2hlY2sgdGhlIG5vZGUgdHlwZSBhbmQgZXhjbHVkZSB0aGUgdGV4dCBubyAoY3VycmVudC5ub2RlVHlwZSAhPT0gMSlcclxuICAgICAgICAgKi9cclxuICAgICAgICBjb25zdCByZW1vdmVUYWdzID0gW10sIGVtcHR5VGFncyA9IFtdLCB3cm9uZ0xpc3QgPSBbXSwgd2l0aG91dEZvcm1hdENlbGxzID0gW107XHJcblxyXG4gICAgICAgIC8vIHdyb25nIHBvc2l0aW9uXHJcbiAgICAgICAgY29uc3Qgd3JvbmdUYWdzID0gdGhpcy5nZXRMaXN0Q2hpbGROb2Rlcyhkb2N1bWVudEZyYWdtZW50LCBmdW5jdGlvbiAoY3VycmVudCkge1xyXG4gICAgICAgICAgICBpZiAoY3VycmVudC5ub2RlVHlwZSAhPT0gMSkgcmV0dXJuIGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgLy8gd2hpdGUgbGlzdFxyXG4gICAgICAgICAgICBpZiAoIWh0bWxDaGVja1doaXRlbGlzdFJlZ0V4cC50ZXN0KGN1cnJlbnQubm9kZU5hbWUpICYmIGN1cnJlbnQuY2hpbGROb2Rlcy5sZW5ndGggPT09IDAgJiYgdGhpcy5pc05vdENoZWNraW5nTm9kZShjdXJyZW50KSkge1xyXG4gICAgICAgICAgICAgICAgcmVtb3ZlVGFncy5wdXNoKGN1cnJlbnQpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBucnRhZyA9ICF0aGlzLmdldFBhcmVudEVsZW1lbnQoY3VycmVudCwgdGhpcy5pc05vdENoZWNraW5nTm9kZSk7XHJcbiAgICAgICAgICAgIC8vIGVtcHR5IHRhZ3NcclxuICAgICAgICAgICAgaWYgKCghdGhpcy5pc1RhYmxlKGN1cnJlbnQpICYmICF0aGlzLmlzTGlzdENlbGwoY3VycmVudCkpICYmICh0aGlzLmlzRm9ybWF0RWxlbWVudChjdXJyZW50KSB8fCB0aGlzLmlzUmFuZ2VGb3JtYXRFbGVtZW50KGN1cnJlbnQpIHx8IHRoaXMuaXNUZXh0U3R5bGVFbGVtZW50KGN1cnJlbnQpKSAmJiBjdXJyZW50LmNoaWxkTm9kZXMubGVuZ3RoID09PSAwICYmIG5ydGFnKSB7XHJcbiAgICAgICAgICAgICAgICBlbXB0eVRhZ3MucHVzaChjdXJyZW50KTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gd3JvbmcgbGlzdFxyXG4gICAgICAgICAgICBpZiAodGhpcy5pc0xpc3QoY3VycmVudC5wYXJlbnROb2RlKSAmJiAhdGhpcy5pc0xpc3QoY3VycmVudCkgJiYgIXRoaXMuaXNMaXN0Q2VsbChjdXJyZW50KSkge1xyXG4gICAgICAgICAgICAgICAgd3JvbmdMaXN0LnB1c2goY3VycmVudCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIHRhYmxlIGNlbGxzXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzQ2VsbChjdXJyZW50KSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZmVsID0gY3VycmVudC5maXJzdEVsZW1lbnRDaGlsZDtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc0Zvcm1hdEVsZW1lbnQoZmVsKSAmJiAhdGhpcy5pc1JhbmdlRm9ybWF0RWxlbWVudChmZWwpICYmICF0aGlzLmlzQ29tcG9uZW50KGZlbCkpIHtcclxuICAgICAgICAgICAgICAgICAgICB3aXRob3V0Rm9ybWF0Q2VsbHMucHVzaChjdXJyZW50KTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50LnBhcmVudE5vZGUgIT09IGRvY3VtZW50RnJhZ21lbnQgJiZcclxuICAgICAgICAgICAgICh0aGlzLmlzRm9ybWF0RWxlbWVudChjdXJyZW50KSB8fCB0aGlzLmlzQ29tcG9uZW50KGN1cnJlbnQpIHx8IHRoaXMuaXNMaXN0KGN1cnJlbnQpKSAmJlxyXG4gICAgICAgICAgICAgIXRoaXMuaXNSYW5nZUZvcm1hdEVsZW1lbnQoY3VycmVudC5wYXJlbnROb2RlKSAmJiAhdGhpcy5pc0xpc3RDZWxsKGN1cnJlbnQucGFyZW50Tm9kZSkgJiZcclxuICAgICAgICAgICAgICF0aGlzLmdldFBhcmVudEVsZW1lbnQoY3VycmVudCwgdGhpcy5pc0NvbXBvbmVudCkgJiYgbnJ0YWc7XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHJlbW92ZVRhZ3MubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgdGhpcy5yZW1vdmVJdGVtKHJlbW92ZVRhZ3NbaV0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICBjb25zdCBjaGVja1RhZ3MgPSBbXTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gd3JvbmdUYWdzLmxlbmd0aCwgdCwgcDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHQgPSB3cm9uZ1RhZ3NbaV07XHJcbiAgICAgICAgICAgIHAgPSB0LnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgIGlmICghcCB8fCAhcC5wYXJlbnROb2RlKSBjb250aW51ZTtcclxuICAgICAgICAgICAgcC5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0LCBwKTtcclxuICAgICAgICAgICAgY2hlY2tUYWdzLnB1c2gocCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gY2hlY2tUYWdzLmxlbmd0aCwgdDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHQgPSBjaGVja1RhZ3NbaV07XHJcbiAgICAgICAgICAgIGlmICh0aGlzLm9ubHlaZXJvV2lkdGhTcGFjZSh0LnRleHRDb250ZW50LnRyaW0oKSkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlSXRlbSh0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGVtcHR5VGFncy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICB0aGlzLnJlbW92ZUl0ZW0oZW1wdHlUYWdzW2ldKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSB3cm9uZ0xpc3QubGVuZ3RoLCB0LCB0cCwgY2hpbGRyZW4sIHA7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICB0ID0gd3JvbmdMaXN0W2ldO1xyXG5cclxuICAgICAgICAgICAgdHAgPSB0aGlzLmNyZWF0ZUVsZW1lbnQoJ0xJJyk7XHJcbiAgICAgICAgICAgIGNoaWxkcmVuID0gdC5jaGlsZE5vZGVzO1xyXG4gICAgICAgICAgICB3aGlsZSAoY2hpbGRyZW5bMF0pIHtcclxuICAgICAgICAgICAgICAgIHRwLmFwcGVuZENoaWxkKGNoaWxkcmVuWzBdKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgcCA9IHQucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgaWYgKCFwKSBjb250aW51ZTtcclxuICAgICAgICAgICAgcC5pbnNlcnRCZWZvcmUodHAsIHQpO1xyXG4gICAgICAgICAgICB0aGlzLnJlbW92ZUl0ZW0odCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gd2l0aG91dEZvcm1hdENlbGxzLmxlbmd0aCwgdCwgZjsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHQgPSB3aXRob3V0Rm9ybWF0Q2VsbHNbaV07XHJcbiAgICAgICAgICAgIGYgPSB0aGlzLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xyXG4gICAgICAgICAgICBmLmlubmVySFRNTCA9IHQudGV4dENvbnRlbnQudHJpbSgpLmxlbmd0aCA9PT0gMCA/ICc8YnI+JyA6IHQuaW5uZXJIVE1MO1xyXG4gICAgICAgICAgICB0LmlubmVySFRNTCA9IGYub3V0ZXJIVE1MO1xyXG4gICAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgX3NldERlZmF1bHRPcHRpb25TdHlsZTogZnVuY3Rpb24gKG9wdGlvbnMsIGRlZmF1bHRTdHlsZSkge1xyXG4gICAgICAgIGxldCBvcHRpb25TdHlsZSA9ICcnO1xyXG4gICAgICAgIGlmIChvcHRpb25zLmhlaWdodCkgb3B0aW9uU3R5bGUgKz0gJ2hlaWdodDonICsgb3B0aW9ucy5oZWlnaHQgKyAnOyc7XHJcbiAgICAgICAgaWYgKG9wdGlvbnMubWluSGVpZ2h0KSBvcHRpb25TdHlsZSArPSAnbWluLWhlaWdodDonICsgb3B0aW9ucy5taW5IZWlnaHQgKyAnOyc7XHJcbiAgICAgICAgaWYgKG9wdGlvbnMubWF4SGVpZ2h0KSBvcHRpb25TdHlsZSArPSAnbWF4LWhlaWdodDonICsgb3B0aW9ucy5tYXhIZWlnaHQgKyAnOyc7XHJcbiAgICAgICAgaWYgKG9wdGlvbnMucG9zaXRpb24pIG9wdGlvblN0eWxlICs9ICdwb3NpdGlvbjonICsgb3B0aW9ucy5wb3NpdGlvbiArICc7JztcclxuICAgICAgICBpZiAob3B0aW9ucy53aWR0aCkgb3B0aW9uU3R5bGUgKz0gJ3dpZHRoOicgKyBvcHRpb25zLndpZHRoICsgJzsnO1xyXG4gICAgICAgIGlmIChvcHRpb25zLm1pbldpZHRoKSBvcHRpb25TdHlsZSArPSAnbWluLXdpZHRoOicgKyBvcHRpb25zLm1pbldpZHRoICsgJzsnO1xyXG4gICAgICAgIGlmIChvcHRpb25zLm1heFdpZHRoKSBvcHRpb25TdHlsZSArPSAnbWF4LXdpZHRoOicgKyBvcHRpb25zLm1heFdpZHRoICsgJzsnO1xyXG5cclxuICAgICAgICBsZXQgdG9wID0gJycsIGZyYW1lID0gJycsIGVkaXRvciA9ICcnO1xyXG4gICAgICAgIGRlZmF1bHRTdHlsZSA9IG9wdGlvblN0eWxlICsgZGVmYXVsdFN0eWxlO1xyXG4gICAgICAgIGNvbnN0IHN0eWxlQXJyID0gZGVmYXVsdFN0eWxlLnNwbGl0KCc7Jyk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHN0eWxlQXJyLmxlbmd0aCwgczsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHMgPSBzdHlsZUFycltpXS50cmltKCk7XHJcbiAgICAgICAgICAgIGlmICghcykgY29udGludWU7XHJcbiAgICAgICAgICAgIGlmICgvXihtaW4tfG1heC0pP3dpZHRoXFxzKjovLnRlc3QocykpIHtcclxuICAgICAgICAgICAgICAgIHRvcCArPSBzICsgJzsnO1xyXG4gICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKC9eKG1pbi18bWF4LSk/aGVpZ2h0XFxzKjovLnRlc3QocykpIHtcclxuICAgICAgICAgICAgICAgIGlmICgvXmhlaWdodC8udGVzdChzKSAmJiBzLnNwbGl0KCc6JylbMV0udHJpbSgpID09PSAnYXV0bycpIHtcclxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmhlaWdodCA9ICdhdXRvJztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGZyYW1lICs9IHMgKyAnOyc7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlZGl0b3IgKz0gcyArICc7JztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHRvcDogdG9wLFxyXG4gICAgICAgICAgICBmcmFtZTogZnJhbWUsXHJcbiAgICAgICAgICAgIGVkaXRvcjogZWRpdG9yXHJcbiAgICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgX3NldElmcmFtZURvY3VtZW50OiBmdW5jdGlvbiAoZnJhbWUsIG9wdGlvbnMpIHtcclxuICAgICAgICBmcmFtZS5zZXRBdHRyaWJ1dGUoJ3Njcm9sbGluZycsICdhdXRvJyk7XHJcbiAgICAgICAgZnJhbWUuY29udGVudERvY3VtZW50LmhlYWQuaW5uZXJIVE1MID0gJycgK1xyXG4gICAgICAgICAgICAnPG1ldGEgY2hhcnNldD1cInV0Zi04XCIgLz4nICtcclxuICAgICAgICAgICAgJzxtZXRhIG5hbWU9XCJ2aWV3cG9ydFwiIGNvbnRlbnQ9XCJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MVwiPicgK1xyXG4gICAgICAgICAgICB0aGlzLl9zZXRJZnJhbWVDc3NUYWdzKG9wdGlvbnMpO1xyXG4gICAgICAgIGZyYW1lLmNvbnRlbnREb2N1bWVudC5ib2R5LmNsYXNzTmFtZSA9IG9wdGlvbnMuX2VkaXRhYmxlQ2xhc3M7XHJcbiAgICAgICAgZnJhbWUuY29udGVudERvY3VtZW50LmJvZHkuc2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnLCB0cnVlKTtcclxuICAgIH0sXHJcblxyXG4gICAgX3NldElmcmFtZUNzc1RhZ3M6IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcbiAgICAgICAgY29uc3QgbGlua05hbWVzID0gb3B0aW9ucy5pZnJhbWVDU1NGaWxlTmFtZTtcclxuICAgICAgICBjb25zdCB3UmVnRXhwID0gdGhpcy5fdy5SZWdFeHA7XHJcbiAgICAgICAgbGV0IHRhZ1N0cmluZyA9ICcnO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBmID0gMCwgbGVuID0gbGlua05hbWVzLmxlbmd0aCwgcGF0aDsgZiA8IGxlbjsgZisrKSB7XHJcbiAgICAgICAgICAgIHBhdGggPSBbXTtcclxuXHJcbiAgICAgICAgICAgIGlmICgvKF5odHRwcz86XFwvXFwvKXwoXmRhdGE6dGV4dFxcL2NzcywpLy50ZXN0KGxpbmtOYW1lc1tmXSkpIHtcclxuICAgICAgICAgICAgICAgIHBhdGgucHVzaChsaW5rTmFtZXNbZl0pO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgQ1NTRmlsZU5hbWUgPSBuZXcgd1JlZ0V4cCgnKF58LipbXFxcXC9dKScgKyBsaW5rTmFtZXNbZl0gKyAnKFxcXFwuLispP1xcXFwuY3NzKD86XFxcXD8uKnw7LiopPyQnLCAnaScpO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgYyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdsaW5rJyksIGkgPSAwLCBsZW4gPSBjLmxlbmd0aCwgc3R5bGVUYWc7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlVGFnID0gY1tpXS5ocmVmLm1hdGNoKENTU0ZpbGVOYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGVUYWcpIHBhdGgucHVzaChzdHlsZVRhZ1swXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghcGF0aCB8fCBwYXRoLmxlbmd0aCA9PT0gMCkgdGhyb3cgJ1tTVU5FRElUT1IuY29uc3RydWN0b3IuaWZyYW1lLmZhaWxdIFRoZSBzdW5lZGl0b3IgQ1NTIGZpbGVzIGluc3RhbGxhdGlvbiBwYXRoIGNvdWxkIG5vdCBiZSBhdXRvbWF0aWNhbGx5IGRldGVjdGVkLiBQbGVhc2Ugc2V0IHRoZSBvcHRpb24gcHJvcGVydHkgXCJpZnJhbWVDU1NGaWxlTmFtZVwiIGJlZm9yZSBjcmVhdGluZyBlZGl0b3IgaW5zdGFuY2VzLic7XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gcGF0aC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgdGFnU3RyaW5nICs9ICc8bGluayBocmVmPVwiJyArIHBhdGhbaV0gKyAnXCIgcmVsPVwic3R5bGVzaGVldFwiPic7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0YWdTdHJpbmcgKyAob3B0aW9ucy5oZWlnaHQgPT09ICdhdXRvJyA/ICc8c3R5bGU+XFxuLyoqIElmcmFtZSBoZWlnaHQgYXV0byAqL1xcbmJvZHl7aGVpZ2h0OiBtaW4tY29udGVudDsgb3ZlcmZsb3c6IGhpZGRlbjt9XFxuPC9zdHlsZT4nIDogJycpO1xyXG4gICAgfVxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgdXRpbDsiLCIvKlxyXG4gKiB3eXNpd3lnIHdlYiBlZGl0b3JcclxuICpcclxuICogc3VuZWRpdG9yLmpzXHJcbiAqIENvcHlyaWdodCAyMDE3IEppSG9uZyBMZWUuXHJcbiAqIE1JVCBsaWNlbnNlLlxyXG4gKi9cclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuaW1wb3J0IF9pY29ucyBmcm9tICcuLi9hc3NldHMvZGVmYXVsdEljb25zJztcclxuaW1wb3J0IF9kZWZhdWx0TGFuZyBmcm9tICcuLi9sYW5nL2VuJztcclxuaW1wb3J0IHV0aWwgZnJvbSAnLi91dGlsJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIGRvY3VtZW50IGNyZWF0ZVxyXG4gICAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IFRleHRhcmVhXHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBPcHRpb25zXHJcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fVxyXG4gICAgICovXHJcbiAgICBpbml0OiBmdW5jdGlvbiAoZWxlbWVudCwgb3B0aW9ucykge1xyXG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIG9wdGlvbnMgPSB7fTtcclxuXHJcbiAgICAgICAgY29uc3QgZG9jID0gZG9jdW1lbnQ7XHJcblxyXG4gICAgICAgIC8qKiAtLS0gaW5pdCBvcHRpb25zIC0tLSAqL1xyXG4gICAgICAgIHRoaXMuX2luaXRPcHRpb25zKGVsZW1lbnQsIG9wdGlvbnMpO1xyXG4gICAgXHJcbiAgICAgICAgLy8gc3VuZWRpdG9yIGRpdlxyXG4gICAgICAgIGNvbnN0IHRvcF9kaXYgPSBkb2MuY3JlYXRlRWxlbWVudCgnRElWJyk7XHJcbiAgICAgICAgdG9wX2Rpdi5jbGFzc05hbWUgPSAnc3VuLWVkaXRvcicgKyAob3B0aW9ucy5ydGwgPyAnIHNlLXJ0bCcgOiAnJyk7XHJcbiAgICAgICAgaWYgKGVsZW1lbnQuaWQpIHRvcF9kaXYuaWQgPSAnc3VuZWRpdG9yXycgKyBlbGVtZW50LmlkO1xyXG4gICAgXHJcbiAgICAgICAgLy8gcmVsYXRpdmUgZGl2XHJcbiAgICAgICAgY29uc3QgcmVsYXRpdmUgPSBkb2MuY3JlYXRlRWxlbWVudCgnRElWJyk7XHJcbiAgICAgICAgcmVsYXRpdmUuY2xhc3NOYW1lID0gJ3NlLWNvbnRhaW5lcic7XHJcbiAgICBcclxuICAgICAgICAvLyB0b29sYmFyXHJcbiAgICAgICAgY29uc3QgdG9vbF9iYXIgPSB0aGlzLl9jcmVhdGVUb29sQmFyKGRvYywgb3B0aW9ucy5idXR0b25MaXN0LCBvcHRpb25zLnBsdWdpbnMsIG9wdGlvbnMpO1xyXG4gICAgICAgIHRvb2xfYmFyLmVsZW1lbnQuc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xyXG4gICAgICAgIGlmICh0b29sX2Jhci5wbHVnaW5DYWxsQnV0dG9ucy5tYXRoKSB0aGlzLl9jaGVja0thdGV4TWF0aChvcHRpb25zLmthdGV4KTtcclxuICAgICAgICBjb25zdCBhcnJvdyA9IGRvYy5jcmVhdGVFbGVtZW50KCdESVYnKTtcclxuICAgICAgICBhcnJvdy5jbGFzc05hbWUgPSAnc2UtYXJyb3cnO1xyXG5cclxuICAgICAgICAvLyBzdGlja3kgdG9vbGJhciBkdW1teVxyXG4gICAgICAgIGNvbnN0IHN0aWNreV9kdW1teSA9IGRvYy5jcmVhdGVFbGVtZW50KCdESVYnKTtcclxuICAgICAgICBzdGlja3lfZHVtbXkuY2xhc3NOYW1lID0gJ3NlLXRvb2xiYXItc3RpY2t5LWR1bW15JztcclxuICAgIFxyXG4gICAgICAgIC8vIGlubmVyIGVkaXRvciBkaXZcclxuICAgICAgICBjb25zdCBlZGl0b3JfZGl2ID0gZG9jLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xyXG4gICAgICAgIGVkaXRvcl9kaXYuY2xhc3NOYW1lID0gJ3NlLXdyYXBwZXInO1xyXG5cclxuICAgICAgICAvKiogLS0tIGluaXQgZWxlbWVudHMgYW5kIGNyZWF0ZSBib3R0b20gYmFyIC0tLSAqL1xyXG4gICAgICAgIGNvbnN0IGluaXRFbGVtZW50cyA9IHRoaXMuX2luaXRFbGVtZW50cyhvcHRpb25zLCB0b3BfZGl2LCB0b29sX2Jhci5lbGVtZW50LCBhcnJvdyk7XHJcblxyXG4gICAgICAgIGNvbnN0IGJvdHRvbUJhciA9IGluaXRFbGVtZW50cy5ib3R0b21CYXI7XHJcbiAgICAgICAgY29uc3Qgd3lzaXd5Z19kaXYgPSBpbml0RWxlbWVudHMud3lzaXd5Z0ZyYW1lO1xyXG4gICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyX3NwYW4gPSBpbml0RWxlbWVudHMucGxhY2Vob2xkZXI7XHJcbiAgICAgICAgbGV0IHRleHRhcmVhID0gaW5pdEVsZW1lbnRzLmNvZGVWaWV3O1xyXG5cclxuICAgICAgICAvLyByZXNpemluZyBiYXJcclxuICAgICAgICBjb25zdCByZXNpemluZ19iYXIgPSBib3R0b21CYXIucmVzaXppbmdCYXI7XHJcbiAgICAgICAgY29uc3QgbmF2aWdhdGlvbiA9IGJvdHRvbUJhci5uYXZpZ2F0aW9uO1xyXG4gICAgICAgIGNvbnN0IGNoYXJfd3JhcHBlciA9IGJvdHRvbUJhci5jaGFyV3JhcHBlcjtcclxuICAgICAgICBjb25zdCBjaGFyX2NvdW50ZXIgPSBib3R0b21CYXIuY2hhckNvdW50ZXI7XHJcbiAgICBcclxuICAgICAgICAvLyBsb2FkaW5nIGJveFxyXG4gICAgICAgIGNvbnN0IGxvYWRpbmdfYm94ID0gZG9jLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xyXG4gICAgICAgIGxvYWRpbmdfYm94LmNsYXNzTmFtZSA9ICdzZS1sb2FkaW5nLWJveCBzdW4tZWRpdG9yLWNvbW1vbic7XHJcbiAgICAgICAgbG9hZGluZ19ib3guaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9XCJzZS1sb2FkaW5nLWVmZmVjdFwiPjwvZGl2Pic7XHJcblxyXG4gICAgICAgIC8vIGVudGVyIGxpbmVcclxuICAgICAgICBjb25zdCBsaW5lX2JyZWFrZXIgPSBkb2MuY3JlYXRlRWxlbWVudCgnRElWJyk7XHJcbiAgICAgICAgbGluZV9icmVha2VyLmNsYXNzTmFtZSA9ICdzZS1saW5lLWJyZWFrZXInO1xyXG4gICAgICAgIGxpbmVfYnJlYWtlci5pbm5lckhUTUwgPSAnPGJ1dHRvbiBjbGFzcz1cInNlLWJ0blwiPicgKyBvcHRpb25zLmljb25zLmxpbmVfYnJlYWsgKyAnPC9idXR0b24+JztcclxuICAgICAgICBjb25zdCBsaW5lX2JyZWFrZXJfdCA9IGRvYy5jcmVhdGVFbGVtZW50KCdESVYnKTtcclxuICAgICAgICBsaW5lX2JyZWFrZXJfdC5jbGFzc05hbWUgKz0gJ3NlLWxpbmUtYnJlYWtlci1jb21wb25lbnQnO1xyXG4gICAgICAgIGNvbnN0IGxpbmVfYnJlYWtlcl9iID0gbGluZV9icmVha2VyX3QuY2xvbmVOb2RlKHRydWUpO1xyXG4gICAgICAgIGxpbmVfYnJlYWtlcl90LmlubmVySFRNTCA9IGxpbmVfYnJlYWtlcl9iLmlubmVySFRNTCA9IG9wdGlvbnMuaWNvbnMubGluZV9icmVhaztcclxuICAgIFxyXG4gICAgICAgIC8vIHJlc2l6ZSBvcGVyYXRpb24gYmFja2dyb3VuZFxyXG4gICAgICAgIGNvbnN0IHJlc2l6ZV9iYWNrID0gZG9jLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xyXG4gICAgICAgIHJlc2l6ZV9iYWNrLmNsYXNzTmFtZSA9ICdzZS1yZXNpemluZy1iYWNrJztcclxuXHJcbiAgICAgICAgLy8gdG9vbGJhciBjb250YWluZXJcclxuICAgICAgICBjb25zdCB0b29sYmFyQ29udGFpbmVyID0gb3B0aW9ucy50b29sYmFyQ29udGFpbmVyO1xyXG4gICAgICAgIGlmICh0b29sYmFyQ29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgIHRvb2xiYXJDb250YWluZXIuYXBwZW5kQ2hpbGQodG9vbF9iYXIuZWxlbWVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgXHJcbiAgICAgICAgLyoqIGFwcGVuZCBodG1sICovXHJcbiAgICAgICAgZWRpdG9yX2Rpdi5hcHBlbmRDaGlsZCh0ZXh0YXJlYSk7XHJcbiAgICAgICAgaWYgKHBsYWNlaG9sZGVyX3NwYW4pIGVkaXRvcl9kaXYuYXBwZW5kQ2hpbGQocGxhY2Vob2xkZXJfc3Bhbik7XHJcbiAgICAgICAgaWYgKCF0b29sYmFyQ29udGFpbmVyKSByZWxhdGl2ZS5hcHBlbmRDaGlsZCh0b29sX2Jhci5lbGVtZW50KTtcclxuICAgICAgICByZWxhdGl2ZS5hcHBlbmRDaGlsZChzdGlja3lfZHVtbXkpO1xyXG4gICAgICAgIHJlbGF0aXZlLmFwcGVuZENoaWxkKGVkaXRvcl9kaXYpO1xyXG4gICAgICAgIHJlbGF0aXZlLmFwcGVuZENoaWxkKHJlc2l6ZV9iYWNrKTtcclxuICAgICAgICByZWxhdGl2ZS5hcHBlbmRDaGlsZChsb2FkaW5nX2JveCk7XHJcbiAgICAgICAgcmVsYXRpdmUuYXBwZW5kQ2hpbGQobGluZV9icmVha2VyKTtcclxuICAgICAgICByZWxhdGl2ZS5hcHBlbmRDaGlsZChsaW5lX2JyZWFrZXJfdCk7XHJcbiAgICAgICAgcmVsYXRpdmUuYXBwZW5kQ2hpbGQobGluZV9icmVha2VyX2IpO1xyXG4gICAgICAgIGlmIChyZXNpemluZ19iYXIpIHJlbGF0aXZlLmFwcGVuZENoaWxkKHJlc2l6aW5nX2Jhcik7XHJcbiAgICAgICAgdG9wX2Rpdi5hcHBlbmRDaGlsZChyZWxhdGl2ZSk7XHJcblxyXG4gICAgICAgIHRleHRhcmVhID0gdGhpcy5fY2hlY2tDb2RlTWlycm9yKG9wdGlvbnMsIHRleHRhcmVhKTtcclxuICAgIFxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGNvbnN0cnVjdGVkOiB7XHJcbiAgICAgICAgICAgICAgICBfdG9wOiB0b3BfZGl2LFxyXG4gICAgICAgICAgICAgICAgX3JlbGF0aXZlOiByZWxhdGl2ZSxcclxuICAgICAgICAgICAgICAgIF90b29sQmFyOiB0b29sX2Jhci5lbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgX21lbnVUcmF5OiB0b29sX2Jhci5fbWVudVRyYXksXHJcbiAgICAgICAgICAgICAgICBfZWRpdG9yQXJlYTogZWRpdG9yX2RpdixcclxuICAgICAgICAgICAgICAgIF93eXNpd3lnQXJlYTogd3lzaXd5Z19kaXYsXHJcbiAgICAgICAgICAgICAgICBfY29kZUFyZWE6IHRleHRhcmVhLFxyXG4gICAgICAgICAgICAgICAgX3BsYWNlaG9sZGVyOiBwbGFjZWhvbGRlcl9zcGFuLFxyXG4gICAgICAgICAgICAgICAgX3Jlc2l6aW5nQmFyOiByZXNpemluZ19iYXIsXHJcbiAgICAgICAgICAgICAgICBfbmF2aWdhdGlvbjogbmF2aWdhdGlvbixcclxuICAgICAgICAgICAgICAgIF9jaGFyV3JhcHBlcjogY2hhcl93cmFwcGVyLFxyXG4gICAgICAgICAgICAgICAgX2NoYXJDb3VudGVyOiBjaGFyX2NvdW50ZXIsXHJcbiAgICAgICAgICAgICAgICBfbG9hZGluZzogbG9hZGluZ19ib3gsXHJcbiAgICAgICAgICAgICAgICBfbGluZUJyZWFrZXI6IGxpbmVfYnJlYWtlcixcclxuICAgICAgICAgICAgICAgIF9saW5lQnJlYWtlcl90OiBsaW5lX2JyZWFrZXJfdCxcclxuICAgICAgICAgICAgICAgIF9saW5lQnJlYWtlcl9iOiBsaW5lX2JyZWFrZXJfYixcclxuICAgICAgICAgICAgICAgIF9yZXNpemVCYWNrOiByZXNpemVfYmFjayxcclxuICAgICAgICAgICAgICAgIF9zdGlja3lEdW1teTogc3RpY2t5X2R1bW15LFxyXG4gICAgICAgICAgICAgICAgX2Fycm93OiBhcnJvd1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zLFxyXG4gICAgICAgICAgICBwbHVnaW5zOiB0b29sX2Jhci5wbHVnaW5zLFxyXG4gICAgICAgICAgICBwbHVnaW5DYWxsQnV0dG9uczogdG9vbF9iYXIucGx1Z2luQ2FsbEJ1dHRvbnMsXHJcbiAgICAgICAgICAgIF9yZXNwb25zaXZlQnV0dG9uczogdG9vbF9iYXIucmVzcG9uc2l2ZUJ1dHRvbnNcclxuICAgICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBDaGVjayB0aGUgQ29kZU1pcnJvciBvcHRpb24gdG8gYXBwbHkgdGhlIENvZGVNaXJyb3IgYW5kIHJldHVybiB0aGUgQ29kZU1pcnJvciBlbGVtZW50LlxyXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgb3B0aW9uc1xyXG4gICAgICogQHBhcmFtIHtFbGVtZW50fSB0ZXh0YXJlYSB0ZXh0YXJlYSBlbGVtZW50XHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBfY2hlY2tDb2RlTWlycm9yOiBmdW5jdGlvbiAob3B0aW9ucywgdGV4dGFyZWEpIHtcclxuICAgICAgICBpZiAob3B0aW9ucy5jb2RlTWlycm9yKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNtT3B0aW9ucyA9IFt7XHJcbiAgICAgICAgICAgICAgICBtb2RlOiAnaHRtbG1peGVkJyxcclxuICAgICAgICAgICAgICAgIGh0bWxNb2RlOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgbGluZU51bWJlcnM6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBsaW5lV3JhcHBpbmc6IHRydWVcclxuICAgICAgICAgICAgfSwgKG9wdGlvbnMuY29kZU1pcnJvci5vcHRpb25zIHx8IHt9KV0ucmVkdWNlKGZ1bmN0aW9uIChpbml0LCBvcHRpb24pIHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGtleSBpbiBvcHRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5oYXNPd24ob3B0aW9uLCBrZXkpKSBpbml0W2tleV0gPSBvcHRpb25ba2V5XTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBpbml0O1xyXG4gICAgICAgICAgICB9LCB7fSk7XHJcblxyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5oZWlnaHQgPT09ICdhdXRvJykge1xyXG4gICAgICAgICAgICAgICAgY21PcHRpb25zLnZpZXdwb3J0TWFyZ2luID0gSW5maW5pdHk7XHJcbiAgICAgICAgICAgICAgICBjbU9wdGlvbnMuaGVpZ2h0ID0gJ2F1dG8nO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBjb25zdCBjbSA9IG9wdGlvbnMuY29kZU1pcnJvci5zcmMuZnJvbVRleHRBcmVhKHRleHRhcmVhLCBjbU9wdGlvbnMpO1xyXG4gICAgICAgICAgICBjbS5kaXNwbGF5LndyYXBwZXIuc3R5bGUuY3NzVGV4dCA9IHRleHRhcmVhLnN0eWxlLmNzc1RleHQ7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBvcHRpb25zLmNvZGVNaXJyb3JFZGl0b3IgPSBjbTtcclxuICAgICAgICAgICAgdGV4dGFyZWEgPSBjbS5kaXNwbGF5LndyYXBwZXI7XHJcbiAgICAgICAgICAgIHRleHRhcmVhLmNsYXNzTmFtZSArPSAnIHNlLXdyYXBwZXItY29kZS1taXJyb3InO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRleHRhcmVhO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBDaGVjayBmb3IgYSBrYXRleCBvYmplY3QuXHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0ga2F0ZXgga2F0ZXggb2JqZWN0XHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBfY2hlY2tLYXRleE1hdGg6IGZ1bmN0aW9uIChrYXRleCkge1xyXG4gICAgICAgIGlmICgha2F0ZXgpIHRocm93IEVycm9yKCdbU1VORURJVE9SLmNyZWF0ZS5mYWlsXSBUbyB1c2UgdGhlIG1hdGggYnV0dG9uIHlvdSBuZWVkIHRvIGFkZCBhIFwia2F0ZXhcIiBvYmplY3QgdG8gdGhlIG9wdGlvbnMuJyk7XHJcblxyXG4gICAgICAgIGNvbnN0IGthdGV4T3B0aW9ucyA9IFt7XHJcbiAgICAgICAgICAgIHRocm93T25FcnJvcjogZmFsc2UsXHJcbiAgICAgICAgfSwgKGthdGV4Lm9wdGlvbnMgfHwge30pXS5yZWR1Y2UoZnVuY3Rpb24gKGluaXQsIG9wdGlvbikge1xyXG4gICAgICAgICAgICBmb3IgKGxldCBrZXkgaW4gb3B0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodXRpbC5oYXNPd24ob3B0aW9uLCBrZXkpKSBpbml0W2tleV0gPSBvcHRpb25ba2V5XTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gaW5pdDtcclxuICAgICAgICB9LCB7fSk7XHJcblxyXG4gICAgICAgIGthdGV4Lm9wdGlvbnMgPSBrYXRleE9wdGlvbnM7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIEFkZCBvciByZXNldCBvcHRpb25zXHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gbWVyZ2VPcHRpb25zIE5ldyBvcHRpb25zIHByb3BlcnR5XHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gY29udGV4dCBDb250ZXh0IG9iamVjdCBvZiBjb3JlXHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGx1Z2lucyBPcmlnaW4gcGx1Z2luc1xyXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9yaWdpbk9wdGlvbnMgT3JpZ2luIG9wdGlvbnNcclxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IHBsdWdpbkNhbGxCdXR0b25zXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBfc2V0T3B0aW9uczogZnVuY3Rpb24gKG1lcmdlT3B0aW9ucywgY29udGV4dCwgcGx1Z2lucywgb3JpZ2luT3B0aW9ucykge1xyXG4gICAgICAgIHRoaXMuX2luaXRPcHRpb25zKGNvbnRleHQuZWxlbWVudC5vcmlnaW5FbGVtZW50LCBtZXJnZU9wdGlvbnMpO1xyXG5cclxuICAgICAgICBjb25zdCBlbCA9IGNvbnRleHQuZWxlbWVudDtcclxuICAgICAgICBjb25zdCByZWxhdGl2ZSA9IGVsLnJlbGF0aXZlO1xyXG4gICAgICAgIGNvbnN0IGVkaXRvckFyZWEgPSBlbC5lZGl0b3JBcmVhO1xyXG4gICAgICAgIGNvbnN0IGlzTmV3VG9vbGJhckNvbnRhaW5lciA9IG1lcmdlT3B0aW9ucy50b29sYmFyQ29udGFpbmVyICYmIG1lcmdlT3B0aW9ucy50b29sYmFyQ29udGFpbmVyICE9PSBvcmlnaW5PcHRpb25zLnRvb2xiYXJDb250YWluZXI7XHJcbiAgICAgICAgY29uc3QgaXNOZXdUb29sYmFyID0gISFtZXJnZU9wdGlvbnMuYnV0dG9uTGlzdCB8fCBtZXJnZU9wdGlvbnMubW9kZSAhPT0gb3JpZ2luT3B0aW9ucy5tb2RlIHx8IGlzTmV3VG9vbGJhckNvbnRhaW5lcjtcclxuICAgICAgICBjb25zdCBpc05ld1BsdWdpbnMgPSAhIW1lcmdlT3B0aW9ucy5wbHVnaW5zO1xyXG5cclxuICAgICAgICBjb25zdCB0b29sX2JhciA9IHRoaXMuX2NyZWF0ZVRvb2xCYXIoZG9jdW1lbnQsIChpc05ld1Rvb2xiYXIgPyBtZXJnZU9wdGlvbnMuYnV0dG9uTGlzdCA6IG9yaWdpbk9wdGlvbnMuYnV0dG9uTGlzdCksIChpc05ld1BsdWdpbnMgPyBtZXJnZU9wdGlvbnMucGx1Z2lucyA6IHBsdWdpbnMpLCBtZXJnZU9wdGlvbnMpO1xyXG4gICAgICAgIGlmICh0b29sX2Jhci5wbHVnaW5DYWxsQnV0dG9ucy5tYXRoKSB0aGlzLl9jaGVja0thdGV4TWF0aChtZXJnZU9wdGlvbnMua2F0ZXgpO1xyXG4gICAgICAgIGNvbnN0IGFycm93ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnRElWJyk7XHJcbiAgICAgICAgYXJyb3cuY2xhc3NOYW1lID0gJ3NlLWFycm93JztcclxuXHJcbiAgICAgICAgaWYgKGlzTmV3VG9vbGJhcikge1xyXG4gICAgICAgICAgICB0b29sX2Jhci5lbGVtZW50LnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcclxuICAgICAgICAgICAgLy8gdG9vbGJhciBjb250YWluZXJcclxuICAgICAgICAgICAgaWYgKGlzTmV3VG9vbGJhckNvbnRhaW5lcikge1xyXG4gICAgICAgICAgICAgICAgbWVyZ2VPcHRpb25zLnRvb2xiYXJDb250YWluZXIuYXBwZW5kQ2hpbGQodG9vbF9iYXIuZWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICBlbC50b29sYmFyLnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoZWwudG9vbGJhcik7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBlbC50b29sYmFyLnBhcmVudEVsZW1lbnQucmVwbGFjZUNoaWxkKHRvb2xfYmFyLmVsZW1lbnQsIGVsLnRvb2xiYXIpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBlbC50b29sYmFyID0gdG9vbF9iYXIuZWxlbWVudDtcclxuICAgICAgICAgICAgZWwuX21lbnVUcmF5ID0gdG9vbF9iYXIuX21lbnVUcmF5O1xyXG4gICAgICAgICAgICBlbC5fYXJyb3cgPSBhcnJvdztcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgY29uc3QgaW5pdEVsZW1lbnRzID0gdGhpcy5faW5pdEVsZW1lbnRzKG1lcmdlT3B0aW9ucywgZWwudG9wQXJlYSwgKGlzTmV3VG9vbGJhciA/IHRvb2xfYmFyLmVsZW1lbnQgOiBlbC50b29sYmFyKSwgYXJyb3cpO1xyXG5cclxuICAgICAgICBjb25zdCBib3R0b21CYXIgPSBpbml0RWxlbWVudHMuYm90dG9tQmFyO1xyXG4gICAgICAgIGNvbnN0IHd5c2l3eWdGcmFtZSA9IGluaXRFbGVtZW50cy53eXNpd3lnRnJhbWU7XHJcbiAgICAgICAgY29uc3QgcGxhY2Vob2xkZXJfc3BhbiA9IGluaXRFbGVtZW50cy5wbGFjZWhvbGRlcjtcclxuICAgICAgICBsZXQgY29kZSA9IGluaXRFbGVtZW50cy5jb2RlVmlldztcclxuXHJcbiAgICAgICAgaWYgKGVsLnJlc2l6aW5nQmFyKSByZWxhdGl2ZS5yZW1vdmVDaGlsZChlbC5yZXNpemluZ0Jhcik7XHJcbiAgICAgICAgaWYgKGJvdHRvbUJhci5yZXNpemluZ0JhcikgcmVsYXRpdmUuYXBwZW5kQ2hpbGQoYm90dG9tQmFyLnJlc2l6aW5nQmFyKTtcclxuXHJcbiAgICAgICAgZWRpdG9yQXJlYS5pbm5lckhUTUwgPSAnJztcclxuICAgICAgICBlZGl0b3JBcmVhLmFwcGVuZENoaWxkKGNvZGUpO1xyXG4gICAgICAgIGlmIChwbGFjZWhvbGRlcl9zcGFuKSBlZGl0b3JBcmVhLmFwcGVuZENoaWxkKHBsYWNlaG9sZGVyX3NwYW4pO1xyXG5cclxuICAgICAgICBjb2RlID0gdGhpcy5fY2hlY2tDb2RlTWlycm9yKG1lcmdlT3B0aW9ucywgY29kZSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgZWwucmVzaXppbmdCYXIgPSBib3R0b21CYXIucmVzaXppbmdCYXI7XHJcbiAgICAgICAgZWwubmF2aWdhdGlvbiA9IGJvdHRvbUJhci5uYXZpZ2F0aW9uO1xyXG4gICAgICAgIGVsLmNoYXJXcmFwcGVyID0gYm90dG9tQmFyLmNoYXJXcmFwcGVyO1xyXG4gICAgICAgIGVsLmNoYXJDb3VudGVyID0gYm90dG9tQmFyLmNoYXJDb3VudGVyO1xyXG4gICAgICAgIGVsLnd5c2l3eWdGcmFtZSA9IHd5c2l3eWdGcmFtZTtcclxuICAgICAgICBlbC5jb2RlID0gY29kZTtcclxuICAgICAgICBlbC5wbGFjZWhvbGRlciA9IHBsYWNlaG9sZGVyX3NwYW47XHJcblxyXG4gICAgICAgIGlmIChtZXJnZU9wdGlvbnMucnRsKSB1dGlsLmFkZENsYXNzKGVsLnRvcEFyZWEsICdzZS1ydGwnKTtcclxuICAgICAgICBlbHNlIHV0aWwucmVtb3ZlQ2xhc3MoZWwudG9wQXJlYSwgJ3NlLXJ0bCcpO1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBjYWxsQnV0dG9uczogaXNOZXdUb29sYmFyID8gdG9vbF9iYXIucGx1Z2luQ2FsbEJ1dHRvbnMgOiBudWxsLFxyXG4gICAgICAgICAgICBwbHVnaW5zOiBpc05ld1Rvb2xiYXIgfHwgaXNOZXdQbHVnaW5zID8gdG9vbF9iYXIucGx1Z2lucyA6IG51bGwsXHJcbiAgICAgICAgICAgIHRvb2xiYXI6IHRvb2xfYmFyXHJcbiAgICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gSW5pdGlhbGl6ZSBwcm9wZXJ0eSBvZiBzdW5lZGl0b3IgZWxlbWVudHNcclxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIE9wdGlvbnNcclxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gdG9wRGl2IFN1bmVkaXRvciB0b3AgZGl2XHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IHRvb2xCYXIgVG9vbCBiYXJcclxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gdG9vbEJhckFycm93IFRvb2wgYmFyIGFycm93IChiYWxsb29uIGVkaXRvcilcclxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IEJvdHRvbSBiYXIgZWxlbWVudHMgKHJlc2l6aW5nQmFyLCBuYXZpZ2F0aW9uLCBjaGFyV3JhcHBlciwgY2hhckNvdW50ZXIpXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBfaW5pdEVsZW1lbnRzOiBmdW5jdGlvbiAob3B0aW9ucywgdG9wRGl2LCB0b29sQmFyLCB0b29sQmFyQXJyb3cpIHtcclxuICAgICAgICAvKiogdG9wIGRpdiAqL1xyXG4gICAgICAgIHRvcERpdi5zdHlsZS5jc3NUZXh0ID0gb3B0aW9ucy5fZWRpdG9yU3R5bGVzLnRvcDtcclxuXHJcbiAgICAgICAgLyoqIHRvb2xiYXIgKi9cclxuICAgICAgICBpZiAoL2lubGluZS9pLnRlc3Qob3B0aW9ucy5tb2RlKSkge1xyXG4gICAgICAgICAgICB0b29sQmFyLmNsYXNzTmFtZSArPSAnIHNlLXRvb2xiYXItaW5saW5lJztcclxuICAgICAgICAgICAgdG9vbEJhci5zdHlsZS53aWR0aCA9IG9wdGlvbnMudG9vbGJhcldpZHRoO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoL2JhbGxvb24vaS50ZXN0KG9wdGlvbnMubW9kZSkpIHtcclxuICAgICAgICAgICAgdG9vbEJhci5jbGFzc05hbWUgKz0gJyBzZS10b29sYmFyLWJhbGxvb24nO1xyXG4gICAgICAgICAgICB0b29sQmFyLnN0eWxlLndpZHRoID0gb3B0aW9ucy50b29sYmFyV2lkdGg7XHJcbiAgICAgICAgICAgIHRvb2xCYXIuYXBwZW5kQ2hpbGQodG9vbEJhckFycm93KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKiBlZGl0b3IgKi9cclxuICAgICAgICAvLyB3eXNpd3lnIGRpdiBvciBpZnJhbWVcclxuICAgICAgICBjb25zdCB3eXNpd3lnRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCghb3B0aW9ucy5pZnJhbWUgPyAnRElWJyA6ICdJRlJBTUUnKTtcclxuICAgICAgICB3eXNpd3lnRGl2LmNsYXNzTmFtZSA9ICdzZS13cmFwcGVyLWlubmVyIHNlLXdyYXBwZXItd3lzaXd5Zyc7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKCFvcHRpb25zLmlmcmFtZSkge1xyXG4gICAgICAgICAgICB3eXNpd3lnRGl2LnNldEF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJywgdHJ1ZSk7XHJcbiAgICAgICAgICAgIHd5c2l3eWdEaXYuc2V0QXR0cmlidXRlKCdzY3JvbGxpbmcnLCAnYXV0bycpO1xyXG4gICAgICAgICAgICB3eXNpd3lnRGl2LmNsYXNzTmFtZSArPSAnICcgKyBvcHRpb25zLl9lZGl0YWJsZUNsYXNzO1xyXG4gICAgICAgICAgICB3eXNpd3lnRGl2LnN0eWxlLmNzc1RleHQgPSBvcHRpb25zLl9lZGl0b3JTdHlsZXMuZnJhbWUgKyBvcHRpb25zLl9lZGl0b3JTdHlsZXMuZWRpdG9yO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHd5c2l3eWdEaXYuYWxsb3dGdWxsc2NyZWVuID0gdHJ1ZTtcclxuICAgICAgICAgICAgd3lzaXd5Z0Rpdi5mcmFtZUJvcmRlciA9IDA7XHJcbiAgICAgICAgICAgIHd5c2l3eWdEaXYuc3R5bGUuY3NzVGV4dCA9IG9wdGlvbnMuX2VkaXRvclN0eWxlcy5mcmFtZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIHRleHRhcmVhIGZvciBjb2RlIHZpZXdcclxuICAgICAgICBjb25zdCB0ZXh0YXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ1RFWFRBUkVBJyk7XHJcbiAgICAgICAgdGV4dGFyZWEuY2xhc3NOYW1lID0gJ3NlLXdyYXBwZXItaW5uZXIgc2Utd3JhcHBlci1jb2RlJztcclxuICAgICAgICB0ZXh0YXJlYS5zdHlsZS5jc3NUZXh0ID0gb3B0aW9ucy5fZWRpdG9yU3R5bGVzLmZyYW1lO1xyXG4gICAgICAgIHRleHRhcmVhLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgaWYgKG9wdGlvbnMuaGVpZ2h0ID09PSAnYXV0bycpIHRleHRhcmVhLnN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbic7XHJcblxyXG4gICAgICAgIC8qKiByZXNpemUgYmFyICovXHJcbiAgICAgICAgbGV0IHJlc2l6aW5nQmFyID0gbnVsbDtcclxuICAgICAgICBsZXQgbmF2aWdhdGlvbiA9IG51bGw7XHJcbiAgICAgICAgbGV0IGNoYXJXcmFwcGVyID0gbnVsbDtcclxuICAgICAgICBsZXQgY2hhckNvdW50ZXIgPSBudWxsO1xyXG4gICAgICAgIGlmIChvcHRpb25zLnJlc2l6aW5nQmFyKSB7XHJcbiAgICAgICAgICAgIHJlc2l6aW5nQmFyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnRElWJyk7XHJcbiAgICAgICAgICAgIHJlc2l6aW5nQmFyLmNsYXNzTmFtZSA9ICdzZS1yZXNpemluZy1iYXIgc3VuLWVkaXRvci1jb21tb24nO1xyXG5cclxuICAgICAgICAgICAgLyoqIG5hdmlnYXRpb24gKi9cclxuICAgICAgICAgICAgbmF2aWdhdGlvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xyXG4gICAgICAgICAgICBuYXZpZ2F0aW9uLmNsYXNzTmFtZSA9ICdzZS1uYXZpZ2F0aW9uIHN1bi1lZGl0b3ItY29tbW9uJztcclxuICAgICAgICAgICAgcmVzaXppbmdCYXIuYXBwZW5kQ2hpbGQobmF2aWdhdGlvbik7XHJcblxyXG4gICAgICAgICAgICAvKiogY2hhciBjb3VudGVyICovXHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmNoYXJDb3VudGVyKSB7XHJcbiAgICAgICAgICAgICAgICBjaGFyV3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xyXG4gICAgICAgICAgICAgICAgY2hhcldyYXBwZXIuY2xhc3NOYW1lID0gJ3NlLWNoYXItY291bnRlci13cmFwcGVyJztcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5jaGFyQ291bnRlckxhYmVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhckxhYmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnU1BBTicpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNoYXJMYWJlbC5jbGFzc05hbWUgPSAnc2UtY2hhci1sYWJlbCc7XHJcbiAgICAgICAgICAgICAgICAgICAgY2hhckxhYmVsLnRleHRDb250ZW50ID0gb3B0aW9ucy5jaGFyQ291bnRlckxhYmVsO1xyXG4gICAgICAgICAgICAgICAgICAgIGNoYXJXcmFwcGVyLmFwcGVuZENoaWxkKGNoYXJMYWJlbCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICBcclxuICAgICAgICAgICAgICAgIGNoYXJDb3VudGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnU1BBTicpO1xyXG4gICAgICAgICAgICAgICAgY2hhckNvdW50ZXIuY2xhc3NOYW1lID0gJ3NlLWNoYXItY291bnRlcic7XHJcbiAgICAgICAgICAgICAgICBjaGFyQ291bnRlci50ZXh0Q29udGVudCA9ICcwJztcclxuICAgICAgICAgICAgICAgIGNoYXJXcmFwcGVyLmFwcGVuZENoaWxkKGNoYXJDb3VudGVyKTtcclxuICAgIFxyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMubWF4Q2hhckNvdW50ID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXJfbWF4ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnU1BBTicpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNoYXJfbWF4LnRleHRDb250ZW50ID0gJyAvICcgKyBvcHRpb25zLm1heENoYXJDb3VudDtcclxuICAgICAgICAgICAgICAgICAgICBjaGFyV3JhcHBlci5hcHBlbmRDaGlsZChjaGFyX21heCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmVzaXppbmdCYXIuYXBwZW5kQ2hpbGQoY2hhcldyYXBwZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIGxldCBwbGFjZWhvbGRlciA9IG51bGw7XHJcbiAgICAgICAgaWYgKG9wdGlvbnMucGxhY2Vob2xkZXIpIHtcclxuICAgICAgICAgICAgcGxhY2Vob2xkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdTUEFOJyk7XHJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyLmNsYXNzTmFtZSA9ICdzZS1wbGFjZWhvbGRlcic7XHJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyLmlubmVyVGV4dCA9IG9wdGlvbnMucGxhY2Vob2xkZXI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBib3R0b21CYXI6IHtcclxuICAgICAgICAgICAgICAgIHJlc2l6aW5nQmFyOiByZXNpemluZ0JhcixcclxuICAgICAgICAgICAgICAgIG5hdmlnYXRpb246IG5hdmlnYXRpb24sXHJcbiAgICAgICAgICAgICAgICBjaGFyV3JhcHBlcjogY2hhcldyYXBwZXIsXHJcbiAgICAgICAgICAgICAgICBjaGFyQ291bnRlcjogY2hhckNvdW50ZXJcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgd3lzaXd5Z0ZyYW1lOiB3eXNpd3lnRGl2LFxyXG4gICAgICAgICAgICBjb2RlVmlldzogdGV4dGFyZWEsXHJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyOiBwbGFjZWhvbGRlclxyXG4gICAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIEluaXRpYWxpemUgb3B0aW9uc1xyXG4gICAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IE9wdGlvbnMgb2JqZWN0XHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBPcHRpb25zIG9iamVjdFxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX2luaXRPcHRpb25zOiBmdW5jdGlvbiAoZWxlbWVudCwgb3B0aW9ucykge1xyXG4gICAgICAgIC8qKiBWYWx1ZXMgKi9cclxuICAgICAgICBvcHRpb25zLmxhbmcgPSBvcHRpb25zLmxhbmcgfHwgX2RlZmF1bHRMYW5nO1xyXG4gICAgICAgIG9wdGlvbnMuZGVmYXVsdFRhZyA9IHR5cGVvZiBvcHRpb25zLmRlZmF1bHRUYWcgPT09ICdzdHJpbmcnID8gb3B0aW9ucy5kZWZhdWx0VGFnIDogJ3AnO1xyXG4gICAgICAgIG9wdGlvbnMudmFsdWUgPSB0eXBlb2Ygb3B0aW9ucy52YWx1ZSA9PT0gJ3N0cmluZycgPyBvcHRpb25zLnZhbHVlIDogbnVsbDtcclxuICAgICAgICBvcHRpb25zLmhpc3RvcnlTdGFja0RlbGF5VGltZSA9IHR5cGVvZiBvcHRpb25zLmhpc3RvcnlTdGFja0RlbGF5VGltZSA9PT0gJ251bWJlcicgPyBvcHRpb25zLmhpc3RvcnlTdGFja0RlbGF5VGltZSA6IDQwMDtcclxuICAgICAgICAvKiogV2hpdGVsaXN0ICovXHJcbiAgICAgICAgb3B0aW9ucy5fZGVmYXVsdFRhZ3NXaGl0ZWxpc3QgPSB0eXBlb2Ygb3B0aW9ucy5fZGVmYXVsdFRhZ3NXaGl0ZWxpc3QgPT09ICdzdHJpbmcnID8gb3B0aW9ucy5fZGVmYXVsdFRhZ3NXaGl0ZWxpc3QgOiAnYnJ8cHxkaXZ8cHJlfGJsb2NrcXVvdGV8aFsxLTZdfG9sfHVsfGxpfGhyfGZpZ3VyZXxmaWdjYXB0aW9ufGltZ3xpZnJhbWV8YXVkaW98dmlkZW98c291cmNlfHRhYmxlfHRoZWFkfHRib2R5fHRyfHRofHRkfGF8YnxzdHJvbmd8dmFyfGl8ZW18dXxpbnN8c3xzcGFufHN0cmlrZXxkZWx8c3VifHN1cHxjb2RlJztcclxuICAgICAgICBvcHRpb25zLl9lZGl0b3JUYWdzV2hpdGVsaXN0ID0gb3B0aW9ucy5fZGVmYXVsdFRhZ3NXaGl0ZWxpc3QgKyAodHlwZW9mIG9wdGlvbnMuYWRkVGFnc1doaXRlbGlzdCA9PT0gJ3N0cmluZycgJiYgb3B0aW9ucy5hZGRUYWdzV2hpdGVsaXN0Lmxlbmd0aCA+IDAgPyAnfCcgKyBvcHRpb25zLmFkZFRhZ3NXaGl0ZWxpc3QgOiAnJyk7XHJcbiAgICAgICAgb3B0aW9ucy5wYXN0ZVRhZ3NXaGl0ZWxpc3QgPSB0eXBlb2Ygb3B0aW9ucy5wYXN0ZVRhZ3NXaGl0ZWxpc3QgPT09ICdzdHJpbmcnID8gb3B0aW9ucy5wYXN0ZVRhZ3NXaGl0ZWxpc3QgOiBvcHRpb25zLl9lZGl0b3JUYWdzV2hpdGVsaXN0O1xyXG4gICAgICAgIG9wdGlvbnMuYXR0cmlidXRlc1doaXRlbGlzdCA9ICghb3B0aW9ucy5hdHRyaWJ1dGVzV2hpdGVsaXN0IHx8IHR5cGVvZiBvcHRpb25zLmF0dHJpYnV0ZXNXaGl0ZWxpc3QgIT09ICdvYmplY3QnKSA/IG51bGwgOiBvcHRpb25zLmF0dHJpYnV0ZXNXaGl0ZWxpc3Q7XHJcbiAgICAgICAgLyoqIExheW91dCAqL1xyXG4gICAgICAgIG9wdGlvbnMubW9kZSA9IG9wdGlvbnMubW9kZSB8fCAnY2xhc3NpYyc7IC8vIGNsYXNzaWMsIGlubGluZSwgYmFsbG9vbiwgYmFsbG9vbi1hbHdheXNcclxuICAgICAgICBvcHRpb25zLnJ0bCA9ICEhb3B0aW9ucy5ydGw7XHJcbiAgICAgICAgb3B0aW9ucy5fZWRpdGFibGVDbGFzcyA9ICdzdW4tZWRpdG9yLWVkaXRhYmxlJyArIChvcHRpb25zLnJ0bCA/ICcgc2UtcnRsJyA6ICcnKTtcclxuICAgICAgICBvcHRpb25zLnRvb2xiYXJXaWR0aCA9IG9wdGlvbnMudG9vbGJhcldpZHRoID8gKHV0aWwuaXNOdW1iZXIob3B0aW9ucy50b29sYmFyV2lkdGgpID8gb3B0aW9ucy50b29sYmFyV2lkdGggKyAncHgnIDogb3B0aW9ucy50b29sYmFyV2lkdGgpIDogJ2F1dG8nO1xyXG4gICAgICAgIG9wdGlvbnMudG9vbGJhckNvbnRhaW5lciA9IHR5cGVvZiBvcHRpb25zLnRvb2xiYXJDb250YWluZXIgPT09ICdzdHJpbmcnID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihvcHRpb25zLnRvb2xiYXJDb250YWluZXIpIDogb3B0aW9ucy50b29sYmFyQ29udGFpbmVyO1xyXG4gICAgICAgIG9wdGlvbnMuc3RpY2t5VG9vbGJhciA9ICgvYmFsbG9vbi9pLnRlc3Qob3B0aW9ucy5tb2RlKSB8fCAhIW9wdGlvbnMudG9vbGJhckNvbnRhaW5lcikgPyAtMSA6IG9wdGlvbnMuc3RpY2t5VG9vbGJhciA9PT0gdW5kZWZpbmVkID8gMCA6ICgvXlxcZCsvLnRlc3Qob3B0aW9ucy5zdGlja3lUb29sYmFyKSA/IHV0aWwuZ2V0TnVtYmVyKG9wdGlvbnMuc3RpY2t5VG9vbGJhciwgMCkgOiAtMSk7XHJcbiAgICAgICAgb3B0aW9ucy5pZnJhbWUgPSBvcHRpb25zLmZ1bGxQYWdlIHx8IG9wdGlvbnMuaWZyYW1lO1xyXG4gICAgICAgIG9wdGlvbnMuZnVsbFBhZ2UgPSAhIW9wdGlvbnMuZnVsbFBhZ2U7XHJcbiAgICAgICAgb3B0aW9ucy5pZnJhbWVDU1NGaWxlTmFtZSA9IG9wdGlvbnMuaWZyYW1lID8gdHlwZW9mIG9wdGlvbnMuaWZyYW1lQ1NTRmlsZU5hbWUgPT09ICdzdHJpbmcnID8gW29wdGlvbnMuaWZyYW1lQ1NTRmlsZU5hbWVdIDogKG9wdGlvbnMuaWZyYW1lQ1NTRmlsZU5hbWUgfHwgWydzdW5lZGl0b3InXSkgOiBudWxsO1xyXG4gICAgICAgIG9wdGlvbnMucHJldmlld1RlbXBsYXRlID0gdHlwZW9mIG9wdGlvbnMucHJldmlld1RlbXBsYXRlID09PSAnc3RyaW5nJyA/IG9wdGlvbnMucHJldmlld1RlbXBsYXRlIDogbnVsbDtcclxuICAgICAgICAvKiogQ29kZU1pcnJvciBvYmplY3QgKi9cclxuICAgICAgICBvcHRpb25zLmNvZGVNaXJyb3IgPSBvcHRpb25zLmNvZGVNaXJyb3IgPyBvcHRpb25zLmNvZGVNaXJyb3Iuc3JjID8gb3B0aW9ucy5jb2RlTWlycm9yIDoge3NyYzogb3B0aW9ucy5jb2RlTWlycm9yfSA6IG51bGw7XHJcbiAgICAgICAgLyoqIGthdGV4IG9iamVjdCAoTWF0aCBwbHVnaW4pICovXHJcbiAgICAgICAgb3B0aW9ucy5rYXRleCA9IG9wdGlvbnMua2F0ZXggPyBvcHRpb25zLmthdGV4LnNyYyA/IG9wdGlvbnMua2F0ZXggOiB7c3JjOiBvcHRpb25zLmthdGV4fSA6IG51bGw7XHJcbiAgICAgICAgLyoqIERpc3BsYXkgKi9cclxuICAgICAgICBvcHRpb25zLnBvc2l0aW9uID0gdHlwZW9mIG9wdGlvbnMucG9zaXRpb24gPT09ICdzdHJpbmcnID8gb3B0aW9ucy5wb3NpdGlvbiA6IG51bGw7XHJcbiAgICAgICAgb3B0aW9ucy5kaXNwbGF5ID0gb3B0aW9ucy5kaXNwbGF5IHx8IChlbGVtZW50LnN0eWxlLmRpc3BsYXkgPT09ICdub25lJyB8fCAhZWxlbWVudC5zdHlsZS5kaXNwbGF5ID8gJ2Jsb2NrJyA6IGVsZW1lbnQuc3R5bGUuZGlzcGxheSk7XHJcbiAgICAgICAgb3B0aW9ucy5wb3B1cERpc3BsYXkgPSBvcHRpb25zLnBvcHVwRGlzcGxheSB8fCAnZnVsbCc7XHJcbiAgICAgICAgLyoqIEJvdHRvbSByZXNpemluZyBiYXIgKi9cclxuICAgICAgICBvcHRpb25zLnJlc2l6aW5nQmFyID0gb3B0aW9ucy5yZXNpemluZ0JhciA9PT0gdW5kZWZpbmVkID8gKC9pbmxpbmV8YmFsbG9vbi9pLnRlc3Qob3B0aW9ucy5tb2RlKSA/IGZhbHNlIDogdHJ1ZSkgOiBvcHRpb25zLnJlc2l6aW5nQmFyO1xyXG4gICAgICAgIG9wdGlvbnMuc2hvd1BhdGhMYWJlbCA9ICFvcHRpb25zLnJlc2l6aW5nQmFyID8gZmFsc2UgOiB0eXBlb2Ygb3B0aW9ucy5zaG93UGF0aExhYmVsID09PSAnYm9vbGVhbicgPyBvcHRpb25zLnNob3dQYXRoTGFiZWwgOiB0cnVlO1xyXG4gICAgICAgIC8qKiBDaGFyYWN0ZXIgY291bnQgKi9cclxuICAgICAgICBvcHRpb25zLmNoYXJDb3VudGVyID0gb3B0aW9ucy5tYXhDaGFyQ291bnQgPiAwID8gdHJ1ZSA6IHR5cGVvZiBvcHRpb25zLmNoYXJDb3VudGVyID09PSAnYm9vbGVhbicgPyBvcHRpb25zLmNoYXJDb3VudGVyIDogZmFsc2U7XHJcbiAgICAgICAgb3B0aW9ucy5jaGFyQ291bnRlclR5cGUgPSB0eXBlb2Ygb3B0aW9ucy5jaGFyQ291bnRlclR5cGUgPT09ICdzdHJpbmcnID8gb3B0aW9ucy5jaGFyQ291bnRlclR5cGUgOiAnY2hhcic7XHJcbiAgICAgICAgb3B0aW9ucy5jaGFyQ291bnRlckxhYmVsID0gdHlwZW9mIG9wdGlvbnMuY2hhckNvdW50ZXJMYWJlbCA9PT0gJ3N0cmluZycgPyBvcHRpb25zLmNoYXJDb3VudGVyTGFiZWwudHJpbSgpIDogbnVsbDtcclxuICAgICAgICBvcHRpb25zLm1heENoYXJDb3VudCA9IHV0aWwuaXNOdW1iZXIob3B0aW9ucy5tYXhDaGFyQ291bnQpICYmIG9wdGlvbnMubWF4Q2hhckNvdW50ID4gLTEgPyBvcHRpb25zLm1heENoYXJDb3VudCAqIDEgOiBudWxsO1xyXG4gICAgICAgIC8qKiBXaWR0aCBzaXplICovXHJcbiAgICAgICAgb3B0aW9ucy53aWR0aCA9IG9wdGlvbnMud2lkdGggPyAodXRpbC5pc051bWJlcihvcHRpb25zLndpZHRoKSA/IG9wdGlvbnMud2lkdGggKyAncHgnIDogb3B0aW9ucy53aWR0aCkgOiAoZWxlbWVudC5jbGllbnRXaWR0aCA/IGVsZW1lbnQuY2xpZW50V2lkdGggKyAncHgnIDogJzEwMCUnKTtcclxuICAgICAgICBvcHRpb25zLm1pbldpZHRoID0gKHV0aWwuaXNOdW1iZXIob3B0aW9ucy5taW5XaWR0aCkgPyBvcHRpb25zLm1pbldpZHRoICsgJ3B4JyA6IG9wdGlvbnMubWluV2lkdGgpIHx8ICcnO1xyXG4gICAgICAgIG9wdGlvbnMubWF4V2lkdGggPSAodXRpbC5pc051bWJlcihvcHRpb25zLm1heFdpZHRoKSA/IG9wdGlvbnMubWF4V2lkdGggKyAncHgnIDogb3B0aW9ucy5tYXhXaWR0aCkgfHwgJyc7XHJcbiAgICAgICAgLyoqIEhlaWdodCBzaXplICovXHJcbiAgICAgICAgb3B0aW9ucy5oZWlnaHQgPSBvcHRpb25zLmhlaWdodCA/ICh1dGlsLmlzTnVtYmVyKG9wdGlvbnMuaGVpZ2h0KSA/IG9wdGlvbnMuaGVpZ2h0ICsgJ3B4JyA6IG9wdGlvbnMuaGVpZ2h0KSA6IChlbGVtZW50LmNsaWVudEhlaWdodCA/IGVsZW1lbnQuY2xpZW50SGVpZ2h0ICsgJ3B4JyA6ICdhdXRvJyk7XHJcbiAgICAgICAgb3B0aW9ucy5taW5IZWlnaHQgPSAodXRpbC5pc051bWJlcihvcHRpb25zLm1pbkhlaWdodCkgPyBvcHRpb25zLm1pbkhlaWdodCArICdweCcgOiBvcHRpb25zLm1pbkhlaWdodCkgfHwgJyc7XHJcbiAgICAgICAgb3B0aW9ucy5tYXhIZWlnaHQgPSAodXRpbC5pc051bWJlcihvcHRpb25zLm1heEhlaWdodCkgPyBvcHRpb25zLm1heEhlaWdodCArICdweCcgOiBvcHRpb25zLm1heEhlaWdodCkgfHwgJyc7XHJcbiAgICAgICAgLyoqIEVkaXRpbmcgYXJlYSBkZWZhdWx0IHN0eWxlICovXHJcbiAgICAgICAgb3B0aW9ucy5kZWZhdWx0U3R5bGUgPSB0eXBlb2Ygb3B0aW9ucy5kZWZhdWx0U3R5bGUgPT09ICdzdHJpbmcnID8gb3B0aW9ucy5kZWZhdWx0U3R5bGUgOiAnJztcclxuICAgICAgICAvKiogRGVmaW5pbmcgbWVudSBpdGVtcyAqL1xyXG4gICAgICAgIG9wdGlvbnMuZm9udCA9ICFvcHRpb25zLmZvbnQgPyBudWxsIDogb3B0aW9ucy5mb250O1xyXG4gICAgICAgIG9wdGlvbnMuZm9udFNpemUgPSAhb3B0aW9ucy5mb250U2l6ZSA/IG51bGwgOiBvcHRpb25zLmZvbnRTaXplO1xyXG4gICAgICAgIG9wdGlvbnMuZm9ybWF0cyA9ICFvcHRpb25zLmZvcm1hdHMgPyBudWxsIDogb3B0aW9ucy5mb3JtYXRzO1xyXG4gICAgICAgIG9wdGlvbnMuY29sb3JMaXN0ID0gIW9wdGlvbnMuY29sb3JMaXN0ID8gbnVsbCA6IG9wdGlvbnMuY29sb3JMaXN0O1xyXG4gICAgICAgIG9wdGlvbnMubGluZUhlaWdodHMgPSAhb3B0aW9ucy5saW5lSGVpZ2h0cyA/IG51bGwgOiBvcHRpb25zLmxpbmVIZWlnaHRzO1xyXG4gICAgICAgIG9wdGlvbnMucGFyYWdyYXBoU3R5bGVzID0gIW9wdGlvbnMucGFyYWdyYXBoU3R5bGVzID8gbnVsbCA6IG9wdGlvbnMucGFyYWdyYXBoU3R5bGVzO1xyXG4gICAgICAgIG9wdGlvbnMudGV4dFN0eWxlcyA9ICFvcHRpb25zLnRleHRTdHlsZXMgPyBudWxsIDogb3B0aW9ucy50ZXh0U3R5bGVzO1xyXG4gICAgICAgIG9wdGlvbnMuZm9udFNpemVVbml0ID0gdHlwZW9mIG9wdGlvbnMuZm9udFNpemVVbml0ID09PSAnc3RyaW5nJyA/IChvcHRpb25zLmZvbnRTaXplVW5pdC50cmltKCkgfHwgJ3B4JykgOiAncHgnO1xyXG4gICAgICAgIC8qKiBJbWFnZSAqL1xyXG4gICAgICAgIG9wdGlvbnMuaW1hZ2VSZXNpemluZyA9IG9wdGlvbnMuaW1hZ2VSZXNpemluZyA9PT0gdW5kZWZpbmVkID8gdHJ1ZSA6IG9wdGlvbnMuaW1hZ2VSZXNpemluZztcclxuICAgICAgICBvcHRpb25zLmltYWdlSGVpZ2h0U2hvdyA9IG9wdGlvbnMuaW1hZ2VIZWlnaHRTaG93ID09PSB1bmRlZmluZWQgPyB0cnVlIDogISFvcHRpb25zLmltYWdlSGVpZ2h0U2hvdztcclxuICAgICAgICBvcHRpb25zLmltYWdlV2lkdGggPSAhb3B0aW9ucy5pbWFnZVdpZHRoID8gJ2F1dG8nIDogdXRpbC5pc051bWJlcihvcHRpb25zLmltYWdlV2lkdGgpID8gb3B0aW9ucy5pbWFnZVdpZHRoICsgJ3B4JyA6IG9wdGlvbnMuaW1hZ2VXaWR0aDtcclxuICAgICAgICBvcHRpb25zLmltYWdlSGVpZ2h0ID0gIW9wdGlvbnMuaW1hZ2VIZWlnaHQgPyAnYXV0bycgOiB1dGlsLmlzTnVtYmVyKG9wdGlvbnMuaW1hZ2VIZWlnaHQpID8gb3B0aW9ucy5pbWFnZUhlaWdodCArICdweCcgOiBvcHRpb25zLmltYWdlSGVpZ2h0O1xyXG4gICAgICAgIG9wdGlvbnMuaW1hZ2VTaXplT25seVBlcmNlbnRhZ2UgPSAhIW9wdGlvbnMuaW1hZ2VTaXplT25seVBlcmNlbnRhZ2U7XHJcbiAgICAgICAgb3B0aW9ucy5faW1hZ2VTaXplVW5pdCA9IG9wdGlvbnMuaW1hZ2VTaXplT25seVBlcmNlbnRhZ2UgPyAnJScgOiAncHgnO1xyXG4gICAgICAgIG9wdGlvbnMuaW1hZ2VSb3RhdGlvbiA9IG9wdGlvbnMuaW1hZ2VSb3RhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5pbWFnZVJvdGF0aW9uIDogIShvcHRpb25zLmltYWdlU2l6ZU9ubHlQZXJjZW50YWdlIHx8ICFvcHRpb25zLmltYWdlSGVpZ2h0U2hvdyk7XHJcbiAgICAgICAgb3B0aW9ucy5pbWFnZUZpbGVJbnB1dCA9IG9wdGlvbnMuaW1hZ2VGaWxlSW5wdXQgPT09IHVuZGVmaW5lZCA/IHRydWUgOiBvcHRpb25zLmltYWdlRmlsZUlucHV0O1xyXG4gICAgICAgIG9wdGlvbnMuaW1hZ2VVcmxJbnB1dCA9IChvcHRpb25zLmltYWdlVXJsSW5wdXQgPT09IHVuZGVmaW5lZCB8fCAhb3B0aW9ucy5pbWFnZUZpbGVJbnB1dCkgPyB0cnVlIDogb3B0aW9ucy5pbWFnZVVybElucHV0O1xyXG4gICAgICAgIG9wdGlvbnMuaW1hZ2VVcGxvYWRIZWFkZXIgPSBvcHRpb25zLmltYWdlVXBsb2FkSGVhZGVyIHx8IG51bGw7XHJcbiAgICAgICAgb3B0aW9ucy5pbWFnZVVwbG9hZFVybCA9IHR5cGVvZiBvcHRpb25zLmltYWdlVXBsb2FkVXJsID09PSAnc3RyaW5nJyA/IG9wdGlvbnMuaW1hZ2VVcGxvYWRVcmwgOiBudWxsO1xyXG4gICAgICAgIG9wdGlvbnMuaW1hZ2VVcGxvYWRTaXplTGltaXQgPSAvXFxkKy8udGVzdChvcHRpb25zLmltYWdlVXBsb2FkU2l6ZUxpbWl0KSA/IHV0aWwuZ2V0TnVtYmVyKG9wdGlvbnMuaW1hZ2VVcGxvYWRTaXplTGltaXQsIDApIDogbnVsbDtcclxuICAgICAgICBvcHRpb25zLmltYWdlTXVsdGlwbGVGaWxlID0gISFvcHRpb25zLmltYWdlTXVsdGlwbGVGaWxlO1xyXG4gICAgICAgIG9wdGlvbnMuaW1hZ2VBY2NlcHQgPSAodHlwZW9mIG9wdGlvbnMuaW1hZ2VBY2NlcHQgIT09ICdzdHJpbmcnIHx8IG9wdGlvbnMuaW1hZ2VBY2NlcHQudHJpbSgpID09PSBcIipcIikgPyAnaW1hZ2UvKicgOiBvcHRpb25zLmltYWdlQWNjZXB0LnRyaW0oKSB8fCAnaW1hZ2UvKic7XHJcbiAgICAgICAgLyoqIEltYWdlIC0gaW1hZ2UgZ2FsbGVyeSAqL1xyXG4gICAgICAgIG9wdGlvbnMuaW1hZ2VHYWxsZXJ5VXJsID0gdHlwZW9mIG9wdGlvbnMuaW1hZ2VHYWxsZXJ5VXJsID09PSAnc3RyaW5nJyA/IG9wdGlvbnMuaW1hZ2VHYWxsZXJ5VXJsIDogbnVsbDtcclxuICAgICAgICAvKiogVmlkZW8gKi9cclxuICAgICAgICBvcHRpb25zLnZpZGVvUmVzaXppbmcgPSBvcHRpb25zLnZpZGVvUmVzaXppbmcgPT09IHVuZGVmaW5lZCA/IHRydWUgOiBvcHRpb25zLnZpZGVvUmVzaXppbmc7XHJcbiAgICAgICAgb3B0aW9ucy52aWRlb0hlaWdodFNob3cgPSBvcHRpb25zLnZpZGVvSGVpZ2h0U2hvdyA9PT0gdW5kZWZpbmVkID8gdHJ1ZSA6ICEhb3B0aW9ucy52aWRlb0hlaWdodFNob3c7XHJcbiAgICAgICAgb3B0aW9ucy52aWRlb1JhdGlvU2hvdyA9IG9wdGlvbnMudmlkZW9SYXRpb1Nob3cgPT09IHVuZGVmaW5lZCA/IHRydWUgOiAhIW9wdGlvbnMudmlkZW9SYXRpb1Nob3c7XHJcbiAgICAgICAgb3B0aW9ucy52aWRlb1dpZHRoID0gIW9wdGlvbnMudmlkZW9XaWR0aCB8fCAhdXRpbC5nZXROdW1iZXIob3B0aW9ucy52aWRlb1dpZHRoLCAwKSA/ICcnIDogdXRpbC5pc051bWJlcihvcHRpb25zLnZpZGVvV2lkdGgpID8gb3B0aW9ucy52aWRlb1dpZHRoICsgJ3B4JyA6IG9wdGlvbnMudmlkZW9XaWR0aDtcclxuICAgICAgICBvcHRpb25zLnZpZGVvSGVpZ2h0ID0gIW9wdGlvbnMudmlkZW9IZWlnaHQgfHwgIXV0aWwuZ2V0TnVtYmVyKG9wdGlvbnMudmlkZW9IZWlnaHQsIDApID8gJycgOiB1dGlsLmlzTnVtYmVyKG9wdGlvbnMudmlkZW9IZWlnaHQpID8gb3B0aW9ucy52aWRlb0hlaWdodCArICdweCcgOiBvcHRpb25zLnZpZGVvSGVpZ2h0O1xyXG4gICAgICAgIG9wdGlvbnMudmlkZW9TaXplT25seVBlcmNlbnRhZ2UgPSAhIW9wdGlvbnMudmlkZW9TaXplT25seVBlcmNlbnRhZ2U7XHJcbiAgICAgICAgb3B0aW9ucy5fdmlkZW9TaXplVW5pdCA9IG9wdGlvbnMudmlkZW9TaXplT25seVBlcmNlbnRhZ2UgPyAnJScgOiAncHgnO1xyXG4gICAgICAgIG9wdGlvbnMudmlkZW9Sb3RhdGlvbiA9IG9wdGlvbnMudmlkZW9Sb3RhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy52aWRlb1JvdGF0aW9uIDogIShvcHRpb25zLnZpZGVvU2l6ZU9ubHlQZXJjZW50YWdlIHx8ICFvcHRpb25zLnZpZGVvSGVpZ2h0U2hvdyk7XHJcbiAgICAgICAgb3B0aW9ucy52aWRlb1JhdGlvID0gKHV0aWwuZ2V0TnVtYmVyKG9wdGlvbnMudmlkZW9SYXRpbywgNCkgfHwgMC41NjI1KTtcclxuICAgICAgICBvcHRpb25zLnZpZGVvUmF0aW9MaXN0ID0gIW9wdGlvbnMudmlkZW9SYXRpb0xpc3QgPyBudWxsIDogb3B0aW9ucy52aWRlb1JhdGlvTGlzdDtcclxuICAgICAgICBvcHRpb25zLnlvdXR1YmVRdWVyeSA9IChvcHRpb25zLnlvdXR1YmVRdWVyeSB8fCAnJykucmVwbGFjZSgnPycsICcnKTtcclxuICAgICAgICBvcHRpb25zLnZpZGVvRmlsZUlucHV0ID0gISFvcHRpb25zLnZpZGVvRmlsZUlucHV0O1xyXG4gICAgICAgIG9wdGlvbnMudmlkZW9VcmxJbnB1dCA9IChvcHRpb25zLnZpZGVvVXJsSW5wdXQgPT09IHVuZGVmaW5lZCB8fCAhb3B0aW9ucy52aWRlb0ZpbGVJbnB1dCkgPyB0cnVlIDogb3B0aW9ucy52aWRlb1VybElucHV0O1xyXG4gICAgICAgIG9wdGlvbnMudmlkZW9VcGxvYWRIZWFkZXIgPSBvcHRpb25zLnZpZGVvVXBsb2FkSGVhZGVyIHx8IG51bGw7XHJcbiAgICAgICAgb3B0aW9ucy52aWRlb1VwbG9hZFVybCA9IHR5cGVvZiBvcHRpb25zLnZpZGVvVXBsb2FkVXJsID09PSAnc3RyaW5nJyA/IG9wdGlvbnMudmlkZW9VcGxvYWRVcmwgOiBudWxsO1xyXG4gICAgICAgIG9wdGlvbnMudmlkZW9VcGxvYWRTaXplTGltaXQgPSAvXFxkKy8udGVzdChvcHRpb25zLnZpZGVvVXBsb2FkU2l6ZUxpbWl0KSA/IHV0aWwuZ2V0TnVtYmVyKG9wdGlvbnMudmlkZW9VcGxvYWRTaXplTGltaXQsIDApIDogbnVsbDtcclxuICAgICAgICBvcHRpb25zLnZpZGVvTXVsdGlwbGVGaWxlID0gISFvcHRpb25zLnZpZGVvTXVsdGlwbGVGaWxlO1xyXG4gICAgICAgIG9wdGlvbnMudmlkZW9UYWdBdHRycyA9IG9wdGlvbnMudmlkZW9UYWdBdHRycyB8fCBudWxsO1xyXG4gICAgICAgIG9wdGlvbnMudmlkZW9JZnJhbWVBdHRycyA9IG9wdGlvbnMudmlkZW9JZnJhbWVBdHRycyB8fCBudWxsO1xyXG4gICAgICAgIG9wdGlvbnMudmlkZW9BY2NlcHQgPSAodHlwZW9mIG9wdGlvbnMudmlkZW9BY2NlcHQgIT09ICdzdHJpbmcnIHx8IG9wdGlvbnMudmlkZW9BY2NlcHQudHJpbSgpID09PSBcIipcIikgPyAndmlkZW8vKicgOiBvcHRpb25zLnZpZGVvQWNjZXB0LnRyaW0oKSB8fCAndmlkZW8vKic7XHJcbiAgICAgICAgLyoqIEF1ZGlvICovXHJcbiAgICAgICAgb3B0aW9ucy5hdWRpb1dpZHRoID0gIW9wdGlvbnMuYXVkaW9XaWR0aCA/ICcnIDogdXRpbC5pc051bWJlcihvcHRpb25zLmF1ZGlvV2lkdGgpID8gb3B0aW9ucy5hdWRpb1dpZHRoICsgJ3B4JyA6IG9wdGlvbnMuYXVkaW9XaWR0aDtcclxuICAgICAgICBvcHRpb25zLmF1ZGlvSGVpZ2h0ID0gIW9wdGlvbnMuYXVkaW9IZWlnaHQgPyAnJyA6IHV0aWwuaXNOdW1iZXIob3B0aW9ucy5hdWRpb0hlaWdodCkgPyBvcHRpb25zLmF1ZGlvSGVpZ2h0ICsgJ3B4JyA6IG9wdGlvbnMuYXVkaW9IZWlnaHQ7XHJcbiAgICAgICAgb3B0aW9ucy5hdWRpb0ZpbGVJbnB1dCA9ICEhb3B0aW9ucy5hdWRpb0ZpbGVJbnB1dDtcclxuICAgICAgICBvcHRpb25zLmF1ZGlvVXJsSW5wdXQgPSAob3B0aW9ucy5hdWRpb1VybElucHV0ID09PSB1bmRlZmluZWQgfHwgIW9wdGlvbnMuYXVkaW9GaWxlSW5wdXQpID8gdHJ1ZSA6IG9wdGlvbnMuYXVkaW9VcmxJbnB1dDtcclxuICAgICAgICBvcHRpb25zLmF1ZGlvVXBsb2FkSGVhZGVyID0gb3B0aW9ucy5hdWRpb1VwbG9hZEhlYWRlciB8fCBudWxsO1xyXG4gICAgICAgIG9wdGlvbnMuYXVkaW9VcGxvYWRVcmwgPSB0eXBlb2Ygb3B0aW9ucy5hdWRpb1VwbG9hZFVybCA9PT0gJ3N0cmluZycgPyBvcHRpb25zLmF1ZGlvVXBsb2FkVXJsIDogbnVsbDtcclxuICAgICAgICBvcHRpb25zLmF1ZGlvVXBsb2FkU2l6ZUxpbWl0ID0gL1xcZCsvLnRlc3Qob3B0aW9ucy5hdWRpb1VwbG9hZFNpemVMaW1pdCkgPyB1dGlsLmdldE51bWJlcihvcHRpb25zLmF1ZGlvVXBsb2FkU2l6ZUxpbWl0LCAwKSA6IG51bGw7XHJcbiAgICAgICAgb3B0aW9ucy5hdWRpb011bHRpcGxlRmlsZSA9ICEhb3B0aW9ucy5hdWRpb011bHRpcGxlRmlsZTtcclxuICAgICAgICBvcHRpb25zLmF1ZGlvVGFnQXR0cnMgPSBvcHRpb25zLmF1ZGlvVGFnQXR0cnMgfHwgbnVsbDtcclxuICAgICAgICBvcHRpb25zLmF1ZGlvQWNjZXB0ID0gKHR5cGVvZiBvcHRpb25zLmF1ZGlvQWNjZXB0ICE9PSAnc3RyaW5nJyB8fCBvcHRpb25zLmF1ZGlvQWNjZXB0LnRyaW0oKSA9PT0gXCIqXCIpID8gJ2F1ZGlvLyonIDogb3B0aW9ucy5hdWRpb0FjY2VwdC50cmltKCkgfHwgJ2F1ZGlvLyonO1xyXG4gICAgICAgIC8qKiBUYWJsZSAqL1xyXG4gICAgICAgIG9wdGlvbnMudGFibGVDZWxsQ29udHJvbGxlclBvc2l0aW9uID0gdHlwZW9mIG9wdGlvbnMudGFibGVDZWxsQ29udHJvbGxlclBvc2l0aW9uID09PSAnc3RyaW5nJyA/IG9wdGlvbnMudGFibGVDZWxsQ29udHJvbGxlclBvc2l0aW9uLnRvTG93ZXJDYXNlKCkgOiAnY2VsbCc7XHJcbiAgICAgICAgLyoqIEtleSBhY3Rpb25zICovXHJcbiAgICAgICAgb3B0aW9ucy50YWJEaXNhYmxlID0gISFvcHRpb25zLnRhYkRpc2FibGU7XHJcbiAgICAgICAgb3B0aW9ucy5zaG9ydGN1dHNEaXNhYmxlID0gKEFycmF5LmlzQXJyYXkob3B0aW9ucy5zaG9ydGN1dHNEaXNhYmxlKSAmJiBvcHRpb25zLnNob3J0Y3V0c0Rpc2FibGUubGVuZ3RoID4gMCkgPyBvcHRpb25zLnNob3J0Y3V0c0Rpc2FibGUubWFwKGZ1bmN0aW9uICh2KSB7IHJldHVybiB2LnRvTG93ZXJDYXNlKCk7IH0pIDogW107XHJcbiAgICAgICAgb3B0aW9ucy5zaG9ydGN1dHNIaW50ID0gb3B0aW9ucy5zaG9ydGN1dHNIaW50ID09PSB1bmRlZmluZWQgPyB0cnVlIDogISFvcHRpb25zLnNob3J0Y3V0c0hpbnQ7XHJcbiAgICAgICAgLyoqIERlZmluaW5nIHNhdmUgYnV0dG9uICovXHJcbiAgICAgICAgb3B0aW9ucy5jYWxsQmFja1NhdmUgPSAhb3B0aW9ucy5jYWxsQmFja1NhdmUgPyBudWxsIDogb3B0aW9ucy5jYWxsQmFja1NhdmU7XHJcbiAgICAgICAgLyoqIFRlbXBsYXRlcyBBcnJheSAqL1xyXG4gICAgICAgIG9wdGlvbnMudGVtcGxhdGVzID0gIW9wdGlvbnMudGVtcGxhdGVzID8gbnVsbCA6IG9wdGlvbnMudGVtcGxhdGVzO1xyXG4gICAgICAgIC8qKiBFVEMgKi9cclxuICAgICAgICBvcHRpb25zLnBsYWNlaG9sZGVyID0gdHlwZW9mIG9wdGlvbnMucGxhY2Vob2xkZXIgPT09ICdzdHJpbmcnID8gb3B0aW9ucy5wbGFjZWhvbGRlciA6IG51bGw7XHJcbiAgICAgICAgb3B0aW9ucy5saW5rUHJvdG9jb2wgPSB0eXBlb2Ygb3B0aW9ucy5saW5rUHJvdG9jb2wgPT09ICdzdHJpbmcnID8gb3B0aW9ucy5saW5rUHJvdG9jb2wgOiBudWxsO1xyXG4gICAgICAgIC8qKiBCdXR0b25zICovXHJcbiAgICAgICAgb3B0aW9ucy5idXR0b25MaXN0ID0gISFvcHRpb25zLmJ1dHRvbkxpc3QgPyBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9wdGlvbnMuYnV0dG9uTGlzdCkpIDogW1xyXG4gICAgICAgICAgICBbJ3VuZG8nLCAncmVkbyddLFxyXG4gICAgICAgICAgICBbJ2JvbGQnLCAndW5kZXJsaW5lJywgJ2l0YWxpYycsICdzdHJpa2UnLCAnc3Vic2NyaXB0JywgJ3N1cGVyc2NyaXB0J10sXHJcbiAgICAgICAgICAgIFsncmVtb3ZlRm9ybWF0J10sXHJcbiAgICAgICAgICAgIFsnb3V0ZGVudCcsICdpbmRlbnQnXSxcclxuICAgICAgICAgICAgWydmdWxsU2NyZWVuJywgJ3Nob3dCbG9ja3MnLCAnY29kZVZpZXcnXSxcclxuICAgICAgICAgICAgWydwcmV2aWV3JywgJ3ByaW50J11cclxuICAgICAgICBdO1xyXG5cclxuICAgICAgICAvKiogUlRMIC0gYnV0dG9ucyAqL1xyXG4gICAgICAgIGlmIChvcHRpb25zLnJ0bCkge1xyXG4gICAgICAgICAgICBvcHRpb25zLmJ1dHRvbkxpc3QgPSBvcHRpb25zLmJ1dHRvbkxpc3QucmV2ZXJzZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqIC0tLSBEZWZpbmUgaWNvbnMgLS0tICovXHJcbiAgICAgICAgLy8gY3VzdG9tIGljb25zXHJcbiAgICAgICAgb3B0aW9ucy5pY29ucyA9ICghb3B0aW9ucy5pY29ucyB8fCB0eXBlb2Ygb3B0aW9ucy5pY29ucyAhPT0gJ29iamVjdCcpID8gX2ljb25zIDogW19pY29ucywgb3B0aW9ucy5pY29uc10ucmVkdWNlKGZ1bmN0aW9uIChfZGVmYXVsdCwgX25ldykge1xyXG4gICAgICAgICAgICBmb3IgKGxldCBrZXkgaW4gX25ldykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHV0aWwuaGFzT3duKF9uZXcsIGtleSkpIF9kZWZhdWx0W2tleV0gPSBfbmV3W2tleV07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIF9kZWZhdWx0O1xyXG4gICAgICAgIH0sIHt9KTtcclxuICAgICAgICAvLyBydGwgaWNvbnNcclxuICAgICAgICBvcHRpb25zLmljb25zID0gIW9wdGlvbnMucnRsID8gb3B0aW9ucy5pY29ucyA6IFtvcHRpb25zLmljb25zLCBvcHRpb25zLmljb25zLnJ0bF0ucmVkdWNlKGZ1bmN0aW9uIChfZGVmYXVsdCwgX25ldykge1xyXG4gICAgICAgICAgICBmb3IgKGxldCBrZXkgaW4gX25ldykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHV0aWwuaGFzT3duKF9uZXcsIGtleSkpIF9kZWZhdWx0W2tleV0gPSBfbmV3W2tleV07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIF9kZWZhdWx0O1xyXG4gICAgICAgIH0sIHt9KTtcclxuXHJcbiAgICAgICAgLyoqIF9pbml0IG9wdGlvbnMgKi9cclxuICAgICAgICBvcHRpb25zLl9lZGl0b3JTdHlsZXMgPSB1dGlsLl9zZXREZWZhdWx0T3B0aW9uU3R5bGUob3B0aW9ucywgb3B0aW9ucy5kZWZhdWx0U3R5bGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBTdW5lZGl0b3IncyBEZWZhdWx0IGJ1dHRvbiBsaXN0XHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBvcHRpb25zXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBfZGVmYXVsdEJ1dHRvbnM6IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcbiAgICAgICAgY29uc3QgaWNvbnMgPSBvcHRpb25zLmljb25zO1xyXG4gICAgICAgIGNvbnN0IGxhbmcgPSBvcHRpb25zLmxhbmc7XHJcbiAgICAgICAgY29uc3QgY21kID0gdXRpbC5pc09TWF9JT1MgPyAn4oyYJyA6ICdDVFJMJztcclxuICAgICAgICBjb25zdCBhZGRTaGlmdCA9IHV0aWwuaXNPU1hfSU9TID8gJ+KHpycgOiAnK1NISUZUJztcclxuICAgICAgICBjb25zdCBzaG9ydGN1dHNEaXNhYmxlID0gIW9wdGlvbnMuc2hvcnRjdXRzSGludCA/IFsnYm9sZCcsICdzdHJpa2UnLCAndW5kZXJsaW5lJywgJ2l0YWxpYycsICd1bmRvJywgJ2luZGVudCddIDogb3B0aW9ucy5zaG9ydGN1dHNEaXNhYmxlO1xyXG4gICAgICAgIGNvbnN0IGluZGVudEtleSA9IG9wdGlvbnMucnRsID8gWydbJywnXSddIDogWyddJywnWyddO1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAvKiogZGVmYXVsdCBjb21tYW5kICovXHJcbiAgICAgICAgICAgIGJvbGQ6IFsnX3NlX2NvbW1hbmRfYm9sZCcsIGxhbmcudG9vbGJhci5ib2xkICsgJzxzcGFuIGNsYXNzPVwic2Utc2hvcnRjdXRcIj4nICsgKHNob3J0Y3V0c0Rpc2FibGUuaW5kZXhPZignYm9sZCcpID4gLTEgPyAnJyA6IGNtZCArICcrPHNwYW4gY2xhc3M9XCJzZS1zaG9ydGN1dC1rZXlcIj5CPC9zcGFuPicpICsgJzwvc3Bhbj4nLCAnU1RST05HJywgJycsIGljb25zLmJvbGRdLFxyXG4gICAgICAgICAgICB1bmRlcmxpbmU6IFsnX3NlX2NvbW1hbmRfdW5kZXJsaW5lJywgbGFuZy50b29sYmFyLnVuZGVybGluZSArICc8c3BhbiBjbGFzcz1cInNlLXNob3J0Y3V0XCI+JyArIChzaG9ydGN1dHNEaXNhYmxlLmluZGV4T2YoJ3VuZGVybGluZScpID4gLTEgPyAnJyA6IGNtZCArICcrPHNwYW4gY2xhc3M9XCJzZS1zaG9ydGN1dC1rZXlcIj5VPC9zcGFuPicpICsgJzwvc3Bhbj4nLCAnVScsICcnLCBpY29ucy51bmRlcmxpbmVdLFxyXG4gICAgICAgICAgICBpdGFsaWM6IFsnX3NlX2NvbW1hbmRfaXRhbGljJywgbGFuZy50b29sYmFyLml0YWxpYyArICc8c3BhbiBjbGFzcz1cInNlLXNob3J0Y3V0XCI+JyArIChzaG9ydGN1dHNEaXNhYmxlLmluZGV4T2YoJ2l0YWxpYycpID4gLTEgPyAnJyA6IGNtZCArICcrPHNwYW4gY2xhc3M9XCJzZS1zaG9ydGN1dC1rZXlcIj5JPC9zcGFuPicpICsgJzwvc3Bhbj4nLCAnRU0nLCAnJywgaWNvbnMuaXRhbGljXSxcclxuICAgICAgICAgICAgc3RyaWtlOiBbJ19zZV9jb21tYW5kX3N0cmlrZScsIGxhbmcudG9vbGJhci5zdHJpa2UgKyAnPHNwYW4gY2xhc3M9XCJzZS1zaG9ydGN1dFwiPicgKyAoc2hvcnRjdXRzRGlzYWJsZS5pbmRleE9mKCdzdHJpa2UnKSA+IC0xID8gJycgOiBjbWQgKyBhZGRTaGlmdCArICcrPHNwYW4gY2xhc3M9XCJzZS1zaG9ydGN1dC1rZXlcIj5TPC9zcGFuPicpICsgJzwvc3Bhbj4nLCAnREVMJywgJycsIGljb25zLnN0cmlrZV0sXHJcbiAgICAgICAgICAgIHN1YnNjcmlwdDogWydfc2VfY29tbWFuZF9zdWJzY3JpcHQnLCBsYW5nLnRvb2xiYXIuc3Vic2NyaXB0LCAnU1VCJywgJycsIGljb25zLnN1YnNjcmlwdF0sXHJcbiAgICAgICAgICAgIHN1cGVyc2NyaXB0OiBbJ19zZV9jb21tYW5kX3N1cGVyc2NyaXB0JywgbGFuZy50b29sYmFyLnN1cGVyc2NyaXB0LCAnU1VQJywgJycsIGljb25zLnN1cGVyc2NyaXB0XSxcclxuICAgICAgICAgICAgcmVtb3ZlRm9ybWF0OiBbJycsIGxhbmcudG9vbGJhci5yZW1vdmVGb3JtYXQsICdyZW1vdmVGb3JtYXQnLCAnJywgaWNvbnMuZXJhc2VdLFxyXG4gICAgICAgICAgICBpbmRlbnQ6IFsnX3NlX2NvbW1hbmRfaW5kZW50JywgbGFuZy50b29sYmFyLmluZGVudCArICc8c3BhbiBjbGFzcz1cInNlLXNob3J0Y3V0XCI+JyArIChzaG9ydGN1dHNEaXNhYmxlLmluZGV4T2YoJ2luZGVudCcpID4gLTEgPyAnJyA6IGNtZCArICcrPHNwYW4gY2xhc3M9XCJzZS1zaG9ydGN1dC1rZXlcIj4nICsgaW5kZW50S2V5WzBdICsgJzwvc3Bhbj4nKSArICc8L3NwYW4+JywgJ2luZGVudCcsICcnLCBpY29ucy5vdXRkZW50XSxcclxuICAgICAgICAgICAgb3V0ZGVudDogWydfc2VfY29tbWFuZF9vdXRkZW50JywgbGFuZy50b29sYmFyLm91dGRlbnQgKyAnPHNwYW4gY2xhc3M9XCJzZS1zaG9ydGN1dFwiPicgKyAoc2hvcnRjdXRzRGlzYWJsZS5pbmRleE9mKCdpbmRlbnQnKSA+IC0xID8gJycgOiBjbWQgKyAnKzxzcGFuIGNsYXNzPVwic2Utc2hvcnRjdXQta2V5XCI+JyArIGluZGVudEtleVsxXSArICc8L3NwYW4+JykgKyAnPC9zcGFuPicsICdvdXRkZW50JywgJycsIGljb25zLmluZGVudF0sXHJcbiAgICAgICAgICAgIGZ1bGxTY3JlZW46IFsnc2UtY29kZS12aWV3LWVuYWJsZWQgc2UtcmVzaXppbmctZW5hYmxlZCBfc2VfY29tbWFuZF9mdWxsU2NyZWVuJywgbGFuZy50b29sYmFyLmZ1bGxTY3JlZW4sICdmdWxsU2NyZWVuJywgJycsIGljb25zLmV4cGFuc2lvbl0sXHJcbiAgICAgICAgICAgIHNob3dCbG9ja3M6IFsnX3NlX2NvbW1hbmRfc2hvd0Jsb2NrcycsIGxhbmcudG9vbGJhci5zaG93QmxvY2tzLCAnc2hvd0Jsb2NrcycsICcnLCBpY29ucy5zaG93X2Jsb2Nrc10sXHJcbiAgICAgICAgICAgIGNvZGVWaWV3OiBbJ3NlLWNvZGUtdmlldy1lbmFibGVkIHNlLXJlc2l6aW5nLWVuYWJsZWQgX3NlX2NvbW1hbmRfY29kZVZpZXcnLCBsYW5nLnRvb2xiYXIuY29kZVZpZXcsICdjb2RlVmlldycsICcnLCBpY29ucy5jb2RlX3ZpZXddLFxyXG4gICAgICAgICAgICB1bmRvOiBbJ19zZV9jb21tYW5kX3VuZG8gc2UtcmVzaXppbmctZW5hYmxlZCcsIGxhbmcudG9vbGJhci51bmRvICsgJzxzcGFuIGNsYXNzPVwic2Utc2hvcnRjdXRcIj4nICsgKHNob3J0Y3V0c0Rpc2FibGUuaW5kZXhPZigndW5kbycpID4gLTEgPyAnJyA6IGNtZCArICcrPHNwYW4gY2xhc3M9XCJzZS1zaG9ydGN1dC1rZXlcIj5aPC9zcGFuPicpICsgJzwvc3Bhbj4nLCAndW5kbycsICcnLCBpY29ucy51bmRvXSxcclxuICAgICAgICAgICAgcmVkbzogWydfc2VfY29tbWFuZF9yZWRvIHNlLXJlc2l6aW5nLWVuYWJsZWQnLCBsYW5nLnRvb2xiYXIucmVkbyArICc8c3BhbiBjbGFzcz1cInNlLXNob3J0Y3V0XCI+JyArIChzaG9ydGN1dHNEaXNhYmxlLmluZGV4T2YoJ3VuZG8nKSA+IC0xID8gJycgOiBjbWQgKyAnKzxzcGFuIGNsYXNzPVwic2Utc2hvcnRjdXQta2V5XCI+WTwvc3Bhbj4gLyAnICsgY21kICsgYWRkU2hpZnQgKyAnKzxzcGFuIGNsYXNzPVwic2Utc2hvcnRjdXQta2V5XCI+Wjwvc3Bhbj4nKSArICc8L3NwYW4+JywgJ3JlZG8nLCAnJywgaWNvbnMucmVkb10sXHJcbiAgICAgICAgICAgIHByZXZpZXc6IFsnc2UtcmVzaXppbmctZW5hYmxlZCcsIGxhbmcudG9vbGJhci5wcmV2aWV3LCAncHJldmlldycsICcnLCBpY29ucy5wcmV2aWV3XSxcclxuICAgICAgICAgICAgcHJpbnQ6IFsnc2UtcmVzaXppbmctZW5hYmxlZCcsIGxhbmcudG9vbGJhci5wcmludCwgJ3ByaW50JywgJycsIGljb25zLnByaW50XSxcclxuICAgICAgICAgICAgc2F2ZTogWydfc2VfY29tbWFuZF9zYXZlIHNlLXJlc2l6aW5nLWVuYWJsZWQnLCBsYW5nLnRvb2xiYXIuc2F2ZSwgJ3NhdmUnLCAnJywgaWNvbnMuc2F2ZV0sXHJcbiAgICAgICAgICAgIC8qKiBwbHVnaW5zIC0gY29tbWFuZCAqL1xyXG4gICAgICAgICAgICBibG9ja3F1b3RlOiBbJycsIGxhbmcudG9vbGJhci50YWdfYmxvY2txdW90ZSwgJ2Jsb2NrcXVvdGUnLCAnY29tbWFuZCcsIGljb25zLmJsb2NrcXVvdGVdLFxyXG4gICAgICAgICAgICAvKiogcGx1Z2lucyAtIHN1Ym1lbnUgKi9cclxuICAgICAgICAgICAgZm9udDogWydzZS1idG4tc2VsZWN0IHNlLWJ0bi10b29sLWZvbnQnLCBsYW5nLnRvb2xiYXIuZm9udCwgJ2ZvbnQnLCAnc3VibWVudScsICc8c3BhbiBjbGFzcz1cInR4dFwiPicgKyBsYW5nLnRvb2xiYXIuZm9udCArICc8L3NwYW4+JyArIGljb25zLmFycm93X2Rvd25dLFxyXG4gICAgICAgICAgICBmb3JtYXRCbG9jazogWydzZS1idG4tc2VsZWN0IHNlLWJ0bi10b29sLWZvcm1hdCcsIGxhbmcudG9vbGJhci5mb3JtYXRzLCAnZm9ybWF0QmxvY2snLCAnc3VibWVudScsICc8c3BhbiBjbGFzcz1cInR4dFwiPicgKyBsYW5nLnRvb2xiYXIuZm9ybWF0cyArICc8L3NwYW4+JyArIGljb25zLmFycm93X2Rvd25dLFxyXG4gICAgICAgICAgICBmb250U2l6ZTogWydzZS1idG4tc2VsZWN0IHNlLWJ0bi10b29sLXNpemUnLCBsYW5nLnRvb2xiYXIuZm9udFNpemUsICdmb250U2l6ZScsICdzdWJtZW51JywgJzxzcGFuIGNsYXNzPVwidHh0XCI+JyArIGxhbmcudG9vbGJhci5mb250U2l6ZSArICc8L3NwYW4+JyArIGljb25zLmFycm93X2Rvd25dLFxyXG4gICAgICAgICAgICBmb250Q29sb3I6IFsnJywgbGFuZy50b29sYmFyLmZvbnRDb2xvciwgJ2ZvbnRDb2xvcicsICdzdWJtZW51JywgaWNvbnMuZm9udF9jb2xvcl0sXHJcbiAgICAgICAgICAgIGhpbGl0ZUNvbG9yOiBbJycsIGxhbmcudG9vbGJhci5oaWxpdGVDb2xvciwgJ2hpbGl0ZUNvbG9yJywgJ3N1Ym1lbnUnLCBpY29ucy5oaWdobGlnaHRfY29sb3JdLFxyXG4gICAgICAgICAgICBhbGlnbjogWydzZS1idG4tYWxpZ24nLCBsYW5nLnRvb2xiYXIuYWxpZ24sICdhbGlnbicsICdzdWJtZW51JywgKG9wdGlvbnMucnRsID8gaWNvbnMuYWxpZ25fcmlnaHQgOiBpY29ucy5hbGlnbl9sZWZ0KV0sXHJcbiAgICAgICAgICAgIGxpc3Q6IFsnJywgbGFuZy50b29sYmFyLmxpc3QsICdsaXN0JywgJ3N1Ym1lbnUnLCBpY29ucy5saXN0X251bWJlcl0sXHJcbiAgICAgICAgICAgIGhvcml6b250YWxSdWxlOiBbJ2J0bl9saW5lJywgbGFuZy50b29sYmFyLmhvcml6b250YWxSdWxlLCAnaG9yaXpvbnRhbFJ1bGUnLCAnc3VibWVudScsIGljb25zLmhvcml6b250YWxfcnVsZV0sXHJcbiAgICAgICAgICAgIHRhYmxlOiBbJycsIGxhbmcudG9vbGJhci50YWJsZSwgJ3RhYmxlJywgJ3N1Ym1lbnUnLCBpY29ucy50YWJsZV0sXHJcbiAgICAgICAgICAgIGxpbmVIZWlnaHQ6IFsnJywgbGFuZy50b29sYmFyLmxpbmVIZWlnaHQsICdsaW5lSGVpZ2h0JywgJ3N1Ym1lbnUnLCBpY29ucy5saW5lX2hlaWdodF0sXHJcbiAgICAgICAgICAgIHRlbXBsYXRlOiBbJycsIGxhbmcudG9vbGJhci50ZW1wbGF0ZSwgJ3RlbXBsYXRlJywgJ3N1Ym1lbnUnLCBpY29ucy50ZW1wbGF0ZV0sXHJcbiAgICAgICAgICAgIHBhcmFncmFwaFN0eWxlOiBbJycsIGxhbmcudG9vbGJhci5wYXJhZ3JhcGhTdHlsZSwgJ3BhcmFncmFwaFN0eWxlJywgJ3N1Ym1lbnUnLCBpY29ucy5wYXJhZ3JhcGhfc3R5bGVdLFxyXG4gICAgICAgICAgICB0ZXh0U3R5bGU6IFsnJywgbGFuZy50b29sYmFyLnRleHRTdHlsZSwgJ3RleHRTdHlsZScsICdzdWJtZW51JywgaWNvbnMudGV4dF9zdHlsZV0sXHJcbiAgICAgICAgICAgIC8qKiBwbHVnaW5zIC0gZGlhbG9nICovXHJcbiAgICAgICAgICAgIGxpbms6IFsnJywgbGFuZy50b29sYmFyLmxpbmssICdsaW5rJywgJ2RpYWxvZycsIGljb25zLmxpbmtdLFxyXG4gICAgICAgICAgICBpbWFnZTogWycnLCBsYW5nLnRvb2xiYXIuaW1hZ2UsICdpbWFnZScsICdkaWFsb2cnLCBpY29ucy5pbWFnZV0sXHJcbiAgICAgICAgICAgIHZpZGVvOiBbJycsIGxhbmcudG9vbGJhci52aWRlbywgJ3ZpZGVvJywgJ2RpYWxvZycsIGljb25zLnZpZGVvXSxcclxuICAgICAgICAgICAgYXVkaW86IFsnJywgbGFuZy50b29sYmFyLmF1ZGlvLCAnYXVkaW8nLCAnZGlhbG9nJywgaWNvbnMuYXVkaW9dLFxyXG4gICAgICAgICAgICBtYXRoOiBbJycsIGxhbmcudG9vbGJhci5tYXRoLCAnbWF0aCcsICdkaWFsb2cnLCBpY29ucy5tYXRoXSxcclxuICAgICAgICAgICAgLyoqIHBsdWdpbnMgLSBmaWxlQnJvd3NlciAqL1xyXG4gICAgICAgICAgICBpbWFnZUdhbGxlcnk6IFsnJywgbGFuZy50b29sYmFyLmltYWdlR2FsbGVyeSwgJ2ltYWdlR2FsbGVyeScsICdmaWxlQnJvd3NlcicsIGljb25zLmltYWdlX2dhbGxlcnldXHJcbiAgICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlIGEgZ3JvdXAgZGl2IGNvbnRhaW5pbmcgZWFjaCBtb2R1bGVcclxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9XHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBfY3JlYXRlTW9kdWxlR3JvdXA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBjb25zdCBvRGl2ID0gdXRpbC5jcmVhdGVFbGVtZW50KCdESVYnKTtcclxuICAgICAgICBvRGl2LmNsYXNzTmFtZSA9ICdzZS1idG4tbW9kdWxlIHNlLWJ0bi1tb2R1bGUtYm9yZGVyJztcclxuXHJcbiAgICAgICAgY29uc3Qgb1VsID0gdXRpbC5jcmVhdGVFbGVtZW50KCdVTCcpO1xyXG4gICAgICAgIG9VbC5jbGFzc05hbWUgPSAnc2UtbWVudS1saXN0JztcclxuICAgICAgICBvRGl2LmFwcGVuZENoaWxkKG9VbCk7XHJcblxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICdkaXYnOiBvRGl2LFxyXG4gICAgICAgICAgICAndWwnOiBvVWxcclxuICAgICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBDcmVhdGUgYSBidXR0b24gZWxlbWVudFxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGJ1dHRvbkNsYXNzIGNsYXNzTmFtZSBpbiBidXR0b25cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0aXRsZSBUaXRsZSBpbiBidXR0b25cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhQ29tbWFuZCBUaGUgZGF0YS1jb21tYW5kIHByb3BlcnR5IG9mIHRoZSBidXR0b25cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhRGlzcGxheSBUaGUgZGF0YS1kaXNwbGF5IHByb3BlcnR5IG9mIHRoZSBidXR0b24gKCdkaWFsb2cnLCAnc3VibWVudScsICdjb21tYW5kJylcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpbm5lckhUTUwgSHRtbCBpbiBidXR0b25cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBfZGlzYWJsZWQgQnV0dG9uIGRpc2FibGVkXHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gX2ljb25zIEljb25zXHJcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fVxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX2NyZWF0ZUJ1dHRvbjogZnVuY3Rpb24gKGJ1dHRvbkNsYXNzLCB0aXRsZSwgZGF0YUNvbW1hbmQsIGRhdGFEaXNwbGF5LCBpbm5lckhUTUwsIF9kaXNhYmxlZCwgX2ljb25zKSB7XHJcbiAgICAgICAgY29uc3Qgb0xpID0gdXRpbC5jcmVhdGVFbGVtZW50KCdMSScpO1xyXG4gICAgICAgIGNvbnN0IG9CdXR0b24gPSB1dGlsLmNyZWF0ZUVsZW1lbnQoJ0JVVFRPTicpO1xyXG5cclxuICAgICAgICBvQnV0dG9uLnNldEF0dHJpYnV0ZSgndHlwZScsICdidXR0b24nKTtcclxuICAgICAgICBvQnV0dG9uLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnc2UtYnRuJyArIChidXR0b25DbGFzcyA/ICcgJyArIGJ1dHRvbkNsYXNzIDogJycpICsgJyBzZS10b29sdGlwJyk7XHJcbiAgICAgICAgb0J1dHRvbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtY29tbWFuZCcsIGRhdGFDb21tYW5kKTtcclxuICAgICAgICBvQnV0dG9uLnNldEF0dHJpYnV0ZSgnZGF0YS1kaXNwbGF5JywgZGF0YURpc3BsYXkpO1xyXG4gICAgICAgIG9CdXR0b24uc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsICctMScpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmICghaW5uZXJIVE1MKSBpbm5lckhUTUwgPSAnPHNwYW4gY2xhc3M9XCJzZS1pY29uLXRleHRcIj4hPC9zcGFuPic7XHJcbiAgICAgICAgaWYgKC9eZGVmYXVsdFxcLi9pLnRlc3QoaW5uZXJIVE1MKSkge1xyXG4gICAgICAgICAgICBpbm5lckhUTUwgPSBfaWNvbnNbaW5uZXJIVE1MLnJlcGxhY2UoL15kZWZhdWx0XFwuL2ksICcnKV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICgvXnRleHRcXC4vaS50ZXN0KGlubmVySFRNTCkpIHtcclxuICAgICAgICAgICAgaW5uZXJIVE1MID0gaW5uZXJIVE1MLnJlcGxhY2UoL150ZXh0XFwuL2ksICcnKTtcclxuICAgICAgICAgICAgb0J1dHRvbi5jbGFzc05hbWUgKz0gJyBzZS1idG4tbW9yZS10ZXh0JztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlubmVySFRNTCArPSAnPHNwYW4gY2xhc3M9XCJzZS10b29sdGlwLWlubmVyXCI+PHNwYW4gY2xhc3M9XCJzZS10b29sdGlwLXRleHRcIj4nICsgKHRpdGxlIHx8IGRhdGFDb21tYW5kKSArICc8L3NwYW4+PC9zcGFuPic7XHJcblxyXG4gICAgICAgIGlmIChfZGlzYWJsZWQpIG9CdXR0b24uc2V0QXR0cmlidXRlKCdkaXNhYmxlZCcsIHRydWUpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIG9CdXR0b24uaW5uZXJIVE1MID0gaW5uZXJIVE1MO1xyXG4gICAgICAgIG9MaS5hcHBlbmRDaGlsZChvQnV0dG9uKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgJ2xpJzogb0xpLFxyXG4gICAgICAgICAgICAnYnV0dG9uJzogb0J1dHRvblxyXG4gICAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIENyZWF0ZSBlZGl0b3IgSFRNTFxyXG4gICAgICogQHBhcmFtIHtBcnJheX0gZG9jIGRvY3VtZW50IG9iamVjdFxyXG4gICAgICogQHBhcmFtIHtBcnJheX0gYnV0dG9uTGlzdCBvcHRpb24uYnV0dG9uTGlzdFxyXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8bnVsbH0gX3BsdWdpbnMgUGx1Z2luc1xyXG4gICAgICogQHBhcmFtIHtBcnJheX0gb3B0aW9ucyBvcHRpb25zXHJcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSB7IGVsZW1lbnQ6IChFbGVtZW50KSBUb29sYmFyIGVsZW1lbnQsIHBsdWdpbnM6IChBcnJheXxudWxsKSBQbHVnaW5zIEFycmF5LCBwbHVnaW5DYWxsQnV0dG9uczogKE9iamVjdCksIHJlc3BvbnNpdmVCdXR0b25zOiAoQXJyYXkpIH1cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9jcmVhdGVUb29sQmFyOiBmdW5jdGlvbiAoZG9jLCBidXR0b25MaXN0LCBfcGx1Z2lucywgb3B0aW9ucykge1xyXG4gICAgICAgIGNvbnN0IHNlcGFyYXRvcl92ZXJ0aWNhbCA9IGRvYy5jcmVhdGVFbGVtZW50KCdESVYnKTtcclxuICAgICAgICBzZXBhcmF0b3JfdmVydGljYWwuY2xhc3NOYW1lID0gJ3NlLXRvb2xiYXItc2VwYXJhdG9yLXZlcnRpY2FsJztcclxuXHJcbiAgICAgICAgY29uc3QgdG9vbF9iYXIgPSBkb2MuY3JlYXRlRWxlbWVudCgnRElWJyk7XHJcbiAgICAgICAgdG9vbF9iYXIuY2xhc3NOYW1lID0gJ3NlLXRvb2xiYXIgc3VuLWVkaXRvci1jb21tb24nO1xyXG5cclxuICAgICAgICBjb25zdCBfYnV0dG9uVHJheSA9IGRvYy5jcmVhdGVFbGVtZW50KCdESVYnKTtcclxuICAgICAgICBfYnV0dG9uVHJheS5jbGFzc05hbWUgPSAnc2UtYnRuLXRyYXknO1xyXG4gICAgICAgIHRvb2xfYmFyLmFwcGVuZENoaWxkKF9idXR0b25UcmF5KTtcclxuXHJcbiAgICAgICAgLyoqIGNyZWF0ZSBidXR0b24gbGlzdCAqL1xyXG4gICAgICAgIGNvbnN0IGljb25zID0gb3B0aW9ucy5pY29ucztcclxuICAgICAgICBjb25zdCBkZWZhdWx0QnV0dG9uTGlzdCA9IHRoaXMuX2RlZmF1bHRCdXR0b25zKG9wdGlvbnMpO1xyXG4gICAgICAgIGNvbnN0IHBsdWdpbkNhbGxCdXR0b25zID0ge307XHJcbiAgICAgICAgY29uc3QgcmVzcG9uc2l2ZUJ1dHRvbnMgPSBbXTtcclxuICAgICAgICBjb25zdCBwbHVnaW5zID0ge307XHJcbiAgICAgICAgaWYgKF9wbHVnaW5zKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBsdWdpbnNWYWx1ZXMgPSBfcGx1Z2lucy5sZW5ndGggPyBfcGx1Z2lucyA6IE9iamVjdC5rZXlzKF9wbHVnaW5zKS5tYXAoZnVuY3Rpb24obmFtZSkgeyByZXR1cm4gX3BsdWdpbnNbbmFtZV07IH0pO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gcGx1Z2luc1ZhbHVlcy5sZW5ndGgsIHA7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgcCA9IHBsdWdpbnNWYWx1ZXNbaV0uZGVmYXVsdCB8fCBwbHVnaW5zVmFsdWVzW2ldO1xyXG4gICAgICAgICAgICAgICAgcGx1Z2luc1twLm5hbWVdID0gcDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IG1vZHVsZSA9IG51bGw7XHJcbiAgICAgICAgbGV0IGJ1dHRvbiA9IG51bGw7XHJcbiAgICAgICAgbGV0IG1vZHVsZUVsZW1lbnQgPSBudWxsO1xyXG4gICAgICAgIGxldCBidXR0b25FbGVtZW50ID0gbnVsbDtcclxuICAgICAgICBsZXQgcGx1Z2luTmFtZSA9ICcnO1xyXG4gICAgICAgIGxldCB2ZXJ0aWNhbCA9IGZhbHNlO1xyXG4gICAgICAgIGNvbnN0IG1vcmVMYXllciA9IHV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XHJcbiAgICAgICAgbW9yZUxheWVyLmNsYXNzTmFtZSA9ICdzZS10b29sYmFyLW1vcmUtbGF5ZXInO1xyXG5cclxuICAgICAgICBidXR0b25Hcm91cExvb3A6XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIG1vcmUsIG1vcmVDb250YWluZXIsIG1vcmVDb21tYW5kLCBidXR0b25Hcm91cCwgYWxpZ247IGkgPCBidXR0b25MaXN0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIG1vcmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgYWxpZ24gPSAnJztcclxuICAgICAgICAgICAgYnV0dG9uR3JvdXAgPSBidXR0b25MaXN0W2ldO1xyXG4gICAgICAgICAgICBtb2R1bGVFbGVtZW50ID0gdGhpcy5fY3JlYXRlTW9kdWxlR3JvdXAoKTtcclxuXHJcbiAgICAgICAgICAgIC8vIGJ1dHRvbiBvYmplY3RcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBidXR0b25Hcm91cCA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgICAgICAgIC8vIGJ1dHRvbnMgbG9vcFxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDAsIG1vcmVCdXR0b247IGogPCBidXR0b25Hcm91cC5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGJ1dHRvbiA9IGJ1dHRvbkdyb3VwW2pdO1xyXG4gICAgICAgICAgICAgICAgICAgIG1vcmVCdXR0b24gPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKC9eXFwlXFxkKy8udGVzdChidXR0b24pICYmIGogPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9uR3JvdXBbMF0gPSBidXR0b24ucmVwbGFjZSgvW15cXGRdL2csICcnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2l2ZUJ1dHRvbnMucHVzaChidXR0b25Hcm91cCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbkxpc3Quc3BsaWNlKGktLSwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIGJ1dHRvbkdyb3VwTG9vcDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBidXR0b24gPT09ICdvYmplY3QnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYnV0dG9uLmFkZCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGx1Z2luTmFtZSA9IGJ1dHRvbi5uYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlID0gZGVmYXVsdEJ1dHRvbkxpc3RbcGx1Z2luTmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbHVnaW5zW3BsdWdpbk5hbWVdID0gYnV0dG9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGx1Z2luTmFtZSA9IGJ1dHRvbi5uYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlID0gW2J1dHRvbi5idXR0b25DbGFzcywgYnV0dG9uLnRpdGxlLCBidXR0b24ubmFtZSwgYnV0dG9uLmRhdGFEaXNwbGF5LCBidXR0b24uaW5uZXJIVE1MLCBidXR0b24uX2Rpc2FibGVkXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFsaWduXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgvXlxcLS8udGVzdChidXR0b24pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGlnbiA9IGJ1dHRvbi5zdWJzdHIoMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGVFbGVtZW50LmRpdi5zdHlsZS5mbG9hdCA9IGFsaWduO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1vcmUgYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgvXlxcOi8udGVzdChidXR0b24pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3JlQnV0dG9uID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGNoZWQgPSBidXR0b24ubWF0Y2goL15cXDooW15cXC1dKylcXC0oW15cXC1dKylcXC0oW15cXC1dKykvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vcmVDb21tYW5kID0gJ19fc2VfXycgKyBtYXRjaGVkWzFdLnRyaW0oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRpdGxlID0gbWF0Y2hlZFsyXS50cmltKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbm5lckhUTUwgPSBtYXRjaGVkWzNdLnRyaW0oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZHVsZSA9IFsnc2UtYnRuLW1vcmUnLCB0aXRsZSwgbW9yZUNvbW1hbmQsICdNT1JFJywgaW5uZXJIVE1MXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBidXR0b25zXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlID0gZGVmYXVsdEJ1dHRvbkxpc3RbYnV0dG9uXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcGx1Z2luTmFtZSA9IGJ1dHRvbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtb2R1bGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1c3RvbSA9IHBsdWdpbnNbcGx1Z2luTmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWN1c3RvbSkgdGhyb3cgRXJyb3IoJ1tTVU5FRElUT1IuY3JlYXRlLnRvb2xiYXIuZmFpbF0gVGhlIGJ1dHRvbiBuYW1lIG9mIGEgcGx1Z2luIHRoYXQgZG9lcyBub3QgZXhpc3QuIFsnICsgcGx1Z2luTmFtZSArICddJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGUgPSBbY3VzdG9tLmJ1dHRvbkNsYXNzLCBjdXN0b20udGl0bGUsIGN1c3RvbS5uYW1lLCBjdXN0b20uZGlzcGxheSwgY3VzdG9tLmlubmVySFRNTCwgY3VzdG9tLl9kaXNhYmxlZF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGJ1dHRvbkVsZW1lbnQgPSB0aGlzLl9jcmVhdGVCdXR0b24obW9kdWxlWzBdLCBtb2R1bGVbMV0sIG1vZHVsZVsyXSwgbW9kdWxlWzNdLCBtb2R1bGVbNF0sIG1vZHVsZVs1XSwgaWNvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIChtb3JlID8gbW9yZUNvbnRhaW5lciA6IG1vZHVsZUVsZW1lbnQudWwpLmFwcGVuZENoaWxkKGJ1dHRvbkVsZW1lbnQubGkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAocGx1Z2luc1twbHVnaW5OYW1lXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwbHVnaW5DYWxsQnV0dG9uc1twbHVnaW5OYW1lXSA9IGJ1dHRvbkVsZW1lbnQuYnV0dG9uO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gbW9yZSBidXR0b25cclxuICAgICAgICAgICAgICAgICAgICBpZiAobW9yZUJ1dHRvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtb3JlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbW9yZUNvbnRhaW5lciA9IHV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vcmVDb250YWluZXIuY2xhc3NOYW1lID0gJ3NlLW1vcmUtbGF5ZXIgJyArIG1vcmVDb21tYW5kO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtb3JlQ29udGFpbmVyLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPVwic2UtbW9yZS1mb3JtXCI+PHVsIGNsYXNzPVwic2UtbWVudS1saXN0XCInICsgKGFsaWduID8gJyBzdHlsZT1cImZsb2F0OiAnICsgYWxpZ24gKyAnO1wiJyA6ICcnKSArICc+PC91bD48L2Rpdj4nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtb3JlTGF5ZXIuYXBwZW5kQ2hpbGQobW9yZUNvbnRhaW5lcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vcmVDb250YWluZXIgPSBtb3JlQ29udGFpbmVyLmZpcnN0RWxlbWVudENoaWxkLmZpcnN0RWxlbWVudENoaWxkO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodmVydGljYWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdiA9ICBzZXBhcmF0b3JfdmVydGljYWwuY2xvbmVOb2RlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYWxpZ24pIHN2LnN0eWxlLmZsb2F0ID0gYWxpZ247XHJcbiAgICAgICAgICAgICAgICAgICAgX2J1dHRvblRyYXkuYXBwZW5kQ2hpbGQoc3YpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICBfYnV0dG9uVHJheS5hcHBlbmRDaGlsZChtb2R1bGVFbGVtZW50LmRpdik7XHJcbiAgICAgICAgICAgICAgICB2ZXJ0aWNhbCA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLyoqIGxpbmUgYnJlYWsgICovXHJcbiAgICAgICAgICAgIGVsc2UgaWYgKC9eXFwvJC8udGVzdChidXR0b25Hcm91cCkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVudGVyRGl2ID0gZG9jLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xyXG4gICAgICAgICAgICAgICAgZW50ZXJEaXYuY2xhc3NOYW1lID0gJ3NlLWJ0bi1tb2R1bGUtZW50ZXInO1xyXG4gICAgICAgICAgICAgICAgX2J1dHRvblRyYXkuYXBwZW5kQ2hpbGQoZW50ZXJEaXYpO1xyXG4gICAgICAgICAgICAgICAgdmVydGljYWwgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgbGFzdEZsb2F0ID0gX2J1dHRvblRyYXkubGFzdEVsZW1lbnRDaGlsZC5zdHlsZS5mbG9hdDtcclxuICAgICAgICBpZiAoISFsYXN0RmxvYXQpIHtcclxuICAgICAgICAgICAgY29uc3Qgc3YgPSAgc2VwYXJhdG9yX3ZlcnRpY2FsLmNsb25lTm9kZShmYWxzZSk7XHJcbiAgICAgICAgICAgIHN2LnN0eWxlLmZsb2F0ID0gbGFzdEZsb2F0O1xyXG4gICAgICAgICAgICBfYnV0dG9uVHJheS5hcHBlbmRDaGlsZChzdik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoX2J1dHRvblRyYXkuY2hpbGRyZW4ubGVuZ3RoID09PSAxKSB1dGlsLnJlbW92ZUNsYXNzKF9idXR0b25UcmF5LmZpcnN0RWxlbWVudENoaWxkLCAnc2UtYnRuLW1vZHVsZS1ib3JkZXInKTtcclxuICAgICAgICBpZiAocmVzcG9uc2l2ZUJ1dHRvbnMubGVuZ3RoID4gMCkgcmVzcG9uc2l2ZUJ1dHRvbnMudW5zaGlmdChidXR0b25MaXN0KTtcclxuICAgICAgICBpZiAobW9yZUxheWVyLmNoaWxkcmVuLmxlbmd0aCA+IDApIF9idXR0b25UcmF5LmFwcGVuZENoaWxkKG1vcmVMYXllcik7XHJcblxyXG4gICAgICAgIC8vIG1lbnUgdHJheVxyXG4gICAgICAgIGNvbnN0IF9tZW51VHJheSA9IGRvYy5jcmVhdGVFbGVtZW50KCdESVYnKTtcclxuICAgICAgICBfbWVudVRyYXkuY2xhc3NOYW1lID0gJ3NlLW1lbnUtdHJheSc7XHJcbiAgICAgICAgdG9vbF9iYXIuYXBwZW5kQ2hpbGQoX21lbnVUcmF5KTtcclxuXHJcbiAgICAgICAgLy8gY292ZXJcclxuICAgICAgICBjb25zdCB0b29sX2NvdmVyID0gZG9jLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xyXG4gICAgICAgIHRvb2xfY292ZXIuY2xhc3NOYW1lID0gJ3NlLXRvb2xiYXItY292ZXInO1xyXG4gICAgICAgIHRvb2xfYmFyLmFwcGVuZENoaWxkKHRvb2xfY292ZXIpO1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAnZWxlbWVudCc6IHRvb2xfYmFyLFxyXG4gICAgICAgICAgICAncGx1Z2lucyc6IHBsdWdpbnMsXHJcbiAgICAgICAgICAgICdwbHVnaW5DYWxsQnV0dG9ucyc6IHBsdWdpbkNhbGxCdXR0b25zLFxyXG4gICAgICAgICAgICAncmVzcG9uc2l2ZUJ1dHRvbnMnOiByZXNwb25zaXZlQnV0dG9ucyxcclxuICAgICAgICAgICAgJ19tZW51VHJheSc6IF9tZW51VHJheSxcclxuICAgICAgICAgICAgJ19idXR0b25UcmF5JzogX2J1dHRvblRyYXlcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG59OyIsIi8qXHJcbiAqIHd5c2l3eWcgd2ViIGVkaXRvclxyXG4gKlxyXG4gKiBzdW5lZGl0b3IuanNcclxuICogQ29weXJpZ2h0IDIwMTcgSmlIb25nIExlZS5cclxuICogTUlUIGxpY2Vuc2UuXHJcbiAqL1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG4vKipcclxuICogQGRlc2NyaXB0aW9uIEVsZW1lbnRzIGFuZCB2YXJpYWJsZXMgeW91IHNob3VsZCBoYXZlXHJcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCB0ZXh0YXJlYSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb25zIFRvb2xiYXIgZWxlbWVudCB5b3UgY3JlYXRlZFxyXG4gKiBAcGFyYW0ge0pTT058T2JqZWN0fSBvcHRpb25zIEluc2VydGVkIG9wdGlvbnNcclxuICogQHJldHVybnMge09iamVjdH0ge0VsZW1lbnRzLCB2YXJpYWJsZXMgb2YgdGhlIGVkaXRvciwgb3B0aW9ufVxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuY29uc3QgX0NvbnRleHQgPSBmdW5jdGlvbiAoZWxlbWVudCwgY29ucywgb3B0aW9ucykge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBlbGVtZW50OiB7XHJcbiAgICAgICAgICAgIG9yaWdpbkVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgICAgICAgIHRvcEFyZWE6IGNvbnMuX3RvcCxcclxuICAgICAgICAgICAgcmVsYXRpdmU6IGNvbnMuX3JlbGF0aXZlLFxyXG4gICAgICAgICAgICB0b29sYmFyOiBjb25zLl90b29sQmFyLFxyXG4gICAgICAgICAgICBfYnV0dG9uVHJheTogY29ucy5fdG9vbEJhci5xdWVyeVNlbGVjdG9yKCcuc2UtYnRuLXRyYXknKSxcclxuICAgICAgICAgICAgX21lbnVUcmF5OiBjb25zLl9tZW51VHJheSxcclxuICAgICAgICAgICAgcmVzaXppbmdCYXI6IGNvbnMuX3Jlc2l6aW5nQmFyLFxyXG4gICAgICAgICAgICBuYXZpZ2F0aW9uOiBjb25zLl9uYXZpZ2F0aW9uLFxyXG4gICAgICAgICAgICBjaGFyV3JhcHBlcjogY29ucy5fY2hhcldyYXBwZXIsXHJcbiAgICAgICAgICAgIGNoYXJDb3VudGVyOiBjb25zLl9jaGFyQ291bnRlcixcclxuICAgICAgICAgICAgZWRpdG9yQXJlYTogY29ucy5fZWRpdG9yQXJlYSxcclxuICAgICAgICAgICAgd3lzaXd5Z0ZyYW1lOiBjb25zLl93eXNpd3lnQXJlYSxcclxuICAgICAgICAgICAgd3lzaXd5ZzogY29ucy5fd3lzaXd5Z0FyZWEsIC8vIGlmIChvcHRpb25zLmlmcmFtZSkgY29ucy5fd3lzaXd5Z0FyZWEuY29udGVudERvY3VtZW50LmJvZHlcclxuICAgICAgICAgICAgY29kZTogY29ucy5fY29kZUFyZWEsXHJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyOiBjb25zLl9wbGFjZWhvbGRlcixcclxuICAgICAgICAgICAgbG9hZGluZzogY29ucy5fbG9hZGluZyxcclxuICAgICAgICAgICAgbGluZUJyZWFrZXI6IGNvbnMuX2xpbmVCcmVha2VyLFxyXG4gICAgICAgICAgICBsaW5lQnJlYWtlcl90OiBjb25zLl9saW5lQnJlYWtlcl90LFxyXG4gICAgICAgICAgICBsaW5lQnJlYWtlcl9iOiBjb25zLl9saW5lQnJlYWtlcl9iLFxyXG4gICAgICAgICAgICByZXNpemVCYWNrZ3JvdW5kOiBjb25zLl9yZXNpemVCYWNrLFxyXG4gICAgICAgICAgICBfc3RpY2t5RHVtbXk6IGNvbnMuX3N0aWNreUR1bW15LFxyXG4gICAgICAgICAgICBfYXJyb3c6IGNvbnMuX2Fycm93XHJcbiAgICAgICAgfSxcclxuICAgICAgICB0b29sOiB7XHJcbiAgICAgICAgICAgIGNvdmVyOiBjb25zLl90b29sQmFyLnF1ZXJ5U2VsZWN0b3IoJy5zZS10b29sYmFyLWNvdmVyJyksXHJcbiAgICAgICAgICAgIGJvbGQ6IGNvbnMuX3Rvb2xCYXIucXVlcnlTZWxlY3RvcignLl9zZV9jb21tYW5kX2JvbGQnKSxcclxuICAgICAgICAgICAgdW5kZXJsaW5lOiBjb25zLl90b29sQmFyLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfY29tbWFuZF91bmRlcmxpbmUnKSxcclxuICAgICAgICAgICAgaXRhbGljOiBjb25zLl90b29sQmFyLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfY29tbWFuZF9pdGFsaWMnKSxcclxuICAgICAgICAgICAgc3RyaWtlOiBjb25zLl90b29sQmFyLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfY29tbWFuZF9zdHJpa2UnKSxcclxuICAgICAgICAgICAgc3Vic2NyaXB0OiBjb25zLl90b29sQmFyLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfY29tbWFuZF9zdWJzY3JpcHQnKSxcclxuICAgICAgICAgICAgc3VwZXJzY3JpcHQ6IGNvbnMuX3Rvb2xCYXIucXVlcnlTZWxlY3RvcignLl9zZV9jb21tYW5kX3N1cGVyc2NyaXB0JyksXHJcbiAgICAgICAgICAgIHVuZG86IGNvbnMuX3Rvb2xCYXIucXVlcnlTZWxlY3RvcignLl9zZV9jb21tYW5kX3VuZG8nKSxcclxuICAgICAgICAgICAgcmVkbzogY29ucy5fdG9vbEJhci5xdWVyeVNlbGVjdG9yKCcuX3NlX2NvbW1hbmRfcmVkbycpLFxyXG4gICAgICAgICAgICBzYXZlOiBjb25zLl90b29sQmFyLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfY29tbWFuZF9zYXZlJyksXHJcbiAgICAgICAgICAgIG91dGRlbnQ6IGNvbnMuX3Rvb2xCYXIucXVlcnlTZWxlY3RvcignLl9zZV9jb21tYW5kX291dGRlbnQnKSxcclxuICAgICAgICAgICAgaW5kZW50OiBjb25zLl90b29sQmFyLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfY29tbWFuZF9pbmRlbnQnKSxcclxuICAgICAgICAgICAgZnVsbFNjcmVlbjogY29ucy5fdG9vbEJhci5xdWVyeVNlbGVjdG9yKCcuX3NlX2NvbW1hbmRfZnVsbFNjcmVlbicpLFxyXG4gICAgICAgICAgICBzaG93QmxvY2tzOiBjb25zLl90b29sQmFyLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfY29tbWFuZF9zaG93QmxvY2tzJyksXHJcbiAgICAgICAgICAgIGNvZGVWaWV3OiBjb25zLl90b29sQmFyLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfY29tbWFuZF9jb2RlVmlldycpXHJcbiAgICAgICAgfSxcclxuICAgICAgICBvcHRpb25zOiBvcHRpb25zLFxyXG4gICAgICAgIG9wdGlvbjogb3B0aW9uc1xyXG4gICAgfTtcclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IF9Db250ZXh0OyIsIi8qXG4gKiB3eXNpd3lnIHdlYiBlZGl0b3JcbiAqXG4gKiBzdW5lZGl0b3IuanNcbiAqIENvcHlyaWdodCAyMDE3IEppSG9uZyBMZWUuXG4gKiBNSVQgbGljZW5zZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gICAgbmFtZTogJ25vdGljZScsXG4gICAgLyoqXG4gICAgICogQGRlc2NyaXB0aW9uIENvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGNvcmUgQ29yZSBvYmplY3QgXG4gICAgICovXG4gICAgYWRkOiBmdW5jdGlvbiAoY29yZSkge1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gY29yZS5jb250ZXh0O1xuICAgICAgICBjb250ZXh0Lm5vdGljZSA9IHt9O1xuXG4gICAgICAgIC8qKiBkaWFsb2cgKi9cbiAgICAgICAgbGV0IG5vdGljZV9kaXYgPSBjb3JlLnV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XG4gICAgICAgIGxldCBub3RpY2Vfc3BhbiA9IGNvcmUudXRpbC5jcmVhdGVFbGVtZW50KCdTUEFOJyk7XG4gICAgICAgIGxldCBub3RpY2VfYnV0dG9uID0gY29yZS51dGlsLmNyZWF0ZUVsZW1lbnQoJ0JVVFRPTicpO1xuXG4gICAgICAgIG5vdGljZV9kaXYuY2xhc3NOYW1lID0gJ3NlLW5vdGljZSc7XG4gICAgICAgIG5vdGljZV9idXR0b24uY2xhc3NOYW1lID0gJ2Nsb3NlJztcbiAgICAgICAgbm90aWNlX2J1dHRvbi5zZXRBdHRyaWJ1dGUoJ2FyaWEtbGFiZWwnLCAnQ2xvc2UnKTtcbiAgICAgICAgbm90aWNlX2J1dHRvbi5zZXRBdHRyaWJ1dGUoJ3RpdGxlJywgY29yZS5sYW5nLmRpYWxvZ0JveC5jbG9zZSk7XG4gICAgICAgIG5vdGljZV9idXR0b24uaW5uZXJIVE1MID0gY29yZS5pY29ucy5jYW5jZWw7XG4gICAgICAgIFxuICAgICAgICBub3RpY2VfZGl2LmFwcGVuZENoaWxkKG5vdGljZV9zcGFuKTtcbiAgICAgICAgbm90aWNlX2Rpdi5hcHBlbmRDaGlsZChub3RpY2VfYnV0dG9uKTtcblxuICAgICAgICBjb250ZXh0Lm5vdGljZS5tb2RhbCA9IG5vdGljZV9kaXY7XG4gICAgICAgIGNvbnRleHQubm90aWNlLm1lc3NhZ2UgPSBub3RpY2Vfc3BhbjtcblxuICAgICAgICAvKiogYWRkIGV2ZW50IGxpc3RlbmVycyAqL1xuICAgICAgICBub3RpY2VfYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5vbkNsaWNrX2NhbmNlbC5iaW5kKGNvcmUpKTtcbiAgICAgICAgXG4gICAgICAgIC8qKiBhcHBlbmQgaHRtbCAqL1xuICAgICAgICBjb250ZXh0LmVsZW1lbnQuZWRpdG9yQXJlYS5hcHBlbmRDaGlsZChub3RpY2VfZGl2KTtcbiAgICAgICAgXG4gICAgICAgIC8qKiBlbXB0eSBtZW1vcnkgKi9cbiAgICAgICAgbm90aWNlX2RpdiA9IG51bGw7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEBkZXNjcmlwdGlvbiBFdmVudCB3aGVuIGNsaWNraW5nIHRoZSBjYW5jZWwgYnV0dG9uXG4gICAgICogQHBhcmFtIHtNb3VzZUV2ZW50fSBlIEV2ZW50IG9iamVjdFxuICAgICAqL1xuICAgIG9uQ2xpY2tfY2FuY2VsOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHRoaXMucGx1Z2lucy5ub3RpY2UuY2xvc2UuY2FsbCh0aGlzKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQGRlc2NyaXB0aW9uICBPcGVuIHRoZSBub3RpY2UgcGFuZWxcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdGV4dCBOb3RpY2UgbWVzc2FnZVxuICAgICAqL1xuICAgIG9wZW46IGZ1bmN0aW9uICh0ZXh0KSAge1xuICAgICAgICB0aGlzLmNvbnRleHQubm90aWNlLm1lc3NhZ2UudGV4dENvbnRlbnQgPSB0ZXh0O1xuICAgICAgICB0aGlzLmNvbnRleHQubm90aWNlLm1vZGFsLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gIE9wZW4gdGhlIG5vdGljZSBwYW5lbFxuICAgICAqL1xuICAgIGNsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC5ub3RpY2UubW9kYWwuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB9XG59O1xuIiwiLypcbiAqIHd5c2l3eWcgd2ViIGVkaXRvclxuICpcbiAqIHN1bmVkaXRvci5qc1xuICogQ29weXJpZ2h0IDIwMTcgSmlIb25nIExlZS5cbiAqIE1JVCBsaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCBjb3JlIGZyb20gJy4vbGliL2NvcmUnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi9saWIvdXRpbCc7XG5pbXBvcnQgX0NvbnN0cnVjdG9yIGZyb20gJy4vbGliL2NvbnN0cnVjdG9yJztcbmltcG9ydCBfQ29udGV4dCBmcm9tICcuL2xpYi9jb250ZXh0JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIC8qKlxuICAgICAqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIHRoZSBjcmVhdGUgZnVuY3Rpb24gd2l0aCBwcmVzZXQgb3B0aW9ucy5cbiAgICAgKiBJZiB0aGUgb3B0aW9ucyBvdmVybGFwLCB0aGUgb3B0aW9ucyBvZiB0aGUgJ2NyZWF0ZScgZnVuY3Rpb24gdGFrZSBwcmVjZWRlbmNlLlxuICAgICAqIEBwYXJhbSB7SnNvbn0gb3B0aW9ucyBJbml0aWFsaXphdGlvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdH1cbiAgICAgKi9cbiAgICBpbml0OiBmdW5jdGlvbiAoaW5pdF9vcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjcmVhdGU6IGZ1bmN0aW9uIChpZE9yRWxlbWVudCwgb3B0aW9ucykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZShpZE9yRWxlbWVudCwgb3B0aW9ucywgaW5pdF9vcHRpb25zKTtcbiAgICAgICAgICAgIH0uYmluZCh0aGlzKVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlIHRoZSBzdW5lZGl0b3JcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xFbGVtZW50fSBpZE9yRWxlbWVudCB0ZXh0YXJlYSBJZCBvciB0ZXh0YXJlYSBlbGVtZW50XG4gICAgICogQHBhcmFtIHtKU09OfE9iamVjdH0gb3B0aW9ucyB1c2VyIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fVxuICAgICAqL1xuICAgIGNyZWF0ZTogZnVuY3Rpb24gKGlkT3JFbGVtZW50LCBvcHRpb25zLCBfaW5pdF9vcHRpb25zKSB7XG4gICAgICAgIHV0aWwuX3Byb3BlcnRpZXNJbml0KCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0Jykgb3B0aW9ucyA9IHt9O1xuICAgICAgICBpZiAoX2luaXRfb3B0aW9ucykge1xuICAgICAgICAgICAgb3B0aW9ucyA9ICBbX2luaXRfb3B0aW9ucywgb3B0aW9uc10ucmVkdWNlKGZ1bmN0aW9uIChpbml0LCBvcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBrZXkgaW4gb3B0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdXRpbC5oYXNPd24ob3B0aW9uLCBrZXkpKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gJ3BsdWdpbnMnICYmIG9wdGlvbltrZXldICYmIGluaXRba2V5XSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGkgPSBpbml0W2tleV0sIG8gPSBvcHRpb25ba2V5XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPSBpLmxlbmd0aCA/IGkgOiBPYmplY3Qua2V5cyhpKS5tYXAoZnVuY3Rpb24obmFtZSkgeyByZXR1cm4gaVtuYW1lXTsgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvID0gby5sZW5ndGggPyBvIDogT2JqZWN0LmtleXMobykubWFwKGZ1bmN0aW9uKG5hbWUpIHsgcmV0dXJuIG9bbmFtZV07IH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5pdFtrZXldID0gKG8uZmlsdGVyKGZ1bmN0aW9uKHZhbCkgeyByZXR1cm4gaS5pbmRleE9mKHZhbCkgPT09IC0xOyB9KSkuY29uY2F0KGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5pdFtrZXldID0gb3B0aW9uW2tleV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluaXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LCB7fSk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0eXBlb2YgaWRPckVsZW1lbnQgPT09ICdzdHJpbmcnID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWRPckVsZW1lbnQpIDogaWRPckVsZW1lbnQ7XG5cbiAgICAgICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGlkT3JFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKCdbU1VORURJVE9SLmNyZWF0ZS5mYWlsXSBUaGUgZWxlbWVudCBmb3IgdGhhdCBpZCB3YXMgbm90IGZvdW5kIChJRDpcIicgKyBpZE9yRWxlbWVudCArICdcIiknKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1tTVU5FRElUT1IuY3JlYXRlLmZhaWxdIHN1bmVkaXRvciByZXF1aXJlcyB0ZXh0YXJlYVxcJ3MgZWxlbWVudCBvciBpZCB2YWx1ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29ucyA9IF9Db25zdHJ1Y3Rvci5pbml0KGVsZW1lbnQsIG9wdGlvbnMpO1xuXG4gICAgICAgIGlmIChjb25zLmNvbnN0cnVjdGVkLl90b3AuaWQgJiYgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoY29ucy5jb25zdHJ1Y3RlZC5fdG9wLmlkKSkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1tTVU5FRElUT1IuY3JlYXRlLmZhaWxdIFRoZSBJRCBvZiB0aGUgc3VuZWRpdG9yIHlvdSBhcmUgdHJ5aW5nIHRvIGNyZWF0ZSBhbHJlYWR5IGV4aXN0cyAoSUQ6XCInICsgY29ucy5jb25zdHJ1Y3RlZC5fdG9wLmlkICsgJ1wiKScpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvcmUoX0NvbnRleHQoZWxlbWVudCwgY29ucy5jb25zdHJ1Y3RlZCwgY29ucy5vcHRpb25zKSwgY29ucy5wbHVnaW5DYWxsQnV0dG9ucywgY29ucy5wbHVnaW5zLCBjb25zLm9wdGlvbnMubGFuZywgb3B0aW9ucywgY29ucy5fcmVzcG9uc2l2ZUJ1dHRvbnMpO1xuICAgIH1cbn07XG4iLCIvKlxyXG4gKiB3eXNpd3lnIHdlYiBlZGl0b3JcclxuICpcclxuICogc3VuZWRpdG9yLmpzXHJcbiAqIENvcHlyaWdodCAyMDE3IEppSG9uZyBMZWUuXHJcbiAqIE1JVCBsaWNlbnNlLlxyXG4gKi9cclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuaW1wb3J0IF9Db25zdHJ1Y3RvciBmcm9tICcuL2NvbnN0cnVjdG9yJztcclxuaW1wb3J0IF9Db250ZXh0IGZyb20gJy4vY29udGV4dCc7XHJcbmltcG9ydCBfaGlzdG9yeSBmcm9tICcuL2hpc3RvcnknO1xyXG5pbXBvcnQgX3V0aWwgZnJvbSAnLi91dGlsJztcclxuaW1wb3J0IF9ub3RpY2UgZnJvbSAnLi4vcGx1Z2lucy9tb2R1bGVzL19ub3RpY2UnO1xyXG5cclxuLyoqXHJcbiAqIEBkZXNjcmlwdGlvbiBTdW5FZGl0b3IgY29uc3R1Y3RvciBmdW5jdGlvbi5cclxuICogY3JlYXRlIGNvcmUgb2JqZWN0IGFuZCBldmVudCByZWdpc3RyYXRpb24uXHJcbiAqIGNvcmUsIGV2ZW50LCBmdW5jdGlvbnNcclxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcclxuICogQHBhcmFtIHtPYmplY3R9IHBsdWdpbkNhbGxCdXR0b25zXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBwbHVnaW5zIFxyXG4gKiBAcGFyYW0ge09iamVjdH0gbGFuZ1xyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xyXG4gKiBAcGFyYW0ge09iamVjdH0gX3Jlc3BvbnNpdmVCdXR0b25zXHJcbiAqIEByZXR1cm5zIHtPYmplY3R9IGZ1bmN0aW9ucyBPYmplY3RcclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChjb250ZXh0LCBwbHVnaW5DYWxsQnV0dG9ucywgcGx1Z2lucywgbGFuZywgb3B0aW9ucywgX3Jlc3BvbnNpdmVCdXR0b25zKSB7XHJcbiAgICBjb25zdCBfZCA9IGNvbnRleHQuZWxlbWVudC5vcmlnaW5FbGVtZW50Lm93bmVyRG9jdW1lbnQgfHwgZG9jdW1lbnQ7XHJcbiAgICBjb25zdCBfdyA9IF9kLmRlZmF1bHRWaWV3IHx8IHdpbmRvdztcclxuICAgIGNvbnN0IHV0aWwgPSBfdXRpbDtcclxuICAgIGNvbnN0IGljb25zID0gb3B0aW9ucy5pY29ucztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBlZGl0b3IgY29yZSBvYmplY3RcclxuICAgICAqIHNob3VsZCBhbHdheXMgYmluZCB0aGlzIG9iamVjdCB3aGVuIHJlZ2lzdGVyaW5nIGFuIGV2ZW50IGluIHRoZSBwbHVnLWluLlxyXG4gICAgICovXHJcbiAgICBjb25zdCBjb3JlID0ge1xyXG4gICAgICAgIF9kOiBfZCxcclxuICAgICAgICBfdzogX3csXHJcbiAgICAgICAgX3BhcnNlcjogbmV3IF93LkRPTVBhcnNlcigpLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gRG9jdW1lbnQgb2JqZWN0IG9mIHRoZSBpZnJhbWUgaWYgY3JlYXRlZCBhcyBhbiBpZnJhbWUgfHwgX2RcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF93ZDogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFdpbmRvdyBvYmplY3Qgb2YgdGhlIGlmcmFtZSBpZiBjcmVhdGVkIGFzIGFuIGlmcmFtZSB8fCBfd1xyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX3d3OiBudWxsLFxyXG4gICAgICAgIFxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDbG9zZXN0IFNoYWRvd1Jvb3QgdG8gZWRpdG9yIGlmIGZvdW5kXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfc2hhZG93Um9vdDogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFV0aWwgb2JqZWN0XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRpbDogdXRpbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEZ1bmN0aW9ucyBvYmplY3RcclxuICAgICAgICAgKi9cclxuICAgICAgICBmdW5jdGlvbnM6IG51bGwsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBOb3RpY2Ugb2JqZWN0XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgbm90aWNlOiBfbm90aWNlLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gRGVmYXVsdCBpY29ucyBvYmplY3RcclxuICAgICAgICAgKi9cclxuICAgICAgICBpY29uczogaWNvbnMsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBIaXN0b3J5IG9iamVjdCBmb3IgdW5kbywgcmVkb1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGhpc3Rvcnk6IG51bGwsXHJcbiAgICAgICAgXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEVsZW1lbnRzIGFuZCB1c2VyIG9wdGlvbnMgcGFyYW1ldGVycyBvZiB0aGUgc3VuZWRpdG9yXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgY29udGV4dDogY29udGV4dCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFBsdWdpbiBidXR0b25zXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgcGx1Z2luQ2FsbEJ1dHRvbnM6IHBsdWdpbkNhbGxCdXR0b25zLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gTG9hZGVkIHBsdWdpbnNcclxuICAgICAgICAgKi9cclxuICAgICAgICBwbHVnaW5zOiBwbHVnaW5zIHx8IHt9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gV2hldGhlciB0aGUgcGx1Z2luIGlzIGluaXRpYWxpemVkXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgaW5pdFBsdWdpbnM6IHt9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gT2JqZWN0IGZvciBtYW5hZ2luZyBzdWJtZW51IGVsZW1lbnRzXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfdGFyZ2V0UGx1Z2luczoge30sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBTYXZlIHJlbmRlcmVkIHN1Ym1lbnVzIGFuZCBjb250YWluZXJzXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfbWVudVRyYXk6IHt9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gbG9hZGVkIGxhbmd1YWdlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgbGFuZzogbGFuZyxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFRoZSBzZWxlY3Rpb24gbm9kZSAoY29yZS5nZXRTZWxlY3Rpb25Ob2RlKCkpIHRvIHdoaWNoIHRoZSBlZmZlY3Qgd2FzIGxhc3QgYXBwbGllZFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGVmZmVjdE5vZGU6IG51bGwsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBzdWJtZW51IGVsZW1lbnRcclxuICAgICAgICAgKi9cclxuICAgICAgICBzdWJtZW51OiBudWxsLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gY29udGFpbmVyIGVsZW1lbnRcclxuICAgICAgICAgKi9cclxuICAgICAgICBjb250YWluZXI6IG51bGwsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBjdXJyZW50IHN1Ym1lbnQgbmFtZVxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX3N1Ym1lbnVOYW1lOiAnJyxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIGJpbmRlZCBzdWJtZW51T2ZmIG1ldGhvZFxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX2JpbmRlZFN1Ym1lbnVPZmY6IG51bGwsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBiaW5kZWQgY29udGFpbmVyT2ZmIG1ldGhvZFxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX2JpbmRlZENvbnRhaW5lck9mZjogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIGFjdGl2ZSBidXR0b24gZWxlbWVudCBpbiBzdWJtZW51XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgc3VibWVudUFjdGl2ZUJ1dHRvbjogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIGFjdGl2ZSBidXR0b24gZWxlbWVudCBpbiBjb250YWluZXJcclxuICAgICAgICAgKi9cclxuICAgICAgICBjb250YWluZXJBY3RpdmVCdXR0b246IG51bGwsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBUaGUgZWxlbWVudHMgYXJyYXkgdG8gYmUgcHJvY2Vzc2VkIHVudmlzaWJsZSB3aGVuIHRoZSBjb250cm9sbGVyc09mZiBmdW5jdGlvbiBpcyBleGVjdXRlZCAocmVzaXppbmcsIGxpbmsgbW9kaWZpZWQgYnV0dG9uLCB0YWJsZSBjb250cm9sbGVyKVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNvbnRyb2xsZXJBcnJheTogW10sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBUaGUgbmFtZSBvZiB0aGUgcGx1Z2luIHRoYXQgY2FsbGVkIHRoZSBjdXJyZW50bHkgYWN0aXZlIGNvbnRyb2xsZXJcclxuICAgICAgICAgKi9cclxuICAgICAgICBjdXJyZW50Q29udHJvbGxlck5hbWU6ICcnLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gVGhlIHRhcmdldCBlbGVtZW50IG9mIGN1cnJlbnQgY29udHJvbGxlclxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGN1cnJlbnRDb250cm9sbGVyVGFyZ2V0OiBudWxsLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gVGhlIGZpbGUgY29tcG9uZW50IG9iamVjdCBvZiBjdXJyZW50IHNlbGVjdGVkIGZpbGUgdGFnIChnZXRGaWxlQ29tcG9uZW50KVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGN1cnJlbnRGaWxlQ29tcG9uZW50SW5mbzogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEFuIGFycmF5IG9mIGJ1dHRvbnMgd2hvc2UgY2xhc3MgbmFtZSBpcyBub3QgXCJzZS1jb2RlLXZpZXctZW5hYmxlZFwiXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgY29kZVZpZXdEaXNhYmxlZEJ1dHRvbnM6IG51bGwsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBBbiBhcnJheSBvZiBidXR0b25zIHdob3NlIGNsYXNzIG5hbWUgaXMgbm90IFwic2UtcmVzaXppbmctZW5hYmxlZFwiXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgcmVzaXppbmdEaXNhYmxlZEJ1dHRvbnM6IG51bGwsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBhY3RpdmUgbW9yZSBsYXllciBlbGVtZW50IGluIHN1Ym1lbnVcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9tb3JlTGF5ZXJBY3RpdmVCdXR0b246IG51bGwsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBUYWcgd2hpdGVsaXN0IFJlZ0V4cCBvYmplY3QgdXNlZCBpbiBcIl9jb25zaXN0ZW5jeUNoZWNrT2ZIVE1MXCIgbWV0aG9kXHJcbiAgICAgICAgICogXihvcHRpb25zLl9lZGl0b3JUYWdzV2hpdGVsaXN0KSRcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9odG1sQ2hlY2tXaGl0ZWxpc3RSZWdFeHA6IG51bGwsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBSZWdFeHAgd2hlbiB1c2luZyBjaGVjayBkaXNhbGxvd2QgdGFncy4gKGIsIGksIGlucywgc3RyaWtlLCBzKVxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX2Rpc2FsbG93ZWRUZXh0VGFnc1JlZ0V4cDogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEVkaXRvciB0YWdzIHdoaXRlbGlzdCAoUmVnRXhwIG9iamVjdClcclxuICAgICAgICAgKiB1dGlsLmNyZWF0ZVRhZ3NXaGl0ZWxpc3Qob3B0aW9ucy5fZWRpdG9yVGFnc1doaXRlbGlzdClcclxuICAgICAgICAgKi9cclxuICAgICAgICBlZGl0b3JUYWdzV2hpdGVsaXN0UmVnRXhwOiBudWxsLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gVGFnIHdoaXRlbGlzdCB3aGVuIHBhc3RpbmcgKFJlZ0V4cCBvYmplY3QpXHJcbiAgICAgICAgICogdXRpbC5jcmVhdGVUYWdzV2hpdGVsaXN0KG9wdGlvbnMucGFzdGVUYWdzV2hpdGVsaXN0KVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHBhc3RlVGFnc1doaXRlbGlzdFJlZ0V4cDogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEJvb2xlYW4gdmFsdWUgb2Ygd2hldGhlciB0aGUgZWRpdG9yIGhhcyBmb2N1c1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGhhc0ZvY3VzOiBmYWxzZSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEJvb2xlYW4gdmFsdWUgb2Ygd2hldGhlciB0aGUgZWRpdG9yIGlzIGRpc2FibGVkXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgaXNEaXNhYmxlZDogZmFsc2UsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBBdHRyaWJ1dGVzIHdoaXRlbGlzdCB1c2VkIGJ5IHRoZSBjbGVhbkhUTUwgbWV0aG9kXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfYXR0cmlidXRlc1doaXRlbGlzdFJlZ0V4cDogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEF0dHJpYnV0ZXMgb2YgdGFncyB3aGl0ZWxpc3QgdXNlZCBieSB0aGUgY2xlYW5IVE1MIG1ldGhvZFxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX2F0dHJpYnV0ZXNUYWdzV2hpdGVsaXN0OiBudWxsLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gYmluZGVkIGNvbnRyb2xsZXJzT2ZmIG1ldGhvZFxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX2JpbmRDb250cm9sbGVyc09mZjogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIElzIGlubGluZSBtb2RlP1xyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX2lzSW5saW5lOiBudWxsLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gSXMgYmFsbG9vbnxiYWxsb29uLWFsd2F5cyBtb2RlP1xyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX2lzQmFsbG9vbjogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIElzIGJhbGxvb24tYWx3YXlzIG1vZGU/XHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfaXNCYWxsb29uQWx3YXlzOiBudWxsLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gUmVxdWlyZWQgdmFsdWUgd2hlbiB1c2luZyBpbmxpbmUgbW9kZSB0byBzdGlja3kgdG9vbGJhclxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX2lubGluZVRvb2xiYXJBdHRyOiB7dG9wOiAnJywgd2lkdGg6ICcnLCBpc1Nob3c6IGZhbHNlfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFZhcmlhYmxlIHRoYXQgY29udHJvbHMgdGhlIFwiYmx1clwiIGV2ZW50IGluIHRoZSBlZGl0b3Igb2YgaW5saW5lIG9yIGJhbGxvb24gbW9kZSB3aGVuIHRoZSBmb2N1cyBpcyBtb3ZlZCB0byBzdWJtZW51XHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfbm90SGlkZVRvb2xiYXI6IGZhbHNlLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gVmFyaWFibGUgdmFsdWUgdGhhdCBzdGlja3kgdG9vbGJhciBtb2RlXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfc3RpY2t5OiBmYWxzZSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFZhcmlhYmxlcyBmb3IgY29udHJvbGxpbmcgZm9jdXMgYW5kIGJsdXIgZXZlbnRzXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfYW50aUJsdXI6IGZhbHNlLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ29tcG9uZW50IGxpbmUgYnJlYWtlciBlbGVtZW50XHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfbGluZUJyZWFrZXI6IG51bGwsXHJcbiAgICAgICAgX2xpbmVCcmVha2VyQnV0dG9uOiBudWxsLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gSWYgdHJ1ZSwgKGluaXRpYWxpemUsIHJlc2V0KSBhbGwgaW5kZXhlcyBvZiBpbWFnZSwgdmlkZW8gaW5mb3JtYXRpb25cclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9jb21wb25lbnRzSW5mb0luaXQ6IHRydWUsXHJcbiAgICAgICAgX2NvbXBvbmVudHNJbmZvUmVzZXQ6IGZhbHNlLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gUGx1Z2lucyBhcnJheSB3aXRoIFwiYWN0aXZlXCIgbWV0aG9kLlxyXG4gICAgICAgICAqIFwiYWN0aXZlUGx1Z2luc1wiIHJ1bnMgdGhlIFwiYWRkXCIgbWV0aG9kIHdoZW4gY3JlYXRpbmcgdGhlIGVkaXRvci5cclxuICAgICAgICAgKi9cclxuICAgICAgICBhY3RpdmVQbHVnaW5zOiBudWxsLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gSW5mb3JtYXRpb24gb2YgdGFncyB0aGF0IHNob3VsZCBtYWludGFpbiBIVE1MIHN0cnVjdHVyZSwgc3R5bGUsIGNsYXNzIG5hbWUsIGV0Yy4gKEluIHVzZSBieSBcIm1hdGhcIiBwbHVnaW4pXHJcbiAgICAgICAgICogV2hlbiBpbnNlcnRpbmcgXCJodG1sXCIgc3VjaCBhcyBwYXN0ZSwgaXQgaXMgZXhlY3V0ZWQgb24gdGhlIFwiaHRtbFwiIHRvIGJlIGluc2VydGVkLiAoY29yZS5jbGVhbkhUTUwpXHJcbiAgICAgICAgICogQmFzaWMgRWRpdG9yIEFjdGlvbnM6XHJcbiAgICAgICAgICogMS4gQWxsIGNsYXNzZXMgbm90IHN0YXJ0aW5nIHdpdGggXCJfX3NlX19cIiBvciBcInNlLVwiIGluIHRoZSBlZGl0b3IgYXJlIHJlbW92ZWQuXHJcbiAgICAgICAgICogMi4gVGhlIHN0eWxlIG9mIGFsbCB0YWdzIGV4Y2VwdCB0aGUgXCJzcGFuXCIgdGFnIGlzIHJlbW92ZWQgZnJvbSB0aGUgZWRpdG9yLlxyXG4gICAgICAgICAqIFwibWFuYWdlZFRhZ3NJbmZvXCIgc3RydWN0dXJlIGV4OlxyXG4gICAgICAgICAqIG1hbmFnZWRUYWdzSW5mbzoge1xyXG4gICAgICAgICAqICAgcXVlcnk6ICcuX19zZV9feHh4LCBzZS14eHgnXHJcbiAgICAgICAgICogICBtYXA6IHtcclxuICAgICAgICAgKiAgICAgJ19fc2VfX3h4eCc6IG1ldGhvZC5iaW5kKGNvcmUpLFxyXG4gICAgICAgICAqICAgICAnc2UteHh4JzogbWV0aG9kLmJpbmQoY29yZSksXHJcbiAgICAgICAgICogICB9XHJcbiAgICAgICAgICogfVxyXG4gICAgICAgICAqIEBleGFtcGxlXHJcbiAgICAgICAgICogRGVmaW5lIGluIHRoZSBmb2xsb3dpbmcgcmV0dXJuIGZvcm1hdCBpbiB0aGUgXCJtYW5hZ2VkVGFnSW5mb1wiIGZ1bmN0aW9uIG9mIHRoZSBwbHVnaW4uXHJcbiAgICAgICAgICogbWFuYWdlZFRhZ0luZm8oKSA9PiB7XHJcbiAgICAgICAgICogIHJldHVybiB7XHJcbiAgICAgICAgICogICAgY2xhc3NOYW1lOiAnc3RyaW5nJywgLy8gQ2xhc3MgbmFtZSB0byBpZGVudGlmeSB0aGUgdGFnLiAoXCJfX3NlX194eHhcIiwgXCJzZS14eHhcIilcclxuICAgICAgICAgKiAgICAvLyBDaGFuZ2UgdGhlIGh0bWwgb2YgdGhlIFwiZWxlbWVudFwiLiAoXCJlbGVtZW50XCIgaXMgdGhlIGVsZW1lbnQgZm91bmQgd2l0aCBcImNsYXNzTmFtZVwiLilcclxuICAgICAgICAgKiAgICAvLyBcIm1ldGhvZFwiIGlzIGV4ZWN1dGVkIGJ5IGJpbmRpbmcgXCJjb3JlXCIuXHJcbiAgICAgICAgICogICAgbWV0aG9kOiBmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAqICAgICAgLy8gdGhpcyA9PT0gY29yZVxyXG4gICAgICAgICAqICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSAvLyAocmVuZGVyZWQgaHRtbCk7XHJcbiAgICAgICAgICogICAgfVxyXG4gICAgICAgICAqICB9XHJcbiAgICAgICAgICogfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIG1hbmFnZWRUYWdzSW5mbzogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIGNhc2hpbmc6IG9wdGlvbnMuY2hhckNvdW50ZXJUeXBlID09PSAnYnl0ZS1odG1sJ1xyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX2NoYXJUeXBlSFRNTDogZmFsc2UsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBBcnJheSBvZiBcImNoZWNrRmlsZUluZm9cIiBmdW5jdGlvbnMgd2l0aCB0aGUgY29yZSBib3VuZFxyXG4gICAgICAgICAqIChQbHVnaW5zIHdpdGggXCJjaGVja0ZpbGVJbmZvXCIgYW5kIFwicmVzZXRGaWxlSW5mb1wiIG1ldGhvZHMpXHJcbiAgICAgICAgICogXCJmaWxlSW5mb1BsdWdpbnNcIiBydW5zIHRoZSBcImFkZFwiIG1ldGhvZCB3aGVuIGNyZWF0aW5nIHRoZSBlZGl0b3IuXHJcbiAgICAgICAgICogXCJjaGVja0ZpbGVJbmZvXCIgbWV0aG9kIGlzIGFsd2F5cyBjYWxsIGp1c3QgYmVmb3JlIHRoZSBcImNoYW5nZVwiIGV2ZW50LlxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX2ZpbGVJbmZvUGx1Z2luc0NoZWNrOiBudWxsLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQXJyYXkgb2YgXCJyZXNldEZpbGVJbmZvXCIgZnVuY3Rpb25zIHdpdGggdGhlIGNvcmUgYm91bmRcclxuICAgICAgICAgKiAoUGx1Z2lucyB3aXRoIFwiY2hlY2tGaWxlSW5mb1wiIGFuZCBcInJlc2V0RmlsZUluZm9cIiBtZXRob2RzKVxyXG4gICAgICAgICAqIFwiY2hlY2tGaWxlSW5mb1wiIG1ldGhvZCBpcyBhbHdheXMgY2FsbCBqdXN0IGJlZm9yZSB0aGUgXCJmdW5jdGlvbnMuc2V0T3B0aW9uc1wiIG1ldGhvZC5cclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9maWxlSW5mb1BsdWdpbnNSZXNldDogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFZhcmlhYmxlcyBmb3IgZmlsZSBjb21wb25lbnQgbWFuYWdlbWVudFxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX2ZpbGVNYW5hZ2VyOiB7XHJcbiAgICAgICAgICAgIHRhZ3M6IG51bGwsXHJcbiAgICAgICAgICAgIHJlZ0V4cDogbnVsbCxcclxuICAgICAgICAgICAgcXVlcnlTdHJpbmc6IG51bGwsXHJcbiAgICAgICAgICAgIHBsdWdpblJlZ0V4cDogbnVsbCxcclxuICAgICAgICAgICAgcGx1Z2luTWFwOiBudWxsXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEVsZW1lbnRzIHRoYXQgbmVlZCB0byBjaGFuZ2UgdGV4dCBvciBjbGFzc05hbWUgZm9yIGVhY2ggc2VsZWN0aW9uIGNoYW5nZVxyXG4gICAgICAgICAqIEFmdGVyIGNyZWF0aW5nIHRoZSBlZGl0b3IsIFwiYWN0aXZlUGx1Z2luc1wiIGFyZSBhZGRlZC5cclxuICAgICAgICAgKiBAcHJvcGVydHkge0VsZW1lbnR9IFNUUk9ORyBib2xkIGJ1dHRvblxyXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7RWxlbWVudH0gVSB1bmRlcmxpbmUgYnV0dG9uXHJcbiAgICAgICAgICogQHByb3BlcnR5IHtFbGVtZW50fSBFTSBpdGFsaWMgYnV0dG9uXHJcbiAgICAgICAgICogQHByb3BlcnR5IHtFbGVtZW50fSBERUwgc3RyaWtlIGJ1dHRvblxyXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7RWxlbWVudH0gU1VCIHN1YnNjcmlwdCBidXR0b25cclxuICAgICAgICAgKiBAcHJvcGVydHkge0VsZW1lbnR9IFNVUCBzdXBlcnNjcmlwdCBidXR0b25cclxuICAgICAgICAgKiBAcHJvcGVydHkge0VsZW1lbnR9IE9VVERFTlQgb3V0ZGVudCBidXR0b25cclxuICAgICAgICAgKiBAcHJvcGVydHkge0VsZW1lbnR9IElOREVOVCBpbmRlbnQgYnV0dG9uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgY29tbWFuZE1hcDogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFN0eWxlIGJ1dHRvbiByZWxhdGVkIHRvIGVkaXQgYXJlYVxyXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7RWxlbWVudH0gZnVsbFNjcmVlbiBmdWxsU2NyZWVuIGJ1dHRvbiBlbGVtZW50XHJcbiAgICAgICAgICogQHByb3BlcnR5IHtFbGVtZW50fSBzaG93QmxvY2tzIHNob3dCbG9ja3MgYnV0dG9uIGVsZW1lbnRcclxuICAgICAgICAgKiBAcHJvcGVydHkge0VsZW1lbnR9IGNvZGVWaWV3IGNvZGVWaWV3IGJ1dHRvbiBlbGVtZW50XHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfc3R5bGVDb21tYW5kTWFwOiBudWxsLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gTWFwIG9mIGRlZmF1bHQgY29tbWFuZFxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX2RlZmF1bHRDb21tYW5kOiB7XHJcbiAgICAgICAgICAgIGJvbGQ6ICdTVFJPTkcnLFxyXG4gICAgICAgICAgICB1bmRlcmxpbmU6ICdVJyxcclxuICAgICAgICAgICAgaXRhbGljOiAnRU0nLFxyXG4gICAgICAgICAgICBzdHJpa2U6ICdERUwnLFxyXG4gICAgICAgICAgICBzdWJzY3JpcHQ6ICdTVUInLFxyXG4gICAgICAgICAgICBzdXBlcnNjcmlwdDogJ1NVUCdcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gVmFyaWFibGVzIHVzZWQgaW50ZXJuYWxseSBpbiBlZGl0b3Igb3BlcmF0aW9uXHJcbiAgICAgICAgICogQHByb3BlcnR5IHtCb29sZWFufSBpc0NvZGVWaWV3IFN0YXRlIG9mIGNvZGUgdmlld1xyXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gaXNGdWxsU2NyZWVuIFN0YXRlIG9mIGZ1bGwgc2NyZWVuXHJcbiAgICAgICAgICogQHByb3BlcnR5IHtOdW1iZXJ9IGlubmVySGVpZ2h0X2Z1bGxTY3JlZW4gSW5uZXJIZWlnaHQgaW4gZWRpdG9yIHdoZW4gaW4gZnVsbCBzY3JlZW5cclxuICAgICAgICAgKiBAcHJvcGVydHkge051bWJlcn0gcmVzaXplQ2xpZW50WSBSZW1lbWJlciB0aGUgdmVydGljYWwgc2l6ZSBvZiB0aGUgZWRpdG9yIGJlZm9yZSByZXNpemluZyB0aGUgZWRpdG9yIChVc2VkIHdoZW4gY2FsY3VsYXRpbmcgZHVyaW5nIHJlc2l6ZSBvcGVyYXRpb24pXHJcbiAgICAgICAgICogQHByb3BlcnR5IHtOdW1iZXJ9IHRhYlNpemUgSW5kZW50IHNpemUgb2YgdGFiICg0KVxyXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBjb2RlSW5kZW50IEluZGVudCBzaXplIG9mIENvZGUgdmlldyBtb2RlICg0KVxyXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBtaW5SZXNpemluZ1NpemUgTWluaW11bSBzaXplIG9mIGVkaXRpbmcgYXJlYSB3aGVuIHJlc2l6ZWQge051bWJlcn0gKC5zZS13cmFwcGVyLWlubmVyIHttaW4taGVpZ2h0OiA2NXB4O30gfHwgNjUpXHJcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheX0gY3VycmVudE5vZGVzICBBbiBhcnJheSBvZiB0aGUgY3VycmVudCBjdXJzb3IncyBub2RlIHN0cnVjdHVyZVxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX3ZhcmlhYmxlOiB7XHJcbiAgICAgICAgICAgIGlzQ29kZVZpZXc6IGZhbHNlLFxyXG4gICAgICAgICAgICBpc0Z1bGxTY3JlZW46IGZhbHNlLFxyXG4gICAgICAgICAgICBpbm5lckhlaWdodF9mdWxsU2NyZWVuOiAwLFxyXG4gICAgICAgICAgICByZXNpemVDbGllbnRZOiAwLFxyXG4gICAgICAgICAgICB0YWJTaXplOiA0LFxyXG4gICAgICAgICAgICBjb2RlSW5kZW50OiA0LFxyXG4gICAgICAgICAgICBtaW5SZXNpemluZ1NpemU6IHV0aWwuZ2V0TnVtYmVyKChjb250ZXh0LmVsZW1lbnQud3lzaXd5Z0ZyYW1lLnN0eWxlLm1pbkhlaWdodCB8fCAnNjUnKSwgMCksXHJcbiAgICAgICAgICAgIGN1cnJlbnROb2RlczogW10sXHJcbiAgICAgICAgICAgIGN1cnJlbnROb2Rlc01hcDogW10sXHJcbiAgICAgICAgICAgIF9yYW5nZTogbnVsbCxcclxuICAgICAgICAgICAgX3NlbGVjdGlvbk5vZGU6IG51bGwsXHJcbiAgICAgICAgICAgIF9vcmlnaW5Dc3NUZXh0OiBjb250ZXh0LmVsZW1lbnQudG9wQXJlYS5zdHlsZS5jc3NUZXh0LFxyXG4gICAgICAgICAgICBfYm9keU92ZXJmbG93OiAnJyxcclxuICAgICAgICAgICAgX2VkaXRvckFyZWFPcmlnaW5Dc3NUZXh0OiAnJyxcclxuICAgICAgICAgICAgX3d5c2l3eWdPcmlnaW5Dc3NUZXh0OiAnJyxcclxuICAgICAgICAgICAgX2NvZGVPcmlnaW5Dc3NUZXh0OiAnJyxcclxuICAgICAgICAgICAgX2Z1bGxTY3JlZW5BdHRyczoge3N0aWNreTogZmFsc2UsIGJhbGxvb246IGZhbHNlLCBpbmxpbmU6IGZhbHNlfSxcclxuICAgICAgICAgICAgX2xpbmVCcmVha0NvbXA6IG51bGwsXHJcbiAgICAgICAgICAgIF9saW5lQnJlYWtEaXI6ICcnXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIElmIHRoZSBwbHVnaW4gaXMgbm90IGFkZGVkLCBhZGQgdGhlIHBsdWdpbiBhbmQgY2FsbCB0aGUgJ2FkZCcgZnVuY3Rpb24uXHJcbiAgICAgICAgICogSWYgdGhlIHBsdWdpbiBpcyBhZGRlZCBjYWxsIGNhbGxCYWNrIGZ1bmN0aW9uLlxyXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBwbHVnaW5OYW1lIFRoZSBuYW1lIG9mIHRoZSBwbHVnaW4gdG8gY2FsbFxyXG4gICAgICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxCYWNrRnVuY3Rpb24gRnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgbW9kdWxlIGNhbGxcclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR8bnVsbH0gX3RhcmdldCBQbHVnaW4gdGFyZ2V0IGJ1dHRvbiAoVGhpcyBpcyBub3QgbmVjZXNzYXJ5IGlmIHlvdSBoYXZlIGEgYnV0dG9uIGxpc3Qgd2hlbiBjcmVhdGluZyB0aGUgZWRpdG9yKVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNhbGxQbHVnaW46IGZ1bmN0aW9uIChwbHVnaW5OYW1lLCBjYWxsQmFja0Z1bmN0aW9uLCBfdGFyZ2V0KSB7XHJcbiAgICAgICAgICAgIF90YXJnZXQgPSBfdGFyZ2V0IHx8IHBsdWdpbkNhbGxCdXR0b25zW3BsdWdpbk5hbWVdO1xyXG5cclxuICAgICAgICAgICAgaWYgKCF0aGlzLnBsdWdpbnNbcGx1Z2luTmFtZV0pIHtcclxuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKCdbU1VORURJVE9SLmNvcmUuY2FsbFBsdWdpbi5mYWlsXSBUaGUgY2FsbGVkIHBsdWdpbiBkb2VzIG5vdCBleGlzdCBvciBpcyBpbiBhbiBpbnZhbGlkIGZvcm1hdC4gKHBsdWdpbk5hbWU6XCInICsgcGx1Z2luTmFtZSArICdcIiknKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5pbml0UGx1Z2luc1twbHVnaW5OYW1lXSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zW3BsdWdpbk5hbWVdLmFkZCh0aGlzLCBfdGFyZ2V0KTtcclxuICAgICAgICAgICAgICAgIHRoaXMuaW5pdFBsdWdpbnNbcGx1Z2luTmFtZV0gPSB0cnVlO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLl90YXJnZXRQbHVnaW5zW3BsdWdpbk5hbWVdID09PSAnb2JqZWN0JyAmJiAhIV90YXJnZXQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaW5pdE1lbnVUYXJnZXQocGx1Z2luTmFtZSwgX3RhcmdldCwgdGhpcy5fdGFyZ2V0UGx1Z2luc1twbHVnaW5OYW1lXSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnBsdWdpbnNbcGx1Z2luTmFtZV0uYWN0aXZlICYmICF0aGlzLmNvbW1hbmRNYXBbcGx1Z2luTmFtZV0gJiYgISFfdGFyZ2V0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbW1hbmRNYXBbcGx1Z2luTmFtZV0gPSBfdGFyZ2V0O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVQbHVnaW5zLnB1c2gocGx1Z2luTmFtZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGNhbGxCYWNrRnVuY3Rpb24gPT09ICdmdW5jdGlvbicpIGNhbGxCYWNrRnVuY3Rpb24oKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gSWYgdGhlIG1vZHVsZSBpcyBub3QgYWRkZWQsIGFkZCB0aGUgbW9kdWxlIGFuZCBjYWxsIHRoZSAnYWRkJyBmdW5jdGlvblxyXG4gICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IG1vZHVsZUFycmF5IG1vZHVsZSBvYmplY3QncyBBcnJheSBbZGlhbG9nLCByZXNpemluZ11cclxuICAgICAgICAgKi9cclxuICAgICAgICBhZGRNb2R1bGU6IGZ1bmN0aW9uIChtb2R1bGVBcnJheSkge1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gbW9kdWxlQXJyYXkubGVuZ3RoLCBtb2R1bGVOYW1lOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWUgPSBtb2R1bGVBcnJheVtpXS5uYW1lO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnBsdWdpbnNbbW9kdWxlTmFtZV0pIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnNbbW9kdWxlTmFtZV0gPSBtb2R1bGVBcnJheVtpXTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5pbml0UGx1Z2luc1ttb2R1bGVOYW1lXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5pdFBsdWdpbnNbbW9kdWxlTmFtZV0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5wbHVnaW5zW21vZHVsZU5hbWVdLmFkZCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5wbHVnaW5zW21vZHVsZU5hbWVdLmFkZCh0aGlzKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZm9yIG1hbmFnaW5nIHN1Ym1lbnUgZWxlbWVudC5cclxuICAgICAgICAgKiBZb3UgbXVzdCBhZGQgdGhlIFwic3VibWVudVwiIGVsZW1lbnQgdXNpbmcgdGhlIHRoaXMgbWV0aG9kIGF0IGN1c3RvbSBwbHVnaW4uXHJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHBsdWdpbk5hbWUgUGx1Z2luIG5hbWVcclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR8bnVsbH0gdGFyZ2V0IFRhcmdldCBidXR0b25cclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IG1lbnUgU3VibWVudSBlbGVtZW50XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgaW5pdE1lbnVUYXJnZXQ6IGZ1bmN0aW9uIChwbHVnaW5OYW1lLCB0YXJnZXQsIG1lbnUpIHtcclxuICAgICAgICAgICAgaWYgKCF0YXJnZXQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RhcmdldFBsdWdpbnNbcGx1Z2luTmFtZV0gPSBtZW51O1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5lbGVtZW50Ll9tZW51VHJheS5hcHBlbmRDaGlsZChtZW51KTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RhcmdldFBsdWdpbnNbcGx1Z2luTmFtZV0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbWVudVRyYXlbdGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS1jb21tYW5kJyldID0gbWVudTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBFbmFibGVkIHN1Ym1lbnVcclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgU3VibWVudSdzIGJ1dHRvbiBlbGVtZW50IHRvIGNhbGxcclxuICAgICAgICAgKi9cclxuICAgICAgICBzdWJtZW51T246IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9iaW5kZWRTdWJtZW51T2ZmKSB0aGlzLl9iaW5kZWRTdWJtZW51T2ZmKCk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9iaW5kQ29udHJvbGxlcnNPZmYpIHRoaXMuY29udHJvbGxlcnNPZmYoKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHN1Ym1lbnVOYW1lID0gdGhpcy5fc3VibWVudU5hbWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1jb21tYW5kJyk7XHJcbiAgICAgICAgICAgIGNvbnN0IG1lbnUgPSB0aGlzLnN1Ym1lbnUgPSB0aGlzLl9tZW51VHJheVtzdWJtZW51TmFtZV07XHJcbiAgICAgICAgICAgIHRoaXMuc3VibWVudUFjdGl2ZUJ1dHRvbiA9IGVsZW1lbnQ7XHJcbiAgICAgICAgICAgIHRoaXMuX3NldE1lbnVQb3NpdGlvbihlbGVtZW50LCBtZW51KTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIHRoaXMuX2JpbmRlZFN1Ym1lbnVPZmYgPSB0aGlzLnN1Ym1lbnVPZmYuYmluZCh0aGlzKTtcclxuICAgICAgICAgICAgdGhpcy5hZGREb2NFdmVudCgnbW91c2Vkb3duJywgdGhpcy5fYmluZGVkU3VibWVudU9mZiwgZmFsc2UpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMucGx1Z2luc1tzdWJtZW51TmFtZV0ub24pIHRoaXMucGx1Z2luc1tzdWJtZW51TmFtZV0ub24uY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgdGhpcy5fYW50aUJsdXIgPSB0cnVlO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBEaXNhYmxlIHN1Ym1lbnVcclxuICAgICAgICAgKi9cclxuICAgICAgICBzdWJtZW51T2ZmOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlRG9jRXZlbnQoJ21vdXNlZG93bicsIHRoaXMuX2JpbmRlZFN1Ym1lbnVPZmYpO1xyXG4gICAgICAgICAgICB0aGlzLl9iaW5kZWRTdWJtZW51T2ZmID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnN1Ym1lbnUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3N1Ym1lbnVOYW1lID0gJyc7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN1Ym1lbnUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgICAgIHRoaXMuc3VibWVudSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUNsYXNzKHRoaXMuc3VibWVudUFjdGl2ZUJ1dHRvbiwgJ29uJyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN1Ym1lbnVBY3RpdmVCdXR0b24gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbm90SGlkZVRvb2xiYXIgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5fYW50aUJsdXIgPSBmYWxzZTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gRW5hYmxlZCBjb250YWluZXJcclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgQ29udGFpbmVyJ3MgYnV0dG9uIGVsZW1lbnQgdG8gY2FsbFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNvbnRhaW5lck9uOiBmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fYmluZGVkQ29udGFpbmVyT2ZmKSB0aGlzLl9iaW5kZWRDb250YWluZXJPZmYoKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lck5hbWUgPSB0aGlzLl9jb250YWluZXJOYW1lID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY29tbWFuZCcpO1xyXG4gICAgICAgICAgICBjb25zdCBtZW51ID0gdGhpcy5jb250YWluZXIgPSB0aGlzLl9tZW51VHJheVtjb250YWluZXJOYW1lXTtcclxuICAgICAgICAgICAgdGhpcy5jb250YWluZXJBY3RpdmVCdXR0b24gPSBlbGVtZW50O1xyXG4gICAgICAgICAgICB0aGlzLl9zZXRNZW51UG9zaXRpb24oZWxlbWVudCwgbWVudSk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICB0aGlzLl9iaW5kZWRDb250YWluZXJPZmYgPSB0aGlzLmNvbnRhaW5lck9mZi5iaW5kKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLmFkZERvY0V2ZW50KCdtb3VzZWRvd24nLCB0aGlzLl9iaW5kZWRDb250YWluZXJPZmYsIGZhbHNlKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnBsdWdpbnNbY29udGFpbmVyTmFtZV0ub24pIHRoaXMucGx1Z2luc1tjb250YWluZXJOYW1lXS5vbi5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLl9hbnRpQmx1ciA9IHRydWU7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIERpc2FibGUgY29udGFpbmVyXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgY29udGFpbmVyT2ZmOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlRG9jRXZlbnQoJ21vdXNlZG93bicsIHRoaXMuX2JpbmRlZENvbnRhaW5lck9mZik7XHJcbiAgICAgICAgICAgIHRoaXMuX2JpbmRlZENvbnRhaW5lck9mZiA9IG51bGw7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2NvbnRhaW5lck5hbWUgPSAnJztcclxuICAgICAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lciA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUNsYXNzKHRoaXMuY29udGFpbmVyQWN0aXZlQnV0dG9uLCAnb24nKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29udGFpbmVyQWN0aXZlQnV0dG9uID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIHRoaXMuX25vdEhpZGVUb29sYmFyID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2FudGlCbHVyID0gZmFsc2U7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFNldCB0aGUgbWVudSBwb3NpdGlvbi4gKHN1Ym1lbnUsIGNvbnRhaW5lcilcclxuICAgICAgICAgKiBAcGFyYW0geyp9IGVsZW1lbnQgQnV0dG9uIGVsZW1lbnRcclxuICAgICAgICAgKiBAcGFyYW0geyp9IG1lbnUgTWVudSBlbGVtZW50XHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfc2V0TWVudVBvc2l0aW9uOiBmdW5jdGlvbiAoZWxlbWVudCwgbWVudSkge1xyXG4gICAgICAgICAgICBtZW51LnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcclxuICAgICAgICAgICAgbWVudS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuICAgICAgICAgICAgbWVudS5zdHlsZS5oZWlnaHQgPSAnJztcclxuICAgICAgICAgICAgdXRpbC5hZGRDbGFzcyhlbGVtZW50LCAnb24nKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHRvb2xiYXIgPSB0aGlzLmNvbnRleHQuZWxlbWVudC50b29sYmFyO1xyXG4gICAgICAgICAgICBjb25zdCB0b29sYmFyVyA9IHRvb2xiYXIub2Zmc2V0V2lkdGg7XHJcbiAgICAgICAgICAgIGNvbnN0IHRvb2xiYXJPZmZzZXQgPSBldmVudC5fZ2V0RWRpdG9yT2Zmc2V0cyhjb250ZXh0LmVsZW1lbnQudG9vbGJhcik7XHJcbiAgICAgICAgICAgIGNvbnN0IG1lbnVXID0gbWVudS5vZmZzZXRXaWR0aDtcclxuICAgICAgICAgICAgY29uc3QgbCA9IGVsZW1lbnQucGFyZW50RWxlbWVudC5vZmZzZXRMZWZ0ICsgMztcclxuXHJcbiAgICAgICAgICAgIC8vIHJ0bFxyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5ydGwpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRXID0gZWxlbWVudC5vZmZzZXRXaWR0aDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJ0bFcgPSBtZW51VyA+IGVsZW1lbnRXID8gbWVudVcgLSBlbGVtZW50VyA6IDA7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBydGxMID0gcnRsVyA+IDAgPyAwIDogZWxlbWVudFcgLSBtZW51VztcclxuICAgICAgICAgICAgICAgIG1lbnUuc3R5bGUubGVmdCA9IChsIC0gcnRsVyArIHJ0bEwpICsgJ3B4JztcclxuICAgICAgICAgICAgICAgIGlmICh0b29sYmFyT2Zmc2V0LmxlZnQgPiBldmVudC5fZ2V0RWRpdG9yT2Zmc2V0cyhtZW51KS5sZWZ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbWVudS5zdHlsZS5sZWZ0ID0gJzBweCc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBvdmVyTGVmdCA9IHRvb2xiYXJXIDw9IG1lbnVXID8gMCA6IHRvb2xiYXJXIC0gKGwgKyBtZW51Vyk7XHJcbiAgICAgICAgICAgICAgICBpZiAob3ZlckxlZnQgPCAwKSBtZW51LnN0eWxlLmxlZnQgPSAobCArIG92ZXJMZWZ0KSArICdweCc7XHJcbiAgICAgICAgICAgICAgICBlbHNlIG1lbnUuc3R5bGUubGVmdCA9IGwgKyAncHgnO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBnZXQgZWxlbWVudCB0b3BcclxuICAgICAgICAgICAgbGV0IHQgPSAwO1xyXG4gICAgICAgICAgICBsZXQgb2Zmc2V0RWwgPSBlbGVtZW50O1xyXG4gICAgICAgICAgICB3aGlsZSAob2Zmc2V0RWwgJiYgb2Zmc2V0RWwgIT09IHRvb2xiYXIpIHtcclxuICAgICAgICAgICAgICAgIHQgKz0gb2Zmc2V0RWwub2Zmc2V0VG9wO1xyXG4gICAgICAgICAgICAgICAgb2Zmc2V0RWwgPSBvZmZzZXRFbC5vZmZzZXRQYXJlbnQ7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGJ0ID0gdDtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzQmFsbG9vbikge1xyXG4gICAgICAgICAgICAgICAgdCArPSB0b29sYmFyLm9mZnNldFRvcCArIGVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdCAtPSBlbGVtZW50Lm9mZnNldEhlaWdodDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gc2V0IG1lbnUgcG9zaXRpb25cclxuICAgICAgICAgICAgY29uc3QgdG9vbGJhclRvcCA9IHRvb2xiYXJPZmZzZXQudG9wO1xyXG4gICAgICAgICAgICBsZXQgbWVudUhlaWdodCA9IG1lbnUub2Zmc2V0SGVpZ2h0O1xyXG4gICAgICAgICAgICBsZXQgZWwgPSBjb250ZXh0LmVsZW1lbnQudG9wQXJlYTtcclxuICAgICAgICAgICAgbGV0IHNjcm9sbFRvcCA9IDA7XHJcbiAgICAgICAgICAgIHdoaWxlICghIWVsKSB7XHJcbiAgICAgICAgICAgICAgICBzY3JvbGxUb3AgKz0gZWwuc2Nyb2xsVG9wO1xyXG4gICAgICAgICAgICAgICAgZWwgPSBlbC5wYXJlbnRFbGVtZW50O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBtZW51SGVpZ2h0X2JvdHRvbSA9IF93LmlubmVySGVpZ2h0IC0gKHRvb2xiYXJUb3AgLSBzY3JvbGxUb3AgKyBidCArIGVsZW1lbnQucGFyZW50RWxlbWVudC5vZmZzZXRIZWlnaHQpO1xyXG4gICAgICAgICAgICBpZiAobWVudUhlaWdodF9ib3R0b20gPCBtZW51SGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgbWVudVRvcCA9IC0xICogKG1lbnVIZWlnaHQgLSBidCArIDMpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaW5zVG9wID0gdG9vbGJhclRvcCAtIHNjcm9sbFRvcCArIG1lbnVUb3A7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtZW51SGVpZ2h0X3RvcCA9IG1lbnVIZWlnaHQgKyAoaW5zVG9wIDwgMCA/IGluc1RvcCA6IDApO1xyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICBpZiAobWVudUhlaWdodF90b3AgPiBtZW51SGVpZ2h0X2JvdHRvbSkge1xyXG4gICAgICAgICAgICAgICAgICAgIG1lbnUuc3R5bGUuaGVpZ2h0ID0gbWVudUhlaWdodF90b3AgKyAncHgnO1xyXG4gICAgICAgICAgICAgICAgICAgIG1lbnVUb3AgPSAtMSAqIChtZW51SGVpZ2h0X3RvcCAtIGJ0ICsgMyk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIG1lbnUuc3R5bGUuaGVpZ2h0ID0gbWVudUhlaWdodF9ib3R0b20gKyAncHgnO1xyXG4gICAgICAgICAgICAgICAgICAgIG1lbnVUb3AgPSBidCArIGVsZW1lbnQucGFyZW50RWxlbWVudC5vZmZzZXRIZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbWVudS5zdHlsZS50b3AgPSBtZW51VG9wICsgJ3B4JztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIG1lbnUuc3R5bGUudG9wID0gKGJ0ICsgZWxlbWVudC5wYXJlbnRFbGVtZW50Lm9mZnNldEhlaWdodCkgKyAncHgnO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBtZW51LnN0eWxlLnZpc2liaWxpdHkgPSAnJztcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gU2hvdyBjb250cm9sbGVyIGF0IGVkaXRvciBhcmVhIChjb250cm9sbGVyIGVsZW1lbnRzLCBmdW5jdGlvbiwgXCJjb250cm9sbGVyIHRhcmdldCBlbGVtZW50KEBSZXF1aXJlZClcIiwgXCJjb250cm9sbGVyIG5hbWUoQFJlcXVpcmVkKVwiLCBldGMuLilcclxuICAgICAgICAgKiBAcGFyYW0geyp9IGFyZ3VtZW50cyBjb250cm9sbGVyIGVsZW1lbnRzLCBmdW5jdGlvbnMuLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNvbnRyb2xsZXJzT246IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2JpbmRDb250cm9sbGVyc09mZikgdGhpcy5fYmluZENvbnRyb2xsZXJzT2ZmKCk7XHJcbiAgICAgICAgICAgIHRoaXMuY29udHJvbGxlckFycmF5ID0gW107XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgYXJnOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBhcmcgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgICAgICBpZiAoIWFyZykgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYXJnID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudENvbnRyb2xsZXJOYW1lID0gYXJnO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRyb2xsZXJBcnJheS5wdXNoKGFyZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoIXV0aWwuaGFzQ2xhc3MoYXJnLCAnc2UtY29udHJvbGxlcicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50Q29udHJvbGxlclRhcmdldCA9IGFyZztcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRGaWxlQ29tcG9uZW50SW5mbyA9IHRoaXMuZ2V0RmlsZUNvbXBvbmVudChhcmcpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGFyZy5zdHlsZSkgYXJnLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb250cm9sbGVyQXJyYXkucHVzaChhcmcpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9iaW5kQ29udHJvbGxlcnNPZmYgPSB0aGlzLmNvbnRyb2xsZXJzT2ZmLmJpbmQodGhpcyk7XHJcbiAgICAgICAgICAgIHRoaXMuYWRkRG9jRXZlbnQoJ21vdXNlZG93bicsIHRoaXMuX2JpbmRDb250cm9sbGVyc09mZiwgZmFsc2UpO1xyXG4gICAgICAgICAgICB0aGlzLmFkZERvY0V2ZW50KCdrZXlkb3duJywgdGhpcy5fYmluZENvbnRyb2xsZXJzT2ZmLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIHRoaXMuX2FudGlCbHVyID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZnVuY3Rpb25zLnNob3dDb250cm9sbGVyID09PSAnZnVuY3Rpb24nKSBmdW5jdGlvbnMuc2hvd0NvbnRyb2xsZXIodGhpcy5jdXJyZW50Q29udHJvbGxlck5hbWUsIHRoaXMuY29udHJvbGxlckFycmF5LCB0aGlzKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gSGlkZSBjb250cm9sbGVyIGF0IGVkaXRvciBhcmVhIChsaW5rIGJ1dHRvbiwgaW1hZ2UgcmVzaXplIGJ1dHRvbi4uKVxyXG4gICAgICAgICAqIEBwYXJhbSB7S2V5Ym9hcmRFdmVudHxNb3VzZUV2ZW50fG51bGx9IGUgRXZlbnQgb2JqZWN0IHdoZW4gY2FsbGVkIGZyb20gbW91c2Vkb3duIGFuZCBrZXlkb3duIGV2ZW50cyByZWdpc3RlcmVkIGluIFwiY29yZS5jb250cm9sbGVyc09uXCJcclxuICAgICAgICAgKi9cclxuICAgICAgICBjb250cm9sbGVyc09mZjogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2ZpbGVNYW5hZ2VyLnBsdWdpblJlZ0V4cC50ZXN0KHRoaXMuY3VycmVudENvbnRyb2xsZXJOYW1lKSAmJiBlICYmIGUudHlwZSA9PT0gJ2tleWRvd24nICYmIGUua2V5Q29kZSAhPT0gMjcpIHJldHVybjtcclxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LmxpbmVCcmVha2VyX3Quc3R5bGUuZGlzcGxheSA9IGNvbnRleHQuZWxlbWVudC5saW5lQnJlYWtlcl9iLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgIHRoaXMuX3ZhcmlhYmxlLl9saW5lQnJlYWtDb21wID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudENvbnRyb2xsZXJOYW1lID0gJyc7XHJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudENvbnRyb2xsZXJUYXJnZXQgPSBudWxsO1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRGaWxlQ29tcG9uZW50SW5mbyA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXMuZWZmZWN0Tm9kZSA9IG51bGw7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5fYmluZENvbnRyb2xsZXJzT2ZmKSByZXR1cm47XHJcblxyXG4gICAgICAgICAgICB0aGlzLnJlbW92ZURvY0V2ZW50KCdtb3VzZWRvd24nLCB0aGlzLl9iaW5kQ29udHJvbGxlcnNPZmYpO1xyXG4gICAgICAgICAgICB0aGlzLnJlbW92ZURvY0V2ZW50KCdrZXlkb3duJywgdGhpcy5fYmluZENvbnRyb2xsZXJzT2ZmKTtcclxuICAgICAgICAgICAgdGhpcy5fYmluZENvbnRyb2xsZXJzT2ZmID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGxlbiA9IHRoaXMuY29udHJvbGxlckFycmF5Lmxlbmd0aDtcclxuICAgICAgICAgICAgaWYgKGxlbiA+IDApIHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMuY29udHJvbGxlckFycmF5W2ldID09PSAnZnVuY3Rpb24nKSB0aGlzLmNvbnRyb2xsZXJBcnJheVtpXSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgdGhpcy5jb250cm9sbGVyQXJyYXlbaV0uc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRyb2xsZXJBcnJheSA9IFtdO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9hbnRpQmx1ciA9IGZhbHNlO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBTcGVjaWZ5IHRoZSBwb3NpdGlvbiBvZiB0aGUgY29udHJvbGxlci5cclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGNvbnRyb2xsZXIgQ29udHJvbGxlciBlbGVtZW50LlxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gcmVmZXJFbCBFbGVtZW50IHRoYXQgaXMgdGhlIGJhc2lzIG9mIHRoZSBjb250cm9sbGVyJ3MgcG9zaXRpb24uXHJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHBvc2l0aW9uIFR5cGUgb2YgcG9zaXRpb24gKFwidG9wXCIgfCBcImJvdHRvbVwiKVxyXG4gICAgICAgICAqIFdoZW4gdXNpbmcgdGhlIFwidG9wXCIgcG9zaXRpb24sIHRoZXJlIHNob3VsZCBub3QgYmUgYW4gYXJyb3cgb24gdGhlIGNvbnRyb2xsZXIuXHJcbiAgICAgICAgICogV2hlbiB1c2luZyB0aGUgXCJib3R0b21cIiBwb3NpdGlvbiB0aGVyZSBzaG91bGQgYmUgYW4gYXJyb3cgb24gdGhlIGNvbnRyb2xsZXIuXHJcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGFkZE9mZnNldCBUaGVzZSBhcmUgdGhlIGxlZnQgYW5kIHRvcCB2YWx1ZXMgdGhhdCBuZWVkIHRvIGJlIGFkZGVkIHNwZWNpYWxseS4gXHJcbiAgICAgICAgICogVGhpcyBhcmd1bWVudCBpcyByZXF1aXJlZC4gLSB7bGVmdDogMCwgdG9wOiAwfVxyXG4gICAgICAgICAqIFBsZWFzZSBlbnRlciB0aGUgdmFsdWUgYmFzZWQgb24gbHRyIG1vZGUuXHJcbiAgICAgICAgICogQ2FsY3VsYXRlZCBhdXRvbWF0aWNhbGx5IGluIHJ0bCBtb2RlLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHNldENvbnRyb2xsZXJQb3NpdGlvbjogZnVuY3Rpb24gKGNvbnRyb2xsZXIsIHJlZmVyRWwsIHBvc2l0aW9uLCBhZGRPZmZzZXQpIHtcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMucnRsKSBhZGRPZmZzZXQubGVmdCAqPSAtMTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9IHV0aWwuZ2V0T2Zmc2V0KHJlZmVyRWwsIGNvbnRleHQuZWxlbWVudC53eXNpd3lnRnJhbWUpO1xyXG4gICAgICAgICAgICBjb250cm9sbGVyLnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcclxuICAgICAgICAgICAgY29udHJvbGxlci5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuXHJcbiAgICAgICAgICAgIC8vIEhlaWdodCB2YWx1ZSBvZiB0aGUgYXJyb3cgZWxlbWVudCBpcyAxMXB4XHJcbiAgICAgICAgICAgIGNvbnN0IHRvcE1hcmdpbiA9IHBvc2l0aW9uID09PSAndG9wJyA/IC0oY29udHJvbGxlci5vZmZzZXRIZWlnaHQgKyAyKSA6IChyZWZlckVsLm9mZnNldEhlaWdodCArIDEyKTtcclxuICAgICAgICAgICAgY29udHJvbGxlci5zdHlsZS50b3AgPSAob2Zmc2V0LnRvcCArIHRvcE1hcmdpbiArIGFkZE9mZnNldC50b3ApICsgJ3B4JztcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGwgPSBvZmZzZXQubGVmdCAtIGNvbnRleHQuZWxlbWVudC53eXNpd3lnRnJhbWUuc2Nyb2xsTGVmdCArIGFkZE9mZnNldC5sZWZ0O1xyXG4gICAgICAgICAgICBjb25zdCBjb250cm9sbGVyVyA9IGNvbnRyb2xsZXIub2Zmc2V0V2lkdGg7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlZmVyRWxXID0gcmVmZXJFbC5vZmZzZXRXaWR0aDtcclxuXHJcbiAgICAgICAgICAgIC8vIHJ0bCAoV2lkdGggdmFsdWUgb2YgdGhlIGFycm93IGVsZW1lbnQgaXMgMjJweClcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMucnRsKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBydGxXID0gKGNvbnRyb2xsZXJXID4gcmVmZXJFbFcpID8gY29udHJvbGxlclcgLSByZWZlckVsVyA6IDA7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBydGxMID0gcnRsVyA+IDAgPyAwIDogcmVmZXJFbFcgLSBjb250cm9sbGVyVztcclxuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuc3R5bGUubGVmdCA9IChsIC0gcnRsVyArIHJ0bEwpICsgJ3B4JztcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgaWYgKHJ0bFcgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5maXJzdEVsZW1lbnRDaGlsZC5zdHlsZS5sZWZ0ID0gKChjb250cm9sbGVyVyAtIDE0IDwgMTAgKyBydGxXKSA/IChjb250cm9sbGVyVyAtIDE0KSA6ICgxMCArIHJ0bFcpKSArICdweCc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIGNvbnN0IG92ZXJTaXplID0gY29udGV4dC5lbGVtZW50Lnd5c2l3eWdGcmFtZS5vZmZzZXRMZWZ0IC0gY29udHJvbGxlci5vZmZzZXRMZWZ0O1xyXG4gICAgICAgICAgICAgICAgaWYgKG92ZXJTaXplID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuc3R5bGUubGVmdCA9ICcwcHgnO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZmlyc3RFbGVtZW50Q2hpbGQuc3R5bGUubGVmdCA9IG92ZXJTaXplICsgJ3B4JztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuc3R5bGUubGVmdCA9IGwgKyAncHgnO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IG92ZXJTaXplID0gY29udGV4dC5lbGVtZW50Lnd5c2l3eWdGcmFtZS5vZmZzZXRXaWR0aCAtIChjb250cm9sbGVyLm9mZnNldExlZnQgKyBjb250cm9sbGVyVyk7XHJcbiAgICAgICAgICAgICAgICBpZiAob3ZlclNpemUgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5zdHlsZS5sZWZ0ID0gKGNvbnRyb2xsZXIub2Zmc2V0TGVmdCArIG92ZXJTaXplKSArICdweCc7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5maXJzdEVsZW1lbnRDaGlsZC5zdHlsZS5sZWZ0ID0gKDIwIC0gb3ZlclNpemUpICsgJ3B4JztcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5maXJzdEVsZW1lbnRDaGlsZC5zdHlsZS5sZWZ0ID0gJzIwcHgnO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb250cm9sbGVyLnN0eWxlLnZpc2liaWxpdHkgPSAnJztcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gUnVuIGV2ZW50LnN0b3BQcm9wYWdhdGlvbiBhbmQgZXZlbnQucHJldmVudERlZmF1bHQuXHJcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGUgRXZlbnQgT2JqZWN0XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZXZlbnRTdG9wOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIGphdmFzY3JpcHQgZXhlY0NvbW1hbmRcclxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gY29tbWFuZCBqYXZhc2NyaXB0IGV4ZWNDb21tYW5kIGZ1bmN0aW9uIHByb3BlcnR5XHJcbiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufHVuZGVmaW5lZH0gc2hvd0RlZmF1bHRVSSBqYXZhc2NyaXB0IGV4ZWNDb21tYW5kIGZ1bmN0aW9uIHByb3BlcnR5XHJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd8dW5kZWZpbmVkfSB2YWx1ZSBqYXZhc2NyaXB0IGV4ZWNDb21tYW5kIGZ1bmN0aW9uIHByb3BlcnR5XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZXhlY0NvbW1hbmQ6IGZ1bmN0aW9uIChjb21tYW5kLCBzaG93RGVmYXVsdFVJLCB2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl93ZC5leGVjQ29tbWFuZChjb21tYW5kLCBzaG93RGVmYXVsdFVJLCAoY29tbWFuZCA9PT0gJ2Zvcm1hdEJsb2NrJyA/ICc8JyArIHZhbHVlICsgJz4nIDogdmFsdWUpKTtcclxuICAgICAgICAgICAgLy8gaGlzdG9yeSBzdGFja1xyXG4gICAgICAgICAgICB0aGlzLmhpc3RvcnkucHVzaCh0cnVlKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gRm9jdXMgdG8gd3lzaXd5ZyBhcmVhIHVzaW5nIFwibmF0aXZlIGZvY3VzIGZ1bmN0aW9uXCJcclxuICAgICAgICAgKi9cclxuICAgICAgICBuYXRpdmVGb2N1czogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjb25zdCBjYXB0aW9uID0gdXRpbC5nZXRQYXJlbnRFbGVtZW50KHRoaXMuZ2V0U2VsZWN0aW9uTm9kZSgpLCAnZmlnY2FwdGlvbicpO1xyXG4gICAgICAgICAgICBpZiAoY2FwdGlvbikge1xyXG4gICAgICAgICAgICAgICAgY2FwdGlvbi5mb2N1cygpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5lbGVtZW50Lnd5c2l3eWcuZm9jdXMoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5fZWRpdG9yUmFuZ2UoKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gRm9jdXMgdG8gd3lzaXd5ZyBhcmVhXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZm9jdXM6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKGNvbnRleHQuZWxlbWVudC53eXNpd3lnRnJhbWUuc3R5bGUuZGlzcGxheSA9PT0gJ25vbmUnKSByZXR1cm47XHJcblxyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5pZnJhbWUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlRm9jdXMoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSB0aGlzLmdldFJhbmdlKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyYW5nZS5zdGFydENvbnRhaW5lciA9PT0gcmFuZ2UuZW5kQ29udGFpbmVyICYmIHV0aWwuaXNXeXNpd3lnRGl2KHJhbmdlLnN0YXJ0Q29udGFpbmVyKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmb3JtYXQgPSB1dGlsLmNyZWF0ZUVsZW1lbnQob3B0aW9ucy5kZWZhdWx0VGFnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYnIgPSB1dGlsLmNyZWF0ZUVsZW1lbnQoJ0JSJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdC5hcHBlbmRDaGlsZChicik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC53eXNpd3lnLmFwcGVuZENoaWxkKGZvcm1hdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0UmFuZ2UoYnIsIDAsIGJyLCAwKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFJhbmdlKHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydE9mZnNldCwgcmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZUZvY3VzKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGV2ZW50Ll9hcHBseVRhZ0VmZmVjdHMoKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzQmFsbG9vbikgZXZlbnQuX3RvZ2dsZVRvb2xiYXJCYWxsb29uKCk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIElmIFwiZm9jdXNFbFwiIGlzIGEgY29tcG9uZW50LCB0aGVuIHRoYXQgY29tcG9uZW50IGlzIHNlbGVjdGVkOyBpZiBpdCBpcyBhIGZvcm1hdCBlbGVtZW50LCB0aGUgbGFzdCB0ZXh0IGlzIHNlbGVjdGVkXHJcbiAgICAgICAgICogSWYgXCJmb2N1c0VkZ2VcIiBpcyBudWxsLCB0aGVuIHNlbGVjdGVkIGxhc3QgZWxlbWVudFxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudHxudWxsfSBmb2N1c0VsIEZvY3VzIGVsZW1lbnRcclxuICAgICAgICAgKi9cclxuICAgICAgICBmb2N1c0VkZ2U6IGZ1bmN0aW9uIChmb2N1c0VsKSB7XHJcbiAgICAgICAgICAgIGlmICghZm9jdXNFbCkgZm9jdXNFbCA9IGNvbnRleHQuZWxlbWVudC53eXNpd3lnLmxhc3RFbGVtZW50Q2hpbGQ7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBmaWxlQ29tcG9uZW50SW5mbyA9IHRoaXMuZ2V0RmlsZUNvbXBvbmVudChmb2N1c0VsKTtcclxuICAgICAgICAgICAgaWYgKGZpbGVDb21wb25lbnRJbmZvKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdENvbXBvbmVudChmaWxlQ29tcG9uZW50SW5mby50YXJnZXQsIGZpbGVDb21wb25lbnRJbmZvLnBsdWdpbk5hbWUpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGZvY3VzRWwpIHtcclxuICAgICAgICAgICAgICAgIGZvY3VzRWwgPSB1dGlsLmdldENoaWxkRWxlbWVudChmb2N1c0VsLCBmdW5jdGlvbiAoY3VycmVudCkgeyByZXR1cm4gY3VycmVudC5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMCB8fCBjdXJyZW50Lm5vZGVUeXBlID09PSAzOyB9LCB0cnVlKTtcclxuICAgICAgICAgICAgICAgIGlmICghZm9jdXNFbCkgdGhpcy5uYXRpdmVGb2N1cygpO1xyXG4gICAgICAgICAgICAgICAgZWxzZSB0aGlzLnNldFJhbmdlKGZvY3VzRWwsIGZvY3VzRWwudGV4dENvbnRlbnQubGVuZ3RoLCBmb2N1c0VsLCBmb2N1c0VsLnRleHRDb250ZW50Lmxlbmd0aCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZvY3VzKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gU2V0IGN1cnJlbnQgZWRpdG9yJ3MgcmFuZ2Ugb2JqZWN0IGFuZCByZXR1cm4uXHJcbiAgICAgICAgICogQHBhcmFtIHtOb2RlfSBzdGFydENvbiBUaGUgc3RhcnRDb250YWluZXIgcHJvcGVydHkgb2YgdGhlIHNlbGVjdGlvbiBvYmplY3QuXHJcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IHN0YXJ0T2ZmIFRoZSBzdGFydE9mZnNldCBwcm9wZXJ0eSBvZiB0aGUgc2VsZWN0aW9uIG9iamVjdC5cclxuICAgICAgICAgKiBAcGFyYW0ge05vZGV9IGVuZENvbiBUaGUgZW5kQ29udGFpbmVyIHByb3BlcnR5IG9mIHRoZSBzZWxlY3Rpb24gb2JqZWN0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSBlbmRPZmYgVGhlIGVuZE9mZnNldCBwcm9wZXJ0eSBvZiB0aGUgc2VsZWN0aW9uIG9iamVjdC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSYW5nZSBvYmplY3QuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgc2V0UmFuZ2U6IGZ1bmN0aW9uIChzdGFydENvbiwgc3RhcnRPZmYsIGVuZENvbiwgZW5kT2ZmKSB7XHJcbiAgICAgICAgICAgIGlmICghc3RhcnRDb24gfHwgIWVuZENvbikgcmV0dXJuO1xyXG4gICAgICAgICAgICBpZiAoc3RhcnRPZmYgPiBzdGFydENvbi50ZXh0Q29udGVudC5sZW5ndGgpIHN0YXJ0T2ZmID0gc3RhcnRDb24udGV4dENvbnRlbnQubGVuZ3RoO1xyXG4gICAgICAgICAgICBpZiAoZW5kT2ZmID4gZW5kQ29uLnRleHRDb250ZW50Lmxlbmd0aCkgZW5kT2ZmID0gZW5kQ29uLnRleHRDb250ZW50Lmxlbmd0aDtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGNvbnN0IHJhbmdlID0gdGhpcy5fd2QuY3JlYXRlUmFuZ2UoKTtcclxuXHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICByYW5nZS5zZXRTdGFydChzdGFydENvbiwgc3RhcnRPZmYpO1xyXG4gICAgICAgICAgICAgICAgcmFuZ2Uuc2V0RW5kKGVuZENvbiwgZW5kT2ZmKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignW1NVTkVESVRPUi5jb3JlLmZvY3VzLmVycm9yXSAnICsgZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVGb2N1cygpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBzZWxlY3Rpb24gPSB0aGlzLmdldFNlbGVjdGlvbigpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMpIHtcclxuICAgICAgICAgICAgICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgc2VsZWN0aW9uLmFkZFJhbmdlKHJhbmdlKTtcclxuICAgICAgICAgICAgdGhpcy5fZWRpdG9yUmFuZ2UoKTtcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuaWZyYW1lKSB0aGlzLm5hdGl2ZUZvY3VzKCk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcmFuZ2U7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFJlbW92ZSByYW5nZSBvYmplY3QgYW5kIGJ1dHRvbiBlZmZlY3RcclxuICAgICAgICAgKi9cclxuICAgICAgICByZW1vdmVSYW5nZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB0aGlzLl92YXJpYWJsZS5fcmFuZ2UgPSBudWxsO1xyXG4gICAgICAgICAgICB0aGlzLl92YXJpYWJsZS5fc2VsZWN0aW9uTm9kZSA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXMuZ2V0U2VsZWN0aW9uKCkucmVtb3ZlQWxsUmFuZ2VzKCk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBjb21tYW5kTWFwID0gdGhpcy5jb21tYW5kTWFwO1xyXG4gICAgICAgICAgICBjb25zdCBhY3RpdmVQbHVnaW5zID0gdGhpcy5hY3RpdmVQbHVnaW5zO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBrZXkgaW4gY29tbWFuZE1hcCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF1dGlsLmhhc093bihjb21tYW5kTWFwLCBrZXkpKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGlmIChhY3RpdmVQbHVnaW5zLmluZGV4T2Yoa2V5KSA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGx1Z2luc1trZXldLmFjdGl2ZS5jYWxsKHRoaXMsIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTWFwLk9VVERFTlQgJiYgL15PVVRERU5UJC9pLnRlc3Qoa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbW1hbmRNYXAuT1VUREVOVC5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmRNYXAuSU5ERU5UICYmIC9eSU5ERU5UJC9pLnRlc3Qoa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbW1hbmRNYXAuSU5ERU5ULnJlbW92ZUF0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVDbGFzcyhjb21tYW5kTWFwW2tleV0sICdhY3RpdmUnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBHZXQgY3VycmVudCBlZGl0b3IncyByYW5nZSBvYmplY3RcclxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldFJhbmdlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJhbmdlID0gdGhpcy5fdmFyaWFibGUuX3JhbmdlIHx8IHRoaXMuX2NyZWF0ZURlZmF1bHRSYW5nZSgpO1xyXG4gICAgICAgICAgICBjb25zdCBzZWxlY3Rpb24gPSB0aGlzLmdldFNlbGVjdGlvbigpO1xyXG4gICAgICAgICAgICBpZiAocmFuZ2UuY29sbGFwc2VkID09PSBzZWxlY3Rpb24uaXNDb2xsYXBzZWQgfHwgIWNvbnRleHQuZWxlbWVudC53eXNpd3lnLmNvbnRhaW5zKHNlbGVjdGlvbi5mb2N1c05vZGUpKSByZXR1cm4gcmFuZ2U7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBpZiAoc2VsZWN0aW9uLnJhbmdlQ291bnQgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl92YXJpYWJsZS5fcmFuZ2UgPSBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl92YXJpYWJsZS5fcmFuZ2U7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzYyA9IHNlbGVjdGlvbi5hbmNob3JOb2RlLCBlYyA9IHNlbGVjdGlvbi5mb2N1c05vZGUsIHNvID0gc2VsZWN0aW9uLmFuY2hvck9mZnNldCwgZW8gPSBzZWxlY3Rpb24uZm9jdXNPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjb21wYXJlVmFsdWUgPSB1dGlsLmNvbXBhcmVFbGVtZW50cyhzYywgZWMpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmlnaHREaXIgPSBjb21wYXJlVmFsdWUuYW5jZXN0b3IgJiYgKGNvbXBhcmVWYWx1ZS5yZXN1bHQgPT09IDAgPyBzbyA8PSBlbyA6IGNvbXBhcmVWYWx1ZS5yZXN1bHQgPiAxID8gdHJ1ZSA6IGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNldFJhbmdlKFxyXG4gICAgICAgICAgICAgICAgICAgIHJpZ2h0RGlyID8gc2MgOiBlYyxcclxuICAgICAgICAgICAgICAgICAgICByaWdodERpciA/IHNvIDogZW8sXHJcbiAgICAgICAgICAgICAgICAgICAgcmlnaHREaXIgPyBlYyA6IHNjLFxyXG4gICAgICAgICAgICAgICAgICAgIHJpZ2h0RGlyID8gZW8gOiBzb1xyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBJZiB0aGUgXCJyYW5nZVwiIG9iamVjdCBpcyBhIG5vbi1lZGl0YWJsZSBhcmVhLCBhZGQgYSBsaW5lIGF0IHRoZSB0b3Agb2YgdGhlIGVkaXRvciBhbmQgdXBkYXRlIHRoZSBcInJhbmdlXCIgb2JqZWN0LlxyXG4gICAgICAgICAqIFJldHVybnMgYSBuZXcgXCJyYW5nZVwiIG9yIGFyZ3VtZW50IFwicmFuZ2VcIi5cclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gcmFuZ2UgY29yZS5nZXRSYW5nZSgpXHJcbiAgICAgICAgICogQHBhcmFtIHtFbGVtZW50fG51bGx9IGNvbnRhaW5lciBJZiB0aGVyZSBpcyBcImNvbnRhaW5lclwiIGFyZ3VtZW50LCBpdCBjcmVhdGVzIGEgbGluZSBpbiBmcm9udCBvZiB0aGUgY29udGFpbmVyLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3R9IHJhbmdlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0UmFuZ2VfYWRkTGluZTogZnVuY3Rpb24gKHJhbmdlLCBjb250YWluZXIpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX3NlbGVjdGlvblZvaWQocmFuZ2UpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB3eXNpd3lnID0gY29udGV4dC5lbGVtZW50Lnd5c2l3eWc7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBvcCA9IHV0aWwuY3JlYXRlRWxlbWVudChvcHRpb25zLmRlZmF1bHRUYWcpO1xyXG4gICAgICAgICAgICAgICAgb3AuaW5uZXJIVE1MID0gJzxicj4nO1xyXG4gICAgICAgICAgICAgICAgd3lzaXd5Zy5pbnNlcnRCZWZvcmUob3AsIGNvbnRhaW5lciAmJiBjb250YWluZXIgIT09IHd5c2l3eWcgPyBjb250YWluZXIubmV4dEVsZW1lbnRTaWJsaW5nIDogd3lzaXd5Zy5maXJzdEVsZW1lbnRDaGlsZCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldFJhbmdlKG9wLmZpcnN0RWxlbWVudENoaWxkLCAwLCBvcC5maXJzdEVsZW1lbnRDaGlsZCwgMSk7XHJcbiAgICAgICAgICAgICAgICByYW5nZSA9IHRoaXMuX3ZhcmlhYmxlLl9yYW5nZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gcmFuZ2U7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEdldCB3aW5kb3cgc2VsZWN0aW9uIG9iZWpjdFxyXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3R9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0U2VsZWN0aW9uOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zaGFkb3dSb290ICYmIHRoaXMuX3NoYWRvd1Jvb3QuZ2V0U2VsZWN0aW9uID8gdGhpcy5fc2hhZG93Um9vdC5nZXRTZWxlY3Rpb24oKSA6IHRoaXMuX3d3LmdldFNlbGVjdGlvbigpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBHZXQgY3VycmVudCBzZWxlY3Qgbm9kZVxyXG4gICAgICAgICAqIEByZXR1cm5zIHtOb2RlfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldFNlbGVjdGlvbk5vZGU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWbCoCh1dGlsLmlzV3lzaXd5Z0Rpdih0aGlzLl92YXJpYWJsZS5fc2VsZWN0aW9uTm9kZSkpwqB0aGlzLl9lZGl0b3JSYW5nZSgpO1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuX3ZhcmlhYmxlLl9zZWxlY3Rpb25Ob2RlKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzZWxlY3Rpb25Ob2RlID0gdXRpbC5nZXRDaGlsZEVsZW1lbnQoY29udGV4dC5lbGVtZW50Lnd5c2l3eWcuZmlyc3RDaGlsZCwgZnVuY3Rpb24gKGN1cnJlbnQpIHsgcmV0dXJuIGN1cnJlbnQuY2hpbGROb2Rlcy5sZW5ndGggPT09IDAgfHwgY3VycmVudC5ub2RlVHlwZSA9PT0gMzsgfSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFzZWxlY3Rpb25Ob2RlKcKge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2VkaXRvclJhbmdlKCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhcmlhYmxlLl9zZWxlY3Rpb25Ob2RlID0gc2VsZWN0aW9uTm9kZTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0aW9uTm9kZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdmFyaWFibGUuX3NlbGVjdGlvbk5vZGU7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFNhdmluZyB0aGUgcmFuZ2Ugb2JqZWN0IGFuZCB0aGUgY3VycmVudGx5IHNlbGVjdGVkIG5vZGUgb2YgZWRpdG9yXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfZWRpdG9yUmFuZ2U6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29uc3Qgc2VsZWN0aW9uID0gdGhpcy5nZXRTZWxlY3Rpb24oKTtcclxuICAgICAgICAgICAgaWYgKCFzZWxlY3Rpb24pIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICBsZXQgcmFuZ2UgPSBudWxsO1xyXG4gICAgICAgICAgICBsZXQgc2VsZWN0aW9uTm9kZSA9IG51bGw7XHJcblxyXG4gICAgICAgICAgICBpZiAoc2VsZWN0aW9uLnJhbmdlQ291bnQgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmFuZ2UgPSB0aGlzLl9jcmVhdGVEZWZhdWx0UmFuZ2UoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5fdmFyaWFibGUuX3JhbmdlID0gcmFuZ2U7XHJcblxyXG4gICAgICAgICAgICBpZiAocmFuZ2UuY29sbGFwc2VkKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb25Ob2RlID0gcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXI7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb25Ob2RlID0gc2VsZWN0aW9uLmV4dGVudE5vZGUgfHwgc2VsZWN0aW9uLmFuY2hvck5vZGU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuX3ZhcmlhYmxlLl9zZWxlY3Rpb25Ob2RlID0gc2VsZWN0aW9uTm9kZTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gUmV0dXJuIHRoZSByYW5nZSBvYmplY3Qgb2YgZWRpdG9yJ3MgZmlyc3QgY2hpbGQgbm9kZVxyXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3R9XHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfY3JlYXRlRGVmYXVsdFJhbmdlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHd5c2l3eWcgPSBjb250ZXh0LmVsZW1lbnQud3lzaXd5ZztcclxuICAgICAgICAgICAgd3lzaXd5Zy5mb2N1cygpO1xyXG4gICAgICAgICAgICBjb25zdCByYW5nZSA9IHRoaXMuX3dkLmNyZWF0ZVJhbmdlKCk7XHJcblxyXG4gICAgICAgICAgICBsZXQgZm9jdXNFbCA9IHd5c2l3eWcuZmlyc3RFbGVtZW50Q2hpbGQ7XHJcbiAgICAgICAgICAgIGlmICghZm9jdXNFbCkge1xyXG4gICAgICAgICAgICAgICAgZm9jdXNFbCA9IHV0aWwuY3JlYXRlRWxlbWVudChvcHRpb25zLmRlZmF1bHRUYWcpO1xyXG4gICAgICAgICAgICAgICAgZm9jdXNFbC5pbm5lckhUTUwgPSAnPGJyPic7XHJcbiAgICAgICAgICAgICAgICB3eXNpd3lnLmFwcGVuZENoaWxkKGZvY3VzRWwpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByYW5nZS5zZXRTdGFydChmb2N1c0VsLCAwKTtcclxuICAgICAgICAgICAgcmFuZ2Uuc2V0RW5kKGZvY3VzRWwsIDApO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgcmV0dXJuIHJhbmdlO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIHRydWUgaWYgdGhlcmUgaXMgbm8gdmFsaWQgXCJzZWxlY3Rpb25cIi5cclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gcmFuZ2UgY29yZS5nZXRSYW5nZSgpXHJcbiAgICAgICAgICogQHJldHVybnMge09iamVjdH0gcmFuZ2VcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9zZWxlY3Rpb25Wb2lkOiBmdW5jdGlvbiAocmFuZ2UpIHtcclxuICAgICAgICAgICAgY29uc3QgY29tbSA9IHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyO1xyXG4gICAgICAgICAgICByZXR1cm4gKHV0aWwuaXNXeXNpd3lnRGl2KHJhbmdlLnN0YXJ0Q29udGFpbmVyKSAmJiB1dGlsLmlzV3lzaXd5Z0RpdihyYW5nZS5lbmRDb250YWluZXIpKSB8fCAvRklHVVJFL2kudGVzdChjb21tLm5vZGVOYW1lKSB8fCB0aGlzLl9maWxlTWFuYWdlci5yZWdFeHAudGVzdChjb21tLm5vZGVOYW1lKSB8fCB1dGlsLmlzTWVkaWFDb21wb25lbnQoY29tbSk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFJlc2V0IHJhbmdlIG9iamVjdCB0byB0ZXh0IG5vZGUgc2VsZWN0ZWQgc3RhdHVzLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtCb29sZWFufSBSZXR1cm5zIGZhbHNlIGlmIHRoZXJlIGlzIG5vIHZhbGlkIHNlbGVjdGlvbi5cclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9yZXNldFJhbmdlVG9UZXh0Tm9kZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjb25zdCByYW5nZSA9IHRoaXMuZ2V0UmFuZ2UoKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX3NlbGVjdGlvblZvaWQocmFuZ2UpKSByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBsZXQgc3RhcnRDb24gPSByYW5nZS5zdGFydENvbnRhaW5lcjtcclxuICAgICAgICAgICAgbGV0IHN0YXJ0T2ZmID0gcmFuZ2Uuc3RhcnRPZmZzZXQ7XHJcbiAgICAgICAgICAgIGxldCBlbmRDb24gPSByYW5nZS5lbmRDb250YWluZXI7XHJcbiAgICAgICAgICAgIGxldCBlbmRPZmYgPSByYW5nZS5lbmRPZmZzZXQ7XHJcbiAgICAgICAgICAgIGxldCB0ZW1wQ29uLCB0ZW1wT2Zmc2V0LCB0ZW1wQ2hpbGQ7XHJcblxyXG4gICAgICAgICAgICBpZiAodXRpbC5pc0Zvcm1hdEVsZW1lbnQoc3RhcnRDb24pKSB7XHJcbiAgICAgICAgICAgICAgICBzdGFydENvbiA9IHN0YXJ0Q29uLmNoaWxkTm9kZXNbc3RhcnRPZmZdIHx8IHN0YXJ0Q29uLmxhc3RDaGlsZDtcclxuICAgICAgICAgICAgICAgIHN0YXJ0T2ZmID0gc3RhcnRDb24udGV4dENvbnRlbnQubGVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh1dGlsLmlzRm9ybWF0RWxlbWVudChlbmRDb24pKSB7XHJcbiAgICAgICAgICAgICAgICBlbmRDb24gPSBlbmRDb24uY2hpbGROb2Rlc1tlbmRPZmZdIHx8IGVuZENvbi5sYXN0Q2hpbGQ7XHJcbiAgICAgICAgICAgICAgICBlbmRPZmYgPSBlbmRDb24udGV4dENvbnRlbnQubGVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBzdGFydENvbnRhaW5lclxyXG4gICAgICAgICAgICB0ZW1wQ29uID0gdXRpbC5pc1d5c2l3eWdEaXYoc3RhcnRDb24pID8gY29udGV4dC5lbGVtZW50Lnd5c2l3eWcuZmlyc3RDaGlsZCA6IHN0YXJ0Q29uO1xyXG4gICAgICAgICAgICB0ZW1wT2Zmc2V0ID0gc3RhcnRPZmY7XHJcblxyXG4gICAgICAgICAgICBpZiAodXRpbC5pc0JyZWFrKHRlbXBDb24pIHx8ICh0ZW1wQ29uLm5vZGVUeXBlID09PSAxICYmIHRlbXBDb24uY2hpbGROb2Rlcy5sZW5ndGggPiAwKSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgb25seUJyZWFrID0gdXRpbC5pc0JyZWFrKHRlbXBDb24pO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFvbmx5QnJlYWspIHtcclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAodGVtcENvbiAmJiAhdXRpbC5pc0JyZWFrKHRlbXBDb24pICYmIHRlbXBDb24ubm9kZVR5cGUgPT09IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGVtcENvbiA9IHRlbXBDb24uY2hpbGROb2Rlc1t0ZW1wT2Zmc2V0XSB8fCB0ZW1wQ29uLm5leHRFbGVtZW50U2libGluZyB8fCB0ZW1wQ29uLm5leHRTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wT2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICBcclxuICAgICAgICAgICAgICAgICAgICBsZXQgZm9ybWF0ID0gdXRpbC5nZXRGb3JtYXRFbGVtZW50KHRlbXBDb24sIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmb3JtYXQgPT09IHV0aWwuZ2V0UmFuZ2VGb3JtYXRFbGVtZW50KGZvcm1hdCwgbnVsbCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0ID0gdXRpbC5jcmVhdGVFbGVtZW50KHV0aWwuZ2V0UGFyZW50RWxlbWVudCh0ZW1wQ29uLCB1dGlsLmlzQ2VsbCkgPyAnRElWJyA6IG9wdGlvbnMuZGVmYXVsdFRhZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBDb24ucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZm9ybWF0LCB0ZW1wQ29uKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0LmFwcGVuZENoaWxkKHRlbXBDb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodXRpbC5pc0JyZWFrKHRlbXBDb24pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW1wdHlUZXh0ID0gdXRpbC5jcmVhdGVUZXh0Tm9kZSh1dGlsLnplcm9XaWR0aFNwYWNlKTtcclxuICAgICAgICAgICAgICAgICAgICB0ZW1wQ29uLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVtcHR5VGV4dCwgdGVtcENvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgdGVtcENvbiA9IGVtcHR5VGV4dDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob25seUJyZWFrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGFydENvbiA9PT0gZW5kQ29uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRDb24gPSB0ZW1wQ29uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kT2ZmID0gMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gc2V0IHN0YXJ0Q29udGFpbmVyXHJcbiAgICAgICAgICAgIHN0YXJ0Q29uID0gdGVtcENvbjtcclxuICAgICAgICAgICAgc3RhcnRPZmYgPSB0ZW1wT2Zmc2V0O1xyXG5cclxuICAgICAgICAgICAgLy8gZW5kQ29udGFpbmVyXHJcbiAgICAgICAgICAgIHRlbXBDb24gPSB1dGlsLmlzV3lzaXd5Z0RpdihlbmRDb24pID8gY29udGV4dC5lbGVtZW50Lnd5c2l3eWcubGFzdENoaWxkIDogZW5kQ29uO1xyXG4gICAgICAgICAgICB0ZW1wT2Zmc2V0ID0gZW5kT2ZmO1xyXG5cclxuICAgICAgICAgICAgaWYgKHV0aWwuaXNCcmVhayh0ZW1wQ29uKSB8fCAodGVtcENvbi5ub2RlVHlwZSA9PT0gMSAmJiB0ZW1wQ29uLmNoaWxkTm9kZXMubGVuZ3RoID4gMCkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG9ubHlCcmVhayA9IHV0aWwuaXNCcmVhayh0ZW1wQ29uKTtcclxuICAgICAgICAgICAgICAgIGlmICghb25seUJyZWFrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHRlbXBDb24gJiYgIXV0aWwuaXNCcmVhayh0ZW1wQ29uKSAmJiB0ZW1wQ29uLm5vZGVUeXBlID09PSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBDaGlsZCA9IHRlbXBDb24uY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXBDaGlsZC5sZW5ndGggPT09IDApIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wQ29uID0gdGVtcENoaWxkW3RlbXBPZmZzZXQgPiAwID8gdGVtcE9mZnNldCAtIDEgOiB0ZW1wT2Zmc2V0XSB8fCAhL0ZJR1VSRS9pLnRlc3QodGVtcENoaWxkWzBdLm5vZGVOYW1lKSA/IHRlbXBDaGlsZFswXSA6ICh0ZW1wQ29uLnByZXZpb3VzRWxlbWVudFNpYmxpbmcgfHwgdGVtcENvbi5wcmV2aW91c1NpYmxpbmcgfHwgc3RhcnRDb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wT2Zmc2V0ID0gdGVtcE9mZnNldCA+IDAgPyB0ZW1wQ29uLnRleHRDb250ZW50Lmxlbmd0aCA6IHRlbXBPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGZvcm1hdCA9IHV0aWwuZ2V0Rm9ybWF0RWxlbWVudCh0ZW1wQ29uLCBudWxsKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZm9ybWF0ID09PSB1dGlsLmdldFJhbmdlRm9ybWF0RWxlbWVudChmb3JtYXQsIG51bGwpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdCA9IHV0aWwuY3JlYXRlRWxlbWVudCh1dGlsLmlzQ2VsbChmb3JtYXQpID8gJ0RJVicgOiBvcHRpb25zLmRlZmF1bHRUYWcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wQ29uLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGZvcm1hdCwgdGVtcENvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdC5hcHBlbmRDaGlsZCh0ZW1wQ29uKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHV0aWwuaXNCcmVhayh0ZW1wQ29uKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVtcHR5VGV4dCA9IHV0aWwuY3JlYXRlVGV4dE5vZGUodXRpbC56ZXJvV2lkdGhTcGFjZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGVtcENvbi5wYXJlbnROb2RlLmluc2VydEJlZm9yZShlbXB0eVRleHQsIHRlbXBDb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIHRlbXBDb24gPSBlbXB0eVRleHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdGVtcE9mZnNldCA9IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9ubHlCcmVhayAmJiAhdGVtcENvbi5wcmV2aW91c1NpYmxpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVJdGVtKGVuZENvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBzZXQgZW5kQ29udGFpbmVyXHJcbiAgICAgICAgICAgIGVuZENvbiA9IHRlbXBDb247XHJcbiAgICAgICAgICAgIGVuZE9mZiA9IHRlbXBPZmZzZXQ7XHJcblxyXG4gICAgICAgICAgICAvLyBzZXQgUmFuZ2VcclxuICAgICAgICAgICAgdGhpcy5zZXRSYW5nZShzdGFydENvbiwgc3RhcnRPZmYsIGVuZENvbiwgZW5kT2ZmKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFJldHVybnMgYSBcImZvcm1hdEVsZW1lbnRcIih1dGlsLmlzRm9ybWF0RWxlbWVudCkgYXJyYXkgZnJvbSB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHJhbmdlLlxyXG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb258bnVsbH0gdmFsaWRhdGlvbiBUaGUgdmFsaWRhdGlvbiBmdW5jdGlvbi4gKFJlcGxhY2VzIHRoZSBkZWZhdWx0IHZhbGlkYXRpb24gZnVuY3Rpb24tdXRpbC5pc0Zvcm1hdEVsZW1lbnQoY3VycmVudCkpXHJcbiAgICAgICAgICogQHJldHVybnMge0FycmF5fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldFNlbGVjdGVkRWxlbWVudHM6IGZ1bmN0aW9uICh2YWxpZGF0aW9uKSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5fcmVzZXRSYW5nZVRvVGV4dE5vZGUoKSkgcmV0dXJuIFtdO1xyXG4gICAgICAgICAgICBsZXQgcmFuZ2UgPSB0aGlzLmdldFJhbmdlKCk7XHJcblxyXG4gICAgICAgICAgICBpZiAodXRpbC5pc1d5c2l3eWdEaXYocmFuZ2Uuc3RhcnRDb250YWluZXIpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IGNvbnRleHQuZWxlbWVudC53eXNpd3lnLmNoaWxkcmVuO1xyXG4gICAgICAgICAgICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuc2V0UmFuZ2UoY2hpbGRyZW5bMF0sIDAsIGNoaWxkcmVuW2NoaWxkcmVuLmxlbmd0aCAtIDFdLCBjaGlsZHJlbltjaGlsZHJlbi5sZW5ndGggLSAxXS50ZXh0Q29udGVudC50cmltKCkubGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIHJhbmdlID0gdGhpcy5nZXRSYW5nZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBzdGFydENvbiA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICBjb25zdCBlbmRDb24gPSByYW5nZS5lbmRDb250YWluZXI7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvbW1vbkNvbiA9IHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyO1xyXG5cclxuICAgICAgICAgICAgLy8gZ2V0IGxpbmUgbm9kZXNcclxuICAgICAgICAgICAgY29uc3QgbGluZU5vZGVzID0gdXRpbC5nZXRMaXN0Q2hpbGRyZW4oY29tbW9uQ29uLCBmdW5jdGlvbiAoY3VycmVudCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbGlkYXRpb24gPyB2YWxpZGF0aW9uKGN1cnJlbnQpIDogdXRpbC5pc0Zvcm1hdEVsZW1lbnQoY3VycmVudCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgaWYgKCF1dGlsLmlzV3lzaXd5Z0Rpdihjb21tb25Db24pICYmICF1dGlsLmlzUmFuZ2VGb3JtYXRFbGVtZW50KGNvbW1vbkNvbikpIGxpbmVOb2Rlcy51bnNoaWZ0KHV0aWwuZ2V0Rm9ybWF0RWxlbWVudChjb21tb25Db24sIG51bGwpKTtcclxuICAgICAgICAgICAgaWYgKHN0YXJ0Q29uID09PSBlbmRDb24gfHwgbGluZU5vZGVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGxpbmVOb2RlcztcclxuXHJcbiAgICAgICAgICAgIGxldCBzdGFydExpbmUgPSB1dGlsLmdldEZvcm1hdEVsZW1lbnQoc3RhcnRDb24sIG51bGwpO1xyXG4gICAgICAgICAgICBsZXQgZW5kTGluZSA9IHV0aWwuZ2V0Rm9ybWF0RWxlbWVudChlbmRDb24sIG51bGwpO1xyXG4gICAgICAgICAgICBsZXQgc3RhcnRJZHggPSBudWxsO1xyXG4gICAgICAgICAgICBsZXQgZW5kSWR4ID0gbnVsbDtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGNvbnN0IG9ubHlUYWJsZSA9IGZ1bmN0aW9uIChjdXJyZW50KSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdXRpbC5pc1RhYmxlKGN1cnJlbnQpID8gL15UQUJMRSQvaS50ZXN0KGN1cnJlbnQubm9kZU5hbWUpIDogdHJ1ZTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGxldCBzdGFydFJhbmdlRWwgPSB1dGlsLmdldFJhbmdlRm9ybWF0RWxlbWVudChzdGFydExpbmUsIG9ubHlUYWJsZSk7XHJcbiAgICAgICAgICAgIGxldCBlbmRSYW5nZUVsID0gdXRpbC5nZXRSYW5nZUZvcm1hdEVsZW1lbnQoZW5kTGluZSwgb25seVRhYmxlKTtcclxuICAgICAgICAgICAgaWYgKHV0aWwuaXNUYWJsZShzdGFydFJhbmdlRWwpICYmIHV0aWwuaXNMaXN0Q2VsbChzdGFydFJhbmdlRWwucGFyZW50Tm9kZSkpIHN0YXJ0UmFuZ2VFbCA9IHN0YXJ0UmFuZ2VFbC5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICBpZiAodXRpbC5pc1RhYmxlKGVuZFJhbmdlRWwpICYmIHV0aWwuaXNMaXN0Q2VsbChlbmRSYW5nZUVsLnBhcmVudE5vZGUpKSBlbmRSYW5nZUVsID0gZW5kUmFuZ2VFbC5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgY29uc3Qgc2FtZVJhbmdlID0gc3RhcnRSYW5nZUVsID09PSBlbmRSYW5nZUVsO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gbGluZU5vZGVzLmxlbmd0aCwgbGluZTsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsaW5lID0gbGluZU5vZGVzW2ldO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChzdGFydExpbmUgPT09IGxpbmUgfHwgKCFzYW1lUmFuZ2UgJiYgbGluZSA9PT0gc3RhcnRSYW5nZUVsKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0SWR4ID0gaTtcclxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoZW5kTGluZSA9PT0gbGluZSB8fCAoIXNhbWVSYW5nZSAmJiBsaW5lID09PSBlbmRSYW5nZUVsKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVuZElkeCA9IGk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChzdGFydElkeCA9PT0gbnVsbCkgc3RhcnRJZHggPSAwO1xyXG4gICAgICAgICAgICBpZiAoZW5kSWR4ID09PSBudWxsKSBlbmRJZHggPSBsaW5lTm9kZXMubGVuZ3RoIC0gMTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBsaW5lTm9kZXMuc2xpY2Uoc3RhcnRJZHgsIGVuZElkeCArIDEpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBHZXQgZm9ybWF0IGVsZW1lbnRzIGFuZCBjb21wb25lbnRzIGZyb20gdGhlIHNlbGVjdGVkIGFyZWEuIChQLCBESVYsIEhbMS02XSwgT0wsIFVMLCBUQUJMRS4uKVxyXG4gICAgICAgICAqIElmIHNvbWUgb2YgdGhlIGNvbXBvbmVudCBhcmUgaW5jbHVkZWQgaW4gdGhlIHNlbGVjdGlvbiwgZ2V0IHRoZSBlbnRpcmUgdGhhdCBjb21wb25lbnQuXHJcbiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSByZW1vdmVEdXBsaWNhdGUgSWYgdHJ1ZSwgaWYgdGhlcmUgaXMgYSBwYXJlbnQgYW5kIGNoaWxkIHRhZyBhbW9uZyB0aGUgc2VsZWN0ZWQgZWxlbWVudHMsIHRoZSBjaGlsZCB0YWcgaXMgZXhjbHVkZWQuXHJcbiAgICAgICAgICogQHJldHVybnMge0FycmF5fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldFNlbGVjdGVkRWxlbWVudHNBbmRDb21wb25lbnRzOiBmdW5jdGlvbiAocmVtb3ZlRHVwbGljYXRlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvbW1vbkNvbiA9IHRoaXMuZ2V0UmFuZ2UoKS5jb21tb25BbmNlc3RvckNvbnRhaW5lcjtcclxuICAgICAgICAgICAgY29uc3QgbXlDb21wb25lbnQgPSB1dGlsLmdldFBhcmVudEVsZW1lbnQoY29tbW9uQ29uLCB1dGlsLmlzQ29tcG9uZW50KTtcclxuICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWRMaW5lcyA9IHV0aWwuaXNUYWJsZShjb21tb25Db24pID8gXHJcbiAgICAgICAgICAgICAgICB0aGlzLmdldFNlbGVjdGVkRWxlbWVudHMobnVsbCkgOlxyXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRTZWxlY3RlZEVsZW1lbnRzKGZ1bmN0aW9uIChjdXJyZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29tcG9uZW50ID0gdGhpcy5nZXRQYXJlbnRFbGVtZW50KGN1cnJlbnQsIHRoaXMuaXNDb21wb25lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAodGhpcy5pc0Zvcm1hdEVsZW1lbnQoY3VycmVudCkgJiYgKCFjb21wb25lbnQgfHwgY29tcG9uZW50ID09PSBteUNvbXBvbmVudCkpIHx8ICh0aGlzLmlzQ29tcG9uZW50KGN1cnJlbnQpICYmICF0aGlzLmdldEZvcm1hdEVsZW1lbnQoY3VycmVudCkpO1xyXG4gICAgICAgICAgICAgICAgfS5iaW5kKHV0aWwpKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGlmIChyZW1vdmVEdXBsaWNhdGUpIHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBzZWxlY3RlZExpbmVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IGkgLSAxOyBqID49IDA7IGotLSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWRMaW5lc1tqXS5jb250YWlucyhzZWxlY3RlZExpbmVzW2ldKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRMaW5lcy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpLS07IGxlbi0tO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBzZWxlY3RlZExpbmVzO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBEZXRlcm1pbmUgaWYgdGhpcyBvZmZzZXQgaXMgdGhlIGVkZ2Ugb2Zmc2V0IG9mIGNvbnRhaW5lclxyXG4gICAgICAgICAqIEBwYXJhbSB7Tm9kZX0gY29udGFpbmVyIFRoZSBub2RlIG9mIHRoZSBzZWxlY3Rpb24gb2JqZWN0LiAocmFuZ2Uuc3RhcnRDb250YWluZXIuLilcclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gb2Zmc2V0IFRoZSBvZmZzZXQgb2YgdGhlIHNlbGVjdGlvbiBvYmplY3QuIChjb3JlLmdldFJhbmdlKCkuc3RhcnRPZmZzZXQuLi4pXHJcbiAgICAgICAgICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgaXNFZGdlUG9pbnQ6IGZ1bmN0aW9uIChjb250YWluZXIsIG9mZnNldCkge1xyXG4gICAgICAgICAgICByZXR1cm4gKG9mZnNldCA9PT0gMCkgfHwgKCFjb250YWluZXIubm9kZVZhbHVlICYmIG9mZnNldCA9PT0gMSkgfHwgKG9mZnNldCA9PT0gY29udGFpbmVyLm5vZGVWYWx1ZS5sZW5ndGgpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBTaG93IGxvYWRpbmcgYm94XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgc2hvd0xvYWRpbmc6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LmxvYWRpbmcuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIENsb3NlIGxvYWRpbmcgYm94XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgY2xvc2VMb2FkaW5nOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5sb2FkaW5nLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEFwcGVuZCBmb3JtYXQgZWxlbWVudCB0byBzaWJsaW5nIG5vZGUgb2YgYXJndW1lbnQgZWxlbWVudC5cclxuICAgICAgICAgKiBJZiB0aGUgXCJmb3JtYXROb2RlTmFtZVwiIGFyZ3VtZW50IHZhbHVlIGlzIHByZXNlbnQsIHRoZSB0YWcgb2YgdGhhdCBhcmd1bWVudCB2YWx1ZSBpcyBpbnNlcnRlZCxcclxuICAgICAgICAgKiBJZiBub3QsIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgZm9ybWF0IHRhZyBpcyBpbnNlcnRlZC5cclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgSW5zZXJ0IGFzIHNpYmxpbmdzIG9mIHRoYXQgZWxlbWVudFxyXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfEVsZW1lbnR8bnVsbH0gZm9ybWF0Tm9kZSBOb2RlIG5hbWUgb3Igbm9kZSBvYmVqY3QgdG8gYmUgaW5zZXJ0ZWRcclxuICAgICAgICAgKiBAcmV0dXJucyB7RWxlbWVudH1cclxuICAgICAgICAgKi9cclxuICAgICAgICBhcHBlbmRGb3JtYXRUYWc6IGZ1bmN0aW9uIChlbGVtZW50LCBmb3JtYXROb2RlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRGb3JtYXRFbCA9IHV0aWwuZ2V0Rm9ybWF0RWxlbWVudCh0aGlzLmdldFNlbGVjdGlvbk5vZGUoKSwgbnVsbCk7XHJcbiAgICAgICAgICAgIGNvbnN0IG9Gb3JtYXROYW1lID0gZm9ybWF0Tm9kZSA/ICh0eXBlb2YgZm9ybWF0Tm9kZSA9PT0gJ3N0cmluZycgPyBmb3JtYXROb2RlIDogZm9ybWF0Tm9kZS5ub2RlTmFtZSkgOiAodXRpbC5pc0Zvcm1hdEVsZW1lbnQoY3VycmVudEZvcm1hdEVsKSAmJiAhdXRpbC5pc0ZyZWVGb3JtYXRFbGVtZW50KGN1cnJlbnRGb3JtYXRFbCkpID8gY3VycmVudEZvcm1hdEVsLm5vZGVOYW1lIDogb3B0aW9ucy5kZWZhdWx0VGFnO1xyXG4gICAgICAgICAgICBjb25zdCBvRm9ybWF0ID0gdXRpbC5jcmVhdGVFbGVtZW50KG9Gb3JtYXROYW1lKTtcclxuICAgICAgICAgICAgb0Zvcm1hdC5pbm5lckhUTUwgPSAnPGJyPic7XHJcblxyXG4gICAgICAgICAgICBpZiAoKGZvcm1hdE5vZGUgJiYgdHlwZW9mIGZvcm1hdE5vZGUgIT09ICdzdHJpbmcnKSB8fCAoIWZvcm1hdE5vZGUgJiYgdXRpbC5pc0Zvcm1hdEVsZW1lbnQoY3VycmVudEZvcm1hdEVsKSkpIHtcclxuICAgICAgICAgICAgICAgIHV0aWwuY29weVRhZ0F0dHJpYnV0ZXMob0Zvcm1hdCwgZm9ybWF0Tm9kZSB8fCBjdXJyZW50Rm9ybWF0RWwpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodXRpbC5pc0NlbGwoZWxlbWVudCkpIGVsZW1lbnQuaW5zZXJ0QmVmb3JlKG9Gb3JtYXQsIGVsZW1lbnQubmV4dEVsZW1lbnRTaWJsaW5nKTtcclxuICAgICAgICAgICAgZWxzZSBlbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG9Gb3JtYXQsIGVsZW1lbnQubmV4dEVsZW1lbnRTaWJsaW5nKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBvRm9ybWF0O1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBUaGUgbWV0aG9kIHRvIGluc2VydCBhIGVsZW1lbnQgYW5kIHJldHVybi4gKHVzZWQgZWxlbWVudHMgOiB0YWJsZSwgaHIsIGltYWdlLCB2aWRlbylcclxuICAgICAgICAgKiBJZiBcImVsZW1lbnRcIiBpcyBcIkhSXCIsIGluc2VydCBhbmQgcmV0dXJuIHRoZSBuZXcgbGluZS5cclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgRWxlbWVudCB0byBiZSBpbnNlcnRlZFxyXG4gICAgICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gbm90SGlzdG9yeVB1c2ggV2hlbiB0cnVlLCBpdCBkb2VzIG5vdCB1cGRhdGUgdGhlIGhpc3Rvcnkgc3RhY2sgYW5kIHRoZSBzZWxlY3Rpb24gb2JqZWN0IGFuZCByZXR1cm4gRWRnZU5vZGVzICh1dGlsLmdldEVkZ2VDaGlsZE5vZGVzKVxyXG4gICAgICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gY2hlY2tDaGFyQ291bnQgSWYgdHJ1ZSwgaWYgXCJvcHRpb25zLm1heENoYXJDb3VudFwiIGlzIGV4Y2VlZGVkIHdoZW4gXCJlbGVtZW50XCIgaXMgYWRkZWQsIG51bGwgaXMgcmV0dXJuZWQgd2l0aG91dCBhZGRpdGlvbi5cclxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IG5vdFNlbGVjdCBJZiB0cnVlLCBEbyBub3QgYXV0b21hdGljYWxseSBzZWxlY3QgdGhlIGluc2VydGVkIGNvbXBvbmVudC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RWxlbWVudH1cclxuICAgICAgICAgKi9cclxuICAgICAgICBpbnNlcnRDb21wb25lbnQ6IGZ1bmN0aW9uIChlbGVtZW50LCBub3RIaXN0b3J5UHVzaCwgY2hlY2tDaGFyQ291bnQsIG5vdFNlbGVjdCkge1xyXG4gICAgICAgICAgICBpZiAoY2hlY2tDaGFyQ291bnQgJiYgIXRoaXMuY2hlY2tDaGFyQ291bnQoZWxlbWVudCwgbnVsbCkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCByID0gdGhpcy5yZW1vdmVOb2RlKCk7XHJcbiAgICAgICAgICAgIHRoaXMuZ2V0UmFuZ2VfYWRkTGluZSh0aGlzLmdldFJhbmdlKCksIHIuY29udGFpbmVyKTtcclxuICAgICAgICAgICAgbGV0IG9Ob2RlID0gbnVsbDtcclxuICAgICAgICAgICAgbGV0IHNlbGVjdGlvbk5vZGUgPSB0aGlzLmdldFNlbGVjdGlvbk5vZGUoKTtcclxuICAgICAgICAgICAgbGV0IGZvcm1hdEVsID0gdXRpbC5nZXRGb3JtYXRFbGVtZW50KHNlbGVjdGlvbk5vZGUsIG51bGwpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHV0aWwuaXNMaXN0Q2VsbChmb3JtYXRFbCkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0Tm9kZShlbGVtZW50LCBzZWxlY3Rpb25Ob2RlID09PSBmb3JtYXRFbCA/IG51bGwgOiByLmNvbnRhaW5lci5uZXh0U2libGluZywgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFlbGVtZW50Lm5leHRTaWJsaW5nKSBlbGVtZW50LnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQodXRpbC5jcmVhdGVFbGVtZW50KCdCUicpKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmdldFJhbmdlKCkuY29sbGFwc2VkICYmIChyLmNvbnRhaW5lci5ub2RlVHlwZSA9PT0gMyB8fCB1dGlsLmlzQnJlYWsoci5jb250YWluZXIpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRlcHRoRm9ybWF0ID0gdXRpbC5nZXRQYXJlbnRFbGVtZW50KHIuY29udGFpbmVyLCBmdW5jdGlvbiAoY3VycmVudCkgeyByZXR1cm4gdGhpcy5pc1JhbmdlRm9ybWF0RWxlbWVudChjdXJyZW50KTsgfS5iaW5kKHV0aWwpKTtcclxuICAgICAgICAgICAgICAgICAgICBvTm9kZSA9IHV0aWwuc3BsaXRFbGVtZW50KHIuY29udGFpbmVyLCByLm9mZnNldCwgIWRlcHRoRm9ybWF0ID8gMCA6IHV0aWwuZ2V0RWxlbWVudERlcHRoKGRlcHRoRm9ybWF0KSArIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvTm9kZSkgZm9ybWF0RWwgPSBvTm9kZS5wcmV2aW91c1NpYmxpbmc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmluc2VydE5vZGUoZWxlbWVudCwgZm9ybWF0RWwsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIGlmIChmb3JtYXRFbCAmJiB1dGlsLm9ubHlaZXJvV2lkdGhTcGFjZShmb3JtYXRFbCkpIHV0aWwucmVtb3ZlSXRlbShmb3JtYXRFbCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuc2V0UmFuZ2UoZWxlbWVudCwgMCwgZWxlbWVudCwgMCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIW5vdFNlbGVjdCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZUNvbXBvbmVudEluZm8gPSB0aGlzLmdldEZpbGVDb21wb25lbnQoZWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZmlsZUNvbXBvbmVudEluZm8pIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdENvbXBvbmVudChmaWxlQ29tcG9uZW50SW5mby50YXJnZXQsIGZpbGVDb21wb25lbnRJbmZvLnBsdWdpbk5hbWUpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIG9Ob2RlID0gdXRpbC5nZXRFZGdlQ2hpbGROb2RlcyhvTm9kZSwgbnVsbCkuc2MgfHwgb05vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRSYW5nZShvTm9kZSwgMCwgb05vZGUsIDApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBoaXN0b3J5IHN0YWNrXHJcbiAgICAgICAgICAgIGlmICghbm90SGlzdG9yeVB1c2gpIHRoaXMuaGlzdG9yeS5wdXNoKDEpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIG9Ob2RlIHx8IGVsZW1lbnQ7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIGZpbGUgY29tcG9uZW50IGFuZCB0aGF0IHBsdWdpbiBuYW1lXHJcbiAgICAgICAgICogcmV0dXJuOiB7dGFyZ2V0LCBjb21wb25lbnQsIHBsdWdpbk5hbWV9IHwgbnVsbFxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBUYXJnZXQgZWxlbWVudCAoZmlndXJlIHRhZywgY29tcG9uZW50IGRpdiwgZmlsZSB0YWcpXHJcbiAgICAgICAgICogQHJldHVybnMge09iamVjdHxudWxsfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldEZpbGVDb21wb25lbnQ6IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5fZmlsZU1hbmFnZXIucXVlcnlTdHJpbmcgfHwgIWVsZW1lbnQpIHJldHVybiBudWxsO1xyXG5cclxuICAgICAgICAgICAgbGV0IHRhcmdldCwgcGx1Z2luTmFtZTtcclxuICAgICAgICAgICAgaWYgKC9eRklHVVJFJC9pLnRlc3QoZWxlbWVudC5ub2RlTmFtZSkgfHwgL3NlLWNvbXBvbmVudC8udGVzdChlbGVtZW50LmNsYXNzTmFtZSkpIHtcclxuICAgICAgICAgICAgICAgIHRhcmdldCA9IGVsZW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLl9maWxlTWFuYWdlci5xdWVyeVN0cmluZyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCF0YXJnZXQgJiYgZWxlbWVudC5ub2RlTmFtZSAmJiB0aGlzLl9maWxlTWFuYWdlci5yZWdFeHAudGVzdChlbGVtZW50Lm5vZGVOYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgdGFyZ2V0ID0gZWxlbWVudDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHRhcmdldCkge1xyXG4gICAgICAgICAgICAgICAgcGx1Z2luTmFtZSA9IHRoaXMuX2ZpbGVNYW5hZ2VyLnBsdWdpbk1hcFt0YXJnZXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKV07XHJcbiAgICAgICAgICAgICAgICBpZiAocGx1Z2luTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldDogdGFyZ2V0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQ6IHV0aWwuZ2V0UGFyZW50RWxlbWVudCh0YXJnZXQsIHV0aWwuaXNDb21wb25lbnQpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwbHVnaW5OYW1lOiBwbHVnaW5OYW1lXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFRoZSBjb21wb25lbnQoaW1hZ2UsIHZpZGVvKSBpcyBzZWxlY3RlZCBhbmQgdGhlIHJlc2l6aW5nIG1vZHVsZSBpcyBjYWxsZWQuXHJcbiAgICAgICAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IEVsZW1lbnQgdGFnIChpbWcsIGlmcmFtZSwgdmlkZW8pXHJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHBsdWdpbk5hbWUgUGx1Z2luIG5hbWUgKGltYWdlLCB2aWRlbylcclxuICAgICAgICAgKi9cclxuICAgICAgICBzZWxlY3RDb21wb25lbnQ6IGZ1bmN0aW9uIChlbGVtZW50LCBwbHVnaW5OYW1lKSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5oYXNGb2N1cykgdGhpcy5mb2N1cygpO1xyXG4gICAgICAgICAgICBjb25zdCBwbHVnaW4gPSB0aGlzLnBsdWdpbnNbcGx1Z2luTmFtZV07XHJcbiAgICAgICAgICAgIGlmICghcGx1Z2luKSByZXR1cm47XHJcbiAgICAgICAgICAgIF93LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwbHVnaW4uc2VsZWN0ID09PSAnZnVuY3Rpb24nKSB0aGlzLmNhbGxQbHVnaW4ocGx1Z2luTmFtZSwgcGx1Z2luLnNlbGVjdC5iaW5kKHRoaXMsIGVsZW1lbnQpLCBudWxsKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3NldENvbXBvbmVudExpbmVCcmVha2VyKGVsZW1lbnQpO1xyXG4gICAgICAgICAgICB9LmJpbmQodGhpcykpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBTZXQgbGluZSBicmVha2VyIG9mIGNvbXBvbmVudFxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBFbGVtZW50IHRhZyAoaW1nLCBpZnJhbWUsIHZpZGVvKVxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX3NldENvbXBvbmVudExpbmVCcmVha2VyOiBmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICAvLyBsaW5lIGJyZWFrZXJcclxuICAgICAgICAgICAgdGhpcy5fbGluZUJyZWFrZXIuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgY29uc3QgY29udGFpbmVyID0gdXRpbC5nZXRQYXJlbnRFbGVtZW50KGVsZW1lbnQsIHV0aWwuaXNDb21wb25lbnQpO1xyXG4gICAgICAgICAgICBjb25zdCB0X3N0eWxlID0gY29udGV4dC5lbGVtZW50LmxpbmVCcmVha2VyX3Quc3R5bGU7XHJcbiAgICAgICAgICAgIGNvbnN0IGJfc3R5bGUgPSBjb250ZXh0LmVsZW1lbnQubGluZUJyZWFrZXJfYi5zdHlsZTtcclxuICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5jb250ZXh0LnJlc2l6aW5nLnJlc2l6ZUNvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID09PSAnYmxvY2snID8gdGhpcy5jb250ZXh0LnJlc2l6aW5nLnJlc2l6ZUNvbnRhaW5lciA6IGVsZW1lbnQ7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBpc0xpc3QgPSB1dGlsLmlzTGlzdENlbGwoY29udGFpbmVyLnBhcmVudE5vZGUpO1xyXG4gICAgICAgICAgICBsZXQgY29tcG9uZW50VG9wLCB3U2Nyb2xsLCB3O1xyXG4gICAgICAgICAgICAvLyB0b3BcclxuICAgICAgICAgICAgaWYgKGlzTGlzdCA/ICFjb250YWluZXIucHJldmlvdXNTaWJsaW5nIDogIXV0aWwuaXNGb3JtYXRFbGVtZW50KGNvbnRhaW5lci5wcmV2aW91c0VsZW1lbnRTaWJsaW5nKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdmFyaWFibGUuX2xpbmVCcmVha0NvbXAgPSBjb250YWluZXI7XHJcbiAgICAgICAgICAgICAgICB3U2Nyb2xsID0gY29udGV4dC5lbGVtZW50Lnd5c2l3eWcuc2Nyb2xsVG9wO1xyXG4gICAgICAgICAgICAgICAgY29tcG9uZW50VG9wID0gdXRpbC5nZXRPZmZzZXQoZWxlbWVudCwgY29udGV4dC5lbGVtZW50Lnd5c2l3eWdGcmFtZSkudG9wICsgd1Njcm9sbDtcclxuICAgICAgICAgICAgICAgIHcgPSAodGFyZ2V0Lm9mZnNldFdpZHRoIC8gMikgLyAyO1xyXG5cclxuICAgICAgICAgICAgICAgIHRfc3R5bGUudG9wID0gKGNvbXBvbmVudFRvcCAtIHdTY3JvbGwgLSAxMikgKyAncHgnO1xyXG4gICAgICAgICAgICAgICAgdF9zdHlsZS5sZWZ0ID0gKHV0aWwuZ2V0T2Zmc2V0KHRhcmdldCkubGVmdCArIHcpICsgJ3B4JztcclxuICAgICAgICAgICAgICAgIHRfc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0X3N0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gYm90dG9tXHJcbiAgICAgICAgICAgIGlmIChpc0xpc3QgPyAhY29udGFpbmVyLm5leHRTaWJsaW5nIDogIXV0aWwuaXNGb3JtYXRFbGVtZW50KGNvbnRhaW5lci5uZXh0RWxlbWVudFNpYmxpbmcpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWNvbXBvbmVudFRvcCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhcmlhYmxlLl9saW5lQnJlYWtDb21wID0gY29udGFpbmVyO1xyXG4gICAgICAgICAgICAgICAgICAgIHdTY3JvbGwgPSBjb250ZXh0LmVsZW1lbnQud3lzaXd5Zy5zY3JvbGxUb3A7XHJcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50VG9wID0gdXRpbC5nZXRPZmZzZXQoZWxlbWVudCwgY29udGV4dC5lbGVtZW50Lnd5c2l3eWdGcmFtZSkudG9wICsgd1Njcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICB3ID0gKHRhcmdldC5vZmZzZXRXaWR0aCAvIDIpIC8gMjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBiX3N0eWxlLnRvcCA9IChjb21wb25lbnRUb3AgKyB0YXJnZXQub2Zmc2V0SGVpZ2h0IC0gd1Njcm9sbCAtIDEyKSArICdweCc7XHJcbiAgICAgICAgICAgICAgICBiX3N0eWxlLmxlZnQgPSAodXRpbC5nZXRPZmZzZXQodGFyZ2V0KS5sZWZ0ICsgdGFyZ2V0Lm9mZnNldFdpZHRoIC0gdyAtIDI0KSArICdweCc7XHJcbiAgICAgICAgICAgICAgICBiX3N0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYl9zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIERlbGV0ZSBzZWxlY3RlZCBub2RlIGFuZCBpbnNlcnQgYXJndW1lbnQgdmFsdWUgbm9kZSBhbmQgcmV0dXJuLlxyXG4gICAgICAgICAqIElmIHRoZSBcImFmdGVyTm9kZVwiIGV4aXN0cywgaXQgaXMgaW5zZXJ0ZWQgYWZ0ZXIgdGhlIFwiYWZ0ZXJOb2RlXCJcclxuICAgICAgICAgKiBJbnNlcnRpbmcgYSB0ZXh0IG5vZGUgbWVyZ2VzIHdpdGggYm90aCB0ZXh0IG5vZGVzIG9uIGJvdGggc2lkZXMgYW5kIHJldHVybnMgYSBuZXcgXCJ7IGNvbnRhaW5lciwgc3RhcnRPZmZzZXQsIGVuZE9mZnNldCB9XCIuXHJcbiAgICAgICAgICogQHBhcmFtIHtOb2RlfSBvTm9kZSBFbGVtZW50IHRvIGJlIGluc2VydGVkXHJcbiAgICAgICAgICogQHBhcmFtIHtOb2RlfG51bGx9IGFmdGVyTm9kZSBJZiB0aGUgbm9kZSBleGlzdHMsIGl0IGlzIGluc2VydGVkIGFmdGVyIHRoZSBub2RlXHJcbiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSBjaGVja0NoYXJDb3VudCBJZiB0cnVlLCBpZiBcIm9wdGlvbnMubWF4Q2hhckNvdW50XCIgaXMgZXhjZWVkZWQgd2hlbiBcImVsZW1lbnRcIiBpcyBhZGRlZCwgbnVsbCBpcyByZXR1cm5lZCB3aXRob3V0IGFkZGl0aW9uLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3R8Tm9kZXxudWxsfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGluc2VydE5vZGU6IGZ1bmN0aW9uIChvTm9kZSwgYWZ0ZXJOb2RlLCBjaGVja0NoYXJDb3VudCkge1xyXG4gICAgICAgICAgICBpZiAoY2hlY2tDaGFyQ291bnQgJiYgIXRoaXMuY2hlY2tDaGFyQ291bnQob05vZGUsIG51bGwpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgZnJlZUZvcm1hdCA9IHV0aWwuZ2V0RnJlZUZvcm1hdEVsZW1lbnQodGhpcy5nZXRTZWxlY3Rpb25Ob2RlKCksIG51bGwpO1xyXG4gICAgICAgICAgICBjb25zdCBpc0Zvcm1hdHMgPSAoIWZyZWVGb3JtYXQgJiYgKHV0aWwuaXNGb3JtYXRFbGVtZW50KG9Ob2RlKSB8fCB1dGlsLmlzUmFuZ2VGb3JtYXRFbGVtZW50KG9Ob2RlKSkpIHx8IHV0aWwuaXNDb21wb25lbnQob05vZGUpO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFhZnRlck5vZGUgJiYgaXNGb3JtYXRzKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByYW5nZSA9IHRoaXMuZ2V0UmFuZ2UoKTtcclxuICAgICAgICAgICAgICAgIGlmIChyYW5nZS5zdGFydE9mZnNldCAhPT0gcmFuZ2UuZW5kT2Zmc2V0IHx8IHJhbmdlLnN0YXJ0Q29udGFpbmVyICE9PSByYW5nZS5lbmRDb250YWluZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCByID0gdGhpcy5yZW1vdmVOb2RlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHIuY29udGFpbmVyLm5vZGVUeXBlID09PSAzIHx8IHV0aWwuaXNCcmVhayhyLmNvbnRhaW5lcikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVwdGhGb3JtYXQgPSB1dGlsLmdldFBhcmVudEVsZW1lbnQoci5jb250YWluZXIsIGZ1bmN0aW9uIChjdXJyZW50KSB7IHJldHVybiB0aGlzLmlzUmFuZ2VGb3JtYXRFbGVtZW50KGN1cnJlbnQpIHx8IHRoaXMuaXNMaXN0Q2VsbChjdXJyZW50KTsgfS5iaW5kKHV0aWwpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXJOb2RlID0gdXRpbC5zcGxpdEVsZW1lbnQoci5jb250YWluZXIsIHIub2Zmc2V0LCAhZGVwdGhGb3JtYXQgPyAwIDogdXRpbC5nZXRFbGVtZW50RGVwdGgoZGVwdGhGb3JtYXQpICsgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhZnRlck5vZGUpIGFmdGVyTm9kZSA9IGFmdGVyTm9kZS5wcmV2aW91c1NpYmxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCByYW5nZSA9ICghYWZ0ZXJOb2RlICYmICFpc0Zvcm1hdHMpID8gdGhpcy5nZXRSYW5nZV9hZGRMaW5lKHRoaXMuZ2V0UmFuZ2UoKSwgbnVsbCkgOiB0aGlzLmdldFJhbmdlKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvbW1vbkNvbiA9IHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyO1xyXG4gICAgICAgICAgICBjb25zdCBzdGFydE9mZiA9IHJhbmdlLnN0YXJ0T2Zmc2V0O1xyXG4gICAgICAgICAgICBjb25zdCBlbmRPZmYgPSByYW5nZS5lbmRPZmZzZXQ7XHJcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdFJhbmdlID0gcmFuZ2Uuc3RhcnRDb250YWluZXIgPT09IGNvbW1vbkNvbiAmJiB1dGlsLmlzRm9ybWF0RWxlbWVudChjb21tb25Db24pO1xyXG4gICAgICAgICAgICBjb25zdCBzdGFydENvbiA9IGZvcm1hdFJhbmdlID8gY29tbW9uQ29uLmNoaWxkTm9kZXNbc3RhcnRPZmZdIDogcmFuZ2Uuc3RhcnRDb250YWluZXI7XHJcbiAgICAgICAgICAgIGNvbnN0IGVuZENvbiA9IGZvcm1hdFJhbmdlID8gY29tbW9uQ29uLmNoaWxkTm9kZXNbZW5kT2ZmXSA6IHJhbmdlLmVuZENvbnRhaW5lcjtcclxuICAgICAgICAgICAgbGV0IHBhcmVudE5vZGUsIG9yaWdpbkFmdGVyID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgIGlmICghYWZ0ZXJOb2RlKSB7XHJcbiAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gc3RhcnRDb247XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RhcnRDb24ubm9kZVR5cGUgPT09IDMpIHtcclxuICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gc3RhcnRDb24ucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKiogTm8gU2VsZWN0IHJhbmdlIG5vZGUgKi9cclxuICAgICAgICAgICAgICAgIGlmIChyYW5nZS5jb2xsYXBzZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY29tbW9uQ29uLm5vZGVUeXBlID09PSAzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb21tb25Db24udGV4dENvbnRlbnQubGVuZ3RoID4gZW5kT2ZmKSBhZnRlck5vZGUgPSBjb21tb25Db24uc3BsaXRUZXh0KGVuZE9mZik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgYWZ0ZXJOb2RlID0gY29tbW9uQ29uLm5leHRTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdXRpbC5pc0JyZWFrKHBhcmVudE5vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgYyA9IHBhcmVudE5vZGUuY2hpbGROb2Rlc1tzdGFydE9mZl07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmb2N1c05vZGUgPSAoYyAmJiBjLm5vZGVUeXBlID09PSAzICYmIHV0aWwub25seVplcm9XaWR0aFNwYWNlKGMpICYmIHV0aWwuaXNCcmVhayhjLm5leHRTaWJsaW5nKSkgPyBjLm5leHRTaWJsaW5nIDogYztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb2N1c05vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZvY3VzTm9kZS5uZXh0U2libGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlLnJlbW92ZUNoaWxkKGZvY3VzTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFmdGVyTm9kZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXJOb2RlID0gKHV0aWwuaXNCcmVhayhmb2N1c05vZGUpICYmICF1dGlsLmlzQnJlYWsob05vZGUpKSA/IGZvY3VzTm9kZSA6IGZvY3VzTm9kZS5uZXh0U2libGluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFmdGVyTm9kZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZnRlck5vZGUgPSBwYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZSA9IHBhcmVudE5vZGUucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8qKiBTZWxlY3QgcmFuZ2Ugbm9kZXMgKi9cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpc1NhbWVDb250YWluZXIgPSBzdGFydENvbiA9PT0gZW5kQ29uO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNTYW1lQ29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzRWRnZVBvaW50KGVuZENvbiwgZW5kT2ZmKSkgYWZ0ZXJOb2RlID0gZW5kQ29uLm5leHRTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGFmdGVyTm9kZSA9IGVuZENvbi5zcGxpdFRleHQoZW5kT2ZmKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCByZW1vdmVOb2RlID0gc3RhcnRDb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc0VkZ2VQb2ludChzdGFydENvbiwgc3RhcnRPZmYpKSByZW1vdmVOb2RlID0gc3RhcnRDb24uc3BsaXRUZXh0KHN0YXJ0T2ZmKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE5vZGUucmVtb3ZlQ2hpbGQocmVtb3ZlTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnROb2RlLmNoaWxkTm9kZXMubGVuZ3RoID09PSAwICYmIGlzRm9ybWF0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZS5pbm5lckhUTUwgPSAnPGJyPic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbW92ZWRUYWcgPSB0aGlzLnJlbW92ZU5vZGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29udGFpbmVyID0gcmVtb3ZlZFRhZy5jb250YWluZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZXZDb250YWluZXIgPSByZW1vdmVkVGFnLnByZXZDb250YWluZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250YWluZXIgJiYgY29udGFpbmVyLmNoaWxkTm9kZXMubGVuZ3RoID09PSAwICYmIGlzRm9ybWF0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHV0aWwuaXNGb3JtYXRFbGVtZW50KGNvbnRhaW5lcikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gJzxicj4nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh1dGlsLmlzUmFuZ2VGb3JtYXRFbGVtZW50KGNvbnRhaW5lcikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gJzwnICsgb3B0aW9ucy5kZWZhdWx0VGFnICsgJz48YnI+PC8nICsgb3B0aW9ucy5kZWZhdWx0VGFnICsgJz4nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzRm9ybWF0cyAmJiBwcmV2Q29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gcHJldkNvbnRhaW5lci5ub2RlVHlwZSA9PT0gMyA/IHByZXZDb250YWluZXIucGFyZW50Tm9kZSA6IHByZXZDb250YWluZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50Tm9kZS5jb250YWlucyhjb250YWluZXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXJOb2RlID0gY29udGFpbmVyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChhZnRlck5vZGUucGFyZW50Tm9kZSA9PT0gcGFyZW50Tm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZnRlck5vZGUgPSBhZnRlck5vZGUucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFmdGVyTm9kZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gaXNGb3JtYXRzID8gY29tbW9uQ29uIDogY29udGFpbmVyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXJOb2RlID0gaXNGb3JtYXRzID8gZW5kQ29uIDogbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGFmdGVyTm9kZSAmJiAhdXRpbC5pc0Zvcm1hdEVsZW1lbnQoYWZ0ZXJOb2RlKSAmJiBhZnRlck5vZGUucGFyZW50Tm9kZSAhPT0gY29tbW9uQ29uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZnRlck5vZGUgPSBhZnRlck5vZGUucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBoYXMgYWZ0ZXJOb2RlXHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcGFyZW50Tm9kZSA9IGFmdGVyTm9kZS5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgYWZ0ZXJOb2RlID0gYWZ0ZXJOb2RlLm5leHRTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgb3JpZ2luQWZ0ZXIgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyAtLS0gaW5zZXJ0IG5vZGUgLS0tXHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodXRpbC5pc0Zvcm1hdEVsZW1lbnQob05vZGUpIHx8IHV0aWwuaXNSYW5nZUZvcm1hdEVsZW1lbnQob05vZGUpIHx8ICghdXRpbC5pc0xpc3RDZWxsKHBhcmVudE5vZGUpICYmIHV0aWwuaXNDb21wb25lbnQob05vZGUpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9sZFBhcmVudCA9IHBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHV0aWwuaXNMaXN0KGFmdGVyTm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZSA9IGFmdGVyTm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXJOb2RlID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHV0aWwuaXNMaXN0Q2VsbChhZnRlck5vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE5vZGUgPSBhZnRlck5vZGUucHJldmlvdXNFbGVtZW50U2libGluZyB8fCBhZnRlck5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghb3JpZ2luQWZ0ZXIgJiYgIWFmdGVyTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByID0gdGhpcy5yZW1vdmVOb2RlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHIuY29udGFpbmVyLm5vZGVUeXBlID09PSAzID8gKHV0aWwuaXNMaXN0Q2VsbCh1dGlsLmdldEZvcm1hdEVsZW1lbnQoci5jb250YWluZXIsIG51bGwpKSA/IHIuY29udGFpbmVyIDogKHV0aWwuZ2V0Rm9ybWF0RWxlbWVudChyLmNvbnRhaW5lciwgbnVsbCkgfHwgci5jb250YWluZXIucGFyZW50Tm9kZSkpIDogci5jb250YWluZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJhbmdlQ29uID0gdXRpbC5pc1d5c2l3eWdEaXYoY29udGFpbmVyKSB8fCB1dGlsLmlzUmFuZ2VGb3JtYXRFbGVtZW50KGNvbnRhaW5lcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE5vZGUgPSByYW5nZUNvbiA/IGNvbnRhaW5lciA6IGNvbnRhaW5lci5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZnRlck5vZGUgPSByYW5nZUNvbiA/IG51bGwgOiBjb250YWluZXIubmV4dFNpYmxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAob2xkUGFyZW50LmNoaWxkTm9kZXMubGVuZ3RoID09PSAwICYmIHBhcmVudE5vZGUgIT09IG9sZFBhcmVudCkgdXRpbC5yZW1vdmVJdGVtKG9sZFBhcmVudCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGlzRm9ybWF0cyAmJiAhZnJlZUZvcm1hdCAmJiAhdXRpbC5pc1JhbmdlRm9ybWF0RWxlbWVudChwYXJlbnROb2RlKSAmJiAhdXRpbC5pc0xpc3RDZWxsKHBhcmVudE5vZGUpICYmICF1dGlsLmlzV3lzaXd5Z0RpdihwYXJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGFmdGVyTm9kZSA9IHBhcmVudE5vZGUubmV4dEVsZW1lbnRTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudE5vZGUgPSBwYXJlbnROb2RlLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBwYXJlbnROb2RlLmluc2VydEJlZm9yZShvTm9kZSwgcGFyZW50Tm9kZSA9PT0gYWZ0ZXJOb2RlID8gcGFyZW50Tm9kZS5sYXN0Q2hpbGQgOiBhZnRlck5vZGUpO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBwYXJlbnROb2RlLmFwcGVuZENoaWxkKG9Ob2RlKTtcclxuICAgICAgICAgICAgfSBmaW5hbGx5IHtcclxuICAgICAgICAgICAgICAgIGlmIChmcmVlRm9ybWF0ICYmICh1dGlsLmlzRm9ybWF0RWxlbWVudChvTm9kZSkgfHwgdXRpbC5pc1JhbmdlRm9ybWF0RWxlbWVudChvTm9kZSkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb05vZGUgPSB0aGlzLl9zZXRJbnRvRnJlZUZvcm1hdChvTm9kZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCF1dGlsLmlzQ29tcG9uZW50KG9Ob2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBvZmZzZXQgPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvTm9kZS5ub2RlVHlwZSA9PT0gMykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmV2aW91cyA9IG9Ob2RlLnByZXZpb3VzU2libGluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV4dCA9IG9Ob2RlLm5leHRTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmV2aW91c1RleHQgPSAoIXByZXZpb3VzIHx8ICBwcmV2aW91cy5ub2RlVHlwZSA9PT0gMSB8fCB1dGlsLm9ubHlaZXJvV2lkdGhTcGFjZShwcmV2aW91cykpID8gJycgOiBwcmV2aW91cy50ZXh0Q29udGVudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV4dFRleHQgPSAoIW5leHQgfHwgbmV4dC5ub2RlVHlwZSA9PT0gMSB8fCB1dGlsLm9ubHlaZXJvV2lkdGhTcGFjZShuZXh0KSkgPyAnJyA6IG5leHQudGV4dENvbnRlbnQ7XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmV2aW91cyAmJiBwcmV2aW91c1RleHQubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb05vZGUudGV4dENvbnRlbnQgPSBwcmV2aW91c1RleHQgKyBvTm9kZS50ZXh0Q29udGVudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlSXRlbShwcmV2aW91cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQgJiYgbmV4dC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvTm9kZS50ZXh0Q29udGVudCArPSBuZXh0VGV4dDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlSXRlbShuZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3UmFuZ2UgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXI6IG9Ob2RlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRPZmZzZXQ6IHByZXZpb3VzVGV4dC5sZW5ndGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRPZmZzZXQ6IG9Ob2RlLnRleHRDb250ZW50Lmxlbmd0aCAtIG5leHRUZXh0Lmxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRSYW5nZShvTm9kZSwgbmV3UmFuZ2Uuc3RhcnRPZmZzZXQsIG9Ob2RlLCBuZXdSYW5nZS5lbmRPZmZzZXQpO1xyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXdSYW5nZTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCF1dGlsLmlzQnJlYWsob05vZGUpICYmIHV0aWwuaXNGb3JtYXRFbGVtZW50KHBhcmVudE5vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCB6ZXJvV2lkdGggPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW9Ob2RlLnByZXZpb3VzU2libGluZyB8fCB1dGlsLmlzQnJlYWsob05vZGUucHJldmlvdXNTaWJsaW5nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgemVyb1dpZHRoID0gdXRpbC5jcmVhdGVUZXh0Tm9kZSh1dGlsLnplcm9XaWR0aFNwYWNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9Ob2RlLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHplcm9XaWR0aCwgb05vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW9Ob2RlLm5leHRTaWJsaW5nIHx8IHV0aWwuaXNCcmVhayhvTm9kZS5uZXh0U2libGluZykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHplcm9XaWR0aCA9IHV0aWwuY3JlYXRlVGV4dE5vZGUodXRpbC56ZXJvV2lkdGhTcGFjZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvTm9kZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh6ZXJvV2lkdGgsIG9Ob2RlLm5leHRTaWJsaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1dGlsLl9pc0lnbm9yZU5vZGVDaGFuZ2Uob05vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvTm9kZSA9IG9Ob2RlLm5leHRTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0UmFuZ2Uob05vZGUsIG9mZnNldCwgb05vZGUsIG9mZnNldCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gaGlzdG9yeSBzdGFja1xyXG4gICAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnB1c2godHJ1ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9Ob2RlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX3NldEludG9GcmVlRm9ybWF0OiBmdW5jdGlvbiAob05vZGUpIHtcclxuICAgICAgICAgICAgY29uc3QgcGFyZW50Tm9kZSA9IG9Ob2RlLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgIGxldCBvTm9kZUNoaWxkcmVuLCBsYXN0T05vZGU7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICB3aGlsZSAodXRpbC5pc0Zvcm1hdEVsZW1lbnQob05vZGUpIHx8IHV0aWwuaXNSYW5nZUZvcm1hdEVsZW1lbnQob05vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICBvTm9kZUNoaWxkcmVuID0gb05vZGUuY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgIGxhc3RPTm9kZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIHdoaWxlIChvTm9kZUNoaWxkcmVuWzBdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGFzdE9Ob2RlID0gb05vZGVDaGlsZHJlblswXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5pc0Zvcm1hdEVsZW1lbnQobGFzdE9Ob2RlKSB8fCB1dGlsLmlzUmFuZ2VGb3JtYXRFbGVtZW50KGxhc3RPTm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2V0SW50b0ZyZWVGb3JtYXQobGFzdE9Ob2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFvTm9kZS5wYXJlbnROb2RlKSBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgb05vZGVDaGlsZHJlbiA9IG9Ob2RlLmNoaWxkTm9kZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlLmluc2VydEJlZm9yZShsYXN0T05vZGUsIG9Ob2RlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgaWYgKG9Ob2RlLmNoaWxkTm9kZXMubGVuZ3RoID09PSAwKSB1dGlsLnJlbW92ZUl0ZW0ob05vZGUpO1xyXG4gICAgICAgICAgICAgICAgb05vZGUgPSB1dGlsLmNyZWF0ZUVsZW1lbnQoJ0JSJyk7XHJcbiAgICAgICAgICAgICAgICBwYXJlbnROb2RlLmluc2VydEJlZm9yZShvTm9kZSwgbGFzdE9Ob2RlLm5leHRTaWJsaW5nKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIG9Ob2RlO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBEZWxldGUgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBub2RlcyBhbmQgcmVzZXQgc2VsZWN0aW9uIHJhbmdlXHJcbiAgICAgICAgICogUmV0dXJucyB7Y29udGFpbmVyOiBcInRoZSBsYXN0IGVsZW1lbnQgYWZ0ZXIgZGVsZXRpb25cIiwgb2Zmc2V0OiBcIm9mZnNldFwiLCBwcmV2Q29udGFpbmVyOiBcInByZXZpb3VzRWxlbWVudFNpYmxpbmcgT2YgdGhlIGRlbGV0ZWQgYXJlYVwifVxyXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3R9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgcmVtb3ZlTm9kZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB0aGlzLl9yZXNldFJhbmdlVG9UZXh0Tm9kZSgpO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSB0aGlzLmdldFJhbmdlKCk7XHJcbiAgICAgICAgICAgIGxldCBjb250YWluZXIsIG9mZnNldCA9IDA7XHJcbiAgICAgICAgICAgIGxldCBzdGFydENvbiA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICBsZXQgZW5kQ29uID0gcmFuZ2UuZW5kQ29udGFpbmVyO1xyXG4gICAgICAgICAgICBjb25zdCBzdGFydE9mZiA9IHJhbmdlLnN0YXJ0T2Zmc2V0O1xyXG4gICAgICAgICAgICBjb25zdCBlbmRPZmYgPSByYW5nZS5lbmRPZmZzZXQ7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvbW1vbkNvbiA9IChyYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lci5ub2RlVHlwZSA9PT0gMyAmJiByYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lci5wYXJlbnROb2RlID09PSBzdGFydENvbi5wYXJlbnROb2RlKSA/IHN0YXJ0Q29uLnBhcmVudE5vZGUgOiByYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lcjtcclxuXHJcbiAgICAgICAgICAgIGxldCBiZWZvcmVOb2RlID0gbnVsbDtcclxuICAgICAgICAgICAgbGV0IGFmdGVyTm9kZSA9IG51bGw7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBjaGlsZE5vZGVzID0gdXRpbC5nZXRMaXN0Q2hpbGROb2Rlcyhjb21tb25Db24sIG51bGwpO1xyXG4gICAgICAgICAgICBsZXQgc3RhcnRJbmRleCA9IHV0aWwuZ2V0QXJyYXlJbmRleChjaGlsZE5vZGVzLCBzdGFydENvbik7XHJcbiAgICAgICAgICAgIGxldCBlbmRJbmRleCA9IHV0aWwuZ2V0QXJyYXlJbmRleChjaGlsZE5vZGVzLCBlbmRDb24pO1xyXG5cclxuICAgICAgICAgICAgaWYgKGNoaWxkTm9kZXMubGVuZ3RoID4gMCAmJiBzdGFydEluZGV4ID4gLTEgJiYgZW5kSW5kZXggPiAtMSkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0SW5kZXggKyAxLCBzdGFydE5vZGUgPSBzdGFydENvbjsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGROb2Rlc1tpXSA9PT0gc3RhcnROb2RlLnBhcmVudE5vZGUgJiYgY2hpbGROb2Rlc1tpXS5maXJzdENoaWxkID09PSBzdGFydE5vZGUgJiYgc3RhcnRPZmYgPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRJbmRleCA9IGk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0Tm9kZSA9IHN0YXJ0Tm9kZS5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgIFxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IGVuZEluZGV4IC0gMSwgZW5kTm9kZSA9IGVuZENvbjsgaSA+IHN0YXJ0SW5kZXg7IGktLSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZE5vZGVzW2ldID09PSBlbmROb2RlLnBhcmVudE5vZGUgJiYgY2hpbGROb2Rlc1tpXS5ub2RlVHlwZSA9PT0gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZE5vZGVzLnNwbGljZShpLCAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZW5kTm9kZSA9IGVuZE5vZGUucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLS1lbmRJbmRleDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGROb2Rlcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5pc0Zvcm1hdEVsZW1lbnQoY29tbW9uQ29uKSB8fCB1dGlsLmlzUmFuZ2VGb3JtYXRFbGVtZW50KGNvbW1vbkNvbikgfHwgdXRpbC5pc1d5c2l3eWdEaXYoY29tbW9uQ29uKSB8fCB1dGlsLmlzQnJlYWsoY29tbW9uQ29uKSB8fCB1dGlsLmlzTWVkaWEoY29tbW9uQ29uKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyOiBjb21tb25Db24sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IDBcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbW1vbkNvbi5ub2RlVHlwZSA9PT0gMykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyOiBjb21tb25Db24sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IGVuZE9mZlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjaGlsZE5vZGVzLnB1c2goY29tbW9uQ29uKTtcclxuICAgICAgICAgICAgICAgICAgICBzdGFydENvbiA9IGVuZENvbiA9IGNvbW1vbkNvbjtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRDb24gPSBlbmRDb24gPSBjaGlsZE5vZGVzWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh1dGlsLmlzQnJlYWsoc3RhcnRDb24pIHx8IHV0aWwub25seVplcm9XaWR0aFNwYWNlKHN0YXJ0Q29uKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyOiB1dGlsLmlzTWVkaWEoY29tbW9uQ29uKSA/IGNvbW1vbkNvbiA6IHN0YXJ0Q29uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiAwXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHN0YXJ0SW5kZXggPSBlbmRJbmRleCA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIHJlbW92ZSAoaXRlbSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZm9ybWF0ID0gdXRpbC5nZXRGb3JtYXRFbGVtZW50KGl0ZW0sIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVJdGVtKGl0ZW0pO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmKHV0aWwuaXNMaXN0Q2VsbChmb3JtYXQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGlzdCA9IHV0aWwuZ2V0QXJyYXlJdGVtKGZvcm1hdC5jaGlsZHJlbiwgdXRpbC5pc0xpc3QsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobGlzdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGlsZCA9IGxpc3QuZmlyc3RFbGVtZW50Q2hpbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkcmVuID0gY2hpbGQuY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNoaWxkcmVuWzBdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQuaW5zZXJ0QmVmb3JlKGNoaWxkcmVuWzBdLCBsaXN0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW1BbGxQYXJlbnRzKGNoaWxkLCBudWxsLCBudWxsKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBzdGFydEluZGV4OyBpIDw9IGVuZEluZGV4OyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSBjaGlsZE5vZGVzW2ldO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChpdGVtLmxlbmd0aCA9PT0gMCB8fCAoaXRlbS5ub2RlVHlwZSA9PT0gMyAmJiBpdGVtLmRhdGEgPT09IHVuZGVmaW5lZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZW1vdmUoaXRlbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGl0ZW0gPT09IHN0YXJ0Q29uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXJ0Q29uLm5vZGVUeXBlID09PSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlZm9yZU5vZGUgPSB1dGlsLmNyZWF0ZVRleHROb2RlKHN0YXJ0Q29uLnRleHRDb250ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbSA9PT0gZW5kQ29uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWZvcmVOb2RlID0gdXRpbC5jcmVhdGVUZXh0Tm9kZShzdGFydENvbi5zdWJzdHJpbmdEYXRhKDAsIHN0YXJ0T2ZmKSArIGVuZENvbi5zdWJzdHJpbmdEYXRhKGVuZE9mZiwgKGVuZENvbi5sZW5ndGggLSBlbmRPZmYpKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBzdGFydE9mZjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZm9yZU5vZGUgPSB1dGlsLmNyZWF0ZVRleHROb2RlKHN0YXJ0Q29uLnN1YnN0cmluZ0RhdGEoMCwgc3RhcnRPZmYpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJlZm9yZU5vZGUubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydENvbi5kYXRhID0gYmVmb3JlTm9kZS5kYXRhO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZShzdGFydENvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbSA9PT0gZW5kQ29uKSBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoaXRlbSA9PT0gZW5kQ29uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVuZENvbi5ub2RlVHlwZSA9PT0gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZnRlck5vZGUgPSB1dGlsLmNyZWF0ZVRleHROb2RlKGVuZENvbi50ZXh0Q29udGVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXJOb2RlID0gdXRpbC5jcmVhdGVUZXh0Tm9kZShlbmRDb24uc3Vic3RyaW5nRGF0YShlbmRPZmYsIChlbmRDb24ubGVuZ3RoIC0gZW5kT2ZmKSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFmdGVyTm9kZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuZENvbi5kYXRhID0gYWZ0ZXJOb2RlLmRhdGE7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKGVuZENvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZW1vdmUoaXRlbSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnRhaW5lciA9IGVuZENvbiAmJiBlbmRDb24ucGFyZW50Tm9kZSA/IGVuZENvbiA6IHN0YXJ0Q29uICYmIHN0YXJ0Q29uLnBhcmVudE5vZGUgPyBzdGFydENvbiA6IChyYW5nZS5lbmRDb250YWluZXIgfHwgcmFuZ2Uuc3RhcnRDb250YWluZXIpO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgaWYgKCF1dGlsLmlzV3lzaXd5Z0Rpdihjb250YWluZXIpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByYyA9IHV0aWwucmVtb3ZlSXRlbUFsbFBhcmVudHMoY29udGFpbmVyLCBmdW5jdGlvbiAoY3VycmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzQ29tcG9uZW50KGN1cnJlbnQpKSByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGV4dCA9IGN1cnJlbnQudGV4dENvbnRlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQubGVuZ3RoID09PSAwIHx8IC9eKFxcbnxcXHUyMDBCKSskLy50ZXN0KHRleHQpO1xyXG4gICAgICAgICAgICAgICAgfS5iaW5kKHV0aWwpLCBudWxsKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgaWYgKHJjKSBjb250YWluZXIgPSByYy5zYyB8fCByYy5lYyB8fCBjb250ZXh0LmVsZW1lbnQud3lzaXd5ZztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gc2V0IHJhbmdlXHJcbiAgICAgICAgICAgIHRoaXMuc2V0UmFuZ2UoY29udGFpbmVyLCBvZmZzZXQsIGNvbnRhaW5lciwgb2Zmc2V0KTtcclxuICAgICAgICAgICAgLy8gaGlzdG9yeSBzdGFja1xyXG4gICAgICAgICAgICB0aGlzLmhpc3RvcnkucHVzaCh0cnVlKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBjb250YWluZXI6IGNvbnRhaW5lcixcclxuICAgICAgICAgICAgICAgIG9mZnNldDogb2Zmc2V0LFxyXG4gICAgICAgICAgICAgICAgcHJldkNvbnRhaW5lcjogc3RhcnRDb24gJiYgc3RhcnRDb24ucGFyZW50Tm9kZSA/IHN0YXJ0Q29uIDogbnVsbFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBBcHBlbmRlZCBhbGwgc2VsZWN0ZWQgZm9ybWF0IEVsZW1lbnQgdG8gdGhlIGFyZ3VtZW50IGVsZW1lbnQgYW5kIGluc2VydFxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gcmFuZ2VFbGVtZW50IEVsZW1lbnQgb2Ygd3JhcCB0aGUgYXJndW1lbnRzIChCTE9DS1FVT1RFLi4uKVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGFwcGx5UmFuZ2VGb3JtYXRFbGVtZW50OiBmdW5jdGlvbiAocmFuZ2VFbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMuZ2V0UmFuZ2VfYWRkTGluZSh0aGlzLmdldFJhbmdlKCksIG51bGwpO1xyXG4gICAgICAgICAgICBjb25zdCByYW5nZUxpbmVzID0gdGhpcy5nZXRTZWxlY3RlZEVsZW1lbnRzQW5kQ29tcG9uZW50cyhmYWxzZSk7XHJcbiAgICAgICAgICAgIGlmICghcmFuZ2VMaW5lcyB8fCByYW5nZUxpbmVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgbGluZXNMb29wOlxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gcmFuZ2VMaW5lcy5sZW5ndGgsIGxpbmUsIG5lc3RlZCwgZkVsLCBsRWwsIGYsIGw7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbGluZSA9IHJhbmdlTGluZXNbaV07XHJcbiAgICAgICAgICAgICAgICBpZiAoIXV0aWwuaXNMaXN0Q2VsbChsaW5lKSkgY29udGludWU7XHJcblxyXG4gICAgICAgICAgICAgICAgbmVzdGVkID0gbGluZS5sYXN0RWxlbWVudENoaWxkO1xyXG4gICAgICAgICAgICAgICAgaWYgKG5lc3RlZCAmJiB1dGlsLmlzTGlzdENlbGwobGluZS5uZXh0RWxlbWVudFNpYmxpbmcpICYmIHJhbmdlTGluZXMuaW5kZXhPZihsaW5lLm5leHRFbGVtZW50U2libGluZykgPiAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxFbCA9IG5lc3RlZC5sYXN0RWxlbWVudENoaWxkO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyYW5nZUxpbmVzLmluZGV4T2YobEVsKSA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBsaXN0ID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChsaXN0ID0gbEVsLmxhc3RFbGVtZW50Q2hpbGQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5pc0xpc3QobGlzdCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmFuZ2VMaW5lcy5pbmRleE9mKGxpc3QubGFzdEVsZW1lbnRDaGlsZCkgPiAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsRWwgPSBsaXN0Lmxhc3RFbGVtZW50Q2hpbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgbGluZXNMb29wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgZkVsID0gbmVzdGVkLmZpcnN0RWxlbWVudENoaWxkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmID0gcmFuZ2VMaW5lcy5pbmRleE9mKGZFbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGwgPSByYW5nZUxpbmVzLmluZGV4T2YobEVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2VMaW5lcy5zcGxpY2UoZiwgKGwgLSBmKSArIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZW4gPSByYW5nZUxpbmVzLmxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgbGFzdCAgPSByYW5nZUxpbmVzW3JhbmdlTGluZXMubGVuZ3RoIC0gMV07XHJcbiAgICAgICAgICAgIGxldCBzdGFuZFRhZywgYmVmb3JlVGFnLCBwRWxlbWVudDtcclxuXHJcbiAgICAgICAgICAgIGlmICh1dGlsLmlzUmFuZ2VGb3JtYXRFbGVtZW50KGxhc3QpIHx8IHV0aWwuaXNGb3JtYXRFbGVtZW50KGxhc3QpKSB7XHJcbiAgICAgICAgICAgICAgICBzdGFuZFRhZyA9IGxhc3Q7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBzdGFuZFRhZyA9IHV0aWwuZ2V0UmFuZ2VGb3JtYXRFbGVtZW50KGxhc3QsIG51bGwpIHx8IHV0aWwuZ2V0Rm9ybWF0RWxlbWVudChsYXN0LCBudWxsKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHV0aWwuaXNDZWxsKHN0YW5kVGFnKSkge1xyXG4gICAgICAgICAgICAgICAgYmVmb3JlVGFnID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIHBFbGVtZW50ID0gc3RhbmRUYWc7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBiZWZvcmVUYWcgPSBzdGFuZFRhZy5uZXh0U2libGluZztcclxuICAgICAgICAgICAgICAgIHBFbGVtZW50ID0gc3RhbmRUYWcucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgbGV0IHBhcmVudERlcHRoID0gdXRpbC5nZXRFbGVtZW50RGVwdGgoc3RhbmRUYWcpO1xyXG4gICAgICAgICAgICBsZXQgbGlzdFBhcmVudCA9IG51bGw7XHJcbiAgICAgICAgICAgIGNvbnN0IGxpbmVBcnIgPSBbXTtcclxuICAgICAgICAgICAgY29uc3QgcmVtb3ZlSXRlbXMgPSBmdW5jdGlvbiAocGFyZW50LCBvcmlnaW4sIGJlZm9yZSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IGNjID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIGlmIChwYXJlbnQgIT09IG9yaWdpbiAmJiAhdXRpbC5pc1RhYmxlKG9yaWdpbikpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob3JpZ2luICYmIHV0aWwuZ2V0RWxlbWVudERlcHRoKHBhcmVudCkgPT09IHV0aWwuZ2V0RWxlbWVudERlcHRoKG9yaWdpbikpIHJldHVybiBiZWZvcmU7XHJcbiAgICAgICAgICAgICAgICAgICAgY2MgPSB1dGlsLnJlbW92ZUl0ZW1BbGxQYXJlbnRzKG9yaWdpbiwgbnVsbCwgcGFyZW50KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY2MgPyBjYy5lYyA6IGJlZm9yZTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSByYW5nZUxpbmVzLmxlbmd0aCwgbGluZSwgb3JpZ2luUGFyZW50LCBkZXB0aCwgYmVmb3JlLCBuZXh0TGluZSwgbmV4dExpc3QsIG5lc3RlZDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsaW5lID0gcmFuZ2VMaW5lc1tpXTtcclxuICAgICAgICAgICAgICAgIG9yaWdpblBhcmVudCA9IGxpbmUucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgIGlmICghb3JpZ2luUGFyZW50IHx8IHJhbmdlRWxlbWVudC5jb250YWlucyhvcmlnaW5QYXJlbnQpKSBjb250aW51ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBkZXB0aCA9IHV0aWwuZ2V0RWxlbWVudERlcHRoKGxpbmUpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh1dGlsLmlzTGlzdChvcmlnaW5QYXJlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3RQYXJlbnQgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRMaXN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0UGFyZW50ID0gbmV4dExpc3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXN0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dExpc3QgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdFBhcmVudCA9IG9yaWdpblBhcmVudC5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBsaW5lQXJyLnB1c2gobGluZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgbmV4dExpbmUgPSByYW5nZUxpbmVzW2kgKyAxXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT09IGxlbiAtIDEgfHwgKG5leHRMaW5lICYmIG5leHRMaW5lLnBhcmVudE5vZGUgIT09IG9yaWdpblBhcmVudCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmVzdGVkIGxpc3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRMaW5lICYmIGxpbmUuY29udGFpbnMobmV4dExpbmUucGFyZW50Tm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRMaXN0ID0gbmV4dExpbmUucGFyZW50Tm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbGlzdCA9IG9yaWdpblBhcmVudC5wYXJlbnROb2RlLCBwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAodXRpbC5pc0xpc3QobGlzdCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAgPSB1dGlsLmNyZWF0ZUVsZW1lbnQobGlzdC5ub2RlTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLmFwcGVuZENoaWxkKGxpc3RQYXJlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdFBhcmVudCA9IHA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ID0gbGlzdC5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlZGdlID0gdGhpcy5kZXRhY2hSYW5nZUZvcm1hdEVsZW1lbnQob3JpZ2luUGFyZW50LCBsaW5lQXJyLCBudWxsLCB0cnVlLCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnREZXB0aCA+PSBkZXB0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50RGVwdGggPSBkZXB0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBFbGVtZW50ID0gZWRnZS5jYztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZm9yZVRhZyA9IHJlbW92ZUl0ZW1zKHBFbGVtZW50LCBvcmlnaW5QYXJlbnQsIGVkZ2UuZWMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJlZm9yZVRhZykgcEVsZW1lbnQgPSBiZWZvcmVUYWcucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwRWxlbWVudCA9PT0gZWRnZS5jYykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVmb3JlVGFnID0gZWRnZS5lYztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBFbGVtZW50ICE9PSBlZGdlLmNjKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWZvcmUgPSByZW1vdmVJdGVtcyhwRWxlbWVudCwgZWRnZS5jYywgYmVmb3JlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiZWZvcmUgIT09IHVuZGVmaW5lZCkgYmVmb3JlVGFnID0gYmVmb3JlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBiZWZvcmVUYWcgPSBlZGdlLmNjO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBjID0gMCwgY0xlbiA9IGVkZ2UucmVtb3ZlQXJyYXkubGVuZ3RoOyBjIDwgY0xlbjsgYysrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0UGFyZW50LmFwcGVuZENoaWxkKGVkZ2UucmVtb3ZlQXJyYXlbY10pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW5lc3RlZCkgcmFuZ2VFbGVtZW50LmFwcGVuZENoaWxkKGxpc3RQYXJlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dExpc3QpIGVkZ2UucmVtb3ZlQXJyYXlbZWRnZS5yZW1vdmVBcnJheS5sZW5ndGggLSAxXS5hcHBlbmRDaGlsZChuZXh0TGlzdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RQYXJlbnQgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXN0ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnREZXB0aCA+PSBkZXB0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnREZXB0aCA9IGRlcHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwRWxlbWVudCA9IG9yaWdpblBhcmVudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmVmb3JlVGFnID0gbGluZS5uZXh0U2libGluZztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgcmFuZ2VFbGVtZW50LmFwcGVuZENoaWxkKGxpbmUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAocEVsZW1lbnQgIT09IG9yaWdpblBhcmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiZWZvcmUgPSByZW1vdmVJdGVtcyhwRWxlbWVudCwgb3JpZ2luUGFyZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJlZm9yZSAhPT0gdW5kZWZpbmVkKSBiZWZvcmVUYWcgPSBiZWZvcmU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmVmZmVjdE5vZGUgPSBudWxsO1xyXG4gICAgICAgICAgICB1dGlsLm1lcmdlU2FtZVRhZ3MocmFuZ2VFbGVtZW50LCBudWxsLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIHV0aWwubWVyZ2VOZXN0ZWRUYWdzKHJhbmdlRWxlbWVudCwgZnVuY3Rpb24gKGN1cnJlbnQpIHsgcmV0dXJuIHRoaXMuaXNMaXN0KGN1cnJlbnQpOyB9LmJpbmQodXRpbCkpO1xyXG5cclxuICAgICAgICAgICAgLy8gTmVzdGVkIGxpc3RcclxuICAgICAgICAgICAgaWYgKGJlZm9yZVRhZyAmJiB1dGlsLmdldEVsZW1lbnREZXB0aChiZWZvcmVUYWcpID4gMCAmJiAodXRpbC5pc0xpc3QoYmVmb3JlVGFnLnBhcmVudE5vZGUpIHx8IHV0aWwuaXNMaXN0KGJlZm9yZVRhZy5wYXJlbnROb2RlLnBhcmVudE5vZGUpKSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGVwdGhGb3JtYXQgPSB1dGlsLmdldFBhcmVudEVsZW1lbnQoYmVmb3JlVGFnLCBmdW5jdGlvbiAoY3VycmVudCkgeyByZXR1cm4gdGhpcy5pc1JhbmdlRm9ybWF0RWxlbWVudChjdXJyZW50KSAmJiAhdGhpcy5pc0xpc3QoY3VycmVudCk7IH0uYmluZCh1dGlsKSk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzcGxpdFJhbmdlID0gdXRpbC5zcGxpdEVsZW1lbnQoYmVmb3JlVGFnLCBudWxsLCAhZGVwdGhGb3JtYXQgPyAwIDogdXRpbC5nZXRFbGVtZW50RGVwdGgoZGVwdGhGb3JtYXQpICsgMSk7XHJcbiAgICAgICAgICAgICAgICBzcGxpdFJhbmdlLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHJhbmdlRWxlbWVudCwgc3BsaXRSYW5nZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7IC8vIGJhc2ljXHJcbiAgICAgICAgICAgICAgICBwRWxlbWVudC5pbnNlcnRCZWZvcmUocmFuZ2VFbGVtZW50LCBiZWZvcmVUYWcpO1xyXG4gICAgICAgICAgICAgICAgcmVtb3ZlSXRlbXMocmFuZ2VFbGVtZW50LCBiZWZvcmVUYWcpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBlZGdlID0gdXRpbC5nZXRFZGdlQ2hpbGROb2RlcyhyYW5nZUVsZW1lbnQuZmlyc3RFbGVtZW50Q2hpbGQsIHJhbmdlRWxlbWVudC5sYXN0RWxlbWVudENoaWxkKTtcclxuICAgICAgICAgICAgaWYgKHJhbmdlTGluZXMubGVuZ3RoID4gMSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRSYW5nZShlZGdlLnNjLCAwLCBlZGdlLmVjLCBlZGdlLmVjLnRleHRDb250ZW50Lmxlbmd0aCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldFJhbmdlKGVkZ2UuZWMsIGVkZ2UuZWMudGV4dENvbnRlbnQubGVuZ3RoLCBlZGdlLmVjLCBlZGdlLmVjLnRleHRDb250ZW50Lmxlbmd0aCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGhpc3Rvcnkgc3RhY2tcclxuICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnB1c2goZmFsc2UpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBUaGUgZWxlbWVudHMgb2YgdGhlIFwic2VsZWN0ZWRGb3JtYXRzXCIgYXJyYXkgYXJlIGRldGFjaGVkIGZyb20gdGhlIFwicmFuZ2VFbGVtZW50XCIgZWxlbWVudC4gKFwiTElcIiB0YWdzIGFyZSBjb252ZXJ0ZWQgdG8gXCJQXCIgdGFncylcclxuICAgICAgICAgKiBXaGVuIFwic2VsZWN0ZWRGb3JtYXRzXCIgaXMgbnVsbCwgYWxsIGVsZW1lbnRzIGFyZSBkZXRhY2hlZCBhbmQgcmV0dXJuIHtjYzogcGFyZW50Tm9kZSwgc2M6IG5leHRTaWJsaW5nLCBlYzogcHJldmlvdXNTaWJsaW5nLCByZW1vdmVBcnJheTogW0FycmF5IG9mIHJlbW92ZWQgZWxlbWVudHNdfS5cclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJhbmdlRWxlbWVudCBSYW5nZSBmb3JtYXQgZWxlbWVudCAoUFJFLCBCTE9DS1FVT1RFLCBPTCwgVUwuLi4pXHJcbiAgICAgICAgICogQHBhcmFtIHtBcnJheXxudWxsfSBzZWxlY3RlZEZvcm1hdHMgQXJyYXkgb2YgZm9ybWF0IGVsZW1lbnRzIChQLCBESVYsIExJLi4uKSB0byByZW1vdmUuXHJcbiAgICAgICAgICogSWYgbnVsbCwgQXBwbGllcyB0byBhbGwgZWxlbWVudHMgYW5kIHJldHVybiB7Y2M6IHBhcmVudE5vZGUsIHNjOiBuZXh0U2libGluZywgZWM6IHByZXZpb3VzU2libGluZ31cclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR8bnVsbH0gbmV3UmFuZ2VFbGVtZW50IFRoZSBub2RlKHJhbmdlRWxlbWVudCkgdG8gcmVwbGFjZSB0aGUgY3VycmVudGx5IHdyYXBwZWQgbm9kZS5cclxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJlbW92ZSBJZiB0cnVlLCBkZWxldGVkIHdpdGhvdXQgZGV0YWNoZWQuXHJcbiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSBub3RIaXN0b3J5UHVzaCBXaGVuIHRydWUsIGl0IGRvZXMgbm90IHVwZGF0ZSB0aGUgaGlzdG9yeSBzdGFjayBhbmQgdGhlIHNlbGVjdGlvbiBvYmplY3QgYW5kIHJldHVybiBFZGdlTm9kZXMgKHV0aWwuZ2V0RWRnZUNoaWxkTm9kZXMpXHJcbiAgICAgICAgICogQHJldHVybnMge09iamVjdH1cclxuICAgICAgICAgKi9cclxuICAgICAgICBkZXRhY2hSYW5nZUZvcm1hdEVsZW1lbnQ6IGZ1bmN0aW9uIChyYW5nZUVsZW1lbnQsIHNlbGVjdGVkRm9ybWF0cywgbmV3UmFuZ2VFbGVtZW50LCByZW1vdmUsIG5vdEhpc3RvcnlQdXNoKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJhbmdlID0gdGhpcy5nZXRSYW5nZSgpO1xyXG4gICAgICAgICAgICBjb25zdCBzbyA9IHJhbmdlLnN0YXJ0T2Zmc2V0O1xyXG4gICAgICAgICAgICBjb25zdCBlbyA9IHJhbmdlLmVuZE9mZnNldDtcclxuXHJcbiAgICAgICAgICAgIGxldCBjaGlsZHJlbiA9IHV0aWwuZ2V0TGlzdENoaWxkTm9kZXMocmFuZ2VFbGVtZW50LCBmdW5jdGlvbiAoY3VycmVudCkgeyByZXR1cm4gY3VycmVudC5wYXJlbnROb2RlID09PSByYW5nZUVsZW1lbnQ7IH0pO1xyXG4gICAgICAgICAgICBsZXQgcGFyZW50ID0gcmFuZ2VFbGVtZW50LnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgIGxldCBmaXJzdE5vZGUgPSBudWxsO1xyXG4gICAgICAgICAgICBsZXQgbGFzdE5vZGUgPSBudWxsO1xyXG4gICAgICAgICAgICBsZXQgcmFuZ2VFbCA9IHJhbmdlRWxlbWVudC5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgY29uc3QgcmVtb3ZlQXJyYXkgPSBbXTtcclxuICAgICAgICAgICAgY29uc3QgbmV3TGlzdCA9IHV0aWwuaXNMaXN0KG5ld1JhbmdlRWxlbWVudCk7XHJcbiAgICAgICAgICAgIGxldCBpbnNlcnRlZE5ldyA9IGZhbHNlO1xyXG4gICAgICAgICAgICBsZXQgcmVzZXQgPSBmYWxzZTtcclxuICAgICAgICAgICAgbGV0IG1vdmVDb21wbGV0ZSA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gYXBwZW5kTm9kZSAocGFyZW50LCBpbnNOb2RlLCBzaWJsaW5nLCBvcmlnaW5Ob2RlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodXRpbC5vbmx5WmVyb1dpZHRoU3BhY2UoaW5zTm9kZSkpIGluc05vZGUuaW5uZXJIVE1MID0gdXRpbC56ZXJvV2lkdGhTcGFjZTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoaW5zTm9kZS5ub2RlVHlwZSA9PT0gMykge1xyXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoaW5zTm9kZSwgc2libGluZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluc05vZGU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIGNvbnN0IGluc0NoaWxkcmVuID0gKG1vdmVDb21wbGV0ZSA/IGluc05vZGUgOiBvcmlnaW5Ob2RlKS5jaGlsZE5vZGVzO1xyXG4gICAgICAgICAgICAgICAgbGV0IGZvcm1hdCA9IGluc05vZGUuY2xvbmVOb2RlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIGxldCBmaXJzdCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICBsZXQgYyA9IG51bGw7XHJcblxyXG4gICAgICAgICAgICAgICAgd2hpbGUgKGluc0NoaWxkcmVuWzBdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYyA9IGluc0NoaWxkcmVuWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh1dGlsLl9ub3RUZXh0Tm9kZShjKSAmJiAhdXRpbC5pc0JyZWFrKGMpICYmICF1dGlsLmlzTGlzdENlbGwoZm9ybWF0KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZm9ybWF0LmNoaWxkTm9kZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmaXJzdCkgZmlyc3QgPSBmb3JtYXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKGZvcm1hdCwgc2libGluZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQgPSBpbnNOb2RlLmNsb25lTm9kZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShjLCBzaWJsaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmaXJzdCkgZmlyc3QgPSBjO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdC5hcHBlbmRDaGlsZChjKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGZvcm1hdC5jaGlsZE5vZGVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5pc0xpc3RDZWxsKHBhcmVudCkgJiYgdXRpbC5pc0xpc3RDZWxsKGZvcm1hdCkgJiYgdXRpbC5pc0xpc3Qoc2libGluZykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0xpc3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gc2libGluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlKHNpYmxpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQuYXBwZW5kQ2hpbGQoc2libGluZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2libGluZyA9IHNpYmxpbmcubmV4dFNpYmxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZm9ybWF0LCBwYXJlbnQubmV4dEVsZW1lbnRTaWJsaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbk5leHQgPSBvcmlnaW5Ob2RlLm5leHRFbGVtZW50U2libGluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRldGFjaFJhbmdlID0gdXRpbC5kZXRhY2hOZXN0ZWRMaXN0KG9yaWdpbk5vZGUsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocmFuZ2VFbGVtZW50ICE9PSBkZXRhY2hSYW5nZSkgfHwgKG9yaWdpbk5leHQgIT09IG9yaWdpbk5vZGUubmV4dEVsZW1lbnRTaWJsaW5nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZDaGlsZHJlbiA9IGZvcm1hdC5jaGlsZE5vZGVzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChmQ2hpbGRyZW5bMF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luTm9kZS5hcHBlbmRDaGlsZChmQ2hpbGRyZW5bMF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2VFbGVtZW50ID0gZGV0YWNoUmFuZ2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShmb3JtYXQsIHNpYmxpbmcpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFmaXJzdCkgZmlyc3QgPSBmb3JtYXQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZpcnN0O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBkZXRhY2ggbG9vcFxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gY2hpbGRyZW4ubGVuZ3RoLCBpbnNOb2RlLCBsaW5lSW5kZXgsIG5leHQ7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgaW5zTm9kZSA9IGNoaWxkcmVuW2ldO1xyXG4gICAgICAgICAgICAgICAgaWYgKGluc05vZGUubm9kZVR5cGUgPT09IDMgJiYgdXRpbC5pc0xpc3QocmFuZ2VFbCkpIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICBtb3ZlQ29tcGxldGUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIGlmIChyZW1vdmUgJiYgaSA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghc2VsZWN0ZWRGb3JtYXRzIHx8IHNlbGVjdGVkRm9ybWF0cy5sZW5ndGggPT09IGxlbiB8fCBzZWxlY3RlZEZvcm1hdHNbMF0gPT09IGluc05vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3ROb2RlID0gcmFuZ2VFbGVtZW50LnByZXZpb3VzU2libGluZztcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmaXJzdE5vZGUgPSByYW5nZUVsO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWRGb3JtYXRzKSBsaW5lSW5kZXggPSBzZWxlY3RlZEZvcm1hdHMuaW5kZXhPZihpbnNOb2RlKTtcclxuICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZEZvcm1hdHMgJiYgbGluZUluZGV4ID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghcmFuZ2VFbCkgcmFuZ2VFbCA9IHJhbmdlRWxlbWVudC5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJhbmdlRWwuYXBwZW5kQ2hpbGQoaW5zTm9kZSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZEZvcm1hdHMpIG5leHQgPSBzZWxlY3RlZEZvcm1hdHNbbGluZUluZGV4ICsgMV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJhbmdlRWwgJiYgcmFuZ2VFbC5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUocmFuZ2VFbCwgcmFuZ2VFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2VFbCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5ld0xpc3QgJiYgdXRpbC5pc0xpc3RDZWxsKGluc05vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0ICYmIHV0aWwuZ2V0RWxlbWVudERlcHRoKGluc05vZGUpICE9PSB1dGlsLmdldEVsZW1lbnREZXB0aChuZXh0KSAmJiAodXRpbC5pc0xpc3RDZWxsKHBhcmVudCkgfHwgdXRpbC5nZXRBcnJheUl0ZW0oaW5zTm9kZS5jaGlsZHJlbiwgdXRpbC5pc0xpc3QsIGZhbHNlKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGluc05leHQgPSBpbnNOb2RlLm5leHRFbGVtZW50U2libGluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRldGFjaFJhbmdlID0gdXRpbC5kZXRhY2hOZXN0ZWRMaXN0KGluc05vZGUsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocmFuZ2VFbGVtZW50ICE9PSBkZXRhY2hSYW5nZSkgfHwgaW5zTmV4dCAhPT0gaW5zTm9kZS5uZXh0RWxlbWVudFNpYmxpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZUVsZW1lbnQgPSBkZXRhY2hSYW5nZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNldCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbm5lciA9IGluc05vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnNOb2RlID0gdXRpbC5jcmVhdGVFbGVtZW50KHJlbW92ZSA/IGlubmVyLm5vZGVOYW1lIDogKHV0aWwuaXNMaXN0KHJhbmdlRWxlbWVudC5wYXJlbnROb2RlKSB8fCB1dGlsLmlzTGlzdENlbGwocmFuZ2VFbGVtZW50LnBhcmVudE5vZGUpKSA/ICdMSScgOiB1dGlsLmlzQ2VsbChyYW5nZUVsZW1lbnQucGFyZW50Tm9kZSkgPyAnRElWJyA6IG9wdGlvbnMuZGVmYXVsdFRhZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpc0NlbGwgPSB1dGlsLmlzTGlzdENlbGwoaW5zTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbm5lckNoaWxkcmVuID0gaW5uZXIuY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChpbm5lckNoaWxkcmVuWzBdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHV0aWwuaXNMaXN0KGlubmVyQ2hpbGRyZW5bMF0pICYmICFpc0NlbGwpIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc05vZGUuYXBwZW5kQ2hpbGQoaW5uZXJDaGlsZHJlblswXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1dGlsLmNvcHlGb3JtYXRBdHRyaWJ1dGVzKGluc05vZGUsIGlubmVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdmVDb21wbGV0ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnNOb2RlID0gaW5zTm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFyZXNldCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXJlbW92ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld1JhbmdlRWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaW5zZXJ0ZWROZXcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShuZXdSYW5nZUVsZW1lbnQsIHJhbmdlRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydGVkTmV3ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zTm9kZSA9IGFwcGVuZE5vZGUobmV3UmFuZ2VFbGVtZW50LCBpbnNOb2RlLCBudWxsLCBjaGlsZHJlbltpXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc05vZGUgPSBhcHBlbmROb2RlKHBhcmVudCwgaW5zTm9kZSwgcmFuZ2VFbGVtZW50LCBjaGlsZHJlbltpXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcmVzZXQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWRGb3JtYXRzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3ROb2RlID0gaW5zTm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmaXJzdE5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0Tm9kZSA9IGluc05vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFmaXJzdE5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3ROb2RlID0gbGFzdE5vZGUgPSBpbnNOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUFycmF5LnB1c2goaW5zTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW0oY2hpbGRyZW5baV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzZXQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0ID0gbW92ZUNvbXBsZXRlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IHV0aWwuZ2V0TGlzdENoaWxkTm9kZXMocmFuZ2VFbGVtZW50LCBmdW5jdGlvbiAoY3VycmVudCkgeyByZXR1cm4gY3VycmVudC5wYXJlbnROb2RlID09PSByYW5nZUVsZW1lbnQ7IH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2VFbCA9IHJhbmdlRWxlbWVudC5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gcmFuZ2VFbGVtZW50LnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID0gLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW4gPSBjaGlsZHJlbi5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgcmFuZ2VQYXJlbnQgPSByYW5nZUVsZW1lbnQucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgbGV0IHJhbmdlUmlnaHQgPSByYW5nZUVsZW1lbnQubmV4dFNpYmxpbmc7XHJcbiAgICAgICAgICAgIGlmIChyYW5nZUVsICYmIHJhbmdlRWwuY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgcmFuZ2VQYXJlbnQuaW5zZXJ0QmVmb3JlKHJhbmdlRWwsIHJhbmdlUmlnaHQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBpZiAobmV3UmFuZ2VFbGVtZW50KSBmaXJzdE5vZGUgPSBuZXdSYW5nZUVsZW1lbnQucHJldmlvdXNTaWJsaW5nO1xyXG4gICAgICAgICAgICBlbHNlIGlmICghZmlyc3ROb2RlKSBmaXJzdE5vZGUgPSByYW5nZUVsZW1lbnQucHJldmlvdXNTaWJsaW5nO1xyXG4gICAgICAgICAgICByYW5nZVJpZ2h0ID0gcmFuZ2VFbGVtZW50Lm5leHRTaWJsaW5nO1xyXG5cclxuICAgICAgICAgICAgaWYgKHJhbmdlRWxlbWVudC5jaGlsZHJlbi5sZW5ndGggPT09IDAgfHwgcmFuZ2VFbGVtZW50LnRleHRDb250ZW50Lmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVJdGVtKHJhbmdlRWxlbWVudCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUVtcHR5Tm9kZShyYW5nZUVsZW1lbnQsIG51bGwpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgZWRnZSA9IG51bGw7XHJcbiAgICAgICAgICAgIGlmIChyZW1vdmUpIHtcclxuICAgICAgICAgICAgICAgIGVkZ2UgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2M6IHJhbmdlUGFyZW50LFxyXG4gICAgICAgICAgICAgICAgICAgIHNjOiBmaXJzdE5vZGUsXHJcbiAgICAgICAgICAgICAgICAgICAgZWM6IHJhbmdlUmlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQXJyYXk6IHJlbW92ZUFycmF5XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFmaXJzdE5vZGUpIGZpcnN0Tm9kZSA9IGxhc3ROb2RlO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFsYXN0Tm9kZSkgbGFzdE5vZGUgPSBmaXJzdE5vZGU7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZEVkZ2UgPSB1dGlsLmdldEVkZ2VDaGlsZE5vZGVzKGZpcnN0Tm9kZSwgKGxhc3ROb2RlLnBhcmVudE5vZGUgPyBmaXJzdE5vZGUgOiBsYXN0Tm9kZSkpO1xyXG4gICAgICAgICAgICAgICAgZWRnZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICBjYzogKGNoaWxkRWRnZS5zYyB8fCBjaGlsZEVkZ2UuZWMpLnBhcmVudE5vZGUsXHJcbiAgICAgICAgICAgICAgICAgICAgc2M6IGNoaWxkRWRnZS5zYyxcclxuICAgICAgICAgICAgICAgICAgICBlYzogY2hpbGRFZGdlLmVjXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmVmZmVjdE5vZGUgPSBudWxsO1xyXG4gICAgICAgICAgICBpZiAobm90SGlzdG9yeVB1c2gpIHJldHVybiBlZGdlO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgaWYgKCFyZW1vdmUgJiYgZWRnZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFzZWxlY3RlZEZvcm1hdHMpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFJhbmdlKGVkZ2Uuc2MsIDAsIGVkZ2Uuc2MsIDApO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFJhbmdlKGVkZ2Uuc2MsIHNvLCBlZGdlLmVjLCBlbyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGhpc3Rvcnkgc3RhY2tcclxuICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnB1c2goZmFsc2UpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBcInNlbGVjdGVkRm9ybWF0c1wiIGFycmF5IGFyZSBkZXRhY2hlZCBmcm9tIHRoZSBsaXN0IGVsZW1lbnQuXHJcbiAgICAgICAgICogVGhlIHJldHVybiB2YWx1ZSBpcyBhcHBsaWVkIHdoZW4gdGhlIGZpcnN0IGFuZCBsYXN0IGxpbmVzIG9mIFwic2VsZWN0ZWRGb3JtYXRzXCIgYXJlIFwiTElcIiByZXNwZWN0aXZlbHkuXHJcbiAgICAgICAgICogQHBhcmFtIHtBcnJheX0gc2VsZWN0ZWRGb3JtYXRzIEFycmF5IG9mIGZvcm1hdCBlbGVtZW50cyAoTEksIFAuLi4pIHRvIHJlbW92ZS5cclxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJlbW92ZSBJZiB0cnVlLCBkZWxldGVkIHdpdGhvdXQgZGV0YWNoZWQuXHJcbiAgICAgICAgICogQHJldHVybnMge09iamVjdH0ge3NjOiA8TEk+LCBlYzogPExJPn0uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZGV0YWNoTGlzdDogZnVuY3Rpb24gKHNlbGVjdGVkRm9ybWF0cywgcmVtb3ZlKSB7XHJcbiAgICAgICAgICAgIGxldCByYW5nZUFyciA9IHt9O1xyXG4gICAgICAgICAgICBsZXQgbGlzdEZpcnN0ID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGxldCBsaXN0TGFzdCA9IGZhbHNlO1xyXG4gICAgICAgICAgICBsZXQgZmlyc3QgPSBudWxsO1xyXG4gICAgICAgICAgICBsZXQgbGFzdCA9IG51bGw7XHJcbiAgICAgICAgICAgIGNvbnN0IHBhc3NDb21wb25lbnQgPSBmdW5jdGlvbiAoY3VycmVudCkgeyByZXR1cm4gIXRoaXMuaXNDb21wb25lbnQoY3VycmVudCk7IH0uYmluZCh1dGlsKTtcclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBzZWxlY3RlZEZvcm1hdHMubGVuZ3RoLCByLCBvLCBsYXN0SW5kZXgsIGlzTGlzdDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsYXN0SW5kZXggPSBpID09PSBsZW4gLSAxO1xyXG4gICAgICAgICAgICAgICAgbyA9IHV0aWwuZ2V0UmFuZ2VGb3JtYXRFbGVtZW50KHNlbGVjdGVkRm9ybWF0c1tpXSwgcGFzc0NvbXBvbmVudCk7XHJcbiAgICAgICAgICAgICAgICBpc0xpc3QgPSB1dGlsLmlzTGlzdChvKTtcclxuICAgICAgICAgICAgICAgIGlmICghciAmJiBpc0xpc3QpIHtcclxuICAgICAgICAgICAgICAgICAgICByID0gbztcclxuICAgICAgICAgICAgICAgICAgICByYW5nZUFyciA9IHtyOiByLCBmOiBbdXRpbC5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkRm9ybWF0c1tpXSwgJ0xJJyldfTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PT0gMCkgbGlzdEZpcnN0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAociAmJiBpc0xpc3QpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAociAhPT0gbykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlZGdlID0gdGhpcy5kZXRhY2hSYW5nZUZvcm1hdEVsZW1lbnQocmFuZ2VBcnIuZlswXS5wYXJlbnROb2RlLCByYW5nZUFyci5mLCBudWxsLCByZW1vdmUsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvID0gc2VsZWN0ZWRGb3JtYXRzW2ldLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsaXN0Rmlyc3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gZWRnZS5zYztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RGaXJzdCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsYXN0SW5kZXgpIGxhc3QgPSBlZGdlLmVjO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzTGlzdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgciA9IG87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZUFyciA9IHtyOiByLCBmOiBbdXRpbC5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkRm9ybWF0c1tpXSwgJ0xJJyldfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsYXN0SW5kZXgpIGxpc3RMYXN0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHIgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2VBcnIuZi5wdXNoKHV0aWwuZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZEZvcm1hdHNbaV0sICdMSScpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RJbmRleCkgbGlzdExhc3QgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAobGFzdEluZGV4ICYmIHV0aWwuaXNMaXN0KHIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWRnZSA9IHRoaXMuZGV0YWNoUmFuZ2VGb3JtYXRFbGVtZW50KHJhbmdlQXJyLmZbMF0ucGFyZW50Tm9kZSwgcmFuZ2VBcnIuZiwgbnVsbCwgcmVtb3ZlLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobGlzdExhc3QgfHwgbGVuID09PSAxKSBsYXN0ID0gZWRnZS5lYztcclxuICAgICAgICAgICAgICAgICAgICBpZiAobGlzdEZpcnN0KSBmaXJzdCA9IGVkZ2Uuc2MgfHwgbGFzdDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIHNjOiBmaXJzdCxcclxuICAgICAgICAgICAgICAgIGVjOiBsYXN0XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEFkZCwgdXBkYXRlLCBhbmQgZGVsZXRlIG5vZGVzIGZyb20gc2VsZWN0ZWQgdGV4dC5cclxuICAgICAgICAgKiAxLiBJZiB0aGVyZSBpcyBhIG5vZGUgaW4gdGhlIFwiYXBwZW5kTm9kZVwiIGFyZ3VtZW50LCBhIG5vZGUgd2l0aCB0aGUgc2FtZSB0YWdzIGFuZCBhdHRyaWJ1dGVzIGFzIFwiYXBwZW5kTm9kZVwiIGlzIGFkZGVkIHRvIHRoZSBzZWxlY3Rpb24gdGV4dC5cclxuICAgICAgICAgKiAyLiBJZiBpdCBpcyBpbiB0aGUgc2FtZSB0YWcsIG9ubHkgdGhlIHRhZydzIGF0dHJpYnV0ZXMgYXJlIGNoYW5nZWQgd2l0aG91dCBhZGRpbmcgYSB0YWcuXHJcbiAgICAgICAgICogMy4gSWYgdGhlIFwiYXBwZW5kTm9kZVwiIGFyZ3VtZW50IGlzIG51bGwsIHRoZSBub2RlIG9mIHRoZSBzZWxlY3Rpb24gaXMgdXBkYXRlIG9yIHJlbW92ZSB3aXRob3V0IGFkZGluZyBhIG5ldyBub2RlLlxyXG4gICAgICAgICAqIDQuIFRoZSBzYW1lIHN0eWxlIGFzIHRoZSBzdHlsZSBhdHRyaWJ1dGUgb2YgdGhlIFwic3R5bGVBcnJheVwiIGFyZ3VtZW50IGlzIGRlbGV0ZWQuXHJcbiAgICAgICAgICogICAgKFN0eWxlcyBzaG91bGQgYmUgcHV0IHdpdGggYXR0cmlidXRlIG5hbWVzIGZyb20gY3NzLiBbXCJiYWNrZ3JvdW5kLWNvbG9yXCJdKVxyXG4gICAgICAgICAqIDUuIFRoZSBzYW1lIGNsYXNzIG5hbWUgYXMgdGhlIGNsYXNzIGF0dHJpYnV0ZSBvZiB0aGUgXCJzdHlsZUFycmF5XCIgYXJndW1lbnQgaXMgZGVsZXRlZC5cclxuICAgICAgICAgKiAgICAoVGhlIGNsYXNzIG5hbWUgaXMgcHJlY2VkZWQgYnkgXCIuXCIgW1wiLmNsYXNzTmFtZVwiXSlcclxuICAgICAgICAgKiA2LiBVc2UgYSBsaXN0IG9mIHN0eWxlcyBhbmQgY2xhc3NlcyBvZiBcImFwcGVuZE5vZGVcIiBpbiBcInN0eWxlQXJyYXlcIiB0byBhdm9pZCBkdXBsaWNhdGUgcHJvcGVydHkgdmFsdWVzLlxyXG4gICAgICAgICAqIDcuIElmIGEgbm9kZSB3aXRoIGFsbCBzdHlsZXMgYW5kIGNsYXNzZXMgcmVtb3ZlZCBoYXMgdGhlIHNhbWUgdGFnIG5hbWUgYXMgXCJhcHBlbmROb2RlXCIgb3IgXCJyZW1vdmVOb2RlQXJyYXlcIiwgb3IgXCJhcHBlbmROb2RlXCIgaXMgbnVsbCwgdGhhdCBub2RlIGlzIGRlbGV0ZWQuXHJcbiAgICAgICAgICogOC4gUmVnYXJkbGVzcyBvZiB0aGUgc3R5bGUgYW5kIGNsYXNzIG9mIHRoZSBub2RlLCB0aGUgdGFnIHdpdGggdGhlIHNhbWUgbmFtZSBhcyB0aGUgXCJyZW1vdmVOb2RlQXJyYXlcIiBhcmd1bWVudCB2YWx1ZSBpcyBkZWxldGVkLlxyXG4gICAgICAgICAqIDkuIElmIHRoZSBcInN0cmljdFJlbW92ZVwiIGFyZ3VtZW50IGlzIHRydWUsIG9ubHkgbm9kZXMgd2l0aCBhbGwgc3R5bGVzIGFuZCBjbGFzc2VzIHJlbW92ZWQgZnJvbSB0aGUgbm9kZXMgb2YgXCJyZW1vdmVOb2RlQXJyYXlcIiBhcmUgcmVtb3ZlZC5cclxuICAgICAgICAgKjEwLiBJdCB3b24ndCB3b3JrIGlmIHRoZSBwYXJlbnQgbm9kZSBoYXMgdGhlIHNhbWUgY2xhc3MgYW5kIHNhbWUgdmFsdWUgc3R5bGUuXHJcbiAgICAgICAgICogICAgSG93ZXZlciwgaWYgdGhlcmUgaXMgYSB2YWx1ZSBpbiBcInJlbW92ZU5vZGVBcnJheVwiLCBpdCB3b3JrcyBhbmQgdGhlIHRleHQgbm9kZSBpcyBzZXBhcmF0ZWQgZXZlbiBpZiB0aGVyZSBpcyBubyBub2RlIHRvIHJlcGxhY2UuXHJcbiAgICAgICAgICogQHBhcmFtIHtFbGVtZW50fG51bGx9IGFwcGVuZE5vZGUgVGhlIGVsZW1lbnQgdG8gYmUgYWRkZWQgdG8gdGhlIHNlbGVjdGlvbi4gSWYgaXQgaXMgbnVsbCwgb25seSBkZWxldGUgdGhlIG5vZGUuXHJcbiAgICAgICAgICogQHBhcmFtIHtBcnJheXxudWxsfSBzdHlsZUFycmF5IFRoZSBzdHlsZSBvciBjbGFzc05hbWUgYXR0cmlidXRlIG5hbWUgQXJyYXkgdG8gY2hlY2sgKFsnZm9udC1zaXplJ10sIFsnLmNsYXNzTmFtZSddLCBbJ2ZvbnQtZmFtaWx5JywgJ2NvbG9yJywgJy5jbGFzc05hbWUnXS4uLl0pXHJcbiAgICAgICAgICogQHBhcmFtIHtBcnJheXxudWxsfSByZW1vdmVOb2RlQXJyYXkgQW4gYXJyYXkgb2Ygbm9kZSBuYW1lcyB0byByZW1vdmUgdHlwZXMgZnJvbSwgcmVtb3ZlIGFsbCBmb3JtYXRzIHdoZW4gXCJhcHBlbmROb2RlXCIgaXMgbnVsbCBhbmQgdGhlcmUgaXMgYW4gZW1wdHkgYXJyYXkgb3IgbnVsbCB2YWx1ZS4gKFsnc3BhbiddLCBbJ3N0cm9uZycsICdlbSddIC4uLl0pXHJcbiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufG51bGx9IHN0cmljdFJlbW92ZSBJZiB0cnVlLCBvbmx5IG5vZGVzIHdpdGggYWxsIHN0eWxlcyBhbmQgY2xhc3NlcyByZW1vdmVkIGZyb20gdGhlIG5vZGVzIG9mIFwicmVtb3ZlTm9kZUFycmF5XCIgYXJlIHJlbW92ZWQuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgbm9kZUNoYW5nZTogZnVuY3Rpb24gKGFwcGVuZE5vZGUsIHN0eWxlQXJyYXksIHJlbW92ZU5vZGVBcnJheSwgc3RyaWN0UmVtb3ZlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3Jlc2V0UmFuZ2VUb1RleHROb2RlKCk7XHJcbiAgICAgICAgICAgIGxldCByYW5nZSA9IHRoaXMuZ2V0UmFuZ2VfYWRkTGluZSh0aGlzLmdldFJhbmdlKCksIG51bGwpO1xyXG4gICAgICAgICAgICBzdHlsZUFycmF5ID0gc3R5bGVBcnJheSAmJiBzdHlsZUFycmF5Lmxlbmd0aCA+IDAgPyBzdHlsZUFycmF5IDogZmFsc2U7XHJcbiAgICAgICAgICAgIHJlbW92ZU5vZGVBcnJheSA9IHJlbW92ZU5vZGVBcnJheSAmJiByZW1vdmVOb2RlQXJyYXkubGVuZ3RoID4gMCA/IHJlbW92ZU5vZGVBcnJheSA6IGZhbHNlO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgY29uc3QgaXNSZW1vdmVOb2RlID0gIWFwcGVuZE5vZGU7XHJcbiAgICAgICAgICAgIGNvbnN0IGlzUmVtb3ZlRm9ybWF0ID0gaXNSZW1vdmVOb2RlICYmICFyZW1vdmVOb2RlQXJyYXkgJiYgIXN0eWxlQXJyYXk7XHJcbiAgICAgICAgICAgIGxldCBzdGFydENvbiA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICBsZXQgc3RhcnRPZmYgPSByYW5nZS5zdGFydE9mZnNldDtcclxuICAgICAgICAgICAgbGV0IGVuZENvbiA9IHJhbmdlLmVuZENvbnRhaW5lcjtcclxuICAgICAgICAgICAgbGV0IGVuZE9mZiA9IHJhbmdlLmVuZE9mZnNldDtcclxuXHJcbiAgICAgICAgICAgIGlmICgoaXNSZW1vdmVGb3JtYXQgJiYgcmFuZ2UuY29sbGFwc2VkICYmIHV0aWwuaXNGb3JtYXRFbGVtZW50KHN0YXJ0Q29uLnBhcmVudE5vZGUpICYmIHV0aWwuaXNGb3JtYXRFbGVtZW50KGVuZENvbi5wYXJlbnROb2RlKSkgfHwgKHN0YXJ0Q29uID09PSBlbmRDb24gJiYgc3RhcnRDb24ubm9kZVR5cGUgPT09IDEgJiYgdXRpbC5pc05vbkVkaXRhYmxlKHN0YXJ0Q29uKSkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHJhbmdlLmNvbGxhcHNlZCAmJiAhaXNSZW1vdmVGb3JtYXQpIHtcclxuICAgICAgICAgICAgICAgIGlmIChzdGFydENvbi5ub2RlVHlwZSA9PT0gMSAmJiAhdXRpbC5pc0JyZWFrKHN0YXJ0Q29uKSAmJiAhdXRpbC5pc0NvbXBvbmVudChzdGFydENvbikpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgYWZ0ZXJOb2RlID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBmb2N1c05vZGUgPSBzdGFydENvbi5jaGlsZE5vZGVzW3N0YXJ0T2ZmXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZvY3VzTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZvY3VzTm9kZS5uZXh0U2libGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXJOb2RlID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFmdGVyTm9kZSA9IHV0aWwuaXNCcmVhayhmb2N1c05vZGUpID8gZm9jdXNOb2RlIDogZm9jdXNOb2RlLm5leHRTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB6ZXJvV2lkdGggPSB1dGlsLmNyZWF0ZVRleHROb2RlKHV0aWwuemVyb1dpZHRoU3BhY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0Q29uLmluc2VydEJlZm9yZSh6ZXJvV2lkdGgsIGFmdGVyTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRSYW5nZSh6ZXJvV2lkdGgsIDEsIHplcm9XaWR0aCwgMSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJhbmdlID0gdGhpcy5nZXRSYW5nZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0Q29uID0gcmFuZ2Uuc3RhcnRDb250YWluZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRPZmYgPSByYW5nZS5zdGFydE9mZnNldDtcclxuICAgICAgICAgICAgICAgICAgICBlbmRDb24gPSByYW5nZS5lbmRDb250YWluZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgZW5kT2ZmID0gcmFuZ2UuZW5kT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodXRpbC5pc0Zvcm1hdEVsZW1lbnQoc3RhcnRDb24pKSB7XHJcbiAgICAgICAgICAgICAgICBzdGFydENvbiA9IHN0YXJ0Q29uLmNoaWxkTm9kZXNbc3RhcnRPZmZdIHx8IHN0YXJ0Q29uLmZpcnN0Q2hpbGQ7XHJcbiAgICAgICAgICAgICAgICBzdGFydE9mZiA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHV0aWwuaXNGb3JtYXRFbGVtZW50KGVuZENvbikpIHtcclxuICAgICAgICAgICAgICAgIGVuZENvbiA9IGVuZENvbi5jaGlsZE5vZGVzW2VuZE9mZl0gfHwgZW5kQ29uLmxhc3RDaGlsZDtcclxuICAgICAgICAgICAgICAgIGVuZE9mZiA9IGVuZENvbi50ZXh0Q29udGVudC5sZW5ndGg7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChpc1JlbW92ZU5vZGUpIHtcclxuICAgICAgICAgICAgICAgIGFwcGVuZE5vZGUgPSB1dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCB3UmVnRXhwID0gX3cuUmVnRXhwO1xyXG4gICAgICAgICAgICBjb25zdCBuZXdOb2RlTmFtZSA9IGFwcGVuZE5vZGUubm9kZU5hbWU7XHJcblxyXG4gICAgICAgICAgICAvKiBjaGVja2VkIHNhbWUgc3R5bGUgcHJvcGVydHkgKi9cclxuICAgICAgICAgICAgaWYgKCFpc1JlbW92ZUZvcm1hdCAmJiBzdGFydENvbiA9PT0gZW5kQ29uICYmICFyZW1vdmVOb2RlQXJyYXkgJiYgYXBwZW5kTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IHNOb2RlID0gc3RhcnRDb247XHJcbiAgICAgICAgICAgICAgICBsZXQgY2hlY2tDbnQgPSAwO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2hlY2tBdHRycyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICBjb25zdCBjaGVja1N0eWxlcyA9IGFwcGVuZE5vZGUuc3R5bGU7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gY2hlY2tTdHlsZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBjaGVja0F0dHJzLnB1c2goY2hlY2tTdHlsZXNbaV0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGNrZWNrQ2xhc3NlcyA9IGFwcGVuZE5vZGUuY2xhc3NMaXN0O1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNrZWNrQ2xhc3Nlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNoZWNrQXR0cnMucHVzaCgnLicgKyBja2Vja0NsYXNzZXNbaV0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChjaGVja0F0dHJzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSghdXRpbC5pc0Zvcm1hdEVsZW1lbnQoc05vZGUpICYmICF1dGlsLmlzV3lzaXd5Z0RpdihzTm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGVja0F0dHJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc05vZGUubm9kZVR5cGUgPT09IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzID0gY2hlY2tBdHRyc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjbGFzc1JlZyA9IC9eXFwuLy50ZXN0KHMpID8gbmV3IHdSZWdFeHAoJ1xcXFxzKicgKyBzLnJlcGxhY2UoL15cXC4vLCAnJykgKyAnKFxcXFxzK3wkKScsICdpZycpIDogZmFsc2U7XHJcbiAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHlsZUNoZWNrID0gaXNSZW1vdmVOb2RlID8gISFzTm9kZS5zdHlsZVtzXSA6ICghIXNOb2RlLnN0eWxlW3NdICYmICEhYXBwZW5kTm9kZS5zdHlsZVtzXSAmJiBzTm9kZS5zdHlsZVtzXSA9PT0gYXBwZW5kTm9kZS5zdHlsZVtzXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2xhc3NDaGVjayA9IGNsYXNzUmVnID09PSBmYWxzZSA/IGZhbHNlIDogaXNSZW1vdmVOb2RlID8gISFzTm9kZS5jbGFzc05hbWUubWF0Y2goY2xhc3NSZWcpIDogISFzTm9kZS5jbGFzc05hbWUubWF0Y2goY2xhc3NSZWcpICYmICEhYXBwZW5kTm9kZS5jbGFzc05hbWUubWF0Y2goY2xhc3NSZWcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHlsZUNoZWNrIHx8IGNsYXNzQ2hlY2spIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tDbnQrKztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgc05vZGUgPSBzTm9kZS5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGVja0NudCA+PSBjaGVja0F0dHJzLmxlbmd0aCkgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgc3RhcnQgPSB7fSwgZW5kID0ge307XHJcbiAgICAgICAgICAgIGxldCBuZXdOb2RlLCBzdHlsZVJlZ0V4cCA9ICcnLCBjbGFzc1JlZ0V4cCA9ICcnLCByZW1vdmVOb2RlUmVnRXhwID0gJyc7XHJcblxyXG4gICAgICAgICAgICBpZiAoc3R5bGVBcnJheSkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHN0eWxlQXJyYXkubGVuZ3RoLCBzOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBzID0gc3R5bGVBcnJheVtpXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoL15cXC4vLnRlc3QocykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NSZWdFeHAgKz0gKGNsYXNzUmVnRXhwID8gJ3wnIDogJ1xcXFxzKig/OicpICsgcy5yZXBsYWNlKC9eXFwuLywgJycpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlUmVnRXhwICs9IChzdHlsZVJlZ0V4cCA/ICd8JyA6ICcoPzo7fF58XFxcXHMpKD86JykgKyBzO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoc3R5bGVSZWdFeHApIHtcclxuICAgICAgICAgICAgICAgICAgICBzdHlsZVJlZ0V4cCArPSAnKVxcXFxzKjpbXjtdKlxcXFxzKig/Ojt8JCknO1xyXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlUmVnRXhwID0gbmV3IHdSZWdFeHAoc3R5bGVSZWdFeHAsICdpZycpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChjbGFzc1JlZ0V4cCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzUmVnRXhwICs9ICcpKD89XFxcXHMrfCQpJztcclxuICAgICAgICAgICAgICAgICAgICBjbGFzc1JlZ0V4cCA9IG5ldyB3UmVnRXhwKGNsYXNzUmVnRXhwLCAnaWcnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHJlbW92ZU5vZGVBcnJheSkge1xyXG4gICAgICAgICAgICAgICAgcmVtb3ZlTm9kZVJlZ0V4cCA9ICdeKD86JyArIHJlbW92ZU5vZGVBcnJheVswXTtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmVtb3ZlTm9kZUFycmF5Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlTm9kZVJlZ0V4cCArPSAnfCcgKyByZW1vdmVOb2RlQXJyYXlbaV07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZW1vdmVOb2RlUmVnRXhwICs9ICcpJCc7XHJcbiAgICAgICAgICAgICAgICByZW1vdmVOb2RlUmVnRXhwID0gbmV3IHdSZWdFeHAocmVtb3ZlTm9kZVJlZ0V4cCwgJ2knKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyoqIHZhbGlkYXRpb24gY2hlY2sgZnVuY3Rpb24qL1xyXG4gICAgICAgICAgICBjb25zdCB3Qm9vbGVhbiA9IF93LkJvb2xlYW47XHJcbiAgICAgICAgICAgIGNvbnN0IF9yZW1vdmVDaGVjayA9IHt2OiBmYWxzZX07XHJcbiAgICAgICAgICAgIGNvbnN0IHZhbGlkYXRpb24gPSBmdW5jdGlvbiAoY2hlY2tOb2RlKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB2Tm9kZSA9IGNoZWNrTm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIGFsbCBwYXRoXHJcbiAgICAgICAgICAgICAgICBpZiAodk5vZGUubm9kZVR5cGUgPT09IDMgfHwgdXRpbC5pc0JyZWFrKHZOb2RlKSkgcmV0dXJuIHZOb2RlO1xyXG4gICAgICAgICAgICAgICAgLy8gYWxsIHJlbW92ZVxyXG4gICAgICAgICAgICAgICAgaWYgKGlzUmVtb3ZlRm9ybWF0KSByZXR1cm4gbnVsbDtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyByZW1vdmUgbm9kZSBjaGVja1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdGFnUmVtb3ZlID0gKCFyZW1vdmVOb2RlUmVnRXhwICYmIGlzUmVtb3ZlTm9kZSkgfHwgKHJlbW92ZU5vZGVSZWdFeHAgJiYgcmVtb3ZlTm9kZVJlZ0V4cC50ZXN0KHZOb2RlLm5vZGVOYW1lKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gdGFnIHJlbW92ZVxyXG4gICAgICAgICAgICAgICAgaWYgKHRhZ1JlbW92ZSAmJiAhc3RyaWN0UmVtb3ZlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3JlbW92ZUNoZWNrLnYgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIHN0eWxlIHJlZ2V4cFxyXG4gICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luU3R5bGUgPSB2Tm9kZS5zdHlsZS5jc3NUZXh0O1xyXG4gICAgICAgICAgICAgICAgbGV0IHN0eWxlID0gJyc7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3R5bGVSZWdFeHAgJiYgb3JpZ2luU3R5bGUubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlID0gb3JpZ2luU3R5bGUucmVwbGFjZShzdHlsZVJlZ0V4cCwgJycpLnRyaW0oKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGUgIT09IG9yaWdpblN0eWxlKSBfcmVtb3ZlQ2hlY2sudiA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gY2xhc3MgY2hlY2tcclxuICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbkNsYXNzZXMgPSB2Tm9kZS5jbGFzc05hbWU7XHJcbiAgICAgICAgICAgICAgICBsZXQgY2xhc3NlcyA9ICcnO1xyXG4gICAgICAgICAgICAgICAgaWYgKGNsYXNzUmVnRXhwICYmIG9yaWdpbkNsYXNzZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzZXMgPSBvcmlnaW5DbGFzc2VzLnJlcGxhY2UoY2xhc3NSZWdFeHAsICcnKS50cmltKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzZXMgIT09IG9yaWdpbkNsYXNzZXMpIF9yZW1vdmVDaGVjay52ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyByZW1vdmUgb25seVxyXG4gICAgICAgICAgICAgICAgaWYgKGlzUmVtb3ZlTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgoY2xhc3NSZWdFeHAgfHwgIW9yaWdpbkNsYXNzZXMpICYmIChzdHlsZVJlZ0V4cCB8fCAhb3JpZ2luU3R5bGUpICYmICFzdHlsZSAmJiAhY2xhc3NlcyAmJiB0YWdSZW1vdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3JlbW92ZUNoZWNrLnYgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gY2hhbmdlXHJcbiAgICAgICAgICAgICAgICBpZiAoc3R5bGUgfHwgY2xhc3NlcyB8fCB2Tm9kZS5ub2RlTmFtZSAhPT0gbmV3Tm9kZU5hbWUgfHwgKHdCb29sZWFuKHN0eWxlUmVnRXhwKSAhPT0gd0Jvb2xlYW4ob3JpZ2luU3R5bGUpKSB8fCAod0Jvb2xlYW4oY2xhc3NSZWdFeHApICE9PSB3Qm9vbGVhbihvcmlnaW5DbGFzc2VzKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGVSZWdFeHAgJiYgb3JpZ2luU3R5bGUubGVuZ3RoID4gMCkgdk5vZGUuc3R5bGUuY3NzVGV4dCA9IHN0eWxlO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdk5vZGUuc3R5bGUuY3NzVGV4dCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2Tm9kZS5yZW1vdmVBdHRyaWJ1dGUoJ3N0eWxlJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2xhc3NSZWdFeHAgJiYgb3JpZ2luQ2xhc3Nlcy5sZW5ndGggPiAwKSB2Tm9kZS5jbGFzc05hbWUgPSBjbGFzc2VzLnRyaW0oKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXZOb2RlLmNsYXNzTmFtZS50cmltKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdk5vZGUucmVtb3ZlQXR0cmlidXRlKCdjbGFzcycpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF2Tm9kZS5zdHlsZS5jc3NUZXh0ICYmICF2Tm9kZS5jbGFzc05hbWUgJiYgKHZOb2RlLm5vZGVOYW1lID09PSBuZXdOb2RlTmFtZSB8fCB0YWdSZW1vdmUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9yZW1vdmVDaGVjay52ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdk5vZGU7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgX3JlbW92ZUNoZWNrLnYgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAvLyBnZXQgbGluZSBub2Rlc1xyXG4gICAgICAgICAgICBjb25zdCBsaW5lTm9kZXMgPSB0aGlzLmdldFNlbGVjdGVkRWxlbWVudHMobnVsbCk7XHJcbiAgICAgICAgICAgIHJhbmdlID0gdGhpcy5nZXRSYW5nZSgpO1xyXG4gICAgICAgICAgICBzdGFydENvbiA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICBzdGFydE9mZiA9IHJhbmdlLnN0YXJ0T2Zmc2V0O1xyXG4gICAgICAgICAgICBlbmRDb24gPSByYW5nZS5lbmRDb250YWluZXI7XHJcbiAgICAgICAgICAgIGVuZE9mZiA9IHJhbmdlLmVuZE9mZnNldDtcclxuXHJcbiAgICAgICAgICAgIGlmICghdXRpbC5nZXRGb3JtYXRFbGVtZW50KHN0YXJ0Q29uLCBudWxsKSkge1xyXG4gICAgICAgICAgICAgICAgc3RhcnRDb24gPSB1dGlsLmdldENoaWxkRWxlbWVudChsaW5lTm9kZXNbMF0sIGZ1bmN0aW9uIChjdXJyZW50KSB7IHJldHVybiBjdXJyZW50Lm5vZGVUeXBlID09PSAzOyB9LCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICBzdGFydE9mZiA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghdXRpbC5nZXRGb3JtYXRFbGVtZW50KGVuZENvbiwgbnVsbCkpIHtcclxuICAgICAgICAgICAgICAgIGVuZENvbiA9IHV0aWwuZ2V0Q2hpbGRFbGVtZW50KGxpbmVOb2Rlc1tsaW5lTm9kZXMubGVuZ3RoIC0gMV0sIGZ1bmN0aW9uIChjdXJyZW50KSB7IHJldHVybiBjdXJyZW50Lm5vZGVUeXBlID09PSAzOyB9LCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICBlbmRPZmYgPSBlbmRDb24udGV4dENvbnRlbnQubGVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgY29uc3Qgb25lTGluZSA9IHV0aWwuZ2V0Rm9ybWF0RWxlbWVudChzdGFydENvbiwgbnVsbCkgPT09IHV0aWwuZ2V0Rm9ybWF0RWxlbWVudChlbmRDb24sIG51bGwpO1xyXG4gICAgICAgICAgICBjb25zdCBlbmRMZW5ndGggPSBsaW5lTm9kZXMubGVuZ3RoIC0gKG9uZUxpbmUgPyAwIDogMSk7XHJcblxyXG4gICAgICAgICAgICAvLyBub2RlIENoYW5nZXNcclxuICAgICAgICAgICAgbmV3Tm9kZSA9IGFwcGVuZE5vZGUuY2xvbmVOb2RlKGZhbHNlKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGlzUmVtb3ZlQW5jaG9yID0gaXNSZW1vdmVGb3JtYXQgfHwgKGlzUmVtb3ZlTm9kZSAmJiAoZnVuY3Rpb24gKGFycikge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgbiA9IDAsIGxlbiA9IGFyci5sZW5ndGg7IG4gPCBsZW47IG4rKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh1dGlsLl9pc01haW50YWluZWROb2RlKGFycltuXSkgfHwgdXRpbC5faXNTaXplTm9kZShhcnJbbl0pKSByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfSkocmVtb3ZlTm9kZUFycmF5KSk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBpc1NpemVOb2RlID0gdXRpbC5faXNTaXplTm9kZShuZXdOb2RlKTtcclxuICAgICAgICAgICAgY29uc3QgX2dldE1haW50YWluZWROb2RlID0gdGhpcy5fdXRpbF9nZXRNYWludGFpbmVkTm9kZS5iaW5kKHV0aWwsIGlzUmVtb3ZlQW5jaG9yLCBpc1NpemVOb2RlKTtcclxuICAgICAgICAgICAgY29uc3QgX2lzTWFpbnRhaW5lZE5vZGUgPSB0aGlzLl91dGlsX2lzTWFpbnRhaW5lZE5vZGUuYmluZCh1dGlsLCBpc1JlbW92ZUFuY2hvciwgaXNTaXplTm9kZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBvbmUgbGluZVxyXG4gICAgICAgICAgICBpZiAob25lTGluZSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3UmFuZ2UgPSB0aGlzLl9ub2RlQ2hhbmdlX29uZUxpbmUobGluZU5vZGVzWzBdLCBuZXdOb2RlLCB2YWxpZGF0aW9uLCBzdGFydENvbiwgc3RhcnRPZmYsIGVuZENvbiwgZW5kT2ZmLCBpc1JlbW92ZUZvcm1hdCwgaXNSZW1vdmVOb2RlLCByYW5nZS5jb2xsYXBzZWQsIF9yZW1vdmVDaGVjaywgX2dldE1haW50YWluZWROb2RlLCBfaXNNYWludGFpbmVkTm9kZSk7XHJcbiAgICAgICAgICAgICAgICBzdGFydC5jb250YWluZXIgPSBuZXdSYW5nZS5zdGFydENvbnRhaW5lcjtcclxuICAgICAgICAgICAgICAgIHN0YXJ0Lm9mZnNldCA9IG5ld1JhbmdlLnN0YXJ0T2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgZW5kLmNvbnRhaW5lciA9IG5ld1JhbmdlLmVuZENvbnRhaW5lcjtcclxuICAgICAgICAgICAgICAgIGVuZC5vZmZzZXQgPSBuZXdSYW5nZS5lbmRPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RhcnQuY29udGFpbmVyID09PSBlbmQuY29udGFpbmVyICYmIHV0aWwub25seVplcm9XaWR0aFNwYWNlKHN0YXJ0LmNvbnRhaW5lcikpIHtcclxuICAgICAgICAgICAgICAgICAgICBzdGFydC5vZmZzZXQgPSBlbmQub2Zmc2V0ID0gMTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMuX3NldENvbW1vbkxpc3RTdHlsZShuZXdSYW5nZS5hbmNlc3RvciwgbnVsbCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7IC8vIG11bHRpIGxpbmUgXHJcbiAgICAgICAgICAgICAgICAvLyBlbmRcclxuICAgICAgICAgICAgICAgIGlmIChlbmRMZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZSA9IGFwcGVuZE5vZGUuY2xvbmVOb2RlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICBlbmQgPSB0aGlzLl9ub2RlQ2hhbmdlX2VuZExpbmUobGluZU5vZGVzW2VuZExlbmd0aF0sIG5ld05vZGUsIHZhbGlkYXRpb24sIGVuZENvbiwgZW5kT2ZmLCBpc1JlbW92ZUZvcm1hdCwgaXNSZW1vdmVOb2RlLCBfcmVtb3ZlQ2hlY2ssIF9nZXRNYWludGFpbmVkTm9kZSwgX2lzTWFpbnRhaW5lZE5vZGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIG1pZFxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IGVuZExlbmd0aCAtIDEsIG5ld1JhbmdlOyBpID4gMDsgaS0tKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZSA9IGFwcGVuZE5vZGUuY2xvbmVOb2RlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICBuZXdSYW5nZSA9IHRoaXMuX25vZGVDaGFuZ2VfbWlkZGxlTGluZShsaW5lTm9kZXNbaV0sIG5ld05vZGUsIHZhbGlkYXRpb24sIGlzUmVtb3ZlRm9ybWF0LCBpc1JlbW92ZU5vZGUsIF9yZW1vdmVDaGVjaywgZW5kLmNvbnRhaW5lcik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5ld1JhbmdlLmVuZENvbnRhaW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmQuYW5jZXN0b3IgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmQuY29udGFpbmVyID0gbmV3UmFuZ2UuZW5kQ29udGFpbmVyO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZXRDb21tb25MaXN0U3R5bGUobmV3UmFuZ2UuYW5jZXN0b3IsIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIHN0YXJ0XHJcbiAgICAgICAgICAgICAgICBuZXdOb2RlID0gYXBwZW5kTm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgc3RhcnQgPSB0aGlzLl9ub2RlQ2hhbmdlX3N0YXJ0TGluZShsaW5lTm9kZXNbMF0sIG5ld05vZGUsIHZhbGlkYXRpb24sIHN0YXJ0Q29uLCBzdGFydE9mZiwgaXNSZW1vdmVGb3JtYXQsIGlzUmVtb3ZlTm9kZSwgX3JlbW92ZUNoZWNrLCBfZ2V0TWFpbnRhaW5lZE5vZGUsIF9pc01haW50YWluZWROb2RlLCBlbmQuY29udGFpbmVyKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoc3RhcnQuZW5kQ29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZW5kLmFuY2VzdG9yID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICBlbmQuY29udGFpbmVyID0gc3RhcnQuZW5kQ29udGFpbmVyO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChlbmRMZW5ndGggPD0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVuZCA9IHN0YXJ0O1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghZW5kLmNvbnRhaW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgIGVuZC5hbmNlc3RvciA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgZW5kLmNvbnRhaW5lciA9IHN0YXJ0LmNvbnRhaW5lcjtcclxuICAgICAgICAgICAgICAgICAgICBlbmQub2Zmc2V0ID0gc3RhcnQuY29udGFpbmVyLnRleHRDb250ZW50Lmxlbmd0aDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXRDb21tb25MaXN0U3R5bGUoc3RhcnQuYW5jZXN0b3IsIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0Q29tbW9uTGlzdFN0eWxlKGVuZC5hbmNlc3RvciB8fCB1dGlsLmdldEZvcm1hdEVsZW1lbnQoZW5kLmNvbnRhaW5lciksIG51bGwpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBzZXQgcmFuZ2VcclxuICAgICAgICAgICAgdGhpcy5jb250cm9sbGVyc09mZigpO1xyXG4gICAgICAgICAgICB0aGlzLnNldFJhbmdlKHN0YXJ0LmNvbnRhaW5lciwgc3RhcnQub2Zmc2V0LCBlbmQuY29udGFpbmVyLCBlbmQub2Zmc2V0KTtcclxuXHJcbiAgICAgICAgICAgIC8vIGhpc3Rvcnkgc3RhY2tcclxuICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnB1c2goZmFsc2UpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBJZiBjZXJ0YWluIHN0eWxlcyBhcmUgYXBwbGllZCB0byBhbGwgY2hpbGQgbm9kZXMgb2YgdGhlIGxpc3QgY2VsbCwgdGhlIHN0eWxlIG9mIHRoZSBsaXN0IGNlbGwgaXMgYWxzbyBjaGFuZ2VkLiAoYm9sZCwgY29sb3IsIHNpemUpXHJcbiAgICAgICAgICogQHBhcmFtIHtFbGVtZW50fSBlbCBMaXN0IGNlbGwgZWxlbWVudC4gPGxpPlxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudHxudWxsfSBjaGlsZCBWYXJpYWJsZSBmb3IgcmVjdXJzaXZlIGNhbGwuIChcIm51bGxcIiBvbiB0aGUgZmlyc3QgY2FsbClcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9zZXRDb21tb25MaXN0U3R5bGU6IGZ1bmN0aW9uIChlbCwgY2hpbGQpIHtcclxuICAgICAgICAgICAgaWYgKCF1dGlsLmlzTGlzdENlbGwoZWwpKSByZXR1cm47XHJcbiAgICAgICAgICAgIGlmICghY2hpbGQpIGVsLnJlbW92ZUF0dHJpYnV0ZSgnc3R5bGUnKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkcmVuID0gdXRpbC5nZXRBcnJheUl0ZW0oKGNoaWxkIHx8IGVsKS5jaGlsZE5vZGVzLCBmdW5jdGlvbiAoY3VycmVudCkgeyByZXR1cm4gIXV0aWwuaXNCcmVhayhjdXJyZW50KSAmJiAhdXRpbC5vbmx5WmVyb1dpZHRoU3BhY2UoY3VycmVudC50ZXh0Q29udGVudC50cmltKCkpOyB9LCB0cnVlKTtcclxuICAgICAgICAgICAgaWYgKGNoaWxkcmVuWzBdICYmIGNoaWxkcmVuLmxlbmd0aCA9PT0gMSl7XHJcbiAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkcmVuWzBdO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFjaGlsZCB8fCBjaGlsZC5ub2RlVHlwZSAhPT0gMSkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkU3R5bGUgPSBjaGlsZC5zdHlsZTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVsU3R5bGUgPSBlbC5zdHlsZTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBib2xkXHJcbiAgICAgICAgICAgICAgICBpZiAoL1NUUk9ORy9pLnRlc3QoY2hpbGQubm9kZU5hbWUpKSBlbFN0eWxlLmZvbnRXZWlnaHQgPSAnYm9sZCc7IC8vIGJvbGRcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoaWxkU3R5bGUuZm9udFdlaWdodCkgZWxTdHlsZS5mb250V2VpZ2h0ID0gY2hpbGRTdHlsZS5mb250V2VpZ2h0O1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIHN0eWxlc1xyXG4gICAgICAgICAgICAgICAgaWYgKGNoaWxkU3R5bGUuY29sb3IpIGVsU3R5bGUuY29sb3IgPSBjaGlsZFN0eWxlLmNvbG9yOyAvLyBjb2xvclxyXG4gICAgICAgICAgICAgICAgaWYgKGNoaWxkU3R5bGUuZm9udFNpemUpIGVsU3R5bGUuZm9udFNpemUgPSBjaGlsZFN0eWxlLmZvbnRTaXplOyAvLyBzaXplXHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0Q29tbW9uTGlzdFN0eWxlKGVsLCBjaGlsZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gU3RyaXAgcmVtb3ZlIG5vZGVcclxuICAgICAgICAgKiBAcGFyYW0ge05vZGV9IHJlbW92ZU5vZGUgVGhlIHJlbW92ZSBub2RlXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfc3RyaXBSZW1vdmVOb2RlOiBmdW5jdGlvbiAocmVtb3ZlTm9kZSkge1xyXG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gcmVtb3ZlTm9kZS5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICBpZiAoIXJlbW92ZU5vZGUgfHwgcmVtb3ZlTm9kZS5ub2RlVHlwZSA9PT0gMyB8fCAhZWxlbWVudCkgcmV0dXJuO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgY29uc3QgY2hpbGRyZW4gPSByZW1vdmVOb2RlLmNoaWxkTm9kZXM7XHJcbiAgICAgICAgICAgIHdoaWxlIChjaGlsZHJlblswXSkge1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudC5pbnNlcnRCZWZvcmUoY2hpbGRyZW5bMF0sIHJlbW92ZU5vZGUpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBlbGVtZW50LnJlbW92ZUNoaWxkKHJlbW92ZU5vZGUpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBSZXR1cm4gdGhlIHBhcmVudCBtYWludGFpbmVkIHRhZy4gKGJpbmQgYW5kIHVzZSBhIHV0aWwgb2JqZWN0KVxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBFbGVtZW50XHJcbiAgICAgICAgICogQHJldHVybnMge0VsZW1lbnR9XHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfdXRpbF9nZXRNYWludGFpbmVkTm9kZTogZnVuY3Rpb24gKF9pc1JlbW92ZSwgX2lzU2l6ZU5vZGUsIGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgaWYgKCFlbGVtZW50IHx8IF9pc1JlbW92ZSkgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldFBhcmVudEVsZW1lbnQoZWxlbWVudCwgdGhpcy5faXNNYWludGFpbmVkTm9kZS5iaW5kKHRoaXMpKSB8fCAoIV9pc1NpemVOb2RlID8gdGhpcy5nZXRQYXJlbnRFbGVtZW50KGVsZW1lbnQsIHRoaXMuX2lzU2l6ZU5vZGUuYmluZCh0aGlzKSkgOiBudWxsKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ2hlY2sgaWYgZWxlbWVudCBpcyBhIHRhZyB0aGF0IHNob3VsZCBiZSBwZXJzaXN0ZWQuIChiaW5kIGFuZCB1c2UgYSB1dGlsIG9iamVjdClcclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgRWxlbWVudFxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFbGVtZW50fVxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX3V0aWxfaXNNYWludGFpbmVkTm9kZTogZnVuY3Rpb24gKF9pc1JlbW92ZSwgX2lzU2l6ZU5vZGUsIGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgaWYgKCFlbGVtZW50IHx8IF9pc1JlbW92ZSB8fCBlbGVtZW50Lm5vZGVUeXBlICE9PSAxKSByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIGNvbnN0IGFuY2hvciA9IHRoaXMuX2lzTWFpbnRhaW5lZE5vZGUoZWxlbWVudCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldFBhcmVudEVsZW1lbnQoZWxlbWVudCwgdGhpcy5faXNNYWludGFpbmVkTm9kZS5iaW5kKHRoaXMpKSA/IGFuY2hvciA6IChhbmNob3IgfHwgKCFfaXNTaXplTm9kZSA/IHRoaXMuX2lzU2l6ZU5vZGUoZWxlbWVudCkgOiBmYWxzZSkpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiB3cmFwcyB0ZXh0IG5vZGVzIG9mIGxpbmUgc2VsZWN0ZWQgdGV4dC5cclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgVGhlIG5vZGUgb2YgdGhlIGxpbmUgdGhhdCBjb250YWlucyB0aGUgc2VsZWN0ZWQgdGV4dCBub2RlLlxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gbmV3SW5uZXJOb2RlIFRoZSBkb20gdGhhdCB3aWxsIHdyYXAgdGhlIHNlbGVjdGVkIHRleHQgYXJlYVxyXG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHZhbGlkYXRpb24gQ2hlY2sgaWYgdGhlIG5vZGUgc2hvdWxkIGJlIHN0cmlwcGVkLlxyXG4gICAgICAgICAqIEBwYXJhbSB7Tm9kZX0gc3RhcnRDb24gVGhlIHN0YXJ0Q29udGFpbmVyIHByb3BlcnR5IG9mIHRoZSBzZWxlY3Rpb24gb2JqZWN0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzdGFydE9mZiBUaGUgc3RhcnRPZmZzZXQgcHJvcGVydHkgb2YgdGhlIHNlbGVjdGlvbiBvYmplY3QuXHJcbiAgICAgICAgICogQHBhcmFtIHtOb2RlfSBlbmRDb24gVGhlIGVuZENvbnRhaW5lciBwcm9wZXJ0eSBvZiB0aGUgc2VsZWN0aW9uIG9iamVjdC5cclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gZW5kT2ZmIFRoZSBlbmRPZmZzZXQgcHJvcGVydHkgb2YgdGhlIHNlbGVjdGlvbiBvYmplY3QuXHJcbiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSBpc1JlbW92ZUZvcm1hdCBJcyB0aGUgcmVtb3ZlIGFsbCBmb3JtYXRzIGNvbW1hbmQ/XHJcbiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSBpc1JlbW92ZU5vZGUgXCJuZXdJbm5lck5vZGVcIiBpcyByZW1vdmUgbm9kZT9cclxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGNvbGxhcHNlZCByYW5nZS5jb2xsYXBzZWRcclxuICAgICAgICAgKiBAcmV0dXJucyB7e2FuY2VzdG9yOiAqLCBzdGFydENvbnRhaW5lcjogKiwgc3RhcnRPZmZzZXQ6ICosIGVuZENvbnRhaW5lcjogKiwgZW5kT2Zmc2V0OiAqfX1cclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9ub2RlQ2hhbmdlX29uZUxpbmU6IGZ1bmN0aW9uIChlbGVtZW50LCBuZXdJbm5lck5vZGUsIHZhbGlkYXRpb24sIHN0YXJ0Q29uLCBzdGFydE9mZiwgZW5kQ29uLCBlbmRPZmYsIGlzUmVtb3ZlRm9ybWF0LCBpc1JlbW92ZU5vZGUsIGNvbGxhcHNlZCwgX3JlbW92ZUNoZWNrLCBfZ2V0TWFpbnRhaW5lZE5vZGUsIF9pc01haW50YWluZWROb2RlKSB7XHJcbiAgICAgICAgICAgIC8vIG5vdCBhZGQgdGFnXHJcbiAgICAgICAgICAgIGxldCBwYXJlbnRDb24gPSBzdGFydENvbi5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICB3aGlsZSAoIXBhcmVudENvbi5uZXh0U2libGluZyAmJiAhcGFyZW50Q29uLnByZXZpb3VzU2libGluZyAmJiAhdXRpbC5pc0Zvcm1hdEVsZW1lbnQocGFyZW50Q29uLnBhcmVudE5vZGUpICYmICF1dGlsLmlzV3lzaXd5Z0RpdihwYXJlbnRDb24ucGFyZW50Tm9kZSkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChwYXJlbnRDb24ubm9kZU5hbWUgPT09IG5ld0lubmVyTm9kZS5ub2RlTmFtZSkgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBwYXJlbnRDb24gPSBwYXJlbnRDb24ucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCFpc1JlbW92ZU5vZGUgJiYgcGFyZW50Q29uID09PSBlbmRDb24ucGFyZW50Tm9kZSAmJiBwYXJlbnRDb24ubm9kZU5hbWUgPT09IG5ld0lubmVyTm9kZS5ub2RlTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHV0aWwub25seVplcm9XaWR0aFNwYWNlKHN0YXJ0Q29uLnRleHRDb250ZW50LnNsaWNlKDAsIHN0YXJ0T2ZmKSkgJiYgdXRpbC5vbmx5WmVyb1dpZHRoU3BhY2UoZW5kQ29uLnRleHRDb250ZW50LnNsaWNlKGVuZE9mZikpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBwYXJlbnRDb24uY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgICAgICBsZXQgc2FtZVRhZyA9IHRydWU7XHJcbiAgICBcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gY2hpbGRyZW4ubGVuZ3RoLCBjLCBzLCBlLCB6OyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYyA9IGNoaWxkcmVuW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB6ID0gIXV0aWwub25seVplcm9XaWR0aFNwYWNlKGMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PT0gc3RhcnRDb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT09IGVuZENvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKCFzICYmIHopIHx8IChzICYmIGUgJiYgeikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbWVUYWcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNhbWVUYWcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXRpbC5jb3B5VGFnQXR0cmlidXRlcyhwYXJlbnRDb24sIG5ld0lubmVyTm9kZSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydENvbnRhaW5lcjogc3RhcnRDb24sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydE9mZnNldDogc3RhcnRPZmYsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRDb250YWluZXI6IGVuZENvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZE9mZnNldDogZW5kT2ZmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBhZGQgdGFnXHJcbiAgICAgICAgICAgIF9yZW1vdmVDaGVjay52ID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGNvbnN0IGVsID0gZWxlbWVudDtcclxuICAgICAgICAgICAgY29uc3Qgbk5vZGVBcnJheSA9IFtuZXdJbm5lck5vZGVdO1xyXG4gICAgICAgICAgICBjb25zdCBwTm9kZSA9IGVsZW1lbnQuY2xvbmVOb2RlKGZhbHNlKTtcclxuICAgICAgICAgICAgY29uc3QgaXNTYW1lTm9kZSA9IHN0YXJ0Q29uID09PSBlbmRDb247XHJcbiAgICAgICAgICAgIGxldCBzdGFydENvbnRhaW5lciA9IHN0YXJ0Q29uO1xyXG4gICAgICAgICAgICBsZXQgc3RhcnRPZmZzZXQgPSBzdGFydE9mZjtcclxuICAgICAgICAgICAgbGV0IGVuZENvbnRhaW5lciA9IGVuZENvbjtcclxuICAgICAgICAgICAgbGV0IGVuZE9mZnNldCA9IGVuZE9mZjtcclxuICAgICAgICAgICAgbGV0IHN0YXJ0UGFzcyA9IGZhbHNlO1xyXG4gICAgICAgICAgICBsZXQgZW5kUGFzcyA9IGZhbHNlO1xyXG4gICAgICAgICAgICBsZXQgcEN1cnJlbnQsIG5ld05vZGUsIGFwcGVuZE5vZGUsIGNzc1RleHQsIGFuY2hvck5vZGU7XHJcblxyXG4gICAgICAgICAgICBjb25zdCB3UmVnRXhwID0gX3cuUmVnRXhwO1xyXG4gICAgICAgICAgICBmdW5jdGlvbiBjaGVja0NzcyAodk5vZGUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJlZ0V4cCA9IG5ldyB3UmVnRXhwKCcoPzo7fF58XFxcXHMpKD86JyArIGNzc1RleHQgKyAnbnVsbClcXFxccyo6W147XSpcXFxccyooPzo7fCQpJywgJ2lnJyk7XHJcbiAgICAgICAgICAgICAgICBsZXQgc3R5bGUgPSAnJztcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAocmVnRXhwICYmIHZOb2RlLnN0eWxlLmNzc1RleHQubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlID0gcmVnRXhwLnRlc3Qodk5vZGUuc3R5bGUuY3NzVGV4dCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICFzdHlsZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgKGZ1bmN0aW9uIHJlY3Vyc2lvbkZ1bmMoY3VycmVudCwgYW5jZXN0b3IpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkTm9kZXMgPSBjdXJyZW50LmNoaWxkTm9kZXM7XHJcblxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNoaWxkTm9kZXMubGVuZ3RoLCB2Tm9kZTsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNoaWxkID0gY2hpbGROb2Rlc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWNoaWxkKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgY292ZXJOb2RlID0gYW5jZXN0b3I7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNsb25lTm9kZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gc3RhcnRDb250YWluZXJcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXN0YXJ0UGFzcyAmJiBjaGlsZCA9PT0gc3RhcnRDb250YWluZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGxpbmUgPSBwTm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yTm9kZSA9IF9nZXRNYWludGFpbmVkTm9kZShjaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZXZOb2RlID0gdXRpbC5jcmVhdGVUZXh0Tm9kZShzdGFydENvbnRhaW5lci5ub2RlVHlwZSA9PT0gMSA/ICcnIDogc3RhcnRDb250YWluZXIuc3Vic3RyaW5nRGF0YSgwLCBzdGFydE9mZnNldCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXh0Tm9kZSA9IHV0aWwuY3JlYXRlVGV4dE5vZGUoc3RhcnRDb250YWluZXIubm9kZVR5cGUgPT09IDEgPyAnJyA6IHN0YXJ0Q29udGFpbmVyLnN1YnN0cmluZ0RhdGEoc3RhcnRPZmZzZXQsIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzU2FtZU5vZGUgPyBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZW5kT2Zmc2V0ID49IHN0YXJ0T2Zmc2V0ID8gZW5kT2Zmc2V0IC0gc3RhcnRPZmZzZXQgOiBzdGFydENvbnRhaW5lci5kYXRhLmxlbmd0aCAtIHN0YXJ0T2Zmc2V0KSA6IFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0Q29udGFpbmVyLmRhdGEubGVuZ3RoIC0gc3RhcnRPZmZzZXQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFuY2hvck5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGEgPSBfZ2V0TWFpbnRhaW5lZE5vZGUoYW5jZXN0b3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGEgJiYgYS5wYXJlbnROb2RlICE9PSBsaW5lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG0gPSBhO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBwID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAobS5wYXJlbnROb2RlICE9PSBsaW5lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yID0gcCA9IG0ucGFyZW50Tm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZShtLmNoaWxkTm9kZXNbMF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAuYXBwZW5kQ2hpbGQobS5jaGlsZE5vZGVzWzBdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtLmFwcGVuZENoaWxkKHApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtID0gbS5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoYSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JOb2RlID0gYW5jaG9yTm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXV0aWwub25seVplcm9XaWR0aFNwYWNlKHByZXZOb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3IuYXBwZW5kQ2hpbGQocHJldk5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmV2QW5jaG9yTm9kZSA9IF9nZXRNYWludGFpbmVkTm9kZShhbmNlc3Rvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXByZXZBbmNob3JOb2RlKSBhbmNob3JOb2RlID0gcHJldkFuY2hvck5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhbmNob3JOb2RlKSBsaW5lID0gYW5jaG9yTm9kZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBjaGlsZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcEN1cnJlbnQgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzVGV4dCA9ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAobmV3Tm9kZSAhPT0gbGluZSAmJiBuZXdOb2RlICE9PSBlbCAmJiBuZXdOb2RlICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2Tm9kZSA9IF9pc01haW50YWluZWROb2RlKG5ld05vZGUpID8gbnVsbCA6IHZhbGlkYXRpb24obmV3Tm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodk5vZGUgJiYgbmV3Tm9kZS5ub2RlVHlwZSA9PT0gMSAmJiBjaGVja0NzcyhuZXdOb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBDdXJyZW50LnB1c2godk5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1RleHQgKz0gbmV3Tm9kZS5zdHlsZS5jc3NUZXh0LnN1YnN0cigwLCBuZXdOb2RlLnN0eWxlLmNzc1RleHQuaW5kZXhPZignOicpKSArICd8JztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBuZXdOb2RlLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkTm9kZSA9IHBDdXJyZW50LnBvcCgpIHx8IHRleHROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmROb2RlID0gbmV3Tm9kZSA9IGNoaWxkTm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHBDdXJyZW50Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBwQ3VycmVudC5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZE5vZGUuYXBwZW5kQ2hpbGQobmV3Tm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmROb2RlID0gbmV3Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3SW5uZXJOb2RlLmFwcGVuZENoaWxkKGNoaWxkTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUuYXBwZW5kQ2hpbGQobmV3SW5uZXJOb2RlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhbmNob3JOb2RlICYmICFfZ2V0TWFpbnRhaW5lZE5vZGUoZW5kQ29udGFpbmVyKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3SW5uZXJOb2RlID0gbmV3SW5uZXJOb2RlLmNsb25lTm9kZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTm9kZS5hcHBlbmRDaGlsZChuZXdJbm5lck5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbk5vZGVBcnJheS5wdXNoKG5ld0lubmVyTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0Q29udGFpbmVyID0gdGV4dE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0T2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRQYXNzID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdOb2RlICE9PSB0ZXh0Tm9kZSkgbmV3Tm9kZS5hcHBlbmRDaGlsZChzdGFydENvbnRhaW5lcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNTYW1lTm9kZSkgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBlbmRDb250YWluZXJcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWVuZFBhc3MgJiYgY2hpbGQgPT09IGVuZENvbnRhaW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JOb2RlID0gX2dldE1haW50YWluZWROb2RlKGNoaWxkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWZ0ZXJOb2RlID0gdXRpbC5jcmVhdGVUZXh0Tm9kZShlbmRDb250YWluZXIubm9kZVR5cGUgPT09IDEgPyAnJyA6IGVuZENvbnRhaW5lci5zdWJzdHJpbmdEYXRhKGVuZE9mZnNldCwgKGVuZENvbnRhaW5lci5sZW5ndGggLSBlbmRPZmZzZXQpKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRleHROb2RlID0gdXRpbC5jcmVhdGVUZXh0Tm9kZShpc1NhbWVOb2RlIHx8IGVuZENvbnRhaW5lci5ub2RlVHlwZSA9PT0gMSA/ICcnIDogZW5kQ29udGFpbmVyLnN1YnN0cmluZ0RhdGEoMCwgZW5kT2Zmc2V0KSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW5jaG9yTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yTm9kZSA9IGFuY2hvck5vZGUuY2xvbmVOb2RlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChfaXNNYWludGFpbmVkTm9kZShuZXdJbm5lck5vZGUucGFyZW50Tm9kZSkgJiYgIWFuY2hvck5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0lubmVyTm9kZSA9IG5ld0lubmVyTm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5vZGUuYXBwZW5kQ2hpbGQobmV3SW5uZXJOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5Ob2RlQXJyYXkucHVzaChuZXdJbm5lck5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXV0aWwub25seVplcm9XaWR0aFNwYWNlKGFmdGVyTm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBjaGlsZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1RleHQgPSAnJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBDdXJyZW50ID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhbmNob3JzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAobmV3Tm9kZSAhPT0gcE5vZGUgJiYgbmV3Tm9kZSAhPT0gZWwgJiYgbmV3Tm9kZSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdOb2RlLm5vZGVUeXBlID09PSAxICYmIGNoZWNrQ3NzKG5ld05vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNNYWludGFpbmVkTm9kZShuZXdOb2RlKSkgYW5jaG9ycy5wdXNoKG5ld05vZGUuY2xvbmVOb2RlKGZhbHNlKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgcEN1cnJlbnQucHVzaChuZXdOb2RlLmNsb25lTm9kZShmYWxzZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3NUZXh0ICs9IG5ld05vZGUuc3R5bGUuY3NzVGV4dC5zdWJzdHIoMCwgbmV3Tm9kZS5zdHlsZS5jc3NUZXh0LmluZGV4T2YoJzonKSkgKyAnfCc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBuZXdOb2RlLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQ3VycmVudCA9IHBDdXJyZW50LmNvbmNhdChhbmNob3JzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9uZU5vZGUgPSBhcHBlbmROb2RlID0gbmV3Tm9kZSA9IHBDdXJyZW50LnBvcCgpIHx8IGFmdGVyTm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChwQ3VycmVudC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZSA9IHBDdXJyZW50LnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZE5vZGUuYXBwZW5kQ2hpbGQobmV3Tm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kTm9kZSA9IG5ld05vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5vZGUuYXBwZW5kQ2hpbGQoY2xvbmVOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUudGV4dENvbnRlbnQgPSBhZnRlck5vZGUuZGF0YTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFuY2hvck5vZGUgJiYgY2xvbmVOb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhZnRlckFuY2hvck5vZGUgPSBfZ2V0TWFpbnRhaW5lZE5vZGUoY2xvbmVOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhZnRlckFuY2hvck5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JOb2RlID0gYWZ0ZXJBbmNob3JOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdOb2RlID0gY2hpbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBDdXJyZW50ID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1RleHQgPSAnJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKG5ld05vZGUgIT09IHBOb2RlICYmIG5ld05vZGUgIT09IGVsICYmIG5ld05vZGUgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZOb2RlID0gX2lzTWFpbnRhaW5lZE5vZGUobmV3Tm9kZSkgPyBudWxsIDogdmFsaWRhdGlvbihuZXdOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2Tm9kZSAmJiBuZXdOb2RlLm5vZGVUeXBlID09PSAxICYmIGNoZWNrQ3NzKG5ld05vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEN1cnJlbnQucHVzaCh2Tm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NzVGV4dCArPSBuZXdOb2RlLnN0eWxlLmNzc1RleHQuc3Vic3RyKDAsIG5ld05vZGUuc3R5bGUuY3NzVGV4dC5pbmRleE9mKCc6JykpICsgJ3wnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZSA9IG5ld05vZGUucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hpbGROb2RlID0gcEN1cnJlbnQucG9wKCkgfHwgdGV4dE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZE5vZGUgPSBuZXdOb2RlID0gY2hpbGROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocEN1cnJlbnQubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZSA9IHBDdXJyZW50LnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kTm9kZS5hcHBlbmRDaGlsZChuZXdOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZE5vZGUgPSBuZXdOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW5jaG9yTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3SW5uZXJOb2RlID0gbmV3SW5uZXJOb2RlLmNsb25lTm9kZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdJbm5lck5vZGUuYXBwZW5kQ2hpbGQoY2hpbGROb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvck5vZGUuaW5zZXJ0QmVmb3JlKG5ld0lubmVyTm9kZSwgYW5jaG9yTm9kZS5maXJzdENoaWxkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOb2RlLmFwcGVuZENoaWxkKGFuY2hvck5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbk5vZGVBcnJheS5wdXNoKG5ld0lubmVyTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JOb2RlID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0lubmVyTm9kZS5hcHBlbmRDaGlsZChjaGlsZE5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmRDb250YWluZXIgPSB0ZXh0Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZW5kT2Zmc2V0ID0gdGV4dE5vZGUuZGF0YS5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuZFBhc3MgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1JlbW92ZUZvcm1hdCAmJiBjb2xsYXBzZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0lubmVyTm9kZSA9IHRleHROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dE5vZGUudGV4dENvbnRlbnQgPSB1dGlsLnplcm9XaWR0aFNwYWNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3Tm9kZSAhPT0gdGV4dE5vZGUpIG5ld05vZGUuYXBwZW5kQ2hpbGQoZW5kQ29udGFpbmVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBvdGhlclxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGFydFBhc3MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlID09PSAxICYmICF1dGlsLmlzQnJlYWsoY2hpbGQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5faXNJZ25vcmVOb2RlQ2hhbmdlKGNoaWxkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOb2RlLmFwcGVuZENoaWxkKGNoaWxkLmNsb25lTm9kZSh0cnVlKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjb2xsYXBzZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3SW5uZXJOb2RlID0gbmV3SW5uZXJOb2RlLmNsb25lTm9kZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOb2RlLmFwcGVuZENoaWxkKG5ld0lubmVyTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5Ob2RlQXJyYXkucHVzaChuZXdJbm5lck5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjdXJzaW9uRnVuYyhjaGlsZCwgY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBjaGlsZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcEN1cnJlbnQgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzVGV4dCA9ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhbmNob3JzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChuZXdOb2RlLnBhcmVudE5vZGUgIT09IG51bGwgJiYgbmV3Tm9kZSAhPT0gZWwgJiYgbmV3Tm9kZSAhPT0gbmV3SW5uZXJOb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2Tm9kZSA9IGVuZFBhc3MgPyBuZXdOb2RlLmNsb25lTm9kZShmYWxzZSkgOiB2YWxpZGF0aW9uKG5ld05vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld05vZGUubm9kZVR5cGUgPT09IDEgJiYgIXV0aWwuaXNCcmVhayhjaGlsZCkgJiYgdk5vZGUgJiYgY2hlY2tDc3MobmV3Tm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzTWFpbnRhaW5lZE5vZGUobmV3Tm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhbmNob3JOb2RlKSBhbmNob3JzLnB1c2godk5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBDdXJyZW50LnB1c2godk5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3NUZXh0ICs9IG5ld05vZGUuc3R5bGUuY3NzVGV4dC5zdWJzdHIoMCwgbmV3Tm9kZS5zdHlsZS5jc3NUZXh0LmluZGV4T2YoJzonKSkgKyAnfCc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdOb2RlID0gbmV3Tm9kZS5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBDdXJyZW50ID0gcEN1cnJlbnQuY29uY2F0KGFuY2hvcnMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hpbGROb2RlID0gcEN1cnJlbnQucG9wKCkgfHwgY2hpbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZE5vZGUgPSBuZXdOb2RlID0gY2hpbGROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocEN1cnJlbnQubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZSA9IHBDdXJyZW50LnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kTm9kZS5hcHBlbmRDaGlsZChuZXdOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZE5vZGUgPSBuZXdOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzTWFpbnRhaW5lZE5vZGUobmV3SW5uZXJOb2RlLnBhcmVudE5vZGUpICYmICFfaXNNYWludGFpbmVkTm9kZShjaGlsZE5vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdJbm5lck5vZGUgPSBuZXdJbm5lck5vZGUuY2xvbmVOb2RlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOb2RlLmFwcGVuZENoaWxkKG5ld0lubmVyTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuTm9kZUFycmF5LnB1c2gobmV3SW5uZXJOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFlbmRQYXNzICYmICFhbmNob3JOb2RlICYmIF9pc01haW50YWluZWROb2RlKGNoaWxkTm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0lubmVyTm9kZSA9IG5ld0lubmVyTm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYUNoaWxkcmVuID0gY2hpbGROb2RlLmNoaWxkTm9kZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBhID0gMCwgYUxlbiA9IGFDaGlsZHJlbi5sZW5ndGg7IGEgPCBhTGVuOyBhKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdJbm5lck5vZGUuYXBwZW5kQ2hpbGQoYUNoaWxkcmVuW2FdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkTm9kZS5hcHBlbmRDaGlsZChuZXdJbm5lck5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5vZGUuYXBwZW5kQ2hpbGQoY2hpbGROb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5Ob2RlQXJyYXkucHVzaChuZXdJbm5lck5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0lubmVyTm9kZS5jaGlsZHJlbi5sZW5ndGggPiAwKSBhbmNlc3RvciA9IG5ld05vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGFuY2VzdG9yID0gbmV3SW5uZXJOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoaWxkTm9kZSA9PT0gY2hpbGQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZW5kUGFzcykgYW5jZXN0b3IgPSBuZXdJbm5lck5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGFuY2VzdG9yID0gcE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZW5kUGFzcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5vZGUuYXBwZW5kQ2hpbGQoY2hpbGROb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yID0gbmV3Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0lubmVyTm9kZS5hcHBlbmRDaGlsZChjaGlsZE5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3IgPSBuZXdOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW5jaG9yTm9kZSAmJiBjaGlsZC5ub2RlVHlwZSA9PT0gMykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9nZXRNYWludGFpbmVkTm9kZShjaGlsZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhbmNlc3RvckFuY2hvck5vZGUgPSB1dGlsLmdldFBhcmVudEVsZW1lbnQoYW5jZXN0b3IsIGZ1bmN0aW9uIChjdXJyZW50KSB7cmV0dXJuIHRoaXMuX2lzTWFpbnRhaW5lZE5vZGUoY3VycmVudC5wYXJlbnROb2RlKSB8fCBjdXJyZW50LnBhcmVudE5vZGUgPT09IHBOb2RlO30uYmluZCh1dGlsKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yTm9kZS5hcHBlbmRDaGlsZChhbmNlc3RvckFuY2hvck5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0lubmVyTm9kZSA9IGFuY2VzdG9yQW5jaG9yTm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5Ob2RlQXJyYXkucHVzaChuZXdJbm5lck5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOb2RlLmFwcGVuZENoaWxkKG5ld0lubmVyTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvck5vZGUgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBjbG9uZU5vZGUgPSBjaGlsZC5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yLmFwcGVuZENoaWxkKGNsb25lTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlID09PSAxICYmICF1dGlsLmlzQnJlYWsoY2hpbGQpKSBjb3Zlck5vZGUgPSBjbG9uZU5vZGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJlY3Vyc2lvbkZ1bmMoY2hpbGQsIGNvdmVyTm9kZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pKGVsZW1lbnQsIHBOb2RlKTtcclxuXHJcbiAgICAgICAgICAgIC8vIG5vdCByZW1vdmUgdGFnXHJcbiAgICAgICAgICAgIGlmIChpc1JlbW92ZU5vZGUgJiYgIWlzUmVtb3ZlRm9ybWF0ICYmICFfcmVtb3ZlQ2hlY2sudikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICBhbmNlc3RvcjogZWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICBzdGFydENvbnRhaW5lcjogc3RhcnRDb24sXHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRPZmZzZXQ6IHN0YXJ0T2ZmLFxyXG4gICAgICAgICAgICAgICAgICAgIGVuZENvbnRhaW5lcjogZW5kQ29uLFxyXG4gICAgICAgICAgICAgICAgICAgIGVuZE9mZnNldDogZW5kT2ZmXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpc1JlbW92ZUZvcm1hdCA9IGlzUmVtb3ZlRm9ybWF0ICYmIGlzUmVtb3ZlTm9kZTtcclxuXHJcbiAgICAgICAgICAgIGlmIChpc1JlbW92ZUZvcm1hdCkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuTm9kZUFycmF5Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlbW92ZU5vZGUgPSBuTm9kZUFycmF5W2ldO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCB0ZXh0Tm9kZSwgdGV4dE5vZGVfcywgdGV4dE5vZGVfZTtcclxuICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY29sbGFwc2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHROb2RlID0gdXRpbC5jcmVhdGVUZXh0Tm9kZSh1dGlsLnplcm9XaWR0aFNwYWNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcE5vZGUucmVwbGFjZUNoaWxkKHRleHROb2RlLCByZW1vdmVOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByQ2hpbGRyZW4gPSByZW1vdmVOb2RlLmNoaWxkTm9kZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHROb2RlX3MgPSByQ2hpbGRyZW5bMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChyQ2hpbGRyZW5bMF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHROb2RlX2UgPSByQ2hpbGRyZW5bMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTm9kZS5pbnNlcnRCZWZvcmUodGV4dE5vZGVfZSwgcmVtb3ZlTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVJdGVtKHJlbW92ZU5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbGxhcHNlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRDb250YWluZXIgPSBlbmRDb250YWluZXIgPSB0ZXh0Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0Q29udGFpbmVyID0gdGV4dE5vZGVfcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZENvbnRhaW5lciA9IHRleHROb2RlX2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaXNSZW1vdmVOb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuTm9kZUFycmF5Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0cmlwUmVtb3ZlTm9kZShuTm9kZUFycmF5W2ldKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIGlmIChjb2xsYXBzZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBzdGFydENvbnRhaW5lciA9IGVuZENvbnRhaW5lciA9IG5ld0lubmVyTm9kZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdXRpbC5yZW1vdmVFbXB0eU5vZGUocE5vZGUsIG5ld0lubmVyTm9kZSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoY29sbGFwc2VkKSB7XHJcbiAgICAgICAgICAgICAgICBzdGFydE9mZnNldCA9IHN0YXJ0Q29udGFpbmVyLnRleHRDb250ZW50Lmxlbmd0aDtcclxuICAgICAgICAgICAgICAgIGVuZE9mZnNldCA9IGVuZENvbnRhaW5lci50ZXh0Q29udGVudC5sZW5ndGg7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGVuZENvbnRhaW5lciByZXNldFxyXG4gICAgICAgICAgICBjb25zdCBlbmRDb25SZXNldCA9IGlzUmVtb3ZlRm9ybWF0IHx8IGVuZENvbnRhaW5lci50ZXh0Q29udGVudC5sZW5ndGggPT09IDA7XHJcblxyXG4gICAgICAgICAgICBpZiAoIXV0aWwuaXNCcmVhayhlbmRDb250YWluZXIpICYmIGVuZENvbnRhaW5lci50ZXh0Q29udGVudC5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlSXRlbShlbmRDb250YWluZXIpO1xyXG4gICAgICAgICAgICAgICAgZW5kQ29udGFpbmVyID0gc3RhcnRDb250YWluZXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZW5kT2Zmc2V0ID0gZW5kQ29uUmVzZXQgPyBlbmRDb250YWluZXIudGV4dENvbnRlbnQubGVuZ3RoIDogZW5kT2Zmc2V0O1xyXG5cclxuICAgICAgICAgICAgLy8gbm9kZSBjaGFuZ2VcclxuICAgICAgICAgICAgY29uc3QgbmV3U3RhcnRPZmZzZXQgPSB7czogMCwgZTogMH07XHJcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0UGF0aCA9IHV0aWwuZ2V0Tm9kZVBhdGgoc3RhcnRDb250YWluZXIsIHBOb2RlLCBuZXdTdGFydE9mZnNldCk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBtZXJnZUVuZENvbiA9ICFlbmRDb250YWluZXIucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgaWYgKG1lcmdlRW5kQ29uKSBlbmRDb250YWluZXIgPSBzdGFydENvbnRhaW5lcjtcclxuICAgICAgICAgICAgY29uc3QgbmV3RW5kT2Zmc2V0ID0ge3M6IDAsIGU6IDB9O1xyXG4gICAgICAgICAgICBjb25zdCBlbmRQYXRoID0gdXRpbC5nZXROb2RlUGF0aChlbmRDb250YWluZXIgLCBwTm9kZSwgKCFtZXJnZUVuZENvbiAmJiAhZW5kQ29uUmVzZXQpID8gbmV3RW5kT2Zmc2V0IDogbnVsbCk7XHJcblxyXG4gICAgICAgICAgICBzdGFydE9mZnNldCArPSBuZXdTdGFydE9mZnNldC5zO1xyXG4gICAgICAgICAgICBlbmRPZmZzZXQgPSAoY29sbGFwc2VkID8gc3RhcnRPZmZzZXQgOiBtZXJnZUVuZENvbiA/IHN0YXJ0Q29udGFpbmVyLnRleHRDb250ZW50Lmxlbmd0aCA6IGVuZENvblJlc2V0ID8gZW5kT2Zmc2V0ICsgbmV3U3RhcnRPZmZzZXQucyA6IGVuZE9mZnNldCArIG5ld0VuZE9mZnNldC5zKTtcclxuXHJcbiAgICAgICAgICAgIC8vIHRhZyBtZXJnZVxyXG4gICAgICAgICAgICBjb25zdCBuZXdPZmZzZXRzID0gdXRpbC5tZXJnZVNhbWVUYWdzKHBOb2RlLCBbc3RhcnRQYXRoLCBlbmRQYXRoXSwgdHJ1ZSk7XHJcblxyXG4gICAgICAgICAgICBlbGVtZW50LnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKHBOb2RlLCBlbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgIHN0YXJ0Q29udGFpbmVyID0gdXRpbC5nZXROb2RlRnJvbVBhdGgoc3RhcnRQYXRoLCBwTm9kZSk7XHJcbiAgICAgICAgICAgIGVuZENvbnRhaW5lciA9IHV0aWwuZ2V0Tm9kZUZyb21QYXRoKGVuZFBhdGgsIHBOb2RlKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBhbmNlc3RvcjogcE5vZGUsXHJcbiAgICAgICAgICAgICAgICBzdGFydENvbnRhaW5lcjogc3RhcnRDb250YWluZXIsXHJcbiAgICAgICAgICAgICAgICBzdGFydE9mZnNldDogc3RhcnRPZmZzZXQgKyBuZXdPZmZzZXRzWzBdLFxyXG4gICAgICAgICAgICAgICAgZW5kQ29udGFpbmVyOiBlbmRDb250YWluZXIsXHJcbiAgICAgICAgICAgICAgICBlbmRPZmZzZXQ6IGVuZE9mZnNldCArIG5ld09mZnNldHNbMV1cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gd3JhcHMgZmlyc3QgbGluZSBzZWxlY3RlZCB0ZXh0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBUaGUgbm9kZSBvZiB0aGUgbGluZSB0aGF0IGNvbnRhaW5zIHRoZSBzZWxlY3RlZCB0ZXh0IG5vZGUuXHJcbiAgICAgICAgICogQHBhcmFtIHtFbGVtZW50fSBuZXdJbm5lck5vZGUgVGhlIGRvbSB0aGF0IHdpbGwgd3JhcCB0aGUgc2VsZWN0ZWQgdGV4dCBhcmVhXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gdmFsaWRhdGlvbiBDaGVjayBpZiB0aGUgbm9kZSBzaG91bGQgYmUgc3RyaXBwZWQuXHJcbiAgICAgICAgICogQHBhcmFtIHtOb2RlfSBzdGFydENvbiBUaGUgc3RhcnRDb250YWluZXIgcHJvcGVydHkgb2YgdGhlIHNlbGVjdGlvbiBvYmplY3QuXHJcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IHN0YXJ0T2ZmIFRoZSBzdGFydE9mZnNldCBwcm9wZXJ0eSBvZiB0aGUgc2VsZWN0aW9uIG9iamVjdC5cclxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzUmVtb3ZlRm9ybWF0IElzIHRoZSByZW1vdmUgYWxsIGZvcm1hdHMgY29tbWFuZD9cclxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzUmVtb3ZlTm9kZSBcIm5ld0lubmVyTm9kZVwiIGlzIHJlbW92ZSBub2RlP1xyXG4gICAgICAgICAqIEByZXR1cm5zIHtudWxsfE5vZGV9IElmIGVuZCBjb250YWluZXIgaXMgcmVuZXdlZCwgcmV0dXJuZWQgcmVuZXdlZCBub2RlXHJcbiAgICAgICAgICogQHJldHVybnMge09iamVjdH0geyBhbmNlc3RvciwgY29udGFpbmVyLCBvZmZzZXQsIGVuZENvbnRhaW5lciB9XHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfbm9kZUNoYW5nZV9zdGFydExpbmU6IGZ1bmN0aW9uIChlbGVtZW50LCBuZXdJbm5lck5vZGUsIHZhbGlkYXRpb24sIHN0YXJ0Q29uLCBzdGFydE9mZiwgaXNSZW1vdmVGb3JtYXQsIGlzUmVtb3ZlTm9kZSwgX3JlbW92ZUNoZWNrLCBfZ2V0TWFpbnRhaW5lZE5vZGUsIF9pc01haW50YWluZWROb2RlLCBfZW5kQ29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgIC8vIG5vdCBhZGQgdGFnXHJcbiAgICAgICAgICAgIGxldCBwYXJlbnRDb24gPSBzdGFydENvbi5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICB3aGlsZSAoIXBhcmVudENvbi5uZXh0U2libGluZyAmJiAhcGFyZW50Q29uLnByZXZpb3VzU2libGluZyAmJiAhdXRpbC5pc0Zvcm1hdEVsZW1lbnQocGFyZW50Q29uLnBhcmVudE5vZGUpICYmICF1dGlsLmlzV3lzaXd5Z0RpdihwYXJlbnRDb24ucGFyZW50Tm9kZSkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChwYXJlbnRDb24ubm9kZU5hbWUgPT09IG5ld0lubmVyTm9kZS5ub2RlTmFtZSkgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBwYXJlbnRDb24gPSBwYXJlbnRDb24ucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCFpc1JlbW92ZU5vZGUgJiYgcGFyZW50Q29uLm5vZGVOYW1lID09PSBuZXdJbm5lck5vZGUubm9kZU5hbWUgJiYgIXV0aWwuaXNGb3JtYXRFbGVtZW50KHBhcmVudENvbikgJiYgIXBhcmVudENvbi5uZXh0U2libGluZyAmJiB1dGlsLm9ubHlaZXJvV2lkdGhTcGFjZShzdGFydENvbi50ZXh0Q29udGVudC5zbGljZSgwLCBzdGFydE9mZikpKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgc2FtZVRhZyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBsZXQgcyA9IHN0YXJ0Q29uLnByZXZpb3VzU2libGluZztcclxuICAgICAgICAgICAgICAgIHdoaWxlIChzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF1dGlsLm9ubHlaZXJvV2lkdGhTcGFjZShzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzYW1lVGFnID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBzID0gcy5wcmV2aW91c1NpYmxpbmc7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHNhbWVUYWcpIHtcclxuICAgICAgICAgICAgICAgICAgICB1dGlsLmNvcHlUYWdBdHRyaWJ1dGVzKHBhcmVudENvbiwgbmV3SW5uZXJOb2RlKTtcclxuICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yOiBlbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXI6IHN0YXJ0Q29uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IHN0YXJ0T2ZmXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gYWRkIHRhZ1xyXG4gICAgICAgICAgICBfcmVtb3ZlQ2hlY2sudiA9IGZhbHNlO1xyXG4gICAgICAgICAgICBjb25zdCBlbCA9IGVsZW1lbnQ7XHJcbiAgICAgICAgICAgIGNvbnN0IG5Ob2RlQXJyYXkgPSBbbmV3SW5uZXJOb2RlXTtcclxuICAgICAgICAgICAgY29uc3QgcE5vZGUgPSBlbGVtZW50LmNsb25lTm9kZShmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICBsZXQgY29udGFpbmVyID0gc3RhcnRDb247XHJcbiAgICAgICAgICAgIGxldCBvZmZzZXQgPSBzdGFydE9mZjtcclxuICAgICAgICAgICAgbGV0IHBhc3NOb2RlID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGxldCBwQ3VycmVudCwgbmV3Tm9kZSwgYXBwZW5kTm9kZSwgYW5jaG9yTm9kZTtcclxuXHJcbiAgICAgICAgICAgIChmdW5jdGlvbiByZWN1cnNpb25GdW5jKGN1cnJlbnQsIGFuY2VzdG9yKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZE5vZGVzID0gY3VycmVudC5jaGlsZE5vZGVzO1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBjaGlsZE5vZGVzLmxlbmd0aCwgdk5vZGUsIGNsb25lQ2hpbGQ7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkID0gY2hpbGROb2Rlc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWNoaWxkKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgY292ZXJOb2RlID0gYW5jZXN0b3I7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXNzTm9kZSAmJiAhdXRpbC5pc0JyZWFrKGNoaWxkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQubm9kZVR5cGUgPT09IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1dGlsLl9pc0lnbm9yZU5vZGVDaGFuZ2UoY2hpbGQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3SW5uZXJOb2RlID0gbmV3SW5uZXJOb2RlLmNsb25lTm9kZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvbmVDaGlsZCA9IGNoaWxkLmNsb25lTm9kZSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTm9kZS5hcHBlbmRDaGlsZChjbG9uZUNoaWxkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTm9kZS5hcHBlbmRDaGlsZChuZXdJbm5lck5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5Ob2RlQXJyYXkucHVzaChuZXdJbm5lck5vZGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlbmQgY29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9lbmRDb250YWluZXIgJiYgY2hpbGQuY29udGFpbnMoX2VuZENvbnRhaW5lcikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5kUGF0aCA9IHV0aWwuZ2V0Tm9kZVBhdGgoX2VuZENvbnRhaW5lciwgY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZW5kQ29udGFpbmVyID0gdXRpbC5nZXROb2RlRnJvbVBhdGgoZW5kUGF0aCwgY2xvbmVDaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWN1cnNpb25GdW5jKGNoaWxkLCBjaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZSA9IGNoaWxkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwQ3VycmVudCA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhbmNob3JzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChuZXdOb2RlLnBhcmVudE5vZGUgIT09IG51bGwgJiYgbmV3Tm9kZSAhPT0gZWwgJiYgbmV3Tm9kZSAhPT0gbmV3SW5uZXJOb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2Tm9kZSA9IHZhbGlkYXRpb24obmV3Tm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3Tm9kZS5ub2RlVHlwZSA9PT0gMSAmJiB2Tm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNNYWludGFpbmVkTm9kZShuZXdOb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFuY2hvck5vZGUpIGFuY2hvcnMucHVzaCh2Tm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEN1cnJlbnQucHVzaCh2Tm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZSA9IG5ld05vZGUucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwQ3VycmVudCA9IHBDdXJyZW50LmNvbmNhdChhbmNob3JzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlzVG9wTm9kZSA9IHBDdXJyZW50Lmxlbmd0aCA+IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkTm9kZSA9IHBDdXJyZW50LnBvcCgpIHx8IGNoaWxkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmROb2RlID0gbmV3Tm9kZSA9IGNoaWxkTm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHBDdXJyZW50Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBwQ3VycmVudC5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZE5vZGUuYXBwZW5kQ2hpbGQobmV3Tm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmROb2RlID0gbmV3Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc01haW50YWluZWROb2RlKG5ld0lubmVyTm9kZS5wYXJlbnROb2RlKSAmJiAhX2lzTWFpbnRhaW5lZE5vZGUoY2hpbGROb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3SW5uZXJOb2RlID0gbmV3SW5uZXJOb2RlLmNsb25lTm9kZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTm9kZS5hcHBlbmRDaGlsZChuZXdJbm5lck5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbk5vZGVBcnJheS5wdXNoKG5ld0lubmVyTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYW5jaG9yTm9kZSAmJiBfaXNNYWludGFpbmVkTm9kZShjaGlsZE5vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdJbm5lck5vZGUgPSBuZXdJbm5lck5vZGUuY2xvbmVOb2RlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFDaGlsZHJlbiA9IGNoaWxkTm9kZS5jaGlsZE5vZGVzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgYSA9IDAsIGFMZW4gPSBhQ2hpbGRyZW4ubGVuZ3RoOyBhIDwgYUxlbjsgYSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3SW5uZXJOb2RlLmFwcGVuZENoaWxkKGFDaGlsZHJlblthXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZE5vZGUuYXBwZW5kQ2hpbGQobmV3SW5uZXJOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOb2RlLmFwcGVuZENoaWxkKGNoaWxkTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNlc3RvciA9ICFfaXNNYWludGFpbmVkTm9kZShuZXdOb2RlKSA/IG5ld05vZGUgOiBuZXdJbm5lck5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuTm9kZUFycmF5LnB1c2gobmV3SW5uZXJOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc1RvcE5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0lubmVyTm9kZS5hcHBlbmRDaGlsZChjaGlsZE5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3IgPSBuZXdOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3IgPSBuZXdJbm5lck5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhbmNob3JOb2RlICYmIGNoaWxkLm5vZGVUeXBlID09PSAzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2dldE1haW50YWluZWROb2RlKGNoaWxkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFuY2VzdG9yQW5jaG9yTm9kZSA9IHV0aWwuZ2V0UGFyZW50RWxlbWVudChhbmNlc3RvciwgZnVuY3Rpb24gKGN1cnJlbnQpIHtyZXR1cm4gdGhpcy5faXNNYWludGFpbmVkTm9kZShjdXJyZW50LnBhcmVudE5vZGUpIHx8IGN1cnJlbnQucGFyZW50Tm9kZSA9PT0gcE5vZGU7fS5iaW5kKHV0aWwpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JOb2RlLmFwcGVuZENoaWxkKGFuY2VzdG9yQW5jaG9yTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3SW5uZXJOb2RlID0gYW5jZXN0b3JBbmNob3JOb2RlLmNsb25lTm9kZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbk5vZGVBcnJheS5wdXNoKG5ld0lubmVyTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5vZGUuYXBwZW5kQ2hpbGQobmV3SW5uZXJOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yTm9kZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHN0YXJ0Q29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFwYXNzTm9kZSAmJiBjaGlsZCA9PT0gY29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBsaW5lID0gcE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvck5vZGUgPSBfZ2V0TWFpbnRhaW5lZE5vZGUoY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmV2Tm9kZSA9IHV0aWwuY3JlYXRlVGV4dE5vZGUoY29udGFpbmVyLm5vZGVUeXBlID09PSAxID8gJycgOiBjb250YWluZXIuc3Vic3RyaW5nRGF0YSgwLCBvZmZzZXQpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGV4dE5vZGUgPSB1dGlsLmNyZWF0ZVRleHROb2RlKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gMSA/ICcnIDogY29udGFpbmVyLnN1YnN0cmluZ0RhdGEob2Zmc2V0LCAoY29udGFpbmVyLmxlbmd0aCAtIG9mZnNldCkpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhbmNob3JOb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhID0gX2dldE1haW50YWluZWROb2RlKGFuY2VzdG9yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhICYmIGEucGFyZW50Tm9kZSAhPT0gbGluZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBtID0gYTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKG0ucGFyZW50Tm9kZSAhPT0gbGluZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNlc3RvciA9IHAgPSBtLnBhcmVudE5vZGUuY2xvbmVOb2RlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUobS5jaGlsZE5vZGVzWzBdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLmFwcGVuZENoaWxkKG0uY2hpbGROb2Rlc1swXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbS5hcHBlbmRDaGlsZChwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbSA9IG0ucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbS5wYXJlbnROb2RlLmFwcGVuZENoaWxkKGEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yTm9kZSA9IGFuY2hvck5vZGUuY2xvbmVOb2RlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF1dGlsLm9ubHlaZXJvV2lkdGhTcGFjZShwcmV2Tm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yLmFwcGVuZENoaWxkKHByZXZOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJldkFuY2hvck5vZGUgPSBfZ2V0TWFpbnRhaW5lZE5vZGUoYW5jZXN0b3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFwcmV2QW5jaG9yTm9kZSkgYW5jaG9yTm9kZSA9IHByZXZBbmNob3JOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW5jaG9yTm9kZSkgbGluZSA9IGFuY2hvck5vZGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdOb2RlID0gYW5jZXN0b3I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBDdXJyZW50ID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChuZXdOb2RlICE9PSBsaW5lICYmIG5ld05vZGUgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZOb2RlID0gdmFsaWRhdGlvbihuZXdOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdOb2RlLm5vZGVUeXBlID09PSAxICYmIHZOb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEN1cnJlbnQucHVzaCh2Tm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdOb2RlID0gbmV3Tm9kZS5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGlsZE5vZGUgPSBwQ3VycmVudC5wb3AoKSB8fCBhbmNlc3RvcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kTm9kZSA9IG5ld05vZGUgPSBjaGlsZE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChwQ3VycmVudC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdOb2RlID0gcEN1cnJlbnQucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmROb2RlLmFwcGVuZENoaWxkKG5ld05vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kTm9kZSA9IG5ld05vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZE5vZGUgIT09IGFuY2VzdG9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdJbm5lck5vZGUuYXBwZW5kQ2hpbGQoY2hpbGROb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yID0gbmV3Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yID0gbmV3SW5uZXJOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5pc0JyZWFrKGNoaWxkKSkgbmV3SW5uZXJOb2RlLmFwcGVuZENoaWxkKGNoaWxkLmNsb25lTm9kZShmYWxzZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lLmFwcGVuZENoaWxkKG5ld0lubmVyTm9kZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXIgPSB0ZXh0Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFzc05vZGUgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3IuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICB2Tm9kZSA9ICFwYXNzTm9kZSA/IGNoaWxkLmNsb25lTm9kZShmYWxzZSkgOiB2YWxpZGF0aW9uKGNoaWxkKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodk5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3IuYXBwZW5kQ2hpbGQodk5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQubm9kZVR5cGUgPT09IDEgJiYgIXV0aWwuaXNCcmVhayhjaGlsZCkpIGNvdmVyTm9kZSA9IHZOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVjdXJzaW9uRnVuYyhjaGlsZCwgY292ZXJOb2RlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSkoZWxlbWVudCwgcE5vZGUpO1xyXG5cclxuICAgICAgICAgICAgLy8gbm90IHJlbW92ZSB0YWdcclxuICAgICAgICAgICAgaWYgKGlzUmVtb3ZlTm9kZSAmJiAhaXNSZW1vdmVGb3JtYXQgJiYgIV9yZW1vdmVDaGVjay52KSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yOiBlbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lcjogc3RhcnRDb24sXHJcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiBzdGFydE9mZixcclxuICAgICAgICAgICAgICAgICAgICBlbmRDb250YWluZXI6IF9lbmRDb250YWluZXJcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlzUmVtb3ZlRm9ybWF0ID0gaXNSZW1vdmVGb3JtYXQgJiYgaXNSZW1vdmVOb2RlO1xyXG5cclxuICAgICAgICAgICAgaWYgKGlzUmVtb3ZlRm9ybWF0KSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5Ob2RlQXJyYXkubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcmVtb3ZlTm9kZSA9IG5Ob2RlQXJyYXlbaV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJDaGlsZHJlbiA9IHJlbW92ZU5vZGUuY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXh0Tm9kZSA9IHJDaGlsZHJlblswXTtcclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAockNoaWxkcmVuWzBdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBOb2RlLmluc2VydEJlZm9yZShyQ2hpbGRyZW5bMF0sIHJlbW92ZU5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW0ocmVtb3ZlTm9kZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpID09PSAwKSBjb250YWluZXIgPSB0ZXh0Tm9kZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc1JlbW92ZU5vZGUpIHtcclxuICAgICAgICAgICAgICAgIG5ld0lubmVyTm9kZSA9IG5ld0lubmVyTm9kZS5maXJzdENoaWxkO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuTm9kZUFycmF5Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RyaXBSZW1vdmVOb2RlKG5Ob2RlQXJyYXlbaV0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIWlzUmVtb3ZlRm9ybWF0ICYmIHBOb2RlLmNoaWxkTm9kZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5jaGlsZE5vZGVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyID0gZWxlbWVudC5jaGlsZE5vZGVzWzBdO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBjb250YWluZXIgPSB1dGlsLmNyZWF0ZVRleHROb2RlKHV0aWwuemVyb1dpZHRoU3BhY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlRW1wdHlOb2RlKHBOb2RlLCBuZXdJbm5lck5vZGUpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh1dGlsLm9ubHlaZXJvV2lkdGhTcGFjZShwTm9kZS50ZXh0Q29udGVudCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb250YWluZXIgPSBwTm9kZS5maXJzdENoaWxkO1xyXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gbm9kZSBjaGFuZ2VcclxuICAgICAgICAgICAgICAgIGNvbnN0IG9mZnNldHMgPSB7czogMCwgZTogMH07XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwYXRoID0gdXRpbC5nZXROb2RlUGF0aChjb250YWluZXIsIHBOb2RlLCBvZmZzZXRzKTtcclxuICAgICAgICAgICAgICAgIG9mZnNldCArPSBvZmZzZXRzLnM7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gdGFnIG1lcmdlXHJcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdPZmZzZXRzID0gdXRpbC5tZXJnZVNhbWVUYWdzKHBOb2RlLCBbcGF0aF0sIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgICAgIGVsZW1lbnQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQocE5vZGUsIGVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnRhaW5lciA9IHV0aWwuZ2V0Tm9kZUZyb21QYXRoKHBhdGgsIHBOb2RlKTtcclxuICAgICAgICAgICAgICAgIG9mZnNldCArPSBuZXdPZmZzZXRzWzBdO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgYW5jZXN0b3I6IHBOb2RlLFxyXG4gICAgICAgICAgICAgICAgY29udGFpbmVyOiBjb250YWluZXIsXHJcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IG9mZnNldCxcclxuICAgICAgICAgICAgICAgIGVuZENvbnRhaW5lcjogX2VuZENvbnRhaW5lclxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiB3cmFwcyBtaWQgbGluZXMgc2VsZWN0ZWQgdGV4dC5cclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgVGhlIG5vZGUgb2YgdGhlIGxpbmUgdGhhdCBjb250YWlucyB0aGUgc2VsZWN0ZWQgdGV4dCBub2RlLlxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gbmV3SW5uZXJOb2RlIFRoZSBkb20gdGhhdCB3aWxsIHdyYXAgdGhlIHNlbGVjdGVkIHRleHQgYXJlYVxyXG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHZhbGlkYXRpb24gQ2hlY2sgaWYgdGhlIG5vZGUgc2hvdWxkIGJlIHN0cmlwcGVkLlxyXG4gICAgICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNSZW1vdmVGb3JtYXQgSXMgdGhlIHJlbW92ZSBhbGwgZm9ybWF0cyBjb21tYW5kP1xyXG4gICAgICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNSZW1vdmVOb2RlIFwibmV3SW5uZXJOb2RlXCIgaXMgcmVtb3ZlIG5vZGU/XHJcbiAgICAgICAgICogQHBhcmFtIHtOb2RlfSBfZW5kQ29udGFpbmVyIE9mZnNldCBub2RlIG9mIGxhc3QgbGluZSBhbHJlYWR5IG1vZGlmaWVkIChlbmQuY29udGFpbmVyKVxyXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3R9IHsgYW5jZXN0b3IsIGVuZENvbnRhaW5lcjogXCJJZiBlbmQgY29udGFpbmVyIGlzIHJlbmV3ZWQsIHJldHVybmVkIHJlbmV3ZWQgbm9kZVwiIH1cclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9ub2RlQ2hhbmdlX21pZGRsZUxpbmU6IGZ1bmN0aW9uIChlbGVtZW50LCBuZXdJbm5lck5vZGUsIHZhbGlkYXRpb24sIGlzUmVtb3ZlRm9ybWF0LCBpc1JlbW92ZU5vZGUsIF9yZW1vdmVDaGVjaywgX2VuZENvbnRhaW5lcikge1xyXG4gICAgICAgICAgICAvLyBub3QgYWRkIHRhZ1xyXG4gICAgICAgICAgICBpZiAoIWlzUmVtb3ZlTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgLy8gZW5kIGNvbnRhaW5lciBwYXRoXHJcbiAgICAgICAgICAgICAgICBsZXQgZW5kUGF0aCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICBpZiAoX2VuZENvbnRhaW5lciAmJiBlbGVtZW50LmNvbnRhaW5zKF9lbmRDb250YWluZXIpKSBlbmRQYXRoID0gdXRpbC5nZXROb2RlUGF0aChfZW5kQ29udGFpbmVyLCBlbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCB0ZW1wTm9kZSA9IGVsZW1lbnQuY2xvbmVOb2RlKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3Tm9kZU5hbWUgPSBuZXdJbm5lck5vZGUubm9kZU5hbWU7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdDc3NUZXh0ID0gbmV3SW5uZXJOb2RlLnN0eWxlLmNzc1RleHQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdDbGFzcyA9IG5ld0lubmVyTm9kZS5jbGFzc05hbWU7XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IGNoaWxkcmVuID0gdGVtcE5vZGUuY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgIGxldCBpID0gMCwgbGVuID0gY2hpbGRyZW4ubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgY2hpbGQ7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkID0gY2hpbGRyZW5baV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlID09PSAzKSBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQubm9kZU5hbWUgPT09IG5ld05vZGVOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnN0eWxlLmNzc1RleHQgKz0gbmV3Q3NzVGV4dDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXRpbC5hZGRDbGFzcyhjaGlsZCwgbmV3Q2xhc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXV0aWwuaXNCcmVhayhjaGlsZCkgJiYgdXRpbC5faXNJZ25vcmVOb2RlQ2hhbmdlKGNoaWxkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGxlbiA9PT0gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkLmNoaWxkTm9kZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbiA9IGNoaWxkcmVuLmxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaSA9IC0xO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGxlbiA+IDAgJiYgaSA9PT0gbGVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSB0ZW1wTm9kZS5pbm5lckhUTUw7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3I6IGVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuZENvbnRhaW5lcjogZW5kUGF0aCA/IHV0aWwuZ2V0Tm9kZUZyb21QYXRoKGVuZFBhdGgsIGVsZW1lbnQpIDogbnVsbFxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGFkZCB0YWdcclxuICAgICAgICAgICAgX3JlbW92ZUNoZWNrLnYgPSBmYWxzZTtcclxuICAgICAgICAgICAgY29uc3QgcE5vZGUgPSBlbGVtZW50LmNsb25lTm9kZShmYWxzZSk7XHJcbiAgICAgICAgICAgIGNvbnN0IG5Ob2RlQXJyYXkgPSBbbmV3SW5uZXJOb2RlXTtcclxuICAgICAgICAgICAgbGV0IG5vbmVDaGFuZ2UgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgKGZ1bmN0aW9uIHJlY3Vyc2lvbkZ1bmMoY3VycmVudCwgYW5jZXN0b3IpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkTm9kZXMgPSBjdXJyZW50LmNoaWxkTm9kZXM7XHJcblxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNoaWxkTm9kZXMubGVuZ3RoLCB2Tm9kZSwgY2xvbmVDaGlsZDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNoaWxkID0gY2hpbGROb2Rlc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWNoaWxkKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgY292ZXJOb2RlID0gYW5jZXN0b3I7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdXRpbC5pc0JyZWFrKGNoaWxkKSAmJiB1dGlsLl9pc0lnbm9yZU5vZGVDaGFuZ2UoY2hpbGQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdJbm5lck5vZGUuY2hpbGROb2Rlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTm9kZS5hcHBlbmRDaGlsZChuZXdJbm5lck5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3SW5uZXJOb2RlID0gbmV3SW5uZXJOb2RlLmNsb25lTm9kZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsb25lQ2hpbGQgPSBjaGlsZC5jbG9uZU5vZGUodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBOb2RlLmFwcGVuZENoaWxkKGNsb25lQ2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwTm9kZS5hcHBlbmRDaGlsZChuZXdJbm5lck5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuTm9kZUFycmF5LnB1c2gobmV3SW5uZXJOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3IgPSBuZXdJbm5lck5vZGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBlbmQgY29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfZW5kQ29udGFpbmVyICYmIGNoaWxkLmNvbnRhaW5zKF9lbmRDb250YWluZXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmRQYXRoID0gdXRpbC5nZXROb2RlUGF0aChfZW5kQ29udGFpbmVyLCBjaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZW5kQ29udGFpbmVyID0gdXRpbC5nZXROb2RlRnJvbVBhdGgoZW5kUGF0aCwgY2xvbmVDaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZOb2RlID0gdmFsaWRhdGlvbihjaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2Tm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9uZUNoYW5nZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3IuYXBwZW5kQ2hpbGQodk5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlID09PSAxKSBjb3Zlck5vZGUgPSB2Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF1dGlsLmlzQnJlYWsoY2hpbGQpKSByZWN1cnNpb25GdW5jKGNoaWxkLCBjb3Zlck5vZGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KShlbGVtZW50LCBuZXdJbm5lck5vZGUpO1xyXG5cclxuICAgICAgICAgICAgLy8gbm90IHJlbW92ZSB0YWdcclxuICAgICAgICAgICAgaWYgKG5vbmVDaGFuZ2UgfHwgKGlzUmVtb3ZlTm9kZSAmJiAhaXNSZW1vdmVGb3JtYXQgJiYgIV9yZW1vdmVDaGVjay52KSkgcmV0dXJuIHsgYW5jZXN0b3I6IGVsZW1lbnQsIGVuZENvbnRhaW5lcjogX2VuZENvbnRhaW5lciB9O1xyXG5cclxuICAgICAgICAgICAgcE5vZGUuYXBwZW5kQ2hpbGQobmV3SW5uZXJOb2RlKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChpc1JlbW92ZUZvcm1hdCAmJiBpc1JlbW92ZU5vZGUpIHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbk5vZGVBcnJheS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCByZW1vdmVOb2RlID0gbk5vZGVBcnJheVtpXTtcclxuICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCByQ2hpbGRyZW4gPSByZW1vdmVOb2RlLmNoaWxkTm9kZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJDaGlsZHJlblswXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwTm9kZS5pbnNlcnRCZWZvcmUockNoaWxkcmVuWzBdLCByZW1vdmVOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVJdGVtKHJlbW92ZU5vZGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzUmVtb3ZlTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgbmV3SW5uZXJOb2RlID0gbmV3SW5uZXJOb2RlLmZpcnN0Q2hpbGQ7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5Ob2RlQXJyYXkubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdHJpcFJlbW92ZU5vZGUobk5vZGVBcnJheVtpXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHV0aWwucmVtb3ZlRW1wdHlOb2RlKHBOb2RlLCBuZXdJbm5lck5vZGUpO1xyXG4gICAgICAgICAgICB1dGlsLm1lcmdlU2FtZVRhZ3MocE5vZGUsIG51bGwsIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgLy8gbm9kZSBjaGFuZ2VcclxuICAgICAgICAgICAgZWxlbWVudC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChwTm9kZSwgZWxlbWVudCk7XHJcbiAgICAgICAgICAgIHJldHVybiB7IGFuY2VzdG9yOiBwTm9kZSwgZW5kQ29udGFpbmVyOiBfZW5kQ29udGFpbmVyIH07XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIHdyYXBzIGxhc3QgbGluZSBzZWxlY3RlZCB0ZXh0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBUaGUgbm9kZSBvZiB0aGUgbGluZSB0aGF0IGNvbnRhaW5zIHRoZSBzZWxlY3RlZCB0ZXh0IG5vZGUuXHJcbiAgICAgICAgICogQHBhcmFtIHtFbGVtZW50fSBuZXdJbm5lck5vZGUgVGhlIGRvbSB0aGF0IHdpbGwgd3JhcCB0aGUgc2VsZWN0ZWQgdGV4dCBhcmVhXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gdmFsaWRhdGlvbiBDaGVjayBpZiB0aGUgbm9kZSBzaG91bGQgYmUgc3RyaXBwZWQuXHJcbiAgICAgICAgICogQHBhcmFtIHtOb2RlfSBlbmRDb24gVGhlIGVuZENvbnRhaW5lciBwcm9wZXJ0eSBvZiB0aGUgc2VsZWN0aW9uIG9iamVjdC5cclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gZW5kT2ZmIFRoZSBlbmRPZmZzZXQgcHJvcGVydHkgb2YgdGhlIHNlbGVjdGlvbiBvYmplY3QuXHJcbiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSBpc1JlbW92ZUZvcm1hdCBJcyB0aGUgcmVtb3ZlIGFsbCBmb3JtYXRzIGNvbW1hbmQ/XHJcbiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSBpc1JlbW92ZU5vZGUgXCJuZXdJbm5lck5vZGVcIiBpcyByZW1vdmUgbm9kZT9cclxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSB7IGFuY2VzdG9yLCBjb250YWluZXIsIG9mZnNldCB9XHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfbm9kZUNoYW5nZV9lbmRMaW5lOiBmdW5jdGlvbiAoZWxlbWVudCwgbmV3SW5uZXJOb2RlLCB2YWxpZGF0aW9uLCBlbmRDb24sIGVuZE9mZiwgaXNSZW1vdmVGb3JtYXQsIGlzUmVtb3ZlTm9kZSwgX3JlbW92ZUNoZWNrLCBfZ2V0TWFpbnRhaW5lZE5vZGUsIF9pc01haW50YWluZWROb2RlKSB7XHJcbiAgICAgICAgICAgIC8vIG5vdCBhZGQgdGFnXHJcbiAgICAgICAgICAgIGxldCBwYXJlbnRDb24gPSBlbmRDb24ucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgd2hpbGUgKCFwYXJlbnRDb24ubmV4dFNpYmxpbmcgJiYgIXBhcmVudENvbi5wcmV2aW91c1NpYmxpbmcgJiYgIXV0aWwuaXNGb3JtYXRFbGVtZW50KHBhcmVudENvbi5wYXJlbnROb2RlKSAmJiAhdXRpbC5pc1d5c2l3eWdEaXYocGFyZW50Q29uLnBhcmVudE5vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocGFyZW50Q29uLm5vZGVOYW1lID09PSBuZXdJbm5lck5vZGUubm9kZU5hbWUpIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgcGFyZW50Q29uID0gcGFyZW50Q29uLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGlmICghaXNSZW1vdmVOb2RlICYmIHBhcmVudENvbi5ub2RlTmFtZSA9PT0gbmV3SW5uZXJOb2RlLm5vZGVOYW1lICYmICF1dGlsLmlzRm9ybWF0RWxlbWVudChwYXJlbnRDb24pICYmICFwYXJlbnRDb24ucHJldmlvdXNTaWJsaW5nICYmIHV0aWwub25seVplcm9XaWR0aFNwYWNlKGVuZENvbi50ZXh0Q29udGVudC5zbGljZShlbmRPZmYpKSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IHNhbWVUYWcgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgbGV0IGUgPSBlbmRDb24ubmV4dFNpYmxpbmc7XHJcbiAgICAgICAgICAgICAgICB3aGlsZSAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdXRpbC5vbmx5WmVyb1dpZHRoU3BhY2UoZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2FtZVRhZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZSA9IGUubmV4dFNpYmxpbmc7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHNhbWVUYWcpIHtcclxuICAgICAgICAgICAgICAgICAgICB1dGlsLmNvcHlUYWdBdHRyaWJ1dGVzKHBhcmVudENvbiwgbmV3SW5uZXJOb2RlKTtcclxuICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yOiBlbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXI6IGVuZENvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiBlbmRPZmZcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBhZGQgdGFnXHJcbiAgICAgICAgICAgIF9yZW1vdmVDaGVjay52ID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGNvbnN0IGVsID0gZWxlbWVudDtcclxuICAgICAgICAgICAgY29uc3Qgbk5vZGVBcnJheSA9IFtuZXdJbm5lck5vZGVdO1xyXG4gICAgICAgICAgICBjb25zdCBwTm9kZSA9IGVsZW1lbnQuY2xvbmVOb2RlKGZhbHNlKTtcclxuXHJcbiAgICAgICAgICAgIGxldCBjb250YWluZXIgPSBlbmRDb247XHJcbiAgICAgICAgICAgIGxldCBvZmZzZXQgPSBlbmRPZmY7XHJcbiAgICAgICAgICAgIGxldCBwYXNzTm9kZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICBsZXQgcEN1cnJlbnQsIG5ld05vZGUsIGFwcGVuZE5vZGUsIGFuY2hvck5vZGU7XHJcblxyXG4gICAgICAgICAgICAoZnVuY3Rpb24gcmVjdXJzaW9uRnVuYyhjdXJyZW50LCBhbmNlc3Rvcikge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2hpbGROb2RlcyA9IGN1cnJlbnQuY2hpbGROb2RlcztcclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gY2hpbGROb2Rlcy5sZW5ndGggLSAxLCB2Tm9kZTsgMCA8PSBpOyBpLS0pIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGlsZCA9IGNoaWxkTm9kZXNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGlsZCkgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvdmVyTm9kZSA9IGFuY2VzdG9yO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAocGFzc05vZGUgJiYgIXV0aWwuaXNCcmVhayhjaGlsZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlID09PSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5faXNJZ25vcmVOb2RlQ2hhbmdlKGNoaWxkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0lubmVyTm9kZSA9IG5ld0lubmVyTm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNsb25lQ2hpbGQgPSBjaGlsZC5jbG9uZU5vZGUodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5vZGUuaW5zZXJ0QmVmb3JlKGNsb25lQ2hpbGQsIGFuY2VzdG9yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTm9kZS5pbnNlcnRCZWZvcmUobmV3SW5uZXJOb2RlLCBjbG9uZUNoaWxkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuTm9kZUFycmF5LnB1c2gobmV3SW5uZXJOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjdXJzaW9uRnVuYyhjaGlsZCwgY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBjaGlsZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcEN1cnJlbnQgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYW5jaG9ycyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAobmV3Tm9kZS5wYXJlbnROb2RlICE9PSBudWxsICYmIG5ld05vZGUgIT09IGVsICYmIG5ld05vZGUgIT09IG5ld0lubmVyTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdk5vZGUgPSB2YWxpZGF0aW9uKG5ld05vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZOb2RlICYmIG5ld05vZGUubm9kZVR5cGUgPT09IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzTWFpbnRhaW5lZE5vZGUobmV3Tm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhbmNob3JOb2RlKSBhbmNob3JzLnB1c2godk5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBDdXJyZW50LnB1c2godk5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBuZXdOb2RlLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcEN1cnJlbnQgPSBwQ3VycmVudC5jb25jYXQoYW5jaG9ycyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpc1RvcE5vZGUgPSBwQ3VycmVudC5sZW5ndGggPiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGlsZE5vZGUgPSBwQ3VycmVudC5wb3AoKSB8fCBjaGlsZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kTm9kZSA9IG5ld05vZGUgPSBjaGlsZE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChwQ3VycmVudC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdOb2RlID0gcEN1cnJlbnQucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmROb2RlLmFwcGVuZENoaWxkKG5ld05vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kTm9kZSA9IG5ld05vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNNYWludGFpbmVkTm9kZShuZXdJbm5lck5vZGUucGFyZW50Tm9kZSkgJiYgIV9pc01haW50YWluZWROb2RlKGNoaWxkTm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0lubmVyTm9kZSA9IG5ld0lubmVyTm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5vZGUuaW5zZXJ0QmVmb3JlKG5ld0lubmVyTm9kZSwgcE5vZGUuZmlyc3RDaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuTm9kZUFycmF5LnB1c2gobmV3SW5uZXJOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhbmNob3JOb2RlICYmIF9pc01haW50YWluZWROb2RlKGNoaWxkTm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0lubmVyTm9kZSA9IG5ld0lubmVyTm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYUNoaWxkcmVuID0gY2hpbGROb2RlLmNoaWxkTm9kZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBhID0gMCwgYUxlbiA9IGFDaGlsZHJlbi5sZW5ndGg7IGEgPCBhTGVuOyBhKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdJbm5lck5vZGUuYXBwZW5kQ2hpbGQoYUNoaWxkcmVuW2FdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkTm9kZS5hcHBlbmRDaGlsZChuZXdJbm5lck5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5vZGUuaW5zZXJ0QmVmb3JlKGNoaWxkTm9kZSwgcE5vZGUuZmlyc3RDaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuTm9kZUFycmF5LnB1c2gobmV3SW5uZXJOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdJbm5lck5vZGUuY2hpbGRyZW4ubGVuZ3RoID4gMCkgYW5jZXN0b3IgPSBuZXdOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBhbmNlc3RvciA9IG5ld0lubmVyTm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc1RvcE5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0lubmVyTm9kZS5pbnNlcnRCZWZvcmUoY2hpbGROb2RlLCBuZXdJbm5lck5vZGUuZmlyc3RDaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNlc3RvciA9IG5ld05vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNlc3RvciA9IG5ld0lubmVyTm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFuY2hvck5vZGUgJiYgY2hpbGQubm9kZVR5cGUgPT09IDMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfZ2V0TWFpbnRhaW5lZE5vZGUoY2hpbGQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYW5jZXN0b3JBbmNob3JOb2RlID0gdXRpbC5nZXRQYXJlbnRFbGVtZW50KGFuY2VzdG9yLCBmdW5jdGlvbiAoY3VycmVudCkge3JldHVybiB0aGlzLl9pc01haW50YWluZWROb2RlKGN1cnJlbnQucGFyZW50Tm9kZSkgfHwgY3VycmVudC5wYXJlbnROb2RlID09PSBwTm9kZTt9LmJpbmQodXRpbCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvck5vZGUuYXBwZW5kQ2hpbGQoYW5jZXN0b3JBbmNob3JOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdJbm5lck5vZGUgPSBhbmNlc3RvckFuY2hvck5vZGUuY2xvbmVOb2RlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuTm9kZUFycmF5LnB1c2gobmV3SW5uZXJOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTm9kZS5pbnNlcnRCZWZvcmUobmV3SW5uZXJOb2RlLCBwTm9kZS5maXJzdENoaWxkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yTm9kZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGVuZENvbnRhaW5lclxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghcGFzc05vZGUgJiYgY2hpbGQgPT09IGNvbnRhaW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JOb2RlID0gX2dldE1haW50YWluZWROb2RlKGNoaWxkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWZ0ZXJOb2RlID0gdXRpbC5jcmVhdGVUZXh0Tm9kZShjb250YWluZXIubm9kZVR5cGUgPT09IDEgPyAnJyA6IGNvbnRhaW5lci5zdWJzdHJpbmdEYXRhKG9mZnNldCwgKGNvbnRhaW5lci5sZW5ndGggLSBvZmZzZXQpKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRleHROb2RlID0gdXRpbC5jcmVhdGVUZXh0Tm9kZShjb250YWluZXIubm9kZVR5cGUgPT09IDEgPyAnJyA6IGNvbnRhaW5lci5zdWJzdHJpbmdEYXRhKDAsIG9mZnNldCkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFuY2hvck5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvck5vZGUgPSBhbmNob3JOb2RlLmNsb25lTm9kZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhID0gX2dldE1haW50YWluZWROb2RlKGFuY2VzdG9yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhICYmIGEucGFyZW50Tm9kZSAhPT0gcE5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgbSA9IGE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHAgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChtLnBhcmVudE5vZGUgIT09IHBOb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yID0gcCA9IG0ucGFyZW50Tm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZShtLmNoaWxkTm9kZXNbMF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAuYXBwZW5kQ2hpbGQobS5jaGlsZE5vZGVzWzBdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtLmFwcGVuZENoaWxkKHApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtID0gbS5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGEsIG0ucGFyZW50Tm9kZS5maXJzdENoaWxkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvck5vZGUgPSBhbmNob3JOb2RlLmNsb25lTm9kZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoX2lzTWFpbnRhaW5lZE5vZGUobmV3SW5uZXJOb2RlLnBhcmVudE5vZGUpICYmICFhbmNob3JOb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdJbm5lck5vZGUgPSBuZXdJbm5lck5vZGUuY2xvbmVOb2RlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOb2RlLmFwcGVuZENoaWxkKG5ld0lubmVyTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuTm9kZUFycmF5LnB1c2gobmV3SW5uZXJOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF1dGlsLm9ubHlaZXJvV2lkdGhTcGFjZShhZnRlck5vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNlc3Rvci5pbnNlcnRCZWZvcmUoYWZ0ZXJOb2RlLCBhbmNlc3Rvci5maXJzdENoaWxkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZSA9IGFuY2VzdG9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwQ3VycmVudCA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAobmV3Tm9kZSAhPT0gcE5vZGUgJiYgbmV3Tm9kZSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdk5vZGUgPSBfaXNNYWludGFpbmVkTm9kZShuZXdOb2RlKSA/IG51bGwgOiB2YWxpZGF0aW9uKG5ld05vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZOb2RlICYmIG5ld05vZGUubm9kZVR5cGUgPT09IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQ3VycmVudC5wdXNoKHZOb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBuZXdOb2RlLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkTm9kZSA9IHBDdXJyZW50LnBvcCgpIHx8IGFuY2VzdG9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmROb2RlID0gbmV3Tm9kZSA9IGNoaWxkTm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHBDdXJyZW50Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBwQ3VycmVudC5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZE5vZGUuYXBwZW5kQ2hpbGQobmV3Tm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmROb2RlID0gbmV3Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkTm9kZSAhPT0gYW5jZXN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0lubmVyTm9kZS5pbnNlcnRCZWZvcmUoY2hpbGROb2RlLCBuZXdJbm5lck5vZGUuZmlyc3RDaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNlc3RvciA9IG5ld05vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNlc3RvciA9IG5ld0lubmVyTm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHV0aWwuaXNCcmVhayhjaGlsZCkpIG5ld0lubmVyTm9kZS5hcHBlbmRDaGlsZChjaGlsZC5jbG9uZU5vZGUoZmFsc2UpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhbmNob3JOb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JOb2RlLmluc2VydEJlZm9yZShuZXdJbm5lck5vZGUsIGFuY2hvck5vZGUuZmlyc3RDaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTm9kZS5pbnNlcnRCZWZvcmUoYW5jaG9yTm9kZSwgcE5vZGUuZmlyc3RDaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JOb2RlID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOb2RlLmluc2VydEJlZm9yZShuZXdJbm5lck5vZGUsIHBOb2RlLmZpcnN0Q2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXIgPSB0ZXh0Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gdGV4dE5vZGUuZGF0YS5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3NOb2RlID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yLmluc2VydEJlZm9yZShjb250YWluZXIsIGFuY2VzdG9yLmZpcnN0Q2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZOb2RlID0gIXBhc3NOb2RlID8gY2hpbGQuY2xvbmVOb2RlKGZhbHNlKSA6IHZhbGlkYXRpb24oY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh2Tm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhbmNlc3Rvci5pbnNlcnRCZWZvcmUodk5vZGUsIGFuY2VzdG9yLmZpcnN0Q2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQubm9kZVR5cGUgPT09IDEgJiYgIXV0aWwuaXNCcmVhayhjaGlsZCkpIGNvdmVyTm9kZSA9IHZOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVjdXJzaW9uRnVuYyhjaGlsZCwgY292ZXJOb2RlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSkoZWxlbWVudCwgcE5vZGUpO1xyXG5cclxuICAgICAgICAgICAgLy8gbm90IHJlbW92ZSB0YWdcclxuICAgICAgICAgICAgaWYgKGlzUmVtb3ZlTm9kZSAmJiAhaXNSZW1vdmVGb3JtYXQgJiYgIV9yZW1vdmVDaGVjay52KSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yOiBlbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lcjogZW5kQ29uLFxyXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogZW5kT2ZmXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpc1JlbW92ZUZvcm1hdCA9IGlzUmVtb3ZlRm9ybWF0ICYmIGlzUmVtb3ZlTm9kZTtcclxuXHJcbiAgICAgICAgICAgIGlmIChpc1JlbW92ZUZvcm1hdCkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuTm9kZUFycmF5Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlbW92ZU5vZGUgPSBuTm9kZUFycmF5W2ldO1xyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJDaGlsZHJlbiA9IHJlbW92ZU5vZGUuY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgICAgICBsZXQgdGV4dE5vZGUgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChyQ2hpbGRyZW5bMF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dE5vZGUgPSByQ2hpbGRyZW5bMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBOb2RlLmluc2VydEJlZm9yZSh0ZXh0Tm9kZSwgcmVtb3ZlTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlSXRlbShyZW1vdmVOb2RlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT09IG5Ob2RlQXJyYXkubGVuZ3RoIC0gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXIgPSB0ZXh0Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gdGV4dE5vZGUudGV4dENvbnRlbnQubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc1JlbW92ZU5vZGUpIHtcclxuICAgICAgICAgICAgICAgIG5ld0lubmVyTm9kZSA9IG5ld0lubmVyTm9kZS5maXJzdENoaWxkO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuTm9kZUFycmF5Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RyaXBSZW1vdmVOb2RlKG5Ob2RlQXJyYXlbaV0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIWlzUmVtb3ZlRm9ybWF0ICYmIHBOb2RlLmNoaWxkTm9kZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5jaGlsZE5vZGVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyID0gZWxlbWVudC5jaGlsZE5vZGVzWzBdO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBjb250YWluZXIgPSB1dGlsLmNyZWF0ZVRleHROb2RlKHV0aWwuemVyb1dpZHRoU3BhY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmICghaXNSZW1vdmVOb2RlICYmIG5ld0lubmVyTm9kZS50ZXh0Q29udGVudC5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUVtcHR5Tm9kZShwTm9kZSwgbnVsbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3I6IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lcjogbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiAwXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUVtcHR5Tm9kZShwTm9kZSwgbmV3SW5uZXJOb2RlKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodXRpbC5vbmx5WmVyb1dpZHRoU3BhY2UocE5vZGUudGV4dENvbnRlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyID0gcE5vZGUuZmlyc3RDaGlsZDtcclxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBjb250YWluZXIudGV4dENvbnRlbnQubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh1dGlsLm9ubHlaZXJvV2lkdGhTcGFjZShjb250YWluZXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyID0gbmV3SW5uZXJOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IDE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIC8vIG5vZGUgY2hhbmdlXHJcbiAgICAgICAgICAgICAgICBjb25zdCBvZmZzZXRzID0ge3M6IDAsIGU6IDB9O1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcGF0aCA9IHV0aWwuZ2V0Tm9kZVBhdGgoY29udGFpbmVyLCBwTm9kZSwgb2Zmc2V0cyk7XHJcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gb2Zmc2V0cy5zO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIHRhZyBtZXJnZVxyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3T2Zmc2V0cyA9IHV0aWwubWVyZ2VTYW1lVGFncyhwTm9kZSwgW3BhdGhdLCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICBlbGVtZW50LnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKHBOb2RlLCBlbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb250YWluZXIgPSB1dGlsLmdldE5vZGVGcm9tUGF0aChwYXRoLCBwTm9kZSk7XHJcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gbmV3T2Zmc2V0c1swXTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGFuY2VzdG9yOiBwTm9kZSxcclxuICAgICAgICAgICAgICAgIGNvbnRhaW5lcjogY29udGFpbmVyLFxyXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiBvZmZzZXRcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gUnVuIHBsdWdpbiBjYWxscyBhbmQgYmFzaWMgY29tbWFuZHMuXHJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGNvbW1hbmQgQ29tbWFuZCBzdHJpbmdcclxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gZGlzcGxheSBEaXNwbGF5IHR5cGUgc3RyaW5nICgnY29tbWFuZCcsICdzdWJtZW51JywgJ2RpYWxvZycsICdjb250YWluZXInKVxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gdGFyZ2V0IFRoZSBlbGVtZW50IG9mIGNvbW1hbmQgYnV0dG9uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgYWN0aW9uQ2FsbDogZnVuY3Rpb24gKGNvbW1hbmQsIGRpc3BsYXksIHRhcmdldCkge1xyXG4gICAgICAgICAgICAvLyBjYWxsIHBsdWdpbnNcclxuICAgICAgICAgICAgaWYgKGRpc3BsYXkpIHtcclxuICAgICAgICAgICAgICAgIGlmICgvbW9yZS9pLnRlc3QoZGlzcGxheSkgJiYgdGFyZ2V0ICE9PSB0aGlzLl9tb3JlTGF5ZXJBY3RpdmVCdXR0b24pIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBsYXllciA9IGNvbnRleHQuZWxlbWVudC50b29sYmFyLnF1ZXJ5U2VsZWN0b3IoJy4nICsgY29tbWFuZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxheWVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9tb3JlTGF5ZXJBY3RpdmVCdXR0b24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb250ZXh0LmVsZW1lbnQudG9vbGJhci5xdWVyeVNlbGVjdG9yKCcuJyArIHRoaXMuX21vcmVMYXllckFjdGl2ZUJ1dHRvbi5nZXRBdHRyaWJ1dGUoJ2RhdGEtY29tbWFuZCcpKSkuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlQ2xhc3ModGhpcy5fbW9yZUxheWVyQWN0aXZlQnV0dG9uLCAnb24nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB1dGlsLmFkZENsYXNzKHRhcmdldCwgJ29uJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21vcmVMYXllckFjdGl2ZUJ1dHRvbiA9IHRhcmdldDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGF5ZXIuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5fc2hvd1Rvb2xiYXJCYWxsb29uKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50Ll9zaG93VG9vbGJhcklubGluZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKC9zdWJtZW51Ly50ZXN0KGRpc3BsYXkpICYmICh0aGlzLl9tZW51VHJheVtjb21tYW5kXSA9PT0gbnVsbCB8fCB0YXJnZXQgIT09IHRoaXMuc3VibWVudUFjdGl2ZUJ1dHRvbikpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbGxQbHVnaW4oY29tbWFuZCwgdGhpcy5zdWJtZW51T24uYmluZCh0aGlzLCB0YXJnZXQpLCB0YXJnZXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoL2RpYWxvZy8udGVzdChkaXNwbGF5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FsbFBsdWdpbihjb21tYW5kLCB0aGlzLnBsdWdpbnNbY29tbWFuZF0ub3Blbi5iaW5kKHRoaXMpLCB0YXJnZXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoL2NvbW1hbmQvLnRlc3QoZGlzcGxheSkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbGxQbHVnaW4oY29tbWFuZCwgdGhpcy5wbHVnaW5zW2NvbW1hbmRdLmFjdGlvbi5iaW5kKHRoaXMpLCB0YXJnZXQpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICgvY29udGFpbmVyLy50ZXN0KGRpc3BsYXkpICYmICh0aGlzLl9tZW51VHJheVtjb21tYW5kXSA9PT0gbnVsbCB8fCB0YXJnZXQgIT09IHRoaXMuY29udGFpbmVyQWN0aXZlQnV0dG9uKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FsbFBsdWdpbihjb21tYW5kLCB0aGlzLmNvbnRhaW5lck9uLmJpbmQodGhpcywgdGFyZ2V0KSwgdGFyZ2V0KTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKC9maWxlQnJvd3Nlci8udGVzdChkaXNwbGF5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FsbFBsdWdpbihjb21tYW5kLCB0aGlzLnBsdWdpbnNbY29tbWFuZF0ub3Blbi5iaW5kKHRoaXMsIG51bGwpLCB0YXJnZXQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IC8vIGRlZmF1bHQgY29tbWFuZFxyXG4gICAgICAgICAgICBlbHNlIGlmIChjb21tYW5kKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbW1hbmRIYW5kbGVyKHRhcmdldCwgY29tbWFuZCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICgvbW9yZS9pLnRlc3QoZGlzcGxheSkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGxheWVyID0gY29udGV4dC5lbGVtZW50LnRvb2xiYXIucXVlcnlTZWxlY3RvcignLicgKyB0aGlzLl9tb3JlTGF5ZXJBY3RpdmVCdXR0b24uZ2V0QXR0cmlidXRlKCdkYXRhLWNvbW1hbmQnKSk7XHJcbiAgICAgICAgICAgICAgICBpZiAobGF5ZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUNsYXNzKHRoaXMuX21vcmVMYXllckFjdGl2ZUJ1dHRvbiwgJ29uJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbW9yZUxheWVyQWN0aXZlQnV0dG9uID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICBsYXllci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBldmVudC5fc2hvd1Rvb2xiYXJCYWxsb29uKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuX3Nob3dUb29sYmFySW5saW5lKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoL3N1Ym1lbnUvLnRlc3QoZGlzcGxheSkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3VibWVudU9mZigpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zdWJtZW51T2ZmKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lck9mZigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEV4ZWN1dGUgY29tbWFuZCBvZiBjb21tYW5kIGJ1dHRvbihBbGwgQnV0dG9ucyBleGNlcHQgc3VibWVudSBhbmQgZGlhbG9nKVxyXG4gICAgICAgICAqIChzZWxlY3RBbGwsIGNvZGVWaWV3LCBmdWxsU2NyZWVuLCBpbmRlbnQsIG91dGRlbnQsIHVuZG8sIHJlZG8sIHJlbW92ZUZvcm1hdCwgcHJpbnQsIHByZXZpZXcsIHNob3dCbG9ja3MsIHNhdmUsIGJvbGQsIHVuZGVybGluZSwgaXRhbGljLCBzdHJpa2UsIHN1YnNjcmlwdCwgc3VwZXJzY3JpcHQpXHJcbiAgICAgICAgICogQHBhcmFtIHtFbGVtZW50fG51bGx9IHRhcmdldCBUaGUgZWxlbWVudCBvZiBjb21tYW5kIGJ1dHRvblxyXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjb21tYW5kIFByb3BlcnR5IG9mIGNvbW1hbmQgYnV0dG9uIChkYXRhLXZhbHVlKVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNvbW1hbmRIYW5kbGVyOiBmdW5jdGlvbiAodGFyZ2V0LCBjb21tYW5kKSB7XHJcbiAgICAgICAgICAgIHN3aXRjaCAoY29tbWFuZCkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnc2VsZWN0QWxsJzpcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB3eXNpd3lnID0gY29udGV4dC5lbGVtZW50Lnd5c2l3eWc7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyc3QgPSB1dGlsLmdldENoaWxkRWxlbWVudCh3eXNpd3lnLmZpcnN0Q2hpbGQsIGZ1bmN0aW9uIChjdXJyZW50KSB7IHJldHVybiBjdXJyZW50LmNoaWxkTm9kZXMubGVuZ3RoID09PSAwIHx8IGN1cnJlbnQubm9kZVR5cGUgPT09IDM7IH0sIGZhbHNlKSB8fCB3eXNpd3lnLmZpcnN0Q2hpbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGFzdCA9IHV0aWwuZ2V0Q2hpbGRFbGVtZW50KHd5c2l3eWcubGFzdENoaWxkLCBmdW5jdGlvbiAoY3VycmVudCkgeyByZXR1cm4gY3VycmVudC5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMCB8fCBjdXJyZW50Lm5vZGVUeXBlID09PSAzOyB9LCB0cnVlKSB8fCB3eXNpd3lnLmxhc3RDaGlsZDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWZpcnN0IHx8ICFsYXN0KSByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRSYW5nZShmaXJzdCwgMCwgbGFzdCwgbGFzdC50ZXh0Q29udGVudC5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnY29kZVZpZXcnOlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudG9nZ2xlQ29kZVZpZXcoKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJ2Z1bGxTY3JlZW4nOlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudG9nZ2xlRnVsbFNjcmVlbih0YXJnZXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnaW5kZW50JzpcclxuICAgICAgICAgICAgICAgIGNhc2UgJ291dGRlbnQnOlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5kZW50KGNvbW1hbmQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAndW5kbyc6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnVuZG8oKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJ3JlZG8nOlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaGlzdG9yeS5yZWRvKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdyZW1vdmVGb3JtYXQnOlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlRm9ybWF0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb2N1cygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAncHJpbnQnOlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJpbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJ3ByZXZpZXcnOlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlldygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnc2hvd0Jsb2Nrcyc6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b2dnbGVEaXNwbGF5QmxvY2tzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdzYXZlJzpcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMuY2FsbEJhY2tTYXZlID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuY2FsbEJhY2tTYXZlKHRoaXMuZ2V0Q29udGVudHMoZmFsc2UpKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBmdW5jdGlvbnMuc2F2ZSA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbnMuc2F2ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKCdbU1VORURJVE9SLmNvcmUuY29tbWFuZEhhbmRsZXIuZmFpbF0gUGxlYXNlIHJlZ2lzdGVyIGNhbGwgYmFjayBmdW5jdGlvbiBpbiBjcmVhdGlvbiBvcHRpb24uIChjYWxsQmFja1NhdmUgOiBGdW5jdGlvbiknKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZXh0LnRvb2wuc2F2ZSkgY29udGV4dC50b29sLnNhdmUuc2V0QXR0cmlidXRlKCdkaXNhYmxlZCcsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdCA6IC8vICdTVFJPTkcnLCAnVScsICdFTScsICdERUwnLCAnU1VCJywgJ1NVUCcuLlxyXG4gICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSB0aGlzLl9kZWZhdWx0Q29tbWFuZFtjb21tYW5kLnRvTG93ZXJDYXNlKCldIHx8IGNvbW1hbmQ7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmNvbW1hbmRNYXBbY29tbWFuZF0pIHRoaXMuY29tbWFuZE1hcFtjb21tYW5kXSA9IHRhcmdldDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZXNNYXAgPSB0aGlzLl92YXJpYWJsZS5jdXJyZW50Tm9kZXNNYXA7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY21kID0gbm9kZXNNYXAuaW5kZXhPZihjb21tYW5kKSA+IC0xID8gbnVsbCA6IHV0aWwuY3JlYXRlRWxlbWVudChjb21tYW5kKTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcmVtb3ZlTm9kZSA9IGNvbW1hbmQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICgvXlNVQiQvaS50ZXN0KGNvbW1hbmQpICYmIG5vZGVzTWFwLmluZGV4T2YoJ1NVUCcpID4gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlTm9kZSA9ICdTVVAnO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoL15TVVAkL2kudGVzdChjb21tYW5kKSAmJiBub2Rlc01hcC5pbmRleE9mKCdTVUInKSA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZU5vZGUgPSAnU1VCJztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubm9kZUNoYW5nZShjbWQsIG51bGwsIFtyZW1vdmVOb2RlXSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZm9jdXMoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBSZW1vdmUgZm9ybWF0IG9mIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgcmFuZ2VcclxuICAgICAgICAgKi9cclxuICAgICAgICByZW1vdmVGb3JtYXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdGhpcy5ub2RlQ2hhbmdlKG51bGwsIG51bGwsIG51bGwsIG51bGwpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpbXBsZW1lbnRzIGluZGVudGF0aW9uIHRvIHNlbGVjdGVkIHJhbmdlLlxyXG4gICAgICAgICAqIFNldHRlZCBcIm1hcmdpbi1sZWZ0XCIgdG8gXCIyNXB4XCIgaW4gdGhlIHRvcCBcIlBcIiB0YWcgb2YgdGhlIHBhcmFtZXRlciBub2RlLlxyXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjb21tYW5kIFNlcGFyYXRvciAoXCJpbmRlbnRcIiBvciBcIm91dGRlbnRcIilcclxuICAgICAgICAgKi9cclxuICAgICAgICBpbmRlbnQ6IGZ1bmN0aW9uIChjb21tYW5kKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJhbmdlID0gdGhpcy5nZXRSYW5nZSgpO1xyXG4gICAgICAgICAgICBjb25zdCByYW5nZUxpbmVzID0gdGhpcy5nZXRTZWxlY3RlZEVsZW1lbnRzKG51bGwpO1xyXG4gICAgICAgICAgICBjb25zdCBjZWxscyA9IFtdO1xyXG4gICAgICAgICAgICBjb25zdCBzaGlmdCA9ICdpbmRlbnQnICE9PSBjb21tYW5kO1xyXG4gICAgICAgICAgICBjb25zdCBtYXJnaW5EaXIgPSBvcHRpb25zLnJ0bCA/ICdtYXJnaW5SaWdodCcgOiAnbWFyZ2luTGVmdCc7XHJcbiAgICAgICAgICAgIGxldCBzYyA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICBsZXQgZWMgPSByYW5nZS5lbmRDb250YWluZXI7XHJcbiAgICAgICAgICAgIGxldCBzbyA9IHJhbmdlLnN0YXJ0T2Zmc2V0O1xyXG4gICAgICAgICAgICBsZXQgZW8gPSByYW5nZS5lbmRPZmZzZXQ7XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gcmFuZ2VMaW5lcy5sZW5ndGgsIGYsIG1hcmdpbjsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBmID0gcmFuZ2VMaW5lc1tpXTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIXV0aWwuaXNMaXN0Q2VsbChmKSB8fCAhdGhpcy5wbHVnaW5zLmxpc3QpIHtcclxuICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSAvXFxkKy8udGVzdChmLnN0eWxlW21hcmdpbkRpcl0pID8gdXRpbC5nZXROdW1iZXIoZi5zdHlsZVttYXJnaW5EaXJdLCAwKSA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNoaWZ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiAtPSAyNTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gKz0gMjU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHV0aWwuc2V0U3R5bGUoZiwgbWFyZ2luRGlyLCAobWFyZ2luIDw9IDAgPyAnJyA6IG1hcmdpbiArICdweCcpKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNoaWZ0IHx8IGYucHJldmlvdXNFbGVtZW50U2libGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjZWxscy5wdXNoKGYpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gbGlzdCBjZWxsc1xyXG4gICAgICAgICAgICBpZiAoY2VsbHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLmxpc3QuZWRpdEluc2lkZUxpc3QuY2FsbCh0aGlzLCBzaGlmdCwgY2VsbHMpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmVmZmVjdE5vZGUgPSBudWxsO1xyXG4gICAgICAgICAgICB0aGlzLnNldFJhbmdlKHNjLCBzbywgZWMsIGVvKTtcclxuXHJcbiAgICAgICAgICAgIC8vIGhpc3Rvcnkgc3RhY2tcclxuICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnB1c2goZmFsc2UpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBBZGQgb3IgcmVtb3ZlIHRoZSBjbGFzcyBuYW1lIG9mIFwiYm9keVwiIHNvIHRoYXQgdGhlIGNvZGUgYmxvY2sgaXMgdmlzaWJsZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRvZ2dsZURpc3BsYXlCbG9ja3M6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29uc3Qgd3lzaXd5ZyA9IGNvbnRleHQuZWxlbWVudC53eXNpd3lnO1xyXG4gICAgICAgICAgICB1dGlsLnRvZ2dsZUNsYXNzKHd5c2l3eWcsICdzZS1zaG93LWJsb2NrJyk7XHJcbiAgICAgICAgICAgIGlmICh1dGlsLmhhc0NsYXNzKHd5c2l3eWcsICdzZS1zaG93LWJsb2NrJykpIHtcclxuICAgICAgICAgICAgICAgIHV0aWwuYWRkQ2xhc3ModGhpcy5fc3R5bGVDb21tYW5kTWFwLnNob3dCbG9ja3MsICdhY3RpdmUnKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlQ2xhc3ModGhpcy5fc3R5bGVDb21tYW5kTWFwLnNob3dCbG9ja3MsICdhY3RpdmUnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLl9yZXNvdXJjZXNTdGF0ZUNoYW5nZSgpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDaGFuZ2VzIHRvIGNvZGUgdmlldyBvciB3eXNpd3lnIHZpZXdcclxuICAgICAgICAgKi9cclxuICAgICAgICB0b2dnbGVDb2RlVmlldzogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjb25zdCBpc0NvZGVWaWV3ID0gdGhpcy5fdmFyaWFibGUuaXNDb2RlVmlldztcclxuICAgICAgICAgICAgdGhpcy5jb250cm9sbGVyc09mZigpO1xyXG4gICAgICAgICAgICB1dGlsLnNldERpc2FibGVkQnV0dG9ucyghaXNDb2RlVmlldywgdGhpcy5jb2RlVmlld0Rpc2FibGVkQnV0dG9ucyk7XHJcblxyXG4gICAgICAgICAgICBpZiAoaXNDb2RlVmlldykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0Q29kZURhdGFUb0VkaXRvcigpO1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5lbGVtZW50Lnd5c2l3eWdGcmFtZS5zY3JvbGxUb3AgPSAwO1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LmNvZGUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC53eXNpd3lnRnJhbWUuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5fdmFyaWFibGUuX2NvZGVPcmlnaW5Dc3NUZXh0ID0gdGhpcy5fdmFyaWFibGUuX2NvZGVPcmlnaW5Dc3NUZXh0LnJlcGxhY2UoLyhcXHM/ZGlzcGxheShcXHMrKT86KFxccyspPylbYS16QS1aXSsoPz07KS8sICdkaXNwbGF5OiBub25lJyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl92YXJpYWJsZS5fd3lzaXd5Z09yaWdpbkNzc1RleHQgPSB0aGlzLl92YXJpYWJsZS5fd3lzaXd5Z09yaWdpbkNzc1RleHQucmVwbGFjZSgvKFxccz9kaXNwbGF5KFxccyspPzooXFxzKyk/KVthLXpBLVpdKyg/PTspLywgJ2Rpc3BsYXk6IGJsb2NrJyk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuaGVpZ2h0ID09PSAnYXV0bycgJiYgIW9wdGlvbnMuY29kZU1pcnJvckVkaXRvcikgY29udGV4dC5lbGVtZW50LmNvZGUuc3R5bGUuaGVpZ2h0ID0gJzBweCc7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhcmlhYmxlLmlzQ29kZVZpZXcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl92YXJpYWJsZS5pc0Z1bGxTY3JlZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ub3RIaWRlVG9vbGJhciA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgvYmFsbG9vbnxiYWxsb29uLWFsd2F5cy9pLnRlc3Qob3B0aW9ucy5tb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmVsZW1lbnQuX2Fycm93LnN0eWxlLmRpc3BsYXkgPSAnJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faXNJbmxpbmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faXNCYWxsb29uID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuX2hpZGVUb29sYmFyKCk7ICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZUZvY3VzKCk7XHJcbiAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUNsYXNzKHRoaXMuX3N0eWxlQ29tbWFuZE1hcC5jb2RlVmlldywgJ2FjdGl2ZScpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIGhpc3Rvcnkgc3RhY2tcclxuICAgICAgICAgICAgICAgIHRoaXMuaGlzdG9yeS5wdXNoKGZhbHNlKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3NldEVkaXRvckRhdGFUb0NvZGVWaWV3KCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl92YXJpYWJsZS5fY29kZU9yaWdpbkNzc1RleHQgPSB0aGlzLl92YXJpYWJsZS5fY29kZU9yaWdpbkNzc1RleHQucmVwbGFjZSgvKFxccz9kaXNwbGF5KFxccyspPzooXFxzKyk/KVthLXpBLVpdKyg/PTspLywgJ2Rpc3BsYXk6IGJsb2NrJyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl92YXJpYWJsZS5fd3lzaXd5Z09yaWdpbkNzc1RleHQgPSB0aGlzLl92YXJpYWJsZS5fd3lzaXd5Z09yaWdpbkNzc1RleHQucmVwbGFjZSgvKFxccz9kaXNwbGF5KFxccyspPzooXFxzKyk/KVthLXpBLVpdKyg/PTspLywgJ2Rpc3BsYXk6IG5vbmUnKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5oZWlnaHQgPT09ICdhdXRvJyAmJiAhb3B0aW9ucy5jb2RlTWlycm9yRWRpdG9yKSBjb250ZXh0LmVsZW1lbnQuY29kZS5zdHlsZS5oZWlnaHQgPSBjb250ZXh0LmVsZW1lbnQuY29kZS5zY3JvbGxIZWlnaHQgPiAwID8gKGNvbnRleHQuZWxlbWVudC5jb2RlLnNjcm9sbEhlaWdodCArICdweCcpIDogJ2F1dG8nO1xyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuY29kZU1pcnJvckVkaXRvcikgb3B0aW9ucy5jb2RlTWlycm9yRWRpdG9yLnJlZnJlc2goKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fdmFyaWFibGUuaXNDb2RlVmlldyA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl92YXJpYWJsZS5pc0Z1bGxTY3JlZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ub3RIaWRlVG9vbGJhciA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2lzQmFsbG9vbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmVsZW1lbnQuX2Fycm93LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC50b29sYmFyLnN0eWxlLmxlZnQgPSAnJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faXNJbmxpbmUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9pc0JhbGxvb24gPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuX3Nob3dUb29sYmFySW5saW5lKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICB0aGlzLl92YXJpYWJsZS5fcmFuZ2UgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LmNvZGUuZm9jdXMoKTtcclxuICAgICAgICAgICAgICAgIHV0aWwuYWRkQ2xhc3ModGhpcy5fc3R5bGVDb21tYW5kTWFwLmNvZGVWaWV3LCAnYWN0aXZlJyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2NoZWNrUGxhY2Vob2xkZXIoKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZnVuY3Rpb25zLnRvZ2dsZUNvZGVWaWV3ID09PSAnZnVuY3Rpb24nKSBmdW5jdGlvbnMudG9nZ2xlQ29kZVZpZXcodGhpcy5fdmFyaWFibGUuaXNDb2RlVmlldywgdGhpcyk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIENvbnZlcnQgdGhlIGRhdGEgb2YgdGhlIGNvZGUgdmlldyBhbmQgcHV0IGl0IGluIHRoZSBXWVNJV1lHIGFyZWEuXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfc2V0Q29kZURhdGFUb0VkaXRvcjogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjb25zdCBjb2RlX2h0bWwgPSB0aGlzLl9nZXRDb2RlVmlldygpO1xyXG5cclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZnVsbFBhZ2UpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlRG9jdW1lbnQgPSB0aGlzLl9wYXJzZXIucGFyc2VGcm9tU3RyaW5nKGNvZGVfaHRtbCwgJ3RleHQvaHRtbCcpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaGVhZENoaWxkcmVuID0gcGFyc2VEb2N1bWVudC5oZWFkLmNoaWxkcmVuO1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBoZWFkQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoL15zY3JpcHQkL2kudGVzdChoZWFkQ2hpbGRyZW5baV0udGFnTmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VEb2N1bWVudC5oZWFkLnJlbW92ZUNoaWxkKGhlYWRDaGlsZHJlbltpXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGktLSwgbGVuLS07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX3dkLmhlYWQuaW5uZXJIVE1MID0gcGFyc2VEb2N1bWVudC5oZWFkLmlubmVySFRNTDtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3dkLmJvZHkuaW5uZXJIVE1MID0gdGhpcy5jb252ZXJ0Q29udGVudHNGb3JFZGl0b3IocGFyc2VEb2N1bWVudC5ib2R5LmlubmVySFRNTCk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgYXR0cnMgPSBwYXJzZURvY3VtZW50LmJvZHkuYXR0cmlidXRlcztcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBhdHRycy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhdHRyc1tpXS5uYW1lID09PSAnY29udGVudGVkaXRhYmxlJykgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fd2QuYm9keS5zZXRBdHRyaWJ1dGUoYXR0cnNbaV0ubmFtZSwgYXR0cnNbaV0udmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKCF1dGlsLmhhc0NsYXNzKHRoaXMuX3dkLmJvZHksICdzdW4tZWRpdG9yLWVkaXRhYmxlJykpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBlZGl0YWJsZUNsYXNzZXMgPSBvcHRpb25zLl9lZGl0YWJsZUNsYXNzLnNwbGl0KCcgJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlZGl0YWJsZUNsYXNzZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXRpbC5hZGRDbGFzcyh0aGlzLl93ZC5ib2R5LCBvcHRpb25zLl9lZGl0YWJsZUNsYXNzW2ldKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb250ZXh0LmVsZW1lbnQud3lzaXd5Zy5pbm5lckhUTUwgPSBjb2RlX2h0bWwubGVuZ3RoID4gMCA/IHRoaXMuY29udmVydENvbnRlbnRzRm9yRWRpdG9yKGNvZGVfaHRtbCkgOiAnPCcgKyBvcHRpb25zLmRlZmF1bHRUYWcgKyAnPjxicj48LycgKyBvcHRpb25zLmRlZmF1bHRUYWcgKyAnPic7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ29udmVydCB0aGUgZGF0YSBvZiB0aGUgV1lTSVdZRyBhcmVhIGFuZCBwdXQgaXQgaW4gdGhlIGNvZGUgdmlldyBhcmVhLlxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX3NldEVkaXRvckRhdGFUb0NvZGVWaWV3OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvZGVDb250ZW50cyA9IHRoaXMuY29udmVydEhUTUxGb3JDb2RlVmlldyhjb250ZXh0LmVsZW1lbnQud3lzaXd5Zyk7XHJcbiAgICAgICAgICAgIGxldCBjb2RlVmFsdWUgPSAnJztcclxuXHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmZ1bGxQYWdlKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhdHRycyA9IHV0aWwuZ2V0QXR0cmlidXRlc1RvU3RyaW5nKHRoaXMuX3dkLmJvZHksIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgY29kZVZhbHVlID0gJzwhRE9DVFlQRSBodG1sPlxcbjxodG1sPlxcbicgKyB0aGlzLl93ZC5oZWFkLm91dGVySFRNTC5yZXBsYWNlKC8+KD8hXFxuKS9nLCAnPlxcbicpICsgJzxib2R5ICcgKyBhdHRycyArICc+XFxuJyArIGNvZGVDb250ZW50cyArICc8L2JvZHk+XFxuPC9odG1sPic7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb2RlVmFsdWUgPSBjb2RlQ29udGVudHM7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5jb2RlLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG4gICAgICAgICAgICBjb250ZXh0LmVsZW1lbnQud3lzaXd5Z0ZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9zZXRDb2RlVmlldyhjb2RlVmFsdWUpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDaGFuZ2VzIHRvIGZ1bGwgc2NyZWVuIG9yIGRlZmF1bHQgc2NyZWVuXHJcbiAgICAgICAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IGZ1bGwgc2NyZWVuIGJ1dHRvblxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRvZ2dsZUZ1bGxTY3JlZW46IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRvcEFyZWEgPSBjb250ZXh0LmVsZW1lbnQudG9wQXJlYTtcclxuICAgICAgICAgICAgY29uc3QgdG9vbGJhciA9IGNvbnRleHQuZWxlbWVudC50b29sYmFyO1xyXG4gICAgICAgICAgICBjb25zdCBlZGl0b3JBcmVhID0gY29udGV4dC5lbGVtZW50LmVkaXRvckFyZWE7XHJcbiAgICAgICAgICAgIGNvbnN0IHd5c2l3eWdGcmFtZSA9IGNvbnRleHQuZWxlbWVudC53eXNpd3lnRnJhbWU7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvZGUgPSBjb250ZXh0LmVsZW1lbnQuY29kZTtcclxuICAgICAgICAgICAgY29uc3QgX3ZhciA9IHRoaXMuX3ZhcmlhYmxlO1xyXG4gICAgICAgICAgICB0aGlzLmNvbnRyb2xsZXJzT2ZmKCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIV92YXIuaXNGdWxsU2NyZWVuKSB7XHJcbiAgICAgICAgICAgICAgICBfdmFyLmlzRnVsbFNjcmVlbiA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIF92YXIuX2Z1bGxTY3JlZW5BdHRycy5pbmxpbmUgPSB0aGlzLl9pc0lubGluZTtcclxuICAgICAgICAgICAgICAgIF92YXIuX2Z1bGxTY3JlZW5BdHRycy5iYWxsb29uID0gdGhpcy5faXNCYWxsb29uO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9pc0lubGluZSB8fCB0aGlzLl9pc0JhbGxvb24pIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9pc0lubGluZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2lzQmFsbG9vbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICBpZiAoISFvcHRpb25zLnRvb2xiYXJDb250YWluZXIpIGNvbnRleHQuZWxlbWVudC5yZWxhdGl2ZS5pbnNlcnRCZWZvcmUodG9vbGJhciwgZWRpdG9yQXJlYSk7XHJcblxyXG4gICAgICAgICAgICAgICAgdG9wQXJlYS5zdHlsZS5wb3NpdGlvbiA9ICdmaXhlZCc7XHJcbiAgICAgICAgICAgICAgICB0b3BBcmVhLnN0eWxlLnRvcCA9ICcwJztcclxuICAgICAgICAgICAgICAgIHRvcEFyZWEuc3R5bGUubGVmdCA9ICcwJztcclxuICAgICAgICAgICAgICAgIHRvcEFyZWEuc3R5bGUud2lkdGggPSAnMTAwJSc7XHJcbiAgICAgICAgICAgICAgICB0b3BBcmVhLnN0eWxlLm1heFdpZHRoID0gJzEwMCUnO1xyXG4gICAgICAgICAgICAgICAgdG9wQXJlYS5zdHlsZS5oZWlnaHQgPSAnMTAwJSc7XHJcbiAgICAgICAgICAgICAgICB0b3BBcmVhLnN0eWxlLnpJbmRleCA9ICcyMTQ3NDgzNjQ3JztcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoY29udGV4dC5lbGVtZW50Ll9zdGlja3lEdW1teS5zdHlsZS5kaXNwbGF5ICE9PSAoJ25vbmUnICYmICcnKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIF92YXIuX2Z1bGxTY3JlZW5BdHRycy5zdGlja3kgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5fc3RpY2t5RHVtbXkuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUNsYXNzKHRvb2xiYXIsICdzZS10b29sYmFyLXN0aWNreScpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIF92YXIuX2JvZHlPdmVyZmxvdyA9IF9kLmJvZHkuc3R5bGUub3ZlcmZsb3c7XHJcbiAgICAgICAgICAgICAgICBfZC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbic7XHJcblxyXG4gICAgICAgICAgICAgICAgX3Zhci5fZWRpdG9yQXJlYU9yaWdpbkNzc1RleHQgPSBlZGl0b3JBcmVhLnN0eWxlLmNzc1RleHQ7XHJcbiAgICAgICAgICAgICAgICBfdmFyLl93eXNpd3lnT3JpZ2luQ3NzVGV4dCA9IHd5c2l3eWdGcmFtZS5zdHlsZS5jc3NUZXh0O1xyXG4gICAgICAgICAgICAgICAgX3Zhci5fY29kZU9yaWdpbkNzc1RleHQgPSBjb2RlLnN0eWxlLmNzc1RleHQ7XHJcblxyXG4gICAgICAgICAgICAgICAgZWRpdG9yQXJlYS5zdHlsZS5jc3NUZXh0ID0gdG9vbGJhci5zdHlsZS5jc3NUZXh0ID0gJyc7XHJcbiAgICAgICAgICAgICAgICB3eXNpd3lnRnJhbWUuc3R5bGUuY3NzVGV4dCA9ICh3eXNpd3lnRnJhbWUuc3R5bGUuY3NzVGV4dC5tYXRjaCgvXFxzP2Rpc3BsYXkoXFxzKyk/OihcXHMrKT9bYS16QS1aXSs7LykgfHwgWycnXSlbMF07XHJcbiAgICAgICAgICAgICAgICBjb2RlLnN0eWxlLmNzc1RleHQgPSAoY29kZS5zdHlsZS5jc3NUZXh0Lm1hdGNoKC9cXHM/ZGlzcGxheShcXHMrKT86KFxccyspP1thLXpBLVpdKzsvKSB8fCBbJyddKVswXTtcclxuICAgICAgICAgICAgICAgIHRvb2xiYXIuc3R5bGUud2lkdGggPSB3eXNpd3lnRnJhbWUuc3R5bGUuaGVpZ2h0ID0gY29kZS5zdHlsZS5oZWlnaHQgPSAnMTAwJSc7XHJcbiAgICAgICAgICAgICAgICB0b29sYmFyLnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcclxuICAgICAgICAgICAgICAgIHRvb2xiYXIuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcblxyXG4gICAgICAgICAgICAgICAgX3Zhci5pbm5lckhlaWdodF9mdWxsU2NyZWVuID0gKF93LmlubmVySGVpZ2h0IC0gdG9vbGJhci5vZmZzZXRIZWlnaHQpO1xyXG4gICAgICAgICAgICAgICAgZWRpdG9yQXJlYS5zdHlsZS5oZWlnaHQgPSBfdmFyLmlubmVySGVpZ2h0X2Z1bGxTY3JlZW4gKyAncHgnO1xyXG5cclxuICAgICAgICAgICAgICAgIHV0aWwuY2hhbmdlRWxlbWVudChlbGVtZW50LmZpcnN0RWxlbWVudENoaWxkLCBpY29ucy5yZWR1Y3Rpb24pO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmlmcmFtZSAmJiBvcHRpb25zLmhlaWdodCA9PT0gJ2F1dG8nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWRpdG9yQXJlYS5zdHlsZS5vdmVyZmxvdyA9ICdhdXRvJztcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9pZnJhbWVBdXRvSGVpZ2h0KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgdXRpbC5hZGRDbGFzcyh0aGlzLl9zdHlsZUNvbW1hbmRNYXAuZnVsbFNjcmVlbiwgJ2FjdGl2ZScpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgX3Zhci5pc0Z1bGxTY3JlZW4gPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICB3eXNpd3lnRnJhbWUuc3R5bGUuY3NzVGV4dCA9IF92YXIuX3d5c2l3eWdPcmlnaW5Dc3NUZXh0O1xyXG4gICAgICAgICAgICAgICAgY29kZS5zdHlsZS5jc3NUZXh0ID0gX3Zhci5fY29kZU9yaWdpbkNzc1RleHQ7XHJcbiAgICAgICAgICAgICAgICB0b29sYmFyLnN0eWxlLmNzc1RleHQgPSAnJztcclxuICAgICAgICAgICAgICAgIGVkaXRvckFyZWEuc3R5bGUuY3NzVGV4dCA9IF92YXIuX2VkaXRvckFyZWFPcmlnaW5Dc3NUZXh0O1xyXG4gICAgICAgICAgICAgICAgdG9wQXJlYS5zdHlsZS5jc3NUZXh0ID0gX3Zhci5fb3JpZ2luQ3NzVGV4dDtcclxuICAgICAgICAgICAgICAgIF9kLmJvZHkuc3R5bGUub3ZlcmZsb3cgPSBfdmFyLl9ib2R5T3ZlcmZsb3c7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCEhb3B0aW9ucy50b29sYmFyQ29udGFpbmVyKSBvcHRpb25zLnRvb2xiYXJDb250YWluZXIuYXBwZW5kQ2hpbGQodG9vbGJhcik7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc3RpY2t5VG9vbGJhciA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVDbGFzcyh0b29sYmFyLCAnc2UtdG9vbGJhci1zdGlja3knKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoX3Zhci5fZnVsbFNjcmVlbkF0dHJzLnN0aWNreSAmJiAhb3B0aW9ucy50b29sYmFyQ29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Zhci5fZnVsbFNjcmVlbkF0dHJzLnN0aWNreSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5fc3RpY2t5RHVtbXkuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5hZGRDbGFzcyh0b29sYmFyLCBcInNlLXRvb2xiYXItc3RpY2t5XCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX2lzSW5saW5lID0gX3Zhci5fZnVsbFNjcmVlbkF0dHJzLmlubGluZTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2lzQmFsbG9vbiA9IF92YXIuX2Z1bGxTY3JlZW5BdHRycy5iYWxsb29uO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2lzSW5saW5lKSBldmVudC5fc2hvd1Rvb2xiYXJJbmxpbmUoKTtcclxuICAgICAgICAgICAgICAgIGlmICghIW9wdGlvbnMudG9vbGJhckNvbnRhaW5lcikgdXRpbC5yZW1vdmVDbGFzcyh0b29sYmFyLCAnc2UtdG9vbGJhci1iYWxsb29uJyk7XHJcblxyXG4gICAgICAgICAgICAgICAgZXZlbnQub25TY3JvbGxfd2luZG93KCk7XHJcbiAgICAgICAgICAgICAgICB1dGlsLmNoYW5nZUVsZW1lbnQoZWxlbWVudC5maXJzdEVsZW1lbnRDaGlsZCwgaWNvbnMuZXhwYW5zaW9uKTtcclxuXHJcbiAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUNsYXNzKHRoaXMuX3N0eWxlQ29tbWFuZE1hcC5mdWxsU2NyZWVuLCAnYWN0aXZlJyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZnVuY3Rpb25zLnRvZ2dsZUZ1bGxTY3JlZW4gPT09ICdmdW5jdGlvbicpIGZ1bmN0aW9ucy50b2dnbGVGdWxsU2NyZWVuKHRoaXMuX3ZhcmlhYmxlLmlzRnVsbFNjcmVlbiwgdGhpcyk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFByaW50cyB0aGUgY3VycmVudCBjb250ZW50cyBvZiB0aGUgZWRpdG9yLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHByaW50OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGlmcmFtZSA9IHV0aWwuY3JlYXRlRWxlbWVudCgnSUZSQU1FJyk7XHJcbiAgICAgICAgICAgIGlmcmFtZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgICAgICBfZC5ib2R5LmFwcGVuZENoaWxkKGlmcmFtZSk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBwcmludERvY3VtZW50ID0gdXRpbC5nZXRJZnJhbWVEb2N1bWVudChpZnJhbWUpO1xyXG4gICAgICAgICAgICBjb25zdCBjb250ZW50c0hUTUwgPSB0aGlzLmdldENvbnRlbnRzKHRydWUpO1xyXG4gICAgICAgICAgICBjb25zdCB3RG9jID0gdGhpcy5fd2Q7XHJcblxyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5pZnJhbWUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGFycnRzID0gb3B0aW9ucy5mdWxsUGFnZSA/IHV0aWwuZ2V0QXR0cmlidXRlc1RvU3RyaW5nKHdEb2MuYm9keSwgWydjb250ZW50ZWRpdGFibGUnXSkgOiAnY2xhc3M9XCInICsgb3B0aW9ucy5fZWRpdGFibGVDbGFzcyArICdcIic7XHJcblxyXG4gICAgICAgICAgICAgICAgcHJpbnREb2N1bWVudC53cml0ZSgnJyArXHJcbiAgICAgICAgICAgICAgICAgICAgJzwhRE9DVFlQRSBodG1sPjxodG1sPicgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8aGVhZD4nICtcclxuICAgICAgICAgICAgICAgICAgICB3RG9jLmhlYWQuaW5uZXJIVE1MICtcclxuICAgICAgICAgICAgICAgICAgICAnPC9oZWFkPicgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8Ym9keSAnICsgYXJydHMgKyAnPicgKyBjb250ZW50c0hUTUwgKyAnPC9ib2R5PicgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8L2h0bWw+J1xyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGxpbmtzID0gX2QuaGVhZC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnbGluaycpO1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc3R5bGVzID0gX2QuaGVhZC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc3R5bGUnKTtcclxuICAgICAgICAgICAgICAgIGxldCBsaW5rSFRNTCA9ICcnO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxpbmtzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGlua0hUTUwgKz0gbGlua3NbaV0ub3V0ZXJIVE1MO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHN0eWxlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGxpbmtIVE1MICs9IHN0eWxlc1tpXS5vdXRlckhUTUw7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcHJpbnREb2N1bWVudC53cml0ZSgnJyArXHJcbiAgICAgICAgICAgICAgICAgICAgJzwhRE9DVFlQRSBodG1sPjxodG1sPicgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8aGVhZD4nICtcclxuICAgICAgICAgICAgICAgICAgICBsaW5rSFRNTCArXHJcbiAgICAgICAgICAgICAgICAgICAgJzwvaGVhZD4nICtcclxuICAgICAgICAgICAgICAgICAgICAnPGJvZHkgY2xhc3M9XCInICsgb3B0aW9ucy5fZWRpdGFibGVDbGFzcyArICdcIj4nICsgY29udGVudHNIVE1MICsgJzwvYm9keT4nICtcclxuICAgICAgICAgICAgICAgICAgICAnPC9odG1sPidcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuc2hvd0xvYWRpbmcoKTtcclxuICAgICAgICAgICAgX3cuc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmcmFtZS5mb2N1cygpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIElFIG9yIEVkZ2VcclxuICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5pc0lFX0VkZ2UgfHwgISFfZC5kb2N1bWVudE1vZGUgfHwgISFfdy5TdHlsZU1lZGlhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudC5leGVjQ29tbWFuZCgncHJpbnQnLCBmYWxzZSwgbnVsbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnByaW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlciBicm93c2Vyc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wcmludCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1tTVU5FRElUT1IuY29yZS5wcmludC5mYWlsXSBlcnJvcjogJyArIGVycm9yKTtcclxuICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29yZS5jbG9zZUxvYWRpbmcoKTtcclxuICAgICAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW0oaWZyYW1lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgMTAwMCk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIE9wZW4gdGhlIHByZXZpZXcgd2luZG93LlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHByZXZpZXc6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29yZS5zdWJtZW51T2ZmKCk7XHJcbiAgICAgICAgICAgIGNvcmUuY29udGFpbmVyT2ZmKCk7XHJcbiAgICAgICAgICAgIGNvcmUuY29udHJvbGxlcnNPZmYoKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnRzSFRNTCA9IG9wdGlvbnMucHJldmlld1RlbXBsYXRlID8gb3B0aW9ucy5wcmV2aWV3VGVtcGxhdGUucmVwbGFjZSgvXFx7XFx7XFxzKmNvbnRlbnRzXFxzKlxcfVxcfS9pLCB0aGlzLmdldENvbnRlbnRzKHRydWUpKSA6IHRoaXMuZ2V0Q29udGVudHModHJ1ZSk7XHJcbiAgICAgICAgICAgIGNvbnN0IHdpbmRvd09iamVjdCA9IF93Lm9wZW4oJycsICdfYmxhbmsnKTtcclxuICAgICAgICAgICAgd2luZG93T2JqZWN0Lm1pbWVUeXBlID0gJ3RleHQvaHRtbCc7XHJcbiAgICAgICAgICAgIGNvbnN0IHcgPSBjb250ZXh0LmVsZW1lbnQud3lzaXd5Z0ZyYW1lLm9mZnNldFdpZHRoICsgJ3B4ICFpbXBvcnRhbnQnO1xyXG4gICAgICAgICAgICBjb25zdCB3RG9jID0gdGhpcy5fd2Q7XHJcblxyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5pZnJhbWUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGFycnRzID0gb3B0aW9ucy5mdWxsUGFnZSA/IHV0aWwuZ2V0QXR0cmlidXRlc1RvU3RyaW5nKHdEb2MuYm9keSwgWydjb250ZW50ZWRpdGFibGUnXSkgOiAnY2xhc3M9XCInICsgb3B0aW9ucy5fZWRpdGFibGVDbGFzcyArICdcIic7XHJcblxyXG4gICAgICAgICAgICAgICAgd2luZG93T2JqZWN0LmRvY3VtZW50LndyaXRlKCcnICtcclxuICAgICAgICAgICAgICAgICAgICAnPCFET0NUWVBFIGh0bWw+PGh0bWw+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgJzxoZWFkPicgK1xyXG4gICAgICAgICAgICAgICAgICAgIHdEb2MuaGVhZC5pbm5lckhUTUwgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8c3R5bGU+Ym9keSB7b3ZlcmZsb3c6YXV0byAhaW1wb3J0YW50OyB3aWR0aDonICsgdyArICc7IGJvcmRlcjoxcHggc29saWQgI2NjYzsgbWFyZ2luOiAxMHB4IGF1dG8gIWltcG9ydGFudDsgaGVpZ2h0OmF1dG8gIWltcG9ydGFudDt9PC9zdHlsZT4nICtcclxuICAgICAgICAgICAgICAgICAgICAnPC9oZWFkPicgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8Ym9keSAnICsgYXJydHMgKyAnPicgKyBjb250ZW50c0hUTUwgKyAnPC9ib2R5PicgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8L2h0bWw+J1xyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGxpbmtzID0gX2QuaGVhZC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnbGluaycpO1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc3R5bGVzID0gX2QuaGVhZC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc3R5bGUnKTtcclxuICAgICAgICAgICAgICAgIGxldCBsaW5rSFRNTCA9ICcnO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxpbmtzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGlua0hUTUwgKz0gbGlua3NbaV0ub3V0ZXJIVE1MO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHN0eWxlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGxpbmtIVE1MICs9IHN0eWxlc1tpXS5vdXRlckhUTUw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIHdpbmRvd09iamVjdC5kb2N1bWVudC53cml0ZSgnJyArXHJcbiAgICAgICAgICAgICAgICAgICAgJzwhRE9DVFlQRSBodG1sPjxodG1sPicgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8aGVhZD4nICtcclxuICAgICAgICAgICAgICAgICAgICAnPG1ldGEgY2hhcnNldD1cInV0Zi04XCIgLz4nICtcclxuICAgICAgICAgICAgICAgICAgICAnPG1ldGEgbmFtZT1cInZpZXdwb3J0XCIgY29udGVudD1cIndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xXCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgJzx0aXRsZT4nICsgbGFuZy50b29sYmFyLnByZXZpZXcgKyAnPC90aXRsZT4nICtcclxuICAgICAgICAgICAgICAgICAgICBsaW5rSFRNTCArXHJcbiAgICAgICAgICAgICAgICAgICAgJzwvaGVhZD4nICtcclxuICAgICAgICAgICAgICAgICAgICAnPGJvZHkgY2xhc3M9XCInICsgb3B0aW9ucy5fZWRpdGFibGVDbGFzcyArICdcIiBzdHlsZT1cIndpZHRoOicgKyB3ICsgJzsgYm9yZGVyOjFweCBzb2xpZCAjY2NjOyBtYXJnaW46MTBweCBhdXRvICFpbXBvcnRhbnQ7IGhlaWdodDphdXRvICFpbXBvcnRhbnQ7XCI+JyArIGNvbnRlbnRzSFRNTCArICc8L2JvZHk+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgJzwvaHRtbD4nXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIEhUTUwgc3RyaW5nXHJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd8dW5kZWZpbmVkfSBodG1sIEhUTUwgc3RyaW5nXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgc2V0Q29udGVudHM6IGZ1bmN0aW9uIChodG1sKSB7XHJcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlUmFuZ2UoKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnZlcnRWYWx1ZSA9IChodG1sID09PSBudWxsIHx8IGh0bWwgPT09IHVuZGVmaW5lZCkgPyAnJyA6IHRoaXMuY29udmVydENvbnRlbnRzRm9yRWRpdG9yKGh0bWwpO1xyXG4gICAgICAgICAgICB0aGlzLl9yZXNldENvbXBvbmVudHMoKTtcclxuXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5fdmFyaWFibGUuaXNDb2RlVmlldykge1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5lbGVtZW50Lnd5c2l3eWcuaW5uZXJIVE1MID0gY29udmVydFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgLy8gaGlzdG9yeSBzdGFja1xyXG4gICAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnB1c2goZmFsc2UpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmNvbnZlcnRIVE1MRm9yQ29kZVZpZXcoY29udmVydFZhbHVlKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3NldENvZGVWaWV3KHZhbHVlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBjb250ZW50cyBvZiB0aGUgaWZyYW1lJ3MgaGVhZCB0YWcgYW5kIGJvZHkgdGFnIHdoZW4gdXNpbmcgdGhlIFwiaWZyYW1lXCIgb3IgXCJmdWxsUGFnZVwiIG9wdGlvbi5cclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY3R4IHsgaGVhZDogSFRNTCBzdHJpbmcsIGJvZHk6IEhUTUwgc3RyaW5nfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHNldElmcmFtZUNvbnRlbnRzOiBmdW5jdGlvbiAoY3R4KSB7XHJcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5pZnJhbWUpIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgaWYgKGN0eC5oZWFkKSB0aGlzLl93ZC5oZWFkLmlubmVySFRNTCA9IGN0eC5oZWFkLnJlcGxhY2UoLzxzY3JpcHRcXHMqLio+Lio8XFwvc2NyaXB0Pi9nLCAnJyk7XHJcbiAgICAgICAgICAgIGlmIChjdHguYm9keSkgdGhpcy5fd2QuYm9keS5pbm5lckhUTUwgPSB0aGlzLmNvbnZlcnRDb250ZW50c0ZvckVkaXRvcihjdHguYm9keSk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIGN1cnJlbnQgY29udGVudHNcclxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IG9ubHlDb250ZW50cyBSZXR1cm4gb25seSB0aGUgY29udGVudHMgb2YgdGhlIGJvZHkgd2l0aG91dCBoZWFkZXJzIHdoZW4gdGhlIFwiZnVsbFBhZ2VcIiBvcHRpb24gaXMgdHJ1ZVxyXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3R9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0Q29udGVudHM6IGZ1bmN0aW9uIChvbmx5Q29udGVudHMpIHtcclxuICAgICAgICAgICAgY29uc3QgY29udGVudHMgPSBjb250ZXh0LmVsZW1lbnQud3lzaXd5Zy5pbm5lckhUTUw7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlckhUTUwgPSB1dGlsLmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xyXG4gICAgICAgICAgICByZW5kZXJIVE1MLmlubmVySFRNTCA9IGNvbnRlbnRzO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgZmlnY2FwdGlvbnMgPSB1dGlsLmdldExpc3RDaGlsZHJlbihyZW5kZXJIVE1MLCBmdW5jdGlvbiAoY3VycmVudCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIC9GSUdDQVBUSU9OL2kudGVzdChjdXJyZW50Lm5vZGVOYW1lKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gZmlnY2FwdGlvbnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGZpZ2NhcHRpb25zW2ldLnJlbW92ZUF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmZ1bGxQYWdlICYmICFvbmx5Q29udGVudHMpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGF0dHJzID0gdXRpbC5nZXRBdHRyaWJ1dGVzVG9TdHJpbmcodGhpcy5fd2QuYm9keSwgWydjb250ZW50ZWRpdGFibGUnXSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJzwhRE9DVFlQRSBodG1sPjxodG1sPicgKyB0aGlzLl93ZC5oZWFkLm91dGVySFRNTCArICc8Ym9keSAnICsgYXR0cnMgKyAnPicgKyByZW5kZXJIVE1MLmlubmVySFRNTCArICc8L2JvZHk+PC9odG1sPic7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVuZGVySFRNTC5pbm5lckhUTUw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gUmV0dXJucyBIVE1MIHN0cmluZyBhY2NvcmRpbmcgdG8gdGFnIHR5cGUgYW5kIGNvbmZpZ3VyYXRpb24uXHJcbiAgICAgICAgICogVXNlIG9ubHkgXCJjbGVhbkhUTUxcIlxyXG4gICAgICAgICAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBOb2RlXHJcbiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSByZXF1aXJlRm9ybWF0IElmIHRydWUsIHRleHQgbm9kZXMgdGhhdCBkbyBub3QgaGF2ZSBhIGZvcm1hdCBub2RlIGlzIHdyYXBwZWQgd2l0aCB0aGUgZm9ybWF0IHRhZy5cclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9tYWtlTGluZTogZnVuY3Rpb24gKG5vZGUsIHJlcXVpcmVGb3JtYXQpIHtcclxuICAgICAgICAgICAgY29uc3QgZGVmYXVsdFRhZyA9IG9wdGlvbnMuZGVmYXVsdFRhZztcclxuICAgICAgICAgICAgLy8gZWxlbWVudFxyXG4gICAgICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gMSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHV0aWwuX2Rpc2FsbG93ZWRUYWdzKG5vZGUpKSByZXR1cm4gJyc7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXJlcXVpcmVGb3JtYXQgfHwgKHV0aWwuaXNGb3JtYXRFbGVtZW50KG5vZGUpIHx8IHV0aWwuaXNSYW5nZUZvcm1hdEVsZW1lbnQobm9kZSkgfHwgdXRpbC5pc0NvbXBvbmVudChub2RlKSB8fCB1dGlsLmlzTWVkaWEobm9kZSkgfHwgKHV0aWwuaXNBbmNob3Iobm9kZSkgJiYgdXRpbC5pc01lZGlhKG5vZGUuZmlyc3RFbGVtZW50Q2hpbGQpKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5vdXRlckhUTUw7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAnPCcgKyBkZWZhdWx0VGFnICsgJz4nICsgbm9kZS5vdXRlckhUTUwgKyAnPC8nICsgZGVmYXVsdFRhZyArICc+JztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyB0ZXh0XHJcbiAgICAgICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09PSAzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXJlcXVpcmVGb3JtYXQpIHJldHVybiBub2RlLnRleHRDb250ZW50O1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdGV4dEFycmF5ID0gbm9kZS50ZXh0Q29udGVudC5zcGxpdCgvXFxuL2cpO1xyXG4gICAgICAgICAgICAgICAgbGV0IGh0bWwgPSAnJztcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCB0TGVuID0gdGV4dEFycmF5Lmxlbmd0aCwgdGV4dDsgaSA8IHRMZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHQgPSB0ZXh0QXJyYXlbaV0udHJpbSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0Lmxlbmd0aCA+IDApIGh0bWwgKz0gJzwnICsgZGVmYXVsdFRhZyArICc+JyArIHRleHQgKyAnPC8nICsgZGVmYXVsdFRhZyArICc+JztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBodG1sO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGNvbW1lbnRzXHJcbiAgICAgICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09PSA4ICYmIHRoaXMuX2FsbG93SFRNTENvbW1lbnRzKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJzwhLS0nICsgbm9kZS50ZXh0Q29udGVudC50cmltKCkgKyAnLS0+JztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBSZW1vdmVzIGF0dHJpYnV0ZSB2YWx1ZXMgc3VjaCBhcyBzdHlsZSBhbmQgY29udmVydHMgdGFncyB0aGF0IGRvIG5vdCBjb25mb3JtIHRvIHRoZSBcImh0bWw1XCIgc3RhbmRhcmQuXHJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQgXHJcbiAgICAgICAgICogQHJldHVybnMge1N0cmluZ30gSFRNTCBzdHJpbmdcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF90YWdDb252ZXJ0b3I6IGZ1bmN0aW9uICh0ZXh0KSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5fZGlzYWxsb3dlZFRleHRUYWdzUmVnRXhwKSByZXR1cm4gdGV4dDtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGVjID0geydiJzogJ3N0cm9uZycsICdpJzogJ2VtJywgJ2lucyc6ICd1JywgJ3N0cmlrZSc6ICdkZWwnLCAncyc6ICdkZWwnfTtcclxuICAgICAgICAgICAgcmV0dXJuIHRleHQucmVwbGFjZSh0aGlzLl9kaXNhbGxvd2VkVGV4dFRhZ3NSZWdFeHAsIGZ1bmN0aW9uIChtLCB0LCBuKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdCArICh0eXBlb2YgZWNbbl0gPT09ICdzdHJpbmcnID8gZWNbbl0gOiBuKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIERlbGV0ZSBkaXNhbGxvd2VkIHRhZ3NcclxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gaHRtbCBIVE1MIHN0cmluZ1xyXG4gICAgICAgICAqIEByZXR1cm5zIHtTdHJpbmd9XHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfZGVsZXRlRGlzYWxsb3dlZFRhZ3M6IGZ1bmN0aW9uIChodG1sKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBodG1sXHJcbiAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxuL2csICcnKVxyXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoLzwoc2NyaXB0fHN0eWxlKS4qPihcXG58LikqPFxcLyhzY3JpcHR8c3R5bGUpPi9naSwgJycpXHJcbiAgICAgICAgICAgICAgICAucmVwbGFjZSgvPFthLXowLTldK1xcOlthLXowLTldK1tePl5cXC9dKj5bXj5dKjxcXC9bYS16MC05XStcXDpbYS16MC05XSs+L2dpLCAnJylcclxuICAgICAgICAgICAgICAgIC5yZXBsYWNlKHRoaXMuZWRpdG9yVGFnc1doaXRlbGlzdFJlZ0V4cCwgJycpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBHZXRzIHRoZSBjbGVhbiBIVE1MIGNvZGUgZm9yIGVkaXRvclxyXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBodG1sIEhUTUwgc3RyaW5nXHJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfG51bGx9IHdoaXRlbGlzdCBSZWd1bGFyIGV4cHJlc3Npb24gb2YgYWxsb3dlZCB0YWdzLlxyXG4gICAgICAgICAqIFJlZ0V4cCBvYmplY3QgaXMgY3JlYXRlIGJ5IHV0aWwuY3JlYXRlVGFnc1doaXRlbGlzdCBtZXRob2QuIChjb3JlLnBhc3RlVGFnc1doaXRlbGlzdFJlZ0V4cClcclxuICAgICAgICAgKiBAcmV0dXJucyB7U3RyaW5nfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNsZWFuSFRNTDogZnVuY3Rpb24gKGh0bWwsIHdoaXRlbGlzdCkge1xyXG4gICAgICAgICAgICBodG1sID0gdGhpcy5fZGVsZXRlRGlzYWxsb3dlZFRhZ3MoaHRtbClcclxuICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oPFthLXpBLVowLTldKylbXj5dKig/PT4pL2csIGZ1bmN0aW9uIChtLCB0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKC9ePFthLXowLTldK1xcOlthLXowLTldKy9pLnRlc3QobSkpIHJldHVybiBtO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBsZXQgdiA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdEF0dHIgPSB0aGlzLl9hdHRyaWJ1dGVzVGFnc1doaXRlbGlzdFt0Lm1hdGNoKC8oPyE8KVthLXpBLVowLTldKy8pWzBdLnRvTG93ZXJDYXNlKCldO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0QXR0cikgdiA9IG0ubWF0Y2godEF0dHIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgdiA9IG0ubWF0Y2godGhpcy5fYXR0cmlidXRlc1doaXRlbGlzdFJlZ0V4cCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICgvPHNwYW4vaS50ZXN0KHQpICYmICghdiB8fCAhL3N0eWxlPS9pLnRlc3Qodi50b1N0cmluZygpKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3YgPSBtLm1hdGNoKC9zdHlsZVxccyo9XFxzKlwiW15cIl0qXCIvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN2KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXYpIHYgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHYucHVzaChzdlswXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh2KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSB2Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoL15jbGFzcz1cIig/IShfX3NlX198c2UtfGthdGV4KSkvLnRlc3QodltpXSkpIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdCArPSAnICcgKyB2W2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdDtcclxuICAgICAgICAgICAgICAgIH0uYmluZCh0aGlzKSk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBkb20gPSBfZC5jcmVhdGVSYW5nZSgpLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChodG1sKTtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHV0aWwuX2NvbnNpc3RlbmN5Q2hlY2tPZkhUTUwoZG9tLCB0aGlzLl9odG1sQ2hlY2tXaGl0ZWxpc3RSZWdFeHApO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdbU1VORURJVE9SLmNsZWFuSFRNTC5jb25zaXN0ZW5jeUNoZWNrLmZhaWxdICcgKyBlcnJvcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGlmICh0aGlzLm1hbmFnZWRUYWdzSW5mbyAmJiB0aGlzLm1hbmFnZWRUYWdzSW5mby5xdWVyeSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdGV4dENvbXBMaXN0ID0gZG9tLnF1ZXJ5U2VsZWN0b3JBbGwodGhpcy5tYW5hZ2VkVGFnc0luZm8ucXVlcnkpO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHRleHRDb21wTGlzdC5sZW5ndGgsIGluaXRNZXRob2QsIGNsYXNzTGlzdDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NMaXN0ID0gW10uc2xpY2UuY2FsbCh0ZXh0Q29tcExpc3RbaV0uY2xhc3NMaXN0KTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBjID0gMCwgY0xlbiA9IGNsYXNzTGlzdC5sZW5ndGg7IGMgPCBjTGVuOyBjKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdE1ldGhvZCA9IHRoaXMubWFuYWdlZFRhZ3NJbmZvLm1hcFtjbGFzc0xpc3RbY11dO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5pdE1ldGhvZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5pdE1ldGhvZCh0ZXh0Q29tcExpc3RbaV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGRvbVRyZWUgPSBkb20uY2hpbGROb2RlcztcclxuICAgICAgICAgICAgbGV0IGNsZWFuSFRNTCA9ICcnO1xyXG4gICAgICAgICAgICBsZXQgcmVxdWlyZUZvcm1hdCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGRvbVRyZWUubGVuZ3RoLCB0OyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIHQgPSBkb21UcmVlW2ldO1xyXG4gICAgICAgICAgICAgICAgaWYgKHQubm9kZVR5cGUgPT09IDEgJiYgIXV0aWwuaXNUZXh0U3R5bGVFbGVtZW50KHQpICYmICF1dGlsLmlzQnJlYWsodCkgJiYgIXV0aWwuX2Rpc2FsbG93ZWRUYWdzKHQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVxdWlyZUZvcm1hdCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBkb21UcmVlLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBjbGVhbkhUTUwgKz0gdGhpcy5fbWFrZUxpbmUoZG9tVHJlZVtpXSwgcmVxdWlyZUZvcm1hdCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNsZWFuSFRNTCA9IHV0aWwuaHRtbFJlbW92ZVdoaXRlU3BhY2UoY2xlYW5IVE1MKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RhZ0NvbnZlcnRvcighY2xlYW5IVE1MID8gaHRtbCA6ICF3aGl0ZWxpc3QgPyBjbGVhbkhUTUwgOiBjbGVhbkhUTUwucmVwbGFjZSh0eXBlb2Ygd2hpdGVsaXN0ID09PSAnc3RyaW5nJyA/IHV0aWwuY3JlYXRlVGFnc1doaXRlbGlzdCh3aGl0ZWxpc3QpIDogd2hpdGVsaXN0LCAnJykpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBjb250ZW50cyBpbnRvIGEgZm9ybWF0IHRoYXQgY2FuIGJlIHBsYWNlZCBpbiBhbiBlZGl0b3JcclxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gY29udGVudHMgY29udGVudHNcclxuICAgICAgICAgKiBAcmV0dXJucyB7U3RyaW5nfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNvbnZlcnRDb250ZW50c0ZvckVkaXRvcjogZnVuY3Rpb24gKGNvbnRlbnRzKSB7XHJcbiAgICAgICAgICAgIGNvbnRlbnRzID0gdGhpcy5fZGVsZXRlRGlzYWxsb3dlZFRhZ3MoY29udGVudHMpXHJcbiAgICAgICAgICAgICAgICAucmVwbGFjZSgvKDxbYS16QS1aMC05XSspW14+XSooPz0+KS9nLCBmdW5jdGlvbiAobSwgdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgvXjxbYS16MC05XStcXDpbYS16MC05XSsvaS50ZXN0KG0pKSByZXR1cm4gbTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHYgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRBdHRyID0gdGhpcy5fYXR0cmlidXRlc1RhZ3NXaGl0ZWxpc3RbdC5tYXRjaCgvKD8hPClbYS16QS1aMC05XSsvKVswXS50b0xvd2VyQ2FzZSgpXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodEF0dHIpIHYgPSBtLm1hdGNoKHRBdHRyKTtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHYgPSBtLm1hdGNoKHRoaXMuX2F0dHJpYnV0ZXNXaGl0ZWxpc3RSZWdFeHApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoLzxzcGFuL2kudGVzdCh0KSAmJiAoIXYgfHwgIS9zdHlsZT0vaS50ZXN0KHYudG9TdHJpbmcoKSkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN2ID0gbS5tYXRjaCgvc3R5bGVcXHMqPVxccypcIlteXCJdKlwiLyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF2KSB2ID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2LnB1c2goc3ZbMF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAodikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gdi5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdCArPSAnICcgKyB2W2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdDtcclxuICAgICAgICAgICAgICAgIH0uYmluZCh0aGlzKSk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBkb20gPSBfZC5jcmVhdGVSYW5nZSgpLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCh0aGlzLl9kZWxldGVEaXNhbGxvd2VkVGFncyhjb250ZW50cykpO1xyXG5cclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHV0aWwuX2NvbnNpc3RlbmN5Q2hlY2tPZkhUTUwoZG9tLCB0aGlzLl9odG1sQ2hlY2tXaGl0ZWxpc3RSZWdFeHApO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdbU1VORURJVE9SLmNvbnZlcnRDb250ZW50c0ZvckVkaXRvci5jb25zaXN0ZW5jeUNoZWNrLmZhaWxdICcgKyBlcnJvcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGNvbnN0IGRvbVRyZWUgPSBkb20uY2hpbGROb2RlcztcclxuICAgICAgICAgICAgbGV0IGNsZWFuSFRNTCA9ICcnO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gZG9tVHJlZS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgY2xlYW5IVE1MICs9IHRoaXMuX21ha2VMaW5lKGRvbVRyZWVbaV0sIHRydWUpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoY2xlYW5IVE1MLmxlbmd0aCA9PT0gMCkgcmV0dXJuICc8JyArIG9wdGlvbnMuZGVmYXVsdFRhZyArICc+PGJyPjwvJyArIG9wdGlvbnMuZGVmYXVsdFRhZyArICc+JztcclxuXHJcbiAgICAgICAgICAgIGNsZWFuSFRNTCA9IHV0aWwuaHRtbFJlbW92ZVdoaXRlU3BhY2UoY2xlYW5IVE1MKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RhZ0NvbnZlcnRvcihjbGVhbkhUTUwpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyB3eXNpd3lnIGFyZWEgZWxlbWVudCBpbnRvIGEgZm9ybWF0IHRoYXQgY2FuIGJlIHBsYWNlZCBpbiBhbiBlZGl0b3Igb2YgY29kZSB2aWV3IG1vZGVcclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR8U3RyaW5nfSBodG1sIFdZU0lXWUcgZWxlbWVudCAoY29udGV4dC5lbGVtZW50Lnd5c2l3eWcpIG9yIEhUTUwgc3RyaW5nLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtTdHJpbmd9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgY29udmVydEhUTUxGb3JDb2RlVmlldzogZnVuY3Rpb24gKGh0bWwpIHtcclxuICAgICAgICAgICAgbGV0IHJldHVybkhUTUwgPSAnJztcclxuICAgICAgICAgICAgY29uc3Qgd1JlZ0V4cCA9IF93LlJlZ0V4cDtcclxuICAgICAgICAgICAgY29uc3QgYnJSZWcgPSBuZXcgd1JlZ0V4cCgnXihCTE9DS1FVT1RFfFBSRXxUQUJMRXxUSEVBRHxUQk9EWXxUUnxUSHxURHxPTHxVTHxJTUd8SUZSQU1FfFZJREVPfEFVRElPfEZJR1VSRXxGSUdDQVBUSU9OfEhSfEJSfENBTlZBU3xTRUxFQ1QpJCcsICdpJyk7XHJcbiAgICAgICAgICAgIGNvbnN0IGlzRm9ybWF0RWxlbWVudCA9IHV0aWwuaXNGb3JtYXRFbGVtZW50LmJpbmQodXRpbCk7XHJcbiAgICAgICAgICAgIGNvbnN0IHdEb2MgPSB0eXBlb2YgaHRtbCA9PT0gJ3N0cmluZycgPyBfZC5jcmVhdGVSYW5nZSgpLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChodG1sKSA6IGh0bWw7XHJcblxyXG4gICAgICAgICAgICBsZXQgaW5kZW50U2l6ZSA9IHRoaXMuX3ZhcmlhYmxlLmNvZGVJbmRlbnQgKiAxO1xyXG4gICAgICAgICAgICBpbmRlbnRTaXplID0gaW5kZW50U2l6ZSA+IDAgPyBuZXcgX3cuQXJyYXkoaW5kZW50U2l6ZSArIDEpLmpvaW4oJyAnKSA6ICcnO1xyXG5cclxuICAgICAgICAgICAgKGZ1bmN0aW9uIHJlY3Vyc2lvbkZ1bmMgKGVsZW1lbnQsIGluZGVudCwgbGluZUJSKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IGVsZW1lbnQuY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRSZWdUZXN0ID0gYnJSZWcudGVzdChlbGVtZW50Lm5vZGVOYW1lKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRJbmRlbnQgPSAoZWxlbWVudFJlZ1Rlc3QgPyBpbmRlbnQgOiAnJyk7XHJcblxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNoaWxkcmVuLmxlbmd0aCwgbm9kZSwgYnIsIG5vZGVSZWdUZXN0OyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBub2RlID0gY2hpbGRyZW5baV07XHJcbiAgICAgICAgICAgICAgICAgICAgbm9kZVJlZ1Rlc3QgPSBiclJlZy50ZXN0KG5vZGUubm9kZU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyID0gbm9kZVJlZ1Rlc3QgPyAnXFxuJyA6ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgIGxpbmVCUiA9IGlzRm9ybWF0RWxlbWVudChub2RlKSAmJiAhZWxlbWVudFJlZ1Rlc3QgJiYgIS9eKFRIfFREKSQvaS50ZXN0KGVsZW1lbnQubm9kZU5hbWUpID8gJ1xcbicgOiAnJztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IDgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuSFRNTCArPSAnXFxuPCEtLSAnICsgbm9kZS50ZXh0Q29udGVudC50cmltKCkgKyAnIC0tPicgKyBicjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09PSAzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybkhUTUwgKz0gdXRpbC5fSFRNTENvbnZlcnRvcigoL15cXG4rJC8udGVzdChub2RlLmRhdGEpID8gJycgOiBub2RlLmRhdGEpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlLmNoaWxkTm9kZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybkhUTUwgKz0gKC9eSFIkL2kudGVzdChub2RlLm5vZGVOYW1lKSA/ICdcXG4nIDogJycpICsgZWxlbWVudEluZGVudCArIG5vZGUub3V0ZXJIVE1MICsgYnI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICBub2RlLmlubmVySFRNTCA9IG5vZGUuaW5uZXJIVE1MO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhZyA9IG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm5IVE1MICs9IChsaW5lQlIgfHwgKGVsZW1lbnRSZWdUZXN0ID8gJycgOiBicikpICsgKGVsZW1lbnRJbmRlbnQgfHwgbm9kZVJlZ1Rlc3QgPyBpbmRlbnQgOiAnJykgKyBub2RlLm91dGVySFRNTC5tYXRjaCh3UmVnRXhwKCc8JyArIHRhZyArICdbXj5dKj4nLCAnaScpKVswXSArIGJyO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlY3Vyc2lvbkZ1bmMobm9kZSwgaW5kZW50ICsgaW5kZW50U2l6ZSwgJycpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybkhUTUwgKz0gKG5vZGVSZWdUZXN0ID8gaW5kZW50IDogJycpICsgJzwvJyArIHRhZyArICc+JyArIChsaW5lQlIgfHwgYnIgfHwgZWxlbWVudFJlZ1Rlc3QgPyAnXFxuJyA6ICcnIHx8IC9eKFRIfFREKSQvaS50ZXN0KG5vZGUubm9kZU5hbWUpID8gJ1xcbicgOiAnJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0od0RvYywgJycsICdcXG4nKSk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcmV0dXJuSFRNTC50cmltKCkgKyAnXFxuJztcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQWRkIGFuIGV2ZW50IHRvIGRvY3VtZW50LlxyXG4gICAgICAgICAqIFdoZW4gY3JlYXRlZCBhcyBhbiBJZnJhbWUsIHRoZSBzYW1lIGV2ZW50IGlzIGFkZGVkIHRvIHRoZSBkb2N1bWVudCBpbiB0aGUgSWZyYW1lLlxyXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIEV2ZW50IHR5cGVcclxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBFdmVudCBsaXN0ZW5lclxyXG4gICAgICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gdXNlQ2FwdHVyZSBVc2UgZXZlbnQgY2FwdHVyZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGFkZERvY0V2ZW50OiBmdW5jdGlvbiAodHlwZSwgbGlzdGVuZXIsIHVzZUNhcHR1cmUpIHtcclxuICAgICAgICAgICAgX2QuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lciwgdXNlQ2FwdHVyZSk7XHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmlmcmFtZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fd2QuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gUmVtb3ZlIGV2ZW50cyBmcm9tIGRvY3VtZW50LlxyXG7CoCAgICAgICAgKiBXaGVuIGNyZWF0ZWQgYXMgYW4gSWZyYW1lLCB0aGUgZXZlbnQgb2YgdGhlIGRvY3VtZW50IGluc2lkZSB0aGUgSWZyYW1lIGlzIGFsc28gcmVtb3ZlZC5cclxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSBFdmVudCB0eXBlXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgRXZlbnQgbGlzdGVuZXJcclxuICAgICAgICAgKi9cclxuICAgICAgICByZW1vdmVEb2NFdmVudDogZnVuY3Rpb24gKHR5cGUsIGxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgIF9kLnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpO1xyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5pZnJhbWUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3dkLnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFRoZSBjdXJyZW50IG51bWJlciBvZiBjaGFyYWN0ZXJzIGlzIGNvdW50ZWQgYW5kIGRpc3BsYXllZC5cclxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXRUZXh0IFRleHQgYWRkZWQuXHJcbiAgICAgICAgICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfY2hhckNvdW50OiBmdW5jdGlvbiAoaW5wdXRUZXh0KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG1heENoYXJDb3VudCA9IG9wdGlvbnMubWF4Q2hhckNvdW50O1xyXG4gICAgICAgICAgICBjb25zdCBjb3VudFR5cGUgPSBvcHRpb25zLmNoYXJDb3VudGVyVHlwZTtcclxuICAgICAgICAgICAgbGV0IG5leHRDaGFyQ291bnQgPSAwO1xyXG4gICAgICAgICAgICBpZiAoISFpbnB1dFRleHQpIG5leHRDaGFyQ291bnQgPSB0aGlzLmdldENoYXJMZW5ndGgoaW5wdXRUZXh0LCBjb3VudFR5cGUpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fc2V0Q2hhckNvdW50KCk7XHJcblxyXG4gICAgICAgICAgICBpZiAobWF4Q2hhckNvdW50ID4gMCkge1xyXG4gICAgICAgICAgICAgICAgbGV0IG92ZXIgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gZnVuY3Rpb25zLmdldENoYXJDb3VudChjb3VudFR5cGUpO1xyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICBpZiAoY291bnQgPiBtYXhDaGFyQ291bnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBvdmVyID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobmV4dENoYXJDb3VudCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZWRpdG9yUmFuZ2UoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSB0aGlzLmdldFJhbmdlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuZE9mZiA9IHJhbmdlLmVuZE9mZnNldCAtIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRleHQgPSB0aGlzLmdldFNlbGVjdGlvbk5vZGUoKS50ZXh0Q29udGVudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2xpY2VQb3NpdGlvbiA9IHJhbmdlLmVuZE9mZnNldCAtIChjb3VudCAtIG1heENoYXJDb3VudCk7XHJcbiAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRTZWxlY3Rpb25Ob2RlKCkudGV4dENvbnRlbnQgPSB0ZXh0LnNsaWNlKDAsIHNsaWNlUG9zaXRpb24gPCAwID8gMCA6IHNsaWNlUG9zaXRpb24pICsgdGV4dC5zbGljZShyYW5nZS5lbmRPZmZzZXQsIHRleHQubGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRSYW5nZShyYW5nZS5lbmRDb250YWluZXIsIGVuZE9mZiwgcmFuZ2UuZW5kQ29udGFpbmVyLCBlbmRPZmYpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKGNvdW50ICsgbmV4dENoYXJDb3VudCkgPiBtYXhDaGFyQ291bnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBvdmVyID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAob3Zlcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhbGxDb3VudGVyQmxpbmsoKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobmV4dENoYXJDb3VudCA+IDApIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFdoZW4gXCJlbGVtZW50XCIgaXMgYWRkZWQsIGlmIGl0IGlzIGdyZWF0ZXIgdGhhbiBcIm9wdGlvbnMubWF4Q2hhckNvdW50XCIsIGZhbHNlIGlzIHJldHVybmVkLlxyXG4gICAgICAgICAqIEBwYXJhbSB7Tm9kZXxTdHJpbmd9IGVsZW1lbnQgRWxlbWVudCBub2RlIG9yIFN0cmluZy5cclxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ3xudWxsfSBjaGFyQ291bnRlclR5cGUgY2hhckNvdW50ZXJUeXBlLiBJZiBpdCBpcyBudWxsLCB0aGUgb3B0aW9ucy5jaGFyQ291bnRlclR5cGVcclxuICAgICAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBjaGVja0NoYXJDb3VudDogZnVuY3Rpb24gKGVsZW1lbnQsIGNoYXJDb3VudGVyVHlwZSkge1xyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5tYXhDaGFyQ291bnQpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNvdW50VHlwZSA9IGNoYXJDb3VudGVyVHlwZSB8fCBvcHRpb25zLmNoYXJDb3VudGVyVHlwZTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IHRoaXMuZ2V0Q2hhckxlbmd0aCgodHlwZW9mIGVsZW1lbnQgPT09ICdzdHJpbmcnID8gZWxlbWVudCA6IHRoaXMuX2NoYXJUeXBlSFRNTCA/IGVsZW1lbnQub3V0ZXJIVE1MIDogZWxlbWVudC50ZXh0Q29udGVudCksIGNvdW50VHlwZSk7XHJcbiAgICAgICAgICAgICAgICBpZiAobGVuZ3RoID4gMCAmJiBsZW5ndGggKyBmdW5jdGlvbnMuZ2V0Q2hhckNvdW50KGNvdW50VHlwZSkgPiBvcHRpb25zLm1heENoYXJDb3VudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhbGxDb3VudGVyQmxpbmsoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBjb250ZW50LlxyXG4gICAgICAgICAqIERlcGVuZGluZyBvbiB0aGUgb3B0aW9uLCB0aGUgbGVuZ3RoIG9mIHRoZSBjaGFyYWN0ZXIgaXMgdGFrZW4uIChjaGFyQ291bnRlclR5cGUpXHJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGNvbnRlbnQgQ29udGVudCB0byBjb3VudFxyXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjaGFyQ291bnRlclR5cGUgb3B0aW9ucy5jaGFyQ291bnRlclR5cGVcclxuICAgICAgICAgKiBAcmV0dXJucyB7TnVtYmVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldENoYXJMZW5ndGg6IGZ1bmN0aW9uIChjb250ZW50LCBjaGFyQ291bnRlclR5cGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIC9ieXRlLy50ZXN0KGNoYXJDb3VudGVyVHlwZSkgPyB1dGlsLmdldEJ5dGVMZW5ndGgoY29udGVudCkgOiBjb250ZW50Lmxlbmd0aDtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gU2V0IHRoZSBjaGFyIGNvdW50IHRvIGNoYXJDb3VudGVyIGVsZW1lbnQgdGV4dENvbnRlbnQuXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfc2V0Q2hhckNvdW50OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChjb250ZXh0LmVsZW1lbnQuY2hhckNvdW50ZXIpIHtcclxuICAgICAgICAgICAgICAgIF93LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyBjb250ZXh0LmVsZW1lbnQuY2hhckNvdW50ZXIudGV4dENvbnRlbnQgPSBmdW5jdGlvbnMuZ2V0Q2hhckNvdW50KG9wdGlvbnMuY2hhckNvdW50ZXJUeXBlKTsgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gVGhlIGNoYXJhY3RlciBjb3VudGVyIGJsaW5rcy5cclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9jYWxsQ291bnRlckJsaW5rOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNoYXJXcmFwcGVyID0gY29udGV4dC5lbGVtZW50LmNoYXJXcmFwcGVyO1xyXG4gICAgICAgICAgICBpZiAoY2hhcldyYXBwZXIgJiYgIXV0aWwuaGFzQ2xhc3MoY2hhcldyYXBwZXIsICdzZS1ibGluaycpKSB7XHJcbiAgICAgICAgICAgICAgICB1dGlsLmFkZENsYXNzKGNoYXJXcmFwcGVyLCAnc2UtYmxpbmsnKTtcclxuICAgICAgICAgICAgICAgIF93LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlQ2xhc3MoY2hhcldyYXBwZXIsICdzZS1ibGluaycpO1xyXG4gICAgICAgICAgICAgICAgfSwgNjAwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDaGVjayB0aGUgY29tcG9uZW50cyBzdWNoIGFzIGltYWdlIGFuZCB2aWRlbyBhbmQgbW9kaWZ5IHRoZW0gYWNjb3JkaW5nIHRvIHRoZSBmb3JtYXQuXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfY2hlY2tDb21wb25lbnRzOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSB0aGlzLl9maWxlSW5mb1BsdWdpbnNDaGVjay5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZmlsZUluZm9QbHVnaW5zQ2hlY2tbaV0oKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBJbml0aWFsaXplIHRoZSBpbmZvcm1hdGlvbiBvZiB0aGUgY29tcG9uZW50cy5cclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9yZXNldENvbXBvbmVudHM6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHRoaXMuX2ZpbGVJbmZvUGx1Z2luc1Jlc2V0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9maWxlSW5mb1BsdWdpbnNSZXNldFtpXSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFNldCBtZXRob2QgaW4gdGhlIGNvZGUgdmlldyBhcmVhXHJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlIEhUTUwgc3RyaW5nXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfc2V0Q29kZVZpZXc6IGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5jb2RlTWlycm9yRWRpdG9yKSB7XHJcbiAgICAgICAgICAgICAgICBvcHRpb25zLmNvZGVNaXJyb3JFZGl0b3IuZ2V0RG9jKCkuc2V0VmFsdWUodmFsdWUpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LmNvZGUudmFsdWUgPSB2YWx1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBHZXQgbWV0aG9kIGluIHRoZSBjb2RlIHZpZXcgYXJlYVxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX2dldENvZGVWaWV3OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmNvZGVNaXJyb3JFZGl0b3IgPyBvcHRpb25zLmNvZGVNaXJyb3JFZGl0b3IuZ2V0RG9jKCkuZ2V0VmFsdWUoKSA6IGNvbnRleHQuZWxlbWVudC5jb2RlLnZhbHVlO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBJbml0aWFsaXogY29yZSB2YXJpYWJsZVxyXG4gICAgICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVsb2FkIElzIHJlbG9vYWQ/XHJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IF9pbml0SFRNTCBpbml0aWFsIGh0bWwgc3RyaW5nXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfaW5pdDogZnVuY3Rpb24gKHJlbG9hZCwgX2luaXRIVE1MKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHdSZWdFeHAgPSBfdy5SZWdFeHA7XHJcbiAgICAgICAgICAgIHRoaXMuX3d3ID0gb3B0aW9ucy5pZnJhbWUgPyBjb250ZXh0LmVsZW1lbnQud3lzaXd5Z0ZyYW1lLmNvbnRlbnRXaW5kb3cgOiBfdztcclxuICAgICAgICAgICAgdGhpcy5fd2QgPSBfZDtcclxuICAgICAgICAgICAgdGhpcy5fY2hhclR5cGVIVE1MID0gb3B0aW9ucy5jaGFyQ291bnRlclR5cGUgPT09ICdieXRlLWh0bWwnO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFvcHRpb25zLmlmcmFtZSAmJiB0eXBlb2YgX3cuU2hhZG93Um9vdCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICAgICAgbGV0IGNoaWxkID0gY29udGV4dC5lbGVtZW50Lnd5c2l3eWdGcmFtZTtcclxuICAgICAgICAgICAgICAgIHdoaWxlIChjaGlsZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZC5zaGFkb3dSb290KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NoYWRvd1Jvb3QgPSBjaGlsZC5zaGFkb3dSb290O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoaWxkIGluc3RhbmNlb2YgX3cuU2hhZG93Um9vdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zaGFkb3dSb290ID0gY2hpbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIHNldCBkaXNhbGxvdyB0ZXh0IG5vZGVzXHJcbiAgICAgICAgICAgIGNvbnN0IGRpc2FsbG93VGV4dFRhZ3MgPSBbJ2InLCAnaScsICdpbnMnLCAncycsICdzdHJpa2UnXTtcclxuICAgICAgICAgICAgY29uc3QgYWxsb3dUZXh0VGFncyA9ICFvcHRpb25zLmFkZFRhZ3NXaGl0ZWxpc3QgPyBbXSA6IG9wdGlvbnMuYWRkVGFnc1doaXRlbGlzdC5zcGxpdCgnfCcpLmZpbHRlcihmdW5jdGlvbiAodikgeyByZXR1cm4gL2J8aXxpbnN8c3xzdHJpa2UvaS50ZXN0KHYpOyB9KTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhbGxvd1RleHRUYWdzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBkaXNhbGxvd1RleHRUYWdzLnNwbGljZShkaXNhbGxvd1RleHRUYWdzLmluZGV4T2YoYWxsb3dUZXh0VGFnc1tpXS50b0xvd2VyQ2FzZSgpKSwgMSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fZGlzYWxsb3dlZFRleHRUYWdzUmVnRXhwID0gZGlzYWxsb3dUZXh0VGFncy5sZW5ndGggPT09IDAgPyBudWxsIDogbmV3IHdSZWdFeHAoJyg8XFxcXC8/KSgnICsgZGlzYWxsb3dUZXh0VGFncy5qb2luKCd8JykgKyAnKVxcXFxiXFxcXHMqKD86W14+XjxdKyk/XFxcXHMqKD89PiknLCAnZ2knKTtcclxuXHJcbiAgICAgICAgICAgIC8vIHNldCB3aGl0ZWxpc3RcclxuICAgICAgICAgICAgY29uc3QgZGVmYXVsdEF0dHIgPSAnY29udGVudGVkaXRhYmxlfGNvbHNwYW58cm93c3Bhbnx0YXJnZXR8aHJlZnxzcmN8Y2xhc3N8dHlwZXxjb250cm9sc3xkYXRhLWZvcm1hdHxkYXRhLXNpemV8ZGF0YS1maWxlLXNpemV8ZGF0YS1maWxlLW5hbWV8ZGF0YS1vcmlnaW58ZGF0YS1hbGlnbnxkYXRhLWltYWdlLWxpbmt8ZGF0YS1yb3RhdGV8ZGF0YS1wcm9wb3J0aW9ufGRhdGEtcGVyY2VudGFnZXxvcmlnaW4tc2l6ZXxkYXRhLWV4cHxkYXRhLWZvbnQtc2l6ZSc7XHJcbiAgICAgICAgICAgIHRoaXMuX2FsbG93SFRNTENvbW1lbnRzID0gb3B0aW9ucy5fZWRpdG9yVGFnc1doaXRlbGlzdC5pbmRleE9mKCcvLycpID4gLTE7XHJcbiAgICAgICAgICAgIHRoaXMuX2h0bWxDaGVja1doaXRlbGlzdFJlZ0V4cCA9IG5ldyB3UmVnRXhwKCdeKCcgKyBvcHRpb25zLl9lZGl0b3JUYWdzV2hpdGVsaXN0LnJlcGxhY2UoJ3wvLycsICcnKSArICcpJCcsICdpJyk7XHJcbiAgICAgICAgICAgIHRoaXMuZWRpdG9yVGFnc1doaXRlbGlzdFJlZ0V4cCA9IHV0aWwuY3JlYXRlVGFnc1doaXRlbGlzdChvcHRpb25zLl9lZGl0b3JUYWdzV2hpdGVsaXN0LnJlcGxhY2UoJ3wvLycsICd8PCEtLXwtLT4nKSk7XHJcbiAgICAgICAgICAgIHRoaXMucGFzdGVUYWdzV2hpdGVsaXN0UmVnRXhwID0gdXRpbC5jcmVhdGVUYWdzV2hpdGVsaXN0KG9wdGlvbnMucGFzdGVUYWdzV2hpdGVsaXN0KTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IF9hdHRyID0gb3B0aW9ucy5hdHRyaWJ1dGVzV2hpdGVsaXN0O1xyXG4gICAgICAgICAgICBjb25zdCB0YWdzQXR0ciA9IHt9O1xyXG4gICAgICAgICAgICBsZXQgYWxsQXR0ciA9ICcnO1xyXG4gICAgICAgICAgICBpZiAoISFfYXR0cikge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgayBpbiBfYXR0cikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdXRpbC5oYXNPd24oX2F0dHIsIGspKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoayA9PT0gJ2FsbCcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWxsQXR0ciA9IF9hdHRyW2tdICsgJ3wnO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhZ3NBdHRyW2tdID0gbmV3IHdSZWdFeHAoJygoPzonICsgX2F0dHJba10gKyAnfCcgKyBkZWZhdWx0QXR0ciArICcpXFxzKj1cXHMqXCJbXlwiXSpcIiknLCAnaWcnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2F0dHJpYnV0ZXNXaGl0ZWxpc3RSZWdFeHAgPSBuZXcgd1JlZ0V4cCgnKCg/OicgKyBhbGxBdHRyICsgZGVmYXVsdEF0dHIgKyAnKVxccyo9XFxzKlwiW15cIl0qXCIpJywgJ2lnJyk7XHJcbiAgICAgICAgICAgIHRoaXMuX2F0dHJpYnV0ZXNUYWdzV2hpdGVsaXN0ID0gdGFnc0F0dHI7XHJcblxyXG4gICAgICAgICAgICAvLyBzZXQgbW9kZXNcclxuICAgICAgICAgICAgdGhpcy5faXNJbmxpbmUgPSAvaW5saW5lL2kudGVzdChvcHRpb25zLm1vZGUpO1xyXG4gICAgICAgICAgICB0aGlzLl9pc0JhbGxvb24gPSAvYmFsbG9vbnxiYWxsb29uLWFsd2F5cy9pLnRlc3Qob3B0aW9ucy5tb2RlKTtcclxuICAgICAgICAgICAgdGhpcy5faXNCYWxsb29uQWx3YXlzID0gL2JhbGxvb24tYWx3YXlzL2kudGVzdChvcHRpb25zLm1vZGUpO1xyXG5cclxuICAgICAgICAgICAgLy8gY2FjaGluZyBidXR0b25zXHJcbiAgICAgICAgICAgIHRoaXMuX2NhY2hpbmdCdXR0b25zKCk7XHJcblxyXG4gICAgICAgICAgICAvLyBmaWxlIGNvbXBvbmVudHNcclxuICAgICAgICAgICAgdGhpcy5fZmlsZUluZm9QbHVnaW5zQ2hlY2sgPSBbXTtcclxuICAgICAgICAgICAgdGhpcy5fZmlsZUluZm9QbHVnaW5zUmVzZXQgPSBbXTtcclxuXHJcbiAgICAgICAgICAgIC8vIHRleHQgY29tcG9uZW50c1xyXG4gICAgICAgICAgICB0aGlzLm1hbmFnZWRUYWdzSW5mbyA9IHsgcXVlcnk6ICcnLCBtYXA6IHt9IH07XHJcbiAgICAgICAgICAgIGNvbnN0IG1hbmFnZWRDbGFzcyA9IFtdO1xyXG5cclxuICAgICAgICAgICAgLy8gQ29tbWFuZCBhbmQgZmlsZSBwbHVnaW5zIHJlZ2lzdHJhdGlvblxyXG4gICAgICAgICAgICB0aGlzLmFjdGl2ZVBsdWdpbnMgPSBbXTtcclxuICAgICAgICAgICAgdGhpcy5fZmlsZU1hbmFnZXIudGFncyA9IFtdO1xyXG4gICAgICAgICAgICB0aGlzLl9maWxlTWFuYWdlci5wbHVnaW5NYXAgPSB7fTtcclxuXHJcbiAgICAgICAgICAgIGxldCBmaWxlUGx1Z2luUmVnRXhwID0gW107XHJcbiAgICAgICAgICAgIGxldCBwbHVnaW4sIGJ1dHRvbjtcclxuICAgICAgICAgICAgZm9yIChsZXQga2V5IGluIHBsdWdpbnMpIHtcclxuICAgICAgICAgICAgICAgIGlmICghdXRpbC5oYXNPd24ocGx1Z2lucywga2V5KSkgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBwbHVnaW4gPSBwbHVnaW5zW2tleV07XHJcbiAgICAgICAgICAgICAgICBidXR0b24gPSBwbHVnaW5DYWxsQnV0dG9uc1trZXldO1xyXG4gICAgICAgICAgICAgICAgaWYgKHBsdWdpbi5hY3RpdmUgJiYgYnV0dG9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYWxsUGx1Z2luKGtleSwgbnVsbCwgYnV0dG9uKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcGx1Z2luLmNoZWNrRmlsZUluZm8gPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHBsdWdpbi5yZXNldEZpbGVJbmZvID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYWxsUGx1Z2luKGtleSwgbnVsbCwgYnV0dG9uKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9maWxlSW5mb1BsdWdpbnNDaGVjay5wdXNoKHBsdWdpbi5jaGVja0ZpbGVJbmZvLmJpbmQodGhpcykpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2ZpbGVJbmZvUGx1Z2luc1Jlc2V0LnB1c2gocGx1Z2luLnJlc2V0RmlsZUluZm8uYmluZCh0aGlzKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoX3cuQXJyYXkuaXNBcnJheShwbHVnaW4uZmlsZVRhZ3MpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlsZVRhZ3MgPSBwbHVnaW4uZmlsZVRhZ3M7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYWxsUGx1Z2luKGtleSwgbnVsbCwgYnV0dG9uKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9maWxlTWFuYWdlci50YWdzID0gdGhpcy5fZmlsZU1hbmFnZXIudGFncy5jb25jYXQoZmlsZVRhZ3MpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZpbGVQbHVnaW5SZWdFeHAucHVzaChrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHRhZyA9IDAsIHRMZW4gPSBmaWxlVGFncy5sZW5ndGg7IHRhZyA8IHRMZW47IHRhZysrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2ZpbGVNYW5hZ2VyLnBsdWdpbk1hcFtmaWxlVGFnc1t0YWddLnRvTG93ZXJDYXNlKCldID0ga2V5O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChwbHVnaW4ubWFuYWdlZFRhZ3MpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmZvID0gcGx1Z2luLm1hbmFnZWRUYWdzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgbWFuYWdlZENsYXNzLnB1c2goJy4nICsgaW5mby5jbGFzc05hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWFuYWdlZFRhZ3NJbmZvLm1hcFtpbmZvLmNsYXNzTmFtZV0gPSBpbmZvLm1ldGhvZC5iaW5kKHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLm1hbmFnZWRUYWdzSW5mby5xdWVyeSA9IG1hbmFnZWRDbGFzcy50b1N0cmluZygpO1xyXG4gICAgICAgICAgICB0aGlzLl9maWxlTWFuYWdlci5xdWVyeVN0cmluZyA9IHRoaXMuX2ZpbGVNYW5hZ2VyLnRhZ3Muam9pbignLCcpO1xyXG4gICAgICAgICAgICB0aGlzLl9maWxlTWFuYWdlci5yZWdFeHAgPSBuZXcgd1JlZ0V4cCgnXignICsgIHRoaXMuX2ZpbGVNYW5hZ2VyLnRhZ3Muam9pbignfCcpICsgJykkJywgJ2knKTtcclxuICAgICAgICAgICAgdGhpcy5fZmlsZU1hbmFnZXIucGx1Z2luUmVnRXhwID0gbmV3IHdSZWdFeHAoJ14oJyArICAoZmlsZVBsdWdpblJlZ0V4cC5sZW5ndGggPT09IDAgPyAndW5kZWZpbmVkJyA6IGZpbGVQbHVnaW5SZWdFeHAuam9pbignfCcpKSArICcpJCcsICdpJyk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvLyBjYWNoZSBlZGl0b3IncyBlbGVtZW50XHJcbiAgICAgICAgICAgIHRoaXMuX3ZhcmlhYmxlLl9vcmlnaW5Dc3NUZXh0ID0gY29udGV4dC5lbGVtZW50LnRvcEFyZWEuc3R5bGUuY3NzVGV4dDtcclxuICAgICAgICAgICAgdGhpcy5fcGxhY2Vob2xkZXIgPSBjb250ZXh0LmVsZW1lbnQucGxhY2Vob2xkZXI7XHJcbiAgICAgICAgICAgIHRoaXMuX2xpbmVCcmVha2VyID0gY29udGV4dC5lbGVtZW50LmxpbmVCcmVha2VyO1xyXG4gICAgICAgICAgICB0aGlzLl9saW5lQnJlYWtlckJ1dHRvbiA9IHRoaXMuX2xpbmVCcmVha2VyLnF1ZXJ5U2VsZWN0b3IoJ2J1dHRvbicpO1xyXG5cclxuICAgICAgICAgICAgLy8gRXhjdXRlIGhpc3RvcnkgZnVuY3Rpb25cclxuICAgICAgICAgICAgdGhpcy5oaXN0b3J5ID0gX2hpc3RvcnkodGhpcywgdGhpcy5fb25DaGFuZ2VfaGlzdG9yeVN0YWNrLmJpbmQodGhpcykpO1xyXG5cclxuICAgICAgICAgICAgLy8gcmVnaXN0ZXIgbm90aWNlIG1vZHVsZVxyXG4gICAgICAgICAgICB0aGlzLmFkZE1vZHVsZShbX25vdGljZV0pO1xyXG5cclxuICAgICAgICAgICAgLy8gSW5pdCwgdmFsaWRhdGVcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuaWZyYW1lKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl93ZCA9IGNvbnRleHQuZWxlbWVudC53eXNpd3lnRnJhbWUuY29udGVudERvY3VtZW50O1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5lbGVtZW50Lnd5c2l3eWcgPSB0aGlzLl93ZC5ib2R5O1xyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuX2VkaXRvclN0eWxlcy5lZGl0b3IpIGNvbnRleHQuZWxlbWVudC53eXNpd3lnLnN0eWxlLmNzc1RleHQgPSBvcHRpb25zLl9lZGl0b3JTdHlsZXMuZWRpdG9yO1xyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuaGVpZ2h0ID09PSAnYXV0bycpIHRoaXMuX2lmcmFtZUF1dG8gPSB0aGlzLl93ZC5ib2R5O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICB0aGlzLl9pbml0V3lzaXd5Z0FyZWEocmVsb2FkLCBfaW5pdEhUTUwpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDYWNoaW5nIGJhc2ljIGJ1dHRvbnMgdG8gdXNlXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfY2FjaGluZ0J1dHRvbnM6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdGhpcy5jb2RlVmlld0Rpc2FibGVkQnV0dG9ucyA9IGNvbnRleHQuZWxlbWVudC50b29sYmFyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5zZS10b29sYmFyIGJ1dHRvbjpub3QoW2NsYXNzfj1cInNlLWNvZGUtdmlldy1lbmFibGVkXCJdKScpO1xyXG4gICAgICAgICAgICB0aGlzLnJlc2l6aW5nRGlzYWJsZWRCdXR0b25zID0gY29udGV4dC5lbGVtZW50LnRvb2xiYXIucXVlcnlTZWxlY3RvckFsbCgnLnNlLXRvb2xiYXIgYnV0dG9uOm5vdChbY2xhc3N+PVwic2UtcmVzaXppbmctZW5hYmxlZFwiXSknKTtcclxuICAgICAgICAgICAgY29uc3QgdG9vbCA9IGNvbnRleHQudG9vbDtcclxuICAgICAgICAgICAgdGhpcy5jb21tYW5kTWFwID0ge1xyXG4gICAgICAgICAgICAgICAgU1RST05HOiB0b29sLmJvbGQsXHJcbiAgICAgICAgICAgICAgICBVOiB0b29sLnVuZGVybGluZSxcclxuICAgICAgICAgICAgICAgIEVNOiB0b29sLml0YWxpYyxcclxuICAgICAgICAgICAgICAgIERFTDogdG9vbC5zdHJpa2UsXHJcbiAgICAgICAgICAgICAgICBTVUI6IHRvb2wuc3Vic2NyaXB0LFxyXG4gICAgICAgICAgICAgICAgU1VQOiB0b29sLnN1cGVyc2NyaXB0LFxyXG4gICAgICAgICAgICAgICAgT1VUREVOVDogdG9vbC5vdXRkZW50LFxyXG4gICAgICAgICAgICAgICAgSU5ERU5UOiB0b29sLmluZGVudFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB0aGlzLl9zdHlsZUNvbW1hbmRNYXAgPSB7XHJcbiAgICAgICAgICAgICAgICBmdWxsU2NyZWVuOiB0b29sLmZ1bGxTY3JlZW4sXHJcbiAgICAgICAgICAgICAgICBzaG93QmxvY2tzOiB0b29sLnNob3dCbG9ja3MsXHJcbiAgICAgICAgICAgICAgICBjb2RlVmlldzogdG9vbC5jb2RlVmlld1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBJbml0aWFsaXogd3lzaXd5ZyBhcmVhIChPbmx5IGNhbGxlZCBmcm9tIGNvcmUuX2luaXQpXHJcbiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSByZWxvYWQgSXMgcmVsb29hZD9cclxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gX2luaXRIVE1MIGluaXRpYWwgaHRtbCBzdHJpbmdcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9pbml0V3lzaXd5Z0FyZWE6IGZ1bmN0aW9uIChyZWxvYWQsIF9pbml0SFRNTCkge1xyXG4gICAgICAgICAgICBjb250ZXh0LmVsZW1lbnQud3lzaXd5Zy5pbm5lckhUTUwgPSByZWxvYWQgPyBfaW5pdEhUTUwgOiB0aGlzLmNvbnZlcnRDb250ZW50c0ZvckVkaXRvcih0eXBlb2YgX2luaXRIVE1MID09PSAnc3RyaW5nJyA/IF9pbml0SFRNTCA6IGNvbnRleHQuZWxlbWVudC5vcmlnaW5FbGVtZW50LnZhbHVlKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ2FsbGVkIHdoZW4gdGhlcmUgYXJlIGNoYW5nZXMgdG8gdGFncyBpbiB0aGUgd3lzaXd5ZyByZWdpb24uXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfcmVzb3VyY2VzU3RhdGVDaGFuZ2U6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdGhpcy5faWZyYW1lQXV0b0hlaWdodCgpO1xyXG4gICAgICAgICAgICB0aGlzLl9jaGVja1BsYWNlaG9sZGVyKCk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIENhbGxlZCB3aGVuIGFmdGVyIGV4ZWN1dGUgXCJoaXN0b3J5LnB1c2hcIlxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX29uQ2hhbmdlX2hpc3RvcnlTdGFjazogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBldmVudC5fYXBwbHlUYWdFZmZlY3RzKCk7XHJcbiAgICAgICAgICAgIGlmIChjb250ZXh0LnRvb2wuc2F2ZSkgY29udGV4dC50b29sLnNhdmUucmVtb3ZlQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xyXG4gICAgICAgICAgICBpZiAoZnVuY3Rpb25zLm9uQ2hhbmdlKSBmdW5jdGlvbnMub25DaGFuZ2UodGhpcy5nZXRDb250ZW50cyh0cnVlKSwgdGhpcyk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIE1vZGlmeSB0aGUgaGVpZ2h0IHZhbHVlIG9mIHRoZSBpZnJhbWUgd2hlbiB0aGUgaGVpZ2h0IG9mIHRoZSBpZnJhbWUgaXMgYXV0b21hdGljLlxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX2lmcmFtZUF1dG9IZWlnaHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lmcmFtZUF1dG8pIHtcclxuICAgICAgICAgICAgICAgIF93LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyBjb250ZXh0LmVsZW1lbnQud3lzaXd5Z0ZyYW1lLnN0eWxlLmhlaWdodCA9IGNvcmUuX2lmcmFtZUF1dG8ub2Zmc2V0SGVpZ2h0ICsgJ3B4JzsgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gU2V0IGRpc3BsYXkgcHJvcGVydHkgd2hlbiB0aGVyZSBpcyBwbGFjZWhvbGRlci5cclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9jaGVja1BsYWNlaG9sZGVyOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9wbGFjZWhvbGRlcikge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3ZhcmlhYmxlLmlzQ29kZVZpZXcpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wbGFjZWhvbGRlci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCB3eXNpd3lnID0gY29udGV4dC5lbGVtZW50Lnd5c2l3eWc7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXV0aWwub25seVplcm9XaWR0aFNwYWNlKHd5c2l3eWcudGV4dENvbnRlbnQpIHx8IHd5c2l3eWcucXVlcnlTZWxlY3RvcignLnNlLWNvbXBvbmVudCwgcHJlLCBibG9ja3F1b3RlLCBociwgbGksIHRhYmxlLCBpbWcsIGlmcmFtZSwgdmlkZW8nKSB8fCAod3lzaXd5Zy5pbm5lclRleHQubWF0Y2goL1xcbi9nKSB8fCAnJykubGVuZ3RoID4gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BsYWNlaG9sZGVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BsYWNlaG9sZGVyLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIElmIHRoZXJlIGlzIG5vIGRlZmF1bHQgZm9ybWF0LCBhZGQgYSBmb3JtYXQgYW5kIG1vdmUgXCJzZWxlY3Rpb25cIi5cclxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ3xudWxsfSBmb3JtYXROYW1lIEZvcm1hdCB0YWcgbmFtZSAoZGVmYXVsdDogJ1AnKVxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX3NldERlZmF1bHRGb3JtYXQ6IGZ1bmN0aW9uIChmb3JtYXROYW1lKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9maWxlTWFuYWdlci5wbHVnaW5SZWdFeHAudGVzdCh0aGlzLmN1cnJlbnRDb250cm9sbGVyTmFtZSkpIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHJhbmdlID0gdGhpcy5nZXRSYW5nZSgpO1xyXG4gICAgICAgICAgICBjb25zdCBjb21tb25Db24gPSByYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lcjtcclxuICAgICAgICAgICAgY29uc3Qgc3RhcnRDb24gPSByYW5nZS5zdGFydENvbnRhaW5lcjtcclxuICAgICAgICAgICAgY29uc3QgcmFuZ2VFbCA9IHV0aWwuZ2V0UmFuZ2VGb3JtYXRFbGVtZW50KGNvbW1vbkNvbiwgbnVsbCk7XHJcbiAgICAgICAgICAgIGxldCBmb2N1c05vZGUsIG9mZnNldCwgZm9ybWF0O1xyXG5cclxuICAgICAgICAgICAgY29uc3QgZmlsZUNvbXBvbmVudCA9IHV0aWwuZ2V0UGFyZW50RWxlbWVudChjb21tb25Db24sIHV0aWwuaXNDb21wb25lbnQpO1xyXG4gICAgICAgICAgICBpZiAoZmlsZUNvbXBvbmVudCAmJiAhdXRpbC5pc1RhYmxlKGZpbGVDb21wb25lbnQpKSByZXR1cm47XHJcbiAgICAgICAgICAgIGlmKCh1dGlsLmlzUmFuZ2VGb3JtYXRFbGVtZW50KHN0YXJ0Q29uKSB8fCB1dGlsLmlzV3lzaXd5Z0RpdihzdGFydENvbikpICYmIHV0aWwuaXNDb21wb25lbnQoc3RhcnRDb24uY2hpbGROb2Rlc1tyYW5nZS5zdGFydE9mZnNldF0pKSByZXR1cm47XHJcblxyXG4gICAgICAgICAgICBpZiAocmFuZ2VFbCkge1xyXG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gdXRpbC5jcmVhdGVFbGVtZW50KGZvcm1hdE5hbWUgfHwgb3B0aW9ucy5kZWZhdWx0VGFnKTtcclxuICAgICAgICAgICAgICAgIGZvcm1hdC5pbm5lckhUTUwgPSByYW5nZUVsLmlubmVySFRNTDtcclxuICAgICAgICAgICAgICAgIGlmIChmb3JtYXQuY2hpbGROb2Rlcy5sZW5ndGggPT09IDApIGZvcm1hdC5pbm5lckhUTUwgPSB1dGlsLnplcm9XaWR0aFNwYWNlO1xyXG5cclxuICAgICAgICAgICAgICAgIHJhbmdlRWwuaW5uZXJIVE1MID0gZm9ybWF0Lm91dGVySFRNTDtcclxuICAgICAgICAgICAgICAgIGZvcm1hdCA9IHJhbmdlRWwuZmlyc3RDaGlsZDtcclxuICAgICAgICAgICAgICAgIGZvY3VzTm9kZSA9IHV0aWwuZ2V0RWRnZUNoaWxkTm9kZXMoZm9ybWF0LCBudWxsKS5zYztcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWZvY3VzTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvY3VzTm9kZSA9IHV0aWwuY3JlYXRlVGV4dE5vZGUodXRpbC56ZXJvV2lkdGhTcGFjZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9ybWF0Lmluc2VydEJlZm9yZShmb2N1c05vZGUsIGZvcm1hdC5maXJzdENoaWxkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gZm9jdXNOb2RlLnRleHRDb250ZW50Lmxlbmd0aDtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2V0UmFuZ2UoZm9jdXNOb2RlLCBvZmZzZXQsIGZvY3VzTm9kZSwgb2Zmc2V0KTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYodXRpbC5pc1JhbmdlRm9ybWF0RWxlbWVudChjb21tb25Db24pICYmIChjb21tb25Db24uY2hpbGROb2Rlcy5sZW5ndGggPD0gMSkpIHtcclxuICAgICAgICAgICAgICAgIGxldCBiciA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29tbW9uQ29uLmNoaWxkTm9kZXMubGVuZ3RoID09PSAxICYmIHV0aWwuaXNCcmVhayhjb21tb25Db24uZmlyc3RDaGlsZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBiciA9IGNvbW1vbkNvbi5maXJzdENoaWxkO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBiciA9IHV0aWwuY3JlYXRlVGV4dE5vZGUodXRpbC56ZXJvV2lkdGhTcGFjZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29tbW9uQ29uLmFwcGVuZENoaWxkKGJyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldFJhbmdlKGJyLCAxLCBiciwgMSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuZXhlY0NvbW1hbmQoJ2Zvcm1hdEJsb2NrJywgZmFsc2UsIChmb3JtYXROYW1lIHx8IG9wdGlvbnMuZGVmYXVsdFRhZykpO1xyXG4gICAgICAgICAgICBmb2N1c05vZGUgPSB1dGlsLmdldEVkZ2VDaGlsZE5vZGVzKGNvbW1vbkNvbiwgY29tbW9uQ29uKTtcclxuICAgICAgICAgICAgZm9jdXNOb2RlID0gZm9jdXNOb2RlID8gZm9jdXNOb2RlLmVjIDogY29tbW9uQ29uO1xyXG5cclxuICAgICAgICAgICAgZm9ybWF0ID0gdXRpbC5nZXRGb3JtYXRFbGVtZW50KGZvY3VzTm9kZSwgbnVsbCk7XHJcbiAgICAgICAgICAgIGlmICghZm9ybWF0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZVJhbmdlKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9lZGl0b3JSYW5nZSgpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBpZiAodXRpbC5pc0JyZWFrKGZvcm1hdC5uZXh0U2libGluZykpIHV0aWwucmVtb3ZlSXRlbShmb3JtYXQubmV4dFNpYmxpbmcpO1xyXG4gICAgICAgICAgICBpZiAodXRpbC5pc0JyZWFrKGZvcm1hdC5wcmV2aW91c1NpYmxpbmcpKSB1dGlsLnJlbW92ZUl0ZW0oZm9ybWF0LnByZXZpb3VzU2libGluZyk7XHJcbiAgICAgICAgICAgIGlmICh1dGlsLmlzQnJlYWsoZm9jdXNOb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgemVyb1dpZHRoID0gdXRpbC5jcmVhdGVUZXh0Tm9kZSh1dGlsLnplcm9XaWR0aFNwYWNlKTtcclxuICAgICAgICAgICAgICAgIGZvY3VzTm9kZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh6ZXJvV2lkdGgsIGZvY3VzTm9kZSk7XHJcbiAgICAgICAgICAgICAgICBmb2N1c05vZGUgPSB6ZXJvV2lkdGg7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuZWZmZWN0Tm9kZSA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXMubmF0aXZlRm9jdXMoKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gSW5pdGlhbGl6YXRpb24gYWZ0ZXIgXCJzZXRPcHRpb25zXCJcclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gZWwgY29udGV4dC5lbGVtZW50XHJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IF9pbml0SFRNTCBJbml0aWFsIGh0bWwgc3RyaW5nXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfc2V0T3B0aW9uc0luaXQ6IGZ1bmN0aW9uIChlbCwgX2luaXRIVE1MKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQgPSBfQ29udGV4dChlbC5vcmlnaW5FbGVtZW50LCB0aGlzLl9nZXRDb25zdHJ1Y3RlZChlbCksIG9wdGlvbnMpO1xyXG4gICAgICAgICAgICB0aGlzLl9jb21wb25lbnRzSW5mb1Jlc2V0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5fZWRpdG9ySW5pdCh0cnVlLCBfaW5pdEhUTUwpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBJbml0aWFsaXogZWRpdG9yXHJcbiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSByZWxvYWQgSXMgcmVsb29hZD9cclxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gX2luaXRIVE1MIGluaXRpYWwgaHRtbCBzdHJpbmdcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF9lZGl0b3JJbml0OiBmdW5jdGlvbiAocmVsb2FkLCBfaW5pdEhUTUwpIHtcclxuICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZSBjb3JlIGFuZCBhZGQgZXZlbnQgbGlzdGVuZXJzXHJcbiAgICAgICAgICAgIHRoaXMuX2luaXQocmVsb2FkLCBfaW5pdEhUTUwpO1xyXG4gICAgICAgICAgICBldmVudC5fYWRkRXZlbnQoKTtcclxuICAgICAgICAgICAgdGhpcy5fc2V0Q2hhckNvdW50KCk7XHJcbiAgICAgICAgICAgIGV2ZW50Ll9vZmZTdGlja3lUb29sYmFyKCk7XHJcbiAgICAgICAgICAgIGV2ZW50Lm9uUmVzaXplX3dpbmRvdygpO1xyXG5cclxuICAgICAgICAgICAgLy8gdG9vbGJhciB2aXNpYmlsaXR5XHJcbiAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC50b29sYmFyLnN0eWxlLnZpc2liaWxpdHkgPSAnJztcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2NoZWNrQ29tcG9uZW50cygpO1xyXG4gICAgICAgICAgICB0aGlzLl9jb21wb25lbnRzSW5mb0luaXQgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5fY29tcG9uZW50c0luZm9SZXNldCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc2V0KHRydWUpO1xyXG4gICAgICAgICAgICB0aGlzLl9yZXNvdXJjZXNTdGF0ZUNoYW5nZSgpO1xyXG5cclxuICAgICAgICAgICAgX3cuc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiBmdW5jdGlvbnMub25sb2FkID09PSAnZnVuY3Rpb24nKSBmdW5jdGlvbnMub25sb2FkKGNvcmUsIHJlbG9hZCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDcmVhdGUgYW5kIHJldHVybiBhbiBvYmplY3QgdG8gY2FjaGUgdGhlIG5ldyBjb250ZXh0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gY29udGV4dEVsIGNvbnRleHQuZWxlbWVudFxyXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3R9XHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBfZ2V0Q29uc3RydWN0ZWQ6IGZ1bmN0aW9uIChjb250ZXh0RWwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIF90b3A6IGNvbnRleHRFbC50b3BBcmVhLFxyXG4gICAgICAgICAgICAgICAgX3JlbGF0aXZlOiBjb250ZXh0RWwucmVsYXRpdmUsXHJcbiAgICAgICAgICAgICAgICBfdG9vbEJhcjogY29udGV4dEVsLnRvb2xiYXIsXHJcbiAgICAgICAgICAgICAgICBfbWVudVRyYXk6IGNvbnRleHRFbC5fbWVudVRyYXksXHJcbiAgICAgICAgICAgICAgICBfZWRpdG9yQXJlYTogY29udGV4dEVsLmVkaXRvckFyZWEsXHJcbiAgICAgICAgICAgICAgICBfd3lzaXd5Z0FyZWE6IGNvbnRleHRFbC53eXNpd3lnRnJhbWUsXHJcbiAgICAgICAgICAgICAgICBfY29kZUFyZWE6IGNvbnRleHRFbC5jb2RlLFxyXG4gICAgICAgICAgICAgICAgX3BsYWNlaG9sZGVyOiBjb250ZXh0RWwucGxhY2Vob2xkZXIsXHJcbiAgICAgICAgICAgICAgICBfcmVzaXppbmdCYXI6IGNvbnRleHRFbC5yZXNpemluZ0JhcixcclxuICAgICAgICAgICAgICAgIF9uYXZpZ2F0aW9uOiBjb250ZXh0RWwubmF2aWdhdGlvbixcclxuICAgICAgICAgICAgICAgIF9jaGFyQ291bnRlcjogY29udGV4dEVsLmNoYXJDb3VudGVyLFxyXG4gICAgICAgICAgICAgICAgX2NoYXJXcmFwcGVyOiBjb250ZXh0RWwuY2hhcldyYXBwZXIsXHJcbiAgICAgICAgICAgICAgICBfbG9hZGluZzogY29udGV4dEVsLmxvYWRpbmcsXHJcbiAgICAgICAgICAgICAgICBfbGluZUJyZWFrZXI6IGNvbnRleHRFbC5saW5lQnJlYWtlcixcclxuICAgICAgICAgICAgICAgIF9saW5lQnJlYWtlcl90OiBjb250ZXh0RWwubGluZUJyZWFrZXJfdCxcclxuICAgICAgICAgICAgICAgIF9saW5lQnJlYWtlcl9iOiBjb250ZXh0RWwubGluZUJyZWFrZXJfYixcclxuICAgICAgICAgICAgICAgIF9yZXNpemVCYWNrOiBjb250ZXh0RWwucmVzaXplQmFja2dyb3VuZCxcclxuICAgICAgICAgICAgICAgIF9zdGlja3lEdW1teTogY29udGV4dEVsLl9zdGlja3lEdW1teSxcclxuICAgICAgICAgICAgICAgIF9hcnJvdzogY29udGV4dEVsLl9hcnJvd1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gZXZlbnQgZnVuY3Rpb25cclxuICAgICAqL1xyXG4gICAgY29uc3QgZXZlbnQgPSB7XHJcbiAgICAgICAgX0lFaXNDb21wb3Npbmc6IGZhbHNlLCAvLyBJbiBJRSwgdGhlcmUgaXMgbm8gXCJlLmlzQ29tcG9zaW5nXCIgaW4gdGhlIGtleS11cCBldmVudC5cclxuICAgICAgICBfbGluZUJyZWFrZXJCaW5kOiBudWxsLFxyXG4gICAgICAgIF9yZXNwb25zaXZlQ3VycmVudFNpemU6ICdkZWZhdWx0JyxcclxuICAgICAgICBfcmVzcG9uc2l2ZUJ1dHRvblNpemU6IG51bGwsXHJcbiAgICAgICAgX3Jlc3BvbnNpdmVCdXR0b25zOiBudWxsLFxyXG4gICAgICAgIF9kaXJlY3Rpb25LZXlDb2RlOiBuZXcgX3cuUmVnRXhwKCdeKDh8MTN8M1syLTldfDQwfDQ2KSQnKSxcclxuICAgICAgICBfbm9uVGV4dEtleUNvZGU6IG5ldyBfdy5SZWdFeHAoJ14oOHwxM3wxWzYtOV18MjB8Mjd8M1szLTldfDQwfDQ1fDQ2fDExWzItOV18MTJbMC0zXXwxNDR8MTQ1KSQnKSxcclxuICAgICAgICBfaGlzdG9yeUlnbm9yZUtleUNvZGU6IG5ldyBfdy5SZWdFeHAoJ14oMVs2LTldfDIwfDI3fDNbMy05XXw0MHw0NXwxMVsyLTldfDEyWzAtM118MTQ0fDE0NSkkJyksXHJcbiAgICAgICAgX29uQnV0dG9uc0NoZWNrOiBuZXcgX3cuUmVnRXhwKCdeKFNUUk9OR3xVfEVNfERFTHxTVUJ8U1VQKSQnKSxcclxuICAgICAgICBfZnJvbnRaZXJvV2lkdGhSZWc6IG5ldyBfdy5SZWdFeHAodXRpbC56ZXJvV2lkdGhTcGFjZSArICcrJywgJycpLFxyXG4gICAgICAgIF9rZXlDb2RlU2hvcnRjdXQ6IHtcclxuICAgICAgICAgICAgNjU6ICdBJyxcclxuICAgICAgICAgICAgNjY6ICdCJyxcclxuICAgICAgICAgICAgODM6ICdTJyxcclxuICAgICAgICAgICAgODU6ICdVJyxcclxuICAgICAgICAgICAgNzM6ICdJJyxcclxuICAgICAgICAgICAgODk6ICdZJyxcclxuICAgICAgICAgICAgOTA6ICdaJyxcclxuICAgICAgICAgICAgMjE5OiAnWycsXHJcbiAgICAgICAgICAgIDIyMTogJ10nXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX3Nob3J0Y3V0Q29tbWFuZDogZnVuY3Rpb24gKGtleUNvZGUsIHNoaWZ0KSB7XHJcbiAgICAgICAgICAgIGxldCBjb21tYW5kID0gbnVsbDtcclxuICAgICAgICAgICAgY29uc3Qga2V5U3RyID0gZXZlbnQuX2tleUNvZGVTaG9ydGN1dFtrZXlDb2RlXTtcclxuXHJcbiAgICAgICAgICAgIHN3aXRjaCAoa2V5U3RyKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdBJzpcclxuICAgICAgICAgICAgICAgICAgICBjb21tYW5kID0gJ3NlbGVjdEFsbCc7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdCJzpcclxuICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5zaG9ydGN1dHNEaXNhYmxlLmluZGV4T2YoJ2JvbGQnKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFuZCA9ICdTVFJPTkcnO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJ1MnOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzaGlmdCAmJiBvcHRpb25zLnNob3J0Y3V0c0Rpc2FibGUuaW5kZXhPZignc3RyaWtlJykgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSAnREVMJztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdVJzpcclxuICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5zaG9ydGN1dHNEaXNhYmxlLmluZGV4T2YoJ3VuZGVybGluZScpID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kID0gJ1UnO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJ0knOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnNob3J0Y3V0c0Rpc2FibGUuaW5kZXhPZignaXRhbGljJykgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSAnRU0nO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJ1onOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnNob3J0Y3V0c0Rpc2FibGUuaW5kZXhPZigndW5kbycpID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2hpZnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSAncmVkbyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kID0gJ3VuZG8nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnWSc6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2hvcnRjdXRzRGlzYWJsZS5pbmRleE9mKCd1bmRvJykgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSAncmVkbyc7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnWyc6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2hvcnRjdXRzRGlzYWJsZS5pbmRleE9mKCdpbmRlbnQnKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFuZCA9IG9wdGlvbnMucnRsID8gJ2luZGVudCcgOiAnb3V0ZGVudCc7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnXSc6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2hvcnRjdXRzRGlzYWJsZS5pbmRleE9mKCdpbmRlbnQnKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFuZCA9IG9wdGlvbnMucnRsID8gJ291dGRlbnQnIDogJ2luZGVudCc7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIWNvbW1hbmQpIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIGNvcmUuY29tbWFuZEhhbmRsZXIoY29yZS5jb21tYW5kTWFwW2NvbW1hbmRdLCBjb21tYW5kKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX2FwcGx5VGFnRWZmZWN0czogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBsZXQgc2VsZWN0aW9uTm9kZSA9IGNvcmUuZ2V0U2VsZWN0aW9uTm9kZSgpO1xyXG4gICAgICAgICAgICBpZiAoc2VsZWN0aW9uTm9kZSA9PT0gY29yZS5lZmZlY3ROb2RlKSByZXR1cm47XHJcbiAgICAgICAgICAgIGNvcmUuZWZmZWN0Tm9kZSA9IHNlbGVjdGlvbk5vZGU7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBtYXJnaW5EaXIgPSBvcHRpb25zLnJ0bCA/ICdtYXJnaW5SaWdodCcgOiAnbWFyZ2luTGVmdCc7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvbW1hbmRNYXAgPSBjb3JlLmNvbW1hbmRNYXA7XHJcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzT25DaGVjayA9IHRoaXMuX29uQnV0dG9uc0NoZWNrO1xyXG4gICAgICAgICAgICBjb25zdCBjb21tYW5kTWFwTm9kZXMgPSBbXTtcclxuICAgICAgICAgICAgY29uc3QgY3VycmVudE5vZGVzID0gW107XHJcblxyXG4gICAgICAgICAgICBjb25zdCBhY3RpdmVQbHVnaW5zID0gY29yZS5hY3RpdmVQbHVnaW5zO1xyXG4gICAgICAgICAgICBjb25zdCBjTGVuID0gYWN0aXZlUGx1Z2lucy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGxldCBub2RlTmFtZSA9ICcnO1xyXG5cclxuICAgICAgICAgICAgd2hpbGUgKHNlbGVjdGlvbk5vZGUuZmlyc3RDaGlsZCkge1xyXG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uTm9kZSA9IHNlbGVjdGlvbk5vZGUuZmlyc3RDaGlsZDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZm9yIChsZXQgZWxlbWVudCA9IHNlbGVjdGlvbk5vZGU7ICF1dGlsLmlzV3lzaXd5Z0RpdihlbGVtZW50KTsgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50Tm9kZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFlbGVtZW50KSBicmVhaztcclxuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50Lm5vZGVUeXBlICE9PSAxIHx8IHV0aWwuaXNCcmVhayhlbGVtZW50KSkgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBub2RlTmFtZSA9IGVsZW1lbnQubm9kZU5hbWUudG9VcHBlckNhc2UoKTtcclxuICAgICAgICAgICAgICAgIGN1cnJlbnROb2Rlcy5wdXNoKG5vZGVOYW1lKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKiBBY3RpdmUgcGx1Z2lucyAqL1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgYyA9IDAsIG5hbWU7IGMgPCBjTGVuOyBjKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBuYW1lID0gYWN0aXZlUGx1Z2luc1tjXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWFuZE1hcE5vZGVzLmluZGV4T2YobmFtZSkgPT09IC0xICYmIHBsdWdpbnNbbmFtZV0uYWN0aXZlLmNhbGwoY29yZSwgZWxlbWVudCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFuZE1hcE5vZGVzLnB1c2gobmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICh1dGlsLmlzRm9ybWF0RWxlbWVudChlbGVtZW50KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8qIE91dGRlbnQgKi9cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWFuZE1hcE5vZGVzLmluZGV4T2YoJ09VVERFTlQnKSA9PT0gLTEgJiYgY29tbWFuZE1hcC5PVVRERU5UKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1dGlsLmlzTGlzdENlbGwoZWxlbWVudCkgfHwgKGVsZW1lbnQuc3R5bGVbbWFyZ2luRGlyXSAmJiB1dGlsLmdldE51bWJlcihlbGVtZW50LnN0eWxlW21hcmdpbkRpcl0sIDApID4gMCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmRNYXBOb2Rlcy5wdXNoKCdPVVRERU5UJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kTWFwLk9VVERFTlQucmVtb3ZlQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvKiBJbmRlbnQgKi9cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWFuZE1hcE5vZGVzLmluZGV4T2YoJ0lOREVOVCcpID09PSAtMSAmJiBjb21tYW5kTWFwLklOREVOVCAmJiB1dGlsLmlzTGlzdENlbGwoZWxlbWVudCkgJiYgIWVsZW1lbnQucHJldmlvdXNFbGVtZW50U2libGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kTWFwTm9kZXMucHVzaCgnSU5ERU5UJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmRNYXAuSU5ERU5ULnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKiBkZWZhdWx0IGFjdGl2ZSBidXR0b25zIFtzdHJvbmcsIGlucywgZW0sIGRlbCwgc3ViLCBzdXBdICovXHJcbiAgICAgICAgICAgICAgICBpZiAoY2xhc3NPbkNoZWNrLnRlc3Qobm9kZU5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29tbWFuZE1hcE5vZGVzLnB1c2gobm9kZU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHV0aWwuYWRkQ2xhc3MoY29tbWFuZE1hcFtub2RlTmFtZV0sICdhY3RpdmUnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyoqIHJlbW92ZSBjbGFzcywgZGlzcGxheSB0ZXh0ICovXHJcbiAgICAgICAgICAgIGZvciAobGV0IGtleSBpbiBjb21tYW5kTWFwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29tbWFuZE1hcE5vZGVzLmluZGV4T2Yoa2V5KSA+IC0xIHx8ICF1dGlsLmhhc093bihjb21tYW5kTWFwLCBrZXkpKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGlmIChhY3RpdmVQbHVnaW5zLmluZGV4T2Yoa2V5KSA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGx1Z2luc1trZXldLmFjdGl2ZS5jYWxsKGNvcmUsIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTWFwLk9VVERFTlQgJiYgL15PVVRERU5UJC9pLnRlc3Qoa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbW1hbmRNYXAuT1VUREVOVC5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmRNYXAuSU5ERU5UICYmIC9eSU5ERU5UJC9pLnRlc3Qoa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbW1hbmRNYXAuSU5ERU5ULnJlbW92ZUF0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVDbGFzcyhjb21tYW5kTWFwW2tleV0sICdhY3RpdmUnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyoqIHNhdmUgY3VycmVudCBub2RlcyAqL1xyXG4gICAgICAgICAgICBjb3JlLl92YXJpYWJsZS5jdXJyZW50Tm9kZXMgPSBjdXJyZW50Tm9kZXMucmV2ZXJzZSgpO1xyXG4gICAgICAgICAgICBjb3JlLl92YXJpYWJsZS5jdXJyZW50Tm9kZXNNYXAgPSBjb21tYW5kTWFwTm9kZXM7XHJcblxyXG4gICAgICAgICAgICAvKiogIERpc3BsYXlzIHRoZSBjdXJyZW50IG5vZGUgc3RydWN0dXJlIHRvIHJlc2l6aW5nQmFyICovXHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnNob3dQYXRoTGFiZWwpIGNvbnRleHQuZWxlbWVudC5uYXZpZ2F0aW9uLnRleHRDb250ZW50ID0gY29yZS5fdmFyaWFibGUuY3VycmVudE5vZGVzLmpvaW4oJyA+ICcpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9jYW5jZWxDYXB0aW9uRWRpdDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJywgZmFsc2UpO1xyXG4gICAgICAgICAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2JsdXInLCBldmVudC5fY2FuY2VsQ2FwdGlvbkVkaXQpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9idXR0b25zRXZlbnRIYW5kbGVyOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBsZXQgdGFyZ2V0ID0gZS50YXJnZXQ7XHJcbiAgICAgICAgICAgIGlmIChjb3JlLl9iaW5kQ29udHJvbGxlcnNPZmYpIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoL14oaW5wdXR8dGV4dGFyZWF8c2VsZWN0fG9wdGlvbikkL2kudGVzdCh0YXJnZXQubm9kZU5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICBjb3JlLl9hbnRpQmx1ciA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodXRpbC5nZXRQYXJlbnRFbGVtZW50KHRhcmdldCwgJy5zZS1zdWJtZW51JykpIHtcclxuICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICBjb3JlLl9ub3RIaWRlVG9vbGJhciA9IHRydWU7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgY29tbWFuZCA9IHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY29tbWFuZCcpO1xyXG4gICAgICAgICAgICAgICAgbGV0IGNsYXNzTmFtZSA9IHRhcmdldC5jbGFzc05hbWU7XHJcbiAgICBcclxuICAgICAgICAgICAgICAgIHdoaWxlICghY29tbWFuZCAmJiAhL3NlLW1lbnUtbGlzdC8udGVzdChjbGFzc05hbWUpICYmICEvc3VuLWVkaXRvci1jb21tb24vLnRlc3QoY2xhc3NOYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IHRhcmdldC5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLWNvbW1hbmQnKTtcclxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWUgPSB0YXJnZXQuY2xhc3NOYW1lO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICBpZiAoY29tbWFuZCA9PT0gY29yZS5fc3VibWVudU5hbWUgfHwgY29tbWFuZCA9PT0gY29yZS5fY29udGFpbmVyTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBvbkNsaWNrX3Rvb2xiYXI6IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGxldCB0YXJnZXQgPSBlLnRhcmdldDtcclxuICAgICAgICAgICAgbGV0IGRpc3BsYXkgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLWRpc3BsYXknKTtcclxuICAgICAgICAgICAgbGV0IGNvbW1hbmQgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLWNvbW1hbmQnKTtcclxuICAgICAgICAgICAgbGV0IGNsYXNzTmFtZSA9IHRhcmdldC5jbGFzc05hbWU7XHJcblxyXG4gICAgICAgICAgICB3aGlsZSAodGFyZ2V0LnBhcmVudE5vZGUgJiYgIWNvbW1hbmQgJiYgIS9zZS1tZW51LWxpc3QvLnRlc3QoY2xhc3NOYW1lKSAmJiAhL3NlLXRvb2xiYXIvLnRlc3QoY2xhc3NOYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICBjb21tYW5kID0gdGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS1jb21tYW5kJyk7XHJcbiAgICAgICAgICAgICAgICBkaXNwbGF5ID0gdGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS1kaXNwbGF5Jyk7XHJcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUgPSB0YXJnZXQuY2xhc3NOYW1lO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIWNvbW1hbmQgJiYgIWRpc3BsYXkpIHJldHVybjtcclxuICAgICAgICAgICAgaWYgKHRhcmdldC5kaXNhYmxlZCkgcmV0dXJuO1xyXG4gICAgICAgICAgICBpZiAoIWNvcmUuaGFzRm9jdXMpIGNvcmUubmF0aXZlRm9jdXMoKTtcclxuICAgICAgICAgICAgaWYgKCFjb3JlLl92YXJpYWJsZS5pc0NvZGVWaWV3KSBjb3JlLl9lZGl0b3JSYW5nZSgpO1xyXG5cclxuICAgICAgICAgICAgY29yZS5hY3Rpb25DYWxsKGNvbW1hbmQsIGRpc3BsYXksIHRhcmdldCk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgb25Nb3VzZURvd25fd3lzaXd5ZzogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgaWYgKHV0aWwuaXNOb25FZGl0YWJsZShjb250ZXh0LmVsZW1lbnQud3lzaXd5ZykpIHJldHVybjtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ2VsbCA9IHV0aWwuZ2V0UGFyZW50RWxlbWVudChlLnRhcmdldCwgdXRpbC5pc0NlbGwpO1xyXG4gICAgICAgICAgICBpZiAodGFibGVDZWxsKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB0YWJsZVBsdWdpbiA9IGNvcmUucGx1Z2lucy50YWJsZTtcclxuICAgICAgICAgICAgICAgIGlmICh0YWJsZVBsdWdpbiAmJiB0YWJsZUNlbGwgIT09IHRhYmxlUGx1Z2luLl9maXhlZENlbGwgJiYgIXRhYmxlUGx1Z2luLl9zaGlmdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvcmUuY2FsbFBsdWdpbigndGFibGUnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlUGx1Z2luLm9uVGFibGVDZWxsTXVsdGlTZWxlY3QuY2FsbChjb3JlLCB0YWJsZUNlbGwsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICB9LCBudWxsKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGNvcmUuX2lzQmFsbG9vbikge1xyXG4gICAgICAgICAgICAgICAgZXZlbnQuX2hpZGVUb29sYmFyKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICgvRklHVVJFL2kudGVzdChlLnRhcmdldC5ub2RlTmFtZSkpIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBmdW5jdGlvbnMub25Nb3VzZURvd24gPT09ICdmdW5jdGlvbicpIGZ1bmN0aW9ucy5vbk1vdXNlRG93bihlLCBjb3JlKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBvbkNsaWNrX3d5c2l3eWc6IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldEVsZW1lbnQgPSBlLnRhcmdldDtcclxuICAgICAgICAgICAgaWYgKHV0aWwuaXNOb25FZGl0YWJsZShjb250ZXh0LmVsZW1lbnQud3lzaXd5ZykpIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGZpbGVDb21wb25lbnRJbmZvID0gY29yZS5nZXRGaWxlQ29tcG9uZW50KHRhcmdldEVsZW1lbnQpO1xyXG4gICAgICAgICAgICBpZiAoZmlsZUNvbXBvbmVudEluZm8pIHtcclxuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgIGNvcmUuc2VsZWN0Q29tcG9uZW50KGZpbGVDb21wb25lbnRJbmZvLnRhcmdldCwgZmlsZUNvbXBvbmVudEluZm8ucGx1Z2luTmFtZSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGZpZ2NhcHRpb24gPSB1dGlsLmdldFBhcmVudEVsZW1lbnQodGFyZ2V0RWxlbWVudCwgJ0ZJR0NBUFRJT04nKTtcclxuICAgICAgICAgICAgaWYgKHV0aWwuaXNOb25FZGl0YWJsZShmaWdjYXB0aW9uKSkge1xyXG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgZmlnY2FwdGlvbi5zZXRBdHRyaWJ1dGUoJ2NvbnRlbnRlZGl0YWJsZScsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgZmlnY2FwdGlvbi5mb2N1cygpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChjb3JlLl9pc0lubGluZSAmJiAhY29yZS5faW5saW5lVG9vbGJhckF0dHIuaXNTaG93KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuX3Nob3dUb29sYmFySW5saW5lKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGhpZGVUb29sYmFyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5faGlkZVRvb2xiYXIoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmlnY2FwdGlvbi5yZW1vdmVFdmVudExpc3RlbmVyKCdibHVyJywgaGlkZVRvb2xiYXIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZpZ2NhcHRpb24uYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsIGhpZGVUb29sYmFyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgX3cuc2V0VGltZW91dChjb3JlLl9lZGl0b3JSYW5nZS5iaW5kKGNvcmUpKTtcclxuICAgICAgICAgICAgY29yZS5fZWRpdG9yUmFuZ2UoKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGlvbk5vZGUgPSBjb3JlLmdldFNlbGVjdGlvbk5vZGUoKTtcclxuICAgICAgICAgICAgY29uc3QgZm9ybWF0RWwgPSB1dGlsLmdldEZvcm1hdEVsZW1lbnQoc2VsZWN0aW9uTm9kZSwgbnVsbCk7XHJcbiAgICAgICAgICAgIGNvbnN0IHJhbmdlRWwgPSB1dGlsLmdldFJhbmdlRm9ybWF0RWxlbWVudChzZWxlY3Rpb25Ob2RlLCBudWxsKTtcclxuICAgICAgICAgICAgaWYgKCghZm9ybWF0RWwgfHwgZm9ybWF0RWwgPT09IHJhbmdlRWwpICYmICF1dGlsLmlzTm9uRWRpdGFibGUodGFyZ2V0RWxlbWVudCkgJiYgIXV0aWwuaXNMaXN0KHJhbmdlRWwpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByYW5nZSA9IGNvcmUuZ2V0UmFuZ2UoKTtcclxuICAgICAgICAgICAgICAgIGlmICh1dGlsLmdldEZvcm1hdEVsZW1lbnQocmFuZ2Uuc3RhcnRDb250YWluZXIpID09PSB1dGlsLmdldEZvcm1hdEVsZW1lbnQocmFuZ2UuZW5kQ29udGFpbmVyKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh1dGlsLmlzTGlzdChyYW5nZUVsKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvTGkgPSB1dGlsLmNyZWF0ZUVsZW1lbnQoJ0xJJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZXZMaSA9IHNlbGVjdGlvbk5vZGUubmV4dEVsZW1lbnRTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvTGkuYXBwZW5kQ2hpbGQoc2VsZWN0aW9uTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlRWwuaW5zZXJ0QmVmb3JlKG9MaSwgcHJldkxpKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCF1dGlsLmlzV3lzaXd5Z0RpdihzZWxlY3Rpb25Ob2RlKSAmJiAhdXRpbC5pc0NvbXBvbmVudChzZWxlY3Rpb25Ob2RlKSAmJiAoIXV0aWwuaXNUYWJsZShzZWxlY3Rpb25Ob2RlKSB8fCB1dGlsLmlzQ2VsbChzZWxlY3Rpb25Ob2RlKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29yZS5fc2V0RGVmYXVsdEZvcm1hdCh1dGlsLmlzUmFuZ2VGb3JtYXRFbGVtZW50KHJhbmdlRWwpID8gJ0RJVicgOiBvcHRpb25zLmRlZmF1bHRUYWcpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29yZS5mb2N1cygpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZXZlbnQuX2FwcGx5VGFnRWZmZWN0cygpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoY29yZS5faXNCYWxsb29uKSBfdy5zZXRUaW1lb3V0KGV2ZW50Ll90b2dnbGVUb29sYmFyQmFsbG9vbik7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZnVuY3Rpb25zLm9uQ2xpY2sgPT09ICdmdW5jdGlvbicpIGZ1bmN0aW9ucy5vbkNsaWNrKGUsIGNvcmUpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9iYWxsb29uRGVsYXk6IG51bGwsXHJcbiAgICAgICAgX3Nob3dUb29sYmFyQmFsbG9vbkRlbGF5OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChldmVudC5fYmFsbG9vbkRlbGF5KSB7XHJcbiAgICAgICAgICAgICAgICBfdy5jbGVhclRpbWVvdXQoZXZlbnQuX2JhbGxvb25EZWxheSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGV2ZW50Ll9iYWxsb29uRGVsYXkgPSBfdy5zZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIF93LmNsZWFyVGltZW91dCh0aGlzLl9iYWxsb29uRGVsYXkpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYmFsbG9vbkRlbGF5ID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3Nob3dUb29sYmFyQmFsbG9vbigpO1xyXG4gICAgICAgICAgICB9LmJpbmQoZXZlbnQpLCAzNTApO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF90b2dnbGVUb29sYmFyQmFsbG9vbjogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjb3JlLl9lZGl0b3JSYW5nZSgpO1xyXG4gICAgICAgICAgICBjb25zdCByYW5nZSA9IGNvcmUuZ2V0UmFuZ2UoKTtcclxuICAgICAgICAgICAgaWYgKGNvcmUuX2JpbmRDb250cm9sbGVyc09mZiB8fCAoIWNvcmUuX2lzQmFsbG9vbkFsd2F5cyAmJiByYW5nZS5jb2xsYXBzZWQpKSBldmVudC5faGlkZVRvb2xiYXIoKTtcclxuICAgICAgICAgICAgZWxzZSBldmVudC5fc2hvd1Rvb2xiYXJCYWxsb29uKHJhbmdlKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfc2hvd1Rvb2xiYXJCYWxsb29uOiBmdW5jdGlvbiAocmFuZ2VPYmopIHtcclxuICAgICAgICAgICAgaWYgKCFjb3JlLl9pc0JhbGxvb24pIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHJhbmdlID0gcmFuZ2VPYmogfHwgY29yZS5nZXRSYW5nZSgpO1xyXG4gICAgICAgICAgICBjb25zdCB0b29sYmFyID0gY29udGV4dC5lbGVtZW50LnRvb2xiYXI7XHJcbiAgICAgICAgICAgIGNvbnN0IHRvcEFyZWEgPSBjb250ZXh0LmVsZW1lbnQudG9wQXJlYTtcclxuICAgICAgICAgICAgY29uc3Qgc2VsZWN0aW9uID0gY29yZS5nZXRTZWxlY3Rpb24oKTtcclxuXHJcbiAgICAgICAgICAgIGxldCBpc0RpclRvcDtcclxuICAgICAgICAgICAgaWYgKGNvcmUuX2lzQmFsbG9vbkFsd2F5cyAmJiByYW5nZS5jb2xsYXBzZWQpIHtcclxuICAgICAgICAgICAgICAgIGlzRGlyVG9wID0gdHJ1ZTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChzZWxlY3Rpb24uZm9jdXNOb2RlID09PSBzZWxlY3Rpb24uYW5jaG9yTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgaXNEaXJUb3AgPSBzZWxlY3Rpb24uZm9jdXNPZmZzZXQgPCBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0O1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2hpbGROb2RlcyA9IHV0aWwuZ2V0TGlzdENoaWxkTm9kZXMocmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIsIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgaXNEaXJUb3AgPSB1dGlsLmdldEFycmF5SW5kZXgoY2hpbGROb2Rlcywgc2VsZWN0aW9uLmZvY3VzTm9kZSkgPCB1dGlsLmdldEFycmF5SW5kZXgoY2hpbGROb2Rlcywgc2VsZWN0aW9uLmFuY2hvck5vZGUpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgcmVjdHMgPSByYW5nZS5nZXRDbGllbnRSZWN0cygpO1xyXG4gICAgICAgICAgICByZWN0cyA9IHJlY3RzW2lzRGlyVG9wID8gMCA6IHJlY3RzLmxlbmd0aCAtIDFdO1xyXG5cclxuICAgICAgICAgICAgbGV0IHNjcm9sbExlZnQgPSAwO1xyXG4gICAgICAgICAgICBsZXQgc2Nyb2xsVG9wID0gMDtcclxuICAgICAgICAgICAgbGV0IGVsID0gdG9wQXJlYTtcclxuICAgICAgICAgICAgd2hpbGUgKCEhZWwpIHtcclxuICAgICAgICAgICAgICAgIHNjcm9sbExlZnQgKz0gZWwuc2Nyb2xsTGVmdDtcclxuICAgICAgICAgICAgICAgIHNjcm9sbFRvcCArPSBlbC5zY3JvbGxUb3A7XHJcbiAgICAgICAgICAgICAgICBlbCA9IGVsLnBhcmVudEVsZW1lbnQ7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGVkaXRvcldpZHRoID0gdG9wQXJlYS5vZmZzZXRXaWR0aDtcclxuICAgICAgICAgICAgY29uc3Qgb2Zmc2V0cyA9IGV2ZW50Ll9nZXRFZGl0b3JPZmZzZXRzKG51bGwpO1xyXG4gICAgICAgICAgICBjb25zdCBzdGlja3lUb3AgPSBvZmZzZXRzLnRvcDtcclxuICAgICAgICAgICAgY29uc3QgZWRpdG9yTGVmdCA9IG9mZnNldHMubGVmdDtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIHRvb2xiYXIuc3R5bGUudG9wID0gJy0xMDAwMHB4JztcclxuICAgICAgICAgICAgdG9vbGJhci5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7XHJcbiAgICAgICAgICAgIHRvb2xiYXIuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcblxyXG4gICAgICAgICAgICBpZiAoIXJlY3RzKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBub2RlID0gY29yZS5nZXRTZWxlY3Rpb25Ob2RlKCk7XHJcbiAgICAgICAgICAgICAgICBpZiAodXRpbC5pc0Zvcm1hdEVsZW1lbnQobm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB6ZXJvV2lkdGggPSB1dGlsLmNyZWF0ZVRleHROb2RlKHV0aWwuemVyb1dpZHRoU3BhY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvcmUuaW5zZXJ0Tm9kZSh6ZXJvV2lkdGgsIG51bGwsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICBjb3JlLnNldFJhbmdlKHplcm9XaWR0aCwgMSwgemVyb1dpZHRoLCAxKTtcclxuICAgICAgICAgICAgICAgICAgICBjb3JlLl9lZGl0b3JSYW5nZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlY3RzID0gY29yZS5nZXRSYW5nZSgpLmdldENsaWVudFJlY3RzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVjdHMgPSByZWN0c1tpc0RpclRvcCA/IDAgOiByZWN0cy5sZW5ndGggLSAxXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIXJlY3RzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZU9mZnNldCA9IHV0aWwuZ2V0T2Zmc2V0KG5vZGUsIGNvbnRleHQuZWxlbWVudC53eXNpd3lnRnJhbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlY3RzID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0OiBub2RlT2Zmc2V0LmxlZnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogbm9kZU9mZnNldC50b3AsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0OiBub2RlT2Zmc2V0LmxlZnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvdHRvbTogbm9kZU9mZnNldC50b3AgKyBub2RlLm9mZnNldEhlaWdodCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgbm9UZXh0OiB0cnVlXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxMZWZ0ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxUb3AgPSAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlzRGlyVG9wID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgYXJyb3dNYXJnaW4gPSBfdy5NYXRoLnJvdW5kKGNvbnRleHQuZWxlbWVudC5fYXJyb3cub2Zmc2V0V2lkdGggLyAyKTtcclxuICAgICAgICAgICAgY29uc3QgdG9vbGJhcldpZHRoID0gdG9vbGJhci5vZmZzZXRXaWR0aDtcclxuICAgICAgICAgICAgY29uc3QgdG9vbGJhckhlaWdodCA9IHRvb2xiYXIub2Zmc2V0SGVpZ2h0O1xyXG4gICAgICAgICAgICBjb25zdCBpZnJhbWVSZWN0cyA9IC9pZnJhbWUvaS50ZXN0KGNvbnRleHQuZWxlbWVudC53eXNpd3lnRnJhbWUubm9kZU5hbWUpID8gY29udGV4dC5lbGVtZW50Lnd5c2l3eWdGcmFtZS5nZXRDbGllbnRSZWN0cygpWzBdIDogbnVsbDtcclxuICAgICAgICAgICAgaWYgKGlmcmFtZVJlY3RzKSB7XHJcbiAgICAgICAgICAgICAgICByZWN0cyA9IHtcclxuICAgICAgICAgICAgICAgICAgICBsZWZ0OiByZWN0cy5sZWZ0ICsgaWZyYW1lUmVjdHMubGVmdCxcclxuICAgICAgICAgICAgICAgICAgICB0b3A6IHJlY3RzLnRvcCArIGlmcmFtZVJlY3RzLnRvcCxcclxuICAgICAgICAgICAgICAgICAgICByaWdodDogcmVjdHMucmlnaHQgKyBpZnJhbWVSZWN0cy5yaWdodCAtIGlmcmFtZVJlY3RzLndpZHRoLFxyXG4gICAgICAgICAgICAgICAgICAgIGJvdHRvbTogcmVjdHMuYm90dG9tICsgaWZyYW1lUmVjdHMuYm90dG9tIC0gaWZyYW1lUmVjdHMuaGVpZ2h0XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBldmVudC5fc2V0VG9vbGJhck9mZnNldChpc0RpclRvcCwgcmVjdHMsIHRvb2xiYXIsIGVkaXRvckxlZnQsIGVkaXRvcldpZHRoLCBzY3JvbGxMZWZ0LCBzY3JvbGxUb3AsIHN0aWNreVRvcCwgYXJyb3dNYXJnaW4pO1xyXG4gICAgICAgICAgICBpZiAodG9vbGJhcldpZHRoICE9PSB0b29sYmFyLm9mZnNldFdpZHRoIHx8IHRvb2xiYXJIZWlnaHQgIT09IHRvb2xiYXIub2Zmc2V0SGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICBldmVudC5fc2V0VG9vbGJhck9mZnNldChpc0RpclRvcCwgcmVjdHMsIHRvb2xiYXIsIGVkaXRvckxlZnQsIGVkaXRvcldpZHRoLCBzY3JvbGxMZWZ0LCBzY3JvbGxUb3AsIHN0aWNreVRvcCwgYXJyb3dNYXJnaW4pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy50b29sYmFyQ29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBlZGl0b3JQYXJlbnQgPSB0b3BBcmVhLnBhcmVudEVsZW1lbnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IGNvbnRhaW5lciA9IG9wdGlvbnMudG9vbGJhckNvbnRhaW5lcjtcclxuICAgICAgICAgICAgICAgIGxldCBsZWZ0ID0gY29udGFpbmVyLm9mZnNldExlZnQ7XHJcbiAgICAgICAgICAgICAgICBsZXQgdG9wID0gY29udGFpbmVyLm9mZnNldFRvcDtcclxuXHJcbiAgICAgICAgICAgICAgICB3aGlsZSghY29udGFpbmVyLnBhcmVudEVsZW1lbnQuY29udGFpbnMoZWRpdG9yUGFyZW50KSB8fCAhL14oQk9EWXxIVE1MKSQvaS50ZXN0KGNvbnRhaW5lci5wYXJlbnRFbGVtZW50Lm5vZGVOYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lciA9IGNvbnRhaW5lci5vZmZzZXRQYXJlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgbGVmdCArPSBjb250YWluZXIub2Zmc2V0TGVmdDtcclxuICAgICAgICAgICAgICAgICAgICB0b3AgKz0gY29udGFpbmVyLm9mZnNldFRvcDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0b29sYmFyLnN0eWxlLmxlZnQgPSAodG9vbGJhci5vZmZzZXRMZWZ0IC0gbGVmdCArIHRvcEFyZWEub2Zmc2V0TGVmdCkgKyAncHgnO1xyXG4gICAgICAgICAgICAgICAgdG9vbGJhci5zdHlsZS50b3AgPSAodG9vbGJhci5vZmZzZXRUb3AgLSB0b3AgKyB0b3BBcmVhLm9mZnNldFRvcCkgKyAncHgnO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0b29sYmFyLnN0eWxlLnZpc2liaWxpdHkgPSAnJztcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfc2V0VG9vbGJhck9mZnNldDogZnVuY3Rpb24gKGlzRGlyVG9wLCByZWN0cywgdG9vbGJhciwgZWRpdG9yTGVmdCwgZWRpdG9yV2lkdGgsIHNjcm9sbExlZnQsIHNjcm9sbFRvcCwgc3RpY2t5VG9wLCBhcnJvd01hcmdpbikge1xyXG4gICAgICAgICAgICBjb25zdCBwYWRkaW5nID0gMTtcclxuICAgICAgICAgICAgY29uc3QgdG9vbGJhcldpZHRoID0gdG9vbGJhci5vZmZzZXRXaWR0aDtcclxuICAgICAgICAgICAgY29uc3QgdG9vbGJhckhlaWdodCA9IHJlY3RzLm5vVGV4dCAmJiAhaXNEaXJUb3AgPyAwIDogdG9vbGJhci5vZmZzZXRIZWlnaHQ7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBhYnNvbHV0ZUxlZnQgPSAoaXNEaXJUb3AgPyByZWN0cy5sZWZ0IDogcmVjdHMucmlnaHQpIC0gZWRpdG9yTGVmdCAtICh0b29sYmFyV2lkdGggLyAyKSArIHNjcm9sbExlZnQ7XHJcbiAgICAgICAgICAgIGNvbnN0IG92ZXJSaWdodCA9IGFic29sdXRlTGVmdCArIHRvb2xiYXJXaWR0aCAtIGVkaXRvcldpZHRoO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgbGV0IHQgPSAoaXNEaXJUb3AgPyByZWN0cy50b3AgLSB0b29sYmFySGVpZ2h0IC0gYXJyb3dNYXJnaW4gOiByZWN0cy5ib3R0b20gKyBhcnJvd01hcmdpbikgLSAocmVjdHMubm9UZXh0ID8gMCA6IHN0aWNreVRvcCkgKyBzY3JvbGxUb3A7XHJcbiAgICAgICAgICAgIGxldCBsID0gYWJzb2x1dGVMZWZ0IDwgMCA/IHBhZGRpbmcgOiBvdmVyUmlnaHQgPCAwID8gYWJzb2x1dGVMZWZ0IDogYWJzb2x1dGVMZWZ0IC0gb3ZlclJpZ2h0IC0gcGFkZGluZyAtIDE7XHJcblxyXG4gICAgICAgICAgICBsZXQgcmVzZXRUb3AgPSBmYWxzZTtcclxuICAgICAgICAgICAgY29uc3Qgc3BhY2UgPSB0ICsgKGlzRGlyVG9wID8gKGV2ZW50Ll9nZXRFZGl0b3JPZmZzZXRzKG51bGwpLnRvcCkgOiAodG9vbGJhci5vZmZzZXRIZWlnaHQgLSBjb250ZXh0LmVsZW1lbnQud3lzaXd5Zy5vZmZzZXRIZWlnaHQpKTtcclxuICAgICAgICAgICAgaWYgKCFpc0RpclRvcCAmJiBzcGFjZSA+IDAgJiYgZXZlbnQuX2dldFBhZ2VCb3R0b21TcGFjZSgpIDwgc3BhY2UpIHtcclxuICAgICAgICAgICAgICAgIGlzRGlyVG9wID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHJlc2V0VG9wID0gdHJ1ZTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc0RpclRvcCAmJiBfZC5kb2N1bWVudEVsZW1lbnQub2Zmc2V0VG9wID4gc3BhY2UpIHtcclxuICAgICAgICAgICAgICAgIGlzRGlyVG9wID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICByZXNldFRvcCA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChyZXNldFRvcCkgdCA9IChpc0RpclRvcCA/IHJlY3RzLnRvcCAtIHRvb2xiYXJIZWlnaHQgLSBhcnJvd01hcmdpbiA6IHJlY3RzLmJvdHRvbSArIGFycm93TWFyZ2luKSAtIChyZWN0cy5ub1RleHQgPyAwIDogc3RpY2t5VG9wKSArIHNjcm9sbFRvcDtcclxuXHJcbiAgICAgICAgICAgIHRvb2xiYXIuc3R5bGUubGVmdCA9IF93Lk1hdGguZmxvb3IobCkgKyAncHgnO1xyXG4gICAgICAgICAgICB0b29sYmFyLnN0eWxlLnRvcCA9IF93Lk1hdGguZmxvb3IodCkgKyAncHgnO1xyXG5cclxuICAgICAgICAgICAgaWYgKGlzRGlyVG9wKSB7XHJcbiAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUNsYXNzKGNvbnRleHQuZWxlbWVudC5fYXJyb3csICdzZS1hcnJvdy11cCcpO1xyXG4gICAgICAgICAgICAgICAgdXRpbC5hZGRDbGFzcyhjb250ZXh0LmVsZW1lbnQuX2Fycm93LCAnc2UtYXJyb3ctZG93bicpO1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5lbGVtZW50Ll9hcnJvdy5zdHlsZS50b3AgPSB0b29sYmFySGVpZ2h0ICsgJ3B4JztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlQ2xhc3MoY29udGV4dC5lbGVtZW50Ll9hcnJvdywgJ3NlLWFycm93LWRvd24nKTtcclxuICAgICAgICAgICAgICAgIHV0aWwuYWRkQ2xhc3MoY29udGV4dC5lbGVtZW50Ll9hcnJvdywgJ3NlLWFycm93LXVwJyk7XHJcbiAgICAgICAgICAgICAgICBjb250ZXh0LmVsZW1lbnQuX2Fycm93LnN0eWxlLnRvcCA9IC1hcnJvd01hcmdpbiArICdweCc7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGFycm93X2xlZnQgPSBfdy5NYXRoLmZsb29yKCh0b29sYmFyV2lkdGggLyAyKSArIChhYnNvbHV0ZUxlZnQgLSBsKSk7XHJcbiAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5fYXJyb3cuc3R5bGUubGVmdCA9IChhcnJvd19sZWZ0ICsgYXJyb3dNYXJnaW4gPiB0b29sYmFyLm9mZnNldFdpZHRoID8gdG9vbGJhci5vZmZzZXRXaWR0aCAtIGFycm93TWFyZ2luIDogYXJyb3dfbGVmdCA8IGFycm93TWFyZ2luID8gYXJyb3dNYXJnaW4gOiBhcnJvd19sZWZ0KSArICdweCc7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX3Nob3dUb29sYmFySW5saW5lOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICghY29yZS5faXNJbmxpbmUpIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHRvb2xiYXIgPSBjb250ZXh0LmVsZW1lbnQudG9vbGJhcjtcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMudG9vbGJhckNvbnRhaW5lcikgdG9vbGJhci5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XHJcbiAgICAgICAgICAgIGVsc2UgdG9vbGJhci5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICB0b29sYmFyLnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcclxuICAgICAgICAgICAgdG9vbGJhci5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuICAgICAgICAgICAgY29yZS5faW5saW5lVG9vbGJhckF0dHIud2lkdGggPSB0b29sYmFyLnN0eWxlLndpZHRoID0gb3B0aW9ucy50b29sYmFyV2lkdGg7XHJcbiAgICAgICAgICAgIGNvcmUuX2lubGluZVRvb2xiYXJBdHRyLnRvcCA9IHRvb2xiYXIuc3R5bGUudG9wID0gKG9wdGlvbnMudG9vbGJhckNvbnRhaW5lciA/IDAgOiAoLTEgLSB0b29sYmFyLm9mZnNldEhlaWdodCkpICsgJ3B4JztcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZnVuY3Rpb25zLnNob3dJbmxpbmUgPT09ICdmdW5jdGlvbicpIGZ1bmN0aW9ucy5zaG93SW5saW5lKHRvb2xiYXIsIGNvbnRleHQsIGNvcmUpO1xyXG5cclxuICAgICAgICAgICAgZXZlbnQub25TY3JvbGxfd2luZG93KCk7XHJcbiAgICAgICAgICAgIGNvcmUuX2lubGluZVRvb2xiYXJBdHRyLmlzU2hvdyA9IHRydWU7XHJcbiAgICAgICAgICAgIHRvb2xiYXIuc3R5bGUudmlzaWJpbGl0eSA9ICcnO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9oaWRlVG9vbGJhcjogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoIWNvcmUuX25vdEhpZGVUb29sYmFyICYmICFjb3JlLl92YXJpYWJsZS5pc0Z1bGxTY3JlZW4pIHtcclxuICAgICAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC50b29sYmFyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICBjb3JlLl9pbmxpbmVUb29sYmFyQXR0ci5pc1Nob3cgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIG9uSW5wdXRfd3lzaXd5ZzogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgY29yZS5fZWRpdG9yUmFuZ2UoKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSAoZS5kYXRhID09PSBudWxsID8gJycgOiBlLmRhdGEgPT09IHVuZGVmaW5lZCA/ICcgJyA6IGUuZGF0YSkgfHwgJyc7ICAgICAgIFxyXG4gICAgICAgICAgICBpZiAoIWNvcmUuX2NoYXJDb3VudChkYXRhKSkge1xyXG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gaGlzdG9yeSBzdGFja1xyXG4gICAgICAgICAgICBjb3JlLmhpc3RvcnkucHVzaCh0cnVlKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZnVuY3Rpb25zLm9uSW5wdXQgPT09ICdmdW5jdGlvbicpIGZ1bmN0aW9ucy5vbklucHV0KGUsIGNvcmUpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9vblNob3J0Y3V0S2V5OiBmYWxzZSxcclxuICAgICAgICBvbktleURvd25fd3lzaXd5ZzogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgY29uc3Qga2V5Q29kZSA9IGUua2V5Q29kZTtcclxuICAgICAgICAgICAgY29uc3Qgc2hpZnQgPSBlLnNoaWZ0S2V5O1xyXG4gICAgICAgICAgICBjb25zdCBjdHJsID0gZS5jdHJsS2V5IHx8IGUubWV0YUtleSB8fCBrZXlDb2RlID09PSA5MSB8fCBrZXlDb2RlID09PSA5MiB8fCBrZXlDb2RlID09PSAyMjQ7XHJcbiAgICAgICAgICAgIGNvbnN0IGFsdCA9IGUuYWx0S2V5O1xyXG4gICAgICAgICAgICBldmVudC5fSUVpc0NvbXBvc2luZyA9IGtleUNvZGUgPT09IDIyOTtcclxuXHJcbiAgICAgICAgICAgIGNvcmUuc3VibWVudU9mZigpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGNvcmUuX2lzQmFsbG9vbikge1xyXG4gICAgICAgICAgICAgICAgZXZlbnQuX2hpZGVUb29sYmFyKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8qKiBTaG9ydGN1dHMgKi9cclxuICAgICAgICAgICAgaWYgKGN0cmwgJiYgZXZlbnQuX3Nob3J0Y3V0Q29tbWFuZChrZXlDb2RlLCBzaGlmdCkpIHtcclxuICAgICAgICAgICAgICAgIGV2ZW50Ll9vblNob3J0Y3V0S2V5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZXZlbnQuX29uU2hvcnRjdXRLZXkpIHtcclxuICAgICAgICAgICAgICAgIGV2ZW50Ll9vblNob3J0Y3V0S2V5ID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8qKiBkZWZhdWx0IGtleSBhY3Rpb24gKi9cclxuICAgICAgICAgICAgbGV0IHNlbGVjdGlvbk5vZGUgPSBjb3JlLmdldFNlbGVjdGlvbk5vZGUoKTtcclxuICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSBjb3JlLmdldFJhbmdlKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdFJhbmdlID0gIXJhbmdlLmNvbGxhcHNlZCB8fCByYW5nZS5zdGFydENvbnRhaW5lciAhPT0gcmFuZ2UuZW5kQ29udGFpbmVyO1xyXG4gICAgICAgICAgICBjb25zdCBmaWxlQ29tcG9uZW50TmFtZSA9IGNvcmUuX2ZpbGVNYW5hZ2VyLnBsdWdpblJlZ0V4cC50ZXN0KGNvcmUuY3VycmVudENvbnRyb2xsZXJOYW1lKSA/IGNvcmUuY3VycmVudENvbnRyb2xsZXJOYW1lIDogJyc7XHJcbiAgICAgICAgICAgIGxldCBmb3JtYXRFbCA9IHV0aWwuZ2V0Rm9ybWF0RWxlbWVudChzZWxlY3Rpb25Ob2RlLCBudWxsKSB8fCBzZWxlY3Rpb25Ob2RlO1xyXG4gICAgICAgICAgICBsZXQgcmFuZ2VFbCA9IHV0aWwuZ2V0UmFuZ2VGb3JtYXRFbGVtZW50KGZvcm1hdEVsLCBudWxsKTtcclxuXHJcbiAgICAgICAgICAgIHN3aXRjaCAoa2V5Q29kZSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSA4OiAvKiogYmFja3NwYWNlIGtleSAqL1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghc2VsZWN0UmFuZ2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVDb21wb25lbnROYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZS5wbHVnaW5zW2ZpbGVDb21wb25lbnROYW1lXS5kZXN0cm95LmNhbGwoY29yZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdFJhbmdlICYmIGV2ZW50Ll9oYXJkRGVsZXRlKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdXRpbC5pc0Zvcm1hdEVsZW1lbnQoZm9ybWF0RWwpICYmICFjb250ZXh0LmVsZW1lbnQud3lzaXd5Zy5maXJzdEVsZW1lbnRDaGlsZCAmJiAhdXRpbC5pc0NvbXBvbmVudChzZWxlY3Rpb25Ob2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuX3NldERlZmF1bHRGb3JtYXQob3B0aW9ucy5kZWZhdWx0VGFnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzZWxlY3RSYW5nZSAmJiAhZm9ybWF0RWwucHJldmlvdXNFbGVtZW50U2libGluZyAmJiAocmFuZ2Uuc3RhcnRPZmZzZXQgPT09IDAgJiYgIXNlbGVjdGlvbk5vZGUucHJldmlvdXNTaWJsaW5nICYmICF1dGlsLmlzTGlzdENlbGwoZm9ybWF0RWwpICYmIFxyXG4gICAgICAgICAgICAgICAgICAgICAodXRpbC5pc0Zvcm1hdEVsZW1lbnQoZm9ybWF0RWwpICYmICghdXRpbC5pc0ZyZWVGb3JtYXRFbGVtZW50KGZvcm1hdEVsKSB8fCB1dGlsLmlzQ2xvc3VyZUZyZWVGb3JtYXRFbGVtZW50KGZvcm1hdEVsKSkpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjbG9zdXJlIHJhbmdlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1dGlsLmlzQ2xvc3VyZVJhbmdlRm9ybWF0RWxlbWVudChmb3JtYXRFbC5wYXJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBtYWludGFpbiBkZWZhdWx0IGZvcm1hdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5pc1d5c2l3eWdEaXYoZm9ybWF0RWwucGFyZW50Tm9kZSkgJiYgZm9ybWF0RWwuY2hpbGROb2Rlcy5sZW5ndGggPD0gMSAmJiAoIWZvcm1hdEVsLmZpcnN0Q2hpbGQgfHwgdXRpbC5vbmx5WmVyb1dpZHRoU3BhY2UoZm9ybWF0RWwudGV4dENvbnRlbnQpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXRFbC5pbm5lckhUTUwgPSAnPGJyPic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhdHRycyA9IGZvcm1hdEVsLmF0dHJpYnV0ZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoYXR0cnNbMF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXRFbC5yZW1vdmVBdHRyaWJ1dGUoYXR0cnNbMF0ubmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlLm5hdGl2ZUZvY3VzKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBjbGVhbiByZW1vdmUgdGFnXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZvcm1hdEVsICYmIHJhbmdlLnN0YXJ0Q29udGFpbmVyID09PSByYW5nZS5lbmRDb250YWluZXIgJiYgc2VsZWN0aW9uTm9kZS5ub2RlVHlwZSA9PT0gMyAmJiAhdXRpbC5pc0Zvcm1hdEVsZW1lbnQoc2VsZWN0aW9uTm9kZS5wYXJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmFuZ2UuY29sbGFwc2VkID8gc2VsZWN0aW9uTm9kZS50ZXh0Q29udGVudC5sZW5ndGggPT09IDEgOiAocmFuZ2UuZW5kT2Zmc2V0IC0gcmFuZ2Uuc3RhcnRPZmZzZXQpID09PSBzZWxlY3Rpb25Ob2RlLnRleHRDb250ZW50Lmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBvZmZzZXQgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHByZXYgPSBzZWxlY3Rpb25Ob2RlLnBhcmVudE5vZGUucHJldmlvdXNTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV4dCA9IHNlbGVjdGlvbk5vZGUucGFyZW50Tm9kZS5uZXh0U2libGluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcHJldikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbmV4dCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2ID0gdXRpbC5jcmVhdGVFbGVtZW50KCdCUicpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXRFbC5hcHBlbmRDaGlsZChwcmV2KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2ID0gbmV4dDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uTm9kZS50ZXh0Q29udGVudCA9ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVJdGVtQWxsUGFyZW50cyhzZWxlY3Rpb25Ob2RlLCBudWxsLCBmb3JtYXRFbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSB0eXBlb2Ygb2Zmc2V0ID09PSAnbnVtYmVyJyA/IG9mZnNldCA6IHByZXYubm9kZVR5cGUgPT09IDMgPyBwcmV2LnRleHRDb250ZW50Lmxlbmd0aCA6IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlLnNldFJhbmdlKHByZXYsIG9mZnNldCwgcHJldiwgb2Zmc2V0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBuZXN0ZWQgbGlzdFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbW1vbkNvbiA9IHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvcm1hdEVsID0gdXRpbC5nZXRGb3JtYXRFbGVtZW50KHJhbmdlLnN0YXJ0Q29udGFpbmVyLCBudWxsKTtcclxuICAgICAgICAgICAgICAgICAgICByYW5nZUVsID0gdXRpbC5nZXRSYW5nZUZvcm1hdEVsZW1lbnQoZm9ybWF0RWwsIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyYW5nZUVsICYmIGZvcm1hdEVsICYmICF1dGlsLmlzQ2VsbChyYW5nZUVsKSAmJiAhL15GSUdDQVBUSU9OJC9pLnRlc3QocmFuZ2VFbC5ub2RlTmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHV0aWwuaXNMaXN0Q2VsbChmb3JtYXRFbCkgJiYgdXRpbC5pc0xpc3QocmFuZ2VFbCkgJiYgKHV0aWwuaXNMaXN0Q2VsbChyYW5nZUVsLnBhcmVudE5vZGUpIHx8IGZvcm1hdEVsLnByZXZpb3VzRWxlbWVudFNpYmxpbmcpICYmIChzZWxlY3Rpb25Ob2RlID09PSBmb3JtYXRFbCB8fCAoc2VsZWN0aW9uTm9kZS5ub2RlVHlwZSA9PT0gMyAmJiAoIXNlbGVjdGlvbk5vZGUucHJldmlvdXNTaWJsaW5nIHx8IHV0aWwuaXNMaXN0KHNlbGVjdGlvbk5vZGUucHJldmlvdXNTaWJsaW5nKSkpKSAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgKHV0aWwuZ2V0Rm9ybWF0RWxlbWVudChyYW5nZS5zdGFydENvbnRhaW5lciwgbnVsbCkgIT09IHV0aWwuZ2V0Rm9ybWF0RWxlbWVudChyYW5nZS5lbmRDb250YWluZXIsIG51bGwpID8gcmFuZ2VFbC5jb250YWlucyhyYW5nZS5zdGFydENvbnRhaW5lcikgOiAocmFuZ2Uuc3RhcnRPZmZzZXQgPT09IDAgICYmIHJhbmdlLmNvbGxhcHNlZCkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmFuZ2Uuc3RhcnRDb250YWluZXIgIT09IHJhbmdlLmVuZENvbnRhaW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZS5yZW1vdmVOb2RlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJhbmdlLnN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlID09PSAzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuc2V0UmFuZ2UocmFuZ2Uuc3RhcnRDb250YWluZXIsIHJhbmdlLnN0YXJ0Q29udGFpbmVyLnRleHRDb250ZW50Lmxlbmd0aCwgcmFuZ2Uuc3RhcnRDb250YWluZXIsIHJhbmdlLnN0YXJ0Q29udGFpbmVyLnRleHRDb250ZW50Lmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhpc3Rvcnkgc3RhY2tcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlLmhpc3RvcnkucHVzaCh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHByZXYgPSBmb3JtYXRFbC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nIHx8IHJhbmdlRWwucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5pc0xpc3RDZWxsKHByZXYpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBwcmV2TGFzdCA9IHByZXY7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcHJldi5jb250YWlucyhmb3JtYXRFbCkgJiYgdXRpbC5pc0xpc3RDZWxsKHByZXZMYXN0KSAmJiB1dGlsLmlzTGlzdChwcmV2TGFzdC5sYXN0RWxlbWVudENoaWxkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldkxhc3QgPSBwcmV2TGFzdC5sYXN0RWxlbWVudENoaWxkLmxhc3RFbGVtZW50Q2hpbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAodXRpbC5pc0xpc3RDZWxsKHByZXZMYXN0KSAmJiB1dGlsLmlzTGlzdChwcmV2TGFzdC5sYXN0RWxlbWVudENoaWxkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZMYXN0ID0gcHJldkxhc3QubGFzdEVsZW1lbnRDaGlsZCAmJiBwcmV2TGFzdC5sYXN0RWxlbWVudENoaWxkLmxhc3RFbGVtZW50Q2hpbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2ID0gcHJldkxhc3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjb24gPSBwcmV2ID09PSByYW5nZUVsLnBhcmVudE5vZGUgPyByYW5nZUVsLnByZXZpb3VzU2libGluZyA6IHByZXYubGFzdENoaWxkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uID0gdXRpbC5jcmVhdGVUZXh0Tm9kZSh1dGlsLnplcm9XaWR0aFNwYWNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlRWwucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoY29uLCByYW5nZUVsLnBhcmVudE5vZGUuZmlyc3RDaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0ID0gY29uLm5vZGVUeXBlID09PSAzID8gY29uLnRleHRDb250ZW50Lmxlbmd0aCA6IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkcmVuID0gZm9ybWF0RWwuY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGFmdGVyID0gY29uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY2hpbGQgPSBjaGlsZHJlblswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChjaGlsZCA9IGNoaWxkcmVuWzBdKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldi5pbnNlcnRCZWZvcmUoY2hpbGQsIGFmdGVyLm5leHRTaWJsaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFmdGVyID0gY2hpbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlSXRlbShmb3JtYXRFbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyYW5nZUVsLmNoaWxkcmVuLmxlbmd0aCA9PT0gMCkgdXRpbC5yZW1vdmVJdGVtKHJhbmdlRWwpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZS5zZXRSYW5nZShjb24sIG9mZnNldCwgY29uLCBvZmZzZXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBoaXN0b3J5IHN0YWNrXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuaGlzdG9yeS5wdXNoKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRldGFjaCByYW5nZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNlbGVjdFJhbmdlICYmIHJhbmdlLnN0YXJ0T2Zmc2V0ID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZGV0YWNoID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjb21tID0gY29tbW9uQ29uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNvbW0gJiYgY29tbSAhPT0gcmFuZ2VFbCAmJiAhdXRpbC5pc1d5c2l3eWdEaXYoY29tbSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tbS5wcmV2aW91c1NpYmxpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbW0ucHJldmlvdXNTaWJsaW5nLm5vZGVUeXBlID09PSAxIHx8ICF1dGlsLm9ubHlaZXJvV2lkdGhTcGFjZShjb21tLnByZXZpb3VzU2libGluZy50ZXh0Q29udGVudC50cmltKCkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXRhY2ggPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW0gPSBjb21tLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZXRhY2ggJiYgcmFuZ2VFbC5wYXJlbnROb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuZGV0YWNoUmFuZ2VGb3JtYXRFbGVtZW50KHJhbmdlRWwsICh1dGlsLmlzTGlzdENlbGwoZm9ybWF0RWwpID8gW2Zvcm1hdEVsXSA6IG51bGwpLCBudWxsLCBmYWxzZSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhpc3Rvcnkgc3RhY2tcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlLmhpc3RvcnkucHVzaCh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY29tcG9uZW50XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzZWxlY3RSYW5nZSAmJiAocmFuZ2Uuc3RhcnRPZmZzZXQgPT09IDAgfHwgKHNlbGVjdGlvbk5vZGUgPT09IGZvcm1hdEVsID8gISFmb3JtYXRFbC5jaGlsZE5vZGVzW3JhbmdlLnN0YXJ0T2Zmc2V0XSA6IGZhbHNlKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2VsID0gc2VsZWN0aW9uTm9kZSA9PT0gZm9ybWF0RWwgPyBmb3JtYXRFbC5jaGlsZE5vZGVzW3JhbmdlLnN0YXJ0T2Zmc2V0XSA6IHNlbGVjdGlvbk5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlbGVjdCBmaWxlIGNvbXBvbmVudFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpZ25vcmVaV1MgPSAoY29tbW9uQ29uLm5vZGVUeXBlID09PSAzIHx8IHV0aWwuaXNCcmVhayhjb21tb25Db24pKSAmJiAhY29tbW9uQ29uLnByZXZpb3VzU2libGluZyAmJiByYW5nZS5zdGFydE9mZnNldCA9PT0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzZWwucHJldmlvdXNTaWJsaW5nICYmICh1dGlsLmlzQ29tcG9uZW50KGNvbW1vbkNvbi5wcmV2aW91c1NpYmxpbmcpIHx8IChpZ25vcmVaV1MgJiYgdXRpbC5pc0NvbXBvbmVudChmb3JtYXRFbC5wcmV2aW91c1NpYmxpbmcpKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbGVDb21wb25lbnRJbmZvID0gY29yZS5nZXRGaWxlQ29tcG9uZW50KGZvcm1hdEVsLnByZXZpb3VzU2libGluZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZUNvbXBvbmVudEluZm8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZm9ybWF0RWwudGV4dENvbnRlbnQubGVuZ3RoID09PSAwKSB1dGlsLnJlbW92ZUl0ZW0oZm9ybWF0RWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuc2VsZWN0Q29tcG9uZW50KGZpbGVDb21wb25lbnRJbmZvLnRhcmdldCwgZmlsZUNvbXBvbmVudEluZm8ucGx1Z2luTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBkZWxldGUgbm9uRWRpdGFibGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHV0aWwuaXNOb25FZGl0YWJsZShzZWwucHJldmlvdXNTaWJsaW5nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlSXRlbShzZWwucHJldmlvdXNTaWJsaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDY6IC8qKiBkZWxldGUga2V5ICovXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVDb21wb25lbnROYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29yZS5wbHVnaW5zW2ZpbGVDb21wb25lbnROYW1lXS5kZXN0cm95LmNhbGwoY29yZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdFJhbmdlICYmIGV2ZW50Ll9oYXJkRGVsZXRlKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbXBvbmVudFxyXG4gICAgICAgICAgICAgICAgICAgIGlmICgodXRpbC5pc0Zvcm1hdEVsZW1lbnQoc2VsZWN0aW9uTm9kZSkgfHwgc2VsZWN0aW9uTm9kZS5uZXh0U2libGluZyA9PT0gbnVsbCB8fCAodXRpbC5vbmx5WmVyb1dpZHRoU3BhY2Uoc2VsZWN0aW9uTm9kZS5uZXh0U2libGluZykgJiYgc2VsZWN0aW9uTm9kZS5uZXh0U2libGluZy5uZXh0U2libGluZyA9PT0gbnVsbCkpICYmIHJhbmdlLnN0YXJ0T2Zmc2V0ID09PSBzZWxlY3Rpb25Ob2RlLnRleHRDb250ZW50Lmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbmV4dEVsID0gZm9ybWF0RWwubmV4dEVsZW1lbnRTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW5leHRFbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1dGlsLmlzQ29tcG9uZW50KG5leHRFbCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5vbmx5WmVyb1dpZHRoU3BhY2UoZm9ybWF0RWwpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVJdGVtKGZvcm1hdEVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0YWJsZSBjb21wb25lbnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5pc1RhYmxlKG5leHRFbCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNlbGwgPSB1dGlsLmdldENoaWxkRWxlbWVudChuZXh0RWwsIHV0aWwuaXNDZWxsLCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwgPSBjZWxsLmZpcnN0RWxlbWVudENoaWxkIHx8IGNlbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuc2V0UmFuZ2UoY2VsbCwgMCwgY2VsbCwgMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzZWxlY3QgZmlsZSBjb21wb25lbnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbGVDb21wb25lbnRJbmZvID0gY29yZS5nZXRGaWxlQ29tcG9uZW50KG5leHRFbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZUNvbXBvbmVudEluZm8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuc2VsZWN0Q29tcG9uZW50KGZpbGVDb21wb25lbnRJbmZvLnRhcmdldCwgZmlsZUNvbXBvbmVudEluZm8ucGx1Z2luTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghc2VsZWN0UmFuZ2UgJiYgKGNvcmUuaXNFZGdlUG9pbnQocmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpIHx8IChzZWxlY3Rpb25Ob2RlID09PSBmb3JtYXRFbCA/ICEhZm9ybWF0RWwuY2hpbGROb2Rlc1tyYW5nZS5zdGFydE9mZnNldF0gOiBmYWxzZSkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNlbCA9IHNlbGVjdGlvbk5vZGUgPT09IGZvcm1hdEVsID8gZm9ybWF0RWwuY2hpbGROb2Rlc1tyYW5nZS5zdGFydE9mZnNldF0gOiBzZWxlY3Rpb25Ob2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBkZWxldGUgbm9uRWRpdGFibGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHV0aWwuaXNOb25FZGl0YWJsZShzZWwubmV4dFNpYmxpbmcpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVJdGVtKHNlbC5uZXh0U2libGluZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gbmVzdGVkIGxpc3RcclxuICAgICAgICAgICAgICAgICAgICBmb3JtYXRFbCA9IHV0aWwuZ2V0Rm9ybWF0RWxlbWVudChyYW5nZS5zdGFydENvbnRhaW5lciwgbnVsbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmFuZ2VFbCA9IHV0aWwuZ2V0UmFuZ2VGb3JtYXRFbGVtZW50KGZvcm1hdEVsLCBudWxsKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5pc0xpc3RDZWxsKGZvcm1hdEVsKSAmJiB1dGlsLmlzTGlzdChyYW5nZUVsKSAmJiAoc2VsZWN0aW9uTm9kZSA9PT0gZm9ybWF0RWwgfHwgKHNlbGVjdGlvbk5vZGUubm9kZVR5cGUgPT09IDMgJiYgKCFzZWxlY3Rpb25Ob2RlLm5leHRTaWJsaW5nIHx8IHV0aWwuaXNMaXN0KHNlbGVjdGlvbk5vZGUubmV4dFNpYmxpbmcpKSAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAodXRpbC5nZXRGb3JtYXRFbGVtZW50KHJhbmdlLnN0YXJ0Q29udGFpbmVyLCBudWxsKSAhPT0gdXRpbC5nZXRGb3JtYXRFbGVtZW50KHJhbmdlLmVuZENvbnRhaW5lciwgbnVsbCkgPyByYW5nZUVsLmNvbnRhaW5zKHJhbmdlLmVuZENvbnRhaW5lcikgOiAocmFuZ2UuZW5kT2Zmc2V0ID09PSBzZWxlY3Rpb25Ob2RlLnRleHRDb250ZW50Lmxlbmd0aCAmJiByYW5nZS5jb2xsYXBzZWQpKSkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyYW5nZS5zdGFydENvbnRhaW5lciAhPT0gcmFuZ2UuZW5kQ29udGFpbmVyKSBjb3JlLnJlbW92ZU5vZGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBuZXh0ID0gdXRpbC5nZXRBcnJheUl0ZW0oZm9ybWF0RWwuY2hpbGRyZW4sIHV0aWwuaXNMaXN0LCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgPSBuZXh0IHx8IGZvcm1hdEVsLm5leHRFbGVtZW50U2libGluZyB8fCByYW5nZUVsLnBhcmVudE5vZGUubmV4dEVsZW1lbnRTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dCAmJiAodXRpbC5pc0xpc3QobmV4dCkgfHwgdXRpbC5nZXRBcnJheUl0ZW0obmV4dC5jaGlsZHJlbiwgdXRpbC5pc0xpc3QsIGZhbHNlKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY29uLCBjaGlsZHJlbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1dGlsLmlzTGlzdChuZXh0KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkID0gbmV4dC5maXJzdEVsZW1lbnRDaGlsZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkLmNoaWxkTm9kZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uID0gY2hpbGRyZW5bMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNoaWxkcmVuWzBdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdEVsLmluc2VydEJlZm9yZShjaGlsZHJlblswXSwgbmV4dCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlSXRlbShjaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbiA9IG5leHQuZmlyc3RDaGlsZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IG5leHQuY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hpbGRyZW5bMF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0RWwuYXBwZW5kQ2hpbGQoY2hpbGRyZW5bMF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW0obmV4dCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlLnNldFJhbmdlKGNvbiwgMCwgY29uLCAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhpc3Rvcnkgc3RhY2tcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuaGlzdG9yeS5wdXNoKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDk6IC8qKiB0YWIga2V5ICovXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVDb21wb25lbnROYW1lIHx8IG9wdGlvbnMudGFiRGlzYWJsZSkgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjdHJsIHx8IGFsdCB8fCB1dGlsLmlzV3lzaXd5Z0RpdihzZWxlY3Rpb25Ob2RlKSkgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlzRWRnZSA9ICghcmFuZ2UuY29sbGFwc2VkIHx8IGNvcmUuaXNFZGdlUG9pbnQocmFuZ2Uuc3RhcnRDb250YWluZXIsIHJhbmdlLnN0YXJ0T2Zmc2V0KSk7ICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWRGb3JtYXRzID0gY29yZS5nZXRTZWxlY3RlZEVsZW1lbnRzKG51bGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvbk5vZGUgPSBjb3JlLmdldFNlbGVjdGlvbk5vZGUoKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjZWxscyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBsaW5lcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBmYyA9IHV0aWwuaXNMaXN0Q2VsbChzZWxlY3RlZEZvcm1hdHNbMF0pLCBsYyA9IHV0aWwuaXNMaXN0Q2VsbChzZWxlY3RlZEZvcm1hdHNbc2VsZWN0ZWRGb3JtYXRzLmxlbmd0aCAtIDFdKTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgciA9IHtzYzogcmFuZ2Uuc3RhcnRDb250YWluZXIsIHNvOiByYW5nZS5zdGFydE9mZnNldCwgZWM6IHJhbmdlLmVuZENvbnRhaW5lciwgZW86IHJhbmdlLmVuZE9mZnNldH07XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHNlbGVjdGVkRm9ybWF0cy5sZW5ndGgsIGY7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmID0gc2VsZWN0ZWRGb3JtYXRzW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5pc0xpc3RDZWxsKGYpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWYucHJldmlvdXNFbGVtZW50U2libGluZyAmJiAhc2hpZnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbHMucHVzaChmKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVzLnB1c2goZik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gTmVzdGVkIGxpc3RcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2VsbHMubGVuZ3RoID4gMCAmJiBpc0VkZ2UgJiYgY29yZS5wbHVnaW5zLmxpc3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgciA9IGNvcmUucGx1Z2lucy5saXN0LmVkaXRJbnNpZGVMaXN0LmNhbGwoY29yZSwgc2hpZnQsIGNlbGxzKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0YWJsZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0YWJsZUNlbGwgPSB1dGlsLmdldFBhcmVudEVsZW1lbnQoc2VsZWN0aW9uTm9kZSwgdXRpbC5pc0NlbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFibGVDZWxsICYmIGlzRWRnZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFibGUgPSB1dGlsLmdldFBhcmVudEVsZW1lbnQodGFibGVDZWxsLCAndGFibGUnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNlbGxzID0gdXRpbC5nZXRMaXN0Q2hpbGRyZW4odGFibGUsIHV0aWwuaXNDZWxsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpZHggPSBzaGlmdCA/IHV0aWwucHJldklkeChjZWxscywgdGFibGVDZWxsKSA6IHV0aWwubmV4dElkeChjZWxscywgdGFibGVDZWxsKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaWR4ID09PSBjZWxscy5sZW5ndGggJiYgIXNoaWZ0KSBpZHggPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlkeCA9PT0gLTEgJiYgc2hpZnQpIGlkeCA9IGNlbGxzLmxlbmd0aCAtIDE7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG1vdmVDZWxsID0gY2VsbHNbaWR4XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbW92ZUNlbGwpIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW92ZUNlbGwgPSBtb3ZlQ2VsbC5maXJzdEVsZW1lbnRDaGlsZCB8fCBtb3ZlQ2VsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuc2V0UmFuZ2UobW92ZUNlbGwsIDAsIG1vdmVDZWxsLCAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lcyA9IGxpbmVzLmNvbmNhdChjZWxscyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZjID0gbGMgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gTGluZXMgdGFiKDQpXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzaGlmdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFiVGV4dCA9IHV0aWwuY3JlYXRlVGV4dE5vZGUobmV3IF93LkFycmF5KGNvcmUuX3ZhcmlhYmxlLnRhYlNpemUgKyAxKS5qb2luKCdcXHUwMEEwJykpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmVzLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRleHRSYW5nZSA9IGNvcmUuaW5zZXJ0Tm9kZSh0YWJUZXh0LCBudWxsLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRleHRSYW5nZSkgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgci5zYyA9IHRhYlRleHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHIuc28gPSB0ZXh0UmFuZ2UuZW5kT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWxjKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHIuZWMgPSB0YWJUZXh0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByLmVvID0gdGV4dFJhbmdlLmVuZE9mZnNldDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxlbiA9IGxpbmVzLmxlbmd0aCAtIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGNoaWxkOyBpIDw9IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkID0gbGluZXNbaV0uZmlyc3RDaGlsZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGlsZCkgY29udGludWU7XHJcbiAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHV0aWwuaXNCcmVhayhjaGlsZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVzW2ldLmluc2VydEJlZm9yZSh0YWJUZXh0LmNsb25lTm9kZShmYWxzZSksIGNoaWxkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnRleHRDb250ZW50ID0gdGFiVGV4dC50ZXh0Q29udGVudCArIGNoaWxkLnRleHRDb250ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyc3RDaGlsZCA9IHV0aWwuZ2V0Q2hpbGRFbGVtZW50KGxpbmVzWzBdLCAndGV4dCcsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmRDaGlsZCA9IHV0aWwuZ2V0Q2hpbGRFbGVtZW50KGxpbmVzW2xlbl0sICd0ZXh0JywgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmYyAmJiBmaXJzdENoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHIuc2MgPSBmaXJzdENoaWxkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByLnNvID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFsYyAmJiBlbmRDaGlsZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByLmVjID0gZW5kQ2hpbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHIuZW8gPSBlbmRDaGlsZC50ZXh0Q29udGVudC5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbGVuID0gbGluZXMubGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsaW5lOyBpIDw9IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZSA9IGxpbmVzW2ldLmNoaWxkTm9kZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgYyA9IDAsIGNMZW4gPSBsaW5lLmxlbmd0aCwgY2hpbGQ7IGMgPCBjTGVuOyBjKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQgPSBsaW5lW2NdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNoaWxkKSBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHV0aWwub25seVplcm9XaWR0aFNwYWNlKGNoaWxkKSkgY29udGludWU7XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgvXlxcc3sxLDR9JC8udGVzdChjaGlsZC50ZXh0Q29udGVudCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlSXRlbShjaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoL15cXHN7MSw0fS8udGVzdChjaGlsZC50ZXh0Q29udGVudCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnRleHRDb250ZW50ID0gY2hpbGQudGV4dENvbnRlbnQucmVwbGFjZSgvXlxcc3sxLDR9LywgJycpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcnN0Q2hpbGQgPSB1dGlsLmdldENoaWxkRWxlbWVudChsaW5lc1swXSwgJ3RleHQnLCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmRDaGlsZCA9IHV0aWwuZ2V0Q2hpbGRFbGVtZW50KGxpbmVzW2xlbl0sICd0ZXh0JywgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZjICYmIGZpcnN0Q2hpbGQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByLnNjID0gZmlyc3RDaGlsZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByLnNvID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbGMgJiYgZW5kQ2hpbGQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByLmVjID0gZW5kQ2hpbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgci5lbyA9IGVuZENoaWxkLnRleHRDb250ZW50Lmxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29yZS5zZXRSYW5nZShyLnNjLCByLnNvLCByLmVjLCByLmVvKTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBoaXN0b3J5IHN0YWNrXHJcbiAgICAgICAgICAgICAgICAgICAgY29yZS5oaXN0b3J5LnB1c2goZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAxMzogLyoqIGVudGVyIGtleSAqL1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZyZWVGb3JtYXRFbCA9IHV0aWwuZ2V0RnJlZUZvcm1hdEVsZW1lbnQoc2VsZWN0aW9uTm9kZSwgbnVsbCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb3JlLl9jaGFyVHlwZUhUTUwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGVudGVySFRNTCA9ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKCFzaGlmdCAmJiBmcmVlRm9ybWF0RWwpIHx8IHNoaWZ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRlckhUTUwgPSAnPGJyPic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRlckhUTUwgPSAnPCcgKyBmb3JtYXRFbC5ub2RlTmFtZSArICc+PGJyPjwvJyArIGZvcm1hdEVsLm5vZGVOYW1lICsgJz4nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNvcmUuY2hlY2tDaGFyQ291bnQoZW50ZXJIVE1MLCAnYnl0ZS1odG1sJykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzaGlmdCAmJiBmcmVlRm9ybWF0RWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzZWxlY3Rpb25Gb3JtYXQgPSBzZWxlY3Rpb25Ob2RlID09PSBmcmVlRm9ybWF0RWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHdTZWxlY3Rpb24gPSBjb3JlLmdldFNlbGVjdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IHNlbGVjdGlvbk5vZGUuY2hpbGROb2Rlcywgb2Zmc2V0ID0gd1NlbGVjdGlvbi5mb2N1c09mZnNldCwgcHJldiA9IHNlbGVjdGlvbk5vZGUucHJldmlvdXNFbGVtZW50U2libGluZywgbmV4dCA9IHNlbGVjdGlvbk5vZGUubmV4dFNpYmxpbmc7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXV0aWwuaXNDbG9zdXJlRnJlZUZvcm1hdEVsZW1lbnQoZnJlZUZvcm1hdEVsKSAmJiAhIWNoaWxkcmVuICYmICgoc2VsZWN0aW9uRm9ybWF0ICYmIHJhbmdlLmNvbGxhcHNlZCAmJiBjaGlsZHJlbi5sZW5ndGggLSAxIDw9IG9mZnNldCArIDEgJiYgdXRpbC5pc0JyZWFrKGNoaWxkcmVuW29mZnNldF0pICYmICghY2hpbGRyZW5bb2Zmc2V0ICsgMV0gfHwgKCghY2hpbGRyZW5bb2Zmc2V0ICsgMl0gfHwgdXRpbC5vbmx5WmVyb1dpZHRoU3BhY2UoY2hpbGRyZW5bb2Zmc2V0ICsgMl0udGV4dENvbnRlbnQpKSAmJiBjaGlsZHJlbltvZmZzZXQgKyAxXS5ub2RlVHlwZSA9PT0gMyAmJiB1dGlsLm9ubHlaZXJvV2lkdGhTcGFjZShjaGlsZHJlbltvZmZzZXQgKyAxXS50ZXh0Q29udGVudCkpKSAmJiAgb2Zmc2V0ID4gMCAmJiB1dGlsLmlzQnJlYWsoY2hpbGRyZW5bb2Zmc2V0IC0gMV0pKSB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICghc2VsZWN0aW9uRm9ybWF0ICYmIHV0aWwub25seVplcm9XaWR0aFNwYWNlKHNlbGVjdGlvbk5vZGUudGV4dENvbnRlbnQpICYmIHV0aWwuaXNCcmVhayhwcmV2KSAmJiAodXRpbC5pc0JyZWFrKHByZXYucHJldmlvdXNTaWJsaW5nKSB8fCAhdXRpbC5vbmx5WmVyb1dpZHRoU3BhY2UocHJldi5wcmV2aW91c1NpYmxpbmcudGV4dENvbnRlbnQpKSAmJiAoIW5leHQgfHwgKCF1dGlsLmlzQnJlYWsobmV4dCkgJiYgdXRpbC5vbmx5WmVyb1dpZHRoU3BhY2UobmV4dC50ZXh0Q29udGVudCkpKSkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0aW9uRm9ybWF0KSB1dGlsLnJlbW92ZUl0ZW0oY2hpbGRyZW5bb2Zmc2V0IC0gMV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB1dGlsLnJlbW92ZUl0ZW0oc2VsZWN0aW9uTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdFbCA9IGNvcmUuYXBwZW5kRm9ybWF0VGFnKGZyZWVGb3JtYXRFbCwgdXRpbC5pc0Zvcm1hdEVsZW1lbnQoZnJlZUZvcm1hdEVsLm5leHRFbGVtZW50U2libGluZykgPyBmcmVlRm9ybWF0RWwubmV4dEVsZW1lbnRTaWJsaW5nIDogbnVsbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1dGlsLmNvcHlGb3JtYXRBdHRyaWJ1dGVzKG5ld0VsLCBmcmVlRm9ybWF0RWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZS5zZXRSYW5nZShuZXdFbCwgMSwgbmV3RWwsIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3Rpb25Gb3JtYXQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9ucy5pbnNlcnRIVE1MKCgocmFuZ2UuY29sbGFwc2VkICYmIHV0aWwuaXNCcmVhayhyYW5nZS5zdGFydENvbnRhaW5lci5jaGlsZE5vZGVzW3JhbmdlLnN0YXJ0T2Zmc2V0IC0gMV0pKSA/ICc8YnI+JyA6ICc8YnI+PGJyPicpLCB0cnVlLCBmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZvY3VzTm9kZSA9IHdTZWxlY3Rpb24uZm9jdXNOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgd09mZnNldCA9IHdTZWxlY3Rpb24uZm9jdXNPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZnJlZUZvcm1hdEVsID09PSBmb2N1c05vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb2N1c05vZGUgPSBmb2N1c05vZGUuY2hpbGROb2Rlc1t3T2Zmc2V0IC0gb2Zmc2V0ID4gMSA/IHdPZmZzZXQgLSAxIDogd09mZnNldF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZS5zZXRSYW5nZShmb2N1c05vZGUsIDEsIGZvY3VzTm9kZSwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmb2N1c05leHQgPSB3U2VsZWN0aW9uLmZvY3VzTm9kZS5uZXh0U2libGluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJyID0gdXRpbC5jcmVhdGVFbGVtZW50KCdCUicpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZS5pbnNlcnROb2RlKGJyLCBudWxsLCBmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYnJQcmV2ID0gYnIucHJldmlvdXNTaWJsaW5nLCBick5leHQgPSBici5uZXh0U2libGluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdXRpbC5pc0JyZWFrKGZvY3VzTmV4dCkgJiYgIXV0aWwuaXNCcmVhayhiclByZXYpICYmICghYnJOZXh0IHx8IHV0aWwub25seVplcm9XaWR0aFNwYWNlKGJyTmV4dCkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnIucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoYnIuY2xvbmVOb2RlKGZhbHNlKSwgYnIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuc2V0UmFuZ2UoYnIsIDEsIGJyLCAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZS5zZXRSYW5nZShick5leHQsIDAsIGJyTmV4dCwgMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50Ll9vblNob3J0Y3V0S2V5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0UmFuZ2UpIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyYW5nZUVsICYmIGZvcm1hdEVsICYmICF1dGlsLmlzQ2VsbChyYW5nZUVsKSAmJiAhL15GSUdDQVBUSU9OJC9pLnRlc3QocmFuZ2VFbC5ub2RlTmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSBjb3JlLmdldFJhbmdlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNvcmUuaXNFZGdlUG9pbnQocmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpICYmIHV0aWwuaXNMaXN0KHNlbGVjdGlvbk5vZGUubmV4dFNpYmxpbmcpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdFbCA9IHV0aWwuY3JlYXRlRWxlbWVudCgnTEknKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJyID0gdXRpbC5jcmVhdGVFbGVtZW50KCdCUicpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3RWwuYXBwZW5kQ2hpbGQoYnIpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdEVsLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5ld0VsLCBmb3JtYXRFbC5uZXh0RWxlbWVudFNpYmxpbmcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3RWwuYXBwZW5kQ2hpbGQoc2VsZWN0aW9uTm9kZS5uZXh0U2libGluZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuc2V0UmFuZ2UoYnIsIDEsIGJyLCAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyLm5vZGVUeXBlID09PSAzID8gIXJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyLm5leHRFbGVtZW50U2libGluZyA6IHRydWUpICYmIHV0aWwub25seVplcm9XaWR0aFNwYWNlKGZvcm1hdEVsLmlubmVyVGV4dC50cmltKCkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgbmV3RWwgPSBudWxsO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1dGlsLmlzTGlzdENlbGwocmFuZ2VFbC5wYXJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlRWwgPSBmb3JtYXRFbC5wYXJlbnROb2RlLnBhcmVudE5vZGUucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdFbCA9IHV0aWwuc3BsaXRFbGVtZW50KGZvcm1hdEVsLCBudWxsLCB1dGlsLmdldEVsZW1lbnREZXB0aChmb3JtYXRFbCkgLSAyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW5ld0VsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0xpc3RDZWxsID0gdXRpbC5jcmVhdGVFbGVtZW50KCdMSScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdMaXN0Q2VsbC5pbm5lckhUTUwgPSAnPGJyPic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlRWwuaW5zZXJ0QmVmb3JlKG5ld0xpc3RDZWxsLCBuZXdFbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0VsID0gbmV3TGlzdENlbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdGb3JtYXQgPSB1dGlsLmlzQ2VsbChyYW5nZUVsLnBhcmVudE5vZGUpID8gJ0RJVicgOiB1dGlsLmlzTGlzdChyYW5nZUVsLnBhcmVudE5vZGUpID8gJ0xJJyA6IHV0aWwuaXNGb3JtYXRFbGVtZW50KHJhbmdlRWwubmV4dEVsZW1lbnRTaWJsaW5nKSA/IHJhbmdlRWwubmV4dEVsZW1lbnRTaWJsaW5nLm5vZGVOYW1lIDogdXRpbC5pc0Zvcm1hdEVsZW1lbnQocmFuZ2VFbC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nKSA/IHJhbmdlRWwucHJldmlvdXNFbGVtZW50U2libGluZy5ub2RlTmFtZSA6IG9wdGlvbnMuZGVmYXVsdFRhZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdFbCA9IHV0aWwuY3JlYXRlRWxlbWVudChuZXdGb3JtYXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVkZ2UgPSBjb3JlLmRldGFjaFJhbmdlRm9ybWF0RWxlbWVudChyYW5nZUVsLCBbZm9ybWF0RWxdLCBudWxsLCB0cnVlLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlZGdlLmNjLmluc2VydEJlZm9yZShuZXdFbCwgZWRnZS5lYyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0VsLmlubmVySFRNTCA9ICc8YnI+JztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwuY29weUZvcm1hdEF0dHJpYnV0ZXMobmV3RWwsIGZvcm1hdEVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlSXRlbUFsbFBhcmVudHMoZm9ybWF0RWwsIG51bGwsIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZS5zZXRSYW5nZShuZXdFbCwgMSwgbmV3RWwsIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyYW5nZUVsICYmIHV0aWwuZ2V0UGFyZW50RWxlbWVudChyYW5nZUVsLCAnRklHQ0FQVElPTicpICYmIHV0aWwuZ2V0UGFyZW50RWxlbWVudChyYW5nZUVsLCB1dGlsLmlzTGlzdCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXRFbCA9IGNvcmUuYXBwZW5kRm9ybWF0VGFnKGZvcm1hdEVsLCBudWxsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29yZS5zZXRSYW5nZShmb3JtYXRFbCwgMCwgZm9ybWF0RWwsIDApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVDb21wb25lbnROYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29tcENvbnRleHQgPSBjb250ZXh0W2ZpbGVDb21wb25lbnROYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29udGFpbmVyID0gY29tcENvbnRleHQuX2NvbnRhaW5lcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2libGluZyA9IGNvbnRhaW5lci5wcmV2aW91c0VsZW1lbnRTaWJsaW5nIHx8IGNvbnRhaW5lci5uZXh0RWxlbWVudFNpYmxpbmc7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbmV3RWwgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodXRpbC5pc0xpc3RDZWxsKGNvbnRhaW5lci5wYXJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3RWwgPSB1dGlsLmNyZWF0ZUVsZW1lbnQoJ0JSJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdFbCA9IHV0aWwuY3JlYXRlRWxlbWVudCh1dGlsLmlzRm9ybWF0RWxlbWVudChzaWJsaW5nKSA/IHNpYmxpbmcubm9kZU5hbWUgOiBvcHRpb25zLmRlZmF1bHRUYWcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3RWwuaW5uZXJIVE1MID0gJzxicj4nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXIucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobmV3RWwsIGNvbnRhaW5lcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb3JlLmNhbGxQbHVnaW4oZmlsZUNvbXBvbmVudE5hbWUsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuc2VsZWN0Q29tcG9uZW50KGNvbXBDb250ZXh0Ll9lbGVtZW50LCBmaWxlQ29tcG9uZW50TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgMjc6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVDb21wb25lbnROYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29yZS5jb250cm9sbGVyc09mZigpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoc2hpZnQgJiYga2V5Q29kZSA9PT0gMTYpIHtcclxuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB0YWJsZVBsdWdpbiA9IGNvcmUucGx1Z2lucy50YWJsZTtcclxuICAgICAgICAgICAgICAgIGlmICh0YWJsZVBsdWdpbiAmJiAhdGFibGVQbHVnaW4uX3NoaWZ0ICYmICF0YWJsZVBsdWdpbi5fcmVmKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2VsbCA9IHV0aWwuZ2V0UGFyZW50RWxlbWVudChmb3JtYXRFbCwgdXRpbC5pc0NlbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjZWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlUGx1Z2luLm9uVGFibGVDZWxsTXVsdGlTZWxlY3QuY2FsbChjb3JlLCBjZWxsLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgdGV4dEtleSA9ICFjdHJsICYmICFhbHQgJiYgIXNlbGVjdFJhbmdlICYmICFldmVudC5fbm9uVGV4dEtleUNvZGUudGVzdChrZXlDb2RlKTtcclxuICAgICAgICAgICAgaWYgKHRleHRLZXkgJiYgcmFuZ2UuY29sbGFwc2VkICYmIHJhbmdlLnN0YXJ0Q29udGFpbmVyID09PSByYW5nZS5lbmRDb250YWluZXIgJiYgdXRpbC5pc0JyZWFrKHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyKSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgemVyb1dpZHRoID0gdXRpbC5jcmVhdGVUZXh0Tm9kZSh1dGlsLnplcm9XaWR0aFNwYWNlKTtcclxuICAgICAgICAgICAgICAgIGNvcmUuaW5zZXJ0Tm9kZSh6ZXJvV2lkdGgsIG51bGwsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIGNvcmUuc2V0UmFuZ2UoemVyb1dpZHRoLCAxLCB6ZXJvV2lkdGgsIDEpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGZ1bmN0aW9ucy5vbktleURvd24gPT09ICdmdW5jdGlvbicpIGZ1bmN0aW9ucy5vbktleURvd24oZSwgY29yZSk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgb25LZXlVcF93eXNpd3lnOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBpZiAoZXZlbnQuX29uU2hvcnRjdXRLZXkpIHJldHVybjtcclxuICAgICAgICAgICAgY29yZS5fZWRpdG9yUmFuZ2UoKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHJhbmdlID0gY29yZS5nZXRSYW5nZSgpO1xyXG4gICAgICAgICAgICBjb25zdCBrZXlDb2RlID0gZS5rZXlDb2RlO1xyXG4gICAgICAgICAgICBjb25zdCBjdHJsID0gZS5jdHJsS2V5IHx8IGUubWV0YUtleSB8fCBrZXlDb2RlID09PSA5MSB8fCBrZXlDb2RlID09PSA5MiB8fCBrZXlDb2RlID09PSAyMjQ7XHJcbiAgICAgICAgICAgIGNvbnN0IGFsdCA9IGUuYWx0S2V5O1xyXG4gICAgICAgICAgICBsZXQgc2VsZWN0aW9uTm9kZSA9IGNvcmUuZ2V0U2VsZWN0aW9uTm9kZSgpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGNvcmUuX2lzQmFsbG9vbiAmJiAoKGNvcmUuX2lzQmFsbG9vbkFsd2F5cyAmJiBrZXlDb2RlICE9PSAyNykgfHwgIXJhbmdlLmNvbGxhcHNlZCkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChjb3JlLl9pc0JhbGxvb25BbHdheXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoa2V5Q29kZSAhPT0gMjcpIGV2ZW50Ll9zaG93VG9vbGJhckJhbGxvb25EZWxheSgpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBldmVudC5fc2hvd1Rvb2xiYXJCYWxsb29uKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKiogd2hlbiBmb3JtYXQgdGFnIGRlbGV0ZWQgKi9cclxuICAgICAgICAgICAgaWYgKGtleUNvZGUgPT09IDggJiYgdXRpbC5pc1d5c2l3eWdEaXYoc2VsZWN0aW9uTm9kZSkgJiYgc2VsZWN0aW9uTm9kZS50ZXh0Q29udGVudCA9PT0gJycgJiYgc2VsZWN0aW9uTm9kZS5jaGlsZHJlbi5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uTm9kZS5pbm5lckhUTUwgPSAnJztcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBvRm9ybWF0VGFnID0gdXRpbC5jcmVhdGVFbGVtZW50KHV0aWwuaXNGb3JtYXRFbGVtZW50KGNvcmUuX3ZhcmlhYmxlLmN1cnJlbnROb2Rlc1swXSkgPyBjb3JlLl92YXJpYWJsZS5jdXJyZW50Tm9kZXNbMF0gOiBvcHRpb25zLmRlZmF1bHRUYWcpO1xyXG4gICAgICAgICAgICAgICAgb0Zvcm1hdFRhZy5pbm5lckhUTUwgPSAnPGJyPic7XHJcblxyXG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uTm9kZS5hcHBlbmRDaGlsZChvRm9ybWF0VGFnKTtcclxuICAgICAgICAgICAgICAgIGNvcmUuc2V0UmFuZ2Uob0Zvcm1hdFRhZywgMCwgb0Zvcm1hdFRhZywgMCk7XHJcbiAgICAgICAgICAgICAgICBldmVudC5fYXBwbHlUYWdFZmZlY3RzKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29yZS5oaXN0b3J5LnB1c2goZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBmb3JtYXRFbCA9IHV0aWwuZ2V0Rm9ybWF0RWxlbWVudChzZWxlY3Rpb25Ob2RlLCBudWxsKTtcclxuICAgICAgICAgICAgY29uc3QgcmFuZ2VFbCA9IHV0aWwuZ2V0UmFuZ2VGb3JtYXRFbGVtZW50KHNlbGVjdGlvbk5vZGUsIG51bGwpO1xyXG4gICAgICAgICAgICBpZiAoKCghZm9ybWF0RWwgJiYgcmFuZ2UuY29sbGFwc2VkKSB8fCBmb3JtYXRFbCA9PT0gcmFuZ2VFbCkgJiYgIXV0aWwuaXNDb21wb25lbnQoc2VsZWN0aW9uTm9kZSkgJiYgIXV0aWwuaXNMaXN0KHNlbGVjdGlvbk5vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICBjb3JlLl9zZXREZWZhdWx0Rm9ybWF0KHV0aWwuaXNSYW5nZUZvcm1hdEVsZW1lbnQocmFuZ2VFbCkgPyAnRElWJyA6IG9wdGlvbnMuZGVmYXVsdFRhZyk7XHJcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb25Ob2RlID0gY29yZS5nZXRTZWxlY3Rpb25Ob2RlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChldmVudC5fZGlyZWN0aW9uS2V5Q29kZS50ZXN0KGtleUNvZGUpKSB7XHJcbiAgICAgICAgICAgICAgICBldmVudC5fYXBwbHlUYWdFZmZlY3RzKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHRleHRLZXkgPSAhY3RybCAmJiAhYWx0ICYmICFldmVudC5fbm9uVGV4dEtleUNvZGUudGVzdChrZXlDb2RlKTtcclxuICAgICAgICAgICAgaWYgKHRleHRLZXkgJiYgc2VsZWN0aW9uTm9kZS5ub2RlVHlwZSA9PT0gMyAmJiB1dGlsLnplcm9XaWR0aFJlZ0V4cC50ZXN0KHNlbGVjdGlvbk5vZGUudGV4dENvbnRlbnQpICYmICEoZS5pc0NvbXBvc2luZyAhPT0gdW5kZWZpbmVkID8gZS5pc0NvbXBvc2luZyA6IGV2ZW50Ll9JRWlzQ29tcG9zaW5nKSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IHNvID0gcmFuZ2Uuc3RhcnRPZmZzZXQsIGVvID0gcmFuZ2UuZW5kT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZnJvbnRaZXJvV2lkdGhDbnQgPSAoc2VsZWN0aW9uTm9kZS50ZXh0Q29udGVudC5zdWJzdHJpbmcoMCwgZW8pLm1hdGNoKGV2ZW50Ll9mcm9udFplcm9XaWR0aFJlZykgfHwgJycpLmxlbmd0aDtcclxuICAgICAgICAgICAgICAgIHNvID0gcmFuZ2Uuc3RhcnRPZmZzZXQgLSBmcm9udFplcm9XaWR0aENudDtcclxuICAgICAgICAgICAgICAgIGVvID0gcmFuZ2UuZW5kT2Zmc2V0IC0gZnJvbnRaZXJvV2lkdGhDbnQ7XHJcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb25Ob2RlLnRleHRDb250ZW50ID0gc2VsZWN0aW9uTm9kZS50ZXh0Q29udGVudC5yZXBsYWNlKHV0aWwuemVyb1dpZHRoUmVnRXhwLCAnJyk7XHJcbiAgICAgICAgICAgICAgICBjb3JlLnNldFJhbmdlKHNlbGVjdGlvbk5vZGUsIHNvIDwgMCA/IDAgOiBzbywgc2VsZWN0aW9uTm9kZSwgZW8gPCAwID8gMCA6IGVvKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29yZS5fY2hhckNvdW50KCcnKTtcclxuXHJcbiAgICAgICAgICAgIC8vIGhpc3Rvcnkgc3RhY2tcclxuICAgICAgICAgICAgY29yZS5oaXN0b3J5LnB1c2godHJ1ZSk7XHJcblxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGZ1bmN0aW9ucy5vbktleVVwID09PSAnZnVuY3Rpb24nKSBmdW5jdGlvbnMub25LZXlVcChlLCBjb3JlKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBvblNjcm9sbF93eXNpd3lnOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBjb3JlLmNvbnRyb2xsZXJzT2ZmKCk7XHJcbiAgICAgICAgICAgIGNvcmUuX2xpbmVCcmVha2VyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgIGlmIChjb3JlLl9pc0JhbGxvb24pIGV2ZW50Ll9oaWRlVG9vbGJhcigpO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGZ1bmN0aW9ucy5vblNjcm9sbCA9PT0gJ2Z1bmN0aW9uJykgZnVuY3Rpb25zLm9uU2Nyb2xsKGUsIGNvcmUpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIG9uRm9jdXNfd3lzaXd5ZzogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgaWYgKGNvcmUuX2FudGlCbHVyKSByZXR1cm47XHJcbiAgICAgICAgICAgIGNvcmUuaGFzRm9jdXMgPSB0cnVlO1xyXG4gICAgICAgICAgICBpZiAoY29yZS5faXNJbmxpbmUpIGV2ZW50Ll9zaG93VG9vbGJhcklubGluZSgpO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGZ1bmN0aW9ucy5vbkZvY3VzID09PSAnZnVuY3Rpb24nKSBmdW5jdGlvbnMub25Gb2N1cyhlLCBjb3JlKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBvbkJsdXJfd3lzaXd5ZzogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgaWYgKGNvcmUuX2FudGlCbHVyIHx8IGNvcmUuX3ZhcmlhYmxlLmlzQ29kZVZpZXcpIHJldHVybjtcclxuICAgICAgICAgICAgY29yZS5oYXNGb2N1cyA9IGZhbHNlO1xyXG4gICAgICAgICAgICBjb3JlLmNvbnRyb2xsZXJzT2ZmKCk7XHJcbiAgICAgICAgICAgIGlmIChjb3JlLl9pc0lubGluZSB8fCBjb3JlLl9pc0JhbGxvb24pIGV2ZW50Ll9oaWRlVG9vbGJhcigpO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGZ1bmN0aW9ucy5vbkJsdXIgPT09ICdmdW5jdGlvbicpIGZ1bmN0aW9ucy5vbkJsdXIoZSwgY29yZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBhY3RpdmUgY2xhc3MgcmVzZXQgb2YgYnV0dG9uc1xyXG4gICAgICAgICAgICBjb25zdCBjb21tYW5kTWFwID0gY29yZS5jb21tYW5kTWFwO1xyXG4gICAgICAgICAgICBjb25zdCBhY3RpdmVQbHVnaW5zID0gY29yZS5hY3RpdmVQbHVnaW5zO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBrZXkgaW4gY29tbWFuZE1hcCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF1dGlsLmhhc093bihjb21tYW5kTWFwLCBrZXkpKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGlmIChhY3RpdmVQbHVnaW5zLmluZGV4T2Yoa2V5KSA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGx1Z2luc1trZXldLmFjdGl2ZS5jYWxsKGNvcmUsIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTWFwLk9VVERFTlQgJiYgL15PVVRERU5UJC9pLnRlc3Qoa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbW1hbmRNYXAuT1VUREVOVC5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmRNYXAuSU5ERU5UICYmIC9eSU5ERU5UJC9pLnRlc3Qoa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbW1hbmRNYXAuSU5ERU5ULnJlbW92ZUF0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVDbGFzcyhjb21tYW5kTWFwW2tleV0sICdhY3RpdmUnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29yZS5fdmFyaWFibGUuY3VycmVudE5vZGVzID0gW107XHJcbiAgICAgICAgICAgIGNvcmUuX3ZhcmlhYmxlLmN1cnJlbnROb2Rlc01hcCA9IFtdO1xyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5zaG93UGF0aExhYmVsKSBjb250ZXh0LmVsZW1lbnQubmF2aWdhdGlvbi50ZXh0Q29udGVudCA9ICcnO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIG9uTW91c2VEb3duX3Jlc2l6aW5nQmFyOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cclxuICAgICAgICAgICAgY29yZS5fdmFyaWFibGUucmVzaXplQ2xpZW50WSA9IGUuY2xpZW50WTtcclxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LnJlc2l6ZUJhY2tncm91bmQuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBjbG9zdXJlRnVuYygpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5yZXNpemVCYWNrZ3JvdW5kLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICBfZC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBldmVudC5fcmVzaXplX2VkaXRvcik7XHJcbiAgICAgICAgICAgICAgICBfZC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgY2xvc3VyZUZ1bmMpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBfZC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBldmVudC5fcmVzaXplX2VkaXRvcik7XHJcbiAgICAgICAgICAgIF9kLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBjbG9zdXJlRnVuYyk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX3Jlc2l6ZV9lZGl0b3I6IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlc2l6ZUludGVydmFsID0gY29udGV4dC5lbGVtZW50LmVkaXRvckFyZWEub2Zmc2V0SGVpZ2h0ICsgKGUuY2xpZW50WSAtIGNvcmUuX3ZhcmlhYmxlLnJlc2l6ZUNsaWVudFkpO1xyXG4gICAgICAgICAgICBjb250ZXh0LmVsZW1lbnQud3lzaXd5Z0ZyYW1lLnN0eWxlLmhlaWdodCA9IGNvbnRleHQuZWxlbWVudC5jb2RlLnN0eWxlLmhlaWdodCA9IChyZXNpemVJbnRlcnZhbCA8IGNvcmUuX3ZhcmlhYmxlLm1pblJlc2l6aW5nU2l6ZSA/IGNvcmUuX3ZhcmlhYmxlLm1pblJlc2l6aW5nU2l6ZSA6IHJlc2l6ZUludGVydmFsKSArICdweCc7XHJcbiAgICAgICAgICAgIGNvcmUuX3ZhcmlhYmxlLnJlc2l6ZUNsaWVudFkgPSBlLmNsaWVudFk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgb25SZXNpemVfd2luZG93OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvcmUuY29udHJvbGxlcnNPZmYoKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNpdmVTaXplID0gZXZlbnQuX3Jlc3BvbnNpdmVCdXR0b25TaXplO1xyXG4gICAgICAgICAgICBpZiAocmVzcG9uc2l2ZVNpemUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHdpbmRvd1dpZHRoID0gX3cuaW5uZXJXaWR0aDtcclxuICAgICAgICAgICAgICAgIGxldCByZXNwb25zaXZlV2lkdGggPSAnZGVmYXVsdCc7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMSwgbGVuID0gcmVzcG9uc2l2ZVNpemUubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAod2luZG93V2lkdGggPCByZXNwb25zaXZlU2l6ZVtpXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zaXZlV2lkdGggPSByZXNwb25zaXZlU2l6ZVtpXSArICcnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50Ll9yZXNwb25zaXZlQ3VycmVudFNpemUgIT09IHJlc3BvbnNpdmVXaWR0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50Ll9yZXNwb25zaXZlQ3VycmVudFNpemUgPSByZXNwb25zaXZlV2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb25zLnNldFRvb2xiYXJCdXR0b25zKGV2ZW50Ll9yZXNwb25zaXZlQnV0dG9uc1tyZXNwb25zaXZlV2lkdGhdKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGNvbnRleHQuZWxlbWVudC50b29sYmFyLm9mZnNldFdpZHRoID09PSAwKSByZXR1cm47XHJcblxyXG4gICAgICAgICAgICBpZiAoY29udGV4dC5maWxlQnJvd3NlciAmJiBjb250ZXh0LmZpbGVCcm93c2VyLmFyZWEuc3R5bGUuZGlzcGxheSA9PT0gJ2Jsb2NrJykge1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5maWxlQnJvd3Nlci5ib2R5LnN0eWxlLm1heEhlaWdodCA9IChfdy5pbm5lckhlaWdodCAtIGNvbnRleHQuZmlsZUJyb3dzZXIuaGVhZGVyLm9mZnNldEhlaWdodCAtIDUwKSArICdweCc7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChjb3JlLnN1Ym1lbnVBY3RpdmVCdXR0b24gJiYgY29yZS5zdWJtZW51KSB7XHJcbiAgICAgICAgICAgICAgICBjb3JlLl9zZXRNZW51UG9zaXRpb24oY29yZS5zdWJtZW51QWN0aXZlQnV0dG9uLCBjb3JlLnN1Ym1lbnUpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoY29yZS5fdmFyaWFibGUuaXNGdWxsU2NyZWVuKSB7XHJcbiAgICAgICAgICAgICAgICBjb3JlLl92YXJpYWJsZS5pbm5lckhlaWdodF9mdWxsU2NyZWVuICs9IChfdy5pbm5lckhlaWdodCAtIGNvbnRleHQuZWxlbWVudC50b29sYmFyLm9mZnNldEhlaWdodCkgLSBjb3JlLl92YXJpYWJsZS5pbm5lckhlaWdodF9mdWxsU2NyZWVuO1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LmVkaXRvckFyZWEuc3R5bGUuaGVpZ2h0ID0gY29yZS5fdmFyaWFibGUuaW5uZXJIZWlnaHRfZnVsbFNjcmVlbiArICdweCc7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChjb3JlLl92YXJpYWJsZS5pc0NvZGVWaWV3ICYmIGNvcmUuX2lzSW5saW5lKSB7XHJcbiAgICAgICAgICAgICAgICBldmVudC5fc2hvd1Rvb2xiYXJJbmxpbmUoKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgY29yZS5faWZyYW1lQXV0b0hlaWdodCgpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGNvcmUuX3N0aWNreSkge1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LnRvb2xiYXIuc3R5bGUud2lkdGggPSAoY29udGV4dC5lbGVtZW50LnRvcEFyZWEub2Zmc2V0V2lkdGggLSAyKSArICdweCc7XHJcbiAgICAgICAgICAgICAgICBldmVudC5vblNjcm9sbF93aW5kb3coKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIG9uU2Nyb2xsX3dpbmRvdzogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoY29yZS5fdmFyaWFibGUuaXNGdWxsU2NyZWVuIHx8IGNvbnRleHQuZWxlbWVudC50b29sYmFyLm9mZnNldFdpZHRoID09PSAwIHx8IG9wdGlvbnMuc3RpY2t5VG9vbGJhciA8IDApIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBjb250ZXh0LmVsZW1lbnQ7XHJcbiAgICAgICAgICAgIGNvbnN0IGVkaXRvckhlaWdodCA9IGVsZW1lbnQuZWRpdG9yQXJlYS5vZmZzZXRIZWlnaHQ7XHJcbiAgICAgICAgICAgIGNvbnN0IHkgPSAodGhpcy5zY3JvbGxZIHx8IF9kLmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3ApICsgb3B0aW9ucy5zdGlja3lUb29sYmFyO1xyXG4gICAgICAgICAgICBjb25zdCBlZGl0b3JUb3AgPSBldmVudC5fZ2V0RWRpdG9yT2Zmc2V0cyhvcHRpb25zLnRvb2xiYXJDb250YWluZXIpLnRvcCAtIChjb3JlLl9pc0lubGluZSA/IGVsZW1lbnQudG9vbGJhci5vZmZzZXRIZWlnaHQgOiAwKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGlmICh5IDwgZWRpdG9yVG9wKSB7XHJcbiAgICAgICAgICAgICAgICBldmVudC5fb2ZmU3RpY2t5VG9vbGJhcigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHkgKyBjb3JlLl92YXJpYWJsZS5taW5SZXNpemluZ1NpemUgPj0gZWRpdG9ySGVpZ2h0ICsgZWRpdG9yVG9wKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWNvcmUuX3N0aWNreSkgZXZlbnQuX29uU3RpY2t5VG9vbGJhcigpO1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudC50b29sYmFyLnN0eWxlLnRvcCA9IChlZGl0b3JIZWlnaHQgKyBlZGl0b3JUb3AgKyBvcHRpb25zLnN0aWNreVRvb2xiYXIgLXkgLSBjb3JlLl92YXJpYWJsZS5taW5SZXNpemluZ1NpemUpICsgJ3B4JztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICh5ID49IGVkaXRvclRvcCkge1xyXG4gICAgICAgICAgICAgICAgZXZlbnQuX29uU3RpY2t5VG9vbGJhcigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX2dldEVkaXRvck9mZnNldHM6IGZ1bmN0aW9uIChjb250YWluZXIpIHtcclxuICAgICAgICAgICAgbGV0IG9mZnNldEVsID0gY29udGFpbmVyIHx8IGNvbnRleHQuZWxlbWVudC50b3BBcmVhO1xyXG4gICAgICAgICAgICBsZXQgdCA9IDAsIGwgPSAwLCBzID0gMDtcclxuXHJcbiAgICAgICAgICAgIHdoaWxlIChvZmZzZXRFbCkge1xyXG4gICAgICAgICAgICAgICAgdCArPSBvZmZzZXRFbC5vZmZzZXRUb3A7XHJcbiAgICAgICAgICAgICAgICBsICs9IG9mZnNldEVsLm9mZnNldExlZnQ7XHJcbiAgICAgICAgICAgICAgICBzICs9IG9mZnNldEVsLnNjcm9sbFRvcDtcclxuICAgICAgICAgICAgICAgIG9mZnNldEVsID0gb2Zmc2V0RWwub2Zmc2V0UGFyZW50O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgdG9wOiB0LFxyXG4gICAgICAgICAgICAgICAgbGVmdDogbCxcclxuICAgICAgICAgICAgICAgIHNjcm9sbDogc1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9nZXRQYWdlQm90dG9tU3BhY2U6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIF9kLmRvY3VtZW50RWxlbWVudC5zY3JvbGxIZWlnaHQgLSAoZXZlbnQuX2dldEVkaXRvck9mZnNldHMobnVsbCkudG9wICsgY29udGV4dC5lbGVtZW50LnRvcEFyZWEub2Zmc2V0SGVpZ2h0KTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfb25TdGlja3lUb29sYmFyOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBjb250ZXh0LmVsZW1lbnQ7XHJcblxyXG4gICAgICAgICAgICBpZiAoIWNvcmUuX2lzSW5saW5lICYmICFvcHRpb25zLnRvb2xiYXJDb250YWluZXIpIHtcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQuX3N0aWNreUR1bW15LnN0eWxlLmhlaWdodCA9IGVsZW1lbnQudG9vbGJhci5vZmZzZXRIZWlnaHQgKyAncHgnO1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudC5fc3RpY2t5RHVtbXkuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGVsZW1lbnQudG9vbGJhci5zdHlsZS50b3AgPSBvcHRpb25zLnN0aWNreVRvb2xiYXIgKyAncHgnO1xyXG4gICAgICAgICAgICBlbGVtZW50LnRvb2xiYXIuc3R5bGUud2lkdGggPSBjb3JlLl9pc0lubGluZSA/IGNvcmUuX2lubGluZVRvb2xiYXJBdHRyLndpZHRoIDogZWxlbWVudC50b29sYmFyLm9mZnNldFdpZHRoICsgJ3B4JztcclxuICAgICAgICAgICAgdXRpbC5hZGRDbGFzcyhlbGVtZW50LnRvb2xiYXIsICdzZS10b29sYmFyLXN0aWNreScpO1xyXG4gICAgICAgICAgICBjb3JlLl9zdGlja3kgPSB0cnVlO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9vZmZTdGlja3lUb29sYmFyOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBjb250ZXh0LmVsZW1lbnQ7XHJcblxyXG4gICAgICAgICAgICBlbGVtZW50Ll9zdGlja3lEdW1teS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgICAgICBlbGVtZW50LnRvb2xiYXIuc3R5bGUudG9wID0gY29yZS5faXNJbmxpbmUgPyBjb3JlLl9pbmxpbmVUb29sYmFyQXR0ci50b3AgOiAnJztcclxuICAgICAgICAgICAgZWxlbWVudC50b29sYmFyLnN0eWxlLndpZHRoID0gY29yZS5faXNJbmxpbmUgPyBjb3JlLl9pbmxpbmVUb29sYmFyQXR0ci53aWR0aCA6ICcnO1xyXG4gICAgICAgICAgICBlbGVtZW50LmVkaXRvckFyZWEuc3R5bGUubWFyZ2luVG9wID0gJyc7XHJcblxyXG4gICAgICAgICAgICB1dGlsLnJlbW92ZUNsYXNzKGVsZW1lbnQudG9vbGJhciwgJ3NlLXRvb2xiYXItc3RpY2t5Jyk7XHJcbiAgICAgICAgICAgIGNvcmUuX3N0aWNreSA9IGZhbHNlO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9jb2RlVmlld0F1dG9IZWlnaHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LmNvZGUuc3R5bGUuaGVpZ2h0ID0gY29udGV4dC5lbGVtZW50LmNvZGUuc2Nyb2xsSGVpZ2h0ICsgJ3B4JztcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvLyBGaXJlRm94IC0gdGFibGUgZGVsZXRlLCBDaHJvbWUgLSBpbWFnZSwgdmlkZW8sIGF1ZGlvXHJcbiAgICAgICAgX2hhcmREZWxldGU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSBjb3JlLmdldFJhbmdlKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IHNjID0gcmFuZ2Uuc3RhcnRDb250YWluZXI7XHJcbiAgICAgICAgICAgIGNvbnN0IGVjID0gcmFuZ2UuZW5kQ29udGFpbmVyO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8gdGFibGVcclxuICAgICAgICAgICAgY29uc3Qgc0NlbGwgPSB1dGlsLmdldFJhbmdlRm9ybWF0RWxlbWVudChzYyk7XHJcbiAgICAgICAgICAgIGNvbnN0IGVDZWxsID0gdXRpbC5nZXRSYW5nZUZvcm1hdEVsZW1lbnQoZWMpO1xyXG4gICAgICAgICAgICBjb25zdCBzSXNDZWxsID0gdXRpbC5pc0NlbGwoc0NlbGwpO1xyXG4gICAgICAgICAgICBjb25zdCBlSXNDZWxsID0gdXRpbC5pc0NlbGwoZUNlbGwpO1xyXG4gICAgICAgICAgICBpZiAoKChzSXNDZWxsICYmICFzQ2VsbC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nICYmICFzQ2VsbC5wYXJlbnRFbGVtZW50LnByZXZpb3VzRWxlbWVudFNpYmxpbmcpIHx8IChlSXNDZWxsICYmICFlQ2VsbC5uZXh0RWxlbWVudFNpYmxpbmcgJiYgIWVDZWxsLnBhcmVudEVsZW1lbnQubmV4dEVsZW1lbnRTaWJsaW5nKSkgJiYgc0NlbGwgIT09IGVDZWxsKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXNJc0NlbGwpIHtcclxuICAgICAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW0odXRpbC5nZXRQYXJlbnRFbGVtZW50KGVDZWxsLCB1dGlsLmlzQ29tcG9uZW50KSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFlSXNDZWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVJdGVtKHV0aWwuZ2V0UGFyZW50RWxlbWVudChzQ2VsbCwgdXRpbC5pc0NvbXBvbmVudCkpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW0odXRpbC5nZXRQYXJlbnRFbGVtZW50KHNDZWxsLCB1dGlsLmlzQ29tcG9uZW50KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29yZS5uYXRpdmVGb2N1cygpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBjb21wb25lbnRcclxuICAgICAgICAgICAgY29uc3Qgc0NvbXAgPSBzYy5ub2RlVHlwZSA9PT0gMSA/IHV0aWwuZ2V0UGFyZW50RWxlbWVudChzYywgJy5zZS1jb21wb25lbnQnKSA6IG51bGw7XHJcbiAgICAgICAgICAgIGNvbnN0IGVDb21wID0gZWMubm9kZVR5cGUgPT09IDEgPyB1dGlsLmdldFBhcmVudEVsZW1lbnQoZWMsICcuc2UtY29tcG9uZW50JykgOiBudWxsO1xyXG4gICAgICAgICAgICBpZiAoc0NvbXApIHV0aWwucmVtb3ZlSXRlbShzQ29tcCk7XHJcbiAgICAgICAgICAgIGlmIChlQ29tcCkgdXRpbC5yZW1vdmVJdGVtKGVDb21wKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBvblBhc3RlX3d5c2l3eWc6IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNsaXBib2FyZERhdGEgPSB1dGlsLmlzSUUgPyBfdy5jbGlwYm9hcmREYXRhIDogZS5jbGlwYm9hcmREYXRhO1xyXG4gICAgICAgICAgICBpZiAoIWNsaXBib2FyZERhdGEpIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICByZXR1cm4gZXZlbnQuX2RhdGFUcmFuc2ZlckFjdGlvbigncGFzdGUnLCBlLCBjbGlwYm9hcmREYXRhKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfc2V0Q2xpcGJvYXJkQ29tcG9uZW50OiBmdW5jdGlvbiAoZSwgaW5mbywgY2xpcGJvYXJkRGF0YSkge1xyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgIGNsaXBib2FyZERhdGEuc2V0RGF0YSgndGV4dC9odG1sJywgaW5mby5jb21wb25lbnQub3V0ZXJIVE1MKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBvbkNvcHlfd3lzaXd5ZzogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgY29uc3QgY2xpcGJvYXJkRGF0YSA9IHV0aWwuaXNJRSA/IF93LmNsaXBib2FyZERhdGEgOiBlLmNsaXBib2FyZERhdGE7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZnVuY3Rpb25zLm9uQ29weSA9PT0gJ2Z1bmN0aW9uJyAmJiAhZnVuY3Rpb25zLm9uQ29weShlLCBjbGlwYm9hcmREYXRhLCBjb3JlKSkge1xyXG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgaW5mbyA9IGNvcmUuY3VycmVudEZpbGVDb21wb25lbnRJbmZvO1xyXG4gICAgICAgICAgICBpZiAoaW5mbyAmJiAhdXRpbC5pc0lFKSB7XHJcbiAgICAgICAgICAgICAgICBldmVudC5fc2V0Q2xpcGJvYXJkQ29tcG9uZW50KGUsIGluZm8sIGNsaXBib2FyZERhdGEpO1xyXG4gICAgICAgICAgICAgICAgdXRpbC5hZGRDbGFzcyhpbmZvLmNvbXBvbmVudCwgJ3NlLWNvbXBvbmVudC1jb3B5Jyk7XHJcbiAgICAgICAgICAgICAgICAvLyBjb3B5IGVmZmVjdFxyXG4gICAgICAgICAgICAgICAgX3cuc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5yZW1vdmVDbGFzcyhpbmZvLmNvbXBvbmVudCwgJ3NlLWNvbXBvbmVudC1jb3B5Jyk7XHJcbiAgICAgICAgICAgICAgICB9LCAxNTApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgb25DdXRfd3lzaXd5ZzogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgY29uc3QgY2xpcGJvYXJkRGF0YSA9IHV0aWwuaXNJRSA/IF93LmNsaXBib2FyZERhdGEgOiBlLmNsaXBib2FyZERhdGE7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZnVuY3Rpb25zLm9uQ3V0ID09PSAnZnVuY3Rpb24nICYmICFmdW5jdGlvbnMub25DdXQoZSwgY2xpcGJvYXJkRGF0YSwgY29yZSkpIHtcclxuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGluZm8gPSBjb3JlLmN1cnJlbnRGaWxlQ29tcG9uZW50SW5mbztcclxuICAgICAgICAgICAgaWYgKGluZm8gJiYgIXV0aWwuaXNJRSkge1xyXG4gICAgICAgICAgICAgICAgZXZlbnQuX3NldENsaXBib2FyZENvbXBvbmVudChlLCBpbmZvLCBjbGlwYm9hcmREYXRhKTtcclxuICAgICAgICAgICAgICAgIHV0aWwucmVtb3ZlSXRlbShpbmZvLmNvbXBvbmVudCk7XHJcbiAgICAgICAgICAgICAgICBjb3JlLmNvbnRyb2xsZXJzT2ZmKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIF93LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgLy8gaGlzdG9yeSBzdGFja1xyXG4gICAgICAgICAgICAgICAgY29yZS5oaXN0b3J5LnB1c2goZmFsc2UpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBvbkRyb3Bfd3lzaXd5ZzogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgY29uc3QgZGF0YVRyYW5zZmVyID0gZS5kYXRhVHJhbnNmZXI7XHJcbiAgICAgICAgICAgIGlmICghZGF0YVRyYW5zZmVyKSByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKHV0aWwuaXNJRSkge1xyXG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29yZS5yZW1vdmVOb2RlKCk7XHJcbiAgICAgICAgICAgIGV2ZW50Ll9zZXREcm9wTG9jYXRpb25TZWxlY3Rpb24oZSk7XHJcbiAgICAgICAgICAgIHJldHVybiBldmVudC5fZGF0YVRyYW5zZmVyQWN0aW9uKCdkcm9wJywgZSwgZGF0YVRyYW5zZmVyKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfc2V0RHJvcExvY2F0aW9uU2VsZWN0aW9uOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBpZiAoZS5yYW5nZVBhcmVudCkge1xyXG4gICAgICAgICAgICAgICAgY29yZS5zZXRSYW5nZShlLnJhbmdlUGFyZW50LCBlLnJhbmdlT2Zmc2V0LCBlLnJhbmdlUGFyZW50LCBlLnJhbmdlT2Zmc2V0KTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChjb3JlLl93ZC5jYXJldFJhbmdlRnJvbVBvaW50KSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByID0gY29yZS5fd2QuY2FyZXRSYW5nZUZyb21Qb2ludChlLmNsaWVudFgsIGUuY2xpZW50WSk7XHJcbiAgICAgICAgICAgICAgICBjb3JlLnNldFJhbmdlKHIuc3RhcnRDb250YWluZXIsIHIuc3RhcnRPZmZzZXQsIHIuZW5kQ29udGFpbmVyLCByLmVuZE9mZnNldCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByID0gY29yZS5nZXRSYW5nZSgpO1xyXG4gICAgICAgICAgICAgICAgY29yZS5zZXRSYW5nZShyLnN0YXJ0Q29udGFpbmVyLCByLnN0YXJ0T2Zmc2V0LCByLmVuZENvbnRhaW5lciwgci5lbmRPZmZzZXQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX2RhdGFUcmFuc2ZlckFjdGlvbjogZnVuY3Rpb24gKHR5cGUsIGUsIGRhdGEpIHtcclxuICAgICAgICAgICAgbGV0IHBsYWluVGV4dCwgY2xlYW5EYXRhO1xyXG4gICAgICAgICAgICBpZiAodXRpbC5pc0lFKSB7XHJcbiAgICAgICAgICAgICAgICBwbGFpblRleHQgPSBkYXRhLmdldERhdGEoJ1RleHQnKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSBjb3JlLmdldFJhbmdlKCk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB0ZW1wRGl2ID0gdXRpbC5jcmVhdGVFbGVtZW50KCdESVYnKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHRlbXBSYW5nZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICBzYzogcmFuZ2Uuc3RhcnRDb250YWluZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgc286IHJhbmdlLnN0YXJ0T2Zmc2V0LFxyXG4gICAgICAgICAgICAgICAgICAgIGVjOiByYW5nZS5lbmRDb250YWluZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgZW86IHJhbmdlLmVuZE9mZnNldFxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICB0ZW1wRGl2LnNldEF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJywgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB0ZW1wRGl2LnN0eWxlLmNzc1RleHQgPSAncG9zaXRpb246YWJzb2x1dGU7IHRvcDowOyBsZWZ0OjA7IHdpZHRoOjFweDsgaGVpZ2h0OjFweDsgb3ZlcmZsb3c6aGlkZGVuOyc7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5yZWxhdGl2ZS5hcHBlbmRDaGlsZCh0ZW1wRGl2KTtcclxuICAgICAgICAgICAgICAgIHRlbXBEaXYuZm9jdXMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBfdy5zZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBjbGVhbkRhdGEgPSB0ZW1wRGl2LmlubmVySFRNTDtcclxuICAgICAgICAgICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW0odGVtcERpdik7XHJcbiAgICAgICAgICAgICAgICAgICAgY29yZS5zZXRSYW5nZSh0ZW1wUmFuZ2Uuc2MsIHRlbXBSYW5nZS5zbywgdGVtcFJhbmdlLmVjLCB0ZW1wUmFuZ2UuZW8pO1xyXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50Ll9zZXRDbGlwYm9hcmREYXRhKHR5cGUsIGUsIHBsYWluVGV4dCwgY2xlYW5EYXRhLCBkYXRhKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcGxhaW5UZXh0ID0gZGF0YS5nZXREYXRhKCd0ZXh0L3BsYWluJyk7XHJcbiAgICAgICAgICAgICAgICBjbGVhbkRhdGEgPSBkYXRhLmdldERhdGEoJ3RleHQvaHRtbCcpIHx8IHBsYWluVGV4dDtcclxuICAgICAgICAgICAgICAgIGlmIChldmVudC5fc2V0Q2xpcGJvYXJkRGF0YSh0eXBlLCBlLCBwbGFpblRleHQsIGNsZWFuRGF0YSwgZGF0YSkgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX3NldENsaXBib2FyZERhdGE6IGZ1bmN0aW9uICh0eXBlLCBlLCBwbGFpblRleHQsIGNsZWFuRGF0YSwgZGF0YSkge1xyXG4gICAgICAgICAgICAvLyBNUyB3b3JkXHJcbiAgICAgICAgICAgIGlmICgvY2xhc3M9W1wiJ10qTXNvKE5vcm1hbHxMaXN0KS9pLnRlc3QoY2xlYW5EYXRhKSB8fCAvY29udGVudD1bXCInXSpXb3JkLkRvY3VtZW50L2kudGVzdChjbGVhbkRhdGEpIHx8IC9jb250ZW50PVtcIiddKk9uZU5vdGUuRmlsZS9pLnRlc3QoY2xlYW5EYXRhKSkge1xyXG4gICAgICAgICAgICAgICAgY2xlYW5EYXRhID0gY2xlYW5EYXRhLnJlcGxhY2UoL1xcbi9nLCAnICcpO1xyXG4gICAgICAgICAgICAgICAgcGxhaW5UZXh0ID0gcGxhaW5UZXh0LnJlcGxhY2UoL1xcbi9nLCAnICcpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcGxhaW5UZXh0ID0gcGxhaW5UZXh0LnJlcGxhY2UoL1xcbi9nLCAnJyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNsZWFuRGF0YSA9IGNvcmUuY2xlYW5IVE1MKGNsZWFuRGF0YSwgY29yZS5wYXN0ZVRhZ3NXaGl0ZWxpc3RSZWdFeHApO1xyXG4gICAgICAgICAgICBjb25zdCBtYXhDaGFyQ291bnQgPSBjb3JlLl9jaGFyQ291bnQoY29yZS5fY2hhclR5cGVIVE1MID8gY2xlYW5EYXRhIDogcGxhaW5UZXh0KTtcclxuXHJcbiAgICAgICAgICAgIC8vIHBhc3RlIGV2ZW50XHJcbiAgICAgICAgICAgIGlmICh0eXBlID09PSAncGFzdGUnICYmIHR5cGVvZiBmdW5jdGlvbnMub25QYXN0ZSA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBmdW5jdGlvbnMub25QYXN0ZShlLCBjbGVhbkRhdGEsIG1heENoYXJDb3VudCwgY29yZSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXZhbHVlKSByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgY2xlYW5EYXRhID0gdmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gZHJvcCBldmVudFxyXG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ2Ryb3AnICYmIHR5cGVvZiBmdW5jdGlvbnMub25Ecm9wID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGZ1bmN0aW9ucy5vbkRyb3AoZSwgY2xlYW5EYXRhLCBtYXhDaGFyQ291bnQsIGNvcmUpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF2YWx1ZSkgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIGNsZWFuRGF0YSA9IHZhbHVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBmaWxlc1xyXG4gICAgICAgICAgICBjb25zdCBmaWxlcyA9IGRhdGEuZmlsZXM7XHJcbiAgICAgICAgICAgIGlmIChmaWxlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoL15pbWFnZS8udGVzdChmaWxlc1swXS50eXBlKSAmJiBjb3JlLnBsdWdpbnMuaW1hZ2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbnMuaW5zZXJ0SW1hZ2UoZmlsZXMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIW1heENoYXJDb3VudCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoY2xlYW5EYXRhKSB7XHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbnMuaW5zZXJ0SFRNTChjbGVhbkRhdGEsIHRydWUsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIG9uTW91c2VNb3ZlX3d5c2l3eWc6IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGlmIChjb3JlLmlzRGlzYWJsZWQpIHJldHVybjtcclxuICAgICAgICAgICAgY29uc3QgY29tcG9uZW50ID0gdXRpbC5nZXRQYXJlbnRFbGVtZW50KGUudGFyZ2V0LCB1dGlsLmlzQ29tcG9uZW50KTtcclxuICAgICAgICAgICAgY29uc3QgbGluZUJyZWFrZXJTdHlsZSA9IGNvcmUuX2xpbmVCcmVha2VyLnN0eWxlO1xyXG5cclxuICAgICAgICAgICAgaWYgKGNvbXBvbmVudCAmJiAhY29yZS5jdXJyZW50Q29udHJvbGxlck5hbWUpIHtcclxuICAgICAgICAgICAgICAgIGxldCBzY3JvbGxUb3AgPSAwO1xyXG4gICAgICAgICAgICAgICAgbGV0IGVsID0gY29udGV4dC5lbGVtZW50Lnd5c2l3eWc7XHJcbiAgICAgICAgICAgICAgICBkbyB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsVG9wICs9IGVsLnNjcm9sbFRvcDtcclxuICAgICAgICAgICAgICAgICAgICBlbCA9IGVsLnBhcmVudEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICB9IHdoaWxlIChlbCAmJiAhL14oQk9EWXxIVE1MKSQvaS50ZXN0KGVsLm5vZGVOYW1lKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3Qgd1Njcm9sbCA9IGNvbnRleHQuZWxlbWVudC53eXNpd3lnLnNjcm9sbFRvcDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG9mZnNldHMgPSBldmVudC5fZ2V0RWRpdG9yT2Zmc2V0cyhudWxsKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbXBvbmVudFRvcCA9IHV0aWwuZ2V0T2Zmc2V0KGNvbXBvbmVudCwgY29udGV4dC5lbGVtZW50Lnd5c2l3eWdGcmFtZSkudG9wICsgd1Njcm9sbDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHkgPSBlLnBhZ2VZICsgc2Nyb2xsVG9wICsgKG9wdGlvbnMuaWZyYW1lICYmICFvcHRpb25zLnRvb2xiYXJDb250YWluZXIgPyBjb250ZXh0LmVsZW1lbnQudG9vbGJhci5vZmZzZXRIZWlnaHQgOiAwKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGMgPSBjb21wb25lbnRUb3AgKyAob3B0aW9ucy5pZnJhbWUgPyBzY3JvbGxUb3AgOiBvZmZzZXRzLnRvcCk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgaXNMaXN0ID0gdXRpbC5pc0xpc3RDZWxsKGNvbXBvbmVudC5wYXJlbnROb2RlKTtcclxuICAgICAgICAgICAgICAgIGxldCBkaXIgPSAnJywgdG9wID0gJyc7XHJcbiAgICAgICAgICAgICAgICBpZiAoKGlzTGlzdCA/ICFjb21wb25lbnQucHJldmlvdXNTaWJsaW5nIDogIXV0aWwuaXNGb3JtYXRFbGVtZW50KGNvbXBvbmVudC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nKSkgJiYgeSA8IChjICsgMjApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdG9wID0gY29tcG9uZW50VG9wO1xyXG4gICAgICAgICAgICAgICAgICAgIGRpciA9ICd0JztcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKGlzTGlzdCA/ICFjb21wb25lbnQubmV4dFNpYmxpbmcgOiAhdXRpbC5pc0Zvcm1hdEVsZW1lbnQoY29tcG9uZW50Lm5leHRFbGVtZW50U2libGluZykpICYmIHkgPiAoYyArIGNvbXBvbmVudC5vZmZzZXRIZWlnaHQgLSAyMCkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0b3AgPSBjb21wb25lbnRUb3AgKyBjb21wb25lbnQub2Zmc2V0SGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgICAgIGRpciA9ICdiJztcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGluZUJyZWFrZXJTdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb3JlLl92YXJpYWJsZS5fbGluZUJyZWFrQ29tcCA9IGNvbXBvbmVudDtcclxuICAgICAgICAgICAgICAgIGNvcmUuX3ZhcmlhYmxlLl9saW5lQnJlYWtEaXIgPSBkaXI7XHJcbiAgICAgICAgICAgICAgICBsaW5lQnJlYWtlclN0eWxlLnRvcCA9ICh0b3AgLSB3U2Nyb2xsKSArICdweCc7XHJcbiAgICAgICAgICAgICAgICBjb3JlLl9saW5lQnJlYWtlckJ1dHRvbi5zdHlsZS5sZWZ0ID0gKHV0aWwuZ2V0T2Zmc2V0KGNvbXBvbmVudCkubGVmdCArIChjb21wb25lbnQub2Zmc2V0V2lkdGggLyAyKSAtIDE1KSArICdweCc7XHJcbiAgICAgICAgICAgICAgICBsaW5lQnJlYWtlclN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG4gICAgICAgICAgICB9IC8vIG9mZiBsaW5lIGJyZWFrZXJcclxuICAgICAgICAgICAgZWxzZSBpZiAobGluZUJyZWFrZXJTdHlsZS5kaXNwbGF5ICE9PSAnbm9uZScpIHtcclxuICAgICAgICAgICAgICAgIGxpbmVCcmVha2VyU3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9vbk1vdXNlRG93bl9saW5lQnJlYWs6IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfb25MaW5lQnJlYWs6IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGNvbnN0IGNvbXBvbmVudCA9IGNvcmUuX3ZhcmlhYmxlLl9saW5lQnJlYWtDb21wO1xyXG4gICAgICAgICAgICBjb25zdCBkaXIgPSAhdGhpcyA/IGNvcmUuX3ZhcmlhYmxlLl9saW5lQnJlYWtEaXIgOiB0aGlzO1xyXG4gICAgICAgICAgICBjb25zdCBpc0xpc3QgPSB1dGlsLmlzTGlzdENlbGwoY29tcG9uZW50LnBhcmVudE5vZGUpO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgZm9ybWF0ID0gdXRpbC5jcmVhdGVFbGVtZW50KGlzTGlzdCA/ICdCUicgOiB1dGlsLmlzQ2VsbChjb21wb25lbnQucGFyZW50Tm9kZSkgPyAnRElWJyA6IG9wdGlvbnMuZGVmYXVsdFRhZyk7XHJcbiAgICAgICAgICAgIGlmICghaXNMaXN0KSBmb3JtYXQuaW5uZXJIVE1MID0gJzxicj4nO1xyXG5cclxuICAgICAgICAgICAgaWYgKGNvcmUuX2NoYXJUeXBlSFRNTCAmJiAhY29yZS5jaGVja0NoYXJDb3VudChmb3JtYXQub3V0ZXJIVE1MLCAnYnl0ZS1odG1sJykpIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgIGNvbXBvbmVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShmb3JtYXQsIGRpciA9PT0gJ3QnID8gY29tcG9uZW50IDogY29tcG9uZW50Lm5leHRTaWJsaW5nKTtcclxuICAgICAgICAgICAgY29yZS5fbGluZUJyZWFrZXIuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgY29yZS5fdmFyaWFibGUuX2xpbmVCcmVha0NvbXAgPSBudWxsO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgZm9jdXNFbCA9IGlzTGlzdCA/IGZvcm1hdCA6IGZvcm1hdC5maXJzdENoaWxkO1xyXG4gICAgICAgICAgICBjb3JlLnNldFJhbmdlKGZvY3VzRWwsIDEsIGZvY3VzRWwsIDEpO1xyXG4gICAgICAgICAgICAvLyBoaXN0b3J5IHN0YWNrXHJcbiAgICAgICAgICAgIGNvcmUuaGlzdG9yeS5wdXNoKGZhbHNlKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfYWRkRXZlbnQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29uc3QgZXZlbnRXeXNpd3lnID0gb3B0aW9ucy5pZnJhbWUgPyBjb3JlLl93dyA6IGNvbnRleHQuZWxlbWVudC53eXNpd3lnO1xyXG5cclxuICAgICAgICAgICAgLyoqIHRvb2xiYXIgZXZlbnQgKi9cclxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LnRvb2xiYXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgZXZlbnQuX2J1dHRvbnNFdmVudEhhbmRsZXIsIGZhbHNlKTtcclxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50Ll9tZW51VHJheS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBldmVudC5fYnV0dG9uc0V2ZW50SGFuZGxlciwgZmFsc2UpO1xyXG4gICAgICAgICAgICBjb250ZXh0LmVsZW1lbnQudG9vbGJhci5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGV2ZW50Lm9uQ2xpY2tfdG9vbGJhciwgZmFsc2UpO1xyXG4gICAgICAgICAgICAvKiogZWRpdG9yIGFyZWEgKi9cclxuICAgICAgICAgICAgZXZlbnRXeXNpd3lnLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGV2ZW50Lm9uTW91c2VEb3duX3d5c2l3eWcsIGZhbHNlKTtcclxuICAgICAgICAgICAgZXZlbnRXeXNpd3lnLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZXZlbnQub25DbGlja193eXNpd3lnLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGV2ZW50V3lzaXd5Zy5hZGRFdmVudExpc3RlbmVyKHV0aWwuaXNJRSA/ICd0ZXh0aW5wdXQnIDogJ2lucHV0JywgZXZlbnQub25JbnB1dF93eXNpd3lnLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGV2ZW50V3lzaXd5Zy5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgZXZlbnQub25LZXlEb3duX3d5c2l3eWcsIGZhbHNlKTtcclxuICAgICAgICAgICAgZXZlbnRXeXNpd3lnLmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgZXZlbnQub25LZXlVcF93eXNpd3lnLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGV2ZW50V3lzaXd5Zy5hZGRFdmVudExpc3RlbmVyKCdwYXN0ZScsIGV2ZW50Lm9uUGFzdGVfd3lzaXd5ZywgZmFsc2UpO1xyXG4gICAgICAgICAgICBldmVudFd5c2l3eWcuYWRkRXZlbnRMaXN0ZW5lcignY29weScsIGV2ZW50Lm9uQ29weV93eXNpd3lnLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGV2ZW50V3lzaXd5Zy5hZGRFdmVudExpc3RlbmVyKCdjdXQnLCBldmVudC5vbkN1dF93eXNpd3lnLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGV2ZW50V3lzaXd5Zy5hZGRFdmVudExpc3RlbmVyKCdkcm9wJywgZXZlbnQub25Ecm9wX3d5c2l3eWcsIGZhbHNlKTtcclxuICAgICAgICAgICAgZXZlbnRXeXNpd3lnLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIGV2ZW50Lm9uU2Nyb2xsX3d5c2l3eWcsIGZhbHNlKTtcclxuICAgICAgICAgICAgZXZlbnRXeXNpd3lnLmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgZXZlbnQub25Gb2N1c193eXNpd3lnLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGV2ZW50V3lzaXd5Zy5hZGRFdmVudExpc3RlbmVyKCdibHVyJywgZXZlbnQub25CbHVyX3d5c2l3eWcsIGZhbHNlKTtcclxuXHJcbiAgICAgICAgICAgIC8qKiBsaW5lIGJyZWFrZXIgKi9cclxuICAgICAgICAgICAgZXZlbnQuX2xpbmVCcmVha2VyQmluZCA9IHsgYTogZXZlbnQuX29uTGluZUJyZWFrLmJpbmQoJycpLCB0OiBldmVudC5fb25MaW5lQnJlYWsuYmluZCgndCcpLCBiOiBldmVudC5fb25MaW5lQnJlYWsuYmluZCgnYicpIH07XHJcbiAgICAgICAgICAgIGV2ZW50V3lzaXd5Zy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBldmVudC5vbk1vdXNlTW92ZV93eXNpd3lnLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGNvcmUuX2xpbmVCcmVha2VyQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGV2ZW50Ll9vbk1vdXNlRG93bl9saW5lQnJlYWssIGZhbHNlKTtcclxuICAgICAgICAgICAgY29yZS5fbGluZUJyZWFrZXJCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBldmVudC5fbGluZUJyZWFrZXJCaW5kLmEsIGZhbHNlKTtcclxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LmxpbmVCcmVha2VyX3QuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgZXZlbnQuX2xpbmVCcmVha2VyQmluZC50LCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5saW5lQnJlYWtlcl9iLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGV2ZW50Ll9saW5lQnJlYWtlckJpbmQuYiwgZmFsc2UpO1xyXG5cclxuICAgICAgICAgICAgLyoqIEV2ZW50cyBhcmUgcmVnaXN0ZXJlZCBvbmx5IHdoZW4gdGhlcmUgaXMgYSB0YWJsZSBwbHVnaW4uICAqL1xyXG4gICAgICAgICAgICBpZiAoY29yZS5wbHVnaW5zLnRhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICBldmVudFd5c2l3eWcuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGV2ZW50Lm9uTW91c2VEb3duX3d5c2l3eWcsIHtwYXNzaXZlOiB0cnVlLCB1c2VDYXB0dXJlOiBmYWxzZX0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvKiogY29kZSB2aWV3IGFyZWEgYXV0byBsaW5lICovXHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmhlaWdodCA9PT0gJ2F1dG8nICYmICFvcHRpb25zLmNvZGVNaXJyb3JFZGl0b3IpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5jb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBldmVudC5fY29kZVZpZXdBdXRvSGVpZ2h0LCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICBjb250ZXh0LmVsZW1lbnQuY29kZS5hZGRFdmVudExpc3RlbmVyKCdrZXl1cCcsIGV2ZW50Ll9jb2RlVmlld0F1dG9IZWlnaHQsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5jb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ3Bhc3RlJywgZXZlbnQuX2NvZGVWaWV3QXV0b0hlaWdodCwgZmFsc2UpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKiogcmVzaXppbmdCYXIgKi9cclxuICAgICAgICAgICAgaWYgKGNvbnRleHQuZWxlbWVudC5yZXNpemluZ0Jhcikge1xyXG4gICAgICAgICAgICAgICAgaWYgKC9cXGQrLy50ZXN0KG9wdGlvbnMuaGVpZ2h0KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5yZXNpemluZ0Jhci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBldmVudC5vbk1vdXNlRG93bl9yZXNpemluZ0JhciwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB1dGlsLmFkZENsYXNzKGNvbnRleHQuZWxlbWVudC5yZXNpemluZ0JhciwgJ3NlLXJlc2l6aW5nLW5vbmUnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLyoqIHdpbmRvdyBldmVudCAqL1xyXG4gICAgICAgICAgICBldmVudC5fc2V0UmVzcG9uc2l2ZVRvb2xiYXIoKTtcclxuICAgICAgICAgICAgX3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgZXZlbnQub25SZXNpemVfd2luZG93KTtcclxuICAgICAgICAgICAgX3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgZXZlbnQub25TY3JvbGxfd2luZG93KTtcclxuXHJcbiAgICAgICAgICAgIF93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIGV2ZW50Lm9uUmVzaXplX3dpbmRvdywgZmFsc2UpO1xyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5zdGlja3lUb29sYmFyID4gLTEpIHtcclxuICAgICAgICAgICAgICAgIF93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIGV2ZW50Lm9uU2Nyb2xsX3dpbmRvdywgZmFsc2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX3JlbW92ZUV2ZW50OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50V3lzaXd5ZyA9IG9wdGlvbnMuaWZyYW1lID8gY29yZS5fd3cgOiBjb250ZXh0LmVsZW1lbnQud3lzaXd5ZztcclxuXHJcbiAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC50b29sYmFyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGV2ZW50Ll9idXR0b25zRXZlbnRIYW5kbGVyKTtcclxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50Ll9tZW51VHJheS5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBldmVudC5fYnV0dG9uc0V2ZW50SGFuZGxlcik7XHJcbiAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC50b29sYmFyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZXZlbnQub25DbGlja190b29sYmFyKTtcclxuXHJcbiAgICAgICAgICAgIGV2ZW50V3lzaXd5Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBldmVudC5vbk1vdXNlRG93bl93eXNpd3lnKTtcclxuICAgICAgICAgICAgZXZlbnRXeXNpd3lnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZXZlbnQub25DbGlja193eXNpd3lnKTtcclxuICAgICAgICAgICAgZXZlbnRXeXNpd3lnLnJlbW92ZUV2ZW50TGlzdGVuZXIodXRpbC5pc0lFID8gJ3RleHRpbnB1dCcgOiAnaW5wdXQnLCBldmVudC5vbklucHV0X3d5c2l3eWcpO1xyXG4gICAgICAgICAgICBldmVudFd5c2l3eWcucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGV2ZW50Lm9uS2V5RG93bl93eXNpd3lnKTtcclxuICAgICAgICAgICAgZXZlbnRXeXNpd3lnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleXVwJywgZXZlbnQub25LZXlVcF93eXNpd3lnKTtcclxuICAgICAgICAgICAgZXZlbnRXeXNpd3lnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Bhc3RlJywgZXZlbnQub25QYXN0ZV93eXNpd3lnKTtcclxuICAgICAgICAgICAgZXZlbnRXeXNpd3lnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NvcHknLCBldmVudC5vbkNvcHlfd3lzaXd5Zyk7XHJcbiAgICAgICAgICAgIGV2ZW50V3lzaXd5Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdjdXQnLCBldmVudC5vbkN1dF93eXNpd3lnKTtcclxuICAgICAgICAgICAgZXZlbnRXeXNpd3lnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Ryb3AnLCBldmVudC5vbkRyb3Bfd3lzaXd5Zyk7XHJcbiAgICAgICAgICAgIGV2ZW50V3lzaXd5Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBldmVudC5vblNjcm9sbF93eXNpd3lnKTtcclxuXHJcbiAgICAgICAgICAgIGV2ZW50V3lzaXd5Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBldmVudC5vbk1vdXNlTW92ZV93eXNpd3lnKTtcclxuICAgICAgICAgICAgY29yZS5fbGluZUJyZWFrZXJCdXR0b24ucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgZXZlbnQuX29uTW91c2VEb3duX2xpbmVCcmVhayk7XHJcbiAgICAgICAgICAgIGNvcmUuX2xpbmVCcmVha2VyQnV0dG9uLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZXZlbnQuX2xpbmVCcmVha2VyQmluZC5hKTtcclxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LmxpbmVCcmVha2VyX3QucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgZXZlbnQuX2xpbmVCcmVha2VyQmluZC50KTtcclxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LmxpbmVCcmVha2VyX2IucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgZXZlbnQuX2xpbmVCcmVha2VyQmluZC5iKTtcclxuICAgICAgICAgICAgZXZlbnQuX2xpbmVCcmVha2VyQmluZCA9IG51bGw7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBldmVudFd5c2l3eWcucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGV2ZW50Lm9uTW91c2VEb3duX3d5c2l3eWcsIHtwYXNzaXZlOiB0cnVlLCB1c2VDYXB0dXJlOiBmYWxzZX0pO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgZXZlbnRXeXNpd3lnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgZXZlbnQub25Gb2N1c193eXNpd3lnKTtcclxuICAgICAgICAgICAgZXZlbnRXeXNpd3lnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2JsdXInLCBldmVudC5vbkJsdXJfd3lzaXd5Zyk7XHJcblxyXG4gICAgICAgICAgICBjb250ZXh0LmVsZW1lbnQuY29kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgZXZlbnQuX2NvZGVWaWV3QXV0b0hlaWdodCk7XHJcbiAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5jb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleXVwJywgZXZlbnQuX2NvZGVWaWV3QXV0b0hlaWdodCk7XHJcbiAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5jb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Bhc3RlJywgZXZlbnQuX2NvZGVWaWV3QXV0b0hlaWdodCk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBpZiAoY29udGV4dC5lbGVtZW50LnJlc2l6aW5nQmFyKSB7XHJcbiAgICAgICAgICAgICAgICBjb250ZXh0LmVsZW1lbnQucmVzaXppbmdCYXIucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgZXZlbnQub25Nb3VzZURvd25fcmVzaXppbmdCYXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBfdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCBldmVudC5vblJlc2l6ZV93aW5kb3cpO1xyXG4gICAgICAgICAgICBfdy5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBldmVudC5vblNjcm9sbF93aW5kb3cpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9zZXRSZXNwb25zaXZlVG9vbGJhcjogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoX3Jlc3BvbnNpdmVCdXR0b25zLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgX3Jlc3BvbnNpdmVCdXR0b25zID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3Qgc2l6ZUFycmF5ID0gZXZlbnQuX3Jlc3BvbnNpdmVCdXR0b25TaXplID0gW107XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1dHRvbnNPYmogPSBldmVudC5fcmVzcG9uc2l2ZUJ1dHRvbnMgPSB7ZGVmYXVsdDogX3Jlc3BvbnNpdmVCdXR0b25zWzBdfTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDEsIGxlbiA9IF9yZXNwb25zaXZlQnV0dG9ucy5sZW5ndGgsIHNpemUsIGJ1dHRvbkdyb3VwOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGJ1dHRvbkdyb3VwID0gX3Jlc3BvbnNpdmVCdXR0b25zW2ldO1xyXG4gICAgICAgICAgICAgICAgc2l6ZSA9IGJ1dHRvbkdyb3VwWzBdICogMTtcclxuICAgICAgICAgICAgICAgIHNpemVBcnJheS5wdXNoKHNpemUpO1xyXG4gICAgICAgICAgICAgICAgYnV0dG9uc09ialtzaXplXSA9IGJ1dHRvbkdyb3VwWzFdO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBzaXplQXJyYXkuc29ydChmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYSAtIGI7IH0pLnVuc2hpZnQoJ2RlZmF1bHQnKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKiBmdW5jdGlvbnMgKi9cclxuICAgIGNvbnN0IGZ1bmN0aW9ucyA9IHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ29yZSwgVXRpbCBvYmplY3RcclxuICAgICAgICAgKi9cclxuICAgICAgICBjb3JlOiBjb3JlLFxyXG4gICAgICAgIHV0aWw6IHV0aWwsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBFdmVudCBmdW5jdGlvbnNcclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gZSBFdmVudCBPYmplY3RcclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY29yZSBDb3JlIG9iamVjdFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIG9ubG9hZDogbnVsbCxcclxuICAgICAgICBvblNjcm9sbDogbnVsbCxcclxuICAgICAgICBvbk1vdXNlRG93bjogbnVsbCxcclxuICAgICAgICBvbkNsaWNrOiBudWxsLFxyXG4gICAgICAgIG9uSW5wdXQ6IG51bGwsXHJcbiAgICAgICAgb25LZXlEb3duOiBudWxsLFxyXG4gICAgICAgIG9uS2V5VXA6IG51bGwsXHJcbiAgICAgICAgb25DaGFuZ2U6IG51bGwsXHJcbiAgICAgICAgb25Db3B5OiBudWxsLFxyXG4gICAgICAgIG9uQ3V0OiBudWxsLFxyXG4gICAgICAgIG9uRm9jdXM6IG51bGwsXHJcbiAgICAgICAgb25CbHVyOiBudWxsLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gRXZlbnQgZnVuY3Rpb25zIChkcm9wLCBwYXN0ZSlcclxuICAgICAgICAgKiBXaGVuIGZhbHNlIGlzIHJldHVybmVkLCB0aGUgZGVmYXVsdCBiZWhhdmlvciBpcyBzdG9wcGVkLlxyXG4gICAgICAgICAqIElmIHRoZSBzdHJpbmcgaXMgcmV0dXJuZWQsIHRoZSBjbGVhbkRhdGEgdmFsdWUgaXMgbW9kaWZpZWQgdG8gdGhlIHJldHVybiB2YWx1ZS5cclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gZSBFdmVudCBvYmplY3QuXHJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGNsZWFuRGF0YSBIVE1MIHN0cmluZyBtb2RpZmllZCBmb3IgZWRpdG9yIGZvcm1hdC5cclxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IG1heENoYXJ0Q291bnQgb3B0aW9uICh0cnVlIGlmIG1heCBjaGFyYWN0ZXIgaXMgZXhjZWVkZWQpXHJcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNvcmUgQ29yZSBvYmplY3RcclxuICAgICAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbnxTdHJpbmd9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgb25Ecm9wOiBudWxsLFxyXG4gICAgICAgIG9uUGFzdGU6IG51bGwsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDYWxsZWQganVzdCBiZWZvcmUgdGhlIGlubGluZSB0b29sYmFyIGlzIHBvc2l0aW9uZWQgYW5kIGRpc3BsYXllZCBvbiB0aGUgc2NyZWVuLlxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gdG9vbGJhciBUb29sYmFyIEVsZW1lbnRcclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY29udGV4dCBUaGUgZWRpdG9yJ3MgY29udGV4dCBvYmplY3QgKGVkaXRvci5nZXRDb250ZXh0KCkpXHJcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNvcmUgQ29yZSBvYmplY3RcclxuICAgICAgICAgKi9cclxuICAgICAgICBzaG93SW5saW5lOiBudWxsLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ2FsbGVkIGp1c3QgYWZ0ZXIgdGhlIGNvbnRyb2xsZXIgaXMgcG9zaXRpb25lZCBhbmQgZGlzcGxheWVkIG9uIHRoZSBzY3JlZW4uXHJcbiAgICAgICAgICogY29udHJvbGxlciAtIGVkaXRpbmcgZWxlbWVudHMgZGlzcGxheWVkIG9uIHRoZSBzY3JlZW4gW2ltYWdlIHJlc2l6aW5nLCB0YWJsZSBlZGl0b3IsIGxpbmsgZWRpdG9yLi5dXVxyXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwbHVnaW4gdGhhdCBjYWxsZWQgdGhlIGNvbnRyb2xsZXJcclxuICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBjb250cm9sbGVycyBBcnJheSBvZiBDb250cm9sbGVyIGVsZW1lbnRzXHJcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNvcmUgQ29yZSBvYmplY3RcclxuICAgICAgICAgKi9cclxuICAgICAgICBzaG93Q29udHJvbGxlcjogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEFuIGV2ZW50IHdoZW4gdG9nZ2xpbmcgYmV0d2VlbiBjb2RlIHZpZXcgYW5kIHd5c2l3eWcgdmlldy5cclxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzQ29kZVZpZXcgV2hldGhlciB0aGUgY3VycmVudCBjb2RlIHZpZXcgbW9kZVxyXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb3JlIENvcmUgb2JqZWN0XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdG9nZ2xlQ29kZVZpZXc6IG51bGwsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBBbiBldmVudCB3aGVuIHRvZ2dsaW5nIGZ1bGwgc2NyZWVuLlxyXG4gICAgICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNGdWxsU2NyZWVuIFdoZXRoZXIgdGhlIGN1cnJlbnQgZnVsbCBzY3JlZW4gbW9kZVxyXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb3JlIENvcmUgb2JqZWN0XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdG9nZ2xlRnVsbFNjcmVlbjogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEl0IHJlcGxhY2VzIHRoZSBkZWZhdWx0IGNhbGxiYWNrIGZ1bmN0aW9uIG9mIHRoZSBpbWFnZSB1cGxvYWRcclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gcmVzcG9uc2UgUmVzcG9uc2Ugb2JqZWN0XHJcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGluZm8gSW5wdXQgaW5mb3JtYXRpb25cclxuICAgICAgICAgKiAtIGxpbmtWYWx1ZTogTGluayB1cmwgdmFsdWVcclxuICAgICAgICAgKiAtIGxpbmtOZXdXaW5kb3c6IE9wZW4gaW4gbmV3IHdpbmRvdyBDaGVjayBWYWx1ZVxyXG4gICAgICAgICAqIC0gaW5wdXRXaWR0aDogVmFsdWUgb2Ygd2lkdGggaW5wdXRcclxuICAgICAgICAgKiAtIGlucHV0SGVpZ2h0OiBWYWx1ZSBvZiBoZWlnaHQgaW5wdXRcclxuICAgICAgICAgKiAtIGFsaWduOiBBbGlnbiBDaGVjayBWYWx1ZVxyXG4gICAgICAgICAqIC0gaXNVcGRhdGU6IFVwZGF0ZSBpbWFnZSBpZiB0cnVlLCBjcmVhdGUgaW1hZ2UgaWYgZmFsc2VcclxuICAgICAgICAgKiAtIGVsZW1lbnQ6IElmIGlzVXBkYXRlIGlzIHRydWUsIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgaW1hZ2UuXHJcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNvcmUgQ29yZSBvYmplY3RcclxuICAgICAgICAgKi9cclxuICAgICAgICBpbWFnZVVwbG9hZEhhbmRsZXI6IG51bGwsXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBJdCByZXBsYWNlcyB0aGUgZGVmYXVsdCBjYWxsYmFjayBmdW5jdGlvbiBvZiB0aGUgdmlkZW8gdXBsb2FkXHJcbiAgICAgICAgICogQHBhcmFtIHhtbEh0dHAgeG1sSHR0cFJlcXVlc3Qgb2JqZWN0XHJcbiAgICAgICAgICogQHBhcmFtIGluZm8gSW5wdXQgaW5mb3JtYXRpb25cclxuICAgICAgICAgKiAtIGlucHV0V2lkdGg6IFZhbHVlIG9mIHdpZHRoIGlucHV0XHJcbiAgICAgICAgICogLSBpbnB1dEhlaWdodDogVmFsdWUgb2YgaGVpZ2h0IGlucHV0XHJcbiAgICAgICAgICogLSBhbGlnbjogQWxpZ24gQ2hlY2sgVmFsdWVcclxuICAgICAgICAgKiAtIGlzVXBkYXRlOiBVcGRhdGUgdmlkZW8gaWYgdHJ1ZSwgY3JlYXRlIHZpZGVvIGlmIGZhbHNlXHJcbiAgICAgICAgICogLSBlbGVtZW50OiBJZiBpc1VwZGF0ZSBpcyB0cnVlLCB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHZpZGVvLlxyXG4gICAgICAgICAqIEBwYXJhbSBjb3JlIENvcmUgb2JqZWN0XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdmlkZW9VcGxvYWRIYW5kbGVyOiBudWxsLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gSXQgcmVwbGFjZXMgdGhlIGRlZmF1bHQgY2FsbGJhY2sgZnVuY3Rpb24gb2YgdGhlIGF1ZGlvIHVwbG9hZFxyXG4gICAgICAgICAqIEBwYXJhbSB4bWxIdHRwIHhtbEh0dHBSZXF1ZXN0IG9iamVjdFxyXG4gICAgICAgICAqIEBwYXJhbSBpbmZvIElucHV0IGluZm9ybWF0aW9uXHJcbiAgICAgICAgICogLSBpc1VwZGF0ZTogVXBkYXRlIGF1ZGlvIGlmIHRydWUsIGNyZWF0ZSBhdWRpbyBpZiBmYWxzZVxyXG4gICAgICAgICAqIC0gZWxlbWVudDogSWYgaXNVcGRhdGUgaXMgdHJ1ZSwgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBhdWRpby5cclxuICAgICAgICAgKiBAcGFyYW0gY29yZSBDb3JlIG9iamVjdFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGF1ZGlvVXBsb2FkSGFuZGxlcjogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIENhbGxlZCBiZWZvcmUgdGhlIGltYWdlIGlzIHVwbG9hZGVkXHJcbiAgICAgICAgICogSWYgdHJ1ZSBpcyByZXR1cm5lZCwgdGhlIGludGVybmFsIHVwbG9hZCBwcm9jZXNzIHJ1bnMgbm9ybWFsbHkuXHJcbiAgICAgICAgICogSWYgZmFsc2UgaXMgcmV0dXJuZWQsIG5vIGltYWdlIHVwbG9hZCBpcyBwZXJmb3JtZWQuXHJcbiAgICAgICAgICogSWYgbmV3IGZpbGVMaXN0IGFyZSByZXR1cm5lZCwgIHJlcGxhY2VkIHRoZSBwcmV2aW91cyBmaWxlTGlzdFxyXG4gICAgICAgICAqIElmIHVuZGVmaW5lZCBpcyByZXR1cm5lZCwgaXQgd2FpdHMgdW50aWwgXCJ1cGxvYWRIYW5kbGVyXCIgaXMgZXhlY3V0ZWQuXHJcbiAgICAgICAgICogQHBhcmFtIHtBcnJheX0gZmlsZXMgRmlsZXMgYXJyYXlcclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gaW5mbyBpbmZvOiB7XHJcbiAgICAgICAgICogLSBsaW5rVmFsdWU6IExpbmsgdXJsIHZhbHVlXHJcbiAgICAgICAgICogLSBsaW5rTmV3V2luZG93OiBPcGVuIGluIG5ldyB3aW5kb3cgQ2hlY2sgVmFsdWVcclxuICAgICAgICAgKiAtIGlucHV0V2lkdGg6IFZhbHVlIG9mIHdpZHRoIGlucHV0XHJcbiAgICAgICAgICogLSBpbnB1dEhlaWdodDogVmFsdWUgb2YgaGVpZ2h0IGlucHV0XHJcbiAgICAgICAgICogLSBhbGlnbjogQWxpZ24gQ2hlY2sgVmFsdWVcclxuICAgICAgICAgKiAtIGlzVXBkYXRlOiBVcGRhdGUgaW1hZ2UgaWYgdHJ1ZSwgY3JlYXRlIGltYWdlIGlmIGZhbHNlXHJcbiAgICAgICAgICogLSBlbGVtZW50OiBJZiBpc1VwZGF0ZSBpcyB0cnVlLCB0aGUgY3VycmVudGx5IHNlbGVjdGVkIGltYWdlLlxyXG4gICAgICAgICAqIH1cclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY29yZSBDb3JlIG9iamVjdFxyXG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHVwbG9hZEhhbmRsZXIgSWYgdW5kZWZpbmVkIGlzIHJldHVybmVkLCBpdCB3YWl0cyB1bnRpbCBcInVwbG9hZEhhbmRsZXJcIiBpcyBleGVjdXRlZC5cclxuICAgICAgICAgKiAgICAgICAgICAgICAgICBcInVwbG9hZEhhbmRsZXJcIiBpcyBhbiB1cGxvYWQgZnVuY3Rpb24gd2l0aCBcImNvcmVcIiBhbmQgXCJpbmZvXCIgYm91bmQuXHJcbiAgICAgICAgICogICAgICAgICAgICAgICAgW3VwbG9hZCBmaWxlc10gOiB1cGxvYWRIYW5kbGVyKGZpbGVzIG9yIFtuZXcgRmlsZSguLi4pLF0pXHJcbiAgICAgICAgICogICAgICAgICAgICAgICAgW2Vycm9yXSAgICAgICAgOiB1cGxvYWRIYW5kbGVyKFwiRXJyb3IgbWVzc2FnZVwiKVxyXG4gICAgICAgICAqICAgICAgICAgICAgICAgIFtKdXN0IGZpbmlzaF0gIDogdXBsb2FkSGFuZGxlcigpXHJcbiAgICAgICAgICogICAgICAgICAgICAgICAgW2RpcmVjdGx5IHJlZ2lzdGVyXSA6IHVwbG9hZEhhbmRsZXIocmVzcG9uc2UpIC8vIFNhbWUgZm9ybWF0IGFzIFwiaW1hZ2VVcGxvYWRVcmxcIiByZXNwb25zZVxyXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleCkge1xyXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBcImVycm9yTWVzc2FnZVwiOiBcImluc2VydCBlcnJvciBtZXNzYWdlXCIsXHJcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwicmVzdWx0XCI6IFsgeyBcInVybFwiOiBcIi4uLlwiLCBcIm5hbWVcIjogXCIuLi5cIiwgXCJzaXplXCI6IFwiOTk5XCIgfSwgXVxyXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICogQHJldHVybnMge0Jvb2xlYW58QXJyYXl8dW5kZWZpbmVkfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIG9uSW1hZ2VVcGxvYWRCZWZvcmU6IG51bGwsXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIENhbGxlZCBiZWZvcmUgdGhlIHZpZGVvIGlzIHVwbG9hZGVkXHJcbiAgICAgICAgICogSWYgdHJ1ZSBpcyByZXR1cm5lZCwgdGhlIGludGVybmFsIHVwbG9hZCBwcm9jZXNzIHJ1bnMgbm9ybWFsbHkuXHJcbiAgICAgICAgICogSWYgZmFsc2UgaXMgcmV0dXJuZWQsIG5vIHZpZGVvKGlmcmFtZSwgdmlkZW8pIHVwbG9hZCBpcyBwZXJmb3JtZWQuXHJcbiAgICAgICAgICogSWYgbmV3IGZpbGVMaXN0IGFyZSByZXR1cm5lZCwgIHJlcGxhY2VkIHRoZSBwcmV2aW91cyBmaWxlTGlzdFxyXG4gICAgICAgICAqIElmIHVuZGVmaW5lZCBpcyByZXR1cm5lZCwgaXQgd2FpdHMgdW50aWwgXCJ1cGxvYWRIYW5kbGVyXCIgaXMgZXhlY3V0ZWQuXHJcbiAgICAgICAgICogQHBhcmFtIHtBcnJheX0gZmlsZXMgRmlsZXMgYXJyYXlcclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gaW5mbyBpbmZvOiB7XHJcbiAgICAgICAgICogLSBpbnB1dFdpZHRoOiBWYWx1ZSBvZiB3aWR0aCBpbnB1dFxyXG4gICAgICAgICAqIC0gaW5wdXRIZWlnaHQ6IFZhbHVlIG9mIGhlaWdodCBpbnB1dFxyXG4gICAgICAgICAqIC0gYWxpZ246IEFsaWduIENoZWNrIFZhbHVlXHJcbiAgICAgICAgICogLSBpc1VwZGF0ZTogVXBkYXRlIHZpZGVvIGlmIHRydWUsIGNyZWF0ZSB2aWRlbyBpZiBmYWxzZVxyXG4gICAgICAgICAqIC0gZWxlbWVudDogSWYgaXNVcGRhdGUgaXMgdHJ1ZSwgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCB2aWRlby5cclxuICAgICAgICAgKiB9XHJcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNvcmUgQ29yZSBvYmplY3RcclxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB1cGxvYWRIYW5kbGVyIElmIHVuZGVmaW5lZCBpcyByZXR1cm5lZCwgaXQgd2FpdHMgdW50aWwgXCJ1cGxvYWRIYW5kbGVyXCIgaXMgZXhlY3V0ZWQuXHJcbiAgICAgICAgICogICAgICAgICAgICAgICAgXCJ1cGxvYWRIYW5kbGVyXCIgaXMgYW4gdXBsb2FkIGZ1bmN0aW9uIHdpdGggXCJjb3JlXCIgYW5kIFwiaW5mb1wiIGJvdW5kLlxyXG4gICAgICAgICAqICAgICAgICAgICAgICAgIFt1cGxvYWQgZmlsZXNdIDogdXBsb2FkSGFuZGxlcihmaWxlcyBvciBbbmV3IEZpbGUoLi4uKSxdKVxyXG4gICAgICAgICAqICAgICAgICAgICAgICAgIFtlcnJvcl0gICAgICAgIDogdXBsb2FkSGFuZGxlcihcIkVycm9yIG1lc3NhZ2VcIilcclxuICAgICAgICAgKiAgICAgICAgICAgICAgICBbSnVzdCBmaW5pc2hdICA6IHVwbG9hZEhhbmRsZXIoKVxyXG4gICAgICAgICAqICAgICAgICAgICAgICAgIFtkaXJlY3RseSByZWdpc3Rlcl0gOiB1cGxvYWRIYW5kbGVyKHJlc3BvbnNlKSAvLyBTYW1lIGZvcm1hdCBhcyBcInZpZGVvVXBsb2FkVXJsXCIgcmVzcG9uc2VcclxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXgpIHtcclxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gXCJlcnJvck1lc3NhZ2VcIjogXCJpbnNlcnQgZXJyb3IgbWVzc2FnZVwiLFxyXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcInJlc3VsdFwiOiBbIHsgXCJ1cmxcIjogXCIuLi5cIiwgXCJuYW1lXCI6IFwiLi4uXCIsIFwic2l6ZVwiOiBcIjk5OVwiIH0sIF1cclxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAqIEByZXR1cm5zIHtCb29sZWFufEFycmF5fHVuZGVmaW5lZH1cclxuICAgICAgICAgKi9cclxuICAgICAgICBvblZpZGVvVXBsb2FkQmVmb3JlOiBudWxsLFxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDYWxsZWQgYmVmb3JlIHRoZSBhdWRpbyBpcyB1cGxvYWRlZFxyXG4gICAgICAgICAqIElmIHRydWUgaXMgcmV0dXJuZWQsIHRoZSBpbnRlcm5hbCB1cGxvYWQgcHJvY2VzcyBydW5zIG5vcm1hbGx5LlxyXG4gICAgICAgICAqIElmIGZhbHNlIGlzIHJldHVybmVkLCBubyBhdWRpbyB1cGxvYWQgaXMgcGVyZm9ybWVkLlxyXG4gICAgICAgICAqIElmIG5ldyBmaWxlTGlzdCBhcmUgcmV0dXJuZWQsICByZXBsYWNlZCB0aGUgcHJldmlvdXMgZmlsZUxpc3RcclxuICAgICAgICAgKiBJZiB1bmRlZmluZWQgaXMgcmV0dXJuZWQsIGl0IHdhaXRzIHVudGlsIFwidXBsb2FkSGFuZGxlclwiIGlzIGV4ZWN1dGVkLlxyXG4gICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGZpbGVzIEZpbGVzIGFycmF5XHJcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGluZm8gaW5mbzoge1xyXG4gICAgICAgICAqIC0gaXNVcGRhdGU6IFVwZGF0ZSBhdWRpbyBpZiB0cnVlLCBjcmVhdGUgYXVkaW8gaWYgZmFsc2VcclxuICAgICAgICAgKiAtIGVsZW1lbnQ6IElmIGlzVXBkYXRlIGlzIHRydWUsIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgYXVkaW8uXHJcbiAgICAgICAgICogfVxyXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb3JlIENvcmUgb2JqZWN0XHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gdXBsb2FkSGFuZGxlciBJZiB1bmRlZmluZWQgaXMgcmV0dXJuZWQsIGl0IHdhaXRzIHVudGlsIFwidXBsb2FkSGFuZGxlclwiIGlzIGV4ZWN1dGVkLlxyXG4gICAgICAgICAqICAgICAgICAgICAgICAgIFwidXBsb2FkSGFuZGxlclwiIGlzIGFuIHVwbG9hZCBmdW5jdGlvbiB3aXRoIFwiY29yZVwiIGFuZCBcImluZm9cIiBib3VuZC5cclxuICAgICAgICAgKiAgICAgICAgICAgICAgICBbdXBsb2FkIGZpbGVzXSA6IHVwbG9hZEhhbmRsZXIoZmlsZXMgb3IgW25ldyBGaWxlKC4uLiksXSlcclxuICAgICAgICAgKiAgICAgICAgICAgICAgICBbZXJyb3JdICAgICAgICA6IHVwbG9hZEhhbmRsZXIoXCJFcnJvciBtZXNzYWdlXCIpXHJcbiAgICAgICAgICogICAgICAgICAgICAgICAgW0p1c3QgZmluaXNoXSAgOiB1cGxvYWRIYW5kbGVyKClcclxuICAgICAgICAgKiAgICAgICAgICAgICAgICBbZGlyZWN0bHkgcmVnaXN0ZXJdIDogdXBsb2FkSGFuZGxlcihyZXNwb25zZSkgLy8gU2FtZSBmb3JtYXQgYXMgXCJhdWRpb1VwbG9hZFVybFwiIHJlc3BvbnNlXHJcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4KSB7XHJcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFwiZXJyb3JNZXNzYWdlXCI6IFwiaW5zZXJ0IGVycm9yIG1lc3NhZ2VcIixcclxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJyZXN1bHRcIjogWyB7IFwidXJsXCI6IFwiLi4uXCIsIFwibmFtZVwiOiBcIi4uLlwiLCBcInNpemVcIjogXCI5OTlcIiB9LCBdXHJcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbnxBcnJheXx1bmRlZmluZWR9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgb25BdWRpb1VwbG9hZEJlZm9yZTogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIENhbGxlZCB3aGVuIHRoZSBpbWFnZSBpcyB1cGxvYWRlZCwgdXBkYXRlZCwgZGVsZXRlZFxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gdGFyZ2V0RWxlbWVudCBUYXJnZXQgZWxlbWVudFxyXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleCBVcGxvYWRlZCBpbmRleFxyXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdGF0ZSBVcGxvYWQgc3RhdHVzICgnY3JlYXRlJywgJ3VwZGF0ZScsICdkZWxldGUnKVxyXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBpbmZvIEltYWdlIGluZm8gb2JqZWN0XHJcbiAgICAgICAgICogLSBpbmRleDogZGF0YSBpbmRleFxyXG4gICAgICAgICAqIC0gbmFtZTogZmlsZSBuYW1lXHJcbiAgICAgICAgICogLSBzaXplOiBmaWxlIHNpemVcclxuICAgICAgICAgKiAtIHNlbGVjdDogc2VsZWN0IGZ1bmN0aW9uXHJcbiAgICAgICAgICogLSBkZWxldGU6IGRlbGV0ZSBmdW5jdGlvblxyXG4gICAgICAgICAqIC0gZWxlbWVudDogdGFyZ2V0IGVsZW1lbnRcclxuICAgICAgICAgKiAtIHNyYzogc3JjIGF0dHJpYnV0ZSBvZiB0YWdcclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gcmVtYWluaW5nRmlsZXNDb3VudCBDb3VudCBvZiByZW1haW5pbmcgZmlsZXMgdG8gdXBsb2FkICgwIHdoZW4gYWRkZWQgYXMgYSB1cmwpXHJcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNvcmUgQ29yZSBvYmplY3RcclxuICAgICAgICAgKi9cclxuICAgICAgICBvbkltYWdlVXBsb2FkOiBudWxsLFxyXG4gICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ2FsbGVkIHdoZW4gdGhlIHZpZGVvKGlmcmFtZSwgdmlkZW8pIGlzIGlzIHVwbG9hZGVkLCB1cGRhdGVkLCBkZWxldGVkXHJcbiAgICAgICAgICogLS0gYXJndW1lbnRzIGlzIHNhbWUgXCJvbkltYWdlVXBsb2FkXCIgLS1cclxuICAgICAgICAgKi9cclxuICAgICAgICBvblZpZGVvVXBsb2FkOiBudWxsLFxyXG4gICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ2FsbGVkIHdoZW4gdGhlIGF1ZGlvIGlzIGlzIHVwbG9hZGVkLCB1cGRhdGVkLCBkZWxldGVkXHJcbiAgICAgICAgICogLS0gYXJndW1lbnRzIGlzIHNhbWUgXCJvbkltYWdlVXBsb2FkXCIgLS1cclxuICAgICAgICAgKi9cclxuICAgICAgICBvbkF1ZGlvVXBsb2FkOiBudWxsLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ2FsbGVkIHdoZW4gdGhlIGltYWdlIGlzIHVwbG9hZCBmYWlsZWRcclxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXJyb3JNZXNzYWdlIEVycm9yIG1lc3NhZ2VcclxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gcmVzdWx0IFJlc3BvbnNlIE9iamVjdFxyXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb3JlIENvcmUgb2JqZWN0XHJcbiAgICAgICAgICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgb25JbWFnZVVwbG9hZEVycm9yOiBudWxsLFxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDYWxsZWQgd2hlbiB0aGUgdmlkZW8oaWZyYW1lLCB2aWRlbykgdXBsb2FkIGZhaWxlZFxyXG4gICAgICAgICAqIC0tIGFyZ3VtZW50cyBpcyBzYW1lIFwib25JbWFnZVVwbG9hZEVycm9yXCIgLS1cclxuICAgICAgICAgKi9cclxuICAgICAgICBvblZpZGVvVXBsb2FkRXJyb3I6IG51bGwsXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIENhbGxlZCB3aGVuIHRoZSBhdWRpbyB1cGxvYWQgZmFpbGVkXHJcbiAgICAgICAgICogLS0gYXJndW1lbnRzIGlzIHNhbWUgXCJvbkltYWdlVXBsb2FkRXJyb3JcIiAtLVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIG9uQXVkaW9VcGxvYWRFcnJvcjogbnVsbCxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFJlc2V0IHRoZSBidXR0b25zIG9uIHRoZSB0b29sYmFyLiAoRWRpdG9yIGlzIG5vdCByZWxvYWRlZClcclxuICAgICAgICAgKiBZb3UgY2Fubm90IHNldCBhIG5ldyBwbHVnaW4gZm9yIHRoZSBidXR0b24uXHJcbiAgICAgICAgICogQHBhcmFtIHtBcnJheX0gYnV0dG9uTGlzdCBCdXR0b24gbGlzdCBcclxuICAgICAgICAgKi9cclxuICAgICAgICBzZXRUb29sYmFyQnV0dG9uczogZnVuY3Rpb24gKGJ1dHRvbkxpc3QpIHtcclxuICAgICAgICAgICAgY29yZS5zdWJtZW51T2ZmKCk7XHJcbiAgICAgICAgICAgIGNvcmUuY29udGFpbmVyT2ZmKCk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBjb25zdCBuZXdUb29sYmFyID0gX0NvbnN0cnVjdG9yLl9jcmVhdGVUb29sQmFyKF9kLCBidXR0b25MaXN0LCBjb3JlLnBsdWdpbnMsIG9wdGlvbnMpO1xyXG4gICAgICAgICAgICBfcmVzcG9uc2l2ZUJ1dHRvbnMgPSBuZXdUb29sYmFyLnJlc3BvbnNpdmVCdXR0b25zO1xyXG4gICAgICAgICAgICBjb3JlLl9tb3JlTGF5ZXJBY3RpdmVCdXR0b24gPSBudWxsO1xyXG4gICAgICAgICAgICBldmVudC5fc2V0UmVzcG9uc2l2ZVRvb2xiYXIoKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC50b29sYmFyLnJlcGxhY2VDaGlsZChuZXdUb29sYmFyLl9idXR0b25UcmF5LCBjb250ZXh0LmVsZW1lbnQuX2J1dHRvblRyYXkpO1xyXG4gICAgICAgICAgICBjb25zdCBuZXdDb250ZXh0ID0gX0NvbnRleHQoY29udGV4dC5lbGVtZW50Lm9yaWdpbkVsZW1lbnQsIGNvcmUuX2dldENvbnN0cnVjdGVkKGNvbnRleHQuZWxlbWVudCksIG9wdGlvbnMpO1xyXG5cclxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50ID0gbmV3Q29udGV4dC5lbGVtZW50O1xyXG4gICAgICAgICAgICBjb250ZXh0LnRvb2wgPSBuZXdDb250ZXh0LnRvb2w7XHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmlmcmFtZSkgY29udGV4dC5lbGVtZW50Lnd5c2l3eWcgPSBjb3JlLl93ZC5ib2R5O1xyXG4gICAgICAgICAgICBjb3JlLl9jYWNoaW5nQnV0dG9ucygpO1xyXG4gICAgICAgICAgICBjb3JlLmhpc3RvcnkuX3Jlc2V0Q2FjaGluZ0J1dHRvbigpO1xyXG5cclxuICAgICAgICAgICAgY29yZS5hY3RpdmVQbHVnaW5zID0gW107XHJcbiAgICAgICAgICAgIGNvbnN0IG9sZENhbGxCdXR0b25zID0gcGx1Z2luQ2FsbEJ1dHRvbnM7XHJcbiAgICAgICAgICAgIHBsdWdpbkNhbGxCdXR0b25zID0gbmV3VG9vbGJhci5wbHVnaW5DYWxsQnV0dG9ucztcclxuICAgICAgICAgICAgbGV0IHBsdWdpbiwgYnV0dG9uLCBvbGRCdXR0b247XHJcbiAgICAgICAgICAgIGZvciAobGV0IGtleSBpbiBwbHVnaW5DYWxsQnV0dG9ucykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF1dGlsLmhhc093bihwbHVnaW5DYWxsQnV0dG9ucywga2V5KSkgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBwbHVnaW4gPSBwbHVnaW5zW2tleV07XHJcbiAgICAgICAgICAgICAgICBidXR0b24gPSBwbHVnaW5DYWxsQnV0dG9uc1trZXldO1xyXG4gICAgICAgICAgICAgICAgaWYgKHBsdWdpbi5hY3RpdmUgJiYgYnV0dG9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2xkQnV0dG9uID0gb2xkQ2FsbEJ1dHRvbnNba2V5XTtcclxuICAgICAgICAgICAgICAgICAgICBjb3JlLmNhbGxQbHVnaW4oa2V5LCBudWxsLCBvbGRCdXR0b24gfHwgYnV0dG9uKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob2xkQnV0dG9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbi5wYXJlbnRFbGVtZW50LnJlcGxhY2VDaGlsZChvbGRCdXR0b24sIGJ1dHRvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsdWdpbkNhbGxCdXR0b25zW2tleV0gPSBvbGRCdXR0b247XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoY29yZS5oYXNGb2N1cykgZXZlbnQuX2FwcGx5VGFnRWZmZWN0cygpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGNvcmUuX3ZhcmlhYmxlLmlzQ29kZVZpZXcpIHV0aWwuYWRkQ2xhc3MoY29yZS5fc3R5bGVDb21tYW5kTWFwLmNvZGVWaWV3LCAnYWN0aXZlJyk7XHJcbiAgICAgICAgICAgIGlmIChjb3JlLl92YXJpYWJsZS5pc0Z1bGxTY3JlZW4pIHV0aWwuYWRkQ2xhc3MoY29yZS5fc3R5bGVDb21tYW5kTWFwLmZ1bGxTY3JlZW4sICdhY3RpdmUnKTtcclxuICAgICAgICAgICAgaWYgKHV0aWwuaGFzQ2xhc3MoY29udGV4dC5lbGVtZW50Lnd5c2l3eWcsICdzZS1zaG93LWJsb2NrJykpIHV0aWwuYWRkQ2xhc3MoY29yZS5fc3R5bGVDb21tYW5kTWFwLnNob3dCbG9ja3MsICdhY3RpdmUnKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQWRkIG9yIHJlc2V0IG9wdGlvbiBwcm9wZXJ0eSAoRWRpdG9yIGlzIHJlbG9hZGVkKVxyXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBfb3B0aW9ucyBPcHRpb25zXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgc2V0T3B0aW9uczogZnVuY3Rpb24gKF9vcHRpb25zKSB7XHJcbiAgICAgICAgICAgIGV2ZW50Ll9yZW1vdmVFdmVudCgpO1xyXG4gICAgICAgICAgICBjb3JlLl9yZXNldENvbXBvbmVudHMoKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIHV0aWwucmVtb3ZlQ2xhc3MoY29yZS5fc3R5bGVDb21tYW5kTWFwLnNob3dCbG9ja3MsICdhY3RpdmUnKTtcclxuICAgICAgICAgICAgdXRpbC5yZW1vdmVDbGFzcyhjb3JlLl9zdHlsZUNvbW1hbmRNYXAuY29kZVZpZXcsICdhY3RpdmUnKTtcclxuICAgICAgICAgICAgY29yZS5fdmFyaWFibGUuaXNDb2RlVmlldyA9IGZhbHNlO1xyXG4gICAgICAgICAgICBjb3JlLl9pZnJhbWVBdXRvID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgIGNvcmUucGx1Z2lucyA9IF9vcHRpb25zLnBsdWdpbnMgfHwgY29yZS5wbHVnaW5zO1xyXG4gICAgICAgICAgICBjb25zdCBtZXJnZU9wdGlvbnMgPSBbb3B0aW9ucywgX29wdGlvbnNdLnJlZHVjZShmdW5jdGlvbiAoaW5pdCwgb3B0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBrZXkgaW4gb3B0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF1dGlsLmhhc093bihvcHRpb24sIGtleSkpIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXkgPT09ICdwbHVnaW5zJyAmJiBvcHRpb25ba2V5XSAmJiBpbml0W2tleV0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGkgPSBpbml0W2tleV0sIG8gPSBvcHRpb25ba2V5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaSA9IGkubGVuZ3RoID8gaSA6IF93Lk9iamVjdC5rZXlzKGkpLm1hcChmdW5jdGlvbihuYW1lKSB7IHJldHVybiBpW25hbWVdOyB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbyA9IG8ubGVuZ3RoID8gbyA6IF93Lk9iamVjdC5rZXlzKG8pLm1hcChmdW5jdGlvbihuYW1lKSB7IHJldHVybiBvW25hbWVdOyB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdFtrZXldID0gKG8uZmlsdGVyKGZ1bmN0aW9uKHZhbCkgeyByZXR1cm4gaS5pbmRleE9mKHZhbCkgPT09IC0xOyB9KSkuY29uY2F0KGkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluaXRba2V5XSA9IG9wdGlvbltrZXldO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBpbml0O1xyXG4gICAgICAgICAgICB9LCB7fSk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBlbCA9IGNvbnRleHQuZWxlbWVudDtcclxuICAgICAgICAgICAgY29uc3QgX2luaXRIVE1MID0gZWwud3lzaXd5Zy5pbm5lckhUTUw7XHJcblxyXG4gICAgICAgICAgICAvLyBzZXQgb3B0aW9uXHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnMgPSBfQ29uc3RydWN0b3IuX3NldE9wdGlvbnMobWVyZ2VPcHRpb25zLCBjb250ZXh0LCBjb3JlLnBsdWdpbnMsIG9wdGlvbnMpOyAgICAgICAgXHJcblxyXG4gICAgICAgICAgICBpZiAoY29ucy5jYWxsQnV0dG9ucykge1xyXG4gICAgICAgICAgICAgICAgcGx1Z2luQ2FsbEJ1dHRvbnMgPSBjb25zLmNhbGxCdXR0b25zO1xyXG4gICAgICAgICAgICAgICAgY29yZS5pbml0UGx1Z2lucyA9IHt9O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoY29ucy5wbHVnaW5zKSB7XHJcbiAgICAgICAgICAgICAgICBjb3JlLnBsdWdpbnMgPSBwbHVnaW5zID0gY29ucy5wbHVnaW5zO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyByZXNldCBjb250ZXh0XHJcbiAgICAgICAgICAgIGlmIChlbC5fbWVudVRyYXkuY2hpbGRyZW4ubGVuZ3RoID09PSAwKSB0aGlzLl9tZW51VHJheSA9IHt9O1xyXG4gICAgICAgICAgICBfcmVzcG9uc2l2ZUJ1dHRvbnMgPSBjb25zLnRvb2xiYXIucmVzcG9uc2l2ZUJ1dHRvbnM7XHJcbiAgICAgICAgICAgIG9wdGlvbnMgPSBtZXJnZU9wdGlvbnM7XHJcbiAgICAgICAgICAgIGNvcmUubGFuZyA9IGxhbmcgPSBvcHRpb25zLmxhbmc7XHJcblxyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5pZnJhbWUpIHtcclxuICAgICAgICAgICAgICAgIGVsLnd5c2l3eWdGcmFtZS5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHV0aWwuX3NldElmcmFtZURvY3VtZW50KHRoaXMsIG9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvcmUuX3NldE9wdGlvbnNJbml0KGVsLCBfaW5pdEhUTUwpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGVsLmVkaXRvckFyZWEuYXBwZW5kQ2hpbGQoZWwud3lzaXd5Z0ZyYW1lKTtcclxuXHJcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5pZnJhbWUpIHtcclxuICAgICAgICAgICAgICAgIGNvcmUuX3NldE9wdGlvbnNJbml0KGVsLCBfaW5pdEhUTUwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFNldCBcIm9wdGlvbnMuZGVmYXVsdFN0eWxlXCIgc3R5bGUuXHJcbiAgICAgICAgICogRGVmaW5lIHRoZSBzdHlsZSBvZiB0aGUgZWRpdCBhcmVhXHJcbiAgICAgICAgICogSXQgY2FuIGFsc28gYmUgZGVmaW5lZCB3aXRoIHRoZSBcInNldE9wdGlvbnNcIiBtZXRob2QsIGJ1dCB0aGUgXCJzZXREZWZhdWx0U3R5bGVcIiBtZXRob2QgZG9lcyBub3QgcmVuZGVyIHRoZSBlZGl0b3IgYWdhaW4uXHJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHN0eWxlIFN0eWxlIHN0cmluZ1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHNldERlZmF1bHRTdHlsZTogZnVuY3Rpb24gKHN0eWxlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG5ld1N0eWxlcyA9IG9wdGlvbnMuX2VkaXRvclN0eWxlcyA9IHV0aWwuX3NldERlZmF1bHRPcHRpb25TdHlsZShvcHRpb25zLCBzdHlsZSk7XHJcbiAgICAgICAgICAgIGNvbnN0IGVsID0gY29udGV4dC5lbGVtZW50O1xyXG5cclxuICAgICAgICAgICAgLy8gdG9wIGFyZWFcclxuICAgICAgICAgICAgZWwudG9wQXJlYS5zdHlsZS5jc3NUZXh0ID0gbmV3U3R5bGVzLnRvcDtcclxuICAgICAgICAgICAgLy8gY29kZSB2aWV3XHJcbiAgICAgICAgICAgIGVsLmNvZGUuc3R5bGUuY3NzVGV4dCA9IG9wdGlvbnMuX2VkaXRvclN0eWxlcy5mcmFtZTtcclxuICAgICAgICAgICAgZWwuY29kZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5oZWlnaHQgPT09ICdhdXRvJykge1xyXG4gICAgICAgICAgICAgICAgZWwuY29kZS5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZWwuY29kZS5zdHlsZS5vdmVyZmxvdyA9ICcnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIHd5c2l3eWcgZnJhbWVcclxuICAgICAgICAgICAgaWYgKCFvcHRpb25zLmlmcmFtZSkge1xyXG4gICAgICAgICAgICAgICAgZWwud3lzaXd5Z0ZyYW1lLnN0eWxlLmNzc1RleHQgPSBuZXdTdHlsZXMuZnJhbWUgKyBuZXdTdHlsZXMuZWRpdG9yO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZWwud3lzaXd5Z0ZyYW1lLnN0eWxlLmNzc1RleHQgPSBuZXdTdHlsZXMuZnJhbWU7XHJcbiAgICAgICAgICAgICAgICBlbC53eXNpd3lnLnN0eWxlLmNzc1RleHQgPSBuZXdTdHlsZXMuZWRpdG9yO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIE9wZW4gYSBub3RpY2UgYXJlYVxyXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIE5vdGljZSBtZXNzYWdlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgbm90aWNlT3BlbjogZnVuY3Rpb24gKG1lc3NhZ2UpIHtcclxuICAgICAgICAgICAgY29yZS5ub3RpY2Uub3Blbi5jYWxsKGNvcmUsIG1lc3NhZ2UpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDbG9zZSBhIG5vdGljZSBhcmVhXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgbm90aWNlQ2xvc2U6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29yZS5ub3RpY2UuY2xvc2UuY2FsbChjb3JlKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ29weWluZyB0aGUgY29udGVudHMgb2YgdGhlIGVkaXRvciB0byB0aGUgb3JpZ2luYWwgdGV4dGFyZWFcclxuICAgICAgICAgKi9cclxuICAgICAgICBzYXZlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5vcmlnaW5FbGVtZW50LnZhbHVlID0gY29yZS5nZXRDb250ZW50cyhmYWxzZSk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIHN1bmVkaXRvcidzIGNvbnRleHQgb2JqZWN0LiBDb250YWlucyBzZXR0aW5ncywgcGx1Z2lucywgYW5kIGNhY2hlZCBlbGVtZW50IG9iamVjdHNcclxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldENvbnRleHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQ7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIGNvbnRlbnRzIG9mIHRoZSBzdW5lZGl0b3JcclxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IG9ubHlDb250ZW50cyAtIFJldHVybiBvbmx5IHRoZSBjb250ZW50cyBvZiB0aGUgYm9keSB3aXRob3V0IGhlYWRlcnMgd2hlbiB0aGUgXCJmdWxsUGFnZVwiIG9wdGlvbiBpcyB0cnVlXHJcbiAgICAgICAgICogQHJldHVybnMge1N0cmluZ31cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXRDb250ZW50czogZnVuY3Rpb24gKG9ubHlDb250ZW50cykge1xyXG4gICAgICAgICAgICByZXR1cm4gY29yZS5nZXRDb250ZW50cyhvbmx5Q29udGVudHMpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBHZXRzIG9ubHkgdGhlIHRleHQgb2YgdGhlIHN1bmVkaXRvciBjb250ZW50c1xyXG4gICAgICAgICAqIEByZXR1cm5zIHtTdHJpbmd9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0VGV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5lbGVtZW50Lnd5c2l3eWcudGV4dENvbnRlbnQ7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEdldCB0aGUgZWRpdG9yJ3MgbnVtYmVyIG9mIGNoYXJhY3RlcnMgb3IgYmluYXJ5IGRhdGEgc2l6ZS5cclxuICAgICAgICAgKiBZb3UgY2FuIHVzZSB0aGUgXCJjaGFyQ291bnRlclR5cGVcIiBvcHRpb24gZm9ybWF0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfG51bGx9IGNoYXJDb3VudGVyVHlwZSBvcHRpb25zIC0gY2hhckNvdW50ZXJUeXBlICgnY2hhcicsICdieXRlJywgJ2J5dGUtaHRtbCcpXHJcbiAgICAgICAgICogSWYgYXJndW1lbnQgaXMgbm8gdmFsdWUsIHRoZSBjdXJyZW50bHkgc2V0IFwiY2hhckNvdW50ZXJUeXBlXCIgb3B0aW9uIGlzIHVzZWQuXHJcbiAgICAgICAgICogQHJldHVybnMge051bWJlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXRDaGFyQ291bnQ6IGZ1bmN0aW9uIChjaGFyQ291bnRlclR5cGUpIHtcclxuICAgICAgICAgICAgY2hhckNvdW50ZXJUeXBlID0gdHlwZW9mIGNoYXJDb3VudGVyVHlwZSA9PT0gJ3N0cmluZycgPyBjaGFyQ291bnRlclR5cGUgOiBvcHRpb25zLmNoYXJDb3VudGVyVHlwZTtcclxuICAgICAgICAgICAgcmV0dXJuIGNvcmUuZ2V0Q2hhckxlbmd0aCgoY29yZS5fY2hhclR5cGVIVE1MID8gY29udGV4dC5lbGVtZW50Lnd5c2l3eWcuaW5uZXJIVE1MIDogY29udGV4dC5lbGVtZW50Lnd5c2l3eWcudGV4dENvbnRlbnQpLCBjaGFyQ291bnRlclR5cGUpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBHZXRzIHVwbG9hZGVkIGltYWdlcyBpbmZvcm1hdGlvbnNcclxuICAgICAgICAgKiAtIGluZGV4OiBkYXRhIGluZGV4XHJcbiAgICAgICAgICogLSBuYW1lOiBmaWxlIG5hbWVcclxuICAgICAgICAgKiAtIHNpemU6IGZpbGUgc2l6ZVxyXG4gICAgICAgICAqIC0gc2VsZWN0OiBzZWxlY3QgZnVuY3Rpb25cclxuICAgICAgICAgKiAtIGRlbGV0ZTogZGVsZXRlIGZ1bmN0aW9uXHJcbiAgICAgICAgICogLSBlbGVtZW50OiB0YXJnZXQgZWxlbWVudFxyXG4gICAgICAgICAqIC0gc3JjOiBzcmMgYXR0cmlidXRlIG9mIHRhZ1xyXG4gICAgICAgICAqIEByZXR1cm5zIHtBcnJheX1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXRJbWFnZXNJbmZvOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmltYWdlID8gY29udGV4dC5pbWFnZS5faW5mb0xpc3QgOiBbXTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIFxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBHZXRzIHVwbG9hZGVkIGZpbGVzKHBsdWdpbiB1c2luZyBmaWxlTWFuYWdlcikgaW5mb3JtYXRpb24gbGlzdC5cclxuICAgICAgICAgKiBpbWFnZTogW2ltZ10sIHZpZGVvOiBbdmlkZW8sIGlmcmFtZV0sIGF1ZGlvOiBbYXVkaW9dXHJcbiAgICAgICAgICogV2hlbiB0aGUgYXJndW1lbnQgdmFsdWUgaXMgJ2ltYWdlJywgaXQgaXMgdGhlIHNhbWUgZnVuY3Rpb24gYXMgXCJnZXRJbWFnZXNJbmZvXCIuXHJcbiAgICAgICAgICogLSBpbmRleDogZGF0YSBpbmRleFxyXG4gICAgICAgICAqIC0gbmFtZTogZmlsZSBuYW1lXHJcbiAgICAgICAgICogLSBzaXplOiBmaWxlIHNpemVcclxuICAgICAgICAgKiAtIHNlbGVjdDogc2VsZWN0IGZ1bmN0aW9uXHJcbiAgICAgICAgICogLSBkZWxldGU6IGRlbGV0ZSBmdW5jdGlvblxyXG4gICAgICAgICAqIC0gZWxlbWVudDogdGFyZ2V0IGVsZW1lbnRcclxuICAgICAgICAgKiAtIHNyYzogc3JjIGF0dHJpYnV0ZSBvZiB0YWdcclxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gcGx1Z2luTmFtZSBQbHVnaW4gbmFtZSAoaW1hZ2UsIHZpZGVvLCBhdWRpbylcclxuICAgICAgICAgKiBAcmV0dXJucyB7QXJyYXl9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0RmlsZXNJbmZvOiBmdW5jdGlvbiAocGx1Z2luTmFtZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gY29udGV4dFtwbHVnaW5OYW1lXSA/IGNvbnRleHRbcGx1Z2luTmFtZV0uX2luZm9MaXN0IDogW107XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFVwbG9hZCBpbWFnZXMgdXNpbmcgaW1hZ2UgcGx1Z2luXHJcbiAgICAgICAgICogQHBhcmFtIHtGaWxlTGlzdH0gZmlsZXMgRmlsZUxpc3RcclxuICAgICAgICAgKi9cclxuICAgICAgICBpbnNlcnRJbWFnZTogZnVuY3Rpb24gKGZpbGVzKSB7XHJcbiAgICAgICAgICAgIGlmICghY29yZS5wbHVnaW5zLmltYWdlIHx8ICFmaWxlcykgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFjb3JlLmluaXRQbHVnaW5zLmltYWdlKSBjb3JlLmNhbGxQbHVnaW4oJ2ltYWdlJywgY29yZS5wbHVnaW5zLmltYWdlLnN1Ym1pdEFjdGlvbi5iaW5kKGNvcmUsIGZpbGVzKSwgbnVsbCk7XHJcbiAgICAgICAgICAgIGVsc2UgY29yZS5wbHVnaW5zLmltYWdlLnN1Ym1pdEFjdGlvbi5jYWxsKGNvcmUsIGZpbGVzKTtcclxuICAgICAgICAgICAgY29yZS5mb2N1cygpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBJbnNlcnRzIGFuIEhUTUwgZWxlbWVudCBvciBIVE1MIHN0cmluZyBvciBwbGFpbiBzdHJpbmcgYXQgdGhlIGN1cnJlbnQgY3Vyc29yIHBvc2l0aW9uXHJcbiAgICAgICAgICogQHBhcmFtIHtFbGVtZW50fFN0cmluZ30gaHRtbCBIVE1MIEVsZW1lbnQgb3IgSFRNTCBzdHJpbmcgb3IgcGxhaW4gc3RyaW5nXHJcbiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSBub3RDbGVhbmluZ0RhdGEgSWYgdHJ1ZSwgaW5zZXJ0cyB0aGUgSFRNTCBzdHJpbmcgd2l0aG91dCByZWZpbmluZyBpdCB3aXRoIGNvcmUuY2xlYW5IVE1MLlxyXG4gICAgICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gY2hlY2tDaGFyQ291bnQgSWYgdHJ1ZSwgaWYgXCJvcHRpb25zLm1heENoYXJDb3VudFwiIGlzIGV4Y2VlZGVkIHdoZW4gXCJlbGVtZW50XCIgaXMgYWRkZWQsIG51bGwgaXMgcmV0dXJuZWQgd2l0aG91dCBhZGRpdGlvbi5cclxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJhbmdlU2VsZWN0aW9uIElmIHRydWUsIHJhbmdlIHNlbGVjdCB0aGUgaW5zZXJ0ZWQgbm9kZS5cclxuICAgICAgICAgKi9cclxuICAgICAgICBpbnNlcnRIVE1MOiBmdW5jdGlvbiAoaHRtbCwgbm90Q2xlYW5pbmdEYXRhLCBjaGVja0NoYXJDb3VudCwgcmFuZ2VTZWxlY3Rpb24pIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBodG1sID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFub3RDbGVhbmluZ0RhdGEpIGh0bWwgPSBjb3JlLmNsZWFuSFRNTChodG1sLCBudWxsKTtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZG9tID0gX2QuY3JlYXRlUmFuZ2UoKS5jcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQoaHRtbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZG9tVHJlZSA9IGRvbS5jaGlsZE5vZGVzO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2hlY2tDaGFyQ291bnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZSA9IGNvcmUuX2NoYXJUeXBlSFRNTCA/ICdvdXRlckhUTUwnIDogJ3RleHRDb250ZW50JztcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNoZWNrSFRNTCA9ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gZG9tVHJlZS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tIVE1MICs9IGRvbVRyZWVbaV1bdHlwZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjb3JlLmNoZWNrQ2hhckNvdW50KGNoZWNrSFRNTCwgbnVsbCkpIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBjLCBhLCB0LCBmaXJzdENvbjtcclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGMgPSBkb21UcmVlWzBdKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ID0gY29yZS5pbnNlcnROb2RlKGMsIGEsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYSA9IHQuY29udGFpbmVyIHx8IHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmlyc3RDb24pIGZpcnN0Q29uID0gdDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9IGEubm9kZVR5cGUgPT09IDMgPyAodC5lbmRPZmZzZXQgfHwgYS50ZXh0Q29udGVudC5sZW5ndGgpOiBhLmNoaWxkTm9kZXMubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyYW5nZVNlbGVjdGlvbikgY29yZS5zZXRSYW5nZShmaXJzdENvbi5jb250YWluZXIgfHwgZmlyc3RDb24sIGZpcnN0Q29uLnN0YXJ0T2Zmc2V0IHx8IDAsIGEsIG9mZnNldCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBjb3JlLnNldFJhbmdlKGEsIG9mZnNldCwgYSwgb2Zmc2V0KTtcclxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29yZS5leGVjQ29tbWFuZCgnaW5zZXJ0SFRNTCcsIGZhbHNlLCBodG1sKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmICh1dGlsLmlzQ29tcG9uZW50KGh0bWwpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29yZS5pbnNlcnRDb21wb25lbnQoaHRtbCwgZmFsc2UsIGNoZWNrQ2hhckNvdW50LCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBhZnRlck5vZGUgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh1dGlsLmlzRm9ybWF0RWxlbWVudChodG1sKSB8fCB1dGlsLmlzTWVkaWEoaHRtbCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXJOb2RlID0gdXRpbC5nZXRGb3JtYXRFbGVtZW50KGNvcmUuZ2V0U2VsZWN0aW9uTm9kZSgpLCBudWxsKTtcdFxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjb3JlLmluc2VydE5vZGUoaHRtbCwgYWZ0ZXJOb2RlLCBjaGVja0NoYXJDb3VudCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGNvcmUuZWZmZWN0Tm9kZSA9IG51bGw7XHJcbiAgICAgICAgICAgIGNvcmUuZm9jdXMoKTtcclxuXHJcbiAgICAgICAgICAgIC8vIGhpc3Rvcnkgc3RhY2tcclxuICAgICAgICAgICAgY29yZS5oaXN0b3J5LnB1c2goZmFsc2UpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDaGFuZ2UgdGhlIGNvbnRlbnRzIG9mIHRoZSBzdW5lZGl0b3JcclxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ3x1bmRlZmluZWR9IGNvbnRlbnRzIENvbnRlbnRzIHRvIElucHV0XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgc2V0Q29udGVudHM6IGZ1bmN0aW9uIChjb250ZW50cykge1xyXG4gICAgICAgICAgICBjb3JlLnNldENvbnRlbnRzKGNvbnRlbnRzKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQWRkIGNvbnRlbnRzIHRvIHRoZSBzdW5lZGl0b3JcclxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gY29udGVudHMgQ29udGVudHMgdG8gSW5wdXRcclxuICAgICAgICAgKi9cclxuICAgICAgICBhcHBlbmRDb250ZW50czogZnVuY3Rpb24gKGNvbnRlbnRzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnZlcnRWYWx1ZSA9IGNvcmUuY29udmVydENvbnRlbnRzRm9yRWRpdG9yKGNvbnRlbnRzKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGlmICghY29yZS5fdmFyaWFibGUuaXNDb2RlVmlldykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdGVtcCA9IHV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XHJcbiAgICAgICAgICAgICAgICB0ZW1wLmlubmVySFRNTCA9IGNvbnZlcnRWYWx1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCB3eXNpd3lnID0gY29udGV4dC5lbGVtZW50Lnd5c2l3eWc7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IHRlbXAuY2hpbGRyZW47XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICB3eXNpd3lnLmFwcGVuZENoaWxkKGNoaWxkcmVuW2ldKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvcmUuX3NldENvZGVWaWV3KGNvcmUuX2dldENvZGVWaWV3KCkgKyAnXFxuJyArIGNvcmUuY29udmVydEhUTUxGb3JDb2RlVmlldyhjb252ZXJ0VmFsdWUpKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gaGlzdG9yeSBzdGFja1xyXG4gICAgICAgICAgICBjb3JlLmhpc3RvcnkucHVzaChmYWxzZSk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIERpc2FibGUgdGhlIHN1bmVkaXRvclxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGRpc2FibGVkOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnRleHQudG9vbC5jb3Zlci5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50Lnd5c2l3eWcuc2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGNvcmUuaXNEaXNhYmxlZCA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5jb2RlTWlycm9yRWRpdG9yKSB7XHJcbiAgICAgICAgICAgICAgICBvcHRpb25zLmNvZGVNaXJyb3JFZGl0b3Iuc2V0T3B0aW9uKCdyZWFkT25seScsIHRydWUpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LmNvZGUuc2V0QXR0cmlidXRlKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEVuYWJsZSB0aGUgc3VuZWRpdG9yXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZW5hYmxlZDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjb250ZXh0LnRvb2wuY292ZXIuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50Lnd5c2l3eWcuc2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnLCB0cnVlKTtcclxuICAgICAgICAgICAgY29yZS5pc0Rpc2FibGVkID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5jb2RlTWlycm9yRWRpdG9yKSB7XHJcbiAgICAgICAgICAgICAgICBvcHRpb25zLmNvZGVNaXJyb3JFZGl0b3Iuc2V0T3B0aW9uKCdyZWFkT25seScsIGZhbHNlKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5jb2RlLnJlbW92ZUF0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBTaG93IHRoZSBzdW5lZGl0b3JcclxuICAgICAgICAgKi9cclxuICAgICAgICBzaG93OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRvcEFyZWFTdHlsZSA9IGNvbnRleHQuZWxlbWVudC50b3BBcmVhLnN0eWxlO1xyXG4gICAgICAgICAgICBpZiAodG9wQXJlYVN0eWxlLmRpc3BsYXkgPT09ICdub25lJykgdG9wQXJlYVN0eWxlLmRpc3BsYXkgPSBvcHRpb25zLmRpc3BsYXk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEhpZGUgdGhlIHN1bmVkaXRvclxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGhpZGU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LnRvcEFyZWEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gRGVzdHJveSB0aGUgc3VuZWRpdG9yXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvKiogb2ZmIG1lbnVzICovXHJcbiAgICAgICAgICAgIGNvcmUuc3VibWVudU9mZigpO1xyXG4gICAgICAgICAgICBjb3JlLmNvbnRhaW5lck9mZigpO1xyXG4gICAgICAgICAgICBjb3JlLmNvbnRyb2xsZXJzT2ZmKCk7XHJcbiAgICAgICAgICAgIGlmIChjb3JlLm5vdGljZSkgY29yZS5ub3RpY2UuY2xvc2UuY2FsbChjb3JlKTtcclxuICAgICAgICAgICAgaWYgKGNvcmUubW9kYWxGb3JtKSBjb3JlLnBsdWdpbnMuZGlhbG9nLmNsb3NlLmNhbGwoY29yZSk7XHJcblxyXG4gICAgICAgICAgICAvKiogcmVtb3ZlIGhpc3RvcnkgKi9cclxuICAgICAgICAgICAgY29yZS5oaXN0b3J5Ll9kZXN0cm95KCk7XHJcblxyXG4gICAgICAgICAgICAvKiogcmVtb3ZlIGV2ZW50IGxpc3RlbmVycyAqL1xyXG4gICAgICAgICAgICBldmVudC5fcmVtb3ZlRXZlbnQoKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIC8qKiByZW1vdmUgZWxlbWVudCAqL1xyXG4gICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW0oY29udGV4dC5lbGVtZW50LnRvb2xiYXIpO1xyXG4gICAgICAgICAgICB1dGlsLnJlbW92ZUl0ZW0oY29udGV4dC5lbGVtZW50LnRvcEFyZWEpO1xyXG5cclxuICAgICAgICAgICAgLyoqIHJlbW92ZSBvYmplY3QgcmVmZXJlbmNlICovXHJcbiAgICAgICAgICAgIGZvciAobGV0IGsgaW4gY29yZSkgeyBpZiAodXRpbC5oYXNPd24oY29yZSwgaykpIGRlbGV0ZSBjb3JlW2tdOyB9XHJcbiAgICAgICAgICAgIGZvciAobGV0IGsgaW4gZXZlbnQpIHsgaWYgKHV0aWwuaGFzT3duKGV2ZW50LCBrKSkgZGVsZXRlIGV2ZW50W2tdOyB9XHJcbiAgICAgICAgICAgIGZvciAobGV0IGsgaW4gY29udGV4dCkgeyBpZiAodXRpbC5oYXNPd24oY29udGV4dCwgaykpIGRlbGV0ZSBjb250ZXh0W2tdOyB9XHJcbiAgICAgICAgICAgIGZvciAobGV0IGsgaW4gcGx1Z2luQ2FsbEJ1dHRvbnMpIHsgaWYgKHV0aWwuaGFzT3duKHBsdWdpbkNhbGxCdXR0b25zLCBrKSkgZGVsZXRlIHBsdWdpbkNhbGxCdXR0b25zW2tdOyB9XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvKiogcmVtb3ZlIHVzZXIgb2JqZWN0ICovXHJcbiAgICAgICAgICAgIGZvciAobGV0IGsgaW4gdGhpcykgeyBpZiAodXRpbC5oYXNPd24odGhpcywgaykpIGRlbGV0ZSB0aGlzW2tdOyB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFRvb2xiYXIgbWV0aG9kc1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRvb2xiYXI6IHtcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEBkZXNjcmlwdGlvbiBEaXNhYmxlIHRoZSB0b29sYmFyXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBkaXNhYmxlZDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC50b29sLmNvdmVyLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG4gICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEBkZXNjcmlwdGlvbiBFbmFibGUgdGhlIHRvb2xiYXJcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGVuYWJsZWQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRleHQudG9vbC5jb3Zlci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEBkZXNjcmlwdGlvbiBTaG93IHRoZSB0b29sYmFyXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBzaG93OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29yZS5faXNJbmxpbmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBldmVudC5fc2hvd1Rvb2xiYXJJbmxpbmUoKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LnRvb2xiYXIuc3R5bGUuZGlzcGxheSA9ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5fc3RpY2t5RHVtbXkuc3R5bGUuZGlzcGxheSA9ICcnO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEBkZXNjcmlwdGlvbiBIaWRlIHRoZSB0b29sYmFyXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBoaWRlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29yZS5faXNJbmxpbmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBldmVudC5faGlkZVRvb2xiYXIoKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5lbGVtZW50LnRvb2xiYXIuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmVsZW1lbnQuX3N0aWNreUR1bW15LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvKioqKioqKioqKioqIENvcmUgaW5pdCAqKioqKioqKioqKiovXHJcbiAgICAvLyBmdW5jdGlvbnNcclxuICAgIGNvcmUuZnVuY3Rpb25zID0gZnVuY3Rpb25zO1xyXG5cclxuICAgIC8vIENyZWF0ZSB0byBzaWJsaW5nIG5vZGVcclxuICAgIGxldCBjb250ZXh0RWwgPSBjb250ZXh0LmVsZW1lbnQ7XHJcbiAgICBsZXQgb3JpZ2luRWwgPSBjb250ZXh0RWwub3JpZ2luRWxlbWVudDtcclxuICAgIGxldCB0b3BFbCA9IGNvbnRleHRFbC50b3BBcmVhO1xyXG4gICAgb3JpZ2luRWwuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgIHRvcEVsLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG5cclxuICAgIC8vIGluaXRcclxuICAgIGlmIChvcHRpb25zLmlmcmFtZSkge1xyXG4gICAgICAgIGNvbnRleHRFbC53eXNpd3lnRnJhbWUuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdXRpbC5fc2V0SWZyYW1lRG9jdW1lbnQodGhpcywgb3B0aW9ucyk7XHJcbiAgICAgICAgICAgIGNvcmUuX2VkaXRvckluaXQoZmFsc2UsIG9wdGlvbnMudmFsdWUpO1xyXG4gICAgICAgICAgICBvcHRpb25zLnZhbHVlID0gbnVsbDtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBpbnNlcnQgZWRpdG9yIGVsZW1lbnRcclxuICAgIGlmICh0eXBlb2Ygb3JpZ2luRWwubmV4dEVsZW1lbnRTaWJsaW5nID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgIG9yaWdpbkVsLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHRvcEVsLCBvcmlnaW5FbC5uZXh0RWxlbWVudFNpYmxpbmcpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICBvcmlnaW5FbC5wYXJlbnROb2RlLmFwcGVuZENoaWxkKHRvcEVsKTtcclxuICAgIH1cclxuXHJcbiAgICBjb250ZXh0RWwuZWRpdG9yQXJlYS5hcHBlbmRDaGlsZChjb250ZXh0RWwud3lzaXd5Z0ZyYW1lKTtcclxuICAgIGNvbnRleHRFbCA9IG9yaWdpbkVsID0gdG9wRWwgPSBudWxsO1xyXG5cclxuICAgIC8vIGluaXRcclxuICAgIGlmICghb3B0aW9ucy5pZnJhbWUpIHtcclxuICAgICAgICBjb3JlLl9lZGl0b3JJbml0KGZhbHNlLCBvcHRpb25zLnZhbHVlKTtcclxuICAgICAgICBvcHRpb25zLnZhbHVlID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZnVuY3Rpb25zO1xyXG59IiwiLypcbiAqIHd5c2l3eWcgd2ViIGVkaXRvclxuICpcbiAqIHN1bmVkaXRvci5qc1xuICogQ29weXJpZ2h0IDIwMTkgSmlIb25nIExlZS5cbiAqIE1JVCBsaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChjb3JlLCBjaGFuZ2UpIHtcbiAgICBjb25zdCBfdyA9IGNvcmUuX3c7XG4gICAgY29uc3QgdXRpbCA9IGNvcmUudXRpbDtcbiAgICBjb25zdCBkZWxheVRpbWUgPSBjb3JlLmNvbnRleHQub3B0aW9ucy5oaXN0b3J5U3RhY2tEZWxheVRpbWU7XG4gICAgbGV0IGVkaXRvciA9IGNvcmUuY29udGV4dC5lbGVtZW50O1xuICAgIGxldCB1bmRvID0gY29yZS5jb250ZXh0LnRvb2wudW5kbztcbiAgICBsZXQgcmVkbyA9IGNvcmUuY29udGV4dC50b29sLnJlZG87XG5cbiAgICBsZXQgcHVzaERlbGF5ID0gbnVsbDtcbiAgICBsZXQgc3RhY2tJbmRleCA9IDA7XG4gICAgbGV0IHN0YWNrID0gW107XG5cbiAgICBmdW5jdGlvbiBzZXRDb250ZW50c0Zyb21TdGFjayAoKSB7XG4gICAgICAgIGNvbnN0IGl0ZW0gPSBzdGFja1tzdGFja0luZGV4XTtcbiAgICAgICAgZWRpdG9yLnd5c2l3eWcuaW5uZXJIVE1MID0gaXRlbS5jb250ZW50cztcblxuICAgICAgICBjb3JlLnNldFJhbmdlKHV0aWwuZ2V0Tm9kZUZyb21QYXRoKGl0ZW0ucy5wYXRoLCBlZGl0b3Iud3lzaXd5ZyksIGl0ZW0ucy5vZmZzZXQsIHV0aWwuZ2V0Tm9kZUZyb21QYXRoKGl0ZW0uZS5wYXRoLCBlZGl0b3Iud3lzaXd5ZyksIGl0ZW0uZS5vZmZzZXQpO1xuICAgICAgICBjb3JlLmZvY3VzKCk7XG5cbiAgICAgICAgaWYgKHN0YWNrSW5kZXggPT09IDApIHtcbiAgICAgICAgICAgIGlmICh1bmRvKSB1bmRvLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgICAgIGlmIChyZWRvKSByZWRvLnJlbW92ZUF0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgICAgICAgfSBlbHNlIGlmIChzdGFja0luZGV4ID09PSBzdGFjay5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICBpZiAodW5kbykgdW5kby5yZW1vdmVBdHRyaWJ1dGUoJ2Rpc2FibGVkJyk7XG4gICAgICAgICAgICBpZiAocmVkbykgcmVkby5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodW5kbykgdW5kby5yZW1vdmVBdHRyaWJ1dGUoJ2Rpc2FibGVkJyk7XG4gICAgICAgICAgICBpZiAocmVkbykgcmVkby5yZW1vdmVBdHRyaWJ1dGUoJ2Rpc2FibGVkJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb3JlLmNvbnRyb2xsZXJzT2ZmKCk7XG4gICAgICAgIGNvcmUuX2NoZWNrQ29tcG9uZW50cygpO1xuICAgICAgICBjb3JlLl9zZXRDaGFyQ291bnQoKTtcbiAgICAgICAgY29yZS5fcmVzb3VyY2VzU3RhdGVDaGFuZ2UoKTtcbiAgICAgICAgXG4gICAgICAgIC8vIG9uQ2hhbmdlXG4gICAgICAgIGNoYW5nZSgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHB1c2hTdGFjayAoKSB7XG4gICAgICAgIGNvcmUuX2NoZWNrQ29tcG9uZW50cygpO1xuICAgICAgICBjb25zdCBjdXJyZW50ID0gY29yZS5nZXRDb250ZW50cyh0cnVlKTtcbiAgICAgICAgaWYgKCFjdXJyZW50IHx8ICghIXN0YWNrW3N0YWNrSW5kZXhdICYmIGN1cnJlbnQgPT09IHN0YWNrW3N0YWNrSW5kZXhdLmNvbnRlbnRzKSkgcmV0dXJuO1xuXG4gICAgICAgIHN0YWNrSW5kZXgrKztcbiAgICAgICAgY29uc3QgcmFuZ2UgPSBjb3JlLl92YXJpYWJsZS5fcmFuZ2U7XG5cbiAgICAgICAgaWYgKHN0YWNrLmxlbmd0aCA+IHN0YWNrSW5kZXgpIHtcbiAgICAgICAgICAgIHN0YWNrID0gc3RhY2suc2xpY2UoMCwgc3RhY2tJbmRleCk7XG4gICAgICAgICAgICBpZiAocmVkbykgcmVkby5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXJhbmdlKSB7XG4gICAgICAgICAgICBzdGFja1tzdGFja0luZGV4XSA9IHtcbiAgICAgICAgICAgICAgICBjb250ZW50czogY3VycmVudCxcbiAgICAgICAgICAgICAgICBzOiB7IHBhdGg6IFswLCAwXSwgb2Zmc2V0OiBbMCwgMF0gfSxcbiAgICAgICAgICAgICAgICBlOiB7IHBhdGg6IDAsIG9mZnNldDogMCB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RhY2tbc3RhY2tJbmRleF0gPSB7XG4gICAgICAgICAgICAgICAgY29udGVudHM6IGN1cnJlbnQsXG4gICAgICAgICAgICAgICAgczoge1xuICAgICAgICAgICAgICAgICAgICBwYXRoOiB1dGlsLmdldE5vZGVQYXRoKHJhbmdlLnN0YXJ0Q29udGFpbmVyLCBudWxsLCBudWxsKSxcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiByYW5nZS5zdGFydE9mZnNldFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZToge1xuICAgICAgICAgICAgICAgICAgICBwYXRoOiB1dGlsLmdldE5vZGVQYXRoKHJhbmdlLmVuZENvbnRhaW5lciwgbnVsbCwgbnVsbCksXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogcmFuZ2UuZW5kT2Zmc2V0XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdGFja0luZGV4ID09PSAxICYmIHVuZG8pIHVuZG8ucmVtb3ZlQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xuXG4gICAgICAgIGNvcmUuX3NldENoYXJDb3VudCgpO1xuICAgICAgICAvLyBvbkNoYW5nZVxuICAgICAgICBjaGFuZ2UoKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEhpc3Rvcnkgc3RhY2tcbiAgICAgICAgICovXG4gICAgICAgIHN0YWNrOiBzdGFjayxcblxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFNhdmluZyB0aGUgY3VycmVudCBzdGF0dXMgdG8gdGhlIGhpc3Rvcnkgb2JqZWN0IHN0YWNrXG4gICAgICAgICAqIElmIFwiZGVsYXlcIiBpcyB0cnVlLCBpdCB3aWxsIGJlIHNhdmVkIGFmdGVyIChvcHRpb25zLmhpc3RvcnlTdGFja0RlbGF5VGltZSB8fCA0MDApIG1pbGlzZWNvbmRzXG4gICAgICAgICAqIElmIHRoZSBmdW5jdGlvbiBpcyBjYWxsZWQgYWdhaW4gd2l0aCB0aGUgXCJkZWxheVwiIGFyZ3VtZW50IHRydWUgYmVmb3JlIGl0IGlzIHNhdmVkLCB0aGUgZGVsYXkgdGltZSBpcyByZW5ld2FsXG4gICAgICAgICAqIFlvdSBjYW4gc3BlY2lmeSB0aGUgZGVsYXkgdGltZSBieSBzZW5kaW5nIGEgbnVtYmVyLlxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW58TnVtYmVyfSBkZWxheSBJZiB0cnVlLCBBZGQgc3RhY2sgd2l0aG91dCBkZWxheSB0aW1lLlxuICAgICAgICAgKi9cbiAgICAgICAgcHVzaDogZnVuY3Rpb24gKGRlbGF5KSB7XG4gICAgICAgICAgICBfdy5zZXRUaW1lb3V0KGNvcmUuX3Jlc291cmNlc1N0YXRlQ2hhbmdlLmJpbmQoY29yZSkpO1xuICAgICAgICAgICAgY29uc3QgdGltZSA9IHR5cGVvZiBkZWxheSA9PT0gJ251bWJlcicgPyAoZGVsYXkgPiAwID8gZGVsYXkgOiAwKSA6ICghZGVsYXkgPyAwIDogZGVsYXlUaW1lKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgKCF0aW1lIHx8IHB1c2hEZWxheSkge1xuICAgICAgICAgICAgICAgIF93LmNsZWFyVGltZW91dChwdXNoRGVsYXkpO1xuICAgICAgICAgICAgICAgIGlmICghdGltZSkge1xuICAgICAgICAgICAgICAgICAgICBwdXNoU3RhY2soKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcHVzaERlbGF5ID0gX3cuc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3cuY2xlYXJUaW1lb3V0KHB1c2hEZWxheSk7XG4gICAgICAgICAgICAgICAgcHVzaERlbGF5ID0gbnVsbDtcbiAgICAgICAgICAgICAgICBwdXNoU3RhY2soKTtcbiAgICAgICAgICAgIH0sIHRpbWUpO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gVW5kbyBmdW5jdGlvblxuICAgICAgICAgKi9cbiAgICAgICAgdW5kbzogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKHN0YWNrSW5kZXggPiAwKSB7XG4gICAgICAgICAgICAgICAgc3RhY2tJbmRleC0tO1xuICAgICAgICAgICAgICAgIHNldENvbnRlbnRzRnJvbVN0YWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBSZWRvIGZ1bmN0aW9uXG4gICAgICAgICAqL1xuICAgICAgICByZWRvOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoc3RhY2subGVuZ3RoIC0gMSA+IHN0YWNrSW5kZXgpIHtcbiAgICAgICAgICAgICAgICBzdGFja0luZGV4Kys7XG4gICAgICAgICAgICAgICAgc2V0Q29udGVudHNGcm9tU3RhY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEdvIHRvIHRoZSBoaXN0b3J5IHN0YWNrIGZvciB0aGF0IGluZGV4LlxuICAgICAgICAgKiBJZiBcImluZGV4XCIgaXMgLTEsIGdvIHRvIHRoZSBsYXN0IHN0YWNrXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleCBTdGFjayBpbmRleFxuICAgICAgICAgKi9cbiAgICAgICAgZ286IGZ1bmN0aW9uIChpbmRleCkge1xuICAgICAgICAgICAgc3RhY2tJbmRleCA9IGluZGV4IDwgMCA/IChzdGFjay5sZW5ndGggLSAxKSA6IGluZGV4O1xuICAgICAgICAgICAgc2V0Q29udGVudHNGcm9tU3RhY2soKTtcbiAgICAgICAgfSxcbiAgICAgICAgXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gUmVzZXQgdGhlIGhpc3Rvcnkgb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICByZXNldDogZnVuY3Rpb24gKGlnbm9yZUNoYW5nZUV2ZW50KSB7XG4gICAgICAgICAgICBpZiAodW5kbykgdW5kby5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgICAgICBpZiAocmVkbykgcmVkby5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgICAgICBpZiAoY29yZS5jb250ZXh0LnRvb2wuc2F2ZSkgY29yZS5jb250ZXh0LnRvb2wuc2F2ZS5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHN0YWNrLnNwbGljZSgwKTtcbiAgICAgICAgICAgIHN0YWNrSW5kZXggPSAwO1xuXG4gICAgICAgICAgICAvLyBwdXNoU3RhY2tcbiAgICAgICAgICAgIHN0YWNrW3N0YWNrSW5kZXhdID0ge1xuICAgICAgICAgICAgICAgIGNvbnRlbnRzOiBjb3JlLmdldENvbnRlbnRzKHRydWUpLFxuICAgICAgICAgICAgICAgIHM6IHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogWzAsIDBdLFxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IDBcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGU6IHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogWzAsIDBdLFxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IDBcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAoIWlnbm9yZUNoYW5nZUV2ZW50KSBjaGFuZ2UoKTtcbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFJlc2V0IHRoZSBkaXNhYmxlZCBzdGF0ZSBvZiB0aGUgYnV0dG9ucyB0byBmaXQgdGhlIGN1cnJlbnQgc3RhY2suXG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICBfcmVzZXRDYWNoaW5nQnV0dG9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBlZGl0b3IgPSBjb3JlLmNvbnRleHQuZWxlbWVudDtcbiAgICAgICAgICAgIHVuZG8gPSBjb3JlLmNvbnRleHQudG9vbC51bmRvO1xuICAgICAgICAgICAgcmVkbyA9IGNvcmUuY29udGV4dC50b29sLnJlZG87XG5cbiAgICAgICAgICAgIGlmIChzdGFja0luZGV4ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKHVuZG8pIHVuZG8uc2V0QXR0cmlidXRlKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgICAgICAgICAgIGlmIChyZWRvICYmIHN0YWNrSW5kZXggPT09IHN0YWNrLmxlbmd0aCAtIDEpIHJlZG8uc2V0QXR0cmlidXRlKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgICAgICAgICAgIGlmIChjb3JlLmNvbnRleHQudG9vbC5zYXZlKSBjb3JlLmNvbnRleHQudG9vbC5zYXZlLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhY2tJbmRleCA9PT0gc3RhY2subGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgIGlmIChyZWRvKSByZWRvLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFJlbW92ZSBhbGwgc3RhY2tzIGFuZCByZW1vdmUgdGhlIHRpbWVvdXQgZnVuY3Rpb24uXG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICBfZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKHB1c2hEZWxheSkgX3cuY2xlYXJUaW1lb3V0KHB1c2hEZWxheSk7XG4gICAgICAgICAgICBzdGFjayA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9O1xufSIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0ICcuL2Fzc2V0cy9jc3Mvc3VuZWRpdG9yLmNzcyc7XG5pbXBvcnQgJy4vYXNzZXRzL2Nzcy9zdW5lZGl0b3ItY29udGVudHMuY3NzJztcblxuaW1wb3J0IHBsdWdpbnMgZnJvbSAnLi9wbHVnaW5zJztcbmltcG9ydCBzdW5lZGl0b3IgZnJvbSAnLi9zdW5lZGl0b3InO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LCAnU1VORURJVE9SJywge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IHN1bmVkaXRvci5pbml0KHtcbiAgICAgICAgcGx1Z2luczogcGx1Z2luc1xuICAgIH0pXG59KTsiLCIvKlxuICogd3lzaXd5ZyB3ZWIgZWRpdG9yXG4gKlxuICogc3VuZWRpdG9yLmpzXG4gKiBDb3B5cmlnaHQgMjAxNyBKaUhvbmcgTGVlLlxuICogTUlUIGxpY2Vuc2UuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgICBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZS5leHBvcnRzID09PSAnb2JqZWN0Jykge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGdsb2JhbC5kb2N1bWVudCA/XG4gICAgICAgICAgICBmYWN0b3J5KGdsb2JhbCwgdHJ1ZSkgOlxuICAgICAgICAgICAgZnVuY3Rpb24gKHcpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXcuZG9jdW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTVU5FRElUT1JfTU9EVUxFUyBhIHdpbmRvdyB3aXRoIGEgZG9jdW1lbnQnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhY3Rvcnkodyk7XG4gICAgICAgICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGZhY3RvcnkoZ2xvYmFsKTtcbiAgICB9XG59KHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdGhpcywgZnVuY3Rpb24gKHdpbmRvdywgbm9HbG9iYWwpIHtcbiAgICBjb25zdCBjb21wb25lbnQgPSB7XG4gICAgICAgIG5hbWU6ICdjb21wb25lbnQnLFxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIENyZWF0ZSBhIGNvbnRhaW5lciBmb3IgdGhlIHJlc2l6aW5nIGNvbXBvbmVudCBhbmQgaW5zZXJ0IHRoZSBlbGVtZW50LlxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGNvdmVyIENvdmVyIGVsZW1lbnQgKEZJR1VSRSlcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGNsYXNzTmFtZSBDbGFzcyBuYW1lIG9mIGNvbnRhaW5lciAoZml4ZWQ6IHNlLWNvbXBvbmVudClcbiAgICAgICAgICogQHJldHVybnMge0VsZW1lbnR9IENyZWF0ZWQgY29udGFpbmVyIGVsZW1lbnRcbiAgICAgICAgICovXG4gICAgICAgIHNldF9jb250YWluZXI6IGZ1bmN0aW9uIChjb3ZlciwgY2xhc3NOYW1lKSB7XG4gICAgICAgICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XG4gICAgICAgICAgICBjb250YWluZXIuY2xhc3NOYW1lID0gJ3NlLWNvbXBvbmVudCAnICsgY2xhc3NOYW1lO1xuICAgICAgICAgICAgY29udGFpbmVyLnNldEF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJywgZmFsc2UpO1xuICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGNvdmVyKTtcbiAgICBcbiAgICAgICAgICAgIHJldHVybiBjb250YWluZXI7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDb3ZlciB0aGUgdGFyZ2V0IGVsZW1lbnQgd2l0aCBhIEZJR1VSRSBlbGVtZW50LlxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgVGFyZ2V0IGVsZW1lbnRcbiAgICAgICAgICovXG4gICAgICAgIHNldF9jb3ZlcjogZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvdmVyID0gdGhpcy51dGlsLmNyZWF0ZUVsZW1lbnQoJ0ZJR1VSRScpO1xuICAgICAgICAgICAgY292ZXIuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG4gICAgXG4gICAgICAgICAgICByZXR1cm4gY292ZXI7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBSZXR1cm4gSFRNTCBzdHJpbmcgb2YgY2FwdGlvbihGSUdDQVBUSU9OKSBlbGVtZW50XG4gICAgICAgICAqIEByZXR1cm5zIHtTdHJpbmd9XG4gICAgICAgICAqL1xuICAgICAgICBjcmVhdGVfY2FwdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgY2FwdGlvbiA9IHRoaXMudXRpbC5jcmVhdGVFbGVtZW50KCdGSUdDQVBUSU9OJyk7XG4gICAgICAgICAgICBjYXB0aW9uLnNldEF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJywgdHJ1ZSk7XG4gICAgICAgICAgICBjYXB0aW9uLmlubmVySFRNTCA9ICc8ZGl2PicgKyB0aGlzLmxhbmcuZGlhbG9nQm94LmNhcHRpb24gKyAnPC9kaXY+JztcbiAgICAgICAgICAgIHJldHVybiBjYXB0aW9uO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGlmICh0eXBlb2Ygbm9HbG9iYWwgPT09IHR5cGVvZiB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCF3aW5kb3cuU1VORURJVE9SX01PRFVMRVMpIHtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3csICdTVU5FRElUT1JfTU9EVUxFUycsIHtcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB7fVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LlNVTkVESVRPUl9NT0RVTEVTLCAnY29tcG9uZW50Jywge1xuICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICB2YWx1ZTogY29tcG9uZW50XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBjb21wb25lbnQ7XG59KSk7IiwiLypcbiAqIHd5c2l3eWcgd2ViIGVkaXRvclxuICpcbiAqIHN1bmVkaXRvci5qc1xuICogQ29weXJpZ2h0IDIwMTcgSmlIb25nIExlZS5cbiAqIE1JVCBsaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gICAgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBnbG9iYWwuZG9jdW1lbnQgP1xuICAgICAgICAgICAgZmFjdG9yeShnbG9iYWwsIHRydWUpIDpcbiAgICAgICAgICAgIGZ1bmN0aW9uICh3KSB7XG4gICAgICAgICAgICAgICAgaWYgKCF3LmRvY3VtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU1VORURJVE9SX01PRFVMRVMgYSB3aW5kb3cgd2l0aCBhIGRvY3VtZW50Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWN0b3J5KHcpO1xuICAgICAgICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBmYWN0b3J5KGdsb2JhbCk7XG4gICAgfVxufSh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHRoaXMsIGZ1bmN0aW9uICh3aW5kb3csIG5vR2xvYmFsKSB7XG4gICAgY29uc3QgcmVzaXppbmcgPSB7XG4gICAgICAgIG5hbWU6ICdyZXNpemluZycsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ29uc3RydWN0b3JcbiAgICAgICAgICogUmVxdWlyZSBjb250ZXh0IHByb3BlcnRpZXMgd2hlbiByZXNpemluZyBtb2R1bGVcbiAgICAgICAgICAgIGlucHV0WDogRWxlbWVudCxcbiAgICAgICAgICAgIGlucHV0WTogRWxlbWVudCxcbiAgICAgICAgICAgIF9jb250YWluZXI6IG51bGwsXG4gICAgICAgICAgICBfY292ZXI6IG51bGwsXG4gICAgICAgICAgICBfZWxlbWVudDogbnVsbCxcbiAgICAgICAgICAgIF9lbGVtZW50X3c6IDEsXG4gICAgICAgICAgICBfZWxlbWVudF9oOiAxLFxuICAgICAgICAgICAgX2VsZW1lbnRfbDogMCxcbiAgICAgICAgICAgIF9lbGVtZW50X3Q6IDAsXG4gICAgICAgICAgICBfZGVmYXVsdFNpemVYOiAnYXV0bycsXG4gICAgICAgICAgICBfZGVmYXVsdFNpemVZOiAnYXV0bycsXG4gICAgICAgICAgICBfb3JpZ2luX3c6IGNvbnRleHQub3B0aW9uLmltYWdlV2lkdGggPT09ICdhdXRvJyA/ICcnIDogY29udGV4dC5vcHRpb24uaW1hZ2VXaWR0aCxcbiAgICAgICAgICAgIF9vcmlnaW5faDogY29udGV4dC5vcHRpb24uaW1hZ2VIZWlnaHQgPT09ICdhdXRvJyA/ICcnIDogY29udGV4dC5vcHRpb24uaW1hZ2VIZWlnaHQsXG4gICAgICAgICAgICBfcHJvcG9ydGlvbkNoZWNrZWQ6IHRydWUsXG4gICAgICAgICAgICAvLyAtLSBzZWxlY3QgZnVuY3Rpb24gLS1cbiAgICAgICAgICAgIF9yZXNpemluZzogY29udGV4dC5vcHRpb24uaW1hZ2VSZXNpemluZyxcbiAgICAgICAgICAgIF9yZXNpemVEb3RIaWRlOiAhY29udGV4dC5vcHRpb24uaW1hZ2VIZWlnaHRTaG93LFxuICAgICAgICAgICAgX3JvdGF0aW9uOiBjb250ZXh0Lm9wdGlvbi5pbWFnZVJvdGF0aW9uLFxuICAgICAgICAgICAgX29ubHlQZXJjZW50YWdlOiBjb250ZXh0Lm9wdGlvbi5pbWFnZVNpemVPbmx5UGVyY2VudGFnZSxcbiAgICAgICAgICAgIF9yYXRpbzogZmFsc2UsXG4gICAgICAgICAgICBfcmF0aW9YOiAxLFxuICAgICAgICAgICAgX3JhdGlvWTogMVxuICAgICAgICAgICAgX2NhcHRpb25TaG93OiB0cnVlLFxuICAgICAgICAgICAgLy8gLS0gd2hlbiB1c2VkIGNhcHRpb24gKF9jYXB0aW9uU2hvdzogdHJ1ZSkgLS1cbiAgICAgICAgICAgIF9jYXB0aW9uOiBudWxsLFxuICAgICAgICAgICAgX2NhcHRpb25DaGVja2VkOiBmYWxzZSxcbiAgICAgICAgICAgIGNhcHRpb25DaGVja0VsOiBudWxsLFxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY29yZSBDb3JlIG9iamVjdCBcbiAgICAgICAgICovXG4gICAgICAgIGFkZDogZnVuY3Rpb24gKGNvcmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGljb25zID0gY29yZS5pY29ucztcbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSBjb3JlLmNvbnRleHQ7XG4gICAgICAgICAgICBjb250ZXh0LnJlc2l6aW5nID0ge1xuICAgICAgICAgICAgICAgIF9yZXNpemVDbGllbnRYOiAwLFxuICAgICAgICAgICAgICAgIF9yZXNpemVDbGllbnRZOiAwLFxuICAgICAgICAgICAgICAgIF9yZXNpemVfcGx1Z2luOiAnJyxcbiAgICAgICAgICAgICAgICBfcmVzaXplX3c6IDAsXG4gICAgICAgICAgICAgICAgX3Jlc2l6ZV9oOiAwLFxuICAgICAgICAgICAgICAgIF9vcmlnaW5fdzogMCxcbiAgICAgICAgICAgICAgICBfb3JpZ2luX2g6IDAsXG4gICAgICAgICAgICAgICAgX3JvdGF0ZVZlcnRpY2FsOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBfcmVzaXplX2RpcmVjdGlvbjogJycsXG4gICAgICAgICAgICAgICAgX21vdmVfcGF0aDogbnVsbCxcbiAgICAgICAgICAgICAgICBfaXNDaGFuZ2U6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGFsaWduSWNvbnM6IHtcbiAgICAgICAgICAgICAgICAgICAgYmFzaWM6IGljb25zLmFsaWduX2p1c3RpZnksXG4gICAgICAgICAgICAgICAgICAgIGxlZnQ6IGljb25zLmFsaWduX2xlZnQsXG4gICAgICAgICAgICAgICAgICAgIHJpZ2h0OiBpY29ucy5hbGlnbl9yaWdodCxcbiAgICAgICAgICAgICAgICAgICAgY2VudGVyOiBpY29ucy5hbGlnbl9jZW50ZXJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgIFxuICAgICAgICAgICAgLyoqIHJlc2l6ZSBjb250cm9sbGVyLCBidXR0b24gKi9cbiAgICAgICAgICAgIGxldCByZXNpemVfZGl2X2NvbnRhaW5lciA9IHRoaXMuc2V0Q29udHJvbGxlcl9yZXNpemUuY2FsbChjb3JlKTtcbiAgICAgICAgICAgIGNvbnRleHQucmVzaXppbmcucmVzaXplQ29udGFpbmVyID0gcmVzaXplX2Rpdl9jb250YWluZXI7XG4gICAgXG4gICAgICAgICAgICBjb250ZXh0LnJlc2l6aW5nLnJlc2l6ZURpdiA9IHJlc2l6ZV9kaXZfY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJy5zZS1tb2RhbC1yZXNpemUnKTtcbiAgICAgICAgICAgIGNvbnRleHQucmVzaXppbmcucmVzaXplRG90ID0gcmVzaXplX2Rpdl9jb250YWluZXIucXVlcnlTZWxlY3RvcignLnNlLXJlc2l6ZS1kb3QnKTtcbiAgICAgICAgICAgIGNvbnRleHQucmVzaXppbmcucmVzaXplRGlzcGxheSA9IHJlc2l6ZV9kaXZfY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJy5zZS1yZXNpemUtZGlzcGxheScpO1xuICAgIFxuICAgICAgICAgICAgbGV0IHJlc2l6ZV9idXR0b24gPSB0aGlzLnNldENvbnRyb2xsZXJfYnV0dG9uLmNhbGwoY29yZSk7XG4gICAgICAgICAgICBjb250ZXh0LnJlc2l6aW5nLnJlc2l6ZUJ1dHRvbiA9IHJlc2l6ZV9idXR0b247XG4gICAgXG4gICAgICAgICAgICBsZXQgcmVzaXplX2hhbmRsZXMgPSBjb250ZXh0LnJlc2l6aW5nLnJlc2l6ZUhhbmRsZXMgPSBjb250ZXh0LnJlc2l6aW5nLnJlc2l6ZURvdC5xdWVyeVNlbGVjdG9yQWxsKCdzcGFuJyk7XG4gICAgICAgICAgICBjb250ZXh0LnJlc2l6aW5nLnJlc2l6ZUJ1dHRvbkdyb3VwID0gcmVzaXplX2J1dHRvbi5xdWVyeVNlbGVjdG9yKCcuX3NlX3Jlc2l6aW5nX2J0bl9ncm91cCcpO1xuICAgICAgICAgICAgY29udGV4dC5yZXNpemluZy5yb3RhdGlvbkJ1dHRvbnMgPSByZXNpemVfYnV0dG9uLnF1ZXJ5U2VsZWN0b3JBbGwoJy5fc2VfcmVzaXppbmdfYnRuX2dyb3VwIC5fc2Vfcm90YXRpb24nKTtcbiAgICAgICAgICAgIGNvbnRleHQucmVzaXppbmcucGVyY2VudGFnZUJ1dHRvbnMgPSByZXNpemVfYnV0dG9uLnF1ZXJ5U2VsZWN0b3JBbGwoJy5fc2VfcmVzaXppbmdfYnRuX2dyb3VwIC5fc2VfcGVyY2VudGFnZScpO1xuICAgIFxuICAgICAgICAgICAgY29udGV4dC5yZXNpemluZy5hbGlnbk1lbnUgPSByZXNpemVfYnV0dG9uLnF1ZXJ5U2VsZWN0b3IoJy5zZS1yZXNpemluZy1hbGlnbi1saXN0Jyk7XG4gICAgICAgICAgICBjb250ZXh0LnJlc2l6aW5nLmFsaWduTWVudUxpc3QgPSBjb250ZXh0LnJlc2l6aW5nLmFsaWduTWVudS5xdWVyeVNlbGVjdG9yQWxsKCdidXR0b24nKTtcbiAgICBcbiAgICAgICAgICAgIGNvbnRleHQucmVzaXppbmcuYWxpZ25CdXR0b24gPSByZXNpemVfYnV0dG9uLnF1ZXJ5U2VsZWN0b3IoJy5fc2VfcmVzaXppbmdfYWxpZ25fYnV0dG9uJyk7XG4gICAgICAgICAgICBjb250ZXh0LnJlc2l6aW5nLmF1dG9TaXplQnV0dG9uID0gcmVzaXplX2J1dHRvbi5xdWVyeVNlbGVjdG9yKCcuX3NlX3Jlc2l6aW5nX2J0bl9ncm91cCAuX3NlX2F1dG9fc2l6ZScpO1xuICAgICAgICAgICAgY29udGV4dC5yZXNpemluZy5jYXB0aW9uQnV0dG9uID0gcmVzaXplX2J1dHRvbi5xdWVyeVNlbGVjdG9yKCcuX3NlX3Jlc2l6aW5nX2NhcHRpb25fYnV0dG9uJyk7XG4gICAgXG4gICAgICAgICAgICAvKiogYWRkIGV2ZW50IGxpc3RlbmVycyAqL1xuICAgICAgICAgICAgcmVzaXplX2Rpdl9jb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgZnVuY3Rpb24gKGUpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB9KTtcbiAgICAgICAgICAgIHJlc2l6ZV9idXR0b24uYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgY29yZS5ldmVudFN0b3ApO1xuICAgICAgICAgICAgcmVzaXplX2hhbmRsZXNbMF0uYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlRG93bl9yZXNpemVfaGFuZGxlLmJpbmQoY29yZSkpO1xuICAgICAgICAgICAgcmVzaXplX2hhbmRsZXNbMV0uYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlRG93bl9yZXNpemVfaGFuZGxlLmJpbmQoY29yZSkpO1xuICAgICAgICAgICAgcmVzaXplX2hhbmRsZXNbMl0uYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlRG93bl9yZXNpemVfaGFuZGxlLmJpbmQoY29yZSkpO1xuICAgICAgICAgICAgcmVzaXplX2hhbmRsZXNbM10uYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlRG93bl9yZXNpemVfaGFuZGxlLmJpbmQoY29yZSkpO1xuICAgICAgICAgICAgcmVzaXplX2hhbmRsZXNbNF0uYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlRG93bl9yZXNpemVfaGFuZGxlLmJpbmQoY29yZSkpO1xuICAgICAgICAgICAgcmVzaXplX2hhbmRsZXNbNV0uYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlRG93bl9yZXNpemVfaGFuZGxlLmJpbmQoY29yZSkpO1xuICAgICAgICAgICAgcmVzaXplX2hhbmRsZXNbNl0uYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlRG93bl9yZXNpemVfaGFuZGxlLmJpbmQoY29yZSkpO1xuICAgICAgICAgICAgcmVzaXplX2hhbmRsZXNbN10uYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlRG93bl9yZXNpemVfaGFuZGxlLmJpbmQoY29yZSkpO1xuICAgICAgICAgICAgcmVzaXplX2J1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMub25DbGlja19yZXNpemVCdXR0b24uYmluZChjb3JlKSk7XG4gICAgXG4gICAgICAgICAgICAvKiogYXBwZW5kIGh0bWwgKi9cbiAgICAgICAgICAgIGNvbnRleHQuZWxlbWVudC5yZWxhdGl2ZS5hcHBlbmRDaGlsZChyZXNpemVfZGl2X2NvbnRhaW5lcik7XG4gICAgICAgICAgICBjb250ZXh0LmVsZW1lbnQucmVsYXRpdmUuYXBwZW5kQ2hpbGQocmVzaXplX2J1dHRvbik7XG4gICAgXG4gICAgICAgICAgICAvKiogZW1wdHkgbWVtb3J5ICovXG4gICAgICAgICAgICByZXNpemVfZGl2X2NvbnRhaW5lciA9IG51bGwsIHJlc2l6ZV9idXR0b24gPSBudWxsLCByZXNpemVfaGFuZGxlcyA9IG51bGw7XG4gICAgICAgIH0sXG4gICAgXG4gICAgICAgIC8qKiByZXNpemUgY29udHJvbGxlciwgYnV0dG9uIChpbWFnZSwgaWZyYW1lLCB2aWRlbykgKi9cbiAgICAgICAgc2V0Q29udHJvbGxlcl9yZXNpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc2l6ZV9jb250YWluZXIgPSB0aGlzLnV0aWwuY3JlYXRlRWxlbWVudCgnRElWJyk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHJlc2l6ZV9jb250YWluZXIuY2xhc3NOYW1lID0gJ3NlLWNvbnRyb2xsZXIgc2UtcmVzaXppbmctY29udGFpbmVyJztcbiAgICAgICAgICAgIHJlc2l6ZV9jb250YWluZXIuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIHJlc2l6ZV9jb250YWluZXIuaW5uZXJIVE1MID0gJycgK1xuICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtbW9kYWwtcmVzaXplXCI+PC9kaXY+JyArXG4gICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1yZXNpemUtZG90XCI+JyArXG4gICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInRsXCI+PC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJ0clwiPjwvc3Bhbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwiYmxcIj48L3NwYW4+JyArXG4gICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cImJyXCI+PC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJsd1wiPjwvc3Bhbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwidGhcIj48L3NwYW4+JyArXG4gICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInJ3XCI+PC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJiaFwiPjwvc3Bhbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1yZXNpemUtZGlzcGxheVwiPjwvZGl2PicgK1xuICAgICAgICAgICAgICAgICc8L2Rpdj4nO1xuICAgIFxuICAgICAgICAgICAgcmV0dXJuIHJlc2l6ZV9jb250YWluZXI7XG4gICAgICAgIH0sXG4gICAgXG4gICAgICAgIHNldENvbnRyb2xsZXJfYnV0dG9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBsYW5nID0gdGhpcy5sYW5nO1xuICAgICAgICAgICAgY29uc3QgaWNvbnMgPSB0aGlzLmljb25zO1xuICAgICAgICAgICAgY29uc3QgcmVzaXplX2J1dHRvbiA9IHRoaXMudXRpbC5jcmVhdGVFbGVtZW50KFwiRElWXCIpO1xuICAgIFxuICAgICAgICAgICAgcmVzaXplX2J1dHRvbi5jbGFzc05hbWUgPSBcInNlLWNvbnRyb2xsZXIgc2UtY29udHJvbGxlci1yZXNpemluZ1wiO1xuICAgICAgICAgICAgcmVzaXplX2J1dHRvbi5pbm5lckhUTUwgPSAnJyArXG4gICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzZS1hcnJvdyBzZS1hcnJvdy11cFwiPjwvZGl2PicgK1xuICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtYnRuLWdyb3VwIF9zZV9yZXNpemluZ19idG5fZ3JvdXBcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtY29tbWFuZD1cInBlcmNlbnRcIiBkYXRhLXZhbHVlPVwiMVwiIGNsYXNzPVwic2UtdG9vbHRpcCBfc2VfcGVyY2VudGFnZVwiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuPjEwMCU8L3NwYW4+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJzZS10b29sdGlwLWlubmVyXCI+PHNwYW4gY2xhc3M9XCJzZS10b29sdGlwLXRleHRcIj4nICsgbGFuZy5jb250cm9sbGVyLnJlc2l6ZTEwMCArICc8L3NwYW4+PC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJwZXJjZW50XCIgZGF0YS12YWx1ZT1cIjAuNzVcIiBjbGFzcz1cInNlLXRvb2x0aXAgX3NlX3BlcmNlbnRhZ2VcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8c3Bhbj43NSU8L3NwYW4+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJzZS10b29sdGlwLWlubmVyXCI+PHNwYW4gY2xhc3M9XCJzZS10b29sdGlwLXRleHRcIj4nICsgbGFuZy5jb250cm9sbGVyLnJlc2l6ZTc1ICsgJzwvc3Bhbj48L3NwYW4+JyArXG4gICAgICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtY29tbWFuZD1cInBlcmNlbnRcIiBkYXRhLXZhbHVlPVwiMC41XCIgY2xhc3M9XCJzZS10b29sdGlwIF9zZV9wZXJjZW50YWdlXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPHNwYW4+NTAlPC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcuY29udHJvbGxlci5yZXNpemU1MCArICc8L3NwYW4+PC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJhdXRvXCIgY2xhc3M9XCJzZS1idG4gc2UtdG9vbHRpcCBfc2VfYXV0b19zaXplXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICBpY29ucy5hdXRvX3NpemUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcuY29udHJvbGxlci5hdXRvU2l6ZSArICc8L3NwYW4+PC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJyb3RhdGVcIiBkYXRhLXZhbHVlPVwiLTkwXCIgY2xhc3M9XCJzZS1idG4gc2UtdG9vbHRpcCBfc2Vfcm90YXRpb25cIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb25zLnJvdGF0ZV9sZWZ0ICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIucm90YXRlTGVmdCArICc8L3NwYW4+PC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJyb3RhdGVcIiBkYXRhLXZhbHVlPVwiOTBcIiBjbGFzcz1cInNlLWJ0biBzZS10b29sdGlwIF9zZV9yb3RhdGlvblwiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgaWNvbnMucm90YXRlX3JpZ2h0ICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIucm90YXRlUmlnaHQgKyAnPC9zcGFuPjwvc3Bhbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzwvYnV0dG9uPicgK1xuICAgICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlLWJ0bi1ncm91cFwiIHN0eWxlPVwicGFkZGluZy10b3A6IDA7XCI+JyArXG4gICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJtaXJyb3JcIiBkYXRhLXZhbHVlPVwiaFwiIGNsYXNzPVwic2UtYnRuIHNlLXRvb2x0aXBcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb25zLm1pcnJvcl9ob3Jpem9udGFsICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIubWlycm9ySG9yaXpvbnRhbCArICc8L3NwYW4+PC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJtaXJyb3JcIiBkYXRhLXZhbHVlPVwidlwiIGNsYXNzPVwic2UtYnRuIHNlLXRvb2x0aXBcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb25zLm1pcnJvcl92ZXJ0aWNhbCArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJzZS10b29sdGlwLWlubmVyXCI+PHNwYW4gY2xhc3M9XCJzZS10b29sdGlwLXRleHRcIj4nICsgbGFuZy5jb250cm9sbGVyLm1pcnJvclZlcnRpY2FsICsgJzwvc3Bhbj48L3NwYW4+JyArXG4gICAgICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtY29tbWFuZD1cIm9uYWxpZ25cIiBjbGFzcz1cInNlLWJ0biBzZS10b29sdGlwIF9zZV9yZXNpemluZ19hbGlnbl9idXR0b25cIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb25zLmFsaWduX2p1c3RpZnkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcudG9vbGJhci5hbGlnbiArICc8L3NwYW4+PC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtYnRuLWdyb3VwLXN1YiBzdW4tZWRpdG9yLWNvbW1vbiBzZS1saXN0LWxheWVyIHNlLXJlc2l6aW5nLWFsaWduLWxpc3RcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic2UtbGlzdC1pbm5lclwiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8dWwgY2xhc3M9XCJzZS1saXN0LWJhc2ljXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8bGk+PGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzZS1idG4tbGlzdCBzZS10b29sdGlwXCIgZGF0YS1jb21tYW5kPVwiYWxpZ25cIiBkYXRhLXZhbHVlPVwiYmFzaWNcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljb25zLmFsaWduX2p1c3RpZnkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcuZGlhbG9nQm94LmJhc2ljICsgJzwvc3Bhbj48L3NwYW4+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L2J1dHRvbj48L2xpPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGxpPjxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2UtYnRuLWxpc3Qgc2UtdG9vbHRpcFwiIGRhdGEtY29tbWFuZD1cImFsaWduXCIgZGF0YS12YWx1ZT1cImxlZnRcIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljb25zLmFsaWduX2xlZnQgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcuZGlhbG9nQm94LmxlZnQgKyAnPC9zcGFuPjwvc3Bhbj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvYnV0dG9uPjwvbGk+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8bGk+PGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzZS1idG4tbGlzdCBzZS10b29sdGlwXCIgZGF0YS1jb21tYW5kPVwiYWxpZ25cIiBkYXRhLXZhbHVlPVwiY2VudGVyXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpY29ucy5hbGlnbl9jZW50ZXIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcuZGlhbG9nQm94LmNlbnRlciArICc8L3NwYW4+PC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+PC9saT4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxsaT48YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNlLWJ0bi1saXN0IHNlLXRvb2x0aXBcIiBkYXRhLWNvbW1hbmQ9XCJhbGlnblwiIGRhdGEtdmFsdWU9XCJyaWdodFwiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvbnMuYWxpZ25fcmlnaHQgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcuZGlhbG9nQm94LnJpZ2h0ICsgJzwvc3Bhbj48L3NwYW4+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L2J1dHRvbj48L2xpPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L3VsPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJjYXB0aW9uXCIgY2xhc3M9XCJzZS1idG4gc2UtdG9vbHRpcCBfc2VfcmVzaXppbmdfY2FwdGlvbl9idXR0b25cIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb25zLmNhcHRpb24gK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcuZGlhbG9nQm94LmNhcHRpb24gKyAnPC9zcGFuPjwvc3Bhbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzwvYnV0dG9uPicgK1xuICAgICAgICAgICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1jb21tYW5kPVwicmV2ZXJ0XCIgY2xhc3M9XCJzZS1idG4gc2UtdG9vbHRpcFwiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgaWNvbnMucmV2ZXJ0ICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmRpYWxvZ0JveC5yZXZlcnRCdXR0b24gKyAnPC9zcGFuPjwvc3Bhbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzwvYnV0dG9uPicgK1xuICAgICAgICAgICAgICAgICAgICAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1jb21tYW5kPVwidXBkYXRlXCIgY2xhc3M9XCJzZS1idG4gc2UtdG9vbHRpcFwiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgaWNvbnMubW9kaWZ5ICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtaW5uZXJcIj48c3BhbiBjbGFzcz1cInNlLXRvb2x0aXAtdGV4dFwiPicgKyBsYW5nLmNvbnRyb2xsZXIuZWRpdCArICc8L3NwYW4+PC9zcGFuPicgK1xuICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgICAgICc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLWNvbW1hbmQ9XCJkZWxldGVcIiBjbGFzcz1cInNlLWJ0biBzZS10b29sdGlwXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICBpY29ucy5kZWxldGUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC1pbm5lclwiPjxzcGFuIGNsYXNzPVwic2UtdG9vbHRpcC10ZXh0XCI+JyArIGxhbmcuY29udHJvbGxlci5yZW1vdmUgKyAnPC9zcGFuPjwvc3Bhbj4nICtcbiAgICAgICAgICAgICAgICAgICAgJzwvYnV0dG9uPicgK1xuICAgICAgICAgICAgICAgICc8L2Rpdj4nO1xuICAgIFxuICAgICAgICAgICAgcmV0dXJuIHJlc2l6ZV9idXR0b247XG4gICAgICAgIH0sXG4gICAgXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgd2lkdGggc2l6ZVxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFBsdWdpbiBjb250ZXh0IG9iamVjdCBvZiBwbHVnaW4gKGNvcmUuY29udGV4dFtwbHVnaW5dKVxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgVGFyZ2V0IGVsZW1lbnRcbiAgICAgICAgICogQHBhcmFtIHtFbGVtZW50fSBjb3ZlciBDb3ZlciBlbGVtZW50IChGSUdVUkUpXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gY29udGFpbmVyIENvbnRhaW5lciBlbGVtZW50IChESVYuc2UtY29tcG9uZW50KVxuICAgICAgICAgKiBAcmV0dXJucyB7U3RyaW5nfVxuICAgICAgICAgKi9cbiAgICAgICAgX21vZHVsZV9nZXRTaXplWDogZnVuY3Rpb24gKGNvbnRleHRQbHVnaW4sIGVsZW1lbnQsIGNvdmVyLCBjb250YWluZXIpIHtcbiAgICAgICAgICAgIGlmICghZWxlbWVudCkgZWxlbWVudCA9IGNvbnRleHRQbHVnaW4uX2VsZW1lbnQ7XG4gICAgICAgICAgICBpZiAoIWNvdmVyKSBjb3ZlciA9IGNvbnRleHRQbHVnaW4uX2NvdmVyO1xuICAgICAgICAgICAgaWYgKCFjb250YWluZXIpIGNvbnRhaW5lciA9IGNvbnRleHRQbHVnaW4uX2NvbnRhaW5lcjtcbiAgICBcbiAgICAgICAgICAgIGlmICghZWxlbWVudCkgcmV0dXJuICcnO1xuICAgIFxuICAgICAgICAgICAgcmV0dXJuICEvJSQvLnRlc3QoZWxlbWVudC5zdHlsZS53aWR0aCkgPyBlbGVtZW50LnN0eWxlLndpZHRoIDogKChjb250YWluZXIgJiYgdGhpcy51dGlsLmdldE51bWJlcihjb250YWluZXIuc3R5bGUud2lkdGgsIDIpKSB8fCAxMDApICsgJyUnO1xuICAgICAgICB9LFxuICAgIFxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIGhlaWdodCBzaXplXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0UGx1Z2luIGNvbnRleHQgb2JqZWN0IG9mIHBsdWdpbiAoY29yZS5jb250ZXh0W3BsdWdpbl0pXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBUYXJnZXQgZWxlbWVudFxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGNvdmVyIENvdmVyIGVsZW1lbnQgKEZJR1VSRSlcbiAgICAgICAgICogQHBhcmFtIHtFbGVtZW50fSBjb250YWluZXIgQ29udGFpbmVyIGVsZW1lbnQgKERJVi5zZS1jb21wb25lbnQpXG4gICAgICAgICAqIEByZXR1cm5zIHtTdHJpbmd9XG4gICAgICAgICAqL1xuICAgICAgICBfbW9kdWxlX2dldFNpemVZOiBmdW5jdGlvbiAoY29udGV4dFBsdWdpbiwgZWxlbWVudCwgY292ZXIsIGNvbnRhaW5lcikge1xuICAgICAgICAgICAgaWYgKCFlbGVtZW50KSBlbGVtZW50ID0gY29udGV4dFBsdWdpbi5fZWxlbWVudDtcbiAgICAgICAgICAgIGlmICghY292ZXIpIGNvdmVyID0gY29udGV4dFBsdWdpbi5fY292ZXI7XG4gICAgICAgICAgICBpZiAoIWNvbnRhaW5lcikgY29udGFpbmVyID0gY29udGV4dFBsdWdpbi5fY29udGFpbmVyO1xuICAgIFxuICAgICAgICAgICAgaWYgKCFjb250YWluZXIgfHwgIWNvdmVyKSByZXR1cm4gKGVsZW1lbnQgJiYgZWxlbWVudC5zdHlsZS5oZWlnaHQpIHx8ICcnO1xuICAgIFxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudXRpbC5nZXROdW1iZXIoY292ZXIuc3R5bGUucGFkZGluZ0JvdHRvbSwgMCkgPiAwICYmICF0aGlzLmNvbnRleHQucmVzaXppbmcuX3JvdGF0ZVZlcnRpY2FsID8gY292ZXIuc3R5bGUuaGVpZ2h0IDogKCEvJSQvLnRlc3QoZWxlbWVudC5zdHlsZS5oZWlnaHQpIHx8ICEvJSQvLnRlc3QoZWxlbWVudC5zdHlsZS53aWR0aCkgPyBlbGVtZW50LnN0eWxlLmhlaWdodCA6ICgoY29udGFpbmVyICYmIHRoaXMudXRpbC5nZXROdW1iZXIoY29udGFpbmVyLnN0eWxlLmhlaWdodCwgMikpIHx8IDEwMCkgKyAnJScpO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ2FsbGVkIGF0IHRoZSBcIm9wZW5Nb2RpZnlcIiB0byBwdXQgdGhlIHNpemUgb2YgdGhlIGN1cnJlbnQgdGFyZ2V0IGludG8gdGhlIHNpemUgaW5wdXQgZWxlbWVudC5cbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRQbHVnaW4gY29udGV4dCBvYmplY3Qgb2YgcGx1Z2luIChjb3JlLmNvbnRleHRbcGx1Z2luXSlcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IHBsdWdpbk9iaiBQbHVnaW4gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBfbW9kdWxlX3NldE1vZGlmeUlucHV0U2l6ZTogZnVuY3Rpb24gKGNvbnRleHRQbHVnaW4sIHBsdWdpbk9iaikge1xuICAgICAgICAgICAgY29uc3QgcGVyY2VudGFnZVJvdGF0aW9uID0gY29udGV4dFBsdWdpbi5fb25seVBlcmNlbnRhZ2UgJiYgdGhpcy5jb250ZXh0LnJlc2l6aW5nLl9yb3RhdGVWZXJ0aWNhbDtcbiAgICAgICAgICAgIGNvbnRleHRQbHVnaW4ucHJvcG9ydGlvbi5jaGVja2VkID0gY29udGV4dFBsdWdpbi5fcHJvcG9ydGlvbkNoZWNrZWQgPSBjb250ZXh0UGx1Z2luLl9lbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1wcm9wb3J0aW9uJykgIT09ICdmYWxzZSc7XG4gICAgXG4gICAgICAgICAgICBsZXQgeCA9IHBlcmNlbnRhZ2VSb3RhdGlvbiA/ICcnIDogdGhpcy5wbHVnaW5zLnJlc2l6aW5nLl9tb2R1bGVfZ2V0U2l6ZVguY2FsbCh0aGlzLCBjb250ZXh0UGx1Z2luKTtcbiAgICAgICAgICAgIGlmICh4ID09PSBjb250ZXh0UGx1Z2luLl9kZWZhdWx0U2l6ZVgpIHggPSAnJztcbiAgICAgICAgICAgIGlmIChjb250ZXh0UGx1Z2luLl9vbmx5UGVyY2VudGFnZSkgeCA9IHRoaXMudXRpbC5nZXROdW1iZXIoeCwgMik7XG4gICAgICAgICAgICBjb250ZXh0UGx1Z2luLmlucHV0WC52YWx1ZSA9IHg7XG4gICAgICAgICAgICBwbHVnaW5PYmouc2V0SW5wdXRTaXplLmNhbGwodGhpcywgJ3gnKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgKCFjb250ZXh0UGx1Z2luLl9vbmx5UGVyY2VudGFnZSkge1xuICAgICAgICAgICAgICAgIGxldCB5ID0gcGVyY2VudGFnZVJvdGF0aW9uID8gJycgOiB0aGlzLnBsdWdpbnMucmVzaXppbmcuX21vZHVsZV9nZXRTaXplWS5jYWxsKHRoaXMsIGNvbnRleHRQbHVnaW4pO1xuICAgICAgICAgICAgICAgIGlmICh5ID09PSBjb250ZXh0UGx1Z2luLl9kZWZhdWx0U2l6ZVkpIHkgPSAnJztcbiAgICAgICAgICAgICAgICBpZiAoY29udGV4dFBsdWdpbi5fb25seVBlcmNlbnRhZ2UpIHkgPSB0aGlzLnV0aWwuZ2V0TnVtYmVyKHksIDIpO1xuICAgICAgICAgICAgICAgIGNvbnRleHRQbHVnaW4uaW5wdXRZLnZhbHVlID0geTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29udGV4dFBsdWdpbi5pbnB1dFguZGlzYWJsZWQgPSBwZXJjZW50YWdlUm90YXRpb24gPyB0cnVlIDogZmFsc2U7XG4gICAgICAgICAgICBjb250ZXh0UGx1Z2luLmlucHV0WS5kaXNhYmxlZCA9IHBlcmNlbnRhZ2VSb3RhdGlvbiA/IHRydWUgOiBmYWxzZTtcbiAgICAgICAgICAgIGNvbnRleHRQbHVnaW4ucHJvcG9ydGlvbi5kaXNhYmxlZCA9IHBlcmNlbnRhZ2VSb3RhdGlvbiA/IHRydWUgOiBmYWxzZTtcbiAgICBcbiAgICAgICAgICAgIHBsdWdpbk9iai5zZXRSYXRpby5jYWxsKHRoaXMpO1xuICAgICAgICB9LFxuICAgIFxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEl0IGlzIGNhbGxlZCBpbiBcInNldElucHV0U2l6ZVwiIChpbnB1dCB0YWcga2V5dXBFdmVudCksIFxuICAgICAgICAgKiBjaGVja3MgdGhlIHZhbHVlIGVudGVyZWQgaW4gdGhlIGlucHV0IHRhZywgXG4gICAgICAgICAqIGNhbGN1bGF0ZXMgdGhlIHJhdGlvLCBhbmQgc2V0cyB0aGUgY2FsY3VsYXRlZCB2YWx1ZSBpbiB0aGUgaW5wdXQgdGFnIG9mIHRoZSBvcHBvc2l0ZSBzaXplLlxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFBsdWdpbiBjb250ZXh0IG9iamVjdCBvZiBwbHVnaW4gKGNvcmUuY29udGV4dFtwbHVnaW5dKVxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30geHkgJ3gnOiB3aWR0aCwgJ3knOiBoZWlnaHRcbiAgICAgICAgICovXG4gICAgICAgIF9tb2R1bGVfc2V0SW5wdXRTaXplOiBmdW5jdGlvbiAoY29udGV4dFBsdWdpbiwgeHkpIHtcbiAgICAgICAgICAgIGlmIChjb250ZXh0UGx1Z2luLl9vbmx5UGVyY2VudGFnZSkge1xuICAgICAgICAgICAgICAgIGlmICh4eSA9PT0gJ3gnICYmIGNvbnRleHRQbHVnaW4uaW5wdXRYLnZhbHVlID4gMTAwKSBjb250ZXh0UGx1Z2luLmlucHV0WC52YWx1ZSA9IDEwMDtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgXG4gICAgICAgICAgICBpZiAoY29udGV4dFBsdWdpbi5wcm9wb3J0aW9uLmNoZWNrZWQgJiYgY29udGV4dFBsdWdpbi5fcmF0aW8gJiYgL1xcZC8udGVzdChjb250ZXh0UGx1Z2luLmlucHV0WC52YWx1ZSkgJiYgL1xcZC8udGVzdChjb250ZXh0UGx1Z2luLmlucHV0WS52YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB4VW5pdCA9IGNvbnRleHRQbHVnaW4uaW5wdXRYLnZhbHVlLnJlcGxhY2UoL1xcZCt8XFwuL2csICcnKSB8fCBjb250ZXh0UGx1Z2luLnNpemVVbml0O1xuICAgICAgICAgICAgICAgIGNvbnN0IHlVbml0ID0gY29udGV4dFBsdWdpbi5pbnB1dFkudmFsdWUucmVwbGFjZSgvXFxkK3xcXC4vZywgJycpIHx8IGNvbnRleHRQbHVnaW4uc2l6ZVVuaXQ7XG4gICAgXG4gICAgICAgICAgICAgICAgaWYgKHhVbml0ICE9PSB5VW5pdCkgcmV0dXJuO1xuICAgIFxuICAgICAgICAgICAgICAgIGNvbnN0IGRlYyA9IHhVbml0ID09PSAnJScgPyAyIDogMDtcbiAgICBcbiAgICAgICAgICAgICAgICBpZiAoeHkgPT09ICd4Jykge1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0UGx1Z2luLmlucHV0WS52YWx1ZSA9IHRoaXMudXRpbC5nZXROdW1iZXIoY29udGV4dFBsdWdpbi5fcmF0aW9ZICogdGhpcy51dGlsLmdldE51bWJlcihjb250ZXh0UGx1Z2luLmlucHV0WC52YWx1ZSwgZGVjKSwgZGVjKSArIHlVbml0O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHRQbHVnaW4uaW5wdXRYLnZhbHVlID0gdGhpcy51dGlsLmdldE51bWJlcihjb250ZXh0UGx1Z2luLl9yYXRpb1ggKiB0aGlzLnV0aWwuZ2V0TnVtYmVyKGNvbnRleHRQbHVnaW4uaW5wdXRZLnZhbHVlLCBkZWMpLCBkZWMpICsgeFVuaXQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgIFxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEl0IGlzIGNhbGxlZCBpbiBcInNldFJhdGlvXCIgKGlucHV0IGFuZCBwcm9wb3J0aW9uQ2hlY2sgdGFncyBjaGFuZ2VFdmVudCksIFxuICAgICAgICAgKiBjaGVja3MgdGhlIHZhbHVlIG9mIHRoZSBpbnB1dCB0YWcsIGNhbGN1bGF0ZXMgdGhlIHJhdGlvLCBhbmQgcmVzZXRzIGl0IGluIHRoZSBpbnB1dCB0YWcuXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0UGx1Z2luIGNvbnRleHQgb2JqZWN0IG9mIHBsdWdpbiAoY29yZS5jb250ZXh0W3BsdWdpbl0pXG4gICAgICAgICAqL1xuICAgICAgICBfbW9kdWxlX3NldFJhdGlvOiBmdW5jdGlvbiAoY29udGV4dFBsdWdpbikge1xuICAgICAgICAgICAgY29uc3QgeFZhbHVlID0gY29udGV4dFBsdWdpbi5pbnB1dFgudmFsdWU7XG4gICAgICAgICAgICBjb25zdCB5VmFsdWUgPSBjb250ZXh0UGx1Z2luLmlucHV0WS52YWx1ZTtcbiAgICBcbiAgICAgICAgICAgIGlmIChjb250ZXh0UGx1Z2luLnByb3BvcnRpb24uY2hlY2tlZCAmJiAvXFxkKy8udGVzdCh4VmFsdWUpICYmIC9cXGQrLy50ZXN0KHlWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB4VW5pdCA9IHhWYWx1ZS5yZXBsYWNlKC9cXGQrfFxcLi9nLCAnJykgfHwgY29udGV4dFBsdWdpbi5zaXplVW5pdDtcbiAgICAgICAgICAgICAgICBjb25zdCB5VW5pdCA9IHlWYWx1ZS5yZXBsYWNlKC9cXGQrfFxcLi9nLCAnJykgfHwgY29udGV4dFBsdWdpbi5zaXplVW5pdDtcbiAgICBcbiAgICAgICAgICAgICAgICBpZiAoeFVuaXQgIT09IHlVbml0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHRQbHVnaW4uX3JhdGlvID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghY29udGV4dFBsdWdpbi5fcmF0aW8pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeCA9IHRoaXMudXRpbC5nZXROdW1iZXIoeFZhbHVlLCAwKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeSA9IHRoaXMudXRpbC5nZXROdW1iZXIoeVZhbHVlLCAwKTtcbiAgICBcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dFBsdWdpbi5fcmF0aW8gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0UGx1Z2luLl9yYXRpb1ggPSB4IC8geTtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dFBsdWdpbi5fcmF0aW9ZID0geSAvIHg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0UGx1Z2luLl9yYXRpbyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgIFxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIFJldmVydCBzaXplIG9mIGVsZW1lbnQgdG8gb3JpZ2luIHNpemUgKHBsdWdpbi5fb3JpZ2luX3csIHBsdWdpbi5fb3JpZ2luX2gpXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0UGx1Z2luIGNvbnRleHQgb2JqZWN0IG9mIHBsdWdpbiAoY29yZS5jb250ZXh0W3BsdWdpbl0pXG4gICAgICAgICAqL1xuICAgICAgICBfbW9kdWxlX3NpemVSZXZlcnQ6IGZ1bmN0aW9uIChjb250ZXh0UGx1Z2luKSB7XG4gICAgICAgICAgICBpZiAoY29udGV4dFBsdWdpbi5fb25seVBlcmNlbnRhZ2UpIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0UGx1Z2luLmlucHV0WC52YWx1ZSA9IGNvbnRleHRQbHVnaW4uX29yaWdpbl93ID4gMTAwID8gMTAwIDogY29udGV4dFBsdWdpbi5fb3JpZ2luX3c7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnRleHRQbHVnaW4uaW5wdXRYLnZhbHVlID0gY29udGV4dFBsdWdpbi5fb3JpZ2luX3c7XG4gICAgICAgICAgICAgICAgY29udGV4dFBsdWdpbi5pbnB1dFkudmFsdWUgPSBjb250ZXh0UGx1Z2luLl9vcmlnaW5faDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICBcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBTYXZlIHRoZSBzaXplIGRhdGEgKGVsZW1lbnQuc2V0QXR0cmlidXRlKFwiZGF0YS1zaXplXCIpKVxuICAgICAgICAgKiBVc2VkIGF0IHRoZSBcInNldFNpemVcIiBtZXRob2RcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRQbHVnaW4gY29udGV4dCBvYmplY3Qgb2YgcGx1Z2luIChjb3JlLmNvbnRleHRbcGx1Z2luXSlcbiAgICAgICAgICovXG4gICAgICAgIF9tb2R1bGVfc2F2ZUN1cnJlbnRTaXplOiBmdW5jdGlvbiAoY29udGV4dFBsdWdpbikge1xuICAgICAgICAgICAgY29uc3QgeCA9IHRoaXMucGx1Z2lucy5yZXNpemluZy5fbW9kdWxlX2dldFNpemVYLmNhbGwodGhpcywgY29udGV4dFBsdWdpbik7XG4gICAgICAgICAgICBjb25zdCB5ID0gdGhpcy5wbHVnaW5zLnJlc2l6aW5nLl9tb2R1bGVfZ2V0U2l6ZVkuY2FsbCh0aGlzLCBjb250ZXh0UGx1Z2luKTtcbiAgICAgICAgICAgIGNvbnRleHRQbHVnaW4uX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLXNpemUnLCB4ICsgJywnICsgeSk7XG4gICAgICAgICAgICBpZiAoISFjb250ZXh0UGx1Z2luLl92aWRlb1JhdGlvKSBjb250ZXh0UGx1Z2luLl92aWRlb1JhdGlvID0geTtcbiAgICAgICAgfSxcbiAgICBcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBDYWxsIHRoZSByZXNpemluZyBtb2R1bGVcbiAgICAgICAgICogQHBhcmFtIHtFbGVtZW50fSB0YXJnZXRFbGVtZW50IFJlc2l6aW5nIHRhcmdldCBlbGVtZW50XG4gICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwbHVnaW4gUGx1Z2luIG5hbWVcbiAgICAgICAgICogQHJldHVybnMge09iamVjdH0gU2l6ZSBvZiByZXNpemluZyBkaXYge3csIGgsIHQsIGx9XG4gICAgICAgICAqL1xuICAgICAgICBjYWxsX2NvbnRyb2xsZXJfcmVzaXplOiBmdW5jdGlvbiAodGFyZ2V0RWxlbWVudCwgcGx1Z2luKSB7XG4gICAgICAgICAgICBjb25zdCBjb250ZXh0UmVzaXppbmcgPSB0aGlzLmNvbnRleHQucmVzaXppbmc7XG4gICAgICAgICAgICBjb25zdCBjb250ZXh0UGx1Z2luID0gdGhpcy5jb250ZXh0W3BsdWdpbl07XG4gICAgICAgICAgICBjb250ZXh0UmVzaXppbmcuX3Jlc2l6ZV9wbHVnaW4gPSBwbHVnaW47XG4gICAgXG4gICAgICAgICAgICBjb25zdCByZXNpemVDb250YWluZXIgPSBjb250ZXh0UmVzaXppbmcucmVzaXplQ29udGFpbmVyO1xuICAgICAgICAgICAgY29uc3QgcmVzaXplRGl2ID0gY29udGV4dFJlc2l6aW5nLnJlc2l6ZURpdjtcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9IHRoaXMudXRpbC5nZXRPZmZzZXQodGFyZ2V0RWxlbWVudCwgdGhpcy5jb250ZXh0LmVsZW1lbnQud3lzaXd5Z0ZyYW1lKTtcbiAgICBcbiAgICAgICAgICAgIGNvbnN0IGlzVmVydGljYWwgPSBjb250ZXh0UmVzaXppbmcuX3JvdGF0ZVZlcnRpY2FsID0gL14oOTB8MjcwKSQvLnRlc3QoTWF0aC5hYnModGFyZ2V0RWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtcm90YXRlJykpLnRvU3RyaW5nKCkpO1xuICAgIFxuICAgICAgICAgICAgY29uc3QgdyA9IGlzVmVydGljYWwgPyB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodCA6IHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGg7XG4gICAgICAgICAgICBjb25zdCBoID0gaXNWZXJ0aWNhbCA/IHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGggOiB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodDtcbiAgICAgICAgICAgIGNvbnN0IHQgPSBvZmZzZXQudG9wO1xuICAgICAgICAgICAgY29uc3QgbCA9IG9mZnNldC5sZWZ0IC0gdGhpcy5jb250ZXh0LmVsZW1lbnQud3lzaXd5Z0ZyYW1lLnNjcm9sbExlZnQ7XG4gICAgXG4gICAgICAgICAgICByZXNpemVDb250YWluZXIuc3R5bGUudG9wID0gdCArICdweCc7XG4gICAgICAgICAgICByZXNpemVDb250YWluZXIuc3R5bGUubGVmdCA9IGwgKyAncHgnO1xuICAgICAgICAgICAgcmVzaXplQ29udGFpbmVyLnN0eWxlLndpZHRoID0gdyArICdweCc7XG4gICAgICAgICAgICByZXNpemVDb250YWluZXIuc3R5bGUuaGVpZ2h0ID0gaCArICdweCc7XG4gICAgXG4gICAgICAgICAgICByZXNpemVEaXYuc3R5bGUudG9wID0gJzBweCc7XG4gICAgICAgICAgICByZXNpemVEaXYuc3R5bGUubGVmdCA9ICcwcHgnO1xuICAgICAgICAgICAgcmVzaXplRGl2LnN0eWxlLndpZHRoID0gIHcgKyAncHgnO1xuICAgICAgICAgICAgcmVzaXplRGl2LnN0eWxlLmhlaWdodCA9ICBoICsgJ3B4JztcbiAgICBcbiAgICAgICAgICAgIGxldCBhbGlnbiA9IHRhcmdldEVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWFsaWduJykgfHwgJ2Jhc2ljJztcbiAgICAgICAgICAgIGFsaWduID0gYWxpZ24gPT09ICdub25lJyA/ICdiYXNpYycgOiBhbGlnbjtcbiAgICBcbiAgICAgICAgICAgIC8vIHRleHRcbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMudXRpbC5nZXRQYXJlbnRFbGVtZW50KHRhcmdldEVsZW1lbnQsIHRoaXMudXRpbC5pc0NvbXBvbmVudCk7XG4gICAgICAgICAgICBjb25zdCBjb3ZlciA9IHRoaXMudXRpbC5nZXRQYXJlbnRFbGVtZW50KHRhcmdldEVsZW1lbnQsICdGSUdVUkUnKTtcbiAgICAgICAgICAgIGNvbnN0IGRpc3BsYXlYID0gdGhpcy5wbHVnaW5zLnJlc2l6aW5nLl9tb2R1bGVfZ2V0U2l6ZVguY2FsbCh0aGlzLCBjb250ZXh0UGx1Z2luLCB0YXJnZXRFbGVtZW50LCBjb3ZlciwgY29udGFpbmVyKSB8fCAnYXV0byc7XG4gICAgICAgICAgICBjb25zdCBkaXNwbGF5WSA9IGNvbnRleHRQbHVnaW4uX29ubHlQZXJjZW50YWdlICYmIHBsdWdpbiA9PT0gJ2ltYWdlJyA/ICcnIDogJywgJyArICh0aGlzLnBsdWdpbnMucmVzaXppbmcuX21vZHVsZV9nZXRTaXplWS5jYWxsKHRoaXMsIGNvbnRleHRQbHVnaW4sIHRhcmdldEVsZW1lbnQsIGNvdmVyLCBjb250YWluZXIpIHx8ICdhdXRvJyk7XG4gICAgICAgICAgICB0aGlzLnV0aWwuY2hhbmdlVHh0KGNvbnRleHRSZXNpemluZy5yZXNpemVEaXNwbGF5LCB0aGlzLmxhbmcuZGlhbG9nQm94W2FsaWduXSArICcgKCcgKyBkaXNwbGF5WCArIGRpc3BsYXlZICsgJyknKTtcbiAgICBcbiAgICAgICAgICAgIC8vIHJlc2l6aW5nIGRpc3BsYXlcbiAgICAgICAgICAgIGNvbnRleHRSZXNpemluZy5yZXNpemVCdXR0b25Hcm91cC5zdHlsZS5kaXNwbGF5ID0gY29udGV4dFBsdWdpbi5fcmVzaXppbmcgPyAnJyA6ICdub25lJztcbiAgICAgICAgICAgIGNvbnN0IHJlc2l6ZURvdFNob3cgPSBjb250ZXh0UGx1Z2luLl9yZXNpemluZyAmJiAhY29udGV4dFBsdWdpbi5fcmVzaXplRG90SGlkZSAmJiAhY29udGV4dFBsdWdpbi5fb25seVBlcmNlbnRhZ2UgPyAnZmxleCcgOiAnbm9uZSc7XG4gICAgICAgICAgICBjb25zdCByZXNpemVIYW5kbGVzID0gY29udGV4dFJlc2l6aW5nLnJlc2l6ZUhhbmRsZXM7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gcmVzaXplSGFuZGxlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIHJlc2l6ZUhhbmRsZXNbaV0uc3R5bGUuZGlzcGxheSA9IHJlc2l6ZURvdFNob3c7XG4gICAgICAgICAgICB9XG4gICAgXG4gICAgICAgICAgICBpZiAoY29udGV4dFBsdWdpbi5fcmVzaXppbmcpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByb3RhdGlvbnMgPSBjb250ZXh0UmVzaXppbmcucm90YXRpb25CdXR0b25zO1xuICAgICAgICAgICAgICAgIHJvdGF0aW9uc1swXS5zdHlsZS5kaXNwbGF5ID0gcm90YXRpb25zWzFdLnN0eWxlLmRpc3BsYXkgPSBjb250ZXh0UGx1Z2luLl9yb3RhdGlvbiA/ICcnIDogJ25vbmUnO1xuICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgLy8gYWxpZ24gaWNvblxuICAgICAgICAgICAgY29uc3QgYWxpZ25MaXN0ID0gY29udGV4dFJlc2l6aW5nLmFsaWduTWVudUxpc3Q7XG4gICAgICAgICAgICB0aGlzLnV0aWwuY2hhbmdlRWxlbWVudChjb250ZXh0UmVzaXppbmcuYWxpZ25CdXR0b24uZmlyc3RFbGVtZW50Q2hpbGQsIGNvbnRleHRSZXNpemluZy5hbGlnbkljb25zW2FsaWduXSk7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gYWxpZ25MaXN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFsaWduTGlzdFtpXS5nZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnKSA9PT0gYWxpZ24pIHRoaXMudXRpbC5hZGRDbGFzcyhhbGlnbkxpc3RbaV0sICdvbicpO1xuICAgICAgICAgICAgICAgIGVsc2UgdGhpcy51dGlsLnJlbW92ZUNsYXNzKGFsaWduTGlzdFtpXSwgJ29uJyk7XG4gICAgICAgICAgICB9XG4gICAgXG4gICAgICAgICAgICAvLyBwZXJjZW50YWdlIGFjdGl2ZVxuICAgICAgICAgICAgY29uc3QgcEJ1dHRvbnMgPSBjb250ZXh0UmVzaXppbmcucGVyY2VudGFnZUJ1dHRvbnM7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IC8lJC8udGVzdCh0YXJnZXRFbGVtZW50LnN0eWxlLndpZHRoKSAmJiAvJSQvLnRlc3QoY29udGFpbmVyLnN0eWxlLndpZHRoKSA/ICh0aGlzLnV0aWwuZ2V0TnVtYmVyKGNvbnRhaW5lci5zdHlsZS53aWR0aCwgMCkgLyAxMDApICsgJycgOiAnJyA7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gcEJ1dHRvbnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAocEJ1dHRvbnNbaV0uZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJykgPT09IHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbC5hZGRDbGFzcyhwQnV0dG9uc1tpXSwgJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbC5yZW1vdmVDbGFzcyhwQnV0dG9uc1tpXSwgJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgIC8vIGNhcHRpb24gZGlzcGxheSwgYWN0aXZlXG4gICAgICAgICAgICBpZiAoIWNvbnRleHRQbHVnaW4uX2NhcHRpb25TaG93KSB7XG4gICAgICAgICAgICAgICAgY29udGV4dFJlc2l6aW5nLmNhcHRpb25CdXR0b24uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29udGV4dFJlc2l6aW5nLmNhcHRpb25CdXR0b24uc3R5bGUuZGlzcGxheSA9ICcnO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnV0aWwuZ2V0Q2hpbGRFbGVtZW50KHRhcmdldEVsZW1lbnQucGFyZW50Tm9kZSwgJ2ZpZ2NhcHRpb24nKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnV0aWwuYWRkQ2xhc3MoY29udGV4dFJlc2l6aW5nLmNhcHRpb25CdXR0b24sICdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dFBsdWdpbi5fY2FwdGlvbkNoZWNrZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbC5yZW1vdmVDbGFzcyhjb250ZXh0UmVzaXppbmcuY2FwdGlvbkJ1dHRvbiwgJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0UGx1Z2luLl9jYXB0aW9uQ2hlY2tlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudENvbnRyb2xsZXJOYW1lICE9PSBwbHVnaW4pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnV0aWwuc2V0RGlzYWJsZWRCdXR0b25zKHRydWUsIHRoaXMucmVzaXppbmdEaXNhYmxlZEJ1dHRvbnMpO1xuICAgICAgICAgICAgICAgIHJlc2l6ZUNvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblxuICAgICAgICAgICAgICAgIGNvbnN0IGFkZE9mZnNldCA9IHtsZWZ0OiAwLCB0b3A6IDUwfTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0Lm9wdGlvbnMuaWZyYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZE9mZnNldC5sZWZ0IC09IHRoaXMuY29udGV4dC5lbGVtZW50Lnd5c2l3eWdGcmFtZS5wYXJlbnRFbGVtZW50Lm9mZnNldExlZnQ7XG4gICAgICAgICAgICAgICAgICAgIGFkZE9mZnNldC50b3AgLT0gdGhpcy5jb250ZXh0LmVsZW1lbnQud3lzaXd5Z0ZyYW1lLnBhcmVudEVsZW1lbnQub2Zmc2V0VG9wO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuc2V0Q29udHJvbGxlclBvc2l0aW9uKGNvbnRleHRSZXNpemluZy5yZXNpemVCdXR0b24sIHJlc2l6ZUNvbnRhaW5lciwgJ2JvdHRvbScsIGFkZE9mZnNldCk7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250cm9sbGVyc09uKHJlc2l6ZUNvbnRhaW5lciwgY29udGV4dFJlc2l6aW5nLnJlc2l6ZUJ1dHRvbiwgdGhpcy51dGlsLnNldERpc2FibGVkQnV0dG9ucy5iaW5kKHRoaXMsIGZhbHNlLCB0aGlzLnJlc2l6aW5nRGlzYWJsZWRCdXR0b25zKSwgdGFyZ2V0RWxlbWVudCwgcGx1Z2luKTtcbiAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgIGNvbnRleHRSZXNpemluZy5fcmVzaXplX3cgPSB3O1xuICAgICAgICAgICAgY29udGV4dFJlc2l6aW5nLl9yZXNpemVfaCA9IGg7XG4gICAgXG4gICAgICAgICAgICBjb25zdCBvcmlnaW5TaXplID0gKHRhcmdldEVsZW1lbnQuZ2V0QXR0cmlidXRlKCdvcmlnaW4tc2l6ZScpIHx8ICcnKS5zcGxpdCgnLCcpO1xuICAgICAgICAgICAgY29udGV4dFJlc2l6aW5nLl9vcmlnaW5fdyA9IG9yaWdpblNpemVbMF0gfHwgdGFyZ2V0RWxlbWVudC5uYXR1cmFsV2lkdGg7XG4gICAgICAgICAgICBjb250ZXh0UmVzaXppbmcuX29yaWdpbl9oID0gb3JpZ2luU2l6ZVsxXSB8fCB0YXJnZXRFbGVtZW50Lm5hdHVyYWxIZWlnaHQ7XG4gICAgXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHc6IHcsXG4gICAgICAgICAgICAgICAgaDogaCxcbiAgICAgICAgICAgICAgICB0OiB0LFxuICAgICAgICAgICAgICAgIGw6IGxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sXG4gICAgXG4gICAgICAgIF9jbG9zZUFsaWduTWVudTogbnVsbCxcblxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIE9wZW4gYWxpZ24gc3VibWVudSBvZiBtb2R1bGVcbiAgICAgICAgICovXG4gICAgICAgIG9wZW5BbGlnbk1lbnU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGFsaWduQnV0dG9uID0gdGhpcy5jb250ZXh0LnJlc2l6aW5nLmFsaWduQnV0dG9uO1xuICAgICAgICAgICAgdGhpcy51dGlsLmFkZENsYXNzKGFsaWduQnV0dG9uLCAnb24nKTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5yZXNpemluZy5hbGlnbk1lbnUuc3R5bGUudG9wID0gKGFsaWduQnV0dG9uLm9mZnNldFRvcCArIGFsaWduQnV0dG9uLm9mZnNldEhlaWdodCkgKyAncHgnO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnJlc2l6aW5nLmFsaWduTWVudS5zdHlsZS5sZWZ0ID0gKGFsaWduQnV0dG9uLm9mZnNldExlZnQgLSBhbGlnbkJ1dHRvbi5vZmZzZXRXaWR0aCAvIDIpICsgJ3B4JztcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5yZXNpemluZy5hbGlnbk1lbnUuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgXG4gICAgICAgICAgICB0aGlzLnBsdWdpbnMucmVzaXppbmcuX2Nsb3NlQWxpZ25NZW51ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMudXRpbC5yZW1vdmVDbGFzcyh0aGlzLmNvbnRleHQucmVzaXppbmcuYWxpZ25CdXR0b24sICdvbicpO1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC5yZXNpemluZy5hbGlnbk1lbnUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZURvY0V2ZW50KCdtb3VzZWRvd24nLCB0aGlzLnBsdWdpbnMucmVzaXppbmcuX2Nsb3NlQWxpZ25NZW51KTtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMucmVzaXppbmcuX2Nsb3NlQWxpZ25NZW51ID0gbnVsbDtcbiAgICAgICAgICAgIH0uYmluZCh0aGlzKTtcbiAgICBcbiAgICAgICAgICAgIHRoaXMuYWRkRG9jRXZlbnQoJ21vdXNlZG93bicsIHRoaXMucGx1Z2lucy5yZXNpemluZy5fY2xvc2VBbGlnbk1lbnUpO1xuICAgICAgICB9LFxuICAgIFxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIENsaWNrIGV2ZW50IG9mIHJlc2l6aW5nIHRvb2xiYXJcbiAgICAgICAgICogUGVyZm9ybXMgdGhlIGFjdGlvbiBvZiB0aGUgY2xpY2tlZCB0b29sYmFyIGJ1dHRvbi5cbiAgICAgICAgICogQHBhcmFtIHtNb3VzZUV2ZW50fSBlIEV2ZW50IG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgb25DbGlja19yZXNpemVCdXR0b246IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIFxuICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQ7XG4gICAgICAgICAgICBjb25zdCBjb21tYW5kID0gdGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS1jb21tYW5kJykgfHwgdGFyZ2V0LnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKCdkYXRhLWNvbW1hbmQnKTtcbiAgICBcbiAgICAgICAgICAgIGlmICghY29tbWFuZCkgcmV0dXJuO1xuICAgIFxuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJykgfHwgdGFyZ2V0LnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJyk7XG4gICAgXG4gICAgICAgICAgICBjb25zdCBwbHVnaW5OYW1lID0gdGhpcy5jb250ZXh0LnJlc2l6aW5nLl9yZXNpemVfcGx1Z2luO1xuICAgICAgICAgICAgY29uc3QgY3VycmVudENvbnRleHQgPSB0aGlzLmNvbnRleHRbcGx1Z2luTmFtZV07XG4gICAgICAgICAgICBjb25zdCBjb250ZXh0RWwgPSBjdXJyZW50Q29udGV4dC5fZWxlbWVudDtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRNb2R1bGUgPSB0aGlzLnBsdWdpbnNbcGx1Z2luTmFtZV07XG4gICAgXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgXG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMucGx1Z2lucy5yZXNpemluZy5fY2xvc2VBbGlnbk1lbnUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMucmVzaXppbmcuX2Nsb3NlQWxpZ25NZW51KCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbW1hbmQgPT09ICdvbmFsaWduJykgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgc3dpdGNoIChjb21tYW5kKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnYXV0byc6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2lucy5yZXNpemluZy5yZXNldFRyYW5zZm9ybS5jYWxsKHRoaXMsIGNvbnRleHRFbCk7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUuc2V0QXV0b1NpemUuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RDb21wb25lbnQoY29udGV4dEVsLCBwbHVnaW5OYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAncGVyY2VudCc6XG4gICAgICAgICAgICAgICAgICAgIGxldCBwZXJjZW50WSA9IHRoaXMucGx1Z2lucy5yZXNpemluZy5fbW9kdWxlX2dldFNpemVZLmNhbGwodGhpcywgY3VycmVudENvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnJlc2l6aW5nLl9yb3RhdGVWZXJ0aWNhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGVyY2VudGFnZSA9IGNvbnRleHRFbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtcGVyY2VudGFnZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBlcmNlbnRhZ2UpIHBlcmNlbnRZID0gcGVyY2VudGFnZS5zcGxpdCgnLCcpWzFdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2lucy5yZXNpemluZy5yZXNldFRyYW5zZm9ybS5jYWxsKHRoaXMsIGNvbnRleHRFbCk7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUuc2V0UGVyY2VudFNpemUuY2FsbCh0aGlzLCAodmFsdWUgKiAxMDApLCAodGhpcy51dGlsLmdldE51bWJlcihwZXJjZW50WSwgMCkgPT09IG51bGwgfHwgIS8lJC8udGVzdChwZXJjZW50WSkpID8gJycgOiBwZXJjZW50WSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0Q29tcG9uZW50KGNvbnRleHRFbCwgcGx1Z2luTmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ21pcnJvcic6XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBjb250ZXh0RWwuZ2V0QXR0cmlidXRlKCdkYXRhLXJvdGF0ZScpIHx8ICcwJztcbiAgICAgICAgICAgICAgICAgICAgbGV0IHggPSBjb250ZXh0RWwuZ2V0QXR0cmlidXRlKCdkYXRhLXJvdGF0ZVgnKSB8fCAnJztcbiAgICAgICAgICAgICAgICAgICAgbGV0IHkgPSBjb250ZXh0RWwuZ2V0QXR0cmlidXRlKCdkYXRhLXJvdGF0ZVknKSB8fCAnJztcbiAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIGlmICgodmFsdWUgPT09ICdoJyAmJiAhdGhpcy5jb250ZXh0LnJlc2l6aW5nLl9yb3RhdGVWZXJ0aWNhbCkgfHwgKHZhbHVlID09PSAndicgJiYgdGhpcy5jb250ZXh0LnJlc2l6aW5nLl9yb3RhdGVWZXJ0aWNhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSB5ID8gJycgOiAnMTgwJztcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHggPSB4ID8gJycgOiAnMTgwJztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dEVsLnNldEF0dHJpYnV0ZSgnZGF0YS1yb3RhdGVYJywgeCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHRFbC5zZXRBdHRyaWJ1dGUoJ2RhdGEtcm90YXRlWScsIHkpO1xuICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnJlc2l6aW5nLl9zZXRUcmFuc0Zvcm0oY29udGV4dEVsLCByLCB4LCB5KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAncm90YXRlJzpcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29udGV4dFJlc2l6aW5nID0gdGhpcy5jb250ZXh0LnJlc2l6aW5nO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzbG9wZSA9IChjb250ZXh0RWwuZ2V0QXR0cmlidXRlKCdkYXRhLXJvdGF0ZScpICogMSkgKyAodmFsdWUgKiAxKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVnID0gdGhpcy5fdy5NYXRoLmFicyhzbG9wZSkgPj0gMzYwID8gMCA6IHNsb3BlO1xuICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dEVsLnNldEF0dHJpYnV0ZSgnZGF0YS1yb3RhdGUnLCBkZWcpO1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0UmVzaXppbmcuX3JvdGF0ZVZlcnRpY2FsID0gL14oOTB8MjcwKSQvLnRlc3QodGhpcy5fdy5NYXRoLmFicyhkZWcpLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMucmVzaXppbmcuc2V0VHJhbnNmb3JtU2l6ZS5jYWxsKHRoaXMsIGNvbnRleHRFbCwgbnVsbCwgbnVsbCk7XG4gICAgICAgIFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdENvbXBvbmVudChjb250ZXh0RWwsIHBsdWdpbk5hbWUpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdvbmFsaWduJzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnJlc2l6aW5nLm9wZW5BbGlnbk1lbnUuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2FsaWduJzpcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWxpZ25WYWx1ZSA9IHZhbHVlID09PSAnYmFzaWMnID8gJ25vbmUnIDogdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUuc2V0QWxpZ24uY2FsbCh0aGlzLCBhbGlnblZhbHVlLCBudWxsLCBudWxsLCBudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RDb21wb25lbnQoY29udGV4dEVsLCBwbHVnaW5OYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnY2FwdGlvbic6XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhcHRpb24gPSAhY3VycmVudENvbnRleHQuX2NhcHRpb25DaGVja2VkO1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50TW9kdWxlLm9wZW5Nb2RpZnkuY2FsbCh0aGlzLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudENvbnRleHQuX2NhcHRpb25DaGVja2VkID0gY3VycmVudENvbnRleHQuY2FwdGlvbkNoZWNrRWwuY2hlY2tlZCA9IGNhcHRpb247XG4gICAgXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUudXBkYXRlX2ltYWdlLmNhbGwodGhpcywgZmFsc2UsIGZhbHNlLCBmYWxzZSk7XG4gICAgXG4gICAgICAgICAgICAgICAgICAgIGlmIChjYXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYXB0aW9uVGV4dCA9IHRoaXMudXRpbC5nZXRDaGlsZEVsZW1lbnQoY3VycmVudENvbnRleHQuX2NhcHRpb24sIGZ1bmN0aW9uIChjdXJyZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQubm9kZVR5cGUgPT09IDM7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2FwdGlvblRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q29udGV4dC5fY2FwdGlvbi5mb2N1cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFJhbmdlKGNhcHRpb25UZXh0LCAwLCBjYXB0aW9uVGV4dCwgY2FwdGlvblRleHQudGV4dENvbnRlbnQubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29udHJvbGxlcnNPZmYoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0Q29tcG9uZW50KGNvbnRleHRFbCwgcGx1Z2luTmFtZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50TW9kdWxlLm9wZW5Nb2RpZnkuY2FsbCh0aGlzLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdyZXZlcnQnOlxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50TW9kdWxlLnNldE9yaWdpblNpemUuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RDb21wb25lbnQoY29udGV4dEVsLCBwbHVnaW5OYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAndXBkYXRlJzpcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudE1vZHVsZS5vcGVuTW9kaWZ5LmNhbGwodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udHJvbGxlcnNPZmYoKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnZGVsZXRlJzpcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudE1vZHVsZS5kZXN0cm95LmNhbGwodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgLy8gaGlzdG9yeSBzdGFja1xuICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnB1c2goZmFsc2UpO1xuICAgICAgICB9LFxuICAgIFxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIEluaXRpYWxpemUgdGhlIHRyYW5zZm9ybSBzdHlsZSAocm90YXRpb24pIG9mIHRoZSBlbGVtZW50LlxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgVGFyZ2V0IGVsZW1lbnRcbiAgICAgICAgICovXG4gICAgICAgIHJlc2V0VHJhbnNmb3JtOiBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICAgICAgY29uc3Qgc2l6ZSA9IChlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1zaXplJykgfHwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtb3JpZ2luJykgfHwgJycpLnNwbGl0KCcsJyk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQucmVzaXppbmcuX3JvdGF0ZVZlcnRpY2FsID0gZmFsc2U7XG4gICAgXG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLm1heFdpZHRoID0gJyc7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLnRyYW5zZm9ybSA9ICcnO1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS50cmFuc2Zvcm1PcmlnaW4gPSAnJztcbiAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLXJvdGF0ZScsICcnKTtcbiAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLXJvdGF0ZVgnLCAnJyk7XG4gICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1yb3RhdGVZJywgJycpO1xuICAgIFxuICAgICAgICAgICAgdGhpcy5wbHVnaW5zW3RoaXMuY29udGV4dC5yZXNpemluZy5fcmVzaXplX3BsdWdpbl0uc2V0U2l6ZS5jYWxsKHRoaXMsIHNpemVbMF0gPyBzaXplWzBdIDogJ2F1dG8nLCBzaXplWzFdID8gc2l6ZVsxXSA6ICcnLCB0cnVlKTtcbiAgICAgICAgfSxcbiAgICBcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBTZXQgdGhlIHRyYW5zZm9ybSBzdHlsZSAocm90YXRpb24pIG9mIHRoZSBlbGVtZW50LlxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgVGFyZ2V0IGVsZW1lbnRcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ8bnVsbH0gd2lkdGggRWxlbWVudCdzIHdpZHRoIHNpemVcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ8bnVsbH0gaGVpZ2h0IEVsZW1lbnQncyBoZWlnaHQgc2l6ZVxuICAgICAgICAgKi9cbiAgICAgICAgc2V0VHJhbnNmb3JtU2l6ZTogZnVuY3Rpb24gKGVsZW1lbnQsIHdpZHRoLCBoZWlnaHQpIHtcbiAgICAgICAgICAgIGxldCBwZXJjZW50YWdlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtcGVyY2VudGFnZScpO1xuICAgICAgICAgICAgY29uc3QgaXNWZXJ0aWNhbCA9IHRoaXMuY29udGV4dC5yZXNpemluZy5fcm90YXRlVmVydGljYWw7XG4gICAgICAgICAgICBjb25zdCBkZWcgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1yb3RhdGUnKSAqIDE7XG4gICAgICAgICAgICBsZXQgdHJhbnNPcmlnaW4gPSAnJztcbiAgICBcbiAgICAgICAgICAgIGlmIChwZXJjZW50YWdlICYmICFpc1ZlcnRpY2FsKSB7XG4gICAgICAgICAgICAgICAgcGVyY2VudGFnZSA9IHBlcmNlbnRhZ2Uuc3BsaXQoJywnKTtcbiAgICAgICAgICAgICAgICBpZiAocGVyY2VudGFnZVswXSA9PT0gJ2F1dG8nICYmIHBlcmNlbnRhZ2VbMV0gPT09ICdhdXRvJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnNbdGhpcy5jb250ZXh0LnJlc2l6aW5nLl9yZXNpemVfcGx1Z2luXS5zZXRBdXRvU2l6ZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luc1t0aGlzLmNvbnRleHQucmVzaXppbmcuX3Jlc2l6ZV9wbHVnaW5dLnNldFBlcmNlbnRTaXplLmNhbGwodGhpcywgcGVyY2VudGFnZVswXSwgcGVyY2VudGFnZVsxXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb3ZlciA9IHRoaXMudXRpbC5nZXRQYXJlbnRFbGVtZW50KGVsZW1lbnQsICdGSUdVUkUnKTtcbiAgICAgICAgXG4gICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0VyA9IHdpZHRoIHx8IGVsZW1lbnQub2Zmc2V0V2lkdGg7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0SCA9IGhlaWdodCB8fCBlbGVtZW50Lm9mZnNldEhlaWdodDtcbiAgICAgICAgICAgICAgICBjb25zdCB3ID0gKGlzVmVydGljYWwgPyBvZmZzZXRIIDogb2Zmc2V0VykgKyAncHgnO1xuICAgICAgICAgICAgICAgIGNvbnN0IGggPSAoaXNWZXJ0aWNhbCA/IG9mZnNldFcgOiBvZmZzZXRIKSArICdweCc7XG4gICAgICAgIFxuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luc1t0aGlzLmNvbnRleHQucmVzaXppbmcuX3Jlc2l6ZV9wbHVnaW5dLmNhbmNlbFBlcmNlbnRBdHRyLmNhbGwodGhpcyk7XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zW3RoaXMuY29udGV4dC5yZXNpemluZy5fcmVzaXplX3BsdWdpbl0uc2V0U2l6ZS5jYWxsKHRoaXMsIG9mZnNldFcgKyAncHgnLCBvZmZzZXRIICsgJ3B4JywgdHJ1ZSk7XG4gICAgICAgIFxuICAgICAgICAgICAgICAgIGNvdmVyLnN0eWxlLndpZHRoID0gdztcbiAgICAgICAgICAgICAgICBjb3Zlci5zdHlsZS5oZWlnaHQgPSAoISF0aGlzLmNvbnRleHRbdGhpcy5jb250ZXh0LnJlc2l6aW5nLl9yZXNpemVfcGx1Z2luXS5fY2FwdGlvbiA/ICcnIDogaCk7XG4gICAgXG4gICAgICAgICAgICAgICAgaWYgKGlzVmVydGljYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRyYW5zVyA9IChvZmZzZXRXLzIpICsgJ3B4ICcgKyAob2Zmc2V0Vy8yKSArICdweCAwJztcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRyYW5zSCA9IChvZmZzZXRILzIpICsgJ3B4ICcgKyAob2Zmc2V0SC8yKSArICdweCAwJztcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNPcmlnaW4gPSBkZWcgPT09IDkwIHx8IGRlZyA9PT0gLTI3MCA/IHRyYW5zSCA6IHRyYW5zVztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgXG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IHRyYW5zT3JpZ2luO1xuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnJlc2l6aW5nLl9zZXRUcmFuc0Zvcm0oZWxlbWVudCwgZGVnLnRvU3RyaW5nKCksIGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXJvdGF0ZVgnKSB8fCAnJywgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtcm90YXRlWScpIHx8ICcnKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgKGlzVmVydGljYWwpIGVsZW1lbnQuc3R5bGUubWF4V2lkdGggPSAnbm9uZSc7XG4gICAgICAgICAgICBlbHNlIGVsZW1lbnQuc3R5bGUubWF4V2lkdGggPSAnJztcbiAgICBcbiAgICAgICAgICAgIHRoaXMucGx1Z2lucy5yZXNpemluZy5zZXRDYXB0aW9uUG9zaXRpb24uY2FsbCh0aGlzLCBlbGVtZW50KTtcbiAgICAgICAgfSxcbiAgICBcbiAgICAgICAgX3NldFRyYW5zRm9ybTogZnVuY3Rpb24gKGVsZW1lbnQsIHIsIHgsIHkpIHtcbiAgICAgICAgICAgIGxldCB3aWR0aCA9IChlbGVtZW50Lm9mZnNldFdpZHRoIC0gZWxlbWVudC5vZmZzZXRIZWlnaHQpICogKC8tLy50ZXN0KHIpID8gMSA6IC0xKTtcbiAgICAgICAgICAgIGxldCB0cmFuc2xhdGUgPSAnJztcbiAgICBcbiAgICAgICAgICAgIGlmICgvWzEtOV0vLnRlc3QocikgJiYgKHggfHwgeSkpIHtcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGUgPSB4ID8gJ1knIDogJ1gnO1xuICAgIFxuICAgICAgICAgICAgICAgIHN3aXRjaCAocikge1xuICAgICAgICAgICAgICAgICAgICBjYXNlICc5MCc6XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGUgPSB4ICYmIHkgPyAnWCcgOiB5ID8gdHJhbnNsYXRlIDogJyc7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnMjcwJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoICo9IC0xO1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlID0geCAmJiB5ID8gJ1knIDogeCA/IHRyYW5zbGF0ZSA6ICcnO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJy05MCc6XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGUgPSB4ICYmIHkgPyAnWScgOiB4ID8gdHJhbnNsYXRlIDogJyc7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnLTI3MCc6XG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCAqPSAtMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZSA9IHggJiYgeSA/ICdYJyA6IHkgPyB0cmFuc2xhdGUgOiAnJztcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlID0gJyc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgaWYgKHIgJSAxODAgPT09IDApIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LnN0eWxlLm1heFdpZHRoID0gJyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUudHJhbnNmb3JtID0gJ3JvdGF0ZSgnICsgciArICdkZWcpJyArICh4ID8gJyByb3RhdGVYKCcgKyB4ICsgJ2RlZyknIDogJycpICsgKHkgPyAnIHJvdGF0ZVkoJyArIHkgKyAnZGVnKScgOiAnJykgKyAodHJhbnNsYXRlID8gJyB0cmFuc2xhdGUnICsgdHJhbnNsYXRlICsgJygnICsgd2lkdGggKyAncHgpJyA6ICcnKTtcbiAgICAgICAgfSxcbiAgICBcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBUaGUgcG9zaXRpb24gb2YgdGhlIGNhcHRpb24gaXMgc2V0IGF1dG9tYXRpY2FsbHkuXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBUYXJnZXQgZWxlbWVudCAobm90IGNhcHRpb24gZWxlbWVudClcbiAgICAgICAgICovXG4gICAgICAgIHNldENhcHRpb25Qb3NpdGlvbjogZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpZ2NhcHRpb24gPSB0aGlzLnV0aWwuZ2V0Q2hpbGRFbGVtZW50KHRoaXMudXRpbC5nZXRQYXJlbnRFbGVtZW50KGVsZW1lbnQsICdGSUdVUkUnKSwgJ0ZJR0NBUFRJT04nKTtcbiAgICAgICAgICAgIGlmIChmaWdjYXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgZmlnY2FwdGlvbi5zdHlsZS5tYXJnaW5Ub3AgPSAodGhpcy5jb250ZXh0LnJlc2l6aW5nLl9yb3RhdGVWZXJ0aWNhbCA/IGVsZW1lbnQub2Zmc2V0V2lkdGggLSBlbGVtZW50Lm9mZnNldEhlaWdodCA6IDApICsgJ3B4JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICBcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBNb3VzZSBkb3duIGV2ZW50IG9mIHJlc2l6ZSBoYW5kbGVzXG4gICAgICAgICAqIEBwYXJhbSB7TW91c2VFdmVudH0gZSBFdmVudCBvYmplY3QgXG4gICAgICAgICAqL1xuICAgICAgICBvbk1vdXNlRG93bl9yZXNpemVfaGFuZGxlOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29uc3QgY29udGV4dFJlc2l6aW5nID0gdGhpcy5jb250ZXh0LnJlc2l6aW5nO1xuICAgICAgICAgICAgY29uc3QgZGlyZWN0aW9uID0gY29udGV4dFJlc2l6aW5nLl9yZXNpemVfZGlyZWN0aW9uID0gZS50YXJnZXQuY2xhc3NMaXN0WzBdO1xuICAgIFxuICAgICAgICAgICAgY29udGV4dFJlc2l6aW5nLl9yZXNpemVDbGllbnRYID0gZS5jbGllbnRYO1xuICAgICAgICAgICAgY29udGV4dFJlc2l6aW5nLl9yZXNpemVDbGllbnRZID0gZS5jbGllbnRZO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmVsZW1lbnQucmVzaXplQmFja2dyb3VuZC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgICAgIGNvbnRleHRSZXNpemluZy5yZXNpemVCdXR0b24uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIGNvbnRleHRSZXNpemluZy5yZXNpemVEaXYuc3R5bGUuZmxvYXQgPSAvbC8udGVzdChkaXJlY3Rpb24pID8gJ3JpZ2h0JyA6IC9yLy50ZXN0KGRpcmVjdGlvbikgPyAnbGVmdCcgOiAnbm9uZSc7XG4gICAgXG4gICAgICAgICAgICBjb25zdCBjbG9zdXJlRnVuY19iaW5kID0gZnVuY3Rpb24gY2xvc3VyZUZ1bmMoZSkge1xuICAgICAgICAgICAgICAgIGlmIChlLnR5cGUgPT09ICdrZXlkb3duJyAmJiBlLmtleUNvZGUgIT09IDI3KSByZXR1cm47XG4gICAgXG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbmdlID0gY29udGV4dFJlc2l6aW5nLl9pc0NoYW5nZTtcbiAgICAgICAgICAgICAgICBjb250ZXh0UmVzaXppbmcuX2lzQ2hhbmdlID0gZmFsc2U7XG4gICAgXG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVEb2NFdmVudCgnbW91c2Vtb3ZlJywgcmVzaXppbmdfZWxlbWVudF9iaW5kKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZURvY0V2ZW50KCdtb3VzZXVwJywgY2xvc3VyZUZ1bmNfYmluZCk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVEb2NFdmVudCgna2V5ZG93bicsIGNsb3N1cmVGdW5jX2JpbmQpO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmIChlLnR5cGUgPT09ICdrZXlkb3duJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRyb2xsZXJzT2ZmKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC5lbGVtZW50LnJlc2l6ZUJhY2tncm91bmQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zW3RoaXMuY29udGV4dC5yZXNpemluZy5fcmVzaXplX3BsdWdpbl0uaW5pdC5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGVsZW1lbnQgcmVzaXplXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2lucy5yZXNpemluZy5jYW5jZWxfY29udHJvbGxlcl9yZXNpemUuY2FsbCh0aGlzLCBkaXJlY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAvLyBoaXN0b3J5IHN0YWNrXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGFuZ2UpIHRoaXMuaGlzdG9yeS5wdXNoKGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LmJpbmQodGhpcyk7XG4gICAgXG4gICAgICAgICAgICBjb25zdCByZXNpemluZ19lbGVtZW50X2JpbmQgPSB0aGlzLnBsdWdpbnMucmVzaXppbmcucmVzaXppbmdfZWxlbWVudC5iaW5kKHRoaXMsIGNvbnRleHRSZXNpemluZywgZGlyZWN0aW9uLCB0aGlzLmNvbnRleHRbY29udGV4dFJlc2l6aW5nLl9yZXNpemVfcGx1Z2luXSk7XG4gICAgICAgICAgICB0aGlzLmFkZERvY0V2ZW50KCdtb3VzZW1vdmUnLCByZXNpemluZ19lbGVtZW50X2JpbmQpO1xuICAgICAgICAgICAgdGhpcy5hZGREb2NFdmVudCgnbW91c2V1cCcsIGNsb3N1cmVGdW5jX2JpbmQpO1xuICAgICAgICAgICAgdGhpcy5hZGREb2NFdmVudCgna2V5ZG93bicsIGNsb3N1cmVGdW5jX2JpbmQpO1xuICAgICAgICB9LFxuICAgIFxuICAgICAgICAvKipcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIE1vdXNlIG1vdmUgZXZlbnQgYWZ0ZXIgY2FsbCBcIm9uTW91c2VEb3duX3Jlc2l6ZV9oYW5kbGVcIiBvZiByZXNpemUgaGFuZGxlc1xuICAgICAgICAgKiBUaGUgc2l6ZSBvZiB0aGUgbW9kdWxlJ3MgXCJkaXZcIiBpcyBhZGp1c3RlZCBhY2NvcmRpbmcgdG8gdGhlIG1vdXNlIG1vdmUgZXZlbnQuXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0UmVzaXppbmcgXCJjb3JlLmNvbnRleHQucmVzaXppbmdcIiBvYmplY3QgKGJpbmRpbmcgYXJndW1lbnQpXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBkaXJlY3Rpb24gRGlyZWN0aW9uIChcInRsXCIsIFwidHJcIiwgXCJibFwiLCBcImJyXCIsIFwibHdcIiwgXCJ0aFwiLCBcInJ3XCIsIFwiYmhcIikgKGJpbmRpbmcgYXJndW1lbnQpXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwbHVnaW4gXCJjb3JlLmNvbnRleHRbY3VycmVudFBsdWdpbl1cIiBvYmplY3QgKGJpbmRpbmcgYXJndW1lbnQpXG4gICAgICAgICAqIEBwYXJhbSB7TW91c2VFdmVudH0gZSBFdmVudCBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIHJlc2l6aW5nX2VsZW1lbnQ6IGZ1bmN0aW9uIChjb250ZXh0UmVzaXppbmcsIGRpcmVjdGlvbiwgcGx1Z2luLCBlKSB7XG4gICAgICAgICAgICBjb25zdCBjbGllbnRYID0gZS5jbGllbnRYO1xuICAgICAgICAgICAgY29uc3QgY2xpZW50WSA9IGUuY2xpZW50WTtcbiAgICBcbiAgICAgICAgICAgIGxldCByZXN1bHRXID0gcGx1Z2luLl9lbGVtZW50X3c7XG4gICAgICAgICAgICBsZXQgcmVzdWx0SCA9IHBsdWdpbi5fZWxlbWVudF9oO1xuICAgIFxuICAgICAgICAgICAgY29uc3QgdyA9IHBsdWdpbi5fZWxlbWVudF93ICsgKC9yLy50ZXN0KGRpcmVjdGlvbikgPyBjbGllbnRYIC0gY29udGV4dFJlc2l6aW5nLl9yZXNpemVDbGllbnRYIDogY29udGV4dFJlc2l6aW5nLl9yZXNpemVDbGllbnRYIC0gY2xpZW50WCk7XG4gICAgICAgICAgICBjb25zdCBoID0gcGx1Z2luLl9lbGVtZW50X2ggKyAoL2IvLnRlc3QoZGlyZWN0aW9uKSA/IGNsaWVudFkgLSBjb250ZXh0UmVzaXppbmcuX3Jlc2l6ZUNsaWVudFkgOiBjb250ZXh0UmVzaXppbmcuX3Jlc2l6ZUNsaWVudFkgLSBjbGllbnRZKTtcbiAgICAgICAgICAgIGNvbnN0IHdoID0gKChwbHVnaW4uX2VsZW1lbnRfaCAvIHBsdWdpbi5fZWxlbWVudF93KSAqIHcpO1xuICAgIFxuICAgICAgICAgICAgaWYgKC90Ly50ZXN0KGRpcmVjdGlvbikpIGNvbnRleHRSZXNpemluZy5yZXNpemVEaXYuc3R5bGUudG9wID0gKHBsdWdpbi5fZWxlbWVudF9oIC0gKC9oLy50ZXN0KGRpcmVjdGlvbikgPyBoIDogd2gpKSArICdweCc7XG4gICAgICAgICAgICBpZiAoL2wvLnRlc3QoZGlyZWN0aW9uKSkgY29udGV4dFJlc2l6aW5nLnJlc2l6ZURpdi5zdHlsZS5sZWZ0ID0gKHBsdWdpbi5fZWxlbWVudF93IC0gdykgKyAncHgnO1xuICAgIFxuICAgICAgICAgICAgaWYgKC9yfGwvLnRlc3QoZGlyZWN0aW9uKSkge1xuICAgICAgICAgICAgICAgIGNvbnRleHRSZXNpemluZy5yZXNpemVEaXYuc3R5bGUud2lkdGggPSB3ICsgJ3B4JztcbiAgICAgICAgICAgICAgICByZXN1bHRXID0gdztcbiAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgIGlmICgvXih0fGIpW15oXSQvLnRlc3QoZGlyZWN0aW9uKSkge1xuICAgICAgICAgICAgICAgIGNvbnRleHRSZXNpemluZy5yZXNpemVEaXYuc3R5bGUuaGVpZ2h0ID0gd2ggKyAncHgnO1xuICAgICAgICAgICAgICAgIHJlc3VsdEggPSB3aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKC9eKHR8YiloJC8udGVzdChkaXJlY3Rpb24pKSB7XG4gICAgICAgICAgICAgICAgY29udGV4dFJlc2l6aW5nLnJlc2l6ZURpdi5zdHlsZS5oZWlnaHQgPSBoICsgJ3B4JztcbiAgICAgICAgICAgICAgICByZXN1bHRIID0gaDtcbiAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgIGNvbnRleHRSZXNpemluZy5fcmVzaXplX3cgPSByZXN1bHRXO1xuICAgICAgICAgICAgY29udGV4dFJlc2l6aW5nLl9yZXNpemVfaCA9IHJlc3VsdEg7XG4gICAgICAgICAgICB0aGlzLnV0aWwuY2hhbmdlVHh0KGNvbnRleHRSZXNpemluZy5yZXNpemVEaXNwbGF5LCB0aGlzLl93Lk1hdGgucm91bmQocmVzdWx0VykgKyAnIHggJyArIHRoaXMuX3cuTWF0aC5yb3VuZChyZXN1bHRIKSk7XG4gICAgICAgICAgICBjb250ZXh0UmVzaXppbmcuX2lzQ2hhbmdlID0gdHJ1ZTtcbiAgICAgICAgfSxcbiAgICBcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBSZXNpemUgdGhlIGVsZW1lbnQgdG8gdGhlIHNpemUgb2YgdGhlIFwiZGl2XCIgYWRqdXN0ZWQgaW4gdGhlIFwicmVzaXppbmdfZWxlbWVudFwiIG1ldGhvZC5cbiAgICAgICAgICogQ2FsbGVkIGF0IHRoZSBtb3VzZS11cCBldmVudCByZWdpc3RlcmVkIGluIFwib25Nb3VzZURvd25fcmVzaXplX2hhbmRsZVwiLlxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gZGlyZWN0aW9uIERpcmVjdGlvbiAoXCJ0bFwiLCBcInRyXCIsIFwiYmxcIiwgXCJiclwiLCBcImx3XCIsIFwidGhcIiwgXCJyd1wiLCBcImJoXCIpXG4gICAgICAgICAqL1xuICAgICAgICBjYW5jZWxfY29udHJvbGxlcl9yZXNpemU6IGZ1bmN0aW9uIChkaXJlY3Rpb24pIHtcbiAgICAgICAgICAgIGNvbnN0IGlzVmVydGljYWwgPSB0aGlzLmNvbnRleHQucmVzaXppbmcuX3JvdGF0ZVZlcnRpY2FsO1xuICAgICAgICAgICAgdGhpcy5jb250cm9sbGVyc09mZigpO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmVsZW1lbnQucmVzaXplQmFja2dyb3VuZC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIFxuICAgICAgICAgICAgbGV0IHcgPSB0aGlzLl93Lk1hdGgucm91bmQoaXNWZXJ0aWNhbCA/IHRoaXMuY29udGV4dC5yZXNpemluZy5fcmVzaXplX2ggOiB0aGlzLmNvbnRleHQucmVzaXppbmcuX3Jlc2l6ZV93KTtcbiAgICAgICAgICAgIGxldCBoID0gdGhpcy5fdy5NYXRoLnJvdW5kKGlzVmVydGljYWwgPyB0aGlzLmNvbnRleHQucmVzaXppbmcuX3Jlc2l6ZV93IDogdGhpcy5jb250ZXh0LnJlc2l6aW5nLl9yZXNpemVfaCk7XG4gICAgXG4gICAgICAgICAgICBpZiAoIWlzVmVydGljYWwgJiYgIS8lJC8udGVzdCh3KSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhZGRpbmcgPSAxNjtcbiAgICAgICAgICAgICAgICBjb25zdCBsaW1pdCA9IHRoaXMuY29udGV4dC5lbGVtZW50Lnd5c2l3eWdGcmFtZS5jbGllbnRXaWR0aCAtIChwYWRkaW5nICogMikgLSAyO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnV0aWwuZ2V0TnVtYmVyKHcsIDApID4gbGltaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgaCA9IHRoaXMuX3cuTWF0aC5yb3VuZCgoaCAvIHcpICogbGltaXQpO1xuICAgICAgICAgICAgICAgICAgICB3ID0gbGltaXQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgY29uc3QgcGx1Z2luTmFtZSA9IHRoaXMuY29udGV4dC5yZXNpemluZy5fcmVzaXplX3BsdWdpbjtcbiAgICAgICAgICAgIHRoaXMucGx1Z2luc1twbHVnaW5OYW1lXS5zZXRTaXplLmNhbGwodGhpcywgdywgaCwgZmFsc2UsIGRpcmVjdGlvbik7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdENvbXBvbmVudCh0aGlzLmNvbnRleHRbcGx1Z2luTmFtZV0uX2VsZW1lbnQsIHBsdWdpbk5hbWUpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGlmICh0eXBlb2Ygbm9HbG9iYWwgPT09IHR5cGVvZiB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCF3aW5kb3cuU1VORURJVE9SX01PRFVMRVMpIHtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3csICdTVU5FRElUT1JfTU9EVUxFUycsIHtcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB7fVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LlNVTkVESVRPUl9NT0RVTEVTLCAncmVzaXppbmcnLCB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiByZXNpemluZ1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzaXppbmc7XG59KSk7IiwiLypcbiAqIHd5c2l3eWcgd2ViIGVkaXRvclxuICpcbiAqIHN1bmVkaXRvci5qc1xuICogQ29weXJpZ2h0IDIwMTcgSmlIb25nIExlZS5cbiAqIE1JVCBsaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gICAgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBnbG9iYWwuZG9jdW1lbnQgP1xuICAgICAgICAgICAgZmFjdG9yeShnbG9iYWwsIHRydWUpIDpcbiAgICAgICAgICAgIGZ1bmN0aW9uICh3KSB7XG4gICAgICAgICAgICAgICAgaWYgKCF3LmRvY3VtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU1VORURJVE9SX01PRFVMRVMgYSB3aW5kb3cgd2l0aCBhIGRvY3VtZW50Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWN0b3J5KHcpO1xuICAgICAgICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBmYWN0b3J5KGdsb2JhbCk7XG4gICAgfVxufSh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHRoaXMsIGZ1bmN0aW9uICh3aW5kb3csIG5vR2xvYmFsKSB7XG4gICAgY29uc3QgZmlsZU1hbmFnZXIgPSB7XG4gICAgICAgIG5hbWU6ICdmaWxlTWFuYWdlcicsXG4gICAgICAgIF94bWxIdHRwOiBudWxsLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gVXBsb2FkIHRoZSBmaWxlIHRvIHRoZSBzZXJ2ZXIuXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSB1cGxvYWRVcmwgVXBsb2FkIHNlcnZlciB1cmxcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R8bnVsbH0gdXBsb2FkSGVhZGVyIFJlcXVlc3QgaGVhZGVyXG4gICAgICAgICAqIEBwYXJhbSB7Rm9ybURhdGF9IGZvcm1EYXRhIEZvcm1EYXRhIGluIGJvZHlcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbnxudWxsfSBjYWxsQmFjayBTdWNjZXNzIGNhbGwgYmFjayBmdW5jdGlvblxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufG51bGx9IGVycm9yQ2FsbEJhY2sgRXJyb3IgY2FsbCBiYWNrIGZ1bmN0aW9uXG4gICAgICAgICAqIEBleGFtcGxlIHRoaXMucGx1Z2lucy5maWxlTWFuYWdlci51cGxvYWQuY2FsbCh0aGlzLCBpbWFnZVVwbG9hZFVybCwgdGhpcy5jb250ZXh0Lm9wdGlvbi5pbWFnZVVwbG9hZEhlYWRlciwgZm9ybURhdGEsIHRoaXMucGx1Z2lucy5pbWFnZS5jYWxsQmFja19pbWdVcGxvYWQuYmluZCh0aGlzLCBpbmZvKSwgdGhpcy5mdW5jdGlvbnMub25JbWFnZVVwbG9hZEVycm9yKTtcbiAgICAgICAgICovXG4gICAgICAgIHVwbG9hZDogZnVuY3Rpb24gKHVwbG9hZFVybCwgdXBsb2FkSGVhZGVyLCBmb3JtRGF0YSwgY2FsbEJhY2ssIGVycm9yQ2FsbEJhY2spIHtcbiAgICAgICAgICAgIHRoaXMuc2hvd0xvYWRpbmcoKTtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVQbHVnaW4gPSB0aGlzLnBsdWdpbnMuZmlsZU1hbmFnZXI7XG4gICAgICAgICAgICBjb25zdCB4bWxIdHRwID0gZmlsZVBsdWdpbi5feG1sSHR0cCA9IHRoaXMudXRpbC5nZXRYTUxIdHRwUmVxdWVzdCgpO1xuXG4gICAgICAgICAgICB4bWxIdHRwLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZpbGVQbHVnaW4uX2NhbGxCYWNrVXBsb2FkLmJpbmQodGhpcywgeG1sSHR0cCwgY2FsbEJhY2ssIGVycm9yQ2FsbEJhY2spO1xuICAgICAgICAgICAgeG1sSHR0cC5vcGVuKCdwb3N0JywgdXBsb2FkVXJsLCB0cnVlKTtcbiAgICAgICAgICAgIGlmKHVwbG9hZEhlYWRlciAhPT0gbnVsbCAmJiB0eXBlb2YgdXBsb2FkSGVhZGVyID09PSAnb2JqZWN0JyAmJiB0aGlzLl93Lk9iamVjdC5rZXlzKHVwbG9hZEhlYWRlcikubGVuZ3RoID4gMCl7XG4gICAgICAgICAgICAgICAgZm9yKGxldCBrZXkgaW4gdXBsb2FkSGVhZGVyKXtcbiAgICAgICAgICAgICAgICAgICAgeG1sSHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgdXBsb2FkSGVhZGVyW2tleV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHhtbEh0dHAuc2VuZChmb3JtRGF0YSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2NhbGxCYWNrVXBsb2FkOiBmdW5jdGlvbiAoeG1sSHR0cCwgY2FsbEJhY2ssIGVycm9yQ2FsbEJhY2spIHtcbiAgICAgICAgICAgIGlmICh4bWxIdHRwLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICBpZiAoeG1sSHR0cC5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbEJhY2soeG1sSHR0cCk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKCdbU1VORURJVE9SLmZpbGVNYW5hZ2VyLnVwbG9hZC5jYWxsQmFjay5mYWlsXSBjYXVzZSA6IFwiJyArIGUubWVzc2FnZSArICdcIicpO1xuICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbG9zZUxvYWRpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIGV4Y2VwdGlvblxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNsb3NlTG9hZGluZygpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXMgPSAheG1sSHR0cC5yZXNwb25zZVRleHQgPyB4bWxIdHRwIDogSlNPTi5wYXJzZSh4bWxIdHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZXJyb3JDYWxsQmFjayAhPT0gJ2Z1bmN0aW9uJyB8fCBlcnJvckNhbGxCYWNrKCcnLCByZXMsIHRoaXMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnIgPSAnW1NVTkVESVRPUi5maWxlTWFuYWdlci51cGxvYWQuc2VydmVyRXhjZXB0aW9uXSBzdGF0dXM6ICcgKyB4bWxIdHRwLnN0YXR1cyArICcsIHJlc3BvbnNlOiAnICsgKHJlcy5lcnJvck1lc3NhZ2UgfHwgeG1sSHR0cC5yZXNwb25zZVRleHQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mdW5jdGlvbnMubm90aWNlT3BlbihlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ2hlY2tlIHRoZSBmaWxlJ3MgaW5mb3JtYXRpb24gYW5kIG1vZGlmeSB0aGUgdGFnIHRoYXQgZG9lcyBub3QgZml0IHRoZSBmb3JtYXQuXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBwbHVnaW5OYW1lIFBsdWdpbiBuYW1lXG4gICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IHRhZ05hbWVzIFRhZyBhcnJheSB0byBjaGVja1xuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufG51bGx9IHVwbG9hZEV2ZW50SGFuZGxlciBFdmVudCBoYW5kbGVyIHRvIHByb2Nlc3MgdXBkYXRlZCBmaWxlIGluZm8gYWZ0ZXIgY2hlY2tpbmcgKHVzZWQgaW4gXCJzZXRJbmZvXCIpXG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG1vZGlmeUhhbmRsZXIgQSBmdW5jdGlvbiB0byBtb2RpZnkgYSB0YWcgdGhhdCBkb2VzIG5vdCBmaXQgdGhlIGZvcm1hdCAoQXJndW1lbnQgdmFsdWU6IFRhZyBlbGVtZW50KVxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJlc2l6aW5nIFRydWUgaWYgdGhlIHBsdWdpbiBpcyB1c2luZyBhIHJlc2l6aW5nIG1vZHVsZVxuICAgICAgICAgKiBAZXhhbXBsZSBcbiAgICAgICAgICogY29uc3QgbW9kaWZ5SGFuZGxlciA9IGZ1bmN0aW9uICh0YWcpIHtcbiAgICAgICAgICogICAgICBpbWFnZVBsdWdpbi5vbk1vZGlmeU1vZGUuY2FsbCh0aGlzLCB0YWcsIG51bGwpO1xuICAgICAgICAgKiAgICAgIGltYWdlUGx1Z2luLm9wZW5Nb2RpZnkuY2FsbCh0aGlzLCB0cnVlKTtcbiAgICAgICAgICogICAgICBpbWFnZVBsdWdpbi51cGRhdGVfaW1hZ2UuY2FsbCh0aGlzLCB0cnVlLCBmYWxzZSwgdHJ1ZSk7XG4gICAgICAgICAqICB9LmJpbmQodGhpcyk7XG4gICAgICAgICAqICB0aGlzLnBsdWdpbnMuZmlsZU1hbmFnZXIuY2hlY2tJbmZvLmNhbGwodGhpcywgJ2ltYWdlJywgWydpbWcnXSwgdGhpcy5mdW5jdGlvbnMub25JbWFnZVVwbG9hZCwgbW9kaWZ5SGFuZGxlciwgdHJ1ZSk7XG4gICAgICAgICAqL1xuICAgICAgICBjaGVja0luZm86IGZ1bmN0aW9uIChwbHVnaW5OYW1lLCB0YWdOYW1lcywgdXBsb2FkRXZlbnRIYW5kbGVyLCBtb2RpZnlIYW5kbGVyLCByZXNpemluZykge1xuICAgICAgICAgICAgbGV0IHRhZ3MgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSB0YWdOYW1lcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIHRhZ3MgPSB0YWdzLmNvbmNhdChbXS5zbGljZS5jYWxsKHRoaXMuY29udGV4dC5lbGVtZW50Lnd5c2l3eWcuZ2V0RWxlbWVudHNCeVRhZ05hbWUodGFnTmFtZXNbaV0pKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmNvbnRleHRbcGx1Z2luTmFtZV07XG4gICAgICAgICAgICBjb25zdCBpbmZvTGlzdCA9IGNvbnRleHQuX2luZm9MaXN0O1xuICAgICAgICAgICAgY29uc3Qgc2V0RmlsZUluZm8gPSB0aGlzLnBsdWdpbnMuZmlsZU1hbmFnZXIuc2V0SW5mby5iaW5kKHRoaXMpO1xuXG4gICAgICAgICAgICBpZiAodGFncy5sZW5ndGggPT09IGluZm9MaXN0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIC8vIHJlc2V0XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2NvbXBvbmVudHNJbmZvUmVzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHRhZ3MubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldEZpbGVJbmZvKHBsdWdpbk5hbWUsIHRhZ3NbaV0sIHVwbG9hZEV2ZW50SGFuZGxlciwgbnVsbCwgcmVzaXppbmcpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGluZm9VcGRhdGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGluZm9MaXN0Lmxlbmd0aCwgaW5mbzsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbmZvID0gaW5mb0xpc3RbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFncy5maWx0ZXIoZnVuY3Rpb24gKHQpIHsgcmV0dXJuIGluZm8uc3JjID09PSB0LnNyYyAmJiBpbmZvLmluZGV4LnRvU3RyaW5nKCkgPT09IHQuZ2V0QXR0cmlidXRlKCdkYXRhLWluZGV4Jyk7IH0pLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm9VcGRhdGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIHBhc3NcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpbmZvVXBkYXRlKSByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBjaGVja1xuICAgICAgICAgICAgY29uc3QgX3Jlc2l6ZV9wbHVnaW4gPSByZXNpemluZyA/IHRoaXMuY29udGV4dC5yZXNpemluZy5fcmVzaXplX3BsdWdpbiA6ICcnO1xuICAgICAgICAgICAgaWYgKHJlc2l6aW5nKSB0aGlzLmNvbnRleHQucmVzaXppbmcuX3Jlc2l6ZV9wbHVnaW4gPSBwbHVnaW5OYW1lO1xuICAgICAgICAgICAgY29uc3QgY3VycmVudFRhZ3MgPSBbXTtcbiAgICAgICAgICAgIGNvbnN0IGluZm9JbmRleCA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGluZm9MaXN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaW5mb0luZGV4W2ldID0gaW5mb0xpc3RbaV0uaW5kZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSB0YWdzLmxlbmd0aCwgdGFnOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0YWcgPSB0YWdzW2ldO1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy51dGlsLmdldFBhcmVudEVsZW1lbnQodGFnLCB0aGlzLnV0aWwuaXNNZWRpYUNvbXBvbmVudCkgfHwgIS9GSUdVUkUvaS50ZXN0KHRhZy5wYXJlbnRFbGVtZW50Lm5vZGVOYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50VGFncy5wdXNoKGNvbnRleHQuX2luZm9JbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIG1vZGlmeUhhbmRsZXIodGFnKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCF0YWcuZ2V0QXR0cmlidXRlKCdkYXRhLWluZGV4JykgfHwgaW5mb0luZGV4LmluZGV4T2YodGFnLmdldEF0dHJpYnV0ZSgnZGF0YS1pbmRleCcpICogMSkgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRUYWdzLnB1c2goY29udGV4dC5faW5mb0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgdGFnLnJlbW92ZUF0dHJpYnV0ZSgnZGF0YS1pbmRleCcpO1xuICAgICAgICAgICAgICAgICAgICBzZXRGaWxlSW5mbyhwbHVnaW5OYW1lLCB0YWcsIHVwbG9hZEV2ZW50SGFuZGxlciwgbnVsbCwgcmVzaXppbmcpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRUYWdzLnB1c2godGFnLmdldEF0dHJpYnV0ZSgnZGF0YS1pbmRleCcpICogMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgZGF0YUluZGV4OyBpIDwgaW5mb0xpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBkYXRhSW5kZXggPSBpbmZvTGlzdFtpXS5pbmRleDtcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudFRhZ3MuaW5kZXhPZihkYXRhSW5kZXgpID4gLTEpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICAgICAgaW5mb0xpc3Quc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdXBsb2FkRXZlbnRIYW5kbGVyID09PSAnZnVuY3Rpb24nKSB1cGxvYWRFdmVudEhhbmRsZXIobnVsbCwgZGF0YUluZGV4LCAnZGVsZXRlJywgbnVsbCwgMCwgdGhpcyk7XG4gICAgICAgICAgICAgICAgaS0tO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVzaXppbmcpIHRoaXMuY29udGV4dC5yZXNpemluZy5fcmVzaXplX3BsdWdpbiA9IF9yZXNpemVfcGx1Z2luO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlIGluZm8gb2JqZWN0IG9mIGZpbGUgYW5kIGFkZCBpdCB0byBcIl9pbmZvTGlzdFwiICh0aGlzLmNvbnRleHRbcGx1Z2luTmFtZV0uX2luZm9MaXN0W10pXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBwbHVnaW5OYW1lIFBsdWdpbiBuYW1lIFxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgXG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb258bnVsbH0gdXBsb2FkRXZlbnRIYW5kbGVyIEV2ZW50IGhhbmRsZXIgdG8gcHJvY2VzcyB1cGRhdGVkIGZpbGUgaW5mbyAoY3JlYXRlZCBpbiBzZXRJbmZvKVxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdHxudWxsfSBmaWxlIFxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJlc2l6aW5nIFRydWUgaWYgdGhlIHBsdWdpbiBpcyB1c2luZyBhIHJlc2l6aW5nIG1vZHVsZVxuICAgICAgICAgKiBAZXhhbXBsZSBcbiAgICAgICAgICogdXBsb2FkQ2FsbEJhY2sgey4uIGZpbGUgPSB7IG5hbWU6IGZpbGVMaXN0W2ldLm5hbWUsIHNpemU6IGZpbGVMaXN0W2ldLnNpemUgfTtcbiAgICAgICAgICogdGhpcy5wbHVnaW5zLmZpbGVNYW5hZ2VyLnNldEluZm8uY2FsbCh0aGlzLCAnaW1hZ2UnLCBvSW1nLCB0aGlzLmZ1bmN0aW9ucy5vbkltYWdlVXBsb2FkLCBmaWxlLCB0cnVlKTtcbiAgICAgICAgICovXG4gICAgICAgIHNldEluZm86IGZ1bmN0aW9uIChwbHVnaW5OYW1lLCBlbGVtZW50LCB1cGxvYWRFdmVudEhhbmRsZXIsIGZpbGUsIHJlc2l6aW5nKSB7XG4gICAgICAgICAgICBjb25zdCBfcmVzaXplX3BsdWdpbiA9IHJlc2l6aW5nID8gdGhpcy5jb250ZXh0LnJlc2l6aW5nLl9yZXNpemVfcGx1Z2luIDogJyc7XG4gICAgICAgICAgICBpZiAocmVzaXppbmcpIHRoaXMuY29udGV4dC5yZXNpemluZy5fcmVzaXplX3BsdWdpbiA9IHBsdWdpbk5hbWU7XG4gICAgXG4gICAgICAgICAgICBjb25zdCBwbGd1aW4gPSB0aGlzLnBsdWdpbnNbcGx1Z2luTmFtZV07XG4gICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5jb250ZXh0W3BsdWdpbk5hbWVdO1xuICAgICAgICAgICAgY29uc3QgaW5mb0xpc3QgPSBjb250ZXh0Ll9pbmZvTGlzdDtcbiAgICAgICAgICAgIGxldCBkYXRhSW5kZXggPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1pbmRleCcpO1xuICAgICAgICAgICAgbGV0IGluZm8gPSBudWxsO1xuICAgICAgICAgICAgbGV0IHN0YXRlID0gJyc7XG5cbiAgICAgICAgICAgIGlmICghZmlsZSkge1xuICAgICAgICAgICAgICAgIGZpbGUgPSB7XG4gICAgICAgICAgICAgICAgICAgICduYW1lJzogZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtZmlsZS1uYW1lJykgfHwgKHR5cGVvZiBlbGVtZW50LnNyYyA9PT0gJ3N0cmluZycgPyBlbGVtZW50LnNyYy5zcGxpdCgnLycpLnBvcCgpIDogJycpLFxuICAgICAgICAgICAgICAgICAgICAnc2l6ZSc6IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWZpbGUtc2l6ZScpIHx8IDBcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgLy8gY3JlYXRlXG4gICAgICAgICAgICBpZiAoIWRhdGFJbmRleCB8fCB0aGlzLl9jb21wb25lbnRzSW5mb0luaXQpIHtcbiAgICAgICAgICAgICAgICBzdGF0ZSA9ICdjcmVhdGUnO1xuICAgICAgICAgICAgICAgIGRhdGFJbmRleCA9IGNvbnRleHQuX2luZm9JbmRleCsrO1xuICAgIFxuICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLWluZGV4JywgZGF0YUluZGV4KTtcbiAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1maWxlLW5hbWUnLCBmaWxlLm5hbWUpO1xuICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLWZpbGUtc2l6ZScsIGZpbGUuc2l6ZSk7XG4gICAgXG4gICAgICAgICAgICAgICAgaW5mbyA9IHtcbiAgICAgICAgICAgICAgICAgICAgc3JjOiBlbGVtZW50LnNyYyxcbiAgICAgICAgICAgICAgICAgICAgaW5kZXg6IGRhdGFJbmRleCAqIDEsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IGZpbGUubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgc2l6ZTogZmlsZS5zaXplXG4gICAgICAgICAgICAgICAgfTtcbiAgICBcbiAgICAgICAgICAgICAgICBpbmZvTGlzdC5wdXNoKGluZm8pO1xuICAgICAgICAgICAgfSBlbHNlIHsgLy8gdXBkYXRlXG4gICAgICAgICAgICAgICAgc3RhdGUgPSAndXBkYXRlJztcbiAgICAgICAgICAgICAgICBkYXRhSW5kZXggKj0gMTtcbiAgICBcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gaW5mb0xpc3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFJbmRleCA9PT0gaW5mb0xpc3RbaV0uaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZm8gPSBpbmZvTGlzdFtpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgICAgIGlmICghaW5mbykge1xuICAgICAgICAgICAgICAgICAgICBkYXRhSW5kZXggPSBjb250ZXh0Ll9pbmZvSW5kZXgrKztcbiAgICAgICAgICAgICAgICAgICAgaW5mbyA9IHsgaW5kZXg6IGRhdGFJbmRleCB9O1xuICAgICAgICAgICAgICAgICAgICBpbmZvTGlzdC5wdXNoKGluZm8pO1xuICAgICAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgICAgICBpbmZvLnNyYyA9IGVsZW1lbnQuc3JjO1xuICAgICAgICAgICAgICAgIGluZm8ubmFtZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1maWxlLW5hbWVcIik7XG4gICAgICAgICAgICAgICAgaW5mby5zaXplID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWZpbGUtc2l6ZVwiKSAqIDE7XG4gICAgICAgICAgICB9XG4gICAgXG4gICAgICAgICAgICAvLyBtZXRob2QgYmluZFxuICAgICAgICAgICAgaW5mby5lbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgICAgIGluZm8uZGVsZXRlID0gcGxndWluLmRlc3Ryb3kuYmluZCh0aGlzLCBlbGVtZW50KTtcbiAgICAgICAgICAgIGluZm8uc2VsZWN0ID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LnNjcm9sbEludG9WaWV3KHRydWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3cuc2V0VGltZW91dChwbGd1aW4uc2VsZWN0LmJpbmQodGhpcywgZWxlbWVudCkpO1xuICAgICAgICAgICAgfS5iaW5kKHRoaXMsIGVsZW1lbnQpO1xuICAgIFxuICAgICAgICAgICAgaWYgKHJlc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFlbGVtZW50LmdldEF0dHJpYnV0ZSgnb3JpZ2luLXNpemUnKSAmJiBlbGVtZW50Lm5hdHVyYWxXaWR0aCkge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnb3JpZ2luLXNpemUnLCBlbGVtZW50Lm5hdHVyYWxXaWR0aCArICcsJyArIGVsZW1lbnQubmF0dXJhbEhlaWdodCk7XG4gICAgICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgICAgIGlmICghZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtb3JpZ2luJykpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29udGFpbmVyID0gdGhpcy51dGlsLmdldFBhcmVudEVsZW1lbnQoZWxlbWVudCwgdGhpcy51dGlsLmlzTWVkaWFDb21wb25lbnQpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb3ZlciA9IHRoaXMudXRpbC5nZXRQYXJlbnRFbGVtZW50KGVsZW1lbnQsICdGSUdVUkUnKTtcbiAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHcgPSB0aGlzLnBsdWdpbnMucmVzaXppbmcuX21vZHVsZV9nZXRTaXplWC5jYWxsKHRoaXMsIGNvbnRleHQsIGVsZW1lbnQsIGNvdmVyLCBjb250YWluZXIpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBoID0gdGhpcy5wbHVnaW5zLnJlc2l6aW5nLl9tb2R1bGVfZ2V0U2l6ZVkuY2FsbCh0aGlzLCBjb250ZXh0LCBlbGVtZW50LCBjb3ZlciwgY29udGFpbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2RhdGEtb3JpZ2luJywgdyArICcsJyArIGgpO1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1zaXplJywgdyArICcsJyArIGgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgICAgICAgICAgaWYgKCFlbGVtZW50LnN0eWxlLndpZHRoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemUgPSAoZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtc2l6ZScpIHx8IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLW9yaWdpbicpIHx8ICcnKS5zcGxpdCgnLCcpO1xuICAgICAgICAgICAgICAgICAgICBwbGd1aW4ub25Nb2RpZnlNb2RlLmNhbGwodGhpcywgZWxlbWVudCwgbnVsbCk7XG4gICAgICAgICAgICAgICAgICAgIHBsZ3Vpbi5hcHBseVNpemUuY2FsbCh0aGlzLCBzaXplWzBdLCBzaXplWzFdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC5yZXNpemluZy5fcmVzaXplX3BsdWdpbiA9IF9yZXNpemVfcGx1Z2luO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHVwbG9hZEV2ZW50SGFuZGxlciA9PT0gJ2Z1bmN0aW9uJykgdXBsb2FkRXZlbnRIYW5kbGVyKGVsZW1lbnQsIGRhdGFJbmRleCwgc3RhdGUsIGluZm8sIC0tY29udGV4dC5fdXBsb2FkRmlsZUxlbmd0aCA8IDAgPyAwIDogY29udGV4dC5fdXBsb2FkRmlsZUxlbmd0aCwgdGhpcyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBEZWxldGUgaW5mbyBvYmplY3QgYXQgXCJfaW5mb0xpc3RcIlxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gcGx1Z2luTmFtZSBQbHVnaW4gbmFtZSBcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IGluZGV4IGluZGV4IG9mIGluZm8gb2JqZWN0ICh0aGlzLmNvbnRleHRbcGx1Z2luTmFtZV0uX2luZm9MaXN0W10uaW5kZXgpXG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb258bnVsbH0gdXBsb2FkRXZlbnRIYW5kbGVyIEV2ZW50IGhhbmRsZXIgdG8gcHJvY2VzcyB1cGRhdGVkIGZpbGUgaW5mbyAoY3JlYXRlZCBpbiBzZXRJbmZvKVxuICAgICAgICAgKi9cbiAgICAgICAgZGVsZXRlSW5mbzogZnVuY3Rpb24gKHBsdWdpbk5hbWUsIGluZGV4LCB1cGxvYWRFdmVudEhhbmRsZXIpIHtcbiAgICAgICAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaW5mb0xpc3QgPSB0aGlzLmNvbnRleHRbcGx1Z2luTmFtZV0uX2luZm9MaXN0O1xuICAgIFxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBpbmZvTGlzdC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT09IGluZm9MaXN0W2ldLmluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbmZvTGlzdC5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHVwbG9hZEV2ZW50SGFuZGxlciA9PT0gJ2Z1bmN0aW9uJykgdXBsb2FkRXZlbnRIYW5kbGVyKG51bGwsIGluZGV4LCAnZGVsZXRlJywgbnVsbCwgMCwgdGhpcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBSZXNldCBpbmZvIG9iamVjdCBhbmQgXCJfaW5mb0xpc3QgPSBbXVwiLCBcIl9pbmZvSW5kZXggPSAwXCJcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHBsdWdpbk5hbWUgUGx1Z2luIG5hbWUgXG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb258bnVsbH0gdXBsb2FkRXZlbnRIYW5kbGVyIEV2ZW50IGhhbmRsZXIgdG8gcHJvY2VzcyB1cGRhdGVkIGZpbGUgaW5mbyAoY3JlYXRlZCBpbiBzZXRJbmZvKVxuICAgICAgICAgKi9cbiAgICAgICAgcmVzZXRJbmZvOiBmdW5jdGlvbiAocGx1Z2luTmFtZSwgdXBsb2FkRXZlbnRIYW5kbGVyKSB7XG4gICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5jb250ZXh0W3BsdWdpbk5hbWVdO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHVwbG9hZEV2ZW50SGFuZGxlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGluZm9MaXN0ID0gY29udGV4dC5faW5mb0xpc3Q7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGluZm9MaXN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHVwbG9hZEV2ZW50SGFuZGxlcihudWxsLCBpbmZvTGlzdFtpXS5pbmRleCwgJ2RlbGV0ZScsIG51bGwsIDAsIHRoaXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29udGV4dC5faW5mb0xpc3QgPSBbXTtcbiAgICAgICAgICAgIGNvbnRleHQuX2luZm9JbmRleCA9IDA7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHR5cGVvZiBub0dsb2JhbCA9PT0gdHlwZW9mIHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIXdpbmRvdy5TVU5FRElUT1JfTU9EVUxFUykge1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdywgJ1NVTkVESVRPUl9NT0RVTEVTJywge1xuICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgdmFsdWU6IHt9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuU1VORURJVE9SX01PRFVMRVMsICdmaWxlTWFuYWdlcicsIHtcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgdmFsdWU6IGZpbGVNYW5hZ2VyXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBmaWxlTWFuYWdlcjtcbn0pKTsiXSwic291cmNlUm9vdCI6IiJ9
\ No newline at end of file