// ==UserScript==
// @name MonkeyConfig Mod
// @noframes
// @version 2.1
// @namespace http://odyniec.net/
// @contributionURL https://saweria.co/Bloggerpemula
// @description Enhanced Configuration Dialog Builder with column layout , custom styling , and Additional input types
// ==/UserScript==
/*
* MonkeyConfig Enhanced
* Based on version 0.1.4 by Michal Wojciechowski (odyniec.net)
* v0.1.4 - January 2020 - David Hosier (https://github.com/david-hosier/MonkeyConfig)
* Enhanced by Bloggerpemula - March 2025
* Additions: Column layout, font size/color customization, new input types (textarea, range, radio, file, button, group)
* Modified: Checkbox, number, and text inputs aligned inline with labels - March 2025
* Fixed: Improved Shadow DOM and Optimized Iframe for consistent styling across sites - March 2025
*/
function MonkeyConfig(data) {
let cfg = this, params = data.parameters || data.params, values = {}, storageKey,
displayed, openLayer, shadowRoot, container, iframeFallback;
function log(message) {console.log(`[MonkeyConfig v2.1] ${message}`);}
function init() {
data.buttons = data.buttons || ['save', 'reset', 'close', 'reload', 'homepage'];
storageKey = '_MonkeyConfig_' + (data.title || 'Configuration').replace(/[^a-zA-Z0-9]/g, '_') + '_cfg';
const storedValues = GM_getValue(storageKey) ? JSON.parse(GM_getValue(storageKey)) : {};
cfg.shadowWidth = data.shadowWidth || storedValues.shadowWidth || "600px";
cfg.shadowHeight = data.shadowHeight || storedValues.shadowHeight || "300px";
cfg.iframeWidth = data.iframeWidth || storedValues.iframeWidth || "600px";
cfg.iframeHeight = data.iframeHeight || storedValues.iframeHeight || "300px";
cfg.shadowFontSize = data.shadowFontSize || storedValues.shadowFontSize || "14px";
cfg.shadowFontColor = data.shadowFontColor || storedValues.shadowFontColor || "#000000";
cfg.iframeFontSize = data.iframeFontSize || storedValues.iframeFontSize || "14px";
cfg.iframeFontColor = data.iframeFontColor || storedValues.iframeFontColor || "#000000";
cfg.title = data.title || (typeof GM_getMetadata === 'function' ? GM_getMetadata('name') + ' Configuration' : 'Configuration');
for (let key in params) {
const param = params[key];
values[key] = storedValues[key] ?? param.default ?? '';}
if (data.menuCommand) GM_registerMenuCommand(data.menuCommand === true ? cfg.title : data.menuCommand, () => cfg.open());
cfg.open = open;
cfg.close = close;
cfg.get = name => values[name];
cfg.set = (name, value) => { values[name] = value; update(); };}
function setDefaults() {
for (let key in params) if (params[key].default !== undefined) values[key] = params[key].default;
update();}
function render() {
let html = `<div class="__MonkeyConfig_container"><h1>${cfg.title}</h1><div class="__MonkeyConfig_content"><div class="__MonkeyConfig_top">`;
for (let key in params) if (params[key].column === 'top') html += MonkeyConfig.formatters.tr(key, params[key]);
html += `</div><div class="__MonkeyConfig_columns"><div class="__MonkeyConfig_left_column">`;
for (let key in params) if (params[key].column === 'left') html += MonkeyConfig.formatters.tr(key, params[key]);
html += `</div><div class="__MonkeyConfig_right_column">`;
for (let key in params) if (params[key].column === 'right') html += MonkeyConfig.formatters.tr(key, params[key]);
html += `</div></div><table class="__MonkeyConfig_default">`;
for (let key in params) if (!params[key].column) html += MonkeyConfig.formatters.tr(key, params[key]);
html += `</table><div class="__MonkeyConfig_bottom">`;
for (let key in params) if (params[key].column === 'bottom') html += MonkeyConfig.formatters.tr(key, params[key]);
html += `</div></div><div class="__MonkeyConfig_buttons_container"><table><tr>`;
data.buttons.forEach(btn => {
html += '<td>';
if (btn === 'save') html += `<button type="button" id="__MonkeyConfig_button_save"><img src="data:image/png;base64,${MonkeyConfig.res.icons.save}" alt="Save"/> Save</button>`;
else if (btn === 'reset') html += `<button type="button" id="__MonkeyConfig_button_reset"><img src="data:image/png;base64,${MonkeyConfig.res.icons.reset}" alt="Reset"/> Reset</button>`;
else if (btn === 'close') html += `<button type="button" id="__MonkeyConfig_button_close"><img src="data:image/png;base64,${MonkeyConfig.res.icons.close}" alt="Close"/> Close</button>`;
else if (btn === 'reload') html += `<button type="button" id="__MonkeyConfig_button_reload"><img src="data:image/png;base64,${MonkeyConfig.res.icons.reload}" alt="Reload"/> Reload</button>`;
else if (btn === 'homepage') html += `<button type="button" id="__MonkeyConfig_button_homepage"><img src="data:image/png;base64,${MonkeyConfig.res.icons.home}" alt="Homepage"/> Homepage</button>`;
html += '</td>';});
return html + '</tr></table></div></div>';}
function update() {
if (!displayed) return;
const root = shadowRoot || (iframeFallback && iframeFallback.contentDocument);
if (!root) return;
for (let key in params) {
const elem = root.querySelector(`[name="${key}"]`), param = params[key];
if (!elem) continue;
if (param.type === 'checkbox') elem.checked = !!values[key];
else if (param.type === 'custom' && param.set) param.set(values[key], root.querySelector(`#__MonkeyConfig_parent_${key}`));
else if (['number', 'text', 'color', 'textarea', 'range'].includes(param.type)) elem.value = values[key] || param.default;
else if (param.type === 'radio') { const radio = root.querySelector(`[name="${key}"][value="${values[key]}"]`); if (radio) radio.checked = true; }
else if (param.type === 'file') elem.value = '';
else if (param.type === 'select') {
const currentValue = values[key];
if (elem.type === 'checkbox') {
const checkboxes = root.querySelectorAll(`input[name="${key}"]`);
checkboxes.forEach(cb => cb.checked = currentValue.includes(cb.value));
} else if (elem.multiple) {
const options = root.querySelectorAll(`select[name="${key}"] option`);
options.forEach(opt => opt.selected = currentValue.includes(opt.value));
} else {
elem.value = currentValue;}}
const fontSize = shadowRoot ? this.shadowFontSize : this.iframeFontSize;
const defaultFontColor = shadowRoot ? this.shadowFontColor : this.iframeFontColor;
const labelFontColor = param.fontColor || defaultFontColor;
elem.style.fontSize = fontSize;
elem.style.color = labelFontColor;
if (param.type === 'checkbox' || param.type === 'textarea') {
elem.style.backgroundColor = 'inherit';
elem.style.color = labelFontColor;}
const label = root.querySelector(`label[for="__MonkeyConfig_field_${key}"]`);
if (label) {
label.style.fontSize = fontSize;
label.style.color = labelFontColor;
label.style.cssText += param.type === 'textarea' ? 'text-align:center;display:block;width:100%' : 'text-align:left;display:inline-block;width:auto';}}}
function saveClick() {
const root = shadowRoot || (iframeFallback && iframeFallback.contentDocument);
for (let key in params) {
const elem = root.querySelector(`[name="${key}"]`), param = params[key];
if (!elem) continue;
if (param.type === 'checkbox') values[key] = elem.checked;
else if (param.type === 'custom' && param.get) values[key] = param.get(root.querySelector(`#__MonkeyConfig_parent_${key}`));
else if (['number', 'text', 'color', 'textarea', 'range'].includes(param.type)) values[key] = elem.value;
else if (param.type === 'radio') values[key] = root.querySelector(`[name="${key}"]:checked`)?.value || '';
else if (param.type === 'file') values[key] = elem.dataset.value || values[key];
else if (param.type === 'select') {
if (elem.type === 'checkbox') values[key] = Array.from(root.querySelectorAll(`input[name="${key}"]:checked`)).map(input => input.value);
else if (elem.multiple) values[key] = Array.from(root.querySelectorAll(`select[name="${key}"] option:selected`)).map(opt => opt.value);
else values[key] = elem.value;}}
const allValues = {
...values,
shadowWidth: this.shadowWidth,
shadowHeight: this.shadowHeight,
iframeWidth: this.iframeWidth,
iframeHeight: this.iframeHeight,
shadowFontSize: this.shadowFontSize,
shadowFontColor: this.shadowFontColor,
iframeFontSize: this.iframeFontSize,
iframeFontColor: this.iframeFontColor
};
GM_setValue(storageKey, JSON.stringify(allValues));
close();
if (data.onSave) data.onSave(values);}
function open() {
function openDone(root) {
if (window.self !== window.top) return;
const saveBtn = root.querySelector('#__MonkeyConfig_button_save');
if (saveBtn) saveBtn.addEventListener('click', saveClick, false);
const resetBtn = root.querySelector('#__MonkeyConfig_button_reset');
if (resetBtn) resetBtn.addEventListener('click', setDefaults, false);
const closeBtn = root.querySelector('#__MonkeyConfig_button_close');
if (closeBtn) closeBtn.addEventListener('click', close, false);
const reloadBtn = root.querySelector('#__MonkeyConfig_button_reload');
if (reloadBtn) reloadBtn.addEventListener('click', () => location.reload(), false);
const homepageBtn = root.querySelector('#__MonkeyConfig_button_homepage');
if (homepageBtn) homepageBtn.addEventListener('click', () => window.open('https://bloggerpemula.pythonanywhere.com/', '_blank'), false);
displayed = true;
update();}
const body = document.querySelector('body') || document.documentElement;
if (!body) {
log("Body not found, cannot open dialog");
return;}
openLayer = document.createElement('div');
openLayer.className = '__MonkeyConfig_layer';
shadowRoot = openLayer.attachShadow({ mode: 'open' });
const shadowWidth = cfg.shadowWidth || "600px";
const shadowHeight = cfg.shadowHeight || "300px";
log(`Preparing Shadow DOM with title: ${cfg.title}, dimensions - Width: ${shadowWidth}, Height: ${shadowHeight}`);
const heightStyle = shadowHeight === 'auto' ? 'auto' : shadowHeight;
shadowRoot.innerHTML = `
<style>
:host { all: initial; display: block !important; font-family: Arial, sans-serif !important; isolation: isolate; z-index: 2147483647 !important; font-size: ${cfg.shadowFontSize} !important; color: ${cfg.shadowFontColor} !important; }
h1 { font-size: 120% !important; font-weight: normal !important; margin: 0 !important; padding: 0 !important; }
${MonkeyConfig.res.stylesheets.main.replace(/__FONT_SIZE__/g, cfg.shadowFontSize).replace(/__FONT_COLOR__/g, cfg.shadowFontColor)}
.__MonkeyConfig_overlay { position: fixed !important; top: 0 !important; left: 0 !important; width: 100vw !important; height: 100vh !important; background-color: rgba(0, 0, 0, 0.6) !important; z-index: 2147483646 !important; }
.__MonkeyConfig_container { position: fixed !important; top: 50% !important; left: 50% !important; transform: translate(-50%, -50%) !important; z-index: 2147483647 !important; width: ${shadowWidth} !important; height: ${heightStyle} !important; max-width: 90vw !important; max-height: 80vh !important; overflow-y: auto !important; box-sizing: border-box !important; }
</style>
<div class="__MonkeyConfig_overlay"></div>
${render()}
`;
container = shadowRoot.querySelector('.__MonkeyConfig_container');
openLayer.style.cssText = 'position: fixed !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; z-index: 2147483647 !important;';
body.appendChild(openLayer);
log('Dialog appended to body via Shadow DOM');
const appliedWidth = container.offsetWidth;
const appliedHeight = container.offsetHeight;
log(`Actual applied dimensions - Width: ${appliedWidth}px, Height: ${appliedHeight}px`);
if (!container || shadowRoot.querySelector('.__MonkeyConfig_overlay').offsetHeight === 0) {
log('Shadow DOM failed, switching to iframe fallback');
body.removeChild(openLayer);
shadowRoot = null;
iframeFallback = document.createElement('iframe');
const iframeWidth = cfg.iframeWidth || "600px";
const iframeHeight = cfg.iframeHeight || "300px";
log(`Switching to iframe with dimensions - Width: ${iframeWidth}, Height: ${iframeHeight}`);
iframeFallback.style.cssText = `position: fixed !important; top: 50% !important; left: 50% !important; transform: translate(-50%, -50%) !important; width: ${iframeWidth} !important; height: ${iframeHeight} !important; max-width: 90vw !important; max-height: 80vh !important; z-index: 2147483647 !important; border: none !important; background: #eee !important; box-shadow: 2px 2px 16px #000 !important; border-radius: 0.5em !important;`;
body.appendChild(iframeFallback);
const iframeDoc = iframeFallback.contentDocument;
iframeDoc.open();
iframeDoc.write(`<!DOCTYPE html><html><head><style>
/* Reset semua elemen untuk isolasi */
html, body, * { all: initial !important; margin: 0 !important; padding: 0 !important; font-family: Arial, sans-serif !important; font-size: ${cfg.iframeFontSize} !important; color: ${cfg.iframeFontColor} !important; height: 100% !important; width: 100% !important; box-sizing: border-box !important; }
/* Pastikan background iframe tidak transparan */
html, body { background: #eee !important; display: block !important; isolation: isolate !important; }
/* Override selector global yang mungkin dari situs */
input, textarea, button, label, table, td, div, span { all: unset !important; }
${MonkeyConfig.res.stylesheets.main.replace(/__FONT_SIZE__/g, cfg.iframeFontSize).replace(/__FONT_COLOR__/g, cfg.iframeFontColor)}
.__MonkeyConfig_overlay { position: fixed !important; top: 0 !important; left: 0 !important; width: 100vw !important; height: 100vh !important; background-color: rgba(0, 0, 0, 0.6) !important; z-index: 2147483646 !important; }
.__MonkeyConfig_container { position: relative !important; width: 100% !important; height: 100% !important; padding: 1em !important; box-sizing: border-box !important; overflow-y: auto !important; border-radius: 0.5em !important; font-size: ${cfg.iframeFontSize} !important; isolation: isolate !important; background: #eee linear-gradient(180deg, #f8f8f8 0, #ddd 100%) !important; }
.__MonkeyConfig_container h1 { font-size: 120% !important; font-weight: normal !important; margin: 0 !important; padding: 0 !important; display: block !important; }
.__MonkeyConfig_container td.__MonkeyConfig_inline input[type="checkbox"] { width: 32px !important; height: 32px !important; margin: 0 0.5em 0 0 !important; vertical-align: middle !important; accent-color: #007bff !important; display: inline-block !important; }
.__MonkeyConfig_container textarea { width: 100% !important; padding: 1.2em !important; border: 1px solid #ccc !important; border-radius: 0.3em !important; box-sizing: border-box !important; font-size: 20px !important; color: ${cfg.iframeFontColor} !important; resize: vertical !important; min-height: 140px !important; white-space: pre-wrap !important; display: block !important; }
.__MonkeyConfig_container button { background: #ccc linear-gradient(180deg, #ddd 0, #ccc 45%, #bbb 50%, #aaa 100%) !important; border: 1px solid #999 !important; border-radius: 0.5em !important; box-shadow: 0 0 1px #000 !important; padding: 12px 16px 12px 48px !important; white-space: nowrap !important; font-size: 20px !important; color: ${cfg.iframeFontColor} !important; cursor: pointer !important; display: inline-block !important; }
.__MonkeyConfig_container button:hover { background: #d2d2d2 linear-gradient(180deg, #e2e2e2 0, #d2d2d2 45%, #c2c2c2 50%, #b2b2b2 100%) !important; }
/* Pastikan elemen lain tidak terpengaruh */
.__MonkeyConfig_container label { display: inline-block !important; line-height: 120% !important; vertical-align: middle !important; }
.__MonkeyConfig_container table { border-spacing: 0 !important; margin: 0 !important; width: 100% !important; display: table !important; }
.__MonkeyConfig_container td { border: none !important; line-height: 100% !important; padding: 0.3em !important; text-align: left !important; vertical-align: middle !important; white-space: normal !important; display: table-cell !important; }
</style></head><body><div class="__MonkeyConfig_overlay"></div>${render()}</body></html>`);
iframeDoc.close();
openLayer = iframeFallback;
openDone(iframeDoc);
const iframeAppliedWidth = iframeFallback.offsetWidth;
const iframeAppliedHeight = iframeFallback.offsetHeight;
log(`Iframe actual applied dimensions - Width: ${iframeAppliedWidth}px, Height: ${iframeAppliedHeight}px`);
} else {
openDone(shadowRoot);}}
function close() {
if (openLayer) openLayer.parentNode.removeChild(openLayer);
openLayer = shadowRoot = iframeFallback = undefined;
displayed = false;}
init();}
MonkeyConfig.esc = string => string.replace(/"/g, '"');
MonkeyConfig.HTML = {
_field: (name, opt) => opt.type && MonkeyConfig.HTML[opt.type] ? (opt.html ? opt.html.replace(/\[FIELD\]/, MonkeyConfig.HTML[opt.type](name, opt)) : MonkeyConfig.HTML[opt.type](name, opt)) : '',
_label: (name, opt) => `<label for="__MonkeyConfig_field_${name}"${opt.labelAlign || opt.fontSize || opt.fontColor ? ` style="${[opt.labelAlign && `text-align:${opt.labelAlign}`, opt.fontSize && `font-size:${opt.fontSize}`, opt.fontColor && `color:${opt.fontColor}`].filter(Boolean).join(';')};"` : ''}>${opt.label || name.charAt(0).toUpperCase() + name.slice(1).replace(/_/g, ' ')}</label>`,
checkbox: name => `<input id="__MonkeyConfig_field_${name}" type="checkbox" name="${name}" />`,
custom: (name, opt) => opt.html || '',
number: (name, opt) => `<input id="__MonkeyConfig_field_${name}" type="number" class="__MonkeyConfig_field_number" name="${name}" min="${opt.min || ''}" max="${opt.max || ''}" step="${opt.step || '1'}" />`,
text: name => `<input id="__MonkeyConfig_field_${name}" type="text" class="__MonkeyConfig_field_text" name="${name}" />`,
color: name => `<input id="__MonkeyConfig_field_${name}" type="color" class="__MonkeyConfig_field_text" name="${name}" />`,
textarea: (name, opt) => `<textarea id="__MonkeyConfig_field_${name}" class="__MonkeyConfig_field_text" name="${name}" rows="${opt.rows || 4}" cols="${opt.cols || 20}"></textarea>`,
range: (name, opt) => `<input id="__MonkeyConfig_field_${name}" type="range" name="${name}" min="${opt.min || 0}" max="${opt.max || 100}" step="${opt.step || 1}" />`,
radio: (name, opt) => Object.entries(opt.choices).map(([val, text]) => `<label><input type="radio" name="${name}" value="${MonkeyConfig.esc(val)}" /> ${text}</label><br/>`).join(''),
file: (name, opt) => `<input id="__MonkeyConfig_field_${name}" type="file" name="${name}" accept="${opt.accept || '*/*'}" />`,
button: (name, opt) => `<button type="button" id="__MonkeyConfig_field_${name}" name="${name}">${opt.label || 'Click'}</button>`,
group: (name, opt) => `<fieldset><legend>${opt.label || name}</legend>${Object.entries(opt.params).map(([subName, subOpt]) => MonkeyConfig.formatters.tr(subName, subOpt)).join('')}</fieldset>`,
select: (name, opt) => {
const choices = Array.isArray(opt.choices) ? Object.fromEntries(opt.choices.map(val => [val, val])) : opt.choices;
return `<select id="__MonkeyConfig_field_${name}" class="__MonkeyConfig_field_select" name="${name}"${opt.multiple ? ' multiple="multiple"' : ''}>${Object.entries(choices).map(([val, text]) => `<option value="${MonkeyConfig.esc(val)}">${text}</option>`).join('')}</select>`;}};
MonkeyConfig.formatters = {
tr: (name, opt) => `<tr>${['checkbox', 'number', 'text'].includes(opt.type) ? `<td id="__MonkeyConfig_parent_${name}" colspan="2" class="__MonkeyConfig_inline">${MonkeyConfig.HTML._label(name, opt)} ${MonkeyConfig.HTML._field(name, opt)}</td>` : opt.type === 'group' ? `<td colspan="2">${MonkeyConfig.HTML._field(name, opt)}</td>` : `<td>${MonkeyConfig.HTML._label(name, opt)}</td><td id="__MonkeyConfig_parent_${name}">${MonkeyConfig.HTML._field(name, opt)}</td>`}</tr>`};
MonkeyConfig.res = {
icons: {
save: 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGrSURBVDjLvZPZLkNhFIV75zjvYm7VGFNCqoZUJ+roKUUpjRuqp61Wq0NKDMelGGqOxBSUIBKXWtWGZxAvobr8lWjChRgSF//dv9be+9trCwAI/vIE/26gXmviW5bqnb8yUK028qZjPfoPWEj4Ku5HBspgAz941IXZeze8N1bottSo8BTZviVWrEh546EO03EXpuJOdG63otJbjBKHkEp/Ml6yNYYzpuezWL4s5VMtT8acCMQcb5XL3eJE8VgBlR7BeMGW9Z4yT9y1CeyucuhdTGDxfftaBO7G4L+zg91UocxVmCiy51NpiP3n2treUPujL8xhOjYOzZYsQWANyRYlU4Y9Br6oHd5bDh0bCpSOixJiWx71YY09J5pM/WEbzFcDmHvwwBu2wnikg+lEj4mwBe5bC5h1OUqcwpdC60dxegRmR06TyjCF9G9z+qM2uCJmuMJmaNZaUrCSIi6X+jJIBBYtW5Cge7cd7sgoHDfDaAvKQGAlRZYc6ltJlMxX03UzlaRlBdQrzSCwksLRbOpHUSb7pcsnxCCwngvM2Rm/ugUCi84fycr4l2t8Bb6iqTxSCgNIAAAAAElFTkSuQmCC',
reset: 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIJSURBVDjLpVM9aJNRFD35GsRSoUKKzQ/B0NJJF3EQlKrVgijSCBmC4NBFKihIcXBwEZdSHVoUwUInFUEkQ1DQ4CKiFsQsTrb5xNpgaZHw2Uog5t5zn0NJNFaw0guX97hwzuPcc17IOYfNlIdNVrhxufR6xJkZjAbSQGXjNAorqixSWFDV3KPhJ+UGLtSQMPryrDscPwLnAHOEOQc6gkbUpIagGmApWIb/pZRX4fjj889nWiSQtgYyBZ1BTUEj6AjPa0P71nb0Jfqwa+futIheHrzRn2yRQCUK/lOQhApBJVQJChHfnkCqOwWEQ+iORJHckUyX5ksvAEyGNuJC+s6xCRXNHNxzKMmQ4luwgjfvZp69uvr2+IZcyJ8rjIporrxURggetnV0QET3rrPxzMNM2+n7p678jUTrCiWhphAjVHR9DlR0WkSzf4IHxg5MSF0zXZEuVKWKSlCBCostS8zeG7oV64wPqxInbw86lbVXKEQ8mkAqmUJ4SxieeVhcnANFC02C7N2h69HO2IXeWC8MDj2JnqaFNAMd8f3HKjx6+LxQRmnOz1OZaxKIaF1VISYwB9ARZoQaYY6o1WpYCVYxt+zDn/XzVBv/MOWXW5J44ubRyVgkelFpmF/4BJVfOVDlVyqLVBZI5manPjajDOdcswfG9k/3X9v3/vfZv7rFBanriIo++J/f+BMT+YWS6hXl7QAAAABJRU5ErkJggg==',
close: 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACdklEQVR4nH2RzWucVRjFf899ZyaTNE0FC6K0LjIV/AJBF4IglcFWBTdON1WkDSS48A8QxBYrKIKgSzdiAonBKk0DxUVpQaFQwUU3opAaEmmxCEUqMk1m5r3Ph4smr50ontXlnOecc+9zBeCFr9Z3IRwI5+aFo5O/8z84fHp9nyTuC+fXC0cnb8mh02v3jBb8OSpOGYnbSufiq63l/zI//+VaZ3ctlkYEeiH0lPuTWjw0EkqBMSaZ8cLOthdXX9lpbi+uHtld2NKYKIIygqIerRThf/TNMXOyBo1QxpOdfW7+ahVycP5qZzzZmUYoWQM3p6dOuN8UgGfnV6Ymks+NFk4gCEHPEn9lXgbSnjrnhjRPdFWmLx1/ZFa2W56Z/XlqorC5ZiEEIMCmQgKaNSqub0E3p+nLM4/PssVVePqzH6fGC5trJsEjkC01AkSE0oOupukf3nhidtszFADw5KdXXpuox2IjpSF+4M7tLMeuvPnUwt18bWeAltotBSQFEVstAvnOkm/tnB+qeezjy51m4edqEagp5oa5oabUCJri3zz6yfdDX1w94eGPLh0ZaxRntpcIUOqdU6Mm1XDfgs1SOytvHVyuAg58+F1nV6NYqichIhARsgebpR9HpDdWl6//rWln9e32sky+f/GBZr12o1lLVXM2Y7NkZv1E+3OA1gffvj5aZ6FeFP/cRJ1etn3J3O+VCLI5ak5/oHQHWpkB1t5pf9Et7Vi/VNScbI5EEO57UwTXB2qoGv2sbOQ8c+3k4cq8jWsnDi1sDHSqnxVVo1dmImJFAPafOv9gRLSAG7+999IvO813Y/+751tB7E0iP10/9eLG328sUoT0ZNvDAAAAAElFTkSuQmCC',
reload: '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',
home: 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAACB0RVh0U29mdHdhcmUATWFjcm9tZWRpYSBGaXJld29ya3MgTVi7kSokAAAAFnRFWHRDcmVhdGlvbiBUaW1lADExLzA1LzA33bqJ2wAAAlxJREFUeJx9U0tIVGEU/v7fe30wLQxCDKdykmrUCiqTIgrG1pGBMElto1VQyySMWhVl0qJNix6QGLhQWom6isRHE5SWBWLFNGqlmTWOd+bOf85pcfU6I9WBsznn+77z4BwlIsi1089e791QWHDNVqrOUggaJiQzJpFyTSzpmqsDZ46M5eJVrsC53rfdtlaNsa+/EE86cMnL2VqhrMRCKGDDMdTTf/boqTyBqcXl4ruvPk9O/VwODs0s4n8WClgotZDYF5Adt5siaQ0AN4Y/dv6NHA1vRntDdV7sU8pgLk3B5wumEwDUhf53Bw3L6NMPs+vI5WiPhMECdL2ZwqWhL3n5qkICMdcXhKPnH43NJasW0tk88p1IGCwCFmBXWSm22IS+xG8fYwRQTJV6Y1FBTTzp/IO85id3V+JmfYWPS7GCJlNjEUvF6raj4XK0RcIgETCL3wGLQERwonYbWASXX86AoWCIKrRh8lUvHqj0iJxbncEinqgIjm0vh/1jxhuDGDqTpWlbKwDA4Y5h0AqYRPDwxRgeD46vibHg+K0OaGcJSgRZ4mk957gTZSWW30UuuK1vBG19IyAWz1eOLhPcCYtcuNATulijJRSwfQFaGWEVnN5anbfMVdPpFEw226K7mg7FHEM9oYDld0DrwMTsdwEAVnoJWZae+dbmmAUADZsKmwe+OZPBIhUMPxhEcfx93tHsfzLqx7QCOOMk3Nl4M7Dumerv93cLc+N3o5BiBYa3XCUCi1zodMqrfCWa/0y5Vnuvdw+YrgtRHZEJGmK4jERWJGZEtc63NI3n4v8As6uX85AjWHEAAAAASUVORK5CYII='
},
stylesheets: {
main: `:host, body { all: initial; font-family: Arial, sans-serif !important; display: block !important; isolation: isolate; }.__MonkeyConfig_container { display: flex !important; flex-direction: column !important; padding: 1em !important; font-size: __FONT_SIZE__ !important; color: __FONT_COLOR__ !important; background: #eee linear-gradient(180deg, #f8f8f8 0, #ddd 100%) !important; border-radius: 0.5em !important; box-shadow: 2px 2px 16px #000 !important; box-sizing: border-box !important; }.__MonkeyConfig_container h1 { border-bottom: solid 1px #999 !important; font-size: 120% !important; font-weight: normal !important; margin: 0 0 0.5em 0 !important; padding: 0 0 0.3em 0 !important; text-align: center !important; }.__MonkeyConfig_content { flex: 1 !important; overflow-y: auto !important; max-height: 60vh !important; }.__MonkeyConfig_top, .__MonkeyConfig_bottom { margin-bottom: 1em !important; }.__MonkeyConfig_columns { display: flex !important; justify-content: space-between !important; margin-bottom: 1em !important; }.__MonkeyConfig_left_column, .__MonkeyConfig_right_column { width: 48% !important; }.__MonkeyConfig_container table { border-spacing: 0 !important; margin: 0 !important; width: 100% !important; }.__MonkeyConfig_container td { border: none !important; line-height: 100% !important; padding: 0.3em !important; text-align: left !important; vertical-align: middle !important; white-space: normal !important; }.__MonkeyConfig_container td.__MonkeyConfig_inline { display: flex !important; align-items: center !important; white-space: nowrap !important; }.__MonkeyConfig_container td.__MonkeyConfig_inline label { margin-right: 0.5em !important; flex-shrink: 0 !important; display: block !important; }.__MonkeyConfig_container td.__MonkeyConfig_inline input[type="checkbox"] { flex-grow: 0 !important; margin: 0 0.3em 0 0 !important; display: inline-block !important; width: 16px !important; height: 16px !important; }.__MonkeyConfig_container td.__MonkeyConfig_inline input[type="number"], .__MonkeyConfig_container td.__MonkeyConfig_inline input[type="text"] { flex-grow: 0 !important; width: 100px !important; min-width: 50px !important; }.__MonkeyConfig_buttons_container { margin-top: 1em !important; border-top: solid 1px #999 !important; padding-top: 0.6em !important; text-align: center !important; }.__MonkeyConfig_buttons_container table { width: auto !important; margin: 0 auto !important; }.__MonkeyConfig_buttons_container td { padding: 0.3em !important; }.__MonkeyConfig_container button { background: #ccc linear-gradient(180deg, #ddd 0, #ccc 45%, #bbb 50%, #aaa 100%) !important; border: solid 1px !important; border-radius: 0.5em !important; box-shadow: 0 0 1px #000 !important; padding: 3px 8px 3px 24px !important; white-space: nowrap !important; }.__MonkeyConfig_container button img { vertical-align: middle !important; }.__MonkeyConfig_container label { line-height: 120% !important; vertical-align: middle !important; display: inline-block !important; }.__MonkeyConfig_container textarea { vertical-align: text-top !important; width: 100% !important; white-space: pre-wrap !important; resize: vertical !important; text-align: left !important; }.__MonkeyConfig_container input[type="text"], .__MonkeyConfig_container input[type="number"], .__MonkeyConfig_container input[type="color"] { background: #fff !important; }.__MonkeyConfig_container button:hover { background: #d2d2d2 linear-gradient(180deg, #e2e2e2 0, #d2d2d2 45%, #c2c2c2 50%, #b2b2b2 100%) !important; }@media (max-width: 600px) { .__MonkeyConfig_columns { flex-direction: column !important; } .__MonkeyConfig_left_column, .__MonkeyConfig_right_column { width: 100% !important; } }`}};