@hotstaq/admin-panel 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +3 -2
- package/.vscode/launch.json +16 -23
- package/.vscode/tasks.json +11 -0
- package/HotSite.json +17 -4
- package/assets/html/admin-footer.hott +0 -4
- package/assets/html/admin-header.hott +36 -5
- package/assets/html/admin-sidebar.hott +13 -3
- package/build/src/WebExport.js +2 -2
- package/build/src/WebExport.js.map +1 -1
- package/build/src/cli.d.ts +2 -0
- package/build/src/cli.d.ts.map +1 -0
- package/{assets/components/admin-button.js → build/src/cli.js} +11 -41
- package/build/src/cli.js.map +1 -0
- package/build/src/components/admin-button.d.ts.map +1 -1
- package/build/src/components/admin-button.js.map +1 -1
- package/build/src/components/admin-dashboard.d.ts.map +1 -1
- package/build/src/components/admin-dashboard.js +2 -1
- package/build/src/components/admin-dashboard.js.map +1 -1
- package/build/src/components/admin-edit.d.ts +1 -1
- package/build/src/components/admin-edit.d.ts.map +1 -1
- package/build/src/components/admin-edit.js +2 -1
- package/build/src/components/admin-edit.js.map +1 -1
- package/build/src/components/admin-table-field.d.ts.map +1 -1
- package/build/src/components/admin-table-field.js +4 -2
- package/build/src/components/admin-table-field.js.map +1 -1
- package/build/src/components/admin-table-row.d.ts +3 -1
- package/build/src/components/admin-table-row.d.ts.map +1 -1
- package/build/src/components/admin-table-row.js +2 -6
- package/build/src/components/admin-table-row.js.map +1 -1
- package/build/src/components/admin-table.d.ts.map +1 -1
- package/build/src/components/admin-table.js +2 -1
- package/build/src/components/admin-table.js.map +1 -1
- package/build/src/components/admin-text.d.ts +1 -1
- package/build/src/components/admin-text.d.ts.map +1 -1
- package/build/src/components/admin-text.js +7 -2
- package/build/src/components/admin-text.js.map +1 -1
- package/build-web/AdminPanelComponents.js +2 -0
- package/build-web/AdminPanelWeb_AppAPI.js +238 -0
- package/docker-compose.yaml +39 -0
- package/env-example +1 -0
- package/package.json +5 -5
- package/src/WebExport.ts +2 -2
- package/src/cli.ts +7 -0
- package/src/components/admin-button.ts +3 -3
- package/src/components/admin-dashboard.ts +1 -2
- package/src/components/admin-edit.ts +3 -2
- package/src/components/admin-table-field.ts +3 -3
- package/src/components/admin-table-row.ts +4 -8
- package/src/components/admin-table.ts +1 -2
- package/src/components/admin-text.ts +8 -2
- package/start.sh +9 -0
- package/stop.sh +9 -0
- package/webpack.config.cjs +2 -2
- package/assets/components/admin-dashboard.js +0 -89
- package/assets/components/admin-edit.js +0 -124
- package/assets/components/admin-table-field.js +0 -91
- package/assets/components/admin-table-row.js +0 -104
- package/assets/components/admin-table.js +0 -190
- package/assets/components/admin-text.js +0 -94
- package/build-web/AdminPanel.js +0 -2
- package/build-web/admin-panel.yaml +0 -75
- package/public/index.hott +0 -16
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var AdminPanelComponentsWeb;(()=>{"use strict";var t={1:function(t,e,n){var i=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))((function(o,a){function s(t){try{r(i.next(t))}catch(t){a(t)}}function d(t){try{r(i.throw(t))}catch(t){a(t)}}function r(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,d)}r((i=i.apply(t,e||[])).next())}))};Object.defineProperty(e,"__esModule",{value:!0}),e.AdminText=e.AdminTableRow=e.AdminTableField=e.AdminTable=e.AdminEdit=e.AdminDashboard=e.AdminButton=e.buildAssets=void 0;const o=n(176);Object.defineProperty(e,"AdminButton",{enumerable:!0,get:function(){return o.AdminButton}});const a=n(50);Object.defineProperty(e,"AdminDashboard",{enumerable:!0,get:function(){return a.AdminDashboard}});const s=n(703);Object.defineProperty(e,"AdminEdit",{enumerable:!0,get:function(){return s.AdminEdit}});const d=n(952);Object.defineProperty(e,"AdminTable",{enumerable:!0,get:function(){return d.AdminTable}});const r=n(505);Object.defineProperty(e,"AdminTableField",{enumerable:!0,get:function(){return r.AdminTableField}});const l=n(412);Object.defineProperty(e,"AdminTableRow",{enumerable:!0,get:function(){return l.AdminTableRow}});const c=n(80);Object.defineProperty(e,"AdminText",{enumerable:!0,get:function(){return c.AdminText}}),e.buildAssets=function(){return i(this,void 0,void 0,(function*(){return{import:[{name:"bootstrap",files:["bootstrap.min.js","bootstrap.min.css"]},{name:"jquery",files:["jquery.min.js"]},"chart.js","feather-icons","@popperjs/core"],html:["./assets/html/*.*"],css:["./assets/css/*.*"],js:["./assets/js/*.*","./build-web/AdminPanelComponents.js"],componentLibrary:"AdminPanelComponentsWeb",components:[o.AdminButton,a.AdminDashboard,s.AdminEdit,d.AdminTable,r.AdminTableField,l.AdminTableRow,c.AdminText]}}))}},176:function(t,e,n){var i=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))((function(o,a){function s(t){try{r(i.next(t))}catch(t){a(t)}}function d(t){try{r(i.throw(t))}catch(t){a(t)}}function r(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,d)}r((i=i.apply(t,e||[])).next())}))};Object.defineProperty(e,"__esModule",{value:!0}),e.AdminButton=void 0;const o=n(607);class a extends o.HotComponent{constructor(t,e){super(t,e),this.tag="admin-button"}buttonClicked(){return i(this,void 0,void 0,(function*(){}))}output(){return i(this,void 0,void 0,(function*(){return`<button id = "${this.htmlElements[0].id}" onclick = "this.buttonClicked ();"></button>`}))}}e.AdminButton=a},50:function(t,e,n){var i=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))((function(o,a){function s(t){try{r(i.next(t))}catch(t){a(t)}}function d(t){try{r(i.throw(t))}catch(t){a(t)}}function r(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,d)}r((i=i.apply(t,e||[])).next())}))};Object.defineProperty(e,"__esModule",{value:!0}),e.AdminDashboard=void 0;const o=n(607);class a extends o.HotComponent{constructor(t,e){super(t,e),this.tag="admin-dashboard",this.title="",this.base=""}onPostPlace(t,e){return i(this,void 0,void 0,(function*(){""!=this.base&&(o.Hot.Data.baseUrl=this.base)}))}output(){return i(this,void 0,void 0,(function*(){return`\n\t\t<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">\n\t\t\t<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">\n\t\t\t\t<h1 class="h2">${this.title}</h1>\n\t\t\t\t<div class="btn-toolbar mb-2 mb-md-0">\n\t\t\t\t\t<div class="btn-group me-2">\n\t\t\t\t\t\t<hot-place-here name = "buttons"></hot-place-here>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<hot-place-here name = "body"></hot-place-here>\n\t\t</main>`}))}}e.AdminDashboard=a},703:function(t,e,n){var i=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))((function(o,a){function s(t){try{r(i.next(t))}catch(t){a(t)}}function d(t){try{r(i.throw(t))}catch(t){a(t)}}function r(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,d)}r((i=i.apply(t,e||[])).next())}))};Object.defineProperty(e,"__esModule",{value:!0}),e.AdminEdit=void 0;const o=n(607);class a extends o.HotComponent{constructor(t,e){super(t,e),this.tag="admin-edit",this.title="",this.button_title="",this.attached_list="",this.schema="",this.fieldElements={},this.modalId=""}onSave(){return i(this,void 0,void 0,(function*(){let t={};for(let e in this.fieldElements){let n=this.fieldElements[e].value;t[e]=n}yield o.Hot.jsonRequest(`${o.Hot.Data.baseUrl}/v1/data/add`,{schema:this.schema,fields:t});let e=document.getElementById(this.attached_list);yield e.hotComponent.refreshList(),$(`#${this.modalId}`).modal("hide")}))}output(){return i(this,void 0,void 0,(function*(){if(""===this.name)throw new Error("You must specify a name for each admin-edit element!");return this.modalId=`${this.name}Modal`,[{html:`\n\t\t\t\x3c!-- ${this.title} Modal Start --\x3e\n\t\t\t<div class="modal fade" id="${this.modalId}" tabindex="-1" aria-labelledby="${this.name}ModalLabel" aria-hidden="true">\n\t\t\t\t<div class="modal-dialog">\n\t\t\t\t\t<div class="modal-content">\n\t\t\t\t\t<div class="modal-header">\n\t\t\t\t\t\t<h5 class="modal-title" id="${this.name}ModalLabel">${this.title}</h5>\n\t\t\t\t\t\t<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class="modal-body">\n\t\t\t\t\t\t<hot-place-here name = "modalBody" type = "modal"></hot-place-here>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class="modal-footer">\n\t\t\t\t\t\t<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>\n\t\t\t\t\t\t<button type="button" class="btn btn-primary" onclick = "document.getElementById('${this.modalId}').onSave ();">${this.button_title}</button>\n\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t\x3c!-- ${this.title} Modal End --\x3e`,parentSelector:"body"},{html:`<button id = "${this.modalId}-add-btn" type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#${this.modalId}">Add</button>`,parentSelector:'hot-place-here[name="buttons"]'}]}))}}e.AdminEdit=a},505:function(t,e,n){var i=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))((function(o,a){function s(t){try{r(i.next(t))}catch(t){a(t)}}function d(t){try{r(i.throw(t))}catch(t){a(t)}}function r(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,d)}r((i=i.apply(t,e||[])).next())}))};Object.defineProperty(e,"__esModule",{value:!0}),e.AdminTableField=void 0;const o=n(607);class a extends o.HotComponent{constructor(t,e){super(t,e),this.tag="admin-table-field",this.field=0}onPostPlace(t,e){return i(this,void 0,void 0,(function*(){let n=t.parentNode.parentNode.parentNode.hotComponent;null!=n&&n.addHeaderDataOnly(this,e)}))}output(){return i(this,void 0,void 0,(function*(){return[{html:`<th>${this.inner}</th>`,placeHereParent:"header"}]}))}}e.AdminTableField=a},412:function(t,e,n){var i=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))((function(o,a){function s(t){try{r(i.next(t))}catch(t){a(t)}}function d(t){try{r(i.throw(t))}catch(t){a(t)}}function r(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,d)}r((i=i.apply(t,e||[])).next())}))};Object.defineProperty(e,"__esModule",{value:!0}),e.AdminTableRow=void 0;const o=n(607);class a extends o.HotComponent{constructor(t,e){super(t,e),this.tag="admin-table-row",this.fields=[]}onPostPlace(t,e){return i(this,void 0,void 0,(function*(){t.parentNode.parentNode.parentNode.hotComponent.rowElements.push({fields:this.fields,element:e})}))}output(){return i(this,void 0,void 0,(function*(){let t="";for(let e=0;e<this.fields.length;e++){let n=this.fields[e];for(let e in n)t+=`<td>${n[e]}</td>`}return[{html:`<tr>${t}</tr>`,placeHereParent:"results"}]}))}}e.AdminTableRow=a},952:function(t,e,n){var i=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))((function(o,a){function s(t){try{r(i.next(t))}catch(t){a(t)}}function d(t){try{r(i.throw(t))}catch(t){a(t)}}function r(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,d)}r((i=i.apply(t,e||[])).next())}))};Object.defineProperty(e,"__esModule",{value:!0}),e.AdminTable=void 0;const o=n(607);class a extends o.HotComponent{constructor(t,e){super(t,e),this.headerElements={},this.rowElements=[],this.tag="admin-table",this.title="",this.schema="",this.headerElements={},this.headerIndicies=[],this.rowElements=[]}addHeader(t){let e=this.htmlElements[0].getElementsByTagName("thead")[0];this.headerIndicies.push(t.hotComponent.field),e.appendChild(t)}addHeaderDataOnly(t,e){this.headerIndicies.push(t.field),this.headerElements[t.field]=e}addRow(t){let e=this.htmlElements[1].getElementsByTagName("tbody")[0],n="<tr>";for(let e=0;e<this.headerIndicies.length;e++){let i=this.headerIndicies[e],o=t[i];null!=this.headerElements[i]&&(n+=`<td>${o}</td>`)}n+="</tr>",o.HotStaq.addHtml(e,n)}clearRows(){return i(this,void 0,void 0,(function*(){this.htmlElements[1].getElementsByTagName("tbody")[0].innerHTML=""}))}refreshList(){return i(this,void 0,void 0,(function*(){let t=yield o.Hot.jsonRequest(`${o.Hot.Data.baseUrl}/v1/data/list`,{schema:this.schema});this.clearRows();for(let e=0;e<t.length;e++){let n=t[e];this.addRow(n)}}))}onPostPlace(t,e){return i(this,void 0,void 0,(function*(){setTimeout((()=>i(this,void 0,void 0,(function*(){yield this.refreshList()}))),50)}))}output(){return i(this,void 0,void 0,(function*(){return`\n\t\t<div id = "${this.htmlElements[0].id}">\n\t\t\t<h2>${this.title}</h2>\n\t\t\t<div class="table-responsive">\n\t\t\t<table class="table table-striped table-sm">\n\t\t\t\t<thead hot-place-here = "header">\n\t\t\t\t</thead>\n\t\t\t\t<tbody hot-place-here = "results">\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t\t</div>\n\t\t</div>`}))}}e.AdminTable=a},80:function(t,e,n){var i=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))((function(o,a){function s(t){try{r(i.next(t))}catch(t){a(t)}}function d(t){try{r(i.throw(t))}catch(t){a(t)}}function r(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,d)}r((i=i.apply(t,e||[])).next())}))};Object.defineProperty(e,"__esModule",{value:!0}),e.AdminText=void 0;const o=n(607);class a extends o.HotComponent{constructor(t,e){super(t,e),this.tag="admin-text",this.field=""}onPostPlace(t,e){return i(this,void 0,void 0,(function*(){let n=t.querySelectorAll('hot-place-here[type="modal"]');if(n.length>0){let i=n[0];t.removeChild(e),i.appendChild(e),t.hotComponent.fieldElements[this.field]=e.querySelector("input")}}))}output(){return i(this,void 0,void 0,(function*(){let t="";return null!=this.value&&(t=this.value),`<div>\n\t\t\t<label class="form-label">${this.inner}</label><input class="form-control" type = "text" value = "${t}" />\n\t\t</div>`}))}}e.AdminText=a},607:t=>{t.exports=HotStaqWeb}},e={},n=function n(i){var o=e[i];if(void 0!==o)return o.exports;var a=e[i]={exports:{}};return t[i].call(a.exports,a,a.exports,n),a.exports}(1);AdminPanelComponentsWeb=n})();
|
|
2
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,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MEJJLENBQW9CLEciLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9BZG1pblBhbmVsQ29tcG9uZW50c1dlYi8uL3NyYy9XZWJFeHBvcnQudHMiLCJ3ZWJwYWNrOi8vQWRtaW5QYW5lbENvbXBvbmVudHNXZWIvLi9zcmMvY29tcG9uZW50cy9hZG1pbi1idXR0b24udHMiLCJ3ZWJwYWNrOi8vQWRtaW5QYW5lbENvbXBvbmVudHNXZWIvLi9zcmMvY29tcG9uZW50cy9hZG1pbi1kYXNoYm9hcmQudHMiLCJ3ZWJwYWNrOi8vQWRtaW5QYW5lbENvbXBvbmVudHNXZWIvLi9zcmMvY29tcG9uZW50cy9hZG1pbi1lZGl0LnRzIiwid2VicGFjazovL0FkbWluUGFuZWxDb21wb25lbnRzV2ViLy4vc3JjL2NvbXBvbmVudHMvYWRtaW4tdGFibGUtZmllbGQudHMiLCJ3ZWJwYWNrOi8vQWRtaW5QYW5lbENvbXBvbmVudHNXZWIvLi9zcmMvY29tcG9uZW50cy9hZG1pbi10YWJsZS1yb3cudHMiLCJ3ZWJwYWNrOi8vQWRtaW5QYW5lbENvbXBvbmVudHNXZWIvLi9zcmMvY29tcG9uZW50cy9hZG1pbi10YWJsZS50cyIsIndlYnBhY2s6Ly9BZG1pblBhbmVsQ29tcG9uZW50c1dlYi8uL3NyYy9jb21wb25lbnRzL2FkbWluLXRleHQudHMiLCJ3ZWJwYWNrOi8vQWRtaW5QYW5lbENvbXBvbmVudHNXZWIvZXh0ZXJuYWwgdmFyIFwiSG90U3RhcVdlYlwiIiwid2VicGFjazovL0FkbWluUGFuZWxDb21wb25lbnRzV2ViL3dlYnBhY2svYm9vdHN0cmFwIiwid2VicGFjazovL0FkbWluUGFuZWxDb21wb25lbnRzV2ViL3dlYnBhY2svc3RhcnR1cCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBZG1pbkJ1dHRvbiB9IGZyb20gXCIuL2NvbXBvbmVudHMvYWRtaW4tYnV0dG9uXCI7XG5pbXBvcnQgeyBBZG1pbkRhc2hib2FyZCB9IGZyb20gXCIuL2NvbXBvbmVudHMvYWRtaW4tZGFzaGJvYXJkXCI7XG5pbXBvcnQgeyBBZG1pbkVkaXQgfSBmcm9tIFwiLi9jb21wb25lbnRzL2FkbWluLWVkaXRcIjtcbmltcG9ydCB7IEFkbWluVGFibGUgfSBmcm9tIFwiLi9jb21wb25lbnRzL2FkbWluLXRhYmxlXCI7XG5pbXBvcnQgeyBBZG1pblRhYmxlRmllbGQgfSBmcm9tIFwiLi9jb21wb25lbnRzL2FkbWluLXRhYmxlLWZpZWxkXCI7XG5pbXBvcnQgeyBBZG1pblRhYmxlUm93IH0gZnJvbSBcIi4vY29tcG9uZW50cy9hZG1pbi10YWJsZS1yb3dcIjtcbmltcG9ydCB7IEFkbWluVGV4dCB9IGZyb20gXCIuL2NvbXBvbmVudHMvYWRtaW4tdGV4dFwiO1xuXG5hc3luYyBmdW5jdGlvbiBidWlsZEFzc2V0cyAoKTogUHJvbWlzZTxhbnk+XG57XG5cdHJldHVybiAoe1xuXHRcdFx0aW1wb3J0OiBbeyBuYW1lOiBcImJvb3RzdHJhcFwiLCBmaWxlczogW1wiYm9vdHN0cmFwLm1pbi5qc1wiLCBcImJvb3RzdHJhcC5taW4uY3NzXCJdIH0sIFxuXHRcdFx0XHR7IG5hbWU6IFwianF1ZXJ5XCIsIGZpbGVzOiBbXCJqcXVlcnkubWluLmpzXCJdIH0sIFxuXHRcdFx0XHRcImNoYXJ0LmpzXCIsIFxuXHRcdFx0XHRcImZlYXRoZXItaWNvbnNcIiwgXG5cdFx0XHRcdFwiQHBvcHBlcmpzL2NvcmVcIl0sXG5cdFx0XHRodG1sOiBbXCIuL2Fzc2V0cy9odG1sLyouKlwiXSxcblx0XHRcdGNzczogW1wiLi9hc3NldHMvY3NzLyouKlwiXSxcblx0XHRcdGpzOiBbXCIuL2Fzc2V0cy9qcy8qLipcIiwgXCIuL2J1aWxkLXdlYi9BZG1pblBhbmVsQ29tcG9uZW50cy5qc1wiXSxcblx0XHRcdGNvbXBvbmVudExpYnJhcnk6IFwiQWRtaW5QYW5lbENvbXBvbmVudHNXZWJcIixcblx0XHRcdGNvbXBvbmVudHM6IFtcblx0XHRcdFx0QWRtaW5CdXR0b24sXG5cdFx0XHRcdEFkbWluRGFzaGJvYXJkLFxuXHRcdFx0XHRBZG1pbkVkaXQsXG5cdFx0XHRcdEFkbWluVGFibGUsXG5cdFx0XHRcdEFkbWluVGFibGVGaWVsZCxcblx0XHRcdFx0QWRtaW5UYWJsZVJvdyxcblx0XHRcdFx0QWRtaW5UZXh0XVxuXHRcdH0pO1xufVxuXG5leHBvcnQge1xuXHRcdGJ1aWxkQXNzZXRzLFxuXHRcdEFkbWluQnV0dG9uLFxuXHRcdEFkbWluRGFzaGJvYXJkLFxuXHRcdEFkbWluRWRpdCxcblx0XHRBZG1pblRhYmxlLFxuXHRcdEFkbWluVGFibGVGaWVsZCxcblx0XHRBZG1pblRhYmxlUm93LFxuXHRcdEFkbWluVGV4dFxuXHR9OyIsImltcG9ydCB7IEhvdFN0YXEsIEhvdCwgSG90QVBJLCBIb3RDb21wb25lbnQgfSBmcm9tIFwiaG90c3RhcVwiO1xuXG5leHBvcnQgY2xhc3MgQWRtaW5CdXR0b24gZXh0ZW5kcyBIb3RDb21wb25lbnRcbntcblx0Y29uc3RydWN0b3IgKGNvcHk6IEhvdENvbXBvbmVudCB8IEhvdFN0YXEsIGFwaTogSG90QVBJKVxuXHR7XG5cdFx0c3VwZXIgKGNvcHksIGFwaSk7XG5cblx0XHR0aGlzLnRhZyA9IFwiYWRtaW4tYnV0dG9uXCI7XG5cdH1cblxuXHRhc3luYyBidXR0b25DbGlja2VkICgpXG5cdHtcblx0fVxuXG5cdGFzeW5jIG91dHB1dCAoKVxuXHR7XG5cdFx0cmV0dXJuIChgPGJ1dHRvbiBpZCA9IFwiJHt0aGlzLmh0bWxFbGVtZW50c1swXS5pZH1cIiBvbmNsaWNrID0gXCJ0aGlzLmJ1dHRvbkNsaWNrZWQgKCk7XCI+PC9idXR0b24+YCk7XG5cdH1cbn1cbiIsImltcG9ydCB7IEhvdFN0YXEsIEhvdCwgSG90QVBJLCBIb3RDb21wb25lbnQgfSBmcm9tIFwiaG90c3RhcVwiO1xuXG5leHBvcnQgY2xhc3MgQWRtaW5EYXNoYm9hcmQgZXh0ZW5kcyBIb3RDb21wb25lbnRcbntcblx0LyoqXG5cdCAqIFRoZSB0aXRsZSBvZiB0aGlzIGRhc2hib2FyZC5cblx0ICovXG5cdHRpdGxlOiBzdHJpbmc7XG5cdC8qKlxuXHQgKiBUaGUgYmFzZSB1cmwgdG8gdXNlIGZvciB0aGlzIGRhc2hib2FyZC5cblx0ICovXG5cdGJhc2U6IHN0cmluZztcblxuXHRjb25zdHJ1Y3RvciAoY29weTogSG90Q29tcG9uZW50IHwgSG90U3RhcSwgYXBpOiBIb3RBUEkpXG5cdHtcblx0XHRzdXBlciAoY29weSwgYXBpKTtcblxuXHRcdHRoaXMudGFnID0gXCJhZG1pbi1kYXNoYm9hcmRcIjtcblx0XHR0aGlzLnRpdGxlID0gXCJcIjtcblx0XHR0aGlzLmJhc2UgPSBcIlwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZCB0aGlzIHRhYmxlIGZpZWxkIHRvIHRoZSB0YWJsZVxuXHQgKi9cblx0Ly8gQHRzLWlnbm9yZVxuXHRhc3luYyBvblBvc3RQbGFjZSAocGFyZW50SHRtbEVsZW1lbnQ6IEhUTUxFbGVtZW50LCBodG1sRWxlbWVudDogSFRNTEVsZW1lbnQpOiBQcm9taXNlPEhUTUxFbGVtZW50PlxuXHR7XG5cdFx0Ly8gU2V0IHRoZSBiYXNlIEFQSSB1cmwgdG8gdXNlIGZvciB0aGlzIGRhc2hib2FyZC5cblx0XHRpZiAodGhpcy5iYXNlICE9IFwiXCIpXG5cdFx0XHRIb3QuRGF0YS5iYXNlVXJsID0gdGhpcy5iYXNlO1xuXHR9XG5cblx0YXN5bmMgb3V0cHV0ICgpOiBQcm9taXNlPHN0cmluZz5cblx0e1xuXHRcdHJldHVybiAoYFxuXHRcdDxtYWluIGNsYXNzPVwiY29sLW1kLTkgbXMtc20tYXV0byBjb2wtbGctMTAgcHgtbWQtNFwiPlxuXHRcdFx0PGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBmbGV4LXdyYXAgZmxleC1tZC1ub3dyYXAgYWxpZ24taXRlbXMtY2VudGVyIHB0LTMgcGItMiBtYi0zIGJvcmRlci1ib3R0b21cIj5cblx0XHRcdFx0PGgxIGNsYXNzPVwiaDJcIj4ke3RoaXMudGl0bGV9PC9oMT5cblx0XHRcdFx0PGRpdiBjbGFzcz1cImJ0bi10b29sYmFyIG1iLTIgbWItbWQtMFwiPlxuXHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgbWUtMlwiPlxuXHRcdFx0XHRcdFx0PGhvdC1wbGFjZS1oZXJlIG5hbWUgPSBcImJ1dHRvbnNcIj48L2hvdC1wbGFjZS1oZXJlPlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdFx0PGhvdC1wbGFjZS1oZXJlIG5hbWUgPSBcImJvZHlcIj48L2hvdC1wbGFjZS1oZXJlPlxuXHRcdDwvbWFpbj5gKTtcblx0fVxufVxuIiwiaW1wb3J0IHsgSG90U3RhcSwgSG90LCBIb3RBUEksIEhvdENvbXBvbmVudCB9IGZyb20gXCJob3RzdGFxXCI7XG5cbmV4cG9ydCBjbGFzcyBBZG1pbkVkaXQgZXh0ZW5kcyBIb3RDb21wb25lbnRcbntcblx0LyoqXG5cdCAqIFRoZSB0aXRsZSBvZiB0aGlzIGVkaXQgbW9kYWwuXG5cdCAqL1xuXHR0aXRsZTogc3RyaW5nO1xuXHQvKipcblx0ICogVGhlIGJ1dHRvbiB0aXRsZS5cblx0ICovXG5cdGJ1dHRvbl90aXRsZTogc3RyaW5nO1xuXHQvKipcblx0ICogVGhlIGF0dGFjaGVkIGxpc3QuXG5cdCAqL1xuXHRhdHRhY2hlZF9saXN0OiBzdHJpbmc7XG5cdC8qKlxuXHQgKiBUaGUgYXR0YWNoZWQgc2NoZW1hLlxuXHQgKi9cblx0c2NoZW1hOiBzdHJpbmc7XG5cdC8qKlxuXHQgKiBUaGUgZmllbGQgZWxlbWVudHMgaW4gdGhlIGVkaXQgbW9kYWwuXG5cdCAqL1xuXHRmaWVsZEVsZW1lbnRzOiB7IFtuYW1lOiBzdHJpbmddOiBhbnk7IH07XG5cdC8qKlxuXHQgKiBUaGUgbW9kYWwgaWQuXG5cdCAqL1xuXHRtb2RhbElkOiBzdHJpbmc7XG5cblx0Y29uc3RydWN0b3IgKGNvcHk6IEhvdENvbXBvbmVudCB8IEhvdFN0YXEsIGFwaTogSG90QVBJKVxuXHR7XG5cdFx0c3VwZXIgKGNvcHksIGFwaSk7XG5cblx0XHR0aGlzLnRhZyA9IFwiYWRtaW4tZWRpdFwiO1xuXHRcdHRoaXMudGl0bGUgPSBcIlwiO1xuXHRcdHRoaXMuYnV0dG9uX3RpdGxlID0gXCJcIjtcblx0XHR0aGlzLmF0dGFjaGVkX2xpc3QgPSBcIlwiO1xuXHRcdHRoaXMuc2NoZW1hID0gXCJcIjtcblxuXHRcdHRoaXMuZmllbGRFbGVtZW50cyA9IHt9O1xuXG5cdFx0dGhpcy5tb2RhbElkID0gXCJcIjtcblx0fVxuXG5cdC8qKlxuXHQgKiBTYXZlIHRoaXMgZm9ybS5cblx0ICovXG5cdGFzeW5jIG9uU2F2ZSAoKVxuXHR7XG5cdFx0bGV0IHZhbHVlczogYW55ID0ge307XG5cblx0XHRmb3IgKGxldCBrZXkgaW4gdGhpcy5maWVsZEVsZW1lbnRzKVxuXHRcdHtcblx0XHRcdGxldCBmaWVsZEVsZW1lbnQgPSB0aGlzLmZpZWxkRWxlbWVudHNba2V5XTtcblx0XHRcdGxldCB2YWx1ZSA9IGZpZWxkRWxlbWVudC52YWx1ZTtcblxuXHRcdFx0dmFsdWVzW2tleV0gPSB2YWx1ZTtcblx0XHR9XG5cblx0XHRhd2FpdCBIb3QuanNvblJlcXVlc3QgKGAke0hvdC5EYXRhLmJhc2VVcmx9L3YxL2RhdGEvYWRkYCwge1xuXHRcdFx0XHRzY2hlbWE6IHRoaXMuc2NoZW1hLFxuXHRcdFx0XHRmaWVsZHM6IHZhbHVlc1xuXHRcdFx0fSk7XG5cblx0XHRsZXQgYXR0YWNoZWRMaXN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQgKHRoaXMuYXR0YWNoZWRfbGlzdCk7XG5cblx0XHQvLyBAdHMtaWdub3JlXG5cdFx0YXdhaXQgYXR0YWNoZWRMaXN0LmhvdENvbXBvbmVudC5yZWZyZXNoTGlzdCAoKTtcblxuXHRcdC8vIEB0cy1pZ25vcmVcblx0XHQkKGAjJHt0aGlzLm1vZGFsSWR9YCkubW9kYWwgKFwiaGlkZVwiKTtcblx0fVxuXG5cdGFzeW5jIG91dHB1dCAoKVxuXHR7XG5cdFx0aWYgKHRoaXMubmFtZSA9PT0gXCJcIilcblx0XHRcdHRocm93IG5ldyBFcnJvciAoYFlvdSBtdXN0IHNwZWNpZnkgYSBuYW1lIGZvciBlYWNoIGFkbWluLWVkaXQgZWxlbWVudCFgKTtcblxuXHRcdHRoaXMubW9kYWxJZCA9IGAke3RoaXMubmFtZX1Nb2RhbGA7XG5cblx0XHRyZXR1cm4gKFt7XG5cdFx0XHRodG1sOiBgXG5cdFx0XHQ8IS0tICR7dGhpcy50aXRsZX0gTW9kYWwgU3RhcnQgLS0+XG5cdFx0XHQ8ZGl2IGNsYXNzPVwibW9kYWwgZmFkZVwiIGlkPVwiJHt0aGlzLm1vZGFsSWR9XCIgdGFiaW5kZXg9XCItMVwiIGFyaWEtbGFiZWxsZWRieT1cIiR7dGhpcy5uYW1lfU1vZGFsTGFiZWxcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cIm1vZGFsLWRpYWxvZ1wiPlxuXHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJtb2RhbC1jb250ZW50XCI+XG5cdFx0XHRcdFx0PGRpdiBjbGFzcz1cIm1vZGFsLWhlYWRlclwiPlxuXHRcdFx0XHRcdFx0PGg1IGNsYXNzPVwibW9kYWwtdGl0bGVcIiBpZD1cIiR7dGhpcy5uYW1lfU1vZGFsTGFiZWxcIj4ke3RoaXMudGl0bGV9PC9oNT5cblx0XHRcdFx0XHRcdDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuLWNsb3NlXCIgZGF0YS1icy1kaXNtaXNzPVwibW9kYWxcIiBhcmlhLWxhYmVsPVwiQ2xvc2VcIj48L2J1dHRvbj5cblx0XHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwibW9kYWwtYm9keVwiPlxuXHRcdFx0XHRcdFx0PGhvdC1wbGFjZS1oZXJlIG5hbWUgPSBcIm1vZGFsQm9keVwiIHR5cGUgPSBcIm1vZGFsXCI+PC9ob3QtcGxhY2UtaGVyZT5cblx0XHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwibW9kYWwtZm9vdGVyXCI+XG5cdFx0XHRcdFx0XHQ8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgZGF0YS1icy1kaXNtaXNzPVwibW9kYWxcIj5DYW5jZWw8L2J1dHRvbj5cblx0XHRcdFx0XHRcdDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgb25jbGljayA9IFwiZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJyR7dGhpcy5tb2RhbElkfScpLm9uU2F2ZSAoKTtcIj4ke3RoaXMuYnV0dG9uX3RpdGxlfTwvYnV0dG9uPlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdFx0PCEtLSAke3RoaXMudGl0bGV9IE1vZGFsIEVuZCAtLT5gLFxuXHRcdFx0cGFyZW50U2VsZWN0b3I6IFwiYm9keVwiXG5cdFx0fSxcblx0XHR7XG5cdFx0XHRodG1sOiBgPGJ1dHRvbiBpZCA9IFwiJHt0aGlzLm1vZGFsSWR9LWFkZC1idG5cIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1vdXRsaW5lLXNlY29uZGFyeVwiIGRhdGEtYnMtdG9nZ2xlPVwibW9kYWxcIiBkYXRhLWJzLXRhcmdldD1cIiMke3RoaXMubW9kYWxJZH1cIj5BZGQ8L2J1dHRvbj5gLFxuXHRcdFx0Ly9gPGJ1dHRvbiBpZCA9IFwiJHt0aGlzLm1vZGFsSWR9LWFkZC1idG5cIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1vdXRsaW5lLXNlY29uZGFyeVwiIGRhdGEtYnMtdG9nZ2xlPVwibW9kYWxcIiBvbmNsaWNrID0gXCIkKCcjJHt0aGlzLm1vZGFsSWR9JykubW9kYWwgKCdzaG93Jyk7XCI+QWRkPC9idXR0b24+YCxcblx0XHRcdHBhcmVudFNlbGVjdG9yOiBgaG90LXBsYWNlLWhlcmVbbmFtZT1cImJ1dHRvbnNcIl1gXG5cdFx0fV0pO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBIb3RTdGFxLCBIb3QsIEhvdEFQSSwgSG90Q29tcG9uZW50IH0gZnJvbSBcImhvdHN0YXFcIjtcblxuZXhwb3J0IGNsYXNzIEFkbWluVGFibGVGaWVsZCBleHRlbmRzIEhvdENvbXBvbmVudFxue1xuXHQvKipcblx0ICogVGhlIHRhYmxlIGZpZWxkLlxuXHQgKi9cblx0ZmllbGQ6IG51bWJlcjtcblxuXHRjb25zdHJ1Y3RvciAoY29weTogSG90Q29tcG9uZW50IHwgSG90U3RhcSwgYXBpOiBIb3RBUEkpXG5cdHtcblx0XHRzdXBlciAoY29weSwgYXBpKTtcblxuXHRcdHRoaXMudGFnID0gXCJhZG1pbi10YWJsZS1maWVsZFwiO1xuXHRcdHRoaXMuZmllbGQgPSAwO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZCB0aGlzIHRhYmxlIGZpZWxkIHRvIHRoZSB0YWJsZVxuXHQgKi9cblx0Ly8gQHRzLWlnbm9yZVxuXHRhc3luYyBvblBvc3RQbGFjZSAocGFyZW50SHRtbEVsZW1lbnQ6IEhUTUxFbGVtZW50LCBodG1sRWxlbWVudDogSFRNTEVsZW1lbnQpOiBQcm9taXNlPEhUTUxFbGVtZW50PlxuXHR7XG5cdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdGxldCBob3RDb21wb25lbnQgPSBwYXJlbnRIdG1sRWxlbWVudC5wYXJlbnROb2RlLnBhcmVudE5vZGUucGFyZW50Tm9kZS5ob3RDb21wb25lbnQ7XG5cblx0XHRpZiAoaG90Q29tcG9uZW50ICE9IG51bGwpXG5cdFx0XHRob3RDb21wb25lbnQuYWRkSGVhZGVyRGF0YU9ubHkgKHRoaXMsIGh0bWxFbGVtZW50KTtcblx0fVxuXG5cdGFzeW5jIG91dHB1dCAoKVxuXHR7XG5cdFx0cmV0dXJuIChbe1xuXHRcdFx0aHRtbDogYDx0aD4ke3RoaXMuaW5uZXJ9PC90aD5gLFxuXHRcdFx0cGxhY2VIZXJlUGFyZW50OiBcImhlYWRlclwiXG5cdFx0fV0pO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBIb3RTdGFxLCBIb3QsIEhvdEFQSSwgSG90Q29tcG9uZW50IH0gZnJvbSBcImhvdHN0YXFcIjtcblxuZXhwb3J0IGNsYXNzIEFkbWluVGFibGVSb3cgZXh0ZW5kcyBIb3RDb21wb25lbnRcbntcblx0LyoqXG5cdCAqIFRoZSBmaWVsZHMgYXJlIHN0b3JlZCBpbiBhIGtleS92YWx1ZSBvYmplY3QuXG5cdCAqIFxuXHQgKiBAZXhhbXBsZSB7IFwibmFtZVwiOiBcIkpvaG4gU21pdGhcIiwgXCJlbWFpbFwiOiBcImpvaG4uc21pdGhAZW1haWwuY29tXCIgfVxuXHQgKi9cblx0ZmllbGRzOiBhbnlbXTtcblxuXHRjb25zdHJ1Y3RvciAoY29weTogSG90Q29tcG9uZW50IHwgSG90U3RhcSwgYXBpOiBIb3RBUEkpXG5cdHtcblx0XHRzdXBlciAoY29weSwgYXBpKTtcblxuXHRcdHRoaXMudGFnID0gXCJhZG1pbi10YWJsZS1yb3dcIjtcblx0XHR0aGlzLmZpZWxkcyA9IFtdO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZCB0aGlzIHRhYmxlIHJvdyB0byB0aGUgdGFibGVcblx0ICovXG5cdC8vIEB0cy1pZ25vcmVcblx0YXN5bmMgb25Qb3N0UGxhY2UgKHBhcmVudEh0bWxFbGVtZW50OiBIVE1MRWxlbWVudCwgaHRtbEVsZW1lbnQ6IEhUTUxFbGVtZW50KTogUHJvbWlzZTxIVE1MRWxlbWVudD5cblx0e1xuXHRcdC8vIEB0cy1pZ25vcmVcblx0XHRwYXJlbnRIdG1sRWxlbWVudC5wYXJlbnROb2RlLnBhcmVudE5vZGUucGFyZW50Tm9kZS5ob3RDb21wb25lbnQucm93RWxlbWVudHMucHVzaCAoeyBmaWVsZHM6IHRoaXMuZmllbGRzLCBlbGVtZW50OiBodG1sRWxlbWVudH0pO1xuXHR9XG5cblx0YXN5bmMgb3V0cHV0ICgpXG5cdHtcblx0XHRsZXQgcm93SHRtbCA9IFwiXCI7XG5cblx0XHRmb3IgKGxldCBpSWR4ID0gMDsgaUlkeCA8IHRoaXMuZmllbGRzLmxlbmd0aDsgaUlkeCsrKVxuXHRcdHtcblx0XHRcdGxldCBmaWVsZE9iaiA9IHRoaXMuZmllbGRzW2lJZHhdO1xuXG5cdFx0XHRmb3IgKGxldCBrZXkgaW4gZmllbGRPYmopXG5cdFx0XHR7XG5cdFx0XHRcdGxldCB2YWx1ZSA9IGZpZWxkT2JqW2tleV07XG5cblx0XHRcdFx0cm93SHRtbCArPSBgPHRkPiR7dmFsdWV9PC90ZD5gO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiAoW3tcblx0XHRcdGh0bWw6IGA8dHI+JHtyb3dIdG1sfTwvdHI+YCxcblx0XHRcdHBsYWNlSGVyZVBhcmVudDogXCJyZXN1bHRzXCJcblx0XHR9XSk7XG5cdH1cbn1cbiIsImltcG9ydCB7IEhvdFN0YXEsIEhvdCwgSG90QVBJLCBIb3RDb21wb25lbnQgfSBmcm9tIFwiaG90c3RhcVwiO1xuaW1wb3J0IHsgQWRtaW5UYWJsZUZpZWxkIH0gZnJvbSBcIi4vYWRtaW4tdGFibGUtZmllbGRcIjtcblxuZXhwb3J0IGNsYXNzIEFkbWluVGFibGUgZXh0ZW5kcyBIb3RDb21wb25lbnRcbntcblx0LyoqXG5cdCAqIFRoZSB0aXRsZSBvZiB0aGlzIHRhYmxlLlxuXHQgKi9cblx0dGl0bGU6IHN0cmluZztcblx0LyoqXG5cdCAqIFRoZSBhdHRhY2hlZCBzY2hlbWEuXG5cdCAqL1xuXHRzY2hlbWE6IHN0cmluZztcblx0LyoqXG5cdCAqIFRoZSBoZWFkZXJzIGFyZSBzdG9yZWQgaW4gYSBrZXkvdmFsdWUgb2JqZWN0LlxuXHQgKiBcblx0ICogQGV4YW1wbGUgeyBcIm5hbWVcIjogXCI8dGg+TmFtZTwvdGg+XCIsIFwiZW1haWxcIjogXCI8dGg+RW1haWw8L3RoPlwiIH1cblx0ICovXG5cdGhlYWRlckVsZW1lbnRzOiB7IFtuYW1lOiBzdHJpbmddOiBhbnk7IH0gPSB7fTtcblx0LyoqXG5cdCAqIFRoZSBoZWFkZXIgaW5kaWNpZXMgYXJlIHN0b3JlZCBpbiBhIGtleS92YWx1ZSBvYmplY3QuXG5cdCAqIFxuXHQgKiBAZXhhbXBsZSBjb25zb2xlLmxvZyAodGhpcy5oZWFkZXJJbmRpY2llc1tcIm5hbWVcIl0pOyAvLyBPdXRwdXRzIDBcblx0ICovXG5cdGhlYWRlckluZGljaWVzOiBudW1iZXJbXTtcblx0LyoqXG5cdCAqIFRoZSByb3cgZWxlbWVudHMgYXJlIHN0b3JlZCBpbiBhbiBhcnJheSB3aXRoIGtleS92YWx1ZSBmaWVsZHMgYW5kIGl0J3MgYXR0YWNoZWQgaHRtbCBlbGVtZW50LlxuXHQgKiBcblx0ICogQGV4YW1wbGVcblx0ICoge1xuXHQgKiAgIFwiZmllbGRzXCI6IFtcblx0ICogICAgICAge1xuXHQgKiAgICAgICAgIFwibmFtZVwiOiBcIkpvaG4gU21pdGhcIixcblx0ICogICAgICAgICBcImVtYWlsXCI6IFwiam9obi5zbWl0aEB0ZXN0LmNvbVwiXG5cdCAqICAgICAgIH1cblx0ICogICAgIF0sXG5cdCAqICAgXCJodG1sXCI6IFwiPHRyPjx0ZD5Kb2huIFNtaXRoPC90ZD48dGQ+am9obi5zbWl0aEB0ZXN0LmNvbTwvdGQ+PC90cj5cIlxuXHQgKiB9XG5cdCAqL1xuXHRyb3dFbGVtZW50czogeyBmaWVsZHM6IGFueVtdOyBodG1sOiBzdHJpbmc7IH1bXSA9IFtdO1xuXG5cdGNvbnN0cnVjdG9yIChjb3B5OiBIb3RDb21wb25lbnQgfCBIb3RTdGFxLCBhcGk6IEhvdEFQSSlcblx0e1xuXHRcdHN1cGVyIChjb3B5LCBhcGkpO1xuXG5cdFx0dGhpcy50YWcgPSBcImFkbWluLXRhYmxlXCI7XG5cdFx0dGhpcy50aXRsZSA9IFwiXCI7XG5cdFx0dGhpcy5zY2hlbWEgPSBcIlwiO1xuXHRcdHRoaXMuaGVhZGVyRWxlbWVudHMgPSB7fTtcblx0XHR0aGlzLmhlYWRlckluZGljaWVzID0gW107XG5cdFx0dGhpcy5yb3dFbGVtZW50cyA9IFtdO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZCBhIGhlYWRlciB0byB0aGUgdGFibGUuXG5cdCAqL1xuXHRhZGRIZWFkZXIgKHRhYmxlRmllbGRFbGVtZW50OiBIVE1MRWxlbWVudClcblx0e1xuXHRcdGxldCBoZWFkZXIgPSB0aGlzLmh0bWxFbGVtZW50c1swXS5nZXRFbGVtZW50c0J5VGFnTmFtZSAoXCJ0aGVhZFwiKVswXTtcblxuXHRcdC8vIEB0cy1pZ25vcmVcblx0XHR0aGlzLmhlYWRlckluZGljaWVzLnB1c2ggKHRhYmxlRmllbGRFbGVtZW50LmhvdENvbXBvbmVudC5maWVsZCk7XG5cdFx0aGVhZGVyLmFwcGVuZENoaWxkICh0YWJsZUZpZWxkRWxlbWVudCk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkIGEgaGVhZGVyIHRvIHRoZSB0YWJsZS5cblx0ICovXG5cdGFkZEhlYWRlckRhdGFPbmx5ICh0YWJsZUZpZWxkOiBBZG1pblRhYmxlRmllbGQsIGh0bWxFbGVtZW50OiBIVE1MRWxlbWVudClcblx0e1xuXHRcdHRoaXMuaGVhZGVySW5kaWNpZXMucHVzaCAodGFibGVGaWVsZC5maWVsZCk7XG5cdFx0dGhpcy5oZWFkZXJFbGVtZW50c1t0YWJsZUZpZWxkLmZpZWxkXSA9IGh0bWxFbGVtZW50O1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZCBhIHJvdyB0byB0aGUgdGFibGUuXG5cdCAqIFxuXHQgKiBAcGFyYW0ge0FycmF5fSBmaWVsZHMgQSBsaXN0IG9mIHZhbHVlcyB0byBhcHBlbmQuXG5cdCAqL1xuXHRhZGRSb3cgKGZpZWxkczogeyBbbmFtZTogc3RyaW5nXTogYW55IH1bXSlcblx0e1xuXHRcdGxldCB0Ym9keSA9IHRoaXMuaHRtbEVsZW1lbnRzWzFdLmdldEVsZW1lbnRzQnlUYWdOYW1lIChcInRib2R5XCIpWzBdO1xuXHRcdGxldCByb3dTdHIgPSBcIjx0cj5cIjtcblxuXHRcdGZvciAobGV0IGlJZHggPSAwOyBpSWR4IDwgdGhpcy5oZWFkZXJJbmRpY2llcy5sZW5ndGg7IGlJZHgrKylcblx0XHR7XG5cdFx0XHRsZXQga2V5ID0gdGhpcy5oZWFkZXJJbmRpY2llc1tpSWR4XTtcblx0XHRcdGxldCB2YWx1ZSA9IGZpZWxkc1trZXldO1xuXG5cdFx0XHRpZiAodGhpcy5oZWFkZXJFbGVtZW50c1trZXldICE9IG51bGwpXG5cdFx0XHRcdHJvd1N0ciArPSBgPHRkPiR7dmFsdWV9PC90ZD5gO1xuXHRcdH1cblxuXHRcdHJvd1N0ciArPSBcIjwvdHI+XCI7XG5cblx0XHRIb3RTdGFxLmFkZEh0bWwgKHRib2R5LCByb3dTdHIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENsZWFyIHRoZSBsaXN0IG9mIHJvd3MuXG5cdCAqL1xuXHRhc3luYyBjbGVhclJvd3MgKClcblx0e1xuXHRcdGxldCB0Ym9keSA9IHRoaXMuaHRtbEVsZW1lbnRzWzFdLmdldEVsZW1lbnRzQnlUYWdOYW1lIChcInRib2R5XCIpWzBdO1xuXG5cdFx0dGJvZHkuaW5uZXJIVE1MID0gXCJcIjtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZWZyZXNoIHRoZSBsaXN0LlxuXHQgKi9cblx0YXN5bmMgcmVmcmVzaExpc3QgKClcblx0e1xuXHRcdGxldCBsaXN0ID0gYXdhaXQgSG90Lmpzb25SZXF1ZXN0IChgJHtIb3QuRGF0YS5iYXNlVXJsfS92MS9kYXRhL2xpc3RgLCB7XG5cdFx0XHRcdHNjaGVtYTogdGhpcy5zY2hlbWFcblx0XHRcdH0pO1xuXG5cdFx0dGhpcy5jbGVhclJvd3MgKCk7XG5cblx0XHRmb3IgKGxldCBpSWR4ID0gMDsgaUlkeCA8IGxpc3QubGVuZ3RoOyBpSWR4KyspXG5cdFx0e1xuXHRcdFx0bGV0IGZpZWxkcyA9IGxpc3RbaUlkeF07XG5cblx0XHRcdHRoaXMuYWRkUm93IChmaWVsZHMpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIGxpc3Qgb2YgZGF0YSBmcm9tIHRoZSBzZXJ2ZXIuXG5cdCAqL1xuXHQvLyBAdHMtaWdub3JlXG5cdGFzeW5jIG9uUG9zdFBsYWNlIChwYXJlbnRIdG1sRWxlbWVudDogSFRNTEVsZW1lbnQsIGh0bWxFbGVtZW50OiBIVE1MRWxlbWVudCk6IFByb21pc2U8SFRNTEVsZW1lbnQ+XG5cdHtcblx0XHRzZXRUaW1lb3V0IChhc3luYyAoKSA9PlxuXHRcdFx0e1xuXHRcdFx0XHRhd2FpdCB0aGlzLnJlZnJlc2hMaXN0ICgpO1xuXHRcdFx0fSwgNTApO1xuXHR9XG5cblx0YXN5bmMgb3V0cHV0ICgpXG5cdHtcblx0XHRyZXR1cm4gKGBcblx0XHQ8ZGl2IGlkID0gXCIke3RoaXMuaHRtbEVsZW1lbnRzWzBdLmlkfVwiPlxuXHRcdFx0PGgyPiR7dGhpcy50aXRsZX08L2gyPlxuXHRcdFx0PGRpdiBjbGFzcz1cInRhYmxlLXJlc3BvbnNpdmVcIj5cblx0XHRcdDx0YWJsZSBjbGFzcz1cInRhYmxlIHRhYmxlLXN0cmlwZWQgdGFibGUtc21cIj5cblx0XHRcdFx0PHRoZWFkIGhvdC1wbGFjZS1oZXJlID0gXCJoZWFkZXJcIj5cblx0XHRcdFx0PC90aGVhZD5cblx0XHRcdFx0PHRib2R5IGhvdC1wbGFjZS1oZXJlID0gXCJyZXN1bHRzXCI+XG5cdFx0XHRcdDwvdGJvZHk+XG5cdFx0XHQ8L3RhYmxlPlxuXHRcdFx0PC9kaXY+XG5cdFx0PC9kaXY+YCk7XG5cdH1cbn1cbiIsImltcG9ydCB7IEhvdFN0YXEsIEhvdCwgSG90QVBJLCBIb3RDb21wb25lbnQgfSBmcm9tIFwiaG90c3RhcVwiO1xuXG5leHBvcnQgY2xhc3MgQWRtaW5UZXh0IGV4dGVuZHMgSG90Q29tcG9uZW50XG57XG5cdC8qKlxuXHQgKiBUaGUgYXNzb2NpYXRlZCBkYXRhYmFzZSBmaWVsZC5cblx0ICovXG5cdGZpZWxkOiBzdHJpbmc7XG5cblx0Y29uc3RydWN0b3IgKGNvcHk6IEhvdENvbXBvbmVudCB8IEhvdFN0YXEsIGFwaTogSG90QVBJKVxuXHR7XG5cdFx0c3VwZXIgKGNvcHksIGFwaSk7XG5cblx0XHR0aGlzLnRhZyA9IFwiYWRtaW4tdGV4dFwiO1xuXHRcdHRoaXMuZmllbGQgPSBcIlwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvcnJlY3RzIHRoZSBwbGFjZW1lbnQgb2YgdGhlIHRleHQgZWxlbWVudHMgZm9yIG1vZGFscy5cblx0ICovXG5cdC8vIEB0cy1pZ25vcmVcblx0YXN5bmMgb25Qb3N0UGxhY2UgKHBhcmVudEh0bWxFbGVtZW50OiBIVE1MRWxlbWVudCwgaHRtbEVsZW1lbnQ6IEhUTUxFbGVtZW50KTogUHJvbWlzZTxIVE1MRWxlbWVudD5cblx0e1xuXHRcdGxldCBwbGFjZUhlcmVBcnJheSA9IHBhcmVudEh0bWxFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwgKGBob3QtcGxhY2UtaGVyZVt0eXBlPVwibW9kYWxcIl1gKTtcblxuXHRcdGlmIChwbGFjZUhlcmVBcnJheS5sZW5ndGggPiAwKVxuXHRcdHtcblx0XHRcdGxldCBwbGFjZUhlcmUgPSBwbGFjZUhlcmVBcnJheVswXTtcblx0XHRcdHBhcmVudEh0bWxFbGVtZW50LnJlbW92ZUNoaWxkIChodG1sRWxlbWVudCk7XG5cdFx0XHRwbGFjZUhlcmUuYXBwZW5kQ2hpbGQgKGh0bWxFbGVtZW50KTtcblxuXHRcdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdFx0cGFyZW50SHRtbEVsZW1lbnQuaG90Q29tcG9uZW50LmZpZWxkRWxlbWVudHNbdGhpcy5maWVsZF0gPSBodG1sRWxlbWVudC5xdWVyeVNlbGVjdG9yIChcImlucHV0XCIpO1xuXHRcdH1cblx0fVxuXG5cdGFzeW5jIG91dHB1dCAoKVxuXHR7XG5cdFx0bGV0IHZhbHVlOiBzdHJpbmcgPSBcIlwiO1xuXG5cdFx0aWYgKHRoaXMudmFsdWUgIT0gbnVsbClcblx0XHRcdHZhbHVlID0gdGhpcy52YWx1ZTtcblxuXHRcdHJldHVybiAoYDxkaXY+XG5cdFx0XHQ8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsXCI+JHt0aGlzLmlubmVyfTwvbGFiZWw+PGlucHV0IGNsYXNzPVwiZm9ybS1jb250cm9sXCIgdHlwZSA9IFwidGV4dFwiIHZhbHVlID0gXCIke3ZhbHVlfVwiIC8+XG5cdFx0PC9kaXY+YCk7XG5cdH1cbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gSG90U3RhcVdlYjsiLCIvLyBUaGUgbW9kdWxlIGNhY2hlXG52YXIgX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fID0ge307XG5cbi8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG5mdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuXHR2YXIgY2FjaGVkTW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXTtcblx0aWYgKGNhY2hlZE1vZHVsZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIGNhY2hlZE1vZHVsZS5leHBvcnRzO1xuXHR9XG5cdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG5cdHZhciBtb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdID0ge1xuXHRcdC8vIG5vIG1vZHVsZS5pZCBuZWVkZWRcblx0XHQvLyBubyBtb2R1bGUubG9hZGVkIG5lZWRlZFxuXHRcdGV4cG9ydHM6IHt9XG5cdH07XG5cblx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG5cdF9fd2VicGFja19tb2R1bGVzX19bbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuIiwiLy8gc3RhcnR1cFxuLy8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4vLyBUaGlzIGVudHJ5IG1vZHVsZSBpcyByZWZlcmVuY2VkIGJ5IG90aGVyIG1vZHVsZXMgc28gaXQgY2FuJ3QgYmUgaW5saW5lZFxudmFyIF9fd2VicGFja19leHBvcnRzX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpO1xuIl0sIm5hbWVzIjpbIkFkbWluQnV0dG9uIiwiQWRtaW5EYXNoYm9hcmQiLCJBZG1pbkVkaXQiLCJBZG1pblRhYmxlIiwiQWRtaW5UYWJsZUZpZWxkIiwiQWRtaW5UYWJsZVJvdyIsIkFkbWluVGV4dCIsImJ1aWxkQXNzZXRzIiwiaW1wb3J0IiwibmFtZSIsImZpbGVzIiwiaHRtbCIsImNzcyIsImpzIiwiY29tcG9uZW50TGlicmFyeSIsImNvbXBvbmVudHMiLCJIb3RDb21wb25lbnQiLCJjb25zdHJ1Y3RvciIsImNvcHkiLCJhcGkiLCJzdXBlciIsInRoaXMiLCJ0YWciLCJidXR0b25DbGlja2VkIiwib3V0cHV0IiwiaHRtbEVsZW1lbnRzIiwiaWQiLCJ0aXRsZSIsImJhc2UiLCJvblBvc3RQbGFjZSIsInBhcmVudEh0bWxFbGVtZW50IiwiaHRtbEVsZW1lbnQiLCJIb3QiLCJEYXRhIiwiYmFzZVVybCIsImJ1dHRvbl90aXRsZSIsImF0dGFjaGVkX2xpc3QiLCJzY2hlbWEiLCJmaWVsZEVsZW1lbnRzIiwibW9kYWxJZCIsIm9uU2F2ZSIsInZhbHVlcyIsImtleSIsInZhbHVlIiwianNvblJlcXVlc3QiLCJmaWVsZHMiLCJhdHRhY2hlZExpc3QiLCJkb2N1bWVudCIsImdldEVsZW1lbnRCeUlkIiwiaG90Q29tcG9uZW50IiwicmVmcmVzaExpc3QiLCIkIiwibW9kYWwiLCJFcnJvciIsInBhcmVudFNlbGVjdG9yIiwiZmllbGQiLCJwYXJlbnROb2RlIiwiYWRkSGVhZGVyRGF0YU9ubHkiLCJpbm5lciIsInBsYWNlSGVyZVBhcmVudCIsInJvd0VsZW1lbnRzIiwicHVzaCIsImVsZW1lbnQiLCJyb3dIdG1sIiwiaUlkeCIsImxlbmd0aCIsImZpZWxkT2JqIiwiaGVhZGVyRWxlbWVudHMiLCJoZWFkZXJJbmRpY2llcyIsImFkZEhlYWRlciIsInRhYmxlRmllbGRFbGVtZW50IiwiaGVhZGVyIiwiZ2V0RWxlbWVudHNCeVRhZ05hbWUiLCJhcHBlbmRDaGlsZCIsInRhYmxlRmllbGQiLCJhZGRSb3ciLCJ0Ym9keSIsInJvd1N0ciIsIkhvdFN0YXEiLCJhZGRIdG1sIiwiY2xlYXJSb3dzIiwiaW5uZXJIVE1MIiwibGlzdCIsInNldFRpbWVvdXQiLCJwbGFjZUhlcmVBcnJheSIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJwbGFjZUhlcmUiLCJyZW1vdmVDaGlsZCIsInF1ZXJ5U2VsZWN0b3IiLCJtb2R1bGUiLCJleHBvcnRzIiwiSG90U3RhcVdlYiIsIl9fd2VicGFja19tb2R1bGVfY2FjaGVfXyIsIl9fd2VicGFja19leHBvcnRzX18iLCJfX3dlYnBhY2tfcmVxdWlyZV9fIiwibW9kdWxlSWQiLCJjYWNoZWRNb2R1bGUiLCJ1bmRlZmluZWQiLCJfX3dlYnBhY2tfbW9kdWxlc19fIiwiY2FsbCJdLCJzb3VyY2VSb290IjoiIn0=
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
if (typeof (AdminPanelWeb) === "undefined")
|
|
2
|
+
AdminPanelWeb = {};
|
|
3
|
+
|
|
4
|
+
var HotAPIGlobal = undefined;
|
|
5
|
+
|
|
6
|
+
if (typeof (HotAPI) !== "undefined")
|
|
7
|
+
HotAPIGlobal = HotAPI;
|
|
8
|
+
|
|
9
|
+
if (typeof (window) !== "undefined")
|
|
10
|
+
{
|
|
11
|
+
if (typeof (window.HotAPI) !== "undefined")
|
|
12
|
+
HotAPIGlobal = window.HotAPI;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Get the authorization header string.
|
|
17
|
+
*/
|
|
18
|
+
function HotStaqGetAuthorizationHeaderString ()
|
|
19
|
+
{
|
|
20
|
+
const auth = null;
|
|
21
|
+
|
|
22
|
+
if (this.authorization != null)
|
|
23
|
+
{
|
|
24
|
+
if (this.authorization.toAuthorizationHeaderString != null)
|
|
25
|
+
auth = this.authorization.toAuthorizationHeaderString ();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (auth == null)
|
|
29
|
+
{
|
|
30
|
+
if (Hot != null)
|
|
31
|
+
{
|
|
32
|
+
if (Hot.API != null)
|
|
33
|
+
{
|
|
34
|
+
if (Hot.API.authCredentials != null)
|
|
35
|
+
{
|
|
36
|
+
if (Hot.API.authCredentials.toAuthorizationHeaderString != null)
|
|
37
|
+
auth = Hot.API.authCredentials.toAuthorizationHeaderString ();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return (auth);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Process a JSON object, and get it ready to make a request.
|
|
48
|
+
*/
|
|
49
|
+
function HotStaqProcessJSONObject (jsonObj)
|
|
50
|
+
{
|
|
51
|
+
if (jsonObj != null)
|
|
52
|
+
{
|
|
53
|
+
if (Hot != null)
|
|
54
|
+
{
|
|
55
|
+
if (Hot.API != null)
|
|
56
|
+
{
|
|
57
|
+
if (Hot.API.authCredentials != null)
|
|
58
|
+
{
|
|
59
|
+
for (let key in Hot.API.authCredentials)
|
|
60
|
+
{
|
|
61
|
+
if (jsonObj[key] == null)
|
|
62
|
+
jsonObj[key] = Hot.API.authCredentials[key];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return (jsonObj);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Make a request to the server.
|
|
74
|
+
*/
|
|
75
|
+
function HotStaqPostJSONObject (methodType, url, jsonObj, auth)
|
|
76
|
+
{
|
|
77
|
+
let headers = {
|
|
78
|
+
"Accept": "application/json",
|
|
79
|
+
"Content-Type": "application/json"
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
if (auth != null)
|
|
83
|
+
headers["Authorization"] = auth;
|
|
84
|
+
|
|
85
|
+
let promise = fetch (url, {
|
|
86
|
+
"method": methodType,
|
|
87
|
+
"headers": headers,
|
|
88
|
+
body: JSON.stringify (jsonObj)
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
return (promise);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The data API route.
|
|
96
|
+
*/
|
|
97
|
+
class data
|
|
98
|
+
{
|
|
99
|
+
constructor (baseUrl, connection, db)
|
|
100
|
+
{
|
|
101
|
+
if (baseUrl == null)
|
|
102
|
+
baseUrl = "http://127.0.0.1:3243";
|
|
103
|
+
|
|
104
|
+
if (connection === undefined)
|
|
105
|
+
connection = null;
|
|
106
|
+
|
|
107
|
+
if (db === undefined)
|
|
108
|
+
db = null;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The base url to make calls to.
|
|
112
|
+
*/
|
|
113
|
+
this.baseUrl = baseUrl;
|
|
114
|
+
/**
|
|
115
|
+
* The connection to the server/client.
|
|
116
|
+
*/
|
|
117
|
+
this.connection = connection;
|
|
118
|
+
/**
|
|
119
|
+
* The authorization used to connect to the server.
|
|
120
|
+
*/
|
|
121
|
+
this.authorization = null;
|
|
122
|
+
/**
|
|
123
|
+
* The database connection, if any.
|
|
124
|
+
*/
|
|
125
|
+
this.db = db;
|
|
126
|
+
|
|
127
|
+
if (connection != null)
|
|
128
|
+
{
|
|
129
|
+
if (connection.api != null)
|
|
130
|
+
{
|
|
131
|
+
if (connection.api.authCredentials != null)
|
|
132
|
+
this.authorization = connection.api.authCredentials;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* The JSON object to send to the server.
|
|
139
|
+
*
|
|
140
|
+
* @typedef {Object} DATA_ADD_JSON_OBJECT_TYPE
|
|
141
|
+
* @property {string} schema The schema to add data to.
|
|
142
|
+
* @property {string} fields The fields and their values to add to the database. A key/value object must be passed. Example: { "name": "Test_User" }
|
|
143
|
+
*/
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* The add method.
|
|
147
|
+
*
|
|
148
|
+
* @param {DATA_ADD_JSON_OBJECT_TYPE} jsonObj
|
|
149
|
+
*
|
|
150
|
+
* @returns {string} Returns true if successful.
|
|
151
|
+
*/
|
|
152
|
+
add (jsonObj)
|
|
153
|
+
{
|
|
154
|
+
var promise = new Promise ((resolve, reject) =>
|
|
155
|
+
{
|
|
156
|
+
const url = `${this.baseUrl}/v1/data/add`;
|
|
157
|
+
const auth = null;
|
|
158
|
+
|
|
159
|
+
if (this.authorization != null)
|
|
160
|
+
{
|
|
161
|
+
if (this.authorization.toAuthorizationHeaderString != null)
|
|
162
|
+
auth = this.authorization.toAuthorizationHeaderString ();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
jsonObj = HotStaqProcessJSONObject (jsonObj);
|
|
167
|
+
HotStaqPostJSONObject ("POST", url, jsonObj, auth).then (
|
|
168
|
+
function (response)
|
|
169
|
+
{
|
|
170
|
+
var result = response.json ();
|
|
171
|
+
|
|
172
|
+
resolve (result);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
return (promise);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* The JSON object to send to the server.
|
|
181
|
+
*
|
|
182
|
+
* @typedef {Object} DATA_LIST_JSON_OBJECT_TYPE
|
|
183
|
+
* @property {string} schema The schema to access.
|
|
184
|
+
* @property {array} fields The list of fields in the schema to access.
|
|
185
|
+
* @property {int} offset The offset.
|
|
186
|
+
* @property {int} limit The max number of results to return. Default is 20.
|
|
187
|
+
*/
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* The list method.
|
|
191
|
+
*
|
|
192
|
+
* @param {DATA_LIST_JSON_OBJECT_TYPE} jsonObj
|
|
193
|
+
*
|
|
194
|
+
* @returns {string} Returns the results from the schema.
|
|
195
|
+
*/
|
|
196
|
+
list (jsonObj)
|
|
197
|
+
{
|
|
198
|
+
var promise = new Promise ((resolve, reject) =>
|
|
199
|
+
{
|
|
200
|
+
const url = `${this.baseUrl}/v1/data/list`;
|
|
201
|
+
const auth = null;
|
|
202
|
+
|
|
203
|
+
if (this.authorization != null)
|
|
204
|
+
{
|
|
205
|
+
if (this.authorization.toAuthorizationHeaderString != null)
|
|
206
|
+
auth = this.authorization.toAuthorizationHeaderString ();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
jsonObj = HotStaqProcessJSONObject (jsonObj);
|
|
211
|
+
HotStaqPostJSONObject ("POST", url, jsonObj, auth).then (
|
|
212
|
+
function (response)
|
|
213
|
+
{
|
|
214
|
+
var result = response.json ();
|
|
215
|
+
|
|
216
|
+
resolve (result);
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
return (promise);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (typeof (AdminPanelWeb.AppAPI) === "undefined")
|
|
225
|
+
{
|
|
226
|
+
if (typeof (HotAPIGlobal) !== "undefined")
|
|
227
|
+
{
|
|
228
|
+
AdminPanelWeb.AppAPI = class extends HotAPIGlobal
|
|
229
|
+
{
|
|
230
|
+
constructor (baseUrl, connection, db)
|
|
231
|
+
{
|
|
232
|
+
super (baseUrl, connection, db);
|
|
233
|
+
|
|
234
|
+
this.data = new data (baseUrl, connection, db);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
version: "3.8"
|
|
2
|
+
services:
|
|
3
|
+
# Used just to make sure the database has started before continuing.
|
|
4
|
+
init-app-database:
|
|
5
|
+
image: mariadb:10.10
|
|
6
|
+
depends_on:
|
|
7
|
+
app-database:
|
|
8
|
+
condition: service_healthy
|
|
9
|
+
environment:
|
|
10
|
+
MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}"
|
|
11
|
+
MYSQL_DATABASE: "${DATABASE_SCHEMA}"
|
|
12
|
+
MYSQL_USER: "${DATABASE_USERNAME}"
|
|
13
|
+
MYSQL_PASSWORD: "${DATABASE_PASSWORD}"
|
|
14
|
+
command:
|
|
15
|
+
- "exit 0"
|
|
16
|
+
networks:
|
|
17
|
+
- app-network
|
|
18
|
+
|
|
19
|
+
app-database:
|
|
20
|
+
image: mariadb:10.10
|
|
21
|
+
networks:
|
|
22
|
+
- app-network
|
|
23
|
+
healthcheck:
|
|
24
|
+
test: ["CMD", "mysqladmin" ,"ping", "-h", "127.0.0.1"]
|
|
25
|
+
retries: 10
|
|
26
|
+
timeout: 10s
|
|
27
|
+
ports:
|
|
28
|
+
- "${DATABASE_PORT}:3306"
|
|
29
|
+
environment:
|
|
30
|
+
MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}"
|
|
31
|
+
MYSQL_DATABASE: "${DATABASE_SCHEMA}"
|
|
32
|
+
MYSQL_USER: "${DATABASE_USERNAME}"
|
|
33
|
+
MYSQL_PASSWORD: "${DATABASE_PASSWORD}"
|
|
34
|
+
|
|
35
|
+
volumes:
|
|
36
|
+
app-database-volume:
|
|
37
|
+
|
|
38
|
+
networks:
|
|
39
|
+
app-network:
|
package/env-example
CHANGED
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hotstaq/admin-panel",
|
|
3
3
|
"description": "",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.4",
|
|
5
5
|
"main": "build/src/AppAPI.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"start": "hotstaq --hotsite ./HotSite.json --env-file ./.env run --server-type web-api",
|
|
8
8
|
"dev": "hotstaq --hotsite ./HotSite.json --development-mode run --server-type web-api --web-http-port 8080",
|
|
9
|
-
"test": "hotstaq
|
|
9
|
+
"test": "hotstaq --dev --env-file .env run --server-type web-api",
|
|
10
10
|
"build": "tsc --build ./tsconfig.json",
|
|
11
|
-
"build-web": "webpack --mode=production",
|
|
12
|
-
"build-web-debug": "webpack --mode=development",
|
|
11
|
+
"build-web": "hotstaq create --copy-libraries-to-location ./public/js/ app && hotstaq module build && webpack --mode=production && cp -f ./build-web/AdminPanelComponents.js ./public/js/AdminPanelComponents.js && hotstaq generate --copy-to ./public/js/",
|
|
12
|
+
"build-web-debug": "hotstaq create --copy-libraries-to-location ./public/js/ app && hotstaq module build && webpack --mode=development && cp -f ./build-web/AdminPanelComponents.js ./public/js/AdminPanelComponents.js && hotstaq generate --copy-to ./public/js/",
|
|
13
13
|
"build-doc": "hotstaq generate --generate-type openapi-3.0.0-yaml",
|
|
14
|
-
"prepublishOnly": "npm run build
|
|
14
|
+
"prepublishOnly": "npm run build && npm run build-web"
|
|
15
15
|
},
|
|
16
16
|
"keywords": [],
|
|
17
17
|
"author": "FreeLight, Inc",
|
package/src/WebExport.ts
CHANGED
|
@@ -16,8 +16,8 @@ async function buildAssets (): Promise<any>
|
|
|
16
16
|
"@popperjs/core"],
|
|
17
17
|
html: ["./assets/html/*.*"],
|
|
18
18
|
css: ["./assets/css/*.*"],
|
|
19
|
-
js: ["./assets/js/*.*", "./build-web/
|
|
20
|
-
componentLibrary: "
|
|
19
|
+
js: ["./assets/js/*.*", "./build-web/AdminPanelComponents.js"],
|
|
20
|
+
componentLibrary: "AdminPanelComponentsWeb",
|
|
21
21
|
components: [
|
|
22
22
|
AdminButton,
|
|
23
23
|
AdminDashboard,
|
package/src/cli.ts
ADDED
|
@@ -23,13 +23,12 @@ export class AdminDashboard extends HotComponent
|
|
|
23
23
|
/**
|
|
24
24
|
* Add this table field to the table
|
|
25
25
|
*/
|
|
26
|
+
// @ts-ignore
|
|
26
27
|
async onPostPlace (parentHtmlElement: HTMLElement, htmlElement: HTMLElement): Promise<HTMLElement>
|
|
27
28
|
{
|
|
28
29
|
// Set the base API url to use for this dashboard.
|
|
29
30
|
if (this.base != "")
|
|
30
31
|
Hot.Data.baseUrl = this.base;
|
|
31
|
-
|
|
32
|
-
return (htmlElement);
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
async output (): Promise<string>
|
|
@@ -3,7 +3,7 @@ import { HotStaq, Hot, HotAPI, HotComponent } from "hotstaq";
|
|
|
3
3
|
export class AdminEdit extends HotComponent
|
|
4
4
|
{
|
|
5
5
|
/**
|
|
6
|
-
* The title of this
|
|
6
|
+
* The title of this edit modal.
|
|
7
7
|
*/
|
|
8
8
|
title: string;
|
|
9
9
|
/**
|
|
@@ -102,7 +102,8 @@ export class AdminEdit extends HotComponent
|
|
|
102
102
|
parentSelector: "body"
|
|
103
103
|
},
|
|
104
104
|
{
|
|
105
|
-
html
|
|
105
|
+
html: `<button id = "${this.modalId}-add-btn" type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#${this.modalId}">Add</button>`,
|
|
106
|
+
//`<button id = "${this.modalId}-add-btn" type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" onclick = "$('#${this.modalId}').modal ('show');">Add</button>`,
|
|
106
107
|
parentSelector: `hot-place-here[name="buttons"]`
|
|
107
108
|
}]);
|
|
108
109
|
}
|
|
@@ -18,14 +18,14 @@ export class AdminTableField extends HotComponent
|
|
|
18
18
|
/**
|
|
19
19
|
* Add this table field to the table
|
|
20
20
|
*/
|
|
21
|
+
// @ts-ignore
|
|
21
22
|
async onPostPlace (parentHtmlElement: HTMLElement, htmlElement: HTMLElement): Promise<HTMLElement>
|
|
22
23
|
{
|
|
23
24
|
// @ts-ignore
|
|
24
25
|
let hotComponent = parentHtmlElement.parentNode.parentNode.parentNode.hotComponent;
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return (htmlElement);
|
|
27
|
+
if (hotComponent != null)
|
|
28
|
+
hotComponent.addHeaderDataOnly (this, htmlElement);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
async output ()
|
|
@@ -3,7 +3,9 @@ import { HotStaq, Hot, HotAPI, HotComponent } from "hotstaq";
|
|
|
3
3
|
export class AdminTableRow extends HotComponent
|
|
4
4
|
{
|
|
5
5
|
/**
|
|
6
|
-
* The
|
|
6
|
+
* The fields are stored in a key/value object.
|
|
7
|
+
*
|
|
8
|
+
* @example { "name": "John Smith", "email": "john.smith@email.com" }
|
|
7
9
|
*/
|
|
8
10
|
fields: any[];
|
|
9
11
|
|
|
@@ -12,23 +14,17 @@ export class AdminTableRow extends HotComponent
|
|
|
12
14
|
super (copy, api);
|
|
13
15
|
|
|
14
16
|
this.tag = "admin-table-row";
|
|
15
|
-
/**
|
|
16
|
-
* The fields are stored in a key/value object.
|
|
17
|
-
*
|
|
18
|
-
* @example { "name": "John Smith", "email": "john.smith@email.com" }
|
|
19
|
-
*/
|
|
20
17
|
this.fields = [];
|
|
21
18
|
}
|
|
22
19
|
|
|
23
20
|
/**
|
|
24
21
|
* Add this table row to the table
|
|
25
22
|
*/
|
|
23
|
+
// @ts-ignore
|
|
26
24
|
async onPostPlace (parentHtmlElement: HTMLElement, htmlElement: HTMLElement): Promise<HTMLElement>
|
|
27
25
|
{
|
|
28
26
|
// @ts-ignore
|
|
29
27
|
parentHtmlElement.parentNode.parentNode.parentNode.hotComponent.rowElements.push ({ fields: this.fields, element: htmlElement});
|
|
30
|
-
|
|
31
|
-
return (htmlElement);
|
|
32
28
|
}
|
|
33
29
|
|
|
34
30
|
async output ()
|
|
@@ -128,14 +128,13 @@ export class AdminTable extends HotComponent
|
|
|
128
128
|
/**
|
|
129
129
|
* Get the list of data from the server.
|
|
130
130
|
*/
|
|
131
|
+
// @ts-ignore
|
|
131
132
|
async onPostPlace (parentHtmlElement: HTMLElement, htmlElement: HTMLElement): Promise<HTMLElement>
|
|
132
133
|
{
|
|
133
134
|
setTimeout (async () =>
|
|
134
135
|
{
|
|
135
136
|
await this.refreshList ();
|
|
136
137
|
}, 50);
|
|
137
|
-
|
|
138
|
-
return (htmlElement);
|
|
139
138
|
}
|
|
140
139
|
|
|
141
140
|
async output ()
|
|
@@ -18,7 +18,8 @@ export class AdminText extends HotComponent
|
|
|
18
18
|
/**
|
|
19
19
|
* Corrects the placement of the text elements for modals.
|
|
20
20
|
*/
|
|
21
|
-
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
async onPostPlace (parentHtmlElement: HTMLElement, htmlElement: HTMLElement): Promise<HTMLElement>
|
|
22
23
|
{
|
|
23
24
|
let placeHereArray = parentHtmlElement.querySelectorAll (`hot-place-here[type="modal"]`);
|
|
24
25
|
|
|
@@ -35,8 +36,13 @@ export class AdminText extends HotComponent
|
|
|
35
36
|
|
|
36
37
|
async output ()
|
|
37
38
|
{
|
|
39
|
+
let value: string = "";
|
|
40
|
+
|
|
41
|
+
if (this.value != null)
|
|
42
|
+
value = this.value;
|
|
43
|
+
|
|
38
44
|
return (`<div>
|
|
39
|
-
<label class="form-label">${this.inner}</label><input class="form-control" type = "text" value = "" />
|
|
45
|
+
<label class="form-label">${this.inner}</label><input class="form-control" type = "text" value = "${value}" />
|
|
40
46
|
</div>`);
|
|
41
47
|
}
|
|
42
48
|
}
|
package/start.sh
ADDED
package/stop.sh
ADDED
package/webpack.config.cjs
CHANGED
|
@@ -77,9 +77,9 @@ module.exports = {
|
|
|
77
77
|
"node:zlib": "{}"
|
|
78
78
|
},
|
|
79
79
|
output: {
|
|
80
|
-
filename: "
|
|
80
|
+
filename: "AdminPanelComponents.js",
|
|
81
81
|
path: ppath.resolve (process.cwd (), "build-web"),
|
|
82
|
-
library: "
|
|
82
|
+
library: "AdminPanelComponentsWeb",
|
|
83
83
|
libraryTarget: "var"
|
|
84
84
|
}
|
|
85
85
|
};
|