diff --git a/shadow-query/index.html b/shadow-query/index.html
new file mode 100644
index 00000000..d6514e7d
--- /dev/null
+++ b/shadow-query/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/shadow-query/shadow-query.js b/shadow-query/shadow-query.js
new file mode 100644
index 00000000..c27597fc
--- /dev/null
+++ b/shadow-query/shadow-query.js
@@ -0,0 +1,2 @@
+// Minified ShadowQuery:
+class ShadowQuery extends Array{constructor(e,t){let r;if(Array.isArray(e))r=e;else if(e instanceof ShadowQuery)r=e;else if(e instanceof NodeList){r=[];for(var o=0;ot.length)for(let r=t.length;r=o.length||(!s||r%s?iterNodeArray(e,t,r,{array:o,chunks:s,selector:n,template:i,update:l}):e[timeoutKey(n)]=setTimeout(function(){iterNodeArray(e,t,r,{array:o,chunks:s,selector:n,template:i,update:l})}))}function iterNodeArray(e,t,r,{array:o,chunks:s,selector:n,template:i,update:l}){let a=t[r];a||(e.appendChild(i()),a=e.lastChild),l&&l($(a),o[r],r),delete e[timeoutKey(n)],iterNodeArrayChunk(e,t,++r,{array:o,chunks:s,selector:n,template:i,update:l})}function timeoutKey(e){return`_shadowQueryChildArray${e||""}`}function find(e,t){const r=[];for(let o=0;o
+ :host {
+ display: block;
+ width: 100%;
+ font-family: sans-serif;
+ }
+
+
+
+
+`;
+
+customElements.define('sq-monster', class extends HTMLElement {
+ constructor() {super(); $.template(this, sqTemplate);}
+ connectedCallback() {
+ this.attachShadow({mode: 'open'}).appendChild(this.template);
+ setTimeout(() => {
+ this._table = $(this, 'sq-table')[0];
+ this._table.initialize(ENV.generateData().toArray());
+ this._update();
+ });
+ }
+ _update() {
+ this._table.update(ENV.generateData().toArray());
+ Monitoring.renderRate.ping();
+ setTimeout(() => this._update());
+ }
+});
+
+const tableTemplate = `
+
+
+`;
+const rowTemplate = `\
+ | \
+ | \
+ | \
+ | \
+ | \
+ | \
+ | \
+
`;
+
+customElements.define('sq-table', class extends HTMLElement {
+ constructor() {
+ super();
+ $.template(this, {'default':tableTemplate, 'row': rowTemplate});
+ }
+ connectedCallback() {
+ this.attachShadow({mode: 'open'}).appendChild(this.template);
+ }
+ initialize(data) {
+ this._iniDom(data);
+ this._iniAccessors();
+ }
+ _iniDom(data) {
+ $(this, 'table').childArray({
+ array: data,
+ template: () => this.getTemplate('row'),
+ update: (row, data) => row.query('td:first-child').text(data.dbname),
+ });
+ }
+ _iniAccessors() {
+ const row = $(this, 'tr');
+ const data = 'td + td + td';
+ this._classed = row.map(tr => $(tr, 'span')[0].childNodes[0]);
+ this._class = row.map(tr => $(tr, 'span')[0].classList);
+ this._dataCell = row.map(tr => $(tr, data).map(td => td.childNodes[0]));
+ this._dataPopup = row.map(tr => $(tr, 'div').map(div=>div.childNodes[0]));
+ }
+ update(data) {
+ for(let i = 0; i < data.length; i++) {
+ this._classed[i].nodeValue = data[i].lastSample.nbQueries;
+ this._class [i].toggle(
+ 'w', data[i].lastSample.countClassName.indexOf('w')!==-1
+ );
+ const queries = data[i].lastSample.topFiveQueries;
+ for(let j = 0; j < queries.length; j++) {
+ this._dataCell [i][j].nodeValue = queries[j].formatElapsed;
+ this._dataPopup[i][j].nodeValue = queries[j].query;
+ }
+ }
+ }
+});