@graphty/graphty-element 2.4.0 → 2.4.1
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/dist/ai.js +3 -3
- package/dist/catalog.js +6 -6
- package/dist/chunks/{AiManager-BD9XK30e.js → AiManager-DNJCoeTO.js} +5 -5
- package/dist/chunks/{DataSource-B8vf2uhW.js → DataSource-xL3Yn0Pa.js} +72 -61
- package/dist/chunks/{GraphSession-dcwOjGJh.js → GraphSession-PFm2tJ_j.js} +1483 -1441
- package/dist/chunks/{GraphtyLogger-CqOVV13Y.js → GraphtyLogger-kbOx2zq3.js} +169 -221
- package/dist/chunks/{VoiceInputAdapter-D0tHHi9G.js → VoiceInputAdapter-CDNKQgUK.js} +1 -1
- package/dist/chunks/{XRPivotCameraController-DTfhvhHz.js → XRPivotCameraController-JdlLBcD7.js} +146 -134
- package/dist/chunks/{algorithms-BF0X6RPw.js → algorithms-B87OPYw4.js} +2 -2
- package/dist/chunks/{capability-check-BJzlK4oL.js → capability-check-B2oYf_30.js} +1 -1
- package/dist/chunks/{detect-vJxK7n0D.js → detect-tuYQLJbT.js} +2 -2
- package/dist/chunks/{format-detection-C80TLQ2e.js → format-detection-BG6CMwPO.js} +1 -1
- package/dist/chunks/{index-2xkq7wyD.js → index-6GDfNfwJ.js} +2928 -2856
- package/dist/chunks/{optionsFromZod-BuTOFgVM.js → optionsFromZod-DHLLiX_8.js} +237 -236
- package/dist/chunks/{paletteRegistry-A63C71Gn.js → paletteRegistry-jg9uS7wo.js} +66 -66
- package/dist/chunks/pluginRegistry-MaTIDh6l.js +238 -0
- package/dist/chunks/{registry-jB46Gmeb.js → registry-DQeq4B2K.js} +8 -8
- package/dist/chunks/{scales-B2d-7Bf0.js → scales-BXHmwPXC.js} +4 -4
- package/dist/extend.js +7 -7
- package/dist/graphty-catalog.json +1 -1
- package/dist/graphty.bundle.js +25128 -24837
- package/dist/graphty.js +67 -63
- package/dist/index.d.ts +3 -0
- package/dist/logging.js +2 -2
- package/dist/session.js +5 -5
- package/dist/src/Edge.d.ts +4 -4
- package/dist/src/acceleration/AccelerationController.d.ts +6 -0
- package/dist/src/acceleration/registry.d.ts +3 -0
- package/dist/src/acceleration/types.d.ts +7 -0
- package/dist/src/algorithms/Algorithm.d.ts +13 -0
- package/dist/src/cameras/InputUtils.d.ts +67 -0
- package/dist/src/cameras/XRInputHandler.d.ts +0 -8
- package/dist/src/catalog/pluginRegistry.d.ts +62 -0
- package/dist/src/catalog/registry.d.ts +7 -0
- package/dist/src/data/DataSource.d.ts +1 -1
- package/dist/src/errors/codes.d.ts +2 -1
- package/dist/src/meshes/CustomLineRenderer.d.ts +11 -9
- package/dist/src/meshes/EdgeMesh.d.ts +18 -9
- package/dist/src/meshes/FilledArrowRenderer.d.ts +61 -23
- package/dist/src/meshes/PatternedLineRenderer.d.ts +5 -37
- package/dist/src/meshes/PerSceneMaterials.d.ts +49 -0
- package/dist/src/xr/XRSessionManager.d.ts +1 -1
- package/dist/webgpu.d.ts +8 -0
- package/dist/webgpu.js +2 -2
- package/package.json +6 -6
- package/dist/chunks/GraphtyError-B93WRH3e.js +0 -134
package/dist/ai.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { f as d } from "./chunks/AiManager-
|
|
2
|
-
import { A as C, a as P, b as I, C as L, M as $, S as D, c as R, V as k, d as M, e as V, g as q, h as z, i as E, j as G, k as W, l as j, m as N, n as T, q as U, r as _, s as B, o as F, p as J, t as Y, u as H, z as Q } from "./chunks/AiManager-
|
|
1
|
+
import { f as d } from "./chunks/AiManager-DNJCoeTO.js";
|
|
2
|
+
import { A as C, a as P, b as I, C as L, M as $, S as D, c as R, V as k, d as M, e as V, g as q, h as z, i as E, j as G, k as W, l as j, m as N, n as T, q as U, r as _, s as B, o as F, p as J, t as Y, u as H, z as Q } from "./chunks/AiManager-DNJCoeTO.js";
|
|
3
3
|
import { A as O } from "./chunks/ApiKeyManager-C0ac91dE.js";
|
|
4
|
-
import { V as Z } from "./chunks/VoiceInputAdapter-
|
|
4
|
+
import { V as Z } from "./chunks/VoiceInputAdapter-CDNKQgUK.js";
|
|
5
5
|
import { z as o } from "zod";
|
|
6
6
|
const y = {
|
|
7
7
|
name: "captureScreenshot",
|
package/dist/catalog.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { B as y, C as f, a as m, b as T, c as S, d as v, e as O, f as E, g as A, h as N } from "./chunks/algorithms-
|
|
2
|
-
import { d as I, a as k } from "./chunks/detect-
|
|
3
|
-
import { F as x, U as _, i as C, j as L } from "./chunks/paletteRegistry-
|
|
4
|
-
import { a as W, L as U, P as F, S as H, U as B, l as M, b as j, c as K, p as Y, d as G, s as z, e as V } from "./chunks/scales-
|
|
5
|
-
import { L as X, l as Z } from "./chunks/GraphtyLogger-
|
|
1
|
+
import { B as y, C as f, a as m, b as T, c as S, d as v, e as O, f as E, g as A, h as N } from "./chunks/algorithms-B87OPYw4.js";
|
|
2
|
+
import { d as I, a as k } from "./chunks/detect-tuYQLJbT.js";
|
|
3
|
+
import { F as x, U as _, i as C, j as L } from "./chunks/paletteRegistry-jg9uS7wo.js";
|
|
4
|
+
import { a as W, L as U, P as F, S as H, U as B, l as M, b as j, c as K, p as Y, d as G, s as z, e as V } from "./chunks/scales-BXHmwPXC.js";
|
|
5
|
+
import { L as X, l as Z } from "./chunks/GraphtyLogger-kbOx2zq3.js";
|
|
6
6
|
import { A as J, C as Q, D as ee, f as te, K as ae, a as oe, b as ne, c as re, d as ie, g as se, O as he, R as le, h as de, j as ce, k as we, i as pe, e as ue } from "./chunks/types-C_c53VgR.js";
|
|
7
|
-
import { o as be } from "./chunks/optionsFromZod-
|
|
7
|
+
import { o as be } from "./chunks/optionsFromZod-DHLLiX_8.js";
|
|
8
8
|
const d = Object.keys({
|
|
9
9
|
enabled: 0,
|
|
10
10
|
font: 0,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { l as Y } from "./VoiceInputAdapter-
|
|
2
|
-
import { G as J } from "./GraphtyLogger-
|
|
1
|
+
import { l as Y } from "./VoiceInputAdapter-CDNKQgUK.js";
|
|
2
|
+
import { G as J } from "./GraphtyLogger-kbOx2zq3.js";
|
|
3
3
|
import { z as c } from "zod";
|
|
4
|
-
import { k as Q, A as x, B as P } from "./optionsFromZod-
|
|
5
|
-
import { N as ee, e as te, C as se, d as re } from "./algorithms-
|
|
4
|
+
import { k as Q, A as x, B as P } from "./optionsFromZod-DHLLiX_8.js";
|
|
5
|
+
import { N as ee, e as te, C as se, d as re } from "./algorithms-B87OPYw4.js";
|
|
6
6
|
import ae from "jmespath";
|
|
7
7
|
import { inferSchema as A } from "@jsonhero/schema-infer";
|
|
8
|
-
import { i as oe } from "./
|
|
8
|
+
import { i as oe } from "./pluginRegistry-MaTIDh6l.js";
|
|
9
9
|
import { createAnthropic as ne } from "@ai-sdk/anthropic";
|
|
10
10
|
import { createGoogleGenerativeAI as ie } from "@ai-sdk/google";
|
|
11
11
|
import { createOpenAI as le } from "@ai-sdk/openai";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { z as
|
|
2
|
-
import * as
|
|
3
|
-
import { F as
|
|
4
|
-
import { b as F } from "./GraphtyLogger-
|
|
5
|
-
import { G as
|
|
6
|
-
class
|
|
1
|
+
import { z as y } from "zod/v4";
|
|
2
|
+
import * as w from "zod/v4/core";
|
|
3
|
+
import { F as $, p as E } from "./paletteRegistry-jg9uS7wo.js";
|
|
4
|
+
import { b as F } from "./GraphtyLogger-kbOx2zq3.js";
|
|
5
|
+
import { G as g, S as C } from "./pluginRegistry-MaTIDh6l.js";
|
|
6
|
+
class S {
|
|
7
7
|
/**
|
|
8
8
|
* Creates a new ErrorAggregator instance.
|
|
9
9
|
* @param maxErrors - Maximum number of errors to collect before stopping
|
|
@@ -58,8 +58,8 @@ class C {
|
|
|
58
58
|
getSummary() {
|
|
59
59
|
const e = this.errors.length;
|
|
60
60
|
let t, r = 0;
|
|
61
|
-
for (const [o,
|
|
62
|
-
|
|
61
|
+
for (const [o, c] of this.errorsByCategory.entries())
|
|
62
|
+
c.length > r && (r = c.length, t = o);
|
|
63
63
|
const { message: s, suggestion: i } = this.generateUserFriendlyMessage(
|
|
64
64
|
e,
|
|
65
65
|
t,
|
|
@@ -104,8 +104,8 @@ Suggestion: ${e.suggestion}`), t;
|
|
|
104
104
|
`;
|
|
105
105
|
const i = s.slice(0, 10);
|
|
106
106
|
for (const o of i) {
|
|
107
|
-
const
|
|
108
|
-
t += ` - ${o.message}${
|
|
107
|
+
const c = o.line !== void 0 ? ` [line ${o.line}]` : "", n = o.field ? ` [field: ${o.field}]` : "";
|
|
108
|
+
t += ` - ${o.message}${c}${n}
|
|
109
109
|
`;
|
|
110
110
|
}
|
|
111
111
|
s.length > 10 && (t += ` ... and ${s.length - 10} more
|
|
@@ -131,18 +131,18 @@ Suggestion: ${e.suggestion}`), t;
|
|
|
131
131
|
generateUserFriendlyMessage(e, t, r, s) {
|
|
132
132
|
if (e === 0)
|
|
133
133
|
return { message: "No errors" };
|
|
134
|
-
const i = r.get("missing-column")?.length ?? 0, o = r.get("parse-error")?.length ?? 0,
|
|
134
|
+
const i = r.get("missing-column")?.length ?? 0, o = r.get("parse-error")?.length ?? 0, c = r.get("validation-error")?.length ?? 0, n = r.get("missing-value")?.length ?? 0;
|
|
135
135
|
if (i > 0) {
|
|
136
|
-
const
|
|
137
|
-
return { message:
|
|
136
|
+
const a = Array.from(s.keys()), l = `Found ${e} errors (${i} missing column errors)`, m = a.length > 0 ? `Check that your data has the required columns: ${a.join(", ")}` : "Check that your data has the required columns (e.g., 'source', 'target' for edges)";
|
|
137
|
+
return { message: l, suggestion: m };
|
|
138
138
|
}
|
|
139
139
|
if (o > e * 0.5)
|
|
140
140
|
return { message: `Found ${e} errors (mostly parsing errors)`, suggestion: "Check your file format and encoding. Common issues: incorrect delimiter, malformed quotes, or encoding problems (try UTF-8)" };
|
|
141
|
-
if (
|
|
142
|
-
const
|
|
143
|
-
return { message:
|
|
141
|
+
if (n > 0) {
|
|
142
|
+
const a = Array.from(s.keys()), l = `Found ${e} errors (${n} missing required values)`, m = a.length > 0 ? `Check that rows have values for: ${a.join(", ")}` : "Check that rows have all required values";
|
|
143
|
+
return { message: l, suggestion: m };
|
|
144
144
|
}
|
|
145
|
-
return
|
|
145
|
+
return c > 0 ? { message: `Found ${e} errors (${c} validation errors)`, suggestion: "Check that your data values match the expected format and types" } : t && t !== "unknown" ? {
|
|
146
146
|
message: `Found ${e} errors (mostly ${t} errors)`,
|
|
147
147
|
suggestion: "See detailed error report for more information"
|
|
148
148
|
} : {
|
|
@@ -151,7 +151,7 @@ Suggestion: ${e.suggestion}`), t;
|
|
|
151
151
|
};
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
|
-
const
|
|
154
|
+
const f = new C("format"), k = /* @__PURE__ */ new Set([
|
|
155
155
|
"data",
|
|
156
156
|
"file",
|
|
157
157
|
"url",
|
|
@@ -164,45 +164,45 @@ const l = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Set([
|
|
|
164
164
|
"edgeSrcIdPath",
|
|
165
165
|
"edgeDstIdPath"
|
|
166
166
|
]);
|
|
167
|
-
function h(
|
|
168
|
-
throw new
|
|
167
|
+
function h(d, e) {
|
|
168
|
+
throw new g({
|
|
169
169
|
code: "E_BAD_COMMAND",
|
|
170
170
|
message: e,
|
|
171
171
|
source: "registry",
|
|
172
|
-
details: { kind: "format", field:
|
|
172
|
+
details: { kind: "format", field: d }
|
|
173
173
|
});
|
|
174
174
|
}
|
|
175
|
-
function
|
|
175
|
+
function A(d, e) {
|
|
176
176
|
(e === null || typeof e != "object") && h(
|
|
177
177
|
"descriptor",
|
|
178
|
-
`the format "${
|
|
178
|
+
`the format "${d}" registered no description, so nothing could offer it: declare \`static descriptor: FormatDescriptor\` on the class`
|
|
179
179
|
);
|
|
180
180
|
const t = e;
|
|
181
|
-
t.id !==
|
|
181
|
+
t.id !== d && h(
|
|
182
182
|
"descriptor.id",
|
|
183
|
-
`the reader registered as "${
|
|
183
|
+
`the reader registered as "${d}" describes itself as "${String(t.id)}"; one format has one name, and the two halves disagreeing is how a catalogue entry comes to name a reader nothing registered`
|
|
184
184
|
), (!Array.isArray(t.extensions) || t.extensions.length === 0) && h(
|
|
185
185
|
"descriptor.extensions",
|
|
186
|
-
`the format "${
|
|
186
|
+
`the format "${d}" claims no file extension, so no file could ever be recognised as it`
|
|
187
187
|
);
|
|
188
188
|
for (const r of t.extensions)
|
|
189
189
|
(typeof r != "string" || !r.startsWith(".") || r !== r.toLowerCase()) && h(
|
|
190
190
|
"descriptor.extensions",
|
|
191
|
-
`the format "${
|
|
191
|
+
`the format "${d}" claims the extension ${JSON.stringify(r)}; an extension is a lower-case string beginning with a dot, because that is what a file name is compared against`
|
|
192
192
|
);
|
|
193
193
|
return (!Array.isArray(t.mimeTypes) || t.mimeTypes.length === 0) && h(
|
|
194
194
|
"descriptor.mimeTypes",
|
|
195
|
-
`the format "${
|
|
195
|
+
`the format "${d}" declares no media type, which is what a file picker filters on`
|
|
196
196
|
), t.canExport === !0 && h(
|
|
197
197
|
"descriptor.canExport",
|
|
198
|
-
`the format "${
|
|
198
|
+
`the format "${d}" says it can be written, and there is nowhere to register a writer: a "Save as" menu built from the catalogue would offer a format nothing can save`
|
|
199
199
|
), e;
|
|
200
200
|
}
|
|
201
|
-
function
|
|
201
|
+
function v(d, e) {
|
|
202
202
|
if (e !== void 0)
|
|
203
203
|
return typeof e != "function" && h(
|
|
204
204
|
"detect",
|
|
205
|
-
`the format "${
|
|
205
|
+
`the format "${d}" declares a \`static detect\` that is not a function, so no file could be sniffed`
|
|
206
206
|
), e;
|
|
207
207
|
}
|
|
208
208
|
const u = class u {
|
|
@@ -212,7 +212,7 @@ const u = class u {
|
|
|
212
212
|
* @param chunkSize - Number of nodes to process per chunk
|
|
213
213
|
*/
|
|
214
214
|
constructor(e = 100, t = u.DEFAULT_CHUNK_SIZE) {
|
|
215
|
-
this.edgeSchema = null, this.nodeSchema = null, this.declaration = null, this.errorAggregator = new
|
|
215
|
+
this.edgeSchema = null, this.nodeSchema = null, this.declaration = null, this.errorAggregator = new S(e), this.chunkSize = t;
|
|
216
216
|
}
|
|
217
217
|
/**
|
|
218
218
|
* Standardized error message templates
|
|
@@ -241,23 +241,34 @@ const u = class u {
|
|
|
241
241
|
let s;
|
|
242
242
|
for (let i = 0; i < t; i++)
|
|
243
243
|
try {
|
|
244
|
-
const o = new AbortController(),
|
|
244
|
+
const o = new AbortController(), c = setTimeout(() => {
|
|
245
245
|
o.abort();
|
|
246
246
|
}, r);
|
|
247
247
|
try {
|
|
248
|
-
const
|
|
249
|
-
if (clearTimeout(
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
248
|
+
const n = await fetch(e, { signal: o.signal });
|
|
249
|
+
if (clearTimeout(c), !n.ok) {
|
|
250
|
+
s = n.status;
|
|
251
|
+
const { status: a } = n;
|
|
252
|
+
throw a >= 400 && a < 500 && a !== 408 && a !== 429 ? new g({
|
|
253
|
+
code: "E_FETCH_FAILED",
|
|
254
|
+
message: `Failed to fetch from ${e}: HTTP ${a}`,
|
|
255
|
+
source: "data",
|
|
256
|
+
recoverable: !1,
|
|
257
|
+
details: { url: e, attempts: i + 1, status: a }
|
|
258
|
+
}) : new Error(`HTTP error! status: ${a}`);
|
|
259
|
+
}
|
|
260
|
+
return n;
|
|
261
|
+
} catch (n) {
|
|
262
|
+
throw clearTimeout(c), n instanceof Error && n.name === "AbortError" ? new Error(`Request timeout after ${r}ms`) : n;
|
|
254
263
|
}
|
|
255
264
|
} catch (o) {
|
|
265
|
+
if (o instanceof g)
|
|
266
|
+
throw o;
|
|
256
267
|
if (i === t - 1) {
|
|
257
|
-
const
|
|
258
|
-
throw new
|
|
268
|
+
const a = o instanceof Error ? o.message : String(o);
|
|
269
|
+
throw new g({
|
|
259
270
|
code: "E_FETCH_FAILED",
|
|
260
|
-
message: `Failed to fetch from ${e} after ${t} attempts: ${
|
|
271
|
+
message: `Failed to fetch from ${e} after ${t} attempts: ${a}`,
|
|
261
272
|
source: "data",
|
|
262
273
|
// A server that was down, a network that dropped: the same call unchanged
|
|
263
274
|
// could succeed later, which is exactly what this flag is for.
|
|
@@ -266,10 +277,10 @@ const u = class u {
|
|
|
266
277
|
cause: o
|
|
267
278
|
});
|
|
268
279
|
}
|
|
269
|
-
const
|
|
270
|
-
await new Promise((
|
|
280
|
+
const n = Math.pow(2, i) * 1e3;
|
|
281
|
+
await new Promise((a) => setTimeout(a, n));
|
|
271
282
|
}
|
|
272
|
-
throw new
|
|
283
|
+
throw new g({
|
|
273
284
|
code: "E_FETCH_FAILED",
|
|
274
285
|
message: `Failed to fetch from ${e} after ${t} attempts`,
|
|
275
286
|
source: "data",
|
|
@@ -315,8 +326,8 @@ const u = class u {
|
|
|
315
326
|
*/
|
|
316
327
|
resolveOptions(e) {
|
|
317
328
|
const r = this.constructor.descriptor?.options ?? [], s = new Set(r.map((o) => o.name)), i = {};
|
|
318
|
-
for (const [o,
|
|
319
|
-
(s.has(o) || !
|
|
329
|
+
for (const [o, c] of Object.entries(e))
|
|
330
|
+
(s.has(o) || !k.has(o)) && (i[o] = c);
|
|
320
331
|
return F(r, i, { kind: "format", id: this.type });
|
|
321
332
|
}
|
|
322
333
|
/**
|
|
@@ -398,9 +409,9 @@ const u = class u {
|
|
|
398
409
|
* @returns Promise resolving to true if validation succeeds, false otherwise
|
|
399
410
|
*/
|
|
400
411
|
async dataValidator(e, t) {
|
|
401
|
-
const r = await
|
|
412
|
+
const r = await w.safeParseAsync(e, t);
|
|
402
413
|
if (!r.success) {
|
|
403
|
-
const s =
|
|
414
|
+
const s = y.prettifyError(r.error);
|
|
404
415
|
return this.errorAggregator.addError({
|
|
405
416
|
message: `Validation failed: ${s}`,
|
|
406
417
|
category: "validation-error"
|
|
@@ -443,25 +454,25 @@ const u = class u {
|
|
|
443
454
|
if ((typeof r != "string" || r === "") && h(
|
|
444
455
|
"type",
|
|
445
456
|
"a data source registers under the name in its `static type`, and this class declares none"
|
|
446
|
-
),
|
|
447
|
-
if (
|
|
448
|
-
throw new
|
|
457
|
+
), $.some((i) => i.id === r)) {
|
|
458
|
+
if (f.hasOwn(r))
|
|
459
|
+
throw new g({
|
|
449
460
|
code: "E_DUPLICATE_PLUGIN",
|
|
450
461
|
message: `"${r}" is a format the element ships and already reads, and a built-in name may not be taken: a document that named it yesterday has to mean the same thing today`,
|
|
451
462
|
source: "registry",
|
|
452
463
|
details: { kind: "format", name: r, builtIn: !0 }
|
|
453
464
|
});
|
|
454
|
-
return
|
|
465
|
+
return f.set(r, e), e;
|
|
455
466
|
}
|
|
456
|
-
const s =
|
|
467
|
+
const s = v(r, e.detect);
|
|
457
468
|
return E(
|
|
458
469
|
{
|
|
459
|
-
descriptor:
|
|
470
|
+
descriptor: A(r, e.descriptor),
|
|
460
471
|
type: r,
|
|
461
472
|
...s === void 0 ? {} : { detect: s }
|
|
462
473
|
},
|
|
463
474
|
t
|
|
464
|
-
),
|
|
475
|
+
), f.set(r, e), e;
|
|
465
476
|
}
|
|
466
477
|
/**
|
|
467
478
|
* Turn a plain object into a record the element ingests.
|
|
@@ -497,7 +508,7 @@ const u = class u {
|
|
|
497
508
|
* @returns A new data source instance or null if type not found
|
|
498
509
|
*/
|
|
499
510
|
static get(e, t = {}) {
|
|
500
|
-
const r =
|
|
511
|
+
const r = f.get(e);
|
|
501
512
|
return r ? new r(t) : null;
|
|
502
513
|
}
|
|
503
514
|
/**
|
|
@@ -512,12 +523,12 @@ const u = class u {
|
|
|
512
523
|
* ```
|
|
513
524
|
*/
|
|
514
525
|
static getRegisteredTypes() {
|
|
515
|
-
return Array.from(
|
|
526
|
+
return Array.from(f.keys()).sort();
|
|
516
527
|
}
|
|
517
528
|
};
|
|
518
529
|
u.DEFAULT_CHUNK_SIZE = 1e3;
|
|
519
|
-
let
|
|
530
|
+
let p = u;
|
|
520
531
|
export {
|
|
521
|
-
|
|
522
|
-
|
|
532
|
+
p as D,
|
|
533
|
+
S as E
|
|
523
534
|
};
|