// Shared browser helpers for web UI escaping and formatting.
(function () {
function escapeHtml(value) {
return String(value ?? '')
.replace(/&/g, '&')
.replace(//g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
function formatDashboardDate(value, useTwentyFourHour) {
if (!value) {
return '';
}
var date = new Date(value);
if (Number.isNaN(date.getTime())) {
return '';
}
var formatOptions = {
month: 'short',
day: '2-digit',
year: 'numeric',
hour: 'numeric',
minute: '2-digit',
second: '2-digit'
};
if (useTwentyFourHour) {
formatOptions.hour12 = false;
}
return new Intl.DateTimeFormat('en-US', formatOptions).format(date);
}
function getClientRowKey(client) {
var clientName = String(client && client.client_name ? client.client_name : '').trim();
if (clientName) {
return clientName;
}
return String(client && client.screen_slug ? client.screen_slug : client && client.deviceId ? client.deviceId : client && client.id ? client.id : client && client.clientId ? client.clientId : '').trim();
}
function getClientDisplayName(client) {
if (client && client.client_name) {
return String(client.client_name).trim();
}
var clientId = String(client && client.clientId ? client.clientId : '').trim();
if (clientId) {
return clientId;
}
return '';
}
function setButtonVariant(button, classesToRemove, classToAdd) {
if (!button) {
return;
}
if (button.classList) {
classesToRemove.forEach(function (className) {
button.classList.remove(className);
});
if (classToAdd) {
button.classList.add(classToAdd);
}
return;
}
var className = String(button.className || '');
classesToRemove.forEach(function (removeClass) {
className = className.replace(new RegExp('(^|\\s)' + removeClass + '(?=\\s|$)', 'g'), ' ');
});
if (classToAdd) {
className += ' ' + classToAdd;
}
button.className = className.replace(/\s+/g, ' ').trim();
}
function normalizeDisplayIp(value) {
var ip = String(value || '').trim();
if (!ip) {
return '';
}
if (ip.toLowerCase().indexOf('::ffff:') === 0) {
return ip.slice(7).trim();
}
return ip;
}
window.escapeHtml = escapeHtml;
var defaultQrOptions = window.defaultQrOptions || {
width: 1000,
height: 1000,
type: 'canvas',
margin: 10,
qrOptions: {},
dotsOptions: {
color: '#000000',
type: 'square'
},
cornersSquareOptions: {
color: '#000000',
type: 'square'
},
cornersDotOptions: {
color: '#000000',
type: 'square'
},
backgroundOptions: {
color: '#ffffff'
}
};
var qrDotTypes = window.qrDotTypes || [
{ value: 'square', label: 'Square' },
{ value: 'dots', label: 'Dots' },
{ value: 'rounded', label: 'Rounded' },
{ value: 'extra-rounded', label: 'Extra rounded' },
{ value: 'classy', label: 'Classy' },
{ value: 'classy-rounded', label: 'Classy rounded' }
];
var qrCornerSquareTypes = window.qrCornerSquareTypes || [
{ value: 'square', label: 'Square' },
{ value: 'dot', label: 'Dot' },
{ value: 'rounded', label: 'Rounded' },
{ value: 'extra-rounded', label: 'Extra rounded' },
{ value: 'dots', label: 'Dots' },
{ value: 'classy', label: 'Classy' },
{ value: 'classy-rounded', label: 'Classy rounded' }
];
var qrCornerDotTypes = window.qrCornerDotTypes || [
{ value: 'square', label: 'Square' },
{ value: 'dot', label: 'Dot' },
{ value: 'rounded', label: 'Rounded' },
{ value: 'extra-rounded', label: 'Extra rounded' },
{ value: 'classy', label: 'Classy' },
{ value: 'classy-rounded', label: 'Classy rounded' }
];
function getOptionValue(option) {
if (option && typeof option === 'object' && option.value !== undefined && option.value !== null) {
return String(option.value).trim();
}
return String(option === undefined || option === null ? '' : option).trim();
}
function normalizeMarginValue(value, fallback) {
var parsed = Number(value);
return Number.isFinite(parsed) && parsed >= 0 ? Math.round(parsed) : fallback;
}
function normalizeHexColorValue(value, fallback) {
var raw = String(value === undefined || value === null ? '' : value).trim();
return raw || fallback;
}
function normalizeBooleanValue(value, fallback) {
if (value === undefined || value === null || value === '') {
return Boolean(fallback);
}
if (typeof value === 'boolean') {
return value;
}
var text = String(value).trim().toLowerCase();
if (text === 'true' || text === '1' || text === 'yes' || text === 'on') {
return true;
}
if (text === 'false' || text === '0' || text === 'no' || text === 'off') {
return false;
}
return Boolean(value);
}
function normalizeOptionValue(value, options, fallback) {
var text = String(value === undefined || value === null ? '' : value).trim();
for (var index = 0; index < options.length; index += 1) {
if (getOptionValue(options[index]) === text) {
return text;
}
}
return fallback;
}
function normalizeRatioValue(value, fallback) {
var parsed = Number(value);
return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
}
function normalizeGradientTypeValue(value, fallback) {
var text = String(value === undefined || value === null ? '' : value).trim().toLowerCase();
return text === 'radial' ? 'radial' : 'linear';
}
function normalizeGradientRotationValue(value, fallback) {
var parsed = Number(value);
return Number.isFinite(parsed) ? Math.round(parsed) : fallback;
}
function normalizeColorModeValue(value, fallback) {
var text = String(value === undefined || value === null ? '' : value).trim().toLowerCase();
return text === 'gradient' ? 'gradient' : 'single';
}
function normalizeColorValue(value, fallback) {
return normalizeHexColorValue(value, fallback);
}
function renderSelectOptions(options, currentValue) {
return options.map(function (option) {
var optionValue = getOptionValue(option);
var optionLabel = option && typeof option === 'object' && option.label !== undefined ? option.label : optionValue;
return '';
}).join('');
}
function normalizeSvgMarkup(svg) {
var markup = String(svg || '').trim();
if (!markup || markup.charAt(0) !== '<') {
return markup;
}
return markup.replace(/^