@bonsae/nrg 0.18.4 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -45
- package/package.json +1 -1
- package/server/index.cjs +96 -10
- package/server/resources/nrg-client.js +2269 -2233
- package/test/client/component/config.js +11 -0
- package/test/client/component/index.js +218 -235
- package/test/client/component/nrg.css +1 -0
- package/test/client/component/setup.js +1549 -140
- package/test/client/e2e/index.js +721 -367
- package/test/client/unit/index.js +204 -16
- package/test/client/unit/setup.js +209 -19
- package/test/server/unit/index.js +25 -4
- package/tsconfig/core/client.json +1 -1
- package/tsconfig/test/client/component.json +1 -1
- package/types/client.d.ts +98 -18
- package/types/server.d.ts +50 -12
- package/types/shims/brands.d.ts +32 -0
- package/types/shims/{form → client/form}/components/node-red-editor-input.vue.d.ts +1 -1
- package/types/shims/{form → client/form}/components/node-red-json-schema-form.vue.d.ts +21 -2
- package/types/shims/{form → client/form}/components/node-red-select-input.vue.d.ts +1 -0
- package/types/shims/{form → client/form}/components/node-red-typed-input.vue.d.ts +1 -0
- package/types/shims/client/types.d.ts +206 -0
- package/types/shims/components.d.ts +8 -8
- package/types/shims/constants.d.ts +4 -0
- package/types/shims/schema-options.d.ts +23 -10
- package/types/shims/typebox.d.ts +2 -2
- package/types/test-client-component.d.ts +170 -55
- package/types/test-client-e2e.d.ts +50 -0
- package/types/test-client-unit.d.ts +86 -22
- package/types/test-server-unit.d.ts +3 -1
- package/types/vite.d.ts +38 -9
- package/vite/index.js +733 -528
- /package/types/shims/{form → client/form}/components/node-red-config-input.vue.d.ts +0 -0
- /package/types/shims/{form → client/form}/components/node-red-input-label.vue.d.ts +0 -0
- /package/types/shims/{form → client/form}/components/node-red-input.vue.d.ts +0 -0
- /package/types/shims/{form → client/form}/components/node-red-toggle.vue.d.ts +0 -0
- /package/types/shims/{globals.d.ts → client/globals.d.ts} +0 -0
|
@@ -18,6 +18,17 @@ var defaultConfig = {
|
|
|
18
18
|
allow: [".."]
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
|
+
optimizeDeps: {
|
|
22
|
+
// @bonsae/nrg/server is a CJS bundle — prebundling converts it so browser
|
|
23
|
+
// tests can import TypeBox schemas straight from server schema modules.
|
|
24
|
+
include: [
|
|
25
|
+
"@bonsae/nrg/server",
|
|
26
|
+
"jsonpointer",
|
|
27
|
+
"ajv",
|
|
28
|
+
"ajv-formats",
|
|
29
|
+
"ajv-errors"
|
|
30
|
+
]
|
|
31
|
+
},
|
|
21
32
|
test: {
|
|
22
33
|
testTimeout: 3e4,
|
|
23
34
|
setupFiles: ["@bonsae/nrg/test/client/component/setup"],
|
|
@@ -1,259 +1,242 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
currentValue = val;
|
|
19
|
-
},
|
|
20
|
-
getSession: () => session,
|
|
21
|
-
focus: () => {
|
|
22
|
-
},
|
|
23
|
-
destroy: () => {
|
|
24
|
-
},
|
|
25
|
-
saveView: () => {
|
|
26
|
-
},
|
|
27
|
-
restoreView: () => {
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
},
|
|
31
|
-
prepareConfigNodeSelect: () => {
|
|
32
|
-
},
|
|
33
|
-
validateNode: () => true
|
|
34
|
-
},
|
|
35
|
-
tray: {
|
|
36
|
-
show: () => {
|
|
37
|
-
},
|
|
38
|
-
close: () => {
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
popover: {
|
|
42
|
-
tooltip: () => ({ delete: () => {
|
|
43
|
-
}, setAction: () => {
|
|
44
|
-
} })
|
|
45
|
-
},
|
|
46
|
-
nodes: {
|
|
47
|
-
registerType: () => {
|
|
48
|
-
},
|
|
49
|
-
node: () => null,
|
|
50
|
-
dirty: () => false
|
|
51
|
-
},
|
|
52
|
-
events: {
|
|
53
|
-
on: () => {
|
|
54
|
-
},
|
|
55
|
-
off: () => {
|
|
1
|
+
var y = Object.defineProperty;
|
|
2
|
+
var _ = (r, e, t) => e in r ? y(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
|
|
3
|
+
var u = (r, e, t) => _(r, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { vi as l } from "vitest";
|
|
5
|
+
import { inject as m, reactive as p, watch as g } from "vue";
|
|
6
|
+
import w from "jsonpointer";
|
|
7
|
+
import j from "ajv";
|
|
8
|
+
import $ from "ajv-formats";
|
|
9
|
+
import F from "ajv-errors";
|
|
10
|
+
class b {
|
|
11
|
+
constructor(e) {
|
|
12
|
+
u(this, "ajv");
|
|
13
|
+
const { customKeywords: t, customFormats: o, ...s } = e || {};
|
|
14
|
+
this.ajv = new j({
|
|
15
|
+
allErrors: !0,
|
|
16
|
+
code: {
|
|
17
|
+
source: !1
|
|
56
18
|
},
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
19
|
+
coerceTypes: !0,
|
|
20
|
+
removeAdditional: !1,
|
|
21
|
+
strict: !1,
|
|
22
|
+
strictSchema: !1,
|
|
23
|
+
useDefaults: !0,
|
|
24
|
+
validateFormats: !0,
|
|
25
|
+
// NOTE: typebox handles validation via typescript
|
|
26
|
+
// NOTE: if true, types that are not serializable JSON, like Function, would not work
|
|
27
|
+
validateSchema: !1,
|
|
28
|
+
verbose: !0,
|
|
29
|
+
...s
|
|
30
|
+
}), $(this.ajv), F(this.ajv), this.addCustomKeywords(t || []), this.addCustomFormats(o || {});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Add custom keywords to the validator
|
|
34
|
+
*/
|
|
35
|
+
addCustomKeywords(e) {
|
|
36
|
+
e && e.forEach((t) => {
|
|
37
|
+
this.ajv.addKeyword(t);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Add custom formats to the validator
|
|
42
|
+
*/
|
|
43
|
+
addCustomFormats(e) {
|
|
44
|
+
e && Object.entries(e).forEach(([t, o]) => {
|
|
45
|
+
o instanceof RegExp ? this.ajv.addFormat(t, o) : this.ajv.addFormat(t, { validate: o });
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Create a validator function with caching
|
|
50
|
+
* @param schema - JSON Schema to validate against
|
|
51
|
+
* @param cacheKey - Optional cache key for reusing validators
|
|
52
|
+
*/
|
|
53
|
+
createValidator(e, t) {
|
|
54
|
+
if (t && !e.$id && (e.$id = t), e.$id) {
|
|
55
|
+
const s = this.ajv.getSchema(e.$id);
|
|
56
|
+
if (s) return s;
|
|
62
57
|
}
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
58
|
+
return this.ajv.compile(e);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Validate data against a schema and return a structured result
|
|
62
|
+
*/
|
|
63
|
+
validate(e, t, o) {
|
|
64
|
+
const s = this.createValidator(t, o == null ? void 0 : o.cacheKey);
|
|
65
|
+
if (!s(e)) {
|
|
66
|
+
const n = this.formatErrors(s.errors);
|
|
67
|
+
if (o != null && o.throwOnError)
|
|
68
|
+
throw new f(n, s.errors || []);
|
|
69
|
+
return {
|
|
70
|
+
valid: !1,
|
|
71
|
+
errors: s.errors || void 0,
|
|
72
|
+
errorMessage: n
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
valid: !0,
|
|
77
|
+
data: e
|
|
70
78
|
};
|
|
71
79
|
}
|
|
72
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Format errors into a human-readable string
|
|
82
|
+
*/
|
|
83
|
+
formatErrors(e, t) {
|
|
84
|
+
return !e || e.length === 0 ? "No errors" : this.ajv.errorsText(e, {
|
|
85
|
+
separator: "; ",
|
|
86
|
+
dataVar: "data",
|
|
87
|
+
...t
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get detailed error information
|
|
92
|
+
*/
|
|
93
|
+
getDetailedErrors(e) {
|
|
94
|
+
return !e || e.length === 0 ? [] : e.map((t) => ({
|
|
95
|
+
field: t.instancePath || "/",
|
|
96
|
+
message: t.message || "Validation failed",
|
|
97
|
+
keyword: t.keyword,
|
|
98
|
+
params: t.params,
|
|
99
|
+
schemaPath: t.schemaPath
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Add a schema to the validator for reference
|
|
104
|
+
*/
|
|
105
|
+
addSchema(e, t) {
|
|
106
|
+
return this.ajv.addSchema(e, t), this;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Remove a schema from the validator
|
|
110
|
+
*/
|
|
111
|
+
removeSchema(e) {
|
|
112
|
+
return this.ajv.removeSchema(e), this;
|
|
113
|
+
}
|
|
73
114
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
return
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (value !== void 0) {
|
|
94
|
-
state.typedInput.type = String(value);
|
|
95
|
-
return void 0;
|
|
96
|
-
}
|
|
97
|
-
return state.typedInput.type;
|
|
98
|
-
}
|
|
99
|
-
return jq;
|
|
100
|
-
},
|
|
101
|
-
on(event, cb) {
|
|
102
|
-
if (!state.listeners[event]) state.listeners[event] = [];
|
|
103
|
-
state.listeners[event].push(cb);
|
|
104
|
-
return jq;
|
|
105
|
-
},
|
|
106
|
-
off(event) {
|
|
107
|
-
if (event) {
|
|
108
|
-
delete state.listeners[event];
|
|
109
|
-
} else {
|
|
110
|
-
for (const key of Object.keys(state.listeners)) {
|
|
111
|
-
delete state.listeners[key];
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return jq;
|
|
115
|
-
},
|
|
116
|
-
val(value) {
|
|
117
|
-
if (value !== void 0) {
|
|
118
|
-
if (el instanceof HTMLInputElement || el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement) {
|
|
119
|
-
el.value = String(value);
|
|
120
|
-
}
|
|
121
|
-
return jq;
|
|
122
|
-
}
|
|
123
|
-
if (el instanceof HTMLInputElement || el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement) {
|
|
124
|
-
return el.value;
|
|
115
|
+
class f extends Error {
|
|
116
|
+
constructor(e, t) {
|
|
117
|
+
super(e), this.errors = t, this.name = "ValidationError", Object.setPrototypeOf(this, f.prototype);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const k = new b({
|
|
121
|
+
customKeywords: [
|
|
122
|
+
{
|
|
123
|
+
keyword: "x-nrg-skip-validation",
|
|
124
|
+
schemaType: "boolean",
|
|
125
|
+
valid: !0
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
keyword: "x-nrg-node-type",
|
|
129
|
+
type: "string",
|
|
130
|
+
validate: (r, e) => {
|
|
131
|
+
if (!e) return !0;
|
|
132
|
+
const t = RED.nodes.node(e);
|
|
133
|
+
return !!t && t.type === r;
|
|
125
134
|
}
|
|
126
|
-
return "";
|
|
127
|
-
},
|
|
128
|
-
find(selector) {
|
|
129
|
-
return createJQ(el?.querySelector(selector) ?? null);
|
|
130
|
-
},
|
|
131
|
-
append(child) {
|
|
132
|
-
const childEl = child?.[0] || child;
|
|
133
|
-
if (el && childEl instanceof Element) el.appendChild(childEl);
|
|
134
|
-
return jq;
|
|
135
|
-
},
|
|
136
|
-
appendTo(target) {
|
|
137
|
-
const t = target?.[0] || target;
|
|
138
|
-
if (t instanceof Element && el) t.appendChild(el);
|
|
139
|
-
return jq;
|
|
140
|
-
},
|
|
141
|
-
html(content) {
|
|
142
|
-
if (el) el.innerHTML = content;
|
|
143
|
-
return jq;
|
|
144
|
-
},
|
|
145
|
-
empty() {
|
|
146
|
-
if (el) el.innerHTML = "";
|
|
147
|
-
return jq;
|
|
148
|
-
},
|
|
149
|
-
i18n() {
|
|
150
|
-
return jq;
|
|
151
|
-
},
|
|
152
|
-
addClass(cls) {
|
|
153
|
-
el?.classList.add(cls);
|
|
154
|
-
return jq;
|
|
155
|
-
},
|
|
156
|
-
removeClass(cls) {
|
|
157
|
-
el?.classList.remove(cls);
|
|
158
|
-
return jq;
|
|
159
|
-
},
|
|
160
|
-
__trigger(event) {
|
|
161
|
-
(state.listeners[event] || []).forEach((cb) => cb());
|
|
162
135
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
el.setAttribute(key, String(value));
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return createJQ(el);
|
|
136
|
+
],
|
|
137
|
+
customFormats: {
|
|
138
|
+
"node-id": /^[a-zA-Z0-9-_]+$/,
|
|
139
|
+
"flow-id": /^[a-f0-9]{16}$/,
|
|
140
|
+
"topic-path": (r) => /^[a-zA-Z0-9/_-]+$/.test(r)
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
function O(r, e) {
|
|
144
|
+
return r && (e != null && e.properties) ? {
|
|
145
|
+
...r,
|
|
146
|
+
properties: {
|
|
147
|
+
...r.properties,
|
|
148
|
+
credentials: {
|
|
149
|
+
type: "object",
|
|
150
|
+
properties: e.properties
|
|
183
151
|
}
|
|
184
|
-
return createJQ(document.querySelector(selector));
|
|
185
152
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
153
|
+
} : r;
|
|
154
|
+
}
|
|
155
|
+
function P(r, e) {
|
|
156
|
+
const t = k.validate(r, e, {
|
|
157
|
+
cacheKey: `node-schema-${r.type}`
|
|
158
|
+
});
|
|
159
|
+
return t.valid ? [] : t.errors ?? [];
|
|
191
160
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
161
|
+
function v(r, e) {
|
|
162
|
+
return P(r, e).filter((t) => {
|
|
163
|
+
var s;
|
|
164
|
+
return ((s = t.parentSchema) == null ? void 0 : s.format) !== "password" ? !0 : w.get(r, t.instancePath) !== "__PWD__";
|
|
165
|
+
}).reduce(
|
|
166
|
+
(t, o) => {
|
|
167
|
+
var n;
|
|
168
|
+
let s = o.instancePath;
|
|
169
|
+
o.keyword === "required" && ((n = o.params) != null && n.missingProperty) && (s = `${s}/${o.params.missingProperty}`);
|
|
170
|
+
const i = `node${s.replaceAll("/", ".")}`;
|
|
171
|
+
return t[i] = o.message ?? "Invalid", t;
|
|
172
|
+
},
|
|
173
|
+
{}
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
function I() {
|
|
177
|
+
const r = m("__nrg_form_node"), e = m("__nrg_form_schema"), t = m("__nrg_form_errors");
|
|
178
|
+
if (!r)
|
|
200
179
|
throw new Error(
|
|
201
180
|
"useFormNode() must be called inside a form component mounted by NRG."
|
|
202
181
|
);
|
|
203
|
-
}
|
|
204
182
|
return {
|
|
205
|
-
node,
|
|
206
|
-
schema,
|
|
207
|
-
errors
|
|
183
|
+
node: r,
|
|
184
|
+
schema: e,
|
|
185
|
+
errors: t
|
|
208
186
|
};
|
|
209
187
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
type
|
|
216
|
-
|
|
188
|
+
let h = 0;
|
|
189
|
+
function Z(r = {}) {
|
|
190
|
+
const e = "configs" in r || "configSchema" in r || "credentialsSchema" in r || "nodes" in r ? r : { configs: r }, t = p({
|
|
191
|
+
id: `test-${h}`,
|
|
192
|
+
// Unique type per node: validateForm caches compiled schemas by
|
|
193
|
+
// `node-schema-${subject.type}`, so a shared type would silently reuse
|
|
194
|
+
// the first schema for every later createNode call in the same file.
|
|
195
|
+
type: `test-node-${h++}`,
|
|
196
|
+
changed: !1,
|
|
217
197
|
_def: { outputs: 1 },
|
|
218
|
-
_: (
|
|
219
|
-
...
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
230
|
-
function spyIfNeeded(obj, method) {
|
|
231
|
-
if (!vi.isMockFunction(obj[method])) {
|
|
232
|
-
vi.spyOn(obj, method);
|
|
198
|
+
_: (d) => d,
|
|
199
|
+
...e.configs,
|
|
200
|
+
credentials: { ...e.credentials }
|
|
201
|
+
}), o = O(
|
|
202
|
+
e.configSchema,
|
|
203
|
+
e.credentialsSchema
|
|
204
|
+
);
|
|
205
|
+
let s;
|
|
206
|
+
if (o) {
|
|
207
|
+
const { $id: d, ...c } = o;
|
|
208
|
+
s = c;
|
|
233
209
|
}
|
|
210
|
+
const i = S();
|
|
211
|
+
N(i), i.nodes.clear();
|
|
212
|
+
for (const d of e.nodes ?? [])
|
|
213
|
+
i.nodes.add(d);
|
|
214
|
+
const n = p(
|
|
215
|
+
s ? v(t, s) : {}
|
|
216
|
+
);
|
|
217
|
+
return s && g(
|
|
218
|
+
t,
|
|
219
|
+
() => {
|
|
220
|
+
const d = v(t, s);
|
|
221
|
+
Object.keys(n).forEach((c) => delete n[c]), Object.assign(n, d);
|
|
222
|
+
},
|
|
223
|
+
{ deep: !0 }
|
|
224
|
+
), { node: t, errors: n, RED: i, provide: {
|
|
225
|
+
__nrg_form_node: t,
|
|
226
|
+
__nrg_form_schema: s ?? {},
|
|
227
|
+
__nrg_form_errors: n
|
|
228
|
+
} };
|
|
229
|
+
}
|
|
230
|
+
function a(r, e) {
|
|
231
|
+
l.isMockFunction(r[e]) || l.spyOn(r, e);
|
|
234
232
|
}
|
|
235
|
-
function
|
|
236
|
-
|
|
237
|
-
spyIfNeeded(RED, "notify");
|
|
238
|
-
spyIfNeeded(RED.editor, "createEditor");
|
|
239
|
-
spyIfNeeded(RED.editor, "prepareConfigNodeSelect");
|
|
240
|
-
spyIfNeeded(RED.editor, "validateNode");
|
|
241
|
-
spyIfNeeded(RED.tray, "show");
|
|
242
|
-
spyIfNeeded(RED.tray, "close");
|
|
243
|
-
spyIfNeeded(RED.popover, "tooltip");
|
|
244
|
-
spyIfNeeded(RED.nodes, "registerType");
|
|
245
|
-
spyIfNeeded(RED.nodes, "node");
|
|
246
|
-
spyIfNeeded(RED.nodes, "dirty");
|
|
247
|
-
spyIfNeeded(RED.events, "on");
|
|
248
|
-
spyIfNeeded(RED.events, "off");
|
|
249
|
-
spyIfNeeded(RED.events, "emit");
|
|
233
|
+
function N(r) {
|
|
234
|
+
a(r, "_"), a(r, "notify"), a(r.editor, "createEditor"), a(r.editor, "prepareConfigNodeSelect"), a(r.editor, "validateNode"), a(r.tray, "show"), a(r.tray, "close"), a(r.popover, "tooltip"), a(r.popover, "create"), a(r.nodes, "registerType"), a(r.nodes, "node"), a(r.nodes, "add"), a(r.nodes, "remove"), a(r.nodes, "getType"), a(r.nodes, "dirty"), a(r.events, "on"), a(r.events, "off"), a(r.events, "emit"), a(r.comms, "subscribe"), a(r.comms, "unsubscribe");
|
|
250
235
|
}
|
|
251
|
-
function
|
|
236
|
+
function S() {
|
|
252
237
|
return window.RED;
|
|
253
238
|
}
|
|
254
239
|
export {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
createRED,
|
|
258
|
-
useFormNode
|
|
240
|
+
Z as createNode,
|
|
241
|
+
I as useFormNode
|
|
259
242
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.nrg-label[data-v-864b02f2]{display:inline-block;width:100%;margin-bottom:4px;cursor:default}.nrg-label i[data-v-864b02f2]{margin-right:5px}.nrg-required[data-v-864b02f2]{color:var(--red-ui-text-color-error);margin-left:2px}.editor-wrapper[data-v-ea93e881]{position:relative}.expand-button[data-v-ea93e881]{position:absolute;top:-23px;right:0;z-index:10;transition:color .3s ease;cursor:pointer}.nrg-toggle-wrapper[data-v-724dcae4]{display:inline-flex;align-items:center}.nrg-toggle[data-v-724dcae4]{position:relative;display:inline-flex!important;flex-direction:column;align-items:flex-start;cursor:pointer;gap:4px;-webkit-user-select:none;user-select:none}.nrg-toggle__input[data-v-724dcae4]{position:absolute;opacity:0;width:0;height:0}.nrg-toggle__slider[data-v-724dcae4]{position:relative;display:inline-block;width:36px;min-width:36px;height:20px;background-color:var(--red-ui-secondary-border-color, #ccc);border-radius:10px;transition:background-color .2s ease}.nrg-toggle__slider[data-v-724dcae4]:after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;background-color:#fff;border-radius:50%;transition:transform .2s ease}.nrg-toggle--checked .nrg-toggle__slider[data-v-724dcae4]{background-color:var(--red-ui-text-color-link, #0070d2)}.nrg-toggle--checked .nrg-toggle__slider[data-v-724dcae4]:after{transform:translate(16px)}.nrg-toggle__label[data-v-724dcae4]{cursor:default;white-space:nowrap}.nrg-toggle__label i[data-v-724dcae4]{margin-right:2px}
|