Updated apps
This commit is contained in:
@@ -374,26 +374,37 @@
|
||||
const normalized = typeof size === "string" ? size.trim().toLowerCase() : "";
|
||||
return ["small", "medium", "large"].includes(normalized) ? normalized : fallback;
|
||||
}
|
||||
function normalizeHeroFontSize(value) {
|
||||
if (!Number.isFinite(value)) return null;
|
||||
return Math.min(112, Math.max(12, value));
|
||||
}
|
||||
function normalizeLayoutConfig(entityConfig, cardConfig) {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
|
||||
const cardLayout = cardConfig == null ? void 0 : cardConfig.layout;
|
||||
const entityLayout = entityConfig == null ? void 0 : entityConfig.layout;
|
||||
const entityLabel = entityLayout == null ? void 0 : entityLayout.label;
|
||||
const entityHero = entityLayout == null ? void 0 : entityLayout.hero;
|
||||
const cardLabel = cardLayout == null ? void 0 : cardLayout.label;
|
||||
const cardHero = cardLayout == null ? void 0 : cardLayout.hero;
|
||||
const isCardLevelNormalization = !cardConfig;
|
||||
const rawHeight = (_d = (_c = (_b = (_a = entityLayout == null ? void 0 : entityLayout.height) != null ? _a : entityConfig.height) != null ? _b : cardLayout == null ? void 0 : cardLayout.height) != null ? _c : cardConfig == null ? void 0 : cardConfig.height) != null ? _d : 38;
|
||||
const heightExplicit = (entityLayout == null ? void 0 : entityLayout.height) !== void 0 || entityConfig._height_explicit === true || !isCardLevelNormalization && entityConfig.height !== void 0 || (cardLayout == null ? void 0 : cardLayout.height_explicit) === true || (cardConfig == null ? void 0 : cardConfig._height_explicit) === true;
|
||||
const labelPosition = normalizeLabelPosition(
|
||||
(_h = (_g = (_f = (_e = entityLabel == null ? void 0 : entityLabel.position) != null ? _e : entityConfig.label_position) != null ? _f : cardLabel == null ? void 0 : cardLabel.position) != null ? _g : cardLayout == null ? void 0 : cardLayout.label_position) != null ? _h : cardConfig == null ? void 0 : cardConfig.label_position,
|
||||
"left"
|
||||
);
|
||||
const heroFontSize = labelPosition === "hero" ? normalizeHeroFontSize((_i = entityHero == null ? void 0 : entityHero.value_size) != null ? _i : cardHero == null ? void 0 : cardHero.value_size) : null;
|
||||
return {
|
||||
label: {
|
||||
position: normalizeLabelPosition(
|
||||
(_h = (_g = (_f = (_e = entityLabel == null ? void 0 : entityLabel.position) != null ? _e : entityConfig.label_position) != null ? _f : cardLabel == null ? void 0 : cardLabel.position) != null ? _g : cardLayout == null ? void 0 : cardLayout.label_position) != null ? _h : cardConfig == null ? void 0 : cardConfig.label_position,
|
||||
"left"
|
||||
),
|
||||
width: (_m = (_l = (_k = (_j = (_i = entityLabel == null ? void 0 : entityLabel.width) != null ? _i : entityConfig.label_width) != null ? _j : cardLabel == null ? void 0 : cardLabel.width) != null ? _k : cardLayout == null ? void 0 : cardLayout.label_width) != null ? _l : cardConfig == null ? void 0 : cardConfig.label_width) != null ? _m : 100,
|
||||
hero_size: normalizeHeroSize(
|
||||
(_v = (_u = (_t = (_s = (_r = (_q = (_p = (_o = (_n = entityLabel == null ? void 0 : entityLabel.hero_size) != null ? _n : entityLabel == null ? void 0 : entityLabel.heroSize) != null ? _o : entityConfig.hero_size) != null ? _p : entityConfig.heroSize) != null ? _q : cardLabel == null ? void 0 : cardLabel.hero_size) != null ? _r : cardLabel == null ? void 0 : cardLabel.heroSize) != null ? _s : cardLayout == null ? void 0 : cardLayout.hero_size) != null ? _t : cardLayout == null ? void 0 : cardLayout.heroSize) != null ? _u : cardConfig == null ? void 0 : cardConfig.hero_size) != null ? _v : cardConfig == null ? void 0 : cardConfig.heroSize,
|
||||
position: labelPosition,
|
||||
width: (_n = (_m = (_l = (_k = (_j = entityLabel == null ? void 0 : entityLabel.width) != null ? _j : entityConfig.label_width) != null ? _k : cardLabel == null ? void 0 : cardLabel.width) != null ? _l : cardLayout == null ? void 0 : cardLayout.label_width) != null ? _m : cardConfig == null ? void 0 : cardConfig.label_width) != null ? _n : 100
|
||||
},
|
||||
hero: {
|
||||
size: normalizeHeroSize(
|
||||
(_y = (_x = (_w = (_v = (_u = (_t = (_s = (_r = (_q = (_p = (_o = entityHero == null ? void 0 : entityHero.size) != null ? _o : entityLabel == null ? void 0 : entityLabel.hero_size) != null ? _p : entityLabel == null ? void 0 : entityLabel.heroSize) != null ? _q : entityConfig.hero_size) != null ? _r : entityConfig.heroSize) != null ? _s : cardHero == null ? void 0 : cardHero.size) != null ? _t : cardLabel == null ? void 0 : cardLabel.hero_size) != null ? _u : cardLabel == null ? void 0 : cardLabel.heroSize) != null ? _v : cardLayout == null ? void 0 : cardLayout.hero_size) != null ? _w : cardLayout == null ? void 0 : cardLayout.heroSize) != null ? _x : cardConfig == null ? void 0 : cardConfig.hero_size) != null ? _y : cardConfig == null ? void 0 : cardConfig.heroSize,
|
||||
"medium"
|
||||
)
|
||||
),
|
||||
value_size: heroFontSize
|
||||
},
|
||||
height: clampSupportedRowHeight(rawHeight),
|
||||
height_explicit: heightExplicit
|
||||
@@ -2871,7 +2882,7 @@
|
||||
return 0;
|
||||
}
|
||||
_measureHeroValueWidth(heroLine, valueEl, valueFit = "normal", hideUnit = false) {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
|
||||
const layer = (_a = this.shadowRoot) == null ? void 0 : _a.querySelector(".measure-layer");
|
||||
if (!layer || !heroLine || !valueEl) return 0;
|
||||
const display = this._decodeDataAttr(valueEl.dataset.display || valueEl.textContent || "");
|
||||
@@ -2884,6 +2895,11 @@
|
||||
wrapper.dataset.heroValueFit = valueFit;
|
||||
wrapper.dataset.hideHeroUnit = hideUnit ? "true" : "false";
|
||||
wrapper.style.display = "inline-block";
|
||||
this._setStyleIfChanged(
|
||||
wrapper,
|
||||
"--sbcp-hero-base-size",
|
||||
((_c = (_b = heroLine.style) == null ? void 0 : _b.getPropertyValue) == null ? void 0 : _c.call(_b, "--sbcp-hero-base-size")) || null
|
||||
);
|
||||
const measureValue = document.createElement("span");
|
||||
measureValue.className = "hero-value";
|
||||
measureValue.dataset.display = valueEl.dataset.display || "";
|
||||
@@ -2923,11 +2939,11 @@
|
||||
wrapper.appendChild(measureValue);
|
||||
layer.replaceChildren(wrapper);
|
||||
return Math.max(
|
||||
Math.ceil((_c = (_b = measureValue.getBoundingClientRect) == null ? void 0 : _b.call(measureValue).width) != null ? _c : 0),
|
||||
Math.ceil((_e = (_d = measureValue.getBoundingClientRect) == null ? void 0 : _d.call(measureValue).width) != null ? _e : 0),
|
||||
Math.ceil(measureValue.scrollWidth || 0),
|
||||
Math.ceil((_f = (_e = (_d = text == null ? void 0 : text.getBoundingClientRect) == null ? void 0 : _d.call(text).width) != null ? _e : text == null ? void 0 : text.scrollWidth) != null ? _f : 0),
|
||||
Math.ceil((_i = (_h = (_g = number == null ? void 0 : number.getBoundingClientRect) == null ? void 0 : _g.call(number).width) != null ? _h : number == null ? void 0 : number.scrollWidth) != null ? _i : 0),
|
||||
Math.ceil((_l = (_k = (_j = unitGroup == null ? void 0 : unitGroup.getBoundingClientRect) == null ? void 0 : _j.call(unitGroup).width) != null ? _k : unitGroup == null ? void 0 : unitGroup.scrollWidth) != null ? _l : 0)
|
||||
Math.ceil((_h = (_g = (_f = text == null ? void 0 : text.getBoundingClientRect) == null ? void 0 : _f.call(text).width) != null ? _g : text == null ? void 0 : text.scrollWidth) != null ? _h : 0),
|
||||
Math.ceil((_k = (_j = (_i = number == null ? void 0 : number.getBoundingClientRect) == null ? void 0 : _i.call(number).width) != null ? _j : number == null ? void 0 : number.scrollWidth) != null ? _k : 0),
|
||||
Math.ceil((_n = (_m = (_l = unitGroup == null ? void 0 : unitGroup.getBoundingClientRect) == null ? void 0 : _l.call(unitGroup).width) != null ? _m : unitGroup == null ? void 0 : unitGroup.scrollWidth) != null ? _n : 0)
|
||||
);
|
||||
}
|
||||
_applyHeroValueFit() {
|
||||
@@ -3715,9 +3731,10 @@
|
||||
${this._formatAboveValueMarkup(stateDisplay, unit, false)}
|
||||
</div>
|
||||
</div>` : "";
|
||||
const heroSize = (_q = layout.label.hero_size) != null ? _q : "small";
|
||||
const heroSize = (_q = layout.hero.size) != null ? _q : "small";
|
||||
const heroFontSize = layout.hero.value_size;
|
||||
const heroHeader = lp === "hero" ? `
|
||||
<div class="hero-line" data-hero-size="${heroSize}">
|
||||
<div class="hero-line" data-hero-size="${heroSize}"${Number.isFinite(heroFontSize) ? ` style="--sbcp-hero-base-size:${heroFontSize}px"` : ""}>
|
||||
<div class="hero-header">
|
||||
<span class="hero-label label-left-text">${escapedName}</span>
|
||||
<span class="hero-value" data-display="${this._encodeDataAttr(stateDisplay)}" data-unit="${this._encodeDataAttr(unit)}">${this._formatRightValueMarkup(stateDisplay, unit, false)}</span>
|
||||
@@ -3839,6 +3856,12 @@ ${paintLayers}
|
||||
}
|
||||
const heroHeader = row.querySelector(".hero-header");
|
||||
if (heroHeader) {
|
||||
const heroLine = row.querySelector(".hero-line");
|
||||
this._setStyleIfChanged(
|
||||
heroLine,
|
||||
"--sbcp-hero-base-size",
|
||||
Number.isFinite(ecfg.layout.hero.value_size) ? `${ecfg.layout.hero.value_size}px` : null
|
||||
);
|
||||
heroHeader.innerHTML = `<span class="hero-label label-left-text">${escapeHtml(rowViewModel.name)}</span><span class="hero-value" data-display="${this._encodeDataAttr(display)}" data-unit="${this._encodeDataAttr(displayUnit)}">${this._formatRightValueMarkup(display, displayUnit, false)}</span>`;
|
||||
}
|
||||
const aboveLabel = heroHeader ? null : row.querySelector(".above-bar-label");
|
||||
@@ -4557,8 +4580,10 @@ ${paintLayers}
|
||||
const nextTarget = this._cloneDeep(target);
|
||||
const nextLayout = this._cloneDeep(nextTarget.layout);
|
||||
const nextLabel = this._isObject(nextLayout.label) ? this._cloneDeep(nextLayout.label) : null;
|
||||
const nextHero = this._isObject(nextLayout.hero) ? this._cloneDeep(nextLayout.hero) : null;
|
||||
const height = this._normalizeNumberValue(nextLayout.height);
|
||||
const width = this._normalizeNumberValue(nextLabel == null ? void 0 : nextLabel.width);
|
||||
const valueSize = this._normalizeHeroValueSizeValue(nextHero == null ? void 0 : nextHero.value_size);
|
||||
const position = this._normalizeTextValue(nextLabel == null ? void 0 : nextLabel.position).trim();
|
||||
if (height !== null && height >= 24) {
|
||||
nextLayout.height = height;
|
||||
@@ -4585,6 +4610,18 @@ ${paintLayers}
|
||||
delete nextLayout.label;
|
||||
}
|
||||
}
|
||||
if (nextHero) {
|
||||
if (valueSize !== null) {
|
||||
nextHero.value_size = valueSize;
|
||||
} else {
|
||||
delete nextHero.value_size;
|
||||
}
|
||||
if (Object.keys(nextHero).length) {
|
||||
nextLayout.hero = nextHero;
|
||||
} else {
|
||||
delete nextLayout.hero;
|
||||
}
|
||||
}
|
||||
if (Object.keys(nextLayout).length) {
|
||||
nextTarget.layout = nextLayout;
|
||||
} else {
|
||||
@@ -4772,9 +4809,11 @@ ${paintLayers}
|
||||
case "peak":
|
||||
return ["enabled", "color"];
|
||||
case "layout":
|
||||
return ["height", "label"];
|
||||
return ["height", "label", "hero"];
|
||||
case "layout.label":
|
||||
return ["position", "hero_size", "width"];
|
||||
case "layout.hero":
|
||||
return ["size", "value_size"];
|
||||
case "formatting":
|
||||
return ["unit", "decimal"];
|
||||
case "bar":
|
||||
@@ -5235,7 +5274,7 @@ ${paintLayers}
|
||||
return this._getScopedValue(scope, ["unit"]) !== void 0 || this._getScopedValue(scope, ["decimal"]) !== void 0;
|
||||
}
|
||||
_getScopedLayoutValue(scope, key) {
|
||||
var _a, _b, _c, _d, _e, _f, _g;
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
||||
if (key === "height") {
|
||||
return (_b = (_a = this._getScopedValue(scope, ["layout", "height"])) != null ? _a : this._getScopedValue(scope, ["height"])) != null ? _b : "";
|
||||
}
|
||||
@@ -5246,7 +5285,10 @@ ${paintLayers}
|
||||
return (_f = (_e = this._getScopedValue(scope, ["layout", "label", "width"])) != null ? _e : this._getScopedValue(scope, ["label_width"])) != null ? _f : "";
|
||||
}
|
||||
if (key === "hero_size") {
|
||||
return (_g = this._getScopedValue(scope, ["layout", "label", "hero_size"])) != null ? _g : "";
|
||||
return (_h = (_g = this._getScopedValue(scope, ["layout", "hero", "size"])) != null ? _g : this._getScopedValue(scope, ["layout", "label", "hero_size"])) != null ? _h : "";
|
||||
}
|
||||
if (key === "value_size") {
|
||||
return (_i = this._getScopedValue(scope, ["layout", "hero", "value_size"])) != null ? _i : "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -5261,7 +5303,10 @@ ${paintLayers}
|
||||
return this._getEffectiveScopedDisplayValue(scope, ["layout", "label", "width"], [["label_width"]]);
|
||||
}
|
||||
if (key === "hero_size") {
|
||||
return this._getEffectiveScopedDisplayValue(scope, ["layout", "label", "hero_size"]);
|
||||
return this._getEffectiveScopedDisplayValue(scope, ["layout", "hero", "size"], [["layout", "label", "hero_size"]]);
|
||||
}
|
||||
if (key === "value_size") {
|
||||
return this._getEffectiveScopedDisplayValue(scope, ["layout", "hero", "value_size"]);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -5283,24 +5328,50 @@ ${paintLayers}
|
||||
prunePaths: [["layout", "label"], ["layout"]],
|
||||
rerender: true
|
||||
});
|
||||
this._removeCanonicalScopedValue(scope, ["layout", "hero"], {
|
||||
prunePaths: [["layout"]],
|
||||
rerender: true
|
||||
});
|
||||
return true;
|
||||
}
|
||||
_setLayoutLabelPosition(value) {
|
||||
return this._setScopedLayoutLabelPosition({ type: "card" }, value);
|
||||
}
|
||||
_setScopedLayoutHeroSize(scope, value) {
|
||||
if (!value || value === "medium") {
|
||||
return this._removeCanonicalScopedValue(scope, ["layout", "label", "hero_size"], {
|
||||
prunePaths: [["layout", "label"], ["layout"]]
|
||||
if (!value) {
|
||||
return this._removeCanonicalScopedValue(scope, ["layout", "hero", "size"], {
|
||||
deprecatedKeys: [["layout", "label", "hero_size"]],
|
||||
prunePaths: [["layout", "hero"], ["layout"]]
|
||||
});
|
||||
}
|
||||
return this._setCanonicalScopedValue(scope, ["layout", "label", "hero_size"], value, {
|
||||
prunePaths: [["layout", "label"], ["layout"]]
|
||||
return this._setCanonicalScopedValue(scope, ["layout", "hero", "size"], value, {
|
||||
deprecatedKeys: [["layout", "label", "hero_size"]],
|
||||
prunePaths: [["layout", "hero"], ["layout"]]
|
||||
});
|
||||
}
|
||||
_setLayoutHeroSize(value) {
|
||||
return this._setScopedLayoutHeroSize({ type: "card" }, value);
|
||||
}
|
||||
_normalizeHeroValueSizeValue(value) {
|
||||
const numericValue = this._normalizeNumberValue(value);
|
||||
if (numericValue === null) return null;
|
||||
return Math.min(112, Math.max(12, numericValue));
|
||||
}
|
||||
_setScopedLayoutHeroValueSize(scope, value) {
|
||||
if (value === "" || value === null || value === void 0) {
|
||||
return this._removeCanonicalScopedValue(scope, ["layout", "hero", "value_size"], {
|
||||
prunePaths: [["layout", "hero"], ["layout"]]
|
||||
});
|
||||
}
|
||||
const valueSize = this._normalizeHeroValueSizeValue(value);
|
||||
if (valueSize === null) return false;
|
||||
return this._setCanonicalScopedValue(scope, ["layout", "hero", "value_size"], valueSize, {
|
||||
prunePaths: [["layout", "hero"], ["layout"]]
|
||||
});
|
||||
}
|
||||
_setLayoutHeroValueSize(value) {
|
||||
return this._setScopedLayoutHeroValueSize({ type: "card" }, value);
|
||||
}
|
||||
_setScopedLayoutHeight(scope, value) {
|
||||
const numericValue = this._normalizeNumberValue(value);
|
||||
if (value === "" || value === null || value === void 0) {
|
||||
@@ -5342,6 +5413,7 @@ ${paintLayers}
|
||||
nextTarget = this._deletePathValue(nextTarget, ["layout", "label", "position"]);
|
||||
nextTarget = this._deletePathValue(nextTarget, ["layout", "label", "hero_size"]);
|
||||
nextTarget = this._deletePathValue(nextTarget, ["layout", "label", "width"]);
|
||||
nextTarget = this._deletePathValue(nextTarget, ["layout", "hero"]);
|
||||
nextTarget = this._deletePathValue(nextTarget, ["height"]);
|
||||
nextTarget = this._deletePathValue(nextTarget, ["label_position"]);
|
||||
nextTarget = this._deletePathValue(nextTarget, ["label_width"]);
|
||||
@@ -5357,6 +5429,9 @@ ${paintLayers}
|
||||
if (this._isObject(layoutValue) && (Object.prototype.hasOwnProperty.call(layoutValue, "height") || this._isObject(labelValue) && (Object.prototype.hasOwnProperty.call(labelValue, "position") || Object.prototype.hasOwnProperty.call(labelValue, "hero_size") || Object.prototype.hasOwnProperty.call(labelValue, "width")))) {
|
||||
return true;
|
||||
}
|
||||
if (this._isObject(layoutValue) && this._isObject(layoutValue.hero) && Object.keys(layoutValue.hero).length) {
|
||||
return true;
|
||||
}
|
||||
return this._getScopedValue(scope, ["height"]) !== void 0 || this._getScopedValue(scope, ["label_position"]) !== void 0 || this._getScopedValue(scope, ["label_width"]) !== void 0;
|
||||
}
|
||||
_setScaleBound(key, value) {
|
||||
@@ -7468,6 +7543,7 @@ ${paintLayers}
|
||||
const fillStyle = this._getFillStyleValue();
|
||||
const layoutLabelPosition = this._getScopedLayoutValue({ type: "card" }, "position") || "left";
|
||||
const layoutHeroSize = this._getScopedLayoutValue({ type: "card" }, "hero_size") || "medium";
|
||||
const layoutHeroValueSize = this._getScopedLayoutValue({ type: "card" }, "value_size");
|
||||
const layoutHeight = this._getScopedLayoutValue({ type: "card" }, "height");
|
||||
const layoutLabelWidth = this._getScopedLayoutValue({ type: "card" }, "width");
|
||||
const barColor = this._getScopedBarColorValue({ type: "card" });
|
||||
@@ -8123,6 +8199,11 @@ ${paintLayers}
|
||||
<option value="large"${(this._getEffectiveScopedLayoutValue(scope, "hero_size") || "medium") === "large" ? " selected" : ""}>large</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field-row">
|
||||
<label for="entity-${index}-hero-value-size">Maximum font size</label>
|
||||
<input id="entity-${index}-hero-value-size" type="number" min="12" max="112" step="1" data-kind="entity-layout-hero-value-size" data-index="${index}" value="${this._escapeAttribute(this._getEffectiveScopedLayoutValue(scope, "value_size"))}" placeholder="use Hero size preset">
|
||||
<div class="section-note">The hero value may render smaller when needed to fit. A custom value overrides the Hero size preset.</div>
|
||||
</div>
|
||||
` : ""}
|
||||
<div class="field-row">
|
||||
<label for="entity-${index}-label-width">Label width</label>
|
||||
@@ -8834,6 +8915,11 @@ ${paintLayers}
|
||||
<option value="large"${layoutHeroSize === "large" ? " selected" : ""}>large</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field-row">
|
||||
<label for="layout-hero-value-size">Maximum font size</label>
|
||||
<input id="layout-hero-value-size" type="number" min="12" max="112" step="1" data-field="layout-hero-value-size" value="${this._escapeAttribute(layoutHeroValueSize)}" placeholder="use Hero size preset">
|
||||
<div class="section-note">The hero value may render smaller when needed to fit. A custom value overrides the Hero size preset.</div>
|
||||
</div>
|
||||
` : ""}
|
||||
<div class="field-row">
|
||||
<label for="layout-label-width">Label width</label>
|
||||
@@ -9226,6 +9312,7 @@ ${paintLayers}
|
||||
if (field === "formatting-decimal") return void this._setScopedFormattingDecimal({ type: "card" }, value);
|
||||
if (field === "layout-label-position") return void this._setLayoutLabelPosition(value);
|
||||
if (field === "layout-label-hero-size") return void this._setLayoutHeroSize(value);
|
||||
if (field === "layout-hero-value-size") return void this._setLayoutHeroValueSize(value);
|
||||
if (field === "layout-height") return void this._setLayoutHeight(value);
|
||||
if (field === "layout-label-width") return void this._setScopedLayoutLabelWidth({ type: "card" }, value);
|
||||
if (field === "scale-min") return void this._setScaleBound("min", value);
|
||||
@@ -9315,6 +9402,9 @@ ${paintLayers}
|
||||
if (kind === "entity-layout-label-hero-size") {
|
||||
return void this._setScopedLayoutHeroSize({ type: "entity", index: Number(target.dataset.index) }, value);
|
||||
}
|
||||
if (kind === "entity-layout-hero-value-size") {
|
||||
return void this._setScopedLayoutHeroValueSize({ type: "entity", index: Number(target.dataset.index) }, value);
|
||||
}
|
||||
if (kind === "entity-layout-label-width") {
|
||||
return void this._setScopedLayoutLabelWidth({ type: "entity", index: Number(target.dataset.index) }, value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user