@threepipe/plugin-tweakpane
Version:
Tweakpane UI Plugin for ThreePipe
1,467 lines (1,466 loc) • 297 kB
JavaScript
(function(global2, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("threepipe")) : typeof define === "function" && define.amd ? define(["exports", "threepipe"], factory) : (global2 = typeof globalThis !== "undefined" ? globalThis : global2 || self, factory(global2["@threepipe/plugin-tweakpane"] = {}, global2.threepipe));
})(this, function(exports2, threepipe) {
"use strict";/**
* @license
* @threepipe/plugin-tweakpane v0.6.0
* Copyright 2022-2025 repalash <palash@shaders.app>
* Apache-2.0 License
* See ./dependencies.txt for any bundled third-party dependencies and licenses.
*/
function forceCast(v) {
return v;
}
const PREFIX = "tp";
function ClassName(viewName) {
const fn = (opt_elementName, opt_modifier) => {
return [
PREFIX,
"-",
viewName,
"v",
opt_elementName ? `_${opt_elementName}` : "",
opt_modifier ? `-${opt_modifier}` : ""
].join("");
};
return fn;
}
function parseObject(value, keyToParserMap) {
const keys = Object.keys(keyToParserMap);
const result = keys.reduce((tmp, key) => {
if (tmp === void 0) {
return void 0;
}
const parser = keyToParserMap[key];
const result2 = parser(value[key]);
return result2.succeeded ? Object.assign(Object.assign({}, tmp), { [key]: result2.value }) : void 0;
}, {});
return forceCast(result);
}
function parseArray(value, parseItem) {
return value.reduce((tmp, item) => {
if (tmp === void 0) {
return void 0;
}
const result = parseItem(item);
if (!result.succeeded || result.value === void 0) {
return void 0;
}
return [...tmp, result.value];
}, []);
}
function isObject(value) {
if (value === null) {
return false;
}
return typeof value === "object";
}
function createParamsParserBuilder(parse) {
return (optional) => (v) => {
if (!optional && v === void 0) {
return {
succeeded: false,
value: void 0
};
}
if (optional && v === void 0) {
return {
succeeded: true,
value: void 0
};
}
const result = parse(v);
return result !== void 0 ? {
succeeded: true,
value: result
} : {
succeeded: false,
value: void 0
};
};
}
function createParamsParserBuilders(optional) {
return {
custom: (parse) => createParamsParserBuilder(parse)(optional),
boolean: createParamsParserBuilder((v) => typeof v === "boolean" ? v : void 0)(optional),
number: createParamsParserBuilder((v) => typeof v === "number" ? v : void 0)(optional),
string: createParamsParserBuilder((v) => typeof v === "string" ? v : void 0)(optional),
function: createParamsParserBuilder((v) => typeof v === "function" ? v : void 0)(optional),
constant: (value) => createParamsParserBuilder((v) => v === value ? value : void 0)(optional),
raw: createParamsParserBuilder((v) => v)(optional),
object: (keyToParserMap) => createParamsParserBuilder((v) => {
if (!isObject(v)) {
return void 0;
}
return parseObject(v, keyToParserMap);
})(optional),
array: (itemParser) => createParamsParserBuilder((v) => {
if (!Array.isArray(v)) {
return void 0;
}
return parseArray(v, itemParser);
})(optional)
};
}
const ParamsParsers = {
optional: createParamsParserBuilders(true),
required: createParamsParserBuilders(false)
};
function parseParams(value, keyToParserMap) {
const result = ParamsParsers.required.object(keyToParserMap)(value);
return result.succeeded ? result.value : void 0;
}
function createNumberFormatter(digits) {
return (value) => {
return value.toFixed(Math.max(Math.min(digits, 20), 0));
};
}
const innerFormatter = createNumberFormatter(0);
function formatPercentage(value) {
return innerFormatter(value) + "%";
}
function constrainRange(value, min, max) {
return Math.min(Math.max(value, min), max);
}
function removeAlphaComponent(comps) {
return [comps[0], comps[1], comps[2]];
}
function zerofill(comp) {
const hex = constrainRange(Math.floor(comp), 0, 255).toString(16);
return hex.length === 1 ? `0${hex}` : hex;
}
function colorToHexRgbString(value, prefix = "#") {
const hexes = removeAlphaComponent(value.getComponents("rgb")).map(zerofill).join("");
return `${prefix}${hexes}`;
}
function colorToHexRgbaString(value, prefix = "#") {
const rgbaComps = value.getComponents("rgb");
const hexes = [rgbaComps[0], rgbaComps[1], rgbaComps[2], rgbaComps[3] * 255].map(zerofill).join("");
return `${prefix}${hexes}`;
}
function colorToFunctionalRgbString(value, opt_type) {
const formatter = createNumberFormatter(opt_type === "float" ? 2 : 0);
const comps = removeAlphaComponent(value.getComponents("rgb", opt_type)).map((comp) => formatter(comp));
return `rgb(${comps.join(", ")})`;
}
function createFunctionalRgbColorFormatter(type) {
return (value) => {
return colorToFunctionalRgbString(value, type);
};
}
function colorToFunctionalRgbaString(value, opt_type) {
const aFormatter = createNumberFormatter(2);
const rgbFormatter = createNumberFormatter(opt_type === "float" ? 2 : 0);
const comps = value.getComponents("rgb", opt_type).map((comp, index) => {
const formatter = index === 3 ? aFormatter : rgbFormatter;
return formatter(comp);
});
return `rgba(${comps.join(", ")})`;
}
function createFunctionalRgbaColorFormatter(type) {
return (value) => {
return colorToFunctionalRgbaString(value, type);
};
}
function colorToFunctionalHslString(value) {
const formatters = [
createNumberFormatter(0),
formatPercentage,
formatPercentage
];
const comps = removeAlphaComponent(value.getComponents("hsl")).map((comp, index) => formatters[index](comp));
return `hsl(${comps.join(", ")})`;
}
function colorToFunctionalHslaString(value) {
const formatters = [
createNumberFormatter(0),
formatPercentage,
formatPercentage,
createNumberFormatter(2)
];
const comps = value.getComponents("hsl").map((comp, index) => formatters[index](comp));
return `hsla(${comps.join(", ")})`;
}
function colorToObjectRgbString(value, type) {
const formatter = createNumberFormatter(type === "float" ? 2 : 0);
const names = ["r", "g", "b"];
const comps = removeAlphaComponent(value.getComponents("rgb", type)).map((comp, index) => `${names[index]}: ${formatter(comp)}`);
return `{${comps.join(", ")}}`;
}
function createObjectRgbColorFormatter(type) {
return (value) => colorToObjectRgbString(value, type);
}
function colorToObjectRgbaString(value, type) {
const aFormatter = createNumberFormatter(2);
const rgbFormatter = createNumberFormatter(type === "float" ? 2 : 0);
const names = ["r", "g", "b", "a"];
const comps = value.getComponents("rgb", type).map((comp, index) => {
const formatter = index === 3 ? aFormatter : rgbFormatter;
return `${names[index]}: ${formatter(comp)}`;
});
return `{${comps.join(", ")}}`;
}
function createObjectRgbaColorFormatter(type) {
return (value) => colorToObjectRgbaString(value, type);
}
[
{
format: {
alpha: false,
mode: "rgb",
notation: "hex",
type: "int"
},
stringifier: colorToHexRgbString
},
{
format: {
alpha: true,
mode: "rgb",
notation: "hex",
type: "int"
},
stringifier: colorToHexRgbaString
},
{
format: {
alpha: false,
mode: "hsl",
notation: "func",
type: "int"
},
stringifier: colorToFunctionalHslString
},
{
format: {
alpha: true,
mode: "hsl",
notation: "func",
type: "int"
},
stringifier: colorToFunctionalHslaString
},
...["int", "float"].reduce((prev, type) => {
return [
...prev,
{
format: {
alpha: false,
mode: "rgb",
notation: "func",
type
},
stringifier: createFunctionalRgbColorFormatter(type)
},
{
format: {
alpha: true,
mode: "rgb",
notation: "func",
type
},
stringifier: createFunctionalRgbaColorFormatter(type)
},
{
format: {
alpha: false,
mode: "rgb",
notation: "object",
type
},
stringifier: createObjectRgbColorFormatter(type)
},
{
format: {
alpha: true,
mode: "rgb",
notation: "object",
type
},
stringifier: createObjectRgbaColorFormatter(type)
}
];
}, [])
];
function createPlaceholderImage() {
const canvas = document.createElement("canvas");
canvas.width = 320;
canvas.height = 50;
const ctx = canvas.getContext("2d");
ctx.fillStyle = "#00000004";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#eee";
ctx.font = '1.25rem "Roboto Mono", "Source Code Pro", Menlo, Courier, monospace';
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("No image", canvas.width * 0.5, canvas.height * 0.5);
const image = new Image();
image.src = canvas.toDataURL("image/png", 0.8);
image.isPlaceholder = true;
return image;
}
function loadImage(src) {
const image = new Image();
image.crossOrigin = "anonymous";
image.src = src;
return image;
}
const className = ClassName("img");
class PluginView {
constructor(doc, config) {
this.element = doc.createElement("div");
this.element.classList.add(className());
config.viewProps.bindClassModifiers(this.element);
this.input = doc.createElement("input");
this.input.classList.add(className("input"));
this.input.setAttribute("type", "file");
this.input.setAttribute("accept", config.extensions.join(","));
this.image_ = doc.createElement("img");
this.image_.id = "tpimg_" + Math.random().toString(36).slice(2);
this.image_.classList.add(className("image"));
this.image_.classList.add(className(`image_${config.imageFit}`));
this.image_.crossOrigin = "anonymous";
this.image_.onclick = (event) => {
config.clickCallback ? config.clickCallback(event, this.input) : this.input.click();
};
this.element.classList.add(className("area_root"));
this.element.appendChild(this.image_);
this.element.appendChild(this.input);
}
changeImage(src) {
this.image_.src = src;
}
changeDraggingState(state) {
const el = this.element;
if (state) {
el === null || el === void 0 ? void 0 : el.classList.add(className("area_dragging"));
} else {
el === null || el === void 0 ? void 0 : el.classList.remove(className("area_dragging"));
}
}
}
let placeholderImage = null;
class PluginController {
constructor(doc, config) {
this.value = config.value;
this.viewProps = config.viewProps;
this.view = new PluginView(doc, {
viewProps: this.viewProps,
extensions: config.extensions,
imageFit: config.imageFit,
clickCallback: config.clickCallback
});
this.onFile = this.onFile.bind(this);
this.onDrop = this.onDrop.bind(this);
this.onDragStart = this.onDragStart.bind(this);
this.onDragOver = this.onDragOver.bind(this);
this.onDragLeave = this.onDragLeave.bind(this);
this.view.input.addEventListener("change", this.onFile);
this.view.element.addEventListener("drop", this.onDrop);
this.view.element.addEventListener("dragstart", this.onDragStart);
this.view.element.addEventListener("dragover", this.onDragOver);
this.view.element.addEventListener("dragleave", this.onDragLeave);
this.viewProps.handleDispose(() => {
this.view.input.removeEventListener("change", this.onFile);
this.view.element.removeEventListener("drop", this.onDrop);
this.view.element.removeEventListener("dragstart", this.onDragStart);
this.view.element.removeEventListener("dragover", this.onDragOver);
this.view.element.removeEventListener("dragleave", this.onDragLeave);
});
this.value.emitter.on("change", () => this.handleValueChange());
this.handleValueChange();
}
onFile(event) {
const files = (event === null || event === void 0 ? void 0 : event.target).files;
if (!files || !files.length)
return;
const file = files[0];
this.setValue(file);
}
onDrop(event) {
event.preventDefault();
try {
const { dataTransfer } = event;
const file = dataTransfer === null || dataTransfer === void 0 ? void 0 : dataTransfer.files[0];
if (file) {
this.setValue(file);
} else {
const imgId = dataTransfer === null || dataTransfer === void 0 ? void 0 : dataTransfer.getData("img-id");
if (imgId) {
const img = document.getElementById(imgId);
this.setValue(img);
} else {
const url = dataTransfer === null || dataTransfer === void 0 ? void 0 : dataTransfer.getData("url");
if (!url)
throw new Error("No url");
this.setValue(url);
}
}
} catch (e) {
console.error("Could not parse the dropped image", e);
} finally {
this.view.changeDraggingState(false);
}
}
onDragStart(event) {
var _a2, _b;
(_a2 = event.dataTransfer) === null || _a2 === void 0 ? void 0 : _a2.setData("img-id", this.view.image_.id);
(_b = event.dataTransfer) === null || _b === void 0 ? void 0 : _b.setDragImage(this.view.image_, 0, 0);
}
onDragOver(event) {
event.preventDefault();
this.view.changeDraggingState(true);
}
onDragLeave() {
this.view.changeDraggingState(false);
}
handleImage(image) {
if (image instanceof HTMLImageElement) {
this.updateImage(image.src);
} else if (typeof image === "string" || !image) {
if (image === "placeholder" || !image) {
image = this.handlePlaceholderImage().src;
}
this.updateImage(image);
} else {
this.setValue(image);
}
}
updateImage(src) {
this.view.changeImage(src);
}
setValue(src) {
if (src instanceof HTMLImageElement) {
this.value.setRawValue(src);
} else if (src instanceof File) {
const url = URL.createObjectURL(src) + "#" + src.name;
src.src = url;
const img = loadImage(url);
this.value.setRawValue(img || src);
} else if (src) {
this.value.setRawValue(loadImage(src));
} else {
this.value.setRawValue(this.handlePlaceholderImage());
}
}
handleValueChange() {
this.handleImage(this.value.rawValue);
}
handlePlaceholderImage() {
if (!placeholderImage) {
placeholderImage = createPlaceholderImage();
}
return placeholderImage;
}
}
const DEFAULT_EXTENSIONS = [".jpg", ".png", ".gif"];
const TweakpaneImagePlugin = {
id: "input-image",
type: "input",
css: ".tp-imgv{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:rgba(0,0,0,0);border-width:0;font-family:inherit;font-size:inherit;font-weight:inherit;margin:0;outline:none;padding:0}.tp-imgv{background-color:var(--in-bg);border-radius:var(--elm-br);box-sizing:border-box;color:var(--in-fg);font-family:inherit;height:var(--bld-us);line-height:var(--bld-us);min-width:0;width:100%}.tp-imgv:hover{background-color:var(--in-bg-h)}.tp-imgv:focus{background-color:var(--in-bg-f)}.tp-imgv:active{background-color:var(--in-bg-a)}.tp-imgv:disabled{opacity:.5}:root{--tp-plugin-image-dragging-color: hsla(230, 100%, 66%, 1.00)}.tp-imgv{cursor:pointer;display:inline-flex;height:auto !important;max-height:calc(var(--bld-us)*3);border-radius:4px;position:relative}.tp-imgv.tp-v-disabled{opacity:.5}.tp-imgv_input{width:0;height:0;pointer-events:none;visibility:hidden}.tp-imgv_image{width:100%;height:-moz-max-content;height:max-content;max-height:calc(var(--bld-us)*3);border:0}.tp-imgv_image_contain{-o-object-fit:contain;object-fit:contain}.tp-imgv_image_cover{-o-object-fit:cover;object-fit:cover}.tp-imgv_area_root{transition:opacity .16s ease-in-out}.tp-imgv_area_dragging{border:2px dashed var(--tp-plugin-image-dragging-color);border-radius:4px;opacity:.6}",
accept(exValue, params) {
if (!(exValue instanceof HTMLImageElement || typeof exValue === "string")) {
return null;
}
const p = ParamsParsers;
const result = parseParams(params, {
view: p.required.constant("input-image"),
acceptUrl: p.optional.boolean,
clickCallback: p.optional.function,
imageFit: p.optional.custom((v) => v === "contain" || v === "cover" ? v : void 0),
extensions: p.optional.array(p.required.string)
});
if (!result) {
return null;
}
return {
initialValue: exValue,
params: result
};
},
binding: {
reader(_args) {
return (exValue) => {
if (exValue.src !== void 0) {
return exValue.src === "" ? "placeholder" : exValue.src;
} else {
return typeof exValue === "string" ? exValue : exValue;
}
};
},
writer(_args) {
return (target, inValue) => {
target.write(inValue);
};
}
},
controller(args) {
var _a2, _b;
return new PluginController(args.document, {
value: args.value,
imageFit: (_a2 = args.params.imageFit) !== null && _a2 !== void 0 ? _a2 : "cover",
clickCallback: args.params.clickCallback,
viewProps: args.viewProps,
extensions: (_b = args.params.extensions) !== null && _b !== void 0 ? _b : DEFAULT_EXTENSIONS
});
}
};
const plugin = TweakpaneImagePlugin;
const TweakpaneImagePlugin$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
plugin
}, Symbol.toStringTag, { value: "Module" }));
/**
* @license
* uiconfig-tweakpane v0.0.10
* Copyright 2022-2024 repalash <palash@shaders.app>
* MIT License
* See ./dependencies.txt for bundled third-party dependencies and licenses.
*/
/**
* @license
* ts-browser-helpers v0.16.0
* Copyright 2022-2024 repalash <palash@shaders.app>
* MIT License
* See ./dependencies.txt for bundled third-party dependencies and licenses.
*/
function ua({ innerHTML: u = "", id: s, classList: o, addToBody: p = true, elementTag: l = "div" }) {
const c = document.createElement(l);
return c.id = s, c.innerHTML = u, o && c.classList.add(...o), p && document.body.appendChild(c), c;
}
function ca(u, s = document.head) {
const o = document.createElement("style");
return o.type = "text/css", o.innerText = u, s == null || s.appendChild(o), o;
}
const ha = (u, ...s) => String.raw({ raw: u }, ...s);
function va(u, s) {
let o;
do
o = Object.getOwnPropertyDescriptor(u, s);
while (!o && (u = Object.getPrototypeOf(u)));
return o;
}
function ma(u, s, o = true, p = false) {
const l = va(u, s);
return !!(l != null && l.set) || o && (l == null ? void 0 : l.writable) !== false && (l == null ? void 0 : l.get) === void 0 || p && !l;
}
function ba(u, s, o, p = true, l = false) {
return u && ma(u, s, p, l) ? (u[s] = o, true) : false;
}
function $(u, ...s) {
return typeof u == "function" && (u = u(...s)), u;
}
function fa(u, s) {
return Object.hasOwn ? Object.hasOwn(u, s) : u.hasOwnProperty(s);
}
var _a = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, Xe = { exports: {} };
/*! Tweakpane 3.1.10 (c) 2016 cocopon, licensed under the MIT license. */
(function(u, s) {
(function(o, p) {
p(s);
})(_a, function(o) {
class p {
/**
* @hidden
*/
constructor(t) {
const [e, i] = t.split("-"), r = e.split(".");
this.major = parseInt(r[0], 10), this.minor = parseInt(r[1], 10), this.patch = parseInt(r[2], 10), this.prerelease = i ?? null;
}
toString() {
const t = [this.major, this.minor, this.patch].join(".");
return this.prerelease !== null ? [t, this.prerelease].join("-") : t;
}
}
class l {
constructor(t) {
this.controller_ = t;
}
get element() {
return this.controller_.view.element;
}
get disabled() {
return this.controller_.viewProps.get("disabled");
}
set disabled(t) {
this.controller_.viewProps.set("disabled", t);
}
get hidden() {
return this.controller_.viewProps.get("hidden");
}
set hidden(t) {
this.controller_.viewProps.set("hidden", t);
}
dispose() {
this.controller_.viewProps.set("disposed", true);
}
}
class c {
constructor(t) {
this.target = t;
}
}
class v extends c {
constructor(t, e, i, r) {
super(t), this.value = e, this.presetKey = i, this.last = r ?? true;
}
}
class w extends c {
constructor(t, e, i) {
super(t), this.value = e, this.presetKey = i;
}
}
class b extends c {
constructor(t, e) {
super(t), this.expanded = e;
}
}
class S extends c {
constructor(t, e) {
super(t), this.index = e;
}
}
function g(n) {
return n == null;
}
function P(n, t) {
if (n.length !== t.length)
return false;
for (let e = 0; e < n.length; e++)
if (n[e] !== t[e])
return false;
return true;
}
function y(n, t) {
let e = n;
do {
const i = Object.getOwnPropertyDescriptor(e, t);
if (i && (i.set !== void 0 || i.writable === true))
return true;
e = Object.getPrototypeOf(e);
} while (e !== null);
return false;
}
const A = {
alreadydisposed: () => "View has been already disposed",
invalidparams: (n) => `Invalid parameters for '${n.name}'`,
nomatchingcontroller: (n) => `No matching controller for '${n.key}'`,
nomatchingview: (n) => `No matching view for '${JSON.stringify(n.params)}'`,
notbindable: () => "Value is not bindable",
propertynotfound: (n) => `Property '${n.name}' not found`,
shouldneverhappen: () => "This error should never happen"
};
class _ {
static alreadyDisposed() {
return new _({ type: "alreadydisposed" });
}
static notBindable() {
return new _({
type: "notbindable"
});
}
static propertyNotFound(t) {
return new _({
type: "propertynotfound",
context: {
name: t
}
});
}
static shouldNeverHappen() {
return new _({ type: "shouldneverhappen" });
}
constructor(t) {
var e;
this.message = (e = A[t.type](t.context)) !== null && e !== void 0 ? e : "Unexpected error", this.name = this.constructor.name, this.stack = new Error(this.message).stack, this.type = t.type;
}
}
class L {
constructor(t, e, i) {
this.obj_ = t, this.key_ = e, this.presetKey_ = i ?? e;
}
static isBindable(t) {
return !(t === null || typeof t != "object" && typeof t != "function");
}
get key() {
return this.key_;
}
get presetKey() {
return this.presetKey_;
}
read() {
return this.obj_[this.key_];
}
write(t) {
this.obj_[this.key_] = t;
}
writeProperty(t, e) {
const i = this.read();
if (!L.isBindable(i))
throw _.notBindable();
if (!(t in i))
throw _.propertyNotFound(t);
i[t] = e;
}
}
class et extends l {
get label() {
return this.controller_.props.get("label");
}
set label(t) {
this.controller_.props.set("label", t);
}
get title() {
var t;
return (t = this.controller_.valueController.props.get("title")) !== null && t !== void 0 ? t : "";
}
set title(t) {
this.controller_.valueController.props.set("title", t);
}
on(t, e) {
const i = e.bind(this);
return this.controller_.valueController.emitter.on(t, () => {
i(new c(this));
}), this;
}
}
class M {
constructor() {
this.observers_ = {};
}
on(t, e) {
let i = this.observers_[t];
return i || (i = this.observers_[t] = []), i.push({
handler: e
}), this;
}
off(t, e) {
const i = this.observers_[t];
return i && (this.observers_[t] = i.filter((r) => r.handler !== e)), this;
}
emit(t, e) {
const i = this.observers_[t];
i && i.forEach((r) => {
r.handler(e);
});
}
}
const Qt = "tp";
function E(n) {
return (e, i) => [
Qt,
"-",
n,
"v",
e ? `_${e}` : "",
i ? `-${i}` : ""
].join("");
}
function ki(n, t) {
return (e) => t(n(e));
}
function Vi(n) {
return n.rawValue;
}
function Y(n, t) {
n.emitter.on("change", ki(Vi, t)), t(n.rawValue);
}
function H(n, t, e) {
Y(n.value(t), e);
}
function Si(n, t, e) {
e ? n.classList.add(t) : n.classList.remove(t);
}
function ft(n, t) {
return (e) => {
Si(n, t, e);
};
}
function ce(n, t) {
Y(n, (e) => {
t.textContent = e ?? "";
});
}
const he = E("btn");
class Li {
constructor(t, e) {
this.element = t.createElement("div"), this.element.classList.add(he()), e.viewProps.bindClassModifiers(this.element);
const i = t.createElement("button");
i.classList.add(he("b")), e.viewProps.bindDisabled(i), this.element.appendChild(i), this.buttonElement = i;
const r = t.createElement("div");
r.classList.add(he("t")), ce(e.props.value("title"), r), this.buttonElement.appendChild(r);
}
}
class Ze {
constructor(t, e) {
this.emitter = new M(), this.onClick_ = this.onClick_.bind(this), this.props = e.props, this.viewProps = e.viewProps, this.view = new Li(t, {
props: this.props,
viewProps: this.viewProps
}), this.view.buttonElement.addEventListener("click", this.onClick_);
}
onClick_() {
this.emitter.emit("click", {
sender: this
});
}
}
class Ai {
constructor(t, e) {
var i;
this.constraint_ = e == null ? void 0 : e.constraint, this.equals_ = (i = e == null ? void 0 : e.equals) !== null && i !== void 0 ? i : (r, a) => r === a, this.emitter = new M(), this.rawValue_ = t;
}
get constraint() {
return this.constraint_;
}
get rawValue() {
return this.rawValue_;
}
set rawValue(t) {
this.setRawValue(t, {
forceEmit: false,
last: true
});
}
setRawValue(t, e) {
const i = e ?? {
forceEmit: false,
last: true
}, r = this.constraint_ ? this.constraint_.constrain(t) : t, a = this.rawValue_;
this.equals_(a, r) && !i.forceEmit || (this.emitter.emit("beforechange", {
sender: this
}), this.rawValue_ = r, this.emitter.emit("change", {
options: i,
previousRawValue: a,
rawValue: r,
sender: this
}));
}
}
class Mi {
constructor(t) {
this.emitter = new M(), this.value_ = t;
}
get rawValue() {
return this.value_;
}
set rawValue(t) {
this.setRawValue(t, {
forceEmit: false,
last: true
});
}
setRawValue(t, e) {
const i = e ?? {
forceEmit: false,
last: true
}, r = this.value_;
r === t && !i.forceEmit || (this.emitter.emit("beforechange", {
sender: this
}), this.value_ = t, this.emitter.emit("change", {
options: i,
previousRawValue: r,
rawValue: this.value_,
sender: this
}));
}
}
function N(n, t) {
const e = t == null ? void 0 : t.constraint, i = t == null ? void 0 : t.equals;
return !e && !i ? new Mi(n) : new Ai(n, t);
}
class C {
constructor(t) {
this.emitter = new M(), this.valMap_ = t;
for (const e in this.valMap_)
this.valMap_[e].emitter.on("change", () => {
this.emitter.emit("change", {
key: e,
sender: this
});
});
}
static createCore(t) {
return Object.keys(t).reduce((i, r) => Object.assign(i, {
[r]: N(t[r])
}), {});
}
static fromObject(t) {
const e = this.createCore(t);
return new C(e);
}
get(t) {
return this.valMap_[t].rawValue;
}
set(t, e) {
this.valMap_[t].rawValue = e;
}
value(t) {
return this.valMap_[t];
}
}
function Ri(n, t) {
const i = Object.keys(t).reduce((r, a) => {
if (r === void 0)
return;
const d = t[a], h = d(n[a]);
return h.succeeded ? Object.assign(Object.assign({}, r), { [a]: h.value }) : void 0;
}, {});
return i;
}
function Di(n, t) {
return n.reduce((e, i) => {
if (e === void 0)
return;
const r = t(i);
if (!(!r.succeeded || r.value === void 0))
return [...e, r.value];
}, []);
}
function Oi(n) {
return n === null ? false : typeof n == "object";
}
function Q(n) {
return (t) => (e) => {
if (!t && e === void 0)
return {
succeeded: false,
value: void 0
};
if (t && e === void 0)
return {
succeeded: true,
value: void 0
};
const i = n(e);
return i !== void 0 ? {
succeeded: true,
value: i
} : {
succeeded: false,
value: void 0
};
};
}
function Je(n) {
return {
custom: (t) => Q(t)(n),
boolean: Q((t) => typeof t == "boolean" ? t : void 0)(n),
number: Q((t) => typeof t == "number" ? t : void 0)(n),
string: Q((t) => typeof t == "string" ? t : void 0)(n),
function: Q((t) => typeof t == "function" ? t : void 0)(n),
constant: (t) => Q((e) => e === t ? t : void 0)(n),
raw: Q((t) => t)(n),
object: (t) => Q((e) => {
if (Oi(e))
return Ri(e, t);
})(n),
array: (t) => Q((e) => {
if (Array.isArray(e))
return Di(e, t);
})(n)
};
}
const R = {
optional: Je(true),
required: Je(false)
};
function I(n, t) {
const e = R.required.object(t)(n);
return e.succeeded ? e.value : void 0;
}
function ve(n) {
console.warn([
`Missing '${n.key}' of ${n.target} in ${n.place}.`,
"Please rebuild plugins with the latest core package."
].join(" "));
}
function Ti(n) {
return n && n.parentElement && n.parentElement.removeChild(n), null;
}
class me {
constructor(t) {
this.value_ = t;
}
static create(t) {
return [
new me(t),
(e, i) => {
t.setRawValue(e, i);
}
];
}
get emitter() {
return this.value_.emitter;
}
get rawValue() {
return this.value_.rawValue;
}
}
const Ni = E("");
function tn(n, t) {
return ft(n, Ni(void 0, t));
}
class W extends C {
constructor(t) {
var e;
super(t), this.onDisabledChange_ = this.onDisabledChange_.bind(this), this.onParentChange_ = this.onParentChange_.bind(this), this.onParentGlobalDisabledChange_ = this.onParentGlobalDisabledChange_.bind(this), [this.globalDisabled_, this.setGlobalDisabled_] = me.create(N(this.getGlobalDisabled_())), this.value("disabled").emitter.on("change", this.onDisabledChange_), this.value("parent").emitter.on("change", this.onParentChange_), (e = this.get("parent")) === null || e === void 0 || e.globalDisabled.emitter.on("change", this.onParentGlobalDisabledChange_);
}
static create(t) {
var e, i, r;
const a = t ?? {};
return new W(C.createCore({
disabled: (e = a.disabled) !== null && e !== void 0 ? e : false,
disposed: false,
hidden: (i = a.hidden) !== null && i !== void 0 ? i : false,
parent: (r = a.parent) !== null && r !== void 0 ? r : null
}));
}
get globalDisabled() {
return this.globalDisabled_;
}
bindClassModifiers(t) {
Y(this.globalDisabled_, tn(t, "disabled")), H(this, "hidden", tn(t, "hidden"));
}
bindDisabled(t) {
Y(this.globalDisabled_, (e) => {
t.disabled = e;
});
}
bindTabIndex(t) {
Y(this.globalDisabled_, (e) => {
t.tabIndex = e ? -1 : 0;
});
}
handleDispose(t) {
this.value("disposed").emitter.on("change", (e) => {
e && t();
});
}
getGlobalDisabled_() {
const t = this.get("parent");
return (t ? t.globalDisabled.rawValue : false) || this.get("disabled");
}
updateGlobalDisabled_() {
this.setGlobalDisabled_(this.getGlobalDisabled_());
}
onDisabledChange_() {
this.updateGlobalDisabled_();
}
onParentGlobalDisabledChange_() {
this.updateGlobalDisabled_();
}
onParentChange_(t) {
var e;
const i = t.previousRawValue;
i == null || i.globalDisabled.emitter.off("change", this.onParentGlobalDisabledChange_), (e = this.get("parent")) === null || e === void 0 || e.globalDisabled.emitter.on("change", this.onParentGlobalDisabledChange_), this.updateGlobalDisabled_();
}
}
function Ii() {
return ["veryfirst", "first", "last", "verylast"];
}
const en = E(""), nn = {
veryfirst: "vfst",
first: "fst",
last: "lst",
verylast: "vlst"
};
class Vt {
constructor(t) {
this.parent_ = null, this.blade = t.blade, this.view = t.view, this.viewProps = t.viewProps;
const e = this.view.element;
this.blade.value("positions").emitter.on("change", () => {
Ii().forEach((i) => {
e.classList.remove(en(void 0, nn[i]));
}), this.blade.get("positions").forEach((i) => {
e.classList.add(en(void 0, nn[i]));
});
}), this.viewProps.handleDispose(() => {
Ti(e);
});
}
get parent() {
return this.parent_;
}
set parent(t) {
if (this.parent_ = t, !("parent" in this.viewProps.valMap_)) {
ve({
key: "parent",
target: W.name,
place: "BladeController.parent"
});
return;
}
this.viewProps.set("parent", this.parent_ ? this.parent_.viewProps : null);
}
}
const z = "http://www.w3.org/2000/svg";
function Wt(n) {
n.offsetHeight;
}
function Bi(n, t) {
const e = n.style.transition;
n.style.transition = "none", t(), n.style.transition = e;
}
function be(n) {
return n.ontouchstart !== void 0;
}
function Ui() {
return globalThis;
}
function ji() {
return Ui().document;
}
function Fi(n) {
const t = n.ownerDocument.defaultView;
return t && "document" in t ? n.getContext("2d", {
willReadFrequently: true
}) : null;
}
const Ki = {
check: '<path d="M2 8l4 4l8 -8"/>',
dropdown: '<path d="M5 7h6l-3 3 z"/>',
p2dpad: '<path d="M8 4v8"/><path d="M4 8h8"/><circle cx="12" cy="12" r="1.2"/>'
};
function Xt(n, t) {
const e = n.createElementNS(z, "svg");
return e.innerHTML = Ki[t], e;
}
function rn(n, t, e) {
n.insertBefore(t, n.children[e]);
}
function sn(n) {
n.parentElement && n.parentElement.removeChild(n);
}
function on(n) {
for (; n.children.length > 0; )
n.removeChild(n.children[0]);
}
function $i(n) {
for (; n.childNodes.length > 0; )
n.removeChild(n.childNodes[0]);
}
function an(n) {
return n.relatedTarget ? n.relatedTarget : "explicitOriginalTarget" in n ? n.explicitOriginalTarget : null;
}
const St = E("lbl");
function Hi(n, t) {
const e = n.createDocumentFragment();
return t.split(`
`).map((r) => n.createTextNode(r)).forEach((r, a) => {
a > 0 && e.appendChild(n.createElement("br")), e.appendChild(r);
}), e;
}
class ln {
constructor(t, e) {
this.element = t.createElement("div"), this.element.classList.add(St()), e.viewProps.bindClassModifiers(this.element);
const i = t.createElement("div");
i.classList.add(St("l")), H(e.props, "label", (a) => {
g(a) ? this.element.classList.add(St(void 0, "nol")) : (this.element.classList.remove(St(void 0, "nol")), $i(i), i.appendChild(Hi(t, a)));
}), this.element.appendChild(i), this.labelElement = i;
const r = t.createElement("div");
r.classList.add(St("v")), this.element.appendChild(r), this.valueElement = r;
}
}
class Zt extends Vt {
constructor(t, e) {
const i = e.valueController.viewProps;
super(Object.assign(Object.assign({}, e), { view: new ln(t, {
props: e.props,
viewProps: i
}), viewProps: i })), this.props = e.props, this.valueController = e.valueController, this.view.valueElement.appendChild(this.valueController.view.element);
}
}
const zi = {
id: "button",
type: "blade",
accept(n) {
const t = R, e = I(n, {
title: t.required.string,
view: t.required.constant("button"),
label: t.optional.string
});
return e ? { params: e } : null;
},
controller(n) {
return new Zt(n.document, {
blade: n.blade,
props: C.fromObject({
label: n.params.label
}),
valueController: new Ze(n.document, {
props: C.fromObject({
title: n.params.title
}),
viewProps: n.viewProps
})
});
},
api(n) {
return !(n.controller instanceof Zt) || !(n.controller.valueController instanceof Ze) ? null : new et(n.controller);
}
};
class _t extends Vt {
constructor(t) {
super(t), this.value = t.value;
}
}
function Lt() {
return new C({
positions: N([], {
equals: P
})
});
}
class At extends C {
constructor(t) {
super(t);
}
static create(t) {
const e = {
completed: true,
expanded: t,
expandedHeight: null,
shouldFixHeight: false,
temporaryExpanded: null
}, i = C.createCore(e);
return new At(i);
}
get styleExpanded() {
var t;
return (t = this.get("temporaryExpanded")) !== null && t !== void 0 ? t : this.get("expanded");
}
get styleHeight() {
if (!this.styleExpanded)
return "0";
const t = this.get("expandedHeight");
return this.get("shouldFixHeight") && !g(t) ? `${t}px` : "auto";
}
bindExpandedClass(t, e) {
const i = () => {
this.styleExpanded ? t.classList.add(e) : t.classList.remove(e);
};
H(this, "expanded", i), H(this, "temporaryExpanded", i);
}
cleanUpTransition() {
this.set("shouldFixHeight", false), this.set("expandedHeight", null), this.set("completed", true);
}
}
function Gi(n, t) {
let e = 0;
return Bi(t, () => {
n.set("expandedHeight", null), n.set("temporaryExpanded", true), Wt(t), e = t.clientHeight, n.set("temporaryExpanded", null), Wt(t);
}), e;
}
function pn(n, t) {
t.style.height = n.styleHeight;
}
function fe(n, t) {
n.value("expanded").emitter.on("beforechange", () => {
if (n.set("completed", false), g(n.get("expandedHeight"))) {
const e = Gi(n, t);
e > 0 && n.set("expandedHeight", e);
}
n.set("shouldFixHeight", true), Wt(t);
}), n.emitter.on("change", () => {
pn(n, t);
}), pn(n, t), t.addEventListener("transitionend", (e) => {
e.propertyName === "height" && n.cleanUpTransition();
});
}
class _e extends l {
constructor(t, e) {
super(t), this.rackApi_ = e;
}
}
function qi(n, t) {
return n.addBlade(Object.assign(Object.assign({}, t), { view: "button" }));
}
function Yi(n, t) {
return n.addBlade(Object.assign(Object.assign({}, t), { view: "folder" }));
}
function Qi(n, t) {
const e = t ?? {};
return n.addBlade(Object.assign(Object.assign({}, e), { view: "separator" }));
}
function Wi(n, t) {
return n.addBlade(Object.assign(Object.assign({}, t), { view: "tab" }));
}
class we {
constructor(t) {
this.emitter = new M(), this.items_ = [], this.cache_ = /* @__PURE__ */ new Set(), this.onSubListAdd_ = this.onSubListAdd_.bind(this), this.onSubListRemove_ = this.onSubListRemove_.bind(this), this.extract_ = t;
}
get items() {
return this.items_;
}
allItems() {
return Array.from(this.cache_);
}
find(t) {
for (const e of this.allItems())
if (t(e))
return e;
return null;
}
includes(t) {
return this.cache_.has(t);
}
add(t, e) {
if (this.includes(t))
throw _.shouldNeverHappen();
const i = e !== void 0 ? e : this.items_.length;
this.items_.splice(i, 0, t), this.cache_.add(t);
const r = this.extract_(t);
r && (r.emitter.on("add", this.onSubListAdd_), r.emitter.on("remove", this.onSubListRemove_), r.allItems().forEach((a) => {
this.cache_.add(a);
})), this.emitter.emit("add", {
index: i,
item: t,
root: this,
target: this
});
}
remove(t) {
const e = this.items_.indexOf(t);
if (e < 0)
return;
this.items_.splice(e, 1), this.cache_.delete(t);
const i = this.extract_(t);
i && (i.emitter.off("add", this.onSubListAdd_), i.emitter.off("remove", this.onSubListRemove_)), this.emitter.emit("remove", {
index: e,
item: t,
root: this,
target: this
});
}
onSubListAdd_(t) {
this.cache_.add(t.item), this.emitter.emit("add", {
index: t.index,
item: t.item,
root: this,
target: t.target
});
}
onSubListRemove_(t) {
this.cache_.delete(t.item), this.emitter.emit("remove", {
index: t.index,
item: t.item,
root: this,
target: t.target
});
}
}
class ge extends l {
constructor(t) {
super(t), this.onBindingChange_ = this.onBindingChange_.bind(this), this.emitter_ = new M(), this.controller_.binding.emitter.on("change", this.onBindingChange_);
}
get label() {
return this.controller_.props.get("label");
}
set label(t) {
this.controller_.props.set("label", t);
}
on(t, e) {
const i = e.bind(this);
return this.emitter_.on(t, (r) => {
i(r.event);
}), this;
}
refresh() {
this.controller_.binding.read();
}
onBindingChange_(t) {
const e = t.sender.target.read();
this.emitter_.emit("change", {
event: new v(this, e, this.controller_.binding.target.presetKey, t.options.last)
});
}
}
class G extends Zt {
constructor(t, e) {
super(t, e), this.binding = e.binding;
}
}
class Ce extends l {
constructor(t) {
super(t), this.onBindingUpdate_ = this.onBindingUpdate_.bind(this), this.emitter_ = new M(), this.controller_.binding.emitter.on("update", this.onBindingUpdate_);
}
get label() {
return this.controller_.props.get("label");
}
set label(t) {
this.controller_.props.set("label", t);
}
on(t, e) {
const i = e.bind(this);
return this.emitter_.on(t, (r) => {
i(r.event);
}), this;
}
refresh() {
this.controller_.binding.read();
}
onBindingUpdate_(t) {
const e = t.sender.target.read();
this.emitter_.emit("update", {
event: new w(this, e, this.controller_.binding.target.presetKey)
});
}
}
class nt extends Zt {
constructor(t, e) {
super(t, e), this.binding = e.binding, this.viewProps.bindDisabled(this.binding.ticker), this.viewProps.handleDispose(() => {
this.binding.dispose();
});
}
}
function Xi(n) {
return n instanceof Jt ? n.apiSet_ : n instanceof _e ? n.rackApi_.apiSet_ : null;
}
function Mt(n, t) {
const e = n.find((i) => i.controller_ === t);
if (!e)
throw _.shouldNeverHappen();
return e;
}
function dn(n, t, e) {
if (!L.isBindable(n))
throw _.notBindable();
return new L(n, t, e);
}
class Jt extends l {
constructor(t, e) {
super(t), this.onRackAdd_ = this.onRackAdd_.bind(this), this.onRackRemove_ = this.onRackRemove_.bind(this), this.onRackInputChange_ = this.onRackInputChange_.bind(this), this.onRackMonitorUpdate_ = this.onRackMonitorUpdate_.bind(this), this.emitter_ = new M(), this.apiSet_ = new we(Xi), this.pool_ = e;
const i = this.controller_.rack;
i.emitter.on("add", this.onRackAdd_), i.emitter.on("remove", this.onRackRemove_), i.emitter.on("inputchange", this.onRackInputChange_), i.emitter.on("monitorupdate", this.onRackMonitorUpdate_), i.children.forEach((r) => {
this.setUpApi_(r);
});
}
get children() {
return this.controller_.rack.children.map((t) => Mt(this.apiSet_, t));
}
addInput(t, e, i) {
const r = i ?? {}, a = this.controller_.view.element.ownerDocument, d = this.pool_.createInput(a, dn(t, e, r.presetKey), r), h = new ge(d);
return this.add(h, r.index);
}
addMonitor(t, e, i) {
const r = i ?? {}, a = this.controller_.view.element.ownerDocument, d = this.pool_.createMonitor(a, dn(t, e), r), h = new Ce(d);
return this.add(h, r.index);
}
addFolder(t) {
return Yi(this, t);
}
addButton(t) {
return qi(this, t);
}
addSeparator(t) {
return Qi(this, t);
}
addTab(t) {
return Wi(this, t);
}
add(t, e) {
this.controller_.rack.add(t.controller_, e);
const i = this.apiSet_.find((r) => r.controller_ === t.controller_);
return i && this.apiSet_.remove(i), this.apiSet_.add(t), t;
}
remove