@qaecy/cue-sdk 0.0.30 → 0.0.31

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.
@@ -1,11 +1,11 @@
1
- import { getApps as be, initializeApp as ve } from "firebase/app";
2
- import { ref as _, getDownloadURL as K, getMetadata as z, getBlob as re, updateMetadata as _e, uploadBytesResumable as ft, uploadBytes as st, StringFormat as ke, uploadString as Ee, listAll as $, getStorage as S, connectStorageEmulator as X } from "firebase/storage";
3
- import { Writer as xe, DataFactory as j } from "n3";
4
- import { getFirestore as Ie, connectFirestoreEmulator as Ce, collection as yt, getDocs as Se, query as Te, where as Re, limit as Ae, doc as bt, getDoc as Pe, setDoc as Oe, serverTimestamp as De, increment as Le } from "firebase/firestore";
5
- import { getAuth as qe, connectAuthEmulator as je, onIdTokenChanged as Ue, getIdTokenResult as at, signInWithEmailAndPassword as ze, GoogleAuthProvider as it, OAuthProvider as nt, signInWithPopup as $e, signInWithRedirect as Me, getRedirectResult as Ne, signInWithCustomToken as vt, signOut as Fe, onAuthStateChanged as Be, fetchSignInMethodsForEmail as Ge, linkWithPopup as He, unlink as We, reauthenticateWithCredential as _t, EmailAuthProvider as Q, updatePassword as Ve, linkWithCredential as Ke, verifyBeforeUpdateEmail as Xe, sendEmailVerification as Qe } from "firebase/auth";
6
- import { v5 as Ye } from "uuid";
1
+ import { getApps as xe, initializeApp as Ce } from "firebase/app";
2
+ import { ref as k, getDownloadURL as X, getMetadata as $, getBlob as ne, updateMetadata as Ie, uploadBytesResumable as ft, uploadBytes as st, StringFormat as Se, uploadString as Te, listAll as U, getStorage as C, connectStorageEmulator as K } from "firebase/storage";
3
+ import { Writer as Re, DataFactory as j } from "n3";
4
+ import { getFirestore as Ae, connectFirestoreEmulator as Pe, collection as yt, getDocs as Oe, query as De, where as Le, limit as qe, doc as bt, getDoc as je, setDoc as ze, serverTimestamp as $e, increment as Ue } from "firebase/firestore";
5
+ import { getAuth as Me, connectAuthEmulator as Ne, onIdTokenChanged as Fe, getIdTokenResult as at, signInWithEmailAndPassword as Be, GoogleAuthProvider as it, OAuthProvider as nt, signInWithPopup as Ge, signInWithRedirect as He, getRedirectResult as We, signInWithCustomToken as vt, signOut as Ve, onAuthStateChanged as Xe, fetchSignInMethodsForEmail as Ke, linkWithPopup as Qe, unlink as Ye, reauthenticateWithCredential as _t, EmailAuthProvider as Q, updatePassword as Ze, linkWithCredential as Je, verifyBeforeUpdateEmail as to, sendEmailVerification as eo } from "firebase/auth";
6
+ import { v5 as oo } from "uuid";
7
7
  import "spark-md5";
8
- import { getFunctions as se, connectFunctionsEmulator as ae, httpsCallable as F } from "firebase/functions";
8
+ import { getFunctions as pe, connectFunctionsEmulator as ce, httpsCallable as F } from "firebase/functions";
9
9
  class ht {
10
10
  queryEndpoint;
11
11
  updateEndpoint;
@@ -86,7 +86,7 @@ class Y extends Error {
86
86
  super(`QLever is locked (rebuild in progress): ${t}`), this.name = "QLeverLockedError";
87
87
  }
88
88
  }
89
- class R {
89
+ class A {
90
90
  queryEndpoint;
91
91
  updateEndpoint;
92
92
  dataEndpoint;
@@ -113,7 +113,7 @@ class R {
113
113
  * 423 means qlever accessor has an ongoing rebuild; we should wait and retry.
114
114
  */
115
115
  static async _retryOnLocked(t) {
116
- const e = R.LOCKED_MAX_RETRIES, o = R.LOCKED_BASE_DELAY_MS;
116
+ const e = A.LOCKED_MAX_RETRIES, o = A.LOCKED_BASE_DELAY_MS;
117
117
  let r;
118
118
  for (let s = 0; s <= e; s++)
119
119
  try {
@@ -131,7 +131,7 @@ class R {
131
131
  constructor(t) {
132
132
  this.queryEndpoint = t.queryEndpoint, this.updateEndpoint = t.updateEndpoint, this.dataEndpoint = this.updateEndpoint.replace(/\/update$/, "/data"), this.baseHeaders = Object.fromEntries(
133
133
  Object.entries(t.originalHeaders || {}).filter(
134
- ([e]) => R.RELEVANT_HEADER_KEYS.includes(e)
134
+ ([e]) => A.RELEVANT_HEADER_KEYS.includes(e)
135
135
  )
136
136
  ), this.baseHeaders["x-user-roles"] = "admin";
137
137
  }
@@ -173,7 +173,7 @@ class R {
173
173
  })).text();
174
174
  }
175
175
  async update(t) {
176
- return R._retryOnLocked(async () => {
176
+ return A._retryOnLocked(async () => {
177
177
  const e = await fetch(this.updateEndpoint, {
178
178
  headers: {
179
179
  ...this.baseHeaders,
@@ -204,8 +204,8 @@ class R {
204
204
  await this._postToDataEndpoint(t, `${this.dataEndpoint}/delete`);
205
205
  }
206
206
  async _postToDataEndpoint(t, e) {
207
- const o = await this._quadsToNQuads(t), r = await Ze(Buffer.from(o, "utf-8"));
208
- await R._retryOnLocked(async () => {
207
+ const o = await this._quadsToNQuads(t), r = await ro(Buffer.from(o, "utf-8"));
208
+ await A._retryOnLocked(async () => {
209
209
  const s = await fetch(e, {
210
210
  method: "POST",
211
211
  headers: {
@@ -223,12 +223,12 @@ class R {
223
223
  }
224
224
  _quadsToNQuads(t) {
225
225
  return new Promise((e, o) => {
226
- const r = new xe({ format: "application/n-quads" });
226
+ const r = new Re({ format: "application/n-quads" });
227
227
  r.addQuads(t), r.end((s, a) => s ? o(s) : e(a));
228
228
  });
229
229
  }
230
230
  }
231
- async function Ze(i) {
231
+ async function ro(i) {
232
232
  const t = new CompressionStream("gzip"), e = t.writable.getWriter();
233
233
  e.write(new Uint8Array(i)), e.close();
234
234
  const o = [], r = t.readable.getReader();
@@ -243,11 +243,11 @@ async function Ze(i) {
243
243
  a.set(p, n), n += p.byteLength;
244
244
  return a.buffer;
245
245
  }
246
- class Je {
246
+ class so {
247
247
  constructor(t) {
248
248
  switch (this.options = t, this.options.graphType) {
249
249
  case "qlever":
250
- this._db = new R(this.options);
250
+ this._db = new A(this.options);
251
251
  break;
252
252
  case "fuseki":
253
253
  this._db = new ht(this.options);
@@ -298,7 +298,7 @@ class Je {
298
298
  return this.options.graphType === "qlever" ? this._db.deleteData(t) : Promise.reject(new Error("deleteData not supported for Fuseki — use update() with SPARQL DELETE DATA"));
299
299
  }
300
300
  }
301
- class kt {
301
+ class Et {
302
302
  constructor(t) {
303
303
  this.options = t;
304
304
  }
@@ -320,14 +320,16 @@ class kt {
320
320
  return this.options.storagePublic;
321
321
  case "persistence":
322
322
  return this.options.storagePersistence;
323
+ case "sessions":
324
+ return this.options.storageSessions;
323
325
  }
324
326
  }
325
327
  // ─── Downloads ────────────────────────────────────────────────────────────
326
328
  /** Get an authenticated download URL. Returns undefined if the file does not exist. */
327
329
  async getDownloadURL(t, e) {
328
- const o = _(this._bucket(t), e);
330
+ const o = k(this._bucket(t), e);
329
331
  try {
330
- return await K(o);
332
+ return await X(o);
331
333
  } catch (r) {
332
334
  if (r?.code === "storage/object-not-found") return;
333
335
  throw r;
@@ -340,10 +342,10 @@ class kt {
340
342
  async getCacheBustedUrl(t, e) {
341
343
  const o = `${t}:${e}`;
342
344
  if (this._knownMissing.has(o)) return;
343
- const r = _(this._bucket(t), e);
345
+ const r = k(this._bucket(t), e);
344
346
  try {
345
- const s = await z(r);
346
- return `${await K(r)}&t=${encodeURIComponent(s.updated)}`;
347
+ const s = await $(r);
348
+ return `${await X(r)}&t=${encodeURIComponent(s.updated)}`;
347
349
  } catch (s) {
348
350
  if (s?.code === "storage/object-not-found" || s?.status === 404) {
349
351
  this._knownMissing.add(o), console.debug(`[CueBlobStorage] ${e} not found (404 OK — optional cache file)`);
@@ -354,9 +356,9 @@ class kt {
354
356
  }
355
357
  /** Download a file as a Blob. Returns undefined if the file does not exist. */
356
358
  async getFile(t, e) {
357
- const o = _(this._bucket(t), e);
359
+ const o = k(this._bucket(t), e);
358
360
  try {
359
- return await re(o);
361
+ return await ne(o);
360
362
  } catch (r) {
361
363
  if (r?.code === "storage/object-not-found") return;
362
364
  throw r;
@@ -371,7 +373,7 @@ class kt {
371
373
  * Uses a cache-busted URL to ensure the latest version is fetched.
372
374
  */
373
375
  async downloadPublic(t) {
374
- const e = _(this.options.storagePublic, t), o = new AbortController(), r = setTimeout(() => o.abort(), 1e4), s = (a) => Promise.race([
376
+ const e = k(this.options.storagePublic, t), o = new AbortController(), r = setTimeout(() => o.abort(), 1e4), s = (a) => Promise.race([
375
377
  a,
376
378
  new Promise((n, p) => {
377
379
  o.signal.addEventListener(
@@ -382,8 +384,8 @@ class kt {
382
384
  ]);
383
385
  try {
384
386
  const [a, n] = await Promise.all([
385
- s(K(e)),
386
- s(z(e))
387
+ s(X(e)),
388
+ s($(e))
387
389
  ]), p = `${a}&t=${encodeURIComponent(n.updated)}`, c = await fetch(p, { signal: o.signal });
388
390
  if (!c.ok) throw new Error(`HTTP ${c.status}`);
389
391
  return c.text();
@@ -397,9 +399,9 @@ class kt {
397
399
  // ─── Metadata ─────────────────────────────────────────────────────────────
398
400
  /** Read file metadata. Returns undefined if the file does not exist. */
399
401
  async getMetadata(t, e) {
400
- const o = _(this._bucket(t), e);
402
+ const o = k(this._bucket(t), e);
401
403
  try {
402
- const r = await z(o);
404
+ const r = await $(o);
403
405
  return {
404
406
  updated: r.updated,
405
407
  contentType: r.contentType,
@@ -413,8 +415,8 @@ class kt {
413
415
  }
414
416
  /** Update custom metadata on an existing file. */
415
417
  async setMetadata(t, e, o) {
416
- const r = _(this._bucket(t), e);
417
- await _e(r, { customMetadata: o });
418
+ const r = k(this._bucket(t), e);
419
+ await Ie(r, { customMetadata: o });
418
420
  }
419
421
  // ─── Uploads ──────────────────────────────────────────────────────────────
420
422
  /**
@@ -423,7 +425,7 @@ class kt {
423
425
  * upload progress needs to be surfaced in the UI.
424
426
  */
425
427
  uploadResumable(t, e, o, r) {
426
- const s = _(this._bucket(t), e), a = ft(s, o, r ? { customMetadata: r } : void 0);
428
+ const s = k(this._bucket(t), e), a = ft(s, o, r ? { customMetadata: r } : void 0);
427
429
  return {
428
430
  complete: () => new Promise((n, p) => a.then(() => n(), p)),
429
431
  pause: () => a.pause(),
@@ -442,19 +444,19 @@ class kt {
442
444
  * Use for small files where progress feedback is not needed.
443
445
  */
444
446
  async uploadBytes(t, e, o, r) {
445
- const s = _(this._bucket(t), e);
447
+ const s = k(this._bucket(t), e);
446
448
  await st(s, o, r ? { customMetadata: r } : void 0);
447
449
  }
448
450
  /** Upload a string or base64-encoded value. */
449
- async uploadString(t, e, o, r = ke.RAW, s) {
450
- const a = _(this._bucket(t), e);
451
- await Ee(a, o, r, s ? { customMetadata: s } : void 0);
451
+ async uploadString(t, e, o, r = Se.RAW, s) {
452
+ const a = k(this._bucket(t), e);
453
+ await Te(a, o, r, s ? { customMetadata: s } : void 0);
452
454
  }
453
455
  // ─── Listing ──────────────────────────────────────────────────────────────
454
456
  /** List all item names directly under `prefix` in the given bucket. */
455
457
  async listFiles(t, e) {
456
- const o = _(this._bucket(t), e);
457
- return (await $(o)).items.map((s) => s.name);
458
+ const o = k(this._bucket(t), e);
459
+ return (await U(o)).items.map((s) => s.name);
458
460
  }
459
461
  /**
460
462
  * Recursively list all file full-paths under `prefix` in the given bucket.
@@ -462,7 +464,7 @@ class kt {
462
464
  */
463
465
  async listFilesRecursive(t, e) {
464
466
  const o = this._bucket(t), r = async (s) => {
465
- const a = await $(_(o, s));
467
+ const a = await U(k(o, s));
466
468
  let n = a.items.map((p) => p.fullPath);
467
469
  for (const p of a.prefixes)
468
470
  n = n.concat(await r(p.fullPath));
@@ -478,7 +480,7 @@ class kt {
478
480
  const { deleteObject: o } = await import("firebase/storage"), r = this._bucket(t);
479
481
  let s = 0;
480
482
  const a = async (n) => {
481
- const p = await $(_(r, n));
483
+ const p = await U(k(r, n));
482
484
  for (const c of p.items)
483
485
  await o(c), s++;
484
486
  for (const c of p.prefixes)
@@ -490,7 +492,7 @@ class kt {
490
492
  // (used by loaders / processors that were already depending on CueBlobStorage)
491
493
  /** Upload binary data to the raw bucket with retry logic. */
492
494
  async uploadRaw(t, e, o, r = 3, s, a) {
493
- const n = _(this.options.storageRaw, t);
495
+ const n = k(this.options.storageRaw, t);
494
496
  let p = 0, c;
495
497
  for (; p < r; )
496
498
  try {
@@ -531,16 +533,16 @@ class kt {
531
533
  * Skips upload and returns `false` if the blob already exists.
532
534
  */
533
535
  async uploadProcessed(t, e, o) {
534
- const r = _(this.options.storageProcessed, t);
535
- return await z(r).catch(() => null) ? !1 : (await st(r, e, { customMetadata: o }), !0);
536
+ const r = k(this.options.storageProcessed, t);
537
+ return await $(r).catch(() => null) ? !1 : (await st(r, e, { customMetadata: o }), !0);
536
538
  }
537
539
  /** List all blob names directly under `prefix` in the raw bucket. */
538
540
  async listRaw(t) {
539
- const e = _(this.options.storageRaw, t);
540
- return (await $(e)).items.map((r) => r.name);
541
+ const e = k(this.options.storageRaw, t);
542
+ return (await U(e)).items.map((r) => r.name);
541
543
  }
542
544
  }
543
- const Et = {
545
+ const kt = {
544
546
  ä: "ae",
545
547
  ä: "ae",
546
548
  Ä: "AE",
@@ -576,18 +578,18 @@ const Et = {
576
578
  };
577
579
  function D(i, t = !1) {
578
580
  const e = "daca0510-72b5-48ba-9091-b918ca18136b";
579
- return i = to(i, t), Ye(i, e);
581
+ return i = ao(i, t), oo(i, e);
580
582
  }
581
- function to(i, t = !1) {
583
+ function ao(i, t = !1) {
582
584
  let e = i;
583
- for (const o in Et)
584
- e = e.replace(new RegExp(o, "g"), Et[o]);
585
+ for (const o in kt)
586
+ e = e.replace(new RegExp(o, "g"), kt[o]);
585
587
  return t && e !== i && console.info(`${i} -> ${e}`), e;
586
588
  }
587
- function eo(i, t = "") {
589
+ function io(i, t = "") {
588
590
  return D(`${t}${i}`);
589
591
  }
590
- class k {
592
+ class x {
591
593
  _value;
592
594
  _listeners = /* @__PURE__ */ new Set();
593
595
  constructor(t) {
@@ -646,13 +648,13 @@ const Z = {
646
648
  apiKey: "AIzaSyAiW42QBx9HS4Khu88pCW7MV66IhBAQul0",
647
649
  appId: "1:151132927589:web:d2ffdb377dfadfd23ab88c",
648
650
  measurementId: "G-YT4PK6HGZD"
649
- }, xt = "qaecy-mvp-406413", oo = "734737865998", ie = "europe-west6", It = "projects", Ct = "spaces_chats_eu_west6", St = "spaces_raw_eu_west6", Tt = "spaces_processed_eu_west6", Rt = "spaces_logs_eu_west6", At = "cue_public_eu_west6", Pt = "db_persistence_eu_west6", ro = "/data-views/admin/consumption", so = "/data-views/admin/profile/organizations", Ot = "/data-views/admin/profile/api-keys", Dt = "/commands/admin/profile/api-keys", ao = "/commands/admin/profile/terms", io = (i) => `/data-views/admin/organizations/${i}/members`, no = "/commands/admin/project", po = (i) => `/commands/admin/project/${i}`, lo = "/assistant/search", ne = "/triplestore/query", co = "/triplestore/update", ho = "/triplestore/shacl", pe = "/qlever-server/qlever/query", go = "/qlever-server/qlever/update", uo = "/qlever-server/qlever/shacl", Lt = "/commands/file-system-structure/batch", qt = "microsoft.com", jt = "superadmin", ut = "https://cue.qaecy.com/r/";
650
- class Ut {
651
+ }, xt = "qaecy-mvp-406413", no = "734737865998", le = "europe-west6", Ct = "projects", It = "sessions_eu_west6", St = "spaces_chats_eu_west6", Tt = "spaces_raw_eu_west6", Rt = "spaces_processed_eu_west6", At = "spaces_logs_eu_west6", Pt = "cue_public_eu_west6", Ot = "db_persistence_eu_west6", po = "/data-views/admin/consumption", co = "/data-views/admin/profile/organizations", Dt = "/data-views/admin/profile/api-keys", Lt = "/commands/admin/profile/api-keys", lo = "/commands/admin/profile/terms", ho = (i) => `/data-views/admin/organizations/${i}/members`, go = "/commands/admin/project", uo = (i) => `/commands/admin/project/${i}`, mo = "/assistant/search", he = "/triplestore/query", wo = "/triplestore/update", fo = "/triplestore/shacl", de = "/qlever-server/qlever/query", yo = "/qlever-server/qlever/update", bo = "/qlever-server/qlever/shacl", qt = "/commands/file-system-structure/batch", vo = "/storage/sessions", _o = "/storage/raw", ge = "/storage/processed", jt = "microsoft.com", zt = "superadmin", ut = "https://cue.qaecy.com/r/";
652
+ class $t {
651
653
  _auth;
652
654
  _endpoints;
653
- _userSignal = new k(null);
654
- _tokenSignal = new k(null);
655
- _isSuperAdminSignal = new k(!1);
655
+ _userSignal = new x(null);
656
+ _tokenSignal = new x(null);
657
+ _isSuperAdminSignal = new x(!1);
656
658
  _userIdsSignal;
657
659
  _stopTokenListener;
658
660
  /** Reactive auth state — emits the signed-in `User`, or `null` when signed out. */
@@ -664,19 +666,19 @@ class Ut {
664
666
  /** All unique UIDs for the current user (Firebase UID + linked provider UIDs). */
665
667
  userIds;
666
668
  constructor(t, e = !1, o) {
667
- this._auth = qe(t), this._endpoints = o, e && je(this._auth, o.authEmulatorUrl, {
669
+ this._auth = Me(t), this._endpoints = o, e && Ne(this._auth, o.authEmulatorUrl, {
668
670
  disableWarnings: !0
669
671
  }), this.user = this._userSignal.asReadonly(), this.token = this._tokenSignal.asReadonly(), this.isSuperAdmin = this._isSuperAdminSignal.asReadonly(), this._userIdsSignal = dt([this._userSignal], () => {
670
672
  const r = this._userSignal.get();
671
673
  if (!r) return [];
672
674
  const s = /* @__PURE__ */ new Set([r.uid]);
673
675
  return r.providerData.forEach((a) => s.add(a.uid)), Array.from(s);
674
- }), this.userIds = this._userIdsSignal, this._stopTokenListener = Ue(this._auth, async (r) => {
676
+ }), this.userIds = this._userIdsSignal, this._stopTokenListener = Fe(this._auth, async (r) => {
675
677
  if (this._userSignal.set(r), r) {
676
678
  const s = await r.getIdToken();
677
679
  this._tokenSignal.set(s);
678
680
  const a = await at(r);
679
- this._isSuperAdminSignal.set(a.claims.role === jt);
681
+ this._isSuperAdminSignal.set(a.claims.role === zt);
680
682
  } else
681
683
  this._tokenSignal.set(null), this._isSuperAdminSignal.set(!1);
682
684
  });
@@ -689,14 +691,14 @@ class Ut {
689
691
  if (t === "password") {
690
692
  if (!e)
691
693
  throw new Error("credentials are required for password sign-in");
692
- return (await ze(
694
+ return (await Be(
693
695
  this._auth,
694
696
  e.email,
695
697
  e.password
696
698
  )).user;
697
699
  }
698
- const o = t === "google" ? new it() : new nt(qt);
699
- return (await $e(this._auth, o)).user;
700
+ const o = t === "google" ? new it() : new nt(jt);
701
+ return (await Ge(this._auth, o)).user;
700
702
  }
701
703
  /**
702
704
  * Initiate a redirect-based sign-in (mobile / iframe contexts where popups
@@ -704,8 +706,8 @@ class Ut {
704
706
  * retrieve the result.
705
707
  */
706
708
  async signInWithRedirect(t) {
707
- const e = t === "google" ? new it() : new nt(qt);
708
- await Me(this._auth, e);
709
+ const e = t === "google" ? new it() : new nt(jt);
710
+ await He(this._auth, e);
709
711
  }
710
712
  /**
711
713
  * Retrieve the result of a redirect sign-in. Returns the signed-in `User`
@@ -713,7 +715,7 @@ class Ut {
713
715
  * Call this once on app startup before showing a sign-in UI.
714
716
  */
715
717
  async checkRedirectResult() {
716
- return (await Ne(this._auth))?.user ?? null;
718
+ return (await We(this._auth))?.user ?? null;
717
719
  }
718
720
  /**
719
721
  * One-shot async check — returns `true` if the current user has the
@@ -722,7 +724,7 @@ class Ut {
722
724
  */
723
725
  async checkSuperAdmin() {
724
726
  const t = this._auth.currentUser;
725
- return t ? (await at(t)).claims.role === jt : !1;
727
+ return t ? (await at(t)).claims.role === zt : !1;
726
728
  }
727
729
  /** Sign in with a Cue API key. `projectId` is optional — omit it when no project context is available (e.g. admin flows). */
728
730
  async signInWithApiKey(t, e) {
@@ -743,7 +745,7 @@ class Ut {
743
745
  }
744
746
  /** Sign out the current user */
745
747
  async signOut() {
746
- await Fe(this._auth);
748
+ await Ve(this._auth);
747
749
  }
748
750
  /**
749
751
  * Register a new user by name and email.
@@ -773,7 +775,7 @@ class Ut {
773
775
  }
774
776
  /** Subscribe to authentication state changes. Returns an unsubscribe function. */
775
777
  onAuthStateChanged(t) {
776
- return Be(this._auth, t);
778
+ return Xe(this._auth, t);
777
779
  }
778
780
  /** Get the Firebase ID token for the current user, or null if not authenticated */
779
781
  async getToken(t = !1) {
@@ -805,29 +807,33 @@ class Ut {
805
807
  return this._auth;
806
808
  }
807
809
  }
808
- class zt {
809
- constructor(t) {
810
- this._blob = t;
810
+ const Eo = {
811
+ raw: _o,
812
+ processed: ge
813
+ };
814
+ class Ut {
815
+ constructor(t, e) {
816
+ this._auth = t, this._gatewayUrl = e;
811
817
  }
812
- _blob;
818
+ _auth;
819
+ _gatewayUrl;
813
820
  /**
814
- * Returns a Firebase authenticated download URL for a document stored in Cue.
821
+ * Returns a gateway download URL for a document stored in Cue.
815
822
  *
816
823
  * The storage path is `{projectId}/{uuid}{suffix}`, e.g. `my-project/abc-123.pdf`.
824
+ * The returned URL must be fetched with an Authorization header.
817
825
  *
818
826
  * @param projectId - The Cue project (space) ID.
819
827
  * @param uuid - The document UUID.
820
828
  * @param suffix - File suffix including the leading dot, e.g. `'.pdf'`, `'.ifc'`.
821
829
  * @param bucket - `'raw'` (default, original uploads) or `'processed'` (derived artefacts).
822
830
  */
823
- async getDownloadUrl(t, e, o, r = "raw") {
824
- const s = `${t}/${e}${o}`, a = await this._blob.getDownloadURL(r, s);
825
- if (!a) throw new Error(`File not found in storage: ${s} (bucket: ${r})`);
826
- return a;
831
+ getDownloadUrl(t, e, o, r = "raw") {
832
+ return `${this._gatewayUrl}${Eo[r]}/${t}/${e}${o}`;
827
833
  }
828
834
  /**
829
- * Returns a Firebase authenticated download URL for an alternative representation
830
- * using its full `qcy:remoteRelativePath` stored in the processed bucket.
835
+ * Returns a gateway download URL for an alternative representation using its
836
+ * full `qcy:remoteRelativePath` stored in the processed bucket.
831
837
  *
832
838
  * Use this instead of `getDownloadUrl` when the document info was obtained via
833
839
  * `fetchAlternativeRepresentations` and carries a `remoteRelativePath`.
@@ -835,14 +841,24 @@ class zt {
835
841
  * @param remoteRelativePath - The full path in the processed bucket,
836
842
  * e.g. `{projectId}/fragments/{uuid}.fragments`.
837
843
  */
838
- async getAltRepDownloadUrl(t) {
839
- const e = await this._blob.getDownloadURL("processed", t);
840
- if (!e) throw new Error(`Alternative representation not found in storage: ${t}`);
841
- return e;
844
+ getAltRepDownloadUrl(t) {
845
+ return `${this._gatewayUrl}${ge}/${t}`;
846
+ }
847
+ /**
848
+ * Fetch a file through the gateway and return it as a Blob.
849
+ * Convenience wrapper around `getDownloadUrl` + `authenticatedFetch`.
850
+ */
851
+ async downloadBlob(t, e, o, r = "raw") {
852
+ const s = this.getDownloadUrl(t, e, o, r), a = await this._auth.authenticatedFetch(s, {
853
+ headers: { "cue-project-id": t }
854
+ });
855
+ if (!a.ok)
856
+ throw new Error(`Failed to download file: ${a.status} ${a.statusText}`);
857
+ return a.blob();
842
858
  }
843
859
  }
844
- const mo = "/data-views/tables", wo = "/commands/tables";
845
- class fo {
860
+ const ko = "/data-views/tables", xo = "/commands/tables";
861
+ class Co {
846
862
  constructor(t, e) {
847
863
  this._auth = t, this._gatewayUrl = e;
848
864
  }
@@ -850,7 +866,7 @@ class fo {
850
866
  _gatewayUrl;
851
867
  async listTables(t) {
852
868
  const e = await this._auth.authenticatedFetch(
853
- `${this._gatewayUrl}${mo}`,
869
+ `${this._gatewayUrl}${ko}`,
854
870
  {
855
871
  headers: {
856
872
  "Content-Type": "application/json",
@@ -865,7 +881,7 @@ class fo {
865
881
  }
866
882
  async saveTables(t, e) {
867
883
  const o = await this._auth.authenticatedFetch(
868
- `${this._gatewayUrl}${wo}`,
884
+ `${this._gatewayUrl}${xo}`,
869
885
  {
870
886
  method: "PUT",
871
887
  headers: {
@@ -880,8 +896,8 @@ class fo {
880
896
  throw new Error(`Failed to save tables: ${o.status} ${o.statusText}`);
881
897
  }
882
898
  }
883
- const yo = "/semantic-extraction/extract";
884
- class bo {
899
+ const Io = "/semantic-extraction/extract";
900
+ class So {
885
901
  constructor(t, e) {
886
902
  this._auth = t, this._gatewayUrl = e;
887
903
  }
@@ -898,7 +914,7 @@ class bo {
898
914
  const e = t.rdfFormat ?? "json-ld", o = new FormData();
899
915
  o.append("file", t.image, "page.png"), o.append("template", JSON.stringify(t.template)), o.append("space_id", t.projectId), o.append("rdf_format", e), t.category && o.append("category", t.category), t.text && o.append("text", t.text);
900
916
  const r = await this._auth.authenticatedFetch(
901
- `${this._gatewayUrl}${yo}`,
917
+ `${this._gatewayUrl}${Io}`,
902
918
  {
903
919
  method: "POST",
904
920
  // Do NOT set Content-Type; browser sets it with the correct boundary.
@@ -919,9 +935,38 @@ class bo {
919
935
  return { jsonld: await r.json() };
920
936
  }
921
937
  }
922
- class $t {
938
+ class To {
939
+ constructor(t, e) {
940
+ this._auth = t, this._gatewayUrl = e;
941
+ }
942
+ _auth;
943
+ _gatewayUrl;
944
+ /**
945
+ * Fetch and decompress a session context document.
946
+ *
947
+ * Context files are stored as `sessions_eu_west6/{projectId}/contexts/{contextId}.json.gz`
948
+ * and served via the gateway at `GET /storage/sessions/{projectId}/contexts/{contextId}.json.gz`.
949
+ *
950
+ * @param projectId - The project the context belongs to.
951
+ * @param contextId - The context document ID (without the `.json.gz` suffix).
952
+ */
953
+ async getContext(t, e) {
954
+ const o = `${this._gatewayUrl}${vo}/${t}/contexts/${e}.json.gz`, r = await this._auth.authenticatedFetch(o, {
955
+ headers: {
956
+ "cue-project-id": t,
957
+ // Prevent the HTTP layer from auto-decompressing so we can handle it explicitly.
958
+ "Accept-Encoding": "identity"
959
+ }
960
+ });
961
+ if (!r.ok)
962
+ throw new Error(`Failed to fetch context ${e}: ${r.status} ${r.statusText}`);
963
+ const s = new DecompressionStream("gzip"), a = r.body.pipeThrough(s);
964
+ return JSON.parse(await new Response(a).text());
965
+ }
966
+ }
967
+ class Mt {
923
968
  constructor(t, e, o, r) {
924
- this._auth = t, this._gatewayUrl = e, this.projects = o, this.sync = r, this.tables = new fo(t, e), this.extraction = new bo(t, e);
969
+ this._auth = t, this._gatewayUrl = e, this.projects = o, this.sync = r, this.tables = new Co(t, e), this.extraction = new So(t, e), this.contexts = new To(t, e);
925
970
  }
926
971
  _auth;
927
972
  _gatewayUrl;
@@ -930,6 +975,8 @@ class $t {
930
975
  tables;
931
976
  /** Semantic extraction client — call document pages against a SemanticTemplate. */
932
977
  extraction;
978
+ /** Session context file client — fetch and decompress context documents. */
979
+ contexts;
933
980
  /** Active language used for language-sensitive SPARQL queries across all project classes. */
934
981
  language = "en";
935
982
  /** Updates the active language. All project classes (`CueProjectSchema`, `CueProjectDocuments`, `CueProjectEntities`) read this at query time. */
@@ -955,7 +1002,7 @@ class $t {
955
1002
  */
956
1003
  async search(t) {
957
1004
  const e = await this._auth.authenticatedFetch(
958
- `${this._gatewayUrl}${lo}`,
1005
+ `${this._gatewayUrl}${mo}`,
959
1006
  {
960
1007
  method: "POST",
961
1008
  headers: { "Content-Type": "application/json", "cue-project-id": t.projectId },
@@ -978,7 +1025,7 @@ class $t {
978
1025
  */
979
1026
  async sparql(t, e, o) {
980
1027
  o || (o = (await this.projects.getProject(e))?.projectSettings?.graph?.type ?? "qlever");
981
- const r = o === "fuseki" ? ne : pe;
1028
+ const r = o === "fuseki" ? he : de;
982
1029
  console.log(`Executing SPARQL query against ${r} for project ${e} with graph type ${o}`);
983
1030
  const s = new URLSearchParams();
984
1031
  s.append("query", t);
@@ -1015,7 +1062,7 @@ class $t {
1015
1062
  const r = o?.format ?? "json-ld", s = r === "turtle" ? "text/turtle" : "application/ld+json";
1016
1063
  if (o?.graphType === "fuseki") {
1017
1064
  const c = await this._auth.authenticatedFetch(
1018
- `${this._gatewayUrl}${ho}`,
1065
+ `${this._gatewayUrl}${fo}`,
1019
1066
  {
1020
1067
  method: "POST",
1021
1068
  headers: {
@@ -1033,7 +1080,7 @@ class $t {
1033
1080
  }
1034
1081
  return r === "turtle" ? c.text() : c.json();
1035
1082
  }
1036
- const a = `${this._gatewayUrl}${uo}${o?.verbose ? "?verbose=true" : ""}`, n = new URLSearchParams({ shape: t }), p = await this._auth.authenticatedFetch(a, {
1083
+ const a = `${this._gatewayUrl}${bo}${o?.verbose ? "?verbose=true" : ""}`, n = new URLSearchParams({ shape: t }), p = await this._auth.authenticatedFetch(a, {
1037
1084
  method: "POST",
1038
1085
  headers: {
1039
1086
  "Content-Type": "application/x-www-form-urlencoded",
@@ -1051,7 +1098,7 @@ class $t {
1051
1098
  }
1052
1099
  async getConsumption(t) {
1053
1100
  const e = await this._auth.authenticatedFetch(
1054
- `${this._gatewayUrl}${ro}`,
1101
+ `${this._gatewayUrl}${po}`,
1055
1102
  {
1056
1103
  headers: {
1057
1104
  "Content-Type": "application/json",
@@ -1078,13 +1125,13 @@ const pt = [
1078
1125
  "railway",
1079
1126
  "natural",
1080
1127
  "manmade"
1081
- ], le = [
1128
+ ], ue = [
1082
1129
  "address",
1083
1130
  "poi",
1084
1131
  "railway",
1085
1132
  "natural",
1086
1133
  "manmade"
1087
- ], vo = {
1134
+ ], Ro = {
1088
1135
  address: {
1089
1136
  category: "address",
1090
1137
  label: "Address",
@@ -1147,9 +1194,9 @@ const pt = [
1147
1194
  }
1148
1195
  };
1149
1196
  function T(i) {
1150
- return vo[i];
1197
+ return Ro[i];
1151
1198
  }
1152
- const _o = {
1199
+ const Ao = {
1153
1200
  "land-use-plan": "#f59e0b",
1154
1201
  // amber – primary zoning
1155
1202
  "local-plan": "#ec4899",
@@ -1180,7 +1227,7 @@ const _o = {
1180
1227
  function M(i, t) {
1181
1228
  return i[0] < t[2] && i[2] > t[0] && i[1] < t[3] && i[3] > t[1];
1182
1229
  }
1183
- const ko = "https://nominatim.openstreetmap.org", Eo = "cue-gis/0.0.1", xo = {
1230
+ const Po = "https://nominatim.openstreetmap.org", Oo = "cue-gis/0.0.1", Do = {
1184
1231
  address: "street",
1185
1232
  poi: "shop",
1186
1233
  railway: "station",
@@ -1195,7 +1242,7 @@ const ko = "https://nominatim.openstreetmap.org", Eo = "cue-gis/0.0.1", xo = {
1195
1242
  function B(i) {
1196
1243
  return `${L}:${i}`;
1197
1244
  }
1198
- function Io(i) {
1245
+ function Lo(i) {
1199
1246
  const t = T(i);
1200
1247
  return {
1201
1248
  id: B(i),
@@ -1210,17 +1257,17 @@ function Io(i) {
1210
1257
  descriptionKey: `gis.layer.${L}.${i}.description`
1211
1258
  };
1212
1259
  }
1213
- class Co {
1260
+ class qo {
1214
1261
  baseUrl;
1215
1262
  userAgent;
1216
1263
  email;
1217
1264
  limit;
1218
1265
  constructor(t = {}) {
1219
- this.baseUrl = t.baseUrl ?? ko, this.userAgent = t.userAgent ?? Eo, this.email = t.email, this.limit = Math.min(t.limit ?? 40, 40);
1266
+ this.baseUrl = t.baseUrl ?? Po, this.userAgent = t.userAgent ?? Oo, this.email = t.email, this.limit = Math.min(t.limit ?? 40, 40);
1220
1267
  }
1221
1268
  async listFeatureCategoryDescriptors(t) {
1222
1269
  return (await Promise.allSettled(
1223
- le.map(async (o) => {
1270
+ ue.map(async (o) => {
1224
1271
  const r = await this.search(t, o);
1225
1272
  return { category: o, hasResults: r.length > 0 };
1226
1273
  })
@@ -1229,7 +1276,7 @@ class Co {
1229
1276
  ).map((o) => T(o.value.category));
1230
1277
  }
1231
1278
  async listAvailableLayers(t) {
1232
- return (await this.listFeatureCategoryDescriptors(t)).map((o) => Io(o.category));
1279
+ return (await this.listFeatureCategoryDescriptors(t)).map((o) => Lo(o.category));
1233
1280
  }
1234
1281
  async getFeaturesForLayer(t, e) {
1235
1282
  const o = pt.find((r) => B(r) === e);
@@ -1246,7 +1293,7 @@ class Co {
1246
1293
  * so bounded viewbox searches return meaningful results.
1247
1294
  */
1248
1295
  async search(t, e) {
1249
- const [o, r, s, a] = t, n = e ? xo[e] : "place", p = new URLSearchParams({
1296
+ const [o, r, s, a] = t, n = e ? Do[e] : "place", p = new URLSearchParams({
1250
1297
  q: n,
1251
1298
  format: "jsonv2",
1252
1299
  viewbox: `${o},${a},${s},${r}`,
@@ -1289,7 +1336,7 @@ class Co {
1289
1336
  };
1290
1337
  }
1291
1338
  }
1292
- const Mt = {
1339
+ const Nt = {
1293
1340
  // 100s – Residential
1294
1341
  110: "residential",
1295
1342
  120: "residential",
@@ -1368,7 +1415,7 @@ const Mt = {
1368
1415
  960: "agricultural",
1369
1416
  970: "agricultural",
1370
1417
  990: "other"
1371
- }, Nt = {
1418
+ }, Ft = {
1372
1419
  1010: "residential",
1373
1420
  1020: "mixed",
1374
1421
  1030: "residential",
@@ -1398,7 +1445,7 @@ const Mt = {
1398
1445
  1281: "infrastructure",
1399
1446
  1282: "infrastructure",
1400
1447
  9999: "other"
1401
- }, So = {
1448
+ }, jo = {
1402
1449
  // Residential
1403
1450
  1110: "residential",
1404
1451
  // Einfamilienhaus
@@ -1460,7 +1507,7 @@ const Mt = {
1460
1507
  // Empfangsgebäude Bahn/Bus
1461
1508
  1282: "infrastructure"
1462
1509
  // Parkhaus, Garage
1463
- }, To = [
1510
+ }, zo = [
1464
1511
  // "Gebäude" is the Swiss AV BoFlaeche land-cover label for a building footprint.
1465
1512
  // It does not encode the actual use type, so map it to 'other' as a safe fallback.
1466
1513
  [/^geb[äa]ude$/i, "other"],
@@ -1474,22 +1521,22 @@ const Mt = {
1474
1521
  [/gemischt|mixed|blandet/i, "mixed"]
1475
1522
  ];
1476
1523
  function O(i) {
1477
- for (const [t, e] of To)
1524
+ for (const [t, e] of zo)
1478
1525
  if (t.test(i)) return e;
1479
1526
  }
1480
- function Ro(i, t) {
1527
+ function $o(i, t) {
1481
1528
  if (i == null) return;
1482
1529
  const e = String(i).trim();
1483
- return t === "swiss-gwr" ? So[e] ?? O(e) : t === "danish-matrikel" ? Mt[e] ?? O(e) : t === "zurich-wfs" || t === "swiss-av-wfs" ? Nt[e] ?? O(e) : Nt[e] ?? Mt[e] ?? O(e);
1530
+ return t === "swiss-gwr" ? jo[e] ?? O(e) : t === "danish-matrikel" ? Nt[e] ?? O(e) : t === "zurich-wfs" || t === "swiss-av-wfs" ? Ft[e] ?? O(e) : Ft[e] ?? Nt[e] ?? O(e);
1484
1531
  }
1485
- function Ao(i, t) {
1532
+ function Uo(i, t) {
1486
1533
  if (i != null)
1487
1534
  return O(String(i).trim());
1488
1535
  }
1489
- function ce(i) {
1536
+ function me(i) {
1490
1537
  return i.trim().toLowerCase().replace(/[\s_\-]/g, "");
1491
1538
  }
1492
- const Po = {
1539
+ const Mo = {
1493
1540
  // Swiss ÖREB rechtsstatus
1494
1541
  inkraft: "in-force",
1495
1542
  laufendeanderung: "amendment-pending",
@@ -1508,11 +1555,11 @@ const Po = {
1508
1555
  forslag: "proposed",
1509
1556
  aflyst: "repealed"
1510
1557
  };
1511
- function he(i) {
1558
+ function we(i) {
1512
1559
  if (i)
1513
- return Po[ce(i)];
1560
+ return Mo[me(i)];
1514
1561
  }
1515
- const Ft = {
1562
+ const Bt = {
1516
1563
  // Swiss Nutzungsplanung (typ_gde_bezeichnung and common variants)
1517
1564
  grundnutzungszonenplan: "land-use-plan",
1518
1565
  nutzungszonenplan: "land-use-plan",
@@ -1566,7 +1613,7 @@ const Ft = {
1566
1613
  // Danish plandata.dk
1567
1614
  lokalplan: "local-plan",
1568
1615
  kommuneplanramme: "municipal-plan-framework"
1569
- }, Oo = [
1616
+ }, No = [
1570
1617
  [/quartiererhalt/i, "neighbourhood-conservation-plan"],
1571
1618
  [/lärmempfindlich|laermempfindlich/i, "noise-sensitivity-plan"],
1572
1619
  [/gewässerschutz|grundwasserschutz/i, "water-protection-plan"],
@@ -1606,24 +1653,24 @@ const Ft = {
1606
1653
  // Catch-all: any remaining Xzone / Xareal designation from the Grundnutzungszonenplan
1607
1654
  [/zone$|areal$/i, "land-use-plan"]
1608
1655
  ];
1609
- function de(i) {
1656
+ function fe(i) {
1610
1657
  if (!i) return;
1611
- const t = ce(i);
1612
- if (t in Ft) return Ft[t];
1613
- for (const [e, o] of Oo)
1658
+ const t = me(i);
1659
+ if (t in Bt) return Bt[t];
1660
+ for (const [e, o] of No)
1614
1661
  if (e.test(i)) return o;
1615
1662
  console.warn(
1616
1663
  `[cue-gis] Unknown zone plan type — add "${i}" to classifyZonePlanType: no ZonePlanType mapping found.`
1617
1664
  );
1618
1665
  }
1619
- const Do = "https://maps.zh.ch/wfs/OGDZHWFS", Lo = "zurich-wfs", qo = [8.35, 47.15, 8.95, 47.7], jo = [5.9, 45.7, 10.55, 47.85];
1666
+ const Fo = "https://maps.zh.ch/wfs/OGDZHWFS", Bo = "zurich-wfs", Go = [8.35, 47.15, 8.95, 47.7], Ho = [5.9, 45.7, 10.55, 47.85];
1620
1667
  function J(i) {
1621
1668
  return typeof i == "string" ? i : i.typeName;
1622
1669
  }
1623
1670
  function tt(i) {
1624
1671
  return typeof i == "string" ? void 0 : i.cqlFilter;
1625
1672
  }
1626
- function Uo(i) {
1673
+ function Wo(i) {
1627
1674
  if (!i) return [0, 0];
1628
1675
  const t = i.coordinates;
1629
1676
  switch (i.type) {
@@ -1641,20 +1688,20 @@ function Uo(i) {
1641
1688
  return [0, 0];
1642
1689
  }
1643
1690
  }
1644
- function zo(i, t) {
1691
+ function Vo(i, t) {
1645
1692
  if (!i) return t;
1646
1693
  for (const e of ["plannavn", "bezeichnung", "name", "strassenname", "objektname", "title", "label"])
1647
1694
  if (typeof i[e] == "string" && i[e]) return i[e];
1648
1695
  return t;
1649
1696
  }
1650
- function $o(i, t, e) {
1697
+ function Xo(i, t, e) {
1651
1698
  return e ? `${i}:${t}[${e}]` : `${i}:${t}`;
1652
1699
  }
1653
- const Mo = /* @__PURE__ */ new Set(["building", "cadastre", "greenspace", "paved", "zone"]);
1700
+ const Ko = /* @__PURE__ */ new Set(["building", "cadastre", "greenspace", "paved", "zone"]);
1654
1701
  function et(i, t, e, o) {
1655
- const r = e.replace(/^ms:/, ""), s = T(t), a = Mo.has(t) ? "priority" : "raw";
1702
+ const r = e.replace(/^ms:/, ""), s = T(t), a = Ko.has(t) ? "priority" : "raw";
1656
1703
  return {
1657
- id: $o(i, e, o),
1704
+ id: Xo(i, e, o),
1658
1705
  sourceId: i,
1659
1706
  sourceLayerId: e,
1660
1707
  category: t,
@@ -1666,32 +1713,32 @@ function et(i, t, e, o) {
1666
1713
  descriptionKey: `gis.layer.${i}.${r}.description`
1667
1714
  };
1668
1715
  }
1669
- function No(i, t) {
1716
+ function Qo(i, t) {
1670
1717
  if (!i) return { featureType: "building" };
1671
1718
  const e = i.grundflaeche ?? i.gbf ?? i.gebaeudegrundrissflaeche ?? i.flaeche ?? void 0, o = i.vollgeschosse ?? i.geschossanzahl ?? i.anzahl_geschosse ?? void 0, r = i.gebaeudefunktion ?? i.gfkode ?? i.art ?? i.objektart ?? void 0, s = i.baujahr ?? i.bauperiode ?? void 0, a = String(i.egid ?? i.gwr_egid ?? i.egris_egid ?? "").trim() || void 0;
1672
1719
  return {
1673
1720
  featureType: "building",
1674
1721
  areaM2: typeof e == "number" ? e : void 0,
1675
1722
  buildingUse: r ? String(r) : void 0,
1676
- buildingUseGeneric: Ro(r, t),
1723
+ buildingUseGeneric: $o(r, t),
1677
1724
  floors: typeof o == "number" ? o : void 0,
1678
1725
  yearBuilt: typeof s == "number" ? s : void 0,
1679
1726
  registryId: a
1680
1727
  };
1681
1728
  }
1682
- function Fo(i, t) {
1729
+ function Yo(i, t) {
1683
1730
  if (!i) return { featureType: "plot" };
1684
1731
  const e = i.egris_egrid ?? i.egrid ?? void 0, o = i.nummer ?? void 0, r = i.nbident ?? void 0, s = o && r ? `${o}, ${r}` : o ?? void 0, a = i.flaechenmass ?? i.flaeche ?? void 0, n = i.art ?? i.nutzungsart ?? void 0;
1685
1732
  return {
1686
1733
  featureType: "plot",
1687
1734
  areaM2: typeof a == "number" ? a : void 0,
1688
1735
  plotUse: n ? String(n) : void 0,
1689
- plotUseGeneric: Ao(n),
1736
+ plotUseGeneric: Uo(n),
1690
1737
  plotId: s,
1691
1738
  registryId: e
1692
1739
  };
1693
1740
  }
1694
- function Bo(i) {
1741
+ function Zo(i) {
1695
1742
  if (!i) return { featureType: "greenspace" };
1696
1743
  const t = i.flaeche ?? void 0, e = i.art ?? void 0;
1697
1744
  return {
@@ -1700,7 +1747,7 @@ function Bo(i) {
1700
1747
  surfaceType: e ? String(e) : void 0
1701
1748
  };
1702
1749
  }
1703
- function Go(i) {
1750
+ function Jo(i) {
1704
1751
  if (!i) return { featureType: "paved" };
1705
1752
  const t = i.flaeche ?? void 0, e = i.art ?? void 0;
1706
1753
  return {
@@ -1709,9 +1756,9 @@ function Go(i) {
1709
1756
  surfaceType: e ? String(e) : void 0
1710
1757
  };
1711
1758
  }
1712
- function Ho(i) {
1759
+ function tr(i) {
1713
1760
  if (!i) return { featureType: "zone" };
1714
- const t = i.plannavn ?? i.bezeichnung ?? i.typ_bezeichnung ?? i.art ?? void 0, e = i.planid ?? i.plannummer ?? void 0, o = i.artcode ?? i.typ_code ?? i.abkuerzung ?? e ?? void 0, r = i.rechtsstatus ?? i.status ?? void 0, s = he(r), a = i.typ_gde_bezeichnung ?? void 0, n = de(a), p = i.dagsordenpunkt_url ?? i.dokument_url ?? i.link ?? void 0, c = i.auflagedatum ?? void 0, h = i.festsetzungsdatum ?? void 0, d = i.genehmigungsdatum ?? void 0, g = i.inkraftsetzungsdatum ?? void 0, u = i.flaeche ?? i.flaeche_m2 ?? void 0;
1761
+ const t = i.plannavn ?? i.bezeichnung ?? i.typ_bezeichnung ?? i.art ?? void 0, e = i.planid ?? i.plannummer ?? void 0, o = i.artcode ?? i.typ_code ?? i.abkuerzung ?? e ?? void 0, r = i.rechtsstatus ?? i.status ?? void 0, s = we(r), a = i.typ_gde_bezeichnung ?? void 0, n = fe(a), p = i.dagsordenpunkt_url ?? i.dokument_url ?? i.link ?? void 0, c = i.auflagedatum ?? void 0, h = i.festsetzungsdatum ?? void 0, d = i.genehmigungsdatum ?? void 0, g = i.inkraftsetzungsdatum ?? void 0, u = i.flaeche ?? i.flaeche_m2 ?? void 0;
1715
1762
  return {
1716
1763
  featureType: "zone",
1717
1764
  zoneType: t ? String(t) : void 0,
@@ -1727,7 +1774,7 @@ function Ho(i) {
1727
1774
  areaM2: typeof u == "number" ? u : void 0
1728
1775
  };
1729
1776
  }
1730
- function Wo(i) {
1777
+ function er(i) {
1731
1778
  const t = i.match(/^(\w+)\s*=\s*'([^']+)'$/);
1732
1779
  if (t) {
1733
1780
  const [, o, r] = t;
@@ -1748,7 +1795,7 @@ class ot {
1748
1795
  sourceId;
1749
1796
  outputFormat;
1750
1797
  constructor(t) {
1751
- this.categoryMap = t.categoryMap, this.baseUrl = t.baseUrl ?? Do, this.sourceId = t.sourceId ?? Lo, this.outputFormat = t.outputFormat ?? "application/json; subtype=geojson";
1798
+ this.categoryMap = t.categoryMap, this.baseUrl = t.baseUrl ?? Fo, this.sourceId = t.sourceId ?? Bo, this.outputFormat = t.outputFormat ?? "application/json; subtype=geojson";
1752
1799
  }
1753
1800
  async listFeatureCategoryDescriptors(t) {
1754
1801
  const e = await this.listAvailableLayers(t);
@@ -1772,7 +1819,7 @@ class ot {
1772
1819
  return o ? this._fetchAndConvert(t, o.descriptor, o.cqlFilter) : [];
1773
1820
  }
1774
1821
  async _fetchAndConvert(t, e, o) {
1775
- const r = await this._fetchFeatures(t, e.sourceLayerId, void 0, o), s = o ? Wo(o) : void 0;
1822
+ const r = await this._fetchFeatures(t, e.sourceLayerId, void 0, o), s = o ? er(o) : void 0;
1776
1823
  return (s ? r.features.filter((n) => s(n.properties)) : r.features).map((n, p) => this.toGisFeature(n, e, p));
1777
1824
  }
1778
1825
  /**
@@ -1821,7 +1868,7 @@ class ot {
1821
1868
  return g.json();
1822
1869
  }
1823
1870
  toGisFeature(t, e, o) {
1824
- const [r, s] = Uo(t.geometry), a = zo(t.properties, `${e.sourceLayerId}[${o}]`), n = t.bbox ? [t.bbox[0], t.bbox[1], t.bbox[2], t.bbox[3]] : void 0, p = e.tier, c = p === "priority" ? this._extractNormalisedProperties(t, e) : void 0;
1871
+ const [r, s] = Wo(t.geometry), a = Vo(t.properties, `${e.sourceLayerId}[${o}]`), n = t.bbox ? [t.bbox[0], t.bbox[1], t.bbox[2], t.bbox[3]] : void 0, p = e.tier, c = p === "priority" ? this._extractNormalisedProperties(t, e) : void 0;
1825
1872
  return {
1826
1873
  id: t.id ?? `${e.sourceLayerId}/${o}`,
1827
1874
  preferredColor: e.preferredColor,
@@ -1842,10 +1889,10 @@ class ot {
1842
1889
  };
1843
1890
  }
1844
1891
  _extractNormalisedProperties(t, e) {
1845
- return e.category === "building" ? No(t.properties, this.sourceId) : e.category === "greenspace" ? Bo(t.properties) : e.category === "paved" ? Go(t.properties) : e.category === "zone" ? Ho(t.properties) : Fo(t.properties, this.sourceId);
1892
+ return e.category === "building" ? Qo(t.properties, this.sourceId) : e.category === "greenspace" ? Zo(t.properties) : e.category === "paved" ? Jo(t.properties) : e.category === "zone" ? tr(t.properties) : Yo(t.properties, this.sourceId);
1846
1893
  }
1847
1894
  }
1848
- const ge = [8, 54.5, 15.2, 57.8], ue = {
1895
+ const ye = [8, 54.5, 15.2, 57.8], be = {
1849
1896
  building: [
1850
1897
  { source: "danish-matrikel", typename: "bbr_v001:bygning_current" }
1851
1898
  ],
@@ -1854,7 +1901,7 @@ const ge = [8, 54.5, 15.2, 57.8], ue = {
1854
1901
  { source: "danish-matrikel", typename: "mat_v001:samletfastejendom_current" }
1855
1902
  ]
1856
1903
  };
1857
- function Vo(i) {
1904
+ function or(i) {
1858
1905
  if (!i) return [0, 0];
1859
1906
  const t = i.coordinates;
1860
1907
  switch (i.type) {
@@ -1872,7 +1919,7 @@ function Vo(i) {
1872
1919
  return [0, 0];
1873
1920
  }
1874
1921
  }
1875
- function Ko(i, t) {
1922
+ function rr(i, t) {
1876
1923
  if (!i) return t;
1877
1924
  for (const e of [
1878
1925
  "mat:matrikelnummer",
@@ -1888,14 +1935,14 @@ function Ko(i, t) {
1888
1935
  if (typeof i[e] == "string" && i[e]) return i[e];
1889
1936
  return t;
1890
1937
  }
1891
- function Xo(i, t, e) {
1938
+ function sr(i, t, e) {
1892
1939
  return `${i}:${t}:${e}`;
1893
1940
  }
1894
- const Qo = /* @__PURE__ */ new Set(["building", "cadastre", "zone"]);
1941
+ const ar = /* @__PURE__ */ new Set(["building", "cadastre", "zone"]);
1895
1942
  function rt(i, t, e) {
1896
- const o = e.typename.replace(/^[^:]+:/, ""), r = T(t), s = Qo.has(t) ? "priority" : "raw";
1943
+ const o = e.typename.replace(/^[^:]+:/, ""), r = T(t), s = ar.has(t) ? "priority" : "raw";
1897
1944
  return {
1898
- id: Xo(i, e.source, e.typename),
1945
+ id: sr(i, e.source, e.typename),
1899
1946
  sourceId: i,
1900
1947
  sourceLayerId: e.typename,
1901
1948
  category: t,
@@ -1907,7 +1954,7 @@ function rt(i, t, e) {
1907
1954
  descriptionKey: `gis.layer.${i}.${e.source}.${o}.description`
1908
1955
  };
1909
1956
  }
1910
- function Yo(i, t) {
1957
+ function ir(i, t) {
1911
1958
  if (t === "building") {
1912
1959
  const a = i?.byg041BebyggetAreal ?? i?.byg038SamletBygningsareal, n = i?.byg021BygningensAnvendelse, p = i?.id_lokalId, c = i?.byg026Opførelsesår;
1913
1960
  return {
@@ -1924,8 +1971,8 @@ function Yo(i, t) {
1924
1971
  featureType: "zone",
1925
1972
  zoneType: a ?? void 0,
1926
1973
  zoneCode: p ?? void 0,
1927
- legalStatus: he(c),
1928
- planType: de(i?.typ_gde_bezeichnung),
1974
+ legalStatus: we(c),
1975
+ planType: fe(i?.typ_gde_bezeichnung),
1929
1976
  planId: n ?? void 0,
1930
1977
  planDocumentLink: h ?? void 0,
1931
1978
  publicationDate: i?.auflagedatum ?? void 0,
@@ -1943,13 +1990,13 @@ function Yo(i, t) {
1943
1990
  registryId: s ?? void 0
1944
1991
  };
1945
1992
  }
1946
- class Zo {
1993
+ class nr {
1947
1994
  categoryMap;
1948
1995
  dataViewsBaseUrl;
1949
1996
  getHeaders;
1950
1997
  sourceId;
1951
1998
  constructor(t) {
1952
- this.dataViewsBaseUrl = t.dataViewsBaseUrl.replace(/\/$/, ""), this.getHeaders = t.getHeaders, this.categoryMap = t.categoryMap ?? ue, this.sourceId = t.sourceId ?? "cue-sdk-gis";
1999
+ this.dataViewsBaseUrl = t.dataViewsBaseUrl.replace(/\/$/, ""), this.getHeaders = t.getHeaders, this.categoryMap = t.categoryMap ?? be, this.sourceId = t.sourceId ?? "cue-sdk-gis";
1953
2000
  }
1954
2001
  async listFeatureCategoryDescriptors(t) {
1955
2002
  const e = await this.listAvailableLayers(t);
@@ -2012,7 +2059,7 @@ class Zo {
2012
2059
  return d.json();
2013
2060
  }
2014
2061
  _toGisFeature(t, e, o) {
2015
- const [r, s] = Vo(t.geometry), a = t.id ?? `${e.sourceLayerId}/${o}`, n = Ko(t.properties, a), p = t.bbox ? [t.bbox[0], t.bbox[1], t.bbox[2], t.bbox[3]] : void 0, c = e.tier, h = c === "priority" ? Yo(t.properties, e.category) : void 0;
2062
+ const [r, s] = or(t.geometry), a = t.id ?? `${e.sourceLayerId}/${o}`, n = rr(t.properties, a), p = t.bbox ? [t.bbox[0], t.bbox[1], t.bbox[2], t.bbox[3]] : void 0, c = e.tier, h = c === "priority" ? ir(t.properties, e.category) : void 0;
2016
2063
  return {
2017
2064
  id: a,
2018
2065
  sourceId: this.sourceId,
@@ -2033,7 +2080,7 @@ class Zo {
2033
2080
  };
2034
2081
  }
2035
2082
  }
2036
- const Jo = {
2083
+ const pr = {
2037
2084
  address: [
2038
2085
  "ms:ogd-0406_arv_basis_avzh_hausnummer_pos_p",
2039
2086
  "ms:ogd-0571_afv_gv_strat_strassennetz_l"
@@ -2081,19 +2128,19 @@ const Jo = {
2081
2128
  // ÖREB Überlagernde Festlegungen (Flächen) – overlaying planning constraints
2082
2129
  "ms:ogd-0155_arv_basis_np_ul_flaeche_f"
2083
2130
  ]
2084
- }, me = [
2131
+ }, ve = [
2085
2132
  {
2086
2133
  name: "Canton of Zürich",
2087
- coverageBBox: qo,
2134
+ coverageBBox: Go,
2088
2135
  supportedCategories: ["address", "poi", "railway", "natural", "manmade", "building", "cadastre", "greenspace", "paved", "zone"],
2089
2136
  priority: 10,
2090
2137
  adapter: new ot({
2091
- categoryMap: Jo
2138
+ categoryMap: pr
2092
2139
  })
2093
2140
  },
2094
2141
  {
2095
2142
  name: "Switzerland (national AV cadastre)",
2096
- coverageBBox: jo,
2143
+ coverageBBox: Ho,
2097
2144
  supportedCategories: ["cadastre"],
2098
2145
  priority: 5,
2099
2146
  // Lower priority than canton-specific adapters. For ZH, the canton adapter (priority 10) wins.
@@ -2121,7 +2168,7 @@ const Jo = {
2121
2168
  * - `pdk:kommuneplanramme_vedtaget` – adopted municipal plan frameworks
2122
2169
  */
2123
2170
  name: "Denmark (Plandata.dk – planning zones)",
2124
- coverageBBox: ge,
2171
+ coverageBBox: ye,
2125
2172
  supportedCategories: ["zone"],
2126
2173
  priority: 10,
2127
2174
  adapter: new ot({
@@ -2139,12 +2186,12 @@ const Jo = {
2139
2186
  })
2140
2187
  }
2141
2188
  ];
2142
- function Bt(i) {
2189
+ function Gt(i) {
2143
2190
  return [...i].sort(
2144
2191
  (t, e) => pt.indexOf(t.category) - pt.indexOf(e.category)
2145
2192
  );
2146
2193
  }
2147
- class tr {
2194
+ class cr {
2148
2195
  nominatim;
2149
2196
  regions;
2150
2197
  /**
@@ -2159,9 +2206,9 @@ class tr {
2159
2206
  zonePlanTypeColors: r,
2160
2207
  ...s
2161
2208
  } = t;
2162
- this.nominatim = new Co(s);
2163
- const a = o ? me : [];
2164
- this.regions = e ?? a, this.zonePlanTypeColors = { ..._o, ...r };
2209
+ this.nominatim = new qo(s);
2210
+ const a = o ? ve : [];
2211
+ this.regions = e ?? a, this.zonePlanTypeColors = { ...Ao, ...r };
2165
2212
  }
2166
2213
  /**
2167
2214
  * Return the available feature categories together with UI metadata such as
@@ -2180,12 +2227,12 @@ class tr {
2180
2227
  for (const a of e)
2181
2228
  for (const n of a.supportedCategories ?? [])
2182
2229
  r.has(n) || (r.add(n), s.push(T(n)));
2183
- for (const a of le)
2230
+ for (const a of ue)
2184
2231
  r.has(a) || s.push(T(a));
2185
- return Bt(s);
2232
+ return Gt(s);
2186
2233
  }
2187
2234
  const o = await this._adapterFor(t).listFeatureCategoryDescriptors(t);
2188
- return Bt(o);
2235
+ return Gt(o);
2189
2236
  }
2190
2237
  /**
2191
2238
  * Return the feature categories that have at least one result within the
@@ -2258,7 +2305,7 @@ class tr {
2258
2305
  const { features: n, idx: p } = await Promise.race(a.values());
2259
2306
  a.delete(p);
2260
2307
  for (const c of n) {
2261
- const h = Gt(c), d = W(c), g = s.get(h);
2308
+ const h = Ht(c), d = W(c), g = s.get(h);
2262
2309
  (g === void 0 || d > g) && (s.set(h, d), yield c);
2263
2310
  }
2264
2311
  }
@@ -2292,9 +2339,9 @@ class tr {
2292
2339
  ), a = [], n = [];
2293
2340
  for (const d of s)
2294
2341
  d.status === "fulfilled" && (d.value.isNominatim ? n.push(...d.value.features) : a.push(...d.value.features));
2295
- const p = rr(a, n), c = /* @__PURE__ */ new Map(), h = [];
2342
+ const p = dr(a, n), c = /* @__PURE__ */ new Map(), h = [];
2296
2343
  for (const d of p) {
2297
- const g = Gt(d), u = W(d), m = c.get(g);
2344
+ const g = Ht(d), u = W(d), m = c.get(g);
2298
2345
  (m === void 0 || u > m) && (c.set(g, u), h.push(d));
2299
2346
  }
2300
2347
  return h;
@@ -2312,22 +2359,22 @@ function W(i) {
2312
2359
  const t = i.geometry?.type;
2313
2360
  return t === "Polygon" || t === "MultiPolygon" ? 3 : t === "LineString" || t === "MultiLineString" ? 2 : 1;
2314
2361
  }
2315
- function Gt(i) {
2362
+ function Ht(i) {
2316
2363
  const t = Math.round(i.lat * 1e3) / 1e3, e = Math.round(i.lon * 1e3) / 1e3;
2317
2364
  return `${(i.name ?? i.id ?? "").toLowerCase().trim()}|${t}|${e}`;
2318
2365
  }
2319
- const er = 1e-3;
2320
- function or(i, t) {
2366
+ const lr = 1e-3;
2367
+ function hr(i, t) {
2321
2368
  const e = i.lat - t.lat, o = i.lon - t.lon;
2322
2369
  return Math.sqrt(e * e + o * o);
2323
2370
  }
2324
- function rr(i, t) {
2371
+ function dr(i, t) {
2325
2372
  if (t.length === 0) return i;
2326
2373
  const e = i.filter((a) => W(a) === 3), o = i.filter((a) => W(a) !== 3), r = e.map((a) => ({ feature: { ...a, originalData: { ...a.originalData } }, matched: !1 })), s = [];
2327
2374
  for (const a of t) {
2328
- let n = -1, p = er;
2375
+ let n = -1, p = lr;
2329
2376
  for (let c = 0; c < r.length; c++) {
2330
- const h = or(a, r[c].feature);
2377
+ const h = hr(a, r[c].feature);
2331
2378
  h < p && (p = h, n = c);
2332
2379
  }
2333
2380
  n >= 0 ? (r[n].feature.originalData = {
@@ -2341,8 +2388,8 @@ function rr(i, t) {
2341
2388
  ...s
2342
2389
  ];
2343
2390
  }
2344
- const sr = "/data-views", ar = 1500;
2345
- class ir {
2391
+ const gr = "/data-views", ur = 1500;
2392
+ class mr {
2346
2393
  // undefined = not yet built
2347
2394
  /** @internal — construct via `cue.gis`, not directly. */
2348
2395
  constructor(t, e) {
@@ -2425,25 +2472,25 @@ class ir {
2425
2472
  }
2426
2473
  // ── Private ───────────────────────────────────────────────────────────────
2427
2474
  _scheduleDebouncedQuery() {
2428
- this._debounceTimer !== null && clearTimeout(this._debounceTimer), this._debounceTimer = setTimeout(() => this._queryLayers(), ar);
2475
+ this._debounceTimer !== null && clearTimeout(this._debounceTimer), this._debounceTimer = setTimeout(() => this._queryLayers(), ur);
2429
2476
  }
2430
2477
  _getGateway() {
2431
2478
  if (this._gatewayCache !== null && this._gatewayProjectId === this._projectId)
2432
2479
  return this._gatewayCache;
2433
- const t = this._projectId, e = [...me];
2480
+ const t = this._projectId, e = [...ve];
2434
2481
  return t && e.unshift({
2435
2482
  name: "Cue SDK (authenticated)",
2436
- coverageBBox: ge,
2437
- supportedCategories: Object.keys(ue),
2483
+ coverageBBox: ye,
2484
+ supportedCategories: Object.keys(be),
2438
2485
  priority: 10,
2439
- adapter: new Zo({
2440
- dataViewsBaseUrl: `${this._gatewayUrl}${sr}`,
2486
+ adapter: new nr({
2487
+ dataViewsBaseUrl: `${this._gatewayUrl}${gr}`,
2441
2488
  getHeaders: async () => ({
2442
2489
  ...await this._getAuthHeaders(),
2443
2490
  "x-project-id": t
2444
2491
  })
2445
2492
  })
2446
- }), this._gatewayCache = new tr({ regions: e }), this._gatewayProjectId = t, this._gatewayCache;
2493
+ }), this._gatewayCache = new cr({ regions: e }), this._gatewayProjectId = t, this._gatewayCache;
2447
2494
  }
2448
2495
  async _queryLayers() {
2449
2496
  const t = this._bbox;
@@ -2487,11 +2534,11 @@ class ir {
2487
2534
  this._loadListeners.forEach((e) => e(t));
2488
2535
  }
2489
2536
  }
2490
- class Ht {
2537
+ class Wt {
2491
2538
  constructor(t, e, o = !1, r) {
2492
- if (this._auth = t, this._db = Ie(e), this._functions = se(e, ie), this._gatewayUrl = r?.gatewayUrl ?? "", o) {
2539
+ if (this._auth = t, this._db = Ae(e), this._functions = pe(e, le), this._gatewayUrl = r?.gatewayUrl ?? "", o) {
2493
2540
  const s = r?.firestoreEmulatorHost ?? "localhost", a = r?.firestoreEmulatorPort ?? 8080;
2494
- Ce(this._db, s, a), ae(this._functions, "localhost", 5001);
2541
+ Pe(this._db, s, a), ce(this._functions, "localhost", 5001);
2495
2542
  }
2496
2543
  }
2497
2544
  _auth;
@@ -2508,7 +2555,7 @@ class Ht {
2508
2555
  * Throws if a project with the given ID already exists.
2509
2556
  */
2510
2557
  async createProject(t) {
2511
- const e = await this._auth.authenticatedFetch(`${this._gatewayUrl}${no}`, {
2558
+ const e = await this._auth.authenticatedFetch(`${this._gatewayUrl}${go}`, {
2512
2559
  method: "POST",
2513
2560
  headers: { "Content-Type": "application/json" },
2514
2561
  body: JSON.stringify(t)
@@ -2524,12 +2571,12 @@ class Ht {
2524
2571
  * Access is gated by Firestore rules which check membership.
2525
2572
  */
2526
2573
  async listProjects() {
2527
- const t = this._requireUser(), e = yt(this._db, It);
2528
- return (await Se(Te(e, Re("members", "array-contains", t), Ae(100)))).docs.map((r) => r.data());
2574
+ const t = this._requireUser(), e = yt(this._db, Ct);
2575
+ return (await Oe(De(e, Le("members", "array-contains", t), qe(100)))).docs.map((r) => r.data());
2529
2576
  }
2530
2577
  /** Fetch a single project by ID. Returns null if not found. */
2531
2578
  async getProject(t) {
2532
- const e = bt(yt(this._db, It), t), o = await Pe(e);
2579
+ const e = bt(yt(this._db, Ct), t), o = await je(e);
2533
2580
  return o.exists() ? o.data() : null;
2534
2581
  }
2535
2582
  /**
@@ -2539,9 +2586,9 @@ class Ht {
2539
2586
  async incrementUnitsConsumed(t, e, o) {
2540
2587
  if (e <= 0) return;
2541
2588
  const r = bt(this._db, "clientSync", t);
2542
- await Oe(r, {
2543
- unitsConsumed: Le(e),
2544
- lastUpdated: De(),
2589
+ await ze(r, {
2590
+ unitsConsumed: Ue(e),
2591
+ lastUpdated: $e(),
2545
2592
  lastUserId: o
2546
2593
  }, { merge: !0 });
2547
2594
  }
@@ -2564,7 +2611,7 @@ class Ht {
2564
2611
  */
2565
2612
  async deleteProject(t) {
2566
2613
  const e = await this._auth.authenticatedFetch(
2567
- `${this._gatewayUrl}${po(t)}`,
2614
+ `${this._gatewayUrl}${uo(t)}`,
2568
2615
  { method: "DELETE" }
2569
2616
  );
2570
2617
  if (!e.ok) {
@@ -2573,9 +2620,9 @@ class Ht {
2573
2620
  }
2574
2621
  }
2575
2622
  }
2576
- class Wt {
2623
+ class Vt {
2577
2624
  constructor(t, e, o, r) {
2578
- this._auth = t, this._gatewayUrl = r, this._functions = se(e, ie), o && ae(this._functions, "localhost", 5001);
2625
+ this._auth = t, this._gatewayUrl = r, this._functions = pe(e, le), o && ce(this._functions, "localhost", 5001);
2579
2626
  }
2580
2627
  _auth;
2581
2628
  _gatewayUrl;
@@ -2592,13 +2639,13 @@ class Wt {
2592
2639
  }
2593
2640
  /** Whether the current user has an active API key. */
2594
2641
  async hasAPIKey() {
2595
- return await this._fetch(Ot) !== null;
2642
+ return await this._fetch(Dt) !== null;
2596
2643
  }
2597
2644
  /** Returns the sign-in methods registered for the current user's email. */
2598
2645
  async getSignInMethods() {
2599
2646
  const t = this._auth.currentUser;
2600
2647
  if (!t?.email) throw new Error("User has no e-mail");
2601
- return Ge(this._auth.firebaseAuth, t.email);
2648
+ return Ke(this._auth.firebaseAuth, t.email);
2602
2649
  }
2603
2650
  /** Builds a human-readable label from a Firebase UserInfo provider entry. */
2604
2651
  buildProviderLabel(t) {
@@ -2611,14 +2658,14 @@ class Wt {
2611
2658
  }
2612
2659
  /** Links a Google or Microsoft provider to the current account via popup. Returns the new provider label. */
2613
2660
  async linkProvider(t) {
2614
- const e = this._requireUser(), o = t === "google.com" ? new it() : new nt(t), s = (await He(e, o)).user.providerData.find(
2661
+ const e = this._requireUser(), o = t === "google.com" ? new it() : new nt(t), s = (await Qe(e, o)).user.providerData.find(
2615
2662
  (a) => a.providerId === t
2616
2663
  );
2617
2664
  return s ? this.buildProviderLabel(s) : "-";
2618
2665
  }
2619
2666
  /** Unlinks a provider from the current account. */
2620
2667
  async unlinkProvider(t) {
2621
- await We(this._requireUser(), t);
2668
+ await Ye(this._requireUser(), t);
2622
2669
  }
2623
2670
  /** Changes the password. Reauthenticates first. */
2624
2671
  async updatePassword(t, e) {
@@ -2627,13 +2674,13 @@ class Wt {
2627
2674
  await _t(
2628
2675
  o,
2629
2676
  Q.credential(o.email, t)
2630
- ), await Ve(o, e);
2677
+ ), await Ze(o, e);
2631
2678
  }
2632
2679
  /** Adds (sets) a password for an account that currently only uses SSO. */
2633
2680
  async addPassword(t) {
2634
2681
  const e = this._requireUser();
2635
2682
  if (!e.email) throw new Error("User has no e-mail");
2636
- await Ke(e, Q.credential(e.email, t));
2683
+ await Je(e, Q.credential(e.email, t));
2637
2684
  }
2638
2685
  /** Requests an e-mail change. Sends a verification e-mail to the new address. */
2639
2686
  async updateEmail(t, e) {
@@ -2642,11 +2689,11 @@ class Wt {
2642
2689
  await _t(
2643
2690
  o,
2644
2691
  Q.credential(o.email, e)
2645
- ), await Xe(o, t), await Qe(o);
2692
+ ), await to(o, t), await eo(o);
2646
2693
  }
2647
2694
  /** Creates a new API key for the current user. */
2648
2695
  async createAPIKey(t) {
2649
- return this._fetch(Dt, {
2696
+ return this._fetch(Lt, {
2650
2697
  method: "POST",
2651
2698
  headers: { "Content-Type": "application/json" },
2652
2699
  body: JSON.stringify({ expiration: t })
@@ -2655,7 +2702,7 @@ class Wt {
2655
2702
  /** Revokes the current user's API key. */
2656
2703
  async revokeAPIKey() {
2657
2704
  const t = await this._auth.authenticatedFetch(
2658
- this._url(Dt),
2705
+ this._url(Lt),
2659
2706
  { method: "DELETE" }
2660
2707
  );
2661
2708
  if (!t.ok)
@@ -2663,17 +2710,17 @@ class Wt {
2663
2710
  }
2664
2711
  /** Fetches the current user's existing API key. */
2665
2712
  async requestAPIKey() {
2666
- const t = await this._fetch(Ot);
2713
+ const t = await this._fetch(Dt);
2667
2714
  if (!t) throw new Error("No API key found");
2668
2715
  return t;
2669
2716
  }
2670
2717
  /** Returns organizations the current user is a member of. */
2671
2718
  async listOrganizations() {
2672
- return this._fetch(so);
2719
+ return this._fetch(co);
2673
2720
  }
2674
2721
  /** Returns all members of the given organisation. Caller must be an org admin or superadmin. */
2675
2722
  async getOrgMembers(t) {
2676
- return this._fetch(io(t));
2723
+ return this._fetch(ho(t));
2677
2724
  }
2678
2725
  _requireUser() {
2679
2726
  const t = this._auth.currentUser;
@@ -2689,7 +2736,7 @@ class Wt {
2689
2736
  }
2690
2737
  /** Record that the current user has accepted the terms of service. Sets a `terms` custom claim on the token. */
2691
2738
  async acceptTerms(t) {
2692
- await this._fetch(ao, {
2739
+ await this._fetch(lo, {
2693
2740
  method: "POST",
2694
2741
  headers: { "Content-Type": "application/json" },
2695
2742
  body: JSON.stringify({ version: t })
@@ -2706,7 +2753,7 @@ class Wt {
2706
2753
  return t ? (await at(t)).claims.terms ?? null : null;
2707
2754
  }
2708
2755
  }
2709
- const Vt = ["superadmin", "admin", "syncer", "member"], Kt = {
2756
+ const Xt = ["superadmin", "admin", "syncer", "member"], Kt = {
2710
2757
  createEntities: "admin",
2711
2758
  createProvider: "superadmin",
2712
2759
  changeContentCategories: "syncer",
@@ -2722,7 +2769,7 @@ const Vt = ["superadmin", "admin", "syncer", "member"], Kt = {
2722
2769
  uploadDocuments: "syncer",
2723
2770
  viewEntities: "member"
2724
2771
  };
2725
- function nr() {
2772
+ function wr() {
2726
2773
  return {
2727
2774
  changeContentCategories: !1,
2728
2775
  createEntities: !1,
@@ -2741,9 +2788,9 @@ function nr() {
2741
2788
  viewEntities: !1
2742
2789
  };
2743
2790
  }
2744
- class Xt {
2791
+ class Qt {
2745
2792
  constructor(t) {
2746
- this._isSuperAdmin = t, this._projectRoles = new k([]), this._orgRole = new k(null), this.privileges = dt(
2793
+ this._isSuperAdmin = t, this._projectRoles = new x([]), this._orgRole = new x(null), this.privileges = dt(
2747
2794
  [this._projectRoles, this._orgRole, t],
2748
2795
  () => this._compute()
2749
2796
  );
@@ -2780,17 +2827,17 @@ class Xt {
2780
2827
  _expand(t) {
2781
2828
  if (this._isSuperAdmin.get())
2782
2829
  return ["superadmin", "admin", "syncer", "member"];
2783
- const e = Vt.findIndex((o) => t.includes(o));
2784
- return e === -1 ? [] : Array.from(Vt.slice(e));
2830
+ const e = Xt.findIndex((o) => t.includes(o));
2831
+ return e === -1 ? [] : Array.from(Xt.slice(e));
2785
2832
  }
2786
2833
  _compute() {
2787
- const t = this._projectRoles.get(), e = this._isSuperAdmin.get(), o = nr();
2834
+ const t = this._projectRoles.get(), e = this._isSuperAdmin.get(), o = wr();
2788
2835
  for (const r of Object.keys(Kt))
2789
2836
  o[r] = t.includes(Kt[r]);
2790
2837
  return o.createProject = e || this._orgRole.get() === "admin", o;
2791
2838
  }
2792
2839
  }
2793
- class Qt {
2840
+ class Yt {
2794
2841
  constructor(t) {
2795
2842
  this._storage = t;
2796
2843
  }
@@ -2823,7 +2870,7 @@ class Qt {
2823
2870
  // ── Internal helpers ───────────────────────────────────────────────────────
2824
2871
  async _get(t, e) {
2825
2872
  try {
2826
- const r = await (await re(_(this._storage, `${t}/${e}.json.gz`))).arrayBuffer(), s = new DecompressionStream("gzip"), a = s.writable.getWriter(), n = s.readable.getReader();
2873
+ const r = await (await ne(k(this._storage, `${t}/${e}.json.gz`))).arrayBuffer(), s = new DecompressionStream("gzip"), a = s.writable.getWriter(), n = s.readable.getReader();
2827
2874
  a.write(new Uint8Array(r)), a.close();
2828
2875
  const p = [];
2829
2876
  let c = await n.read();
@@ -2835,7 +2882,7 @@ class Qt {
2835
2882
  d.set(u, g), g += u.length;
2836
2883
  return JSON.parse(new TextDecoder().decode(d));
2837
2884
  } catch (o) {
2838
- if (pr(o)) return;
2885
+ if (fr(o)) return;
2839
2886
  throw o;
2840
2887
  }
2841
2888
  }
@@ -2851,13 +2898,13 @@ class Qt {
2851
2898
  for (const u of p)
2852
2899
  d.set(u, g), g += u.length;
2853
2900
  await st(
2854
- _(this._storage, `${t}/${e}.json.gz`),
2901
+ k(this._storage, `${t}/${e}.json.gz`),
2855
2902
  d,
2856
2903
  { contentType: "application/gzip" }
2857
2904
  );
2858
2905
  }
2859
2906
  }
2860
- function pr(i) {
2907
+ function fr(i) {
2861
2908
  return typeof i == "object" && i !== null && "code" in i && i.code === "storage/object-not-found";
2862
2909
  }
2863
2910
  const y = {
@@ -2880,7 +2927,7 @@ const y = {
2880
2927
  dicu: "https://w3id.org/digitalconstruction/0.5/Units#",
2881
2928
  diclvl: "https://w3id.org/digitalconstruction/0.5/Levels#",
2882
2929
  dicstg: "https://w3id.org/digitalconstruction/0.5/Stages#"
2883
- }, A = {
2930
+ }, R = {
2884
2931
  madsrdf: "http://www.loc.gov/mads/rdf/v1#",
2885
2932
  bflc: "http://id.loc.gov/ontologies/bflc/",
2886
2933
  foaf: "http://xmlns.com/foaf/0.1/",
@@ -6129,28 +6176,42 @@ class V {
6129
6176
  return r === void 0 ? t : t.replace(o, `${r}:`);
6130
6177
  }
6131
6178
  expandIRI(t) {
6132
- const e = t.split(":")[0], o = A[e] ?? y[e];
6179
+ const e = t.split(":")[0], o = R[e] ?? y[e];
6133
6180
  return t.replace(`${e}:`, o);
6134
6181
  }
6135
6182
  _buildNSMap() {
6136
6183
  const t = {};
6137
- return Object.keys(A).forEach((e) => t[A[e]] = e), Object.keys(y).forEach(
6184
+ return Object.keys(R).forEach((e) => t[R[e]] = e), Object.keys(y).forEach(
6138
6185
  (e) => t[y[e]] = e
6139
6186
  ), this._nsMap = t, t;
6140
6187
  }
6141
6188
  }
6142
- class lr {
6143
- constructor(t, e, o, r, s) {
6144
- this._api = t, this._projectId = e, this._queryCache = r, this._graphType = s, this._currentLang = o, this._api.setLanguage(o), this._contentCategories = new k([]), this._entityCategories = new k([]), this._relationships = new k([]), this.availableContentCategories = this._contentCategories.asReadonly(), this.availableEntityCategories = this._entityCategories.asReadonly(), this.availableEntityRelationships = this._relationships.asReadonly(), this.ready = this._load(o).catch(
6145
- (a) => console.error("[CueProjectSchema] Initial load failed:", a)
6189
+ const yr = `${y.qcy}ContentCategory`, br = `${y.qcy}EntityCategory`, vr = `${y.qcy}relatedEntity`, _r = `PREFIX view: <https://qlever.cs.uni-freiburg.de/materializedView/>
6190
+ SELECT ?iri ?type ?parent ?deprecated ?label ?definition
6191
+ WHERE {
6192
+ SERVICE view:schemas {
6193
+ _:cfg view:column-iri ?iri ;
6194
+ view:column-type ?type ;
6195
+ view:column-parent ?parent ;
6196
+ view:column-deprecated ?deprecated ;
6197
+ view:column-label ?label ;
6198
+ view:column-definition ?definition .
6199
+ }
6200
+ }`;
6201
+ class Er {
6202
+ constructor(t, e, o, r, s, a) {
6203
+ this._api = t, this._projectId = e, this._queryCache = r, this._graphType = s, this._verbose = a ?? !1, this._currentLang = o, this._api.setLanguage(o), this._contentCategories = new x([]), this._entityCategories = new x([]), this._relationships = new x([]), this.availableContentCategories = this._contentCategories.asReadonly(), this.availableEntityCategories = this._entityCategories.asReadonly(), this.availableEntityRelationships = this._relationships.asReadonly(), this.ready = this._load().catch(
6204
+ (n) => console.error("[CueProjectSchema] Initial load failed:", n)
6146
6205
  );
6147
6206
  }
6148
6207
  _api;
6149
6208
  _projectId;
6150
6209
  _queryCache;
6151
6210
  _graphType;
6152
- _cache = /* @__PURE__ */ new Map();
6211
+ _snapshot;
6212
+ _inflight;
6153
6213
  _currentLang;
6214
+ _verbose;
6154
6215
  _contentCategories;
6155
6216
  _entityCategories;
6156
6217
  _relationships;
@@ -6170,106 +6231,166 @@ class lr {
6170
6231
  return this._api.language;
6171
6232
  }
6172
6233
  /**
6173
- * Switch the active language. If the data for this language has already been
6174
- * fetched it is applied immediately from cache; otherwise a new SPARQL fetch
6175
- * is triggered.
6234
+ * Switch the active language. Re-projects the already-fetched schema for the
6235
+ * new language without re-querying; only triggers a fetch if nothing has been
6236
+ * loaded yet.
6176
6237
  */
6177
6238
  setLanguage(t) {
6178
- this._currentLang !== t && (this._currentLang = t, this._api.setLanguage(t), this._load(t).catch(
6179
- (e) => console.error("[CueProjectSchema] Language switch failed:", e)
6180
- ));
6239
+ if (this._currentLang !== t) {
6240
+ if (this._currentLang = t, this._api.setLanguage(t), this._snapshot) {
6241
+ this._apply(this._snapshot);
6242
+ return;
6243
+ }
6244
+ this._load().catch(
6245
+ (e) => console.error("[CueProjectSchema] Language switch failed:", e)
6246
+ );
6247
+ }
6181
6248
  }
6182
6249
  /**
6183
- * Force a re-fetch for the current language, bypassing the cache.
6250
+ * Force a re-fetch of the schema, bypassing the cache.
6184
6251
  * Useful when the triplestore data has changed.
6185
6252
  */
6186
6253
  async refresh() {
6187
- const t = this._api.language;
6188
- this._cache.delete(t), await this._load(t);
6254
+ this._snapshot = void 0, await this._load();
6189
6255
  }
6190
6256
  // ── Private helpers ─────────────────────────────────────────────────────────
6191
- async _load(t) {
6192
- const e = this._cache.get(t);
6193
- if (e) {
6194
- this._apply(e);
6257
+ async _load() {
6258
+ if (this._snapshot) {
6259
+ this._apply(this._snapshot);
6195
6260
  return;
6196
6261
  }
6197
- const o = this._buildCategoriesQuery(t, "ContentCategory"), r = this._buildCategoriesQuery(t, "EntityCategory"), s = this._buildRelationshipsQuery(t);
6198
- await gt(
6199
- o + r + s,
6200
- async () => {
6201
- const [a, n, p] = await Promise.all([
6202
- this._runCategoriesQuery(o),
6203
- this._runCategoriesQuery(r),
6204
- this._runRelationshipsQuery(s)
6205
- ]);
6206
- return { contentCategories: a, entityCategories: n, relationships: p };
6207
- },
6208
- (a) => {
6209
- this._cache.set(t, a), this._currentLang === t && this._apply(a);
6262
+ if (this._inflight) return this._inflight;
6263
+ this._verbose && console.log(
6264
+ `[CueProjectSchema] Fetching schema project: ${this._projectId}, graphType: ${this._graphType ?? "default"}`
6265
+ );
6266
+ const t = `cue-schema:${this._projectId}:${this._graphType ?? "default"}`, e = gt(
6267
+ t,
6268
+ () => this._fetchSnapshot(),
6269
+ (o, r) => {
6270
+ this._verbose && console.log(
6271
+ `[CueProjectSchema] Applying ${r ? "stale (cached)" : "fresh"} snapshot — contentCategories: ${o.contentCategories.length}, entityCategories: ${o.entityCategories.length}, relationships: ${o.relationships.length}`
6272
+ ), this._snapshot = o, this._apply(o);
6210
6273
  },
6211
6274
  this._queryCache
6212
- );
6275
+ ).then(() => {
6276
+ }).finally(() => {
6277
+ this._inflight = void 0;
6278
+ });
6279
+ return this._inflight = e, e;
6280
+ }
6281
+ /**
6282
+ * Fetches the schema once. On QLever the pre-computed `schemas` materialized
6283
+ * view is tried first; if it yields no rows we warn and fall back to the live
6284
+ * schema query.
6285
+ */
6286
+ async _fetchSnapshot() {
6287
+ if (this._graphType !== "fuseki") {
6288
+ const e = await this._runSchemaQuery(_r);
6289
+ if (e.contentCategories.length + e.entityCategories.length + e.relationships.length > 0) return e;
6290
+ console.warn(
6291
+ `[CueProjectSchema] Materialized view "schemas" returned no rows for project ${this._projectId} — falling back to the live schema query.`
6292
+ );
6293
+ }
6294
+ return this._runSchemaQuery(this._buildSchemaQuery());
6213
6295
  }
6214
6296
  _apply(t) {
6215
- this._contentCategories.set(t.contentCategories), this._entityCategories.set(t.entityCategories), this._relationships.set(t.relationships);
6297
+ const e = this._currentLang;
6298
+ this._contentCategories.set(
6299
+ t.contentCategories.map((o) => this._toDef(o, e))
6300
+ ), this._entityCategories.set(
6301
+ t.entityCategories.map((o) => this._toDef(o, e))
6302
+ ), this._relationships.set(
6303
+ t.relationships.map((o) => this._toDef(o, e))
6304
+ );
6216
6305
  }
6217
- async _fetchCategories(t, e) {
6218
- return this._runCategoriesQuery(this._buildCategoriesQuery(t, e));
6306
+ /** Projects a language-independent {@link SchemaNode} into a {@link CategoryDef}. */
6307
+ _toDef(t, e) {
6308
+ const o = te(t.labels, e) ?? t.iri.split("#").at(-1) ?? t.iri, r = te(t.definitions, e), s = Object.keys(t.definitions).length > 0;
6309
+ return {
6310
+ iri: t.iri,
6311
+ label: o,
6312
+ labels: t.labels,
6313
+ ...r !== void 0 ? { definition: r } : {},
6314
+ ...s ? { definitions: t.definitions } : {},
6315
+ ...t.parent !== void 0 ? { parent: t.parent } : {},
6316
+ ...t.deprecated !== void 0 ? { deprecated: t.deprecated } : {}
6317
+ };
6219
6318
  }
6220
- _buildCategoriesQuery(t, e) {
6319
+ /**
6320
+ * Single query covering content categories, entity categories and entity
6321
+ * relationship types. Labels/definitions are returned untouched (with their
6322
+ * language tags) so they can be grouped into {@link LangMap}s client-side.
6323
+ */
6324
+ _buildSchemaQuery() {
6221
6325
  return `PREFIX qcy: <${y.qcy}>
6222
- PREFIX skos: <${A.skos}>
6223
- SELECT ?iri ?parent (SAMPLE(?l) AS ?label)
6326
+ PREFIX skos: <${R.skos}>
6327
+ PREFIX rdfs: <${R.rdfs}>
6328
+ PREFIX owl: <${R.owl}>
6329
+ SELECT ?iri ?type ?parent ?deprecated ?label ?definition
6224
6330
  WHERE {
6225
- ?iri a qcy:${e} .
6226
- OPTIONAL { ?iri skos:prefLabel ?lang_label FILTER(LANG(?lang_label) = "${t}") }
6227
- OPTIONAL { ?iri skos:prefLabel ?no_lang_label }
6228
- BIND(COALESCE(?lang_label, ?no_lang_label) AS ?l)
6229
- OPTIONAL { ?iri skos:broader ?parent }
6230
- }
6231
- GROUP BY ?iri ?parent`;
6232
- }
6233
- async _runCategoriesQuery(t) {
6234
- return (await this._api.sparql(t, this._projectId, this._graphType)).results.bindings.filter((o) => o.iri !== void 0).map((o) => {
6235
- const r = o.iri.value;
6236
- return {
6237
- iri: r,
6238
- label: o.label?.value ?? r.split("#").at(-1) ?? r,
6239
- parent: o.parent?.value
6240
- };
6241
- });
6331
+ {
6332
+ VALUES ?type { qcy:ContentCategory qcy:EntityCategory }
6333
+ ?iri a ?type ;
6334
+ skos:prefLabel ?label ;
6335
+ skos:definition ?definition .
6336
+ OPTIONAL { ?iri skos:broader ?parent }
6337
+ OPTIONAL { ?iri owl:deprecated ?deprecated }
6338
+ }
6339
+ UNION
6340
+ {
6341
+ ?iri rdfs:subPropertyOf+ qcy:relatedEntity .
6342
+ ?iri rdfs:label ?label ;
6343
+ rdfs:comment ?definition .
6344
+ OPTIONAL { ?iri rdfs:subPropertyOf ?parent }
6345
+ OPTIONAL { ?iri owl:deprecated ?deprecated }
6346
+ BIND(qcy:relatedEntity AS ?type)
6347
+ }
6348
+ }`;
6242
6349
  }
6243
- async _fetchRelationships(t) {
6244
- return this._runRelationshipsQuery(this._buildRelationshipsQuery(t));
6350
+ /** Runs a schema query and groups the flat rows into a {@link SchemaSnapshot}. */
6351
+ async _runSchemaQuery(t) {
6352
+ const e = await this._api.sparql(
6353
+ t,
6354
+ this._projectId,
6355
+ this._graphType
6356
+ ), o = /* @__PURE__ */ new Map();
6357
+ for (const s of e.results.bindings) {
6358
+ const a = s.iri?.value, n = s.type?.value;
6359
+ if (!a || !n) continue;
6360
+ let p = o.get(a);
6361
+ p || (p = { iri: a, type: n, labels: {}, definitions: {} }, o.set(a, p)), p.parent === void 0 && s.parent?.value && (p.parent = s.parent.value);
6362
+ const c = s.deprecated?.value;
6363
+ c !== void 0 && (p.deprecated = c === "true" || c === "1"), Zt(p.labels, s.label), Zt(p.definitions, s.definition);
6364
+ }
6365
+ const r = {
6366
+ contentCategories: [],
6367
+ entityCategories: [],
6368
+ relationships: []
6369
+ };
6370
+ for (const s of o.values())
6371
+ Jt(s.labels), Jt(s.definitions), s.type === yr ? r.contentCategories.push(s) : s.type === br ? r.entityCategories.push(s) : s.type === vr && r.relationships.push(s);
6372
+ return r;
6245
6373
  }
6246
- _buildRelationshipsQuery(t) {
6247
- return `PREFIX qcy: <${y.qcy}>
6248
- PREFIX rdfs: <${A.rdfs}>
6249
- SELECT ?iri ?parent (SAMPLE(?l) AS ?label)
6250
- WHERE {
6251
- ?x qcy:relatedEntity ?y ;
6252
- ?iri ?y .
6253
- OPTIONAL { ?iri rdfs:label ?lang_label FILTER(LANG(?lang_label) = "${t}") }
6254
- OPTIONAL { ?iri rdfs:label ?no_lang_label }
6255
- BIND(COALESCE(?lang_label, ?no_lang_label) AS ?l)
6256
- OPTIONAL { ?iri rdfs:subPropertyOf ?parent }
6257
6374
  }
6258
- GROUP BY ?iri ?parent`;
6259
- }
6260
- async _runRelationshipsQuery(t) {
6261
- return (await this._api.sparql(t, this._projectId, this._graphType)).results.bindings.filter((o) => o.iri !== void 0).map((o) => {
6262
- const r = o.iri.value;
6263
- return {
6264
- iri: r,
6265
- label: o.label?.value ?? r.split("#").at(-1) ?? r,
6266
- parent: o.parent?.value
6267
- };
6268
- });
6375
+ function Zt(i, t) {
6376
+ if (!t || t.value === void 0) return;
6377
+ const e = t["xml:lang"], o = e && e.length > 0 ? e : "default";
6378
+ i[o] === void 0 && (i[o] = t.value);
6379
+ }
6380
+ function Jt(i) {
6381
+ if (i.en !== void 0) {
6382
+ i.default = i.en;
6383
+ return;
6269
6384
  }
6385
+ if (i.default !== void 0) return;
6386
+ const t = Object.values(i)[0];
6387
+ t !== void 0 && (i.default = t);
6388
+ }
6389
+ function te(i, t) {
6390
+ return i[t] ?? i.default;
6270
6391
  }
6271
- const cr = "https://qlever.dev/api/osm-planet";
6272
- class we {
6392
+ const kr = "https://qlever.dev/api/osm-planet";
6393
+ class _e {
6273
6394
  constructor(t, e, o = ut, r, s, a = !1) {
6274
6395
  this._api = t, this._projectId = e, this._queryCache = r, this._graphType = s, this._verbose = a, this.baseURL = `${o}${e}/`, this.entityInfoMap = this._entityInfoMapComputed, this.entityGraph = this._entityGraph.asReadonly(), this._entityOSMMap.subscribe(() => this._checkPendingOSMFetches()), this._fetchEntityGraph().catch(
6275
6396
  (n) => console.error("[CueProjectEntities] Entity graph fetch failed:", n)
@@ -6283,17 +6404,17 @@ class we {
6283
6404
  /** Full RDF base URL for this project, e.g. `https://cue.qaecy.com/r/{pid}/` */
6284
6405
  baseURL;
6285
6406
  // ── Internal writable slices ───────────────────────────────────────────────
6286
- _entityDetails = new k({});
6287
- _entityDocuments = new k(
6407
+ _entityDetails = new x({});
6408
+ _entityDocuments = new x(
6288
6409
  {}
6289
6410
  );
6290
- _entityRelationships = new k({});
6291
- _entityOSMMap = new k({});
6292
- _osmWKTMap = new k({});
6411
+ _entityRelationships = new x({});
6412
+ _entityOSMMap = new x({});
6413
+ _osmWKTMap = new x({});
6293
6414
  _fetchingOSMIds = /* @__PURE__ */ new Set();
6294
6415
  /** Cumulative unique entity UUIDs ever passed to request methods (survives cache hits). */
6295
6416
  _seenIds = /* @__PURE__ */ new Set();
6296
- _entityGraph = new k(void 0);
6417
+ _entityGraph = new x(void 0);
6297
6418
  // ── Derived signals ────────────────────────────────────────────────────────
6298
6419
  _entityInfoMapComputed = dt(
6299
6420
  [
@@ -6488,7 +6609,7 @@ WHERE {
6488
6609
  */
6489
6610
  async contentCategoriesInProject(t = !0) {
6490
6611
  const e = this._api.language, o = `PREFIX qcy: <${y.qcy}>
6491
- PREFIX skos: <${A.skos}>
6612
+ PREFIX skos: <${R.skos}>
6492
6613
  SELECT ?iri (SAMPLE(?l) AS ?label) ?count
6493
6614
  WHERE {
6494
6615
  ?iri a qcy:EntityCategory .
@@ -6562,11 +6683,7 @@ WHERE {
6562
6683
  ${s}
6563
6684
  }
6564
6685
  GROUP BY ?sourceCat ?predicate ?targetCat
6565
- ORDER BY DESC(?weight)`, n = await this._api.sparql(
6566
- a,
6567
- this._projectId,
6568
- this._graphType
6569
- ), p = n.results.bindings.filter(
6686
+ ORDER BY DESC(?weight)`, n = await this._fetchSummaryData(a, s), p = n.results.bindings.filter(
6570
6687
  (c) => c.sourceCat && c.predicate && c.targetCat
6571
6688
  );
6572
6689
  if (t === "graph") {
@@ -6597,6 +6714,41 @@ ORDER BY DESC(?weight)`, n = await this._api.sparql(
6597
6714
  return n;
6598
6715
  }
6599
6716
  // ── Private helpers ────────────────────────────────────────────────────────
6717
+ /**
6718
+ * Fetches the category-summary rows. On QLever the pre-computed
6719
+ * `entity-summary` materialized view is tried first; if it yields no rows we
6720
+ * warn and fall back to the live aggregation query. Fuseki always uses the
6721
+ * live query.
6722
+ */
6723
+ async _fetchSummaryData(t, e) {
6724
+ if (this._graphType !== "fuseki") {
6725
+ const r = `PREFIX view: <https://qlever.cs.uni-freiburg.de/materializedView/>
6726
+ SELECT ?sourceCat ?predicate ?targetCat ?weight
6727
+ WHERE {
6728
+ SERVICE view:entity-summary {
6729
+ _:cfg view:column-sourceCat ?sourceCat ;
6730
+ view:column-predicate ?predicate ;
6731
+ view:column-targetCat ?targetCat ;
6732
+ view:column-weight ?weight .
6733
+ }
6734
+ ${e}
6735
+ }
6736
+ ORDER BY DESC(?weight)`, s = await this._api.sparql(
6737
+ r,
6738
+ this._projectId,
6739
+ this._graphType
6740
+ );
6741
+ if (s?.results?.bindings?.length) return s;
6742
+ console.warn(
6743
+ '[CueProjectEntities] Materialized view "entity-summary" returned no rows — falling back to the live query.'
6744
+ );
6745
+ }
6746
+ return await this._api.sparql(
6747
+ t,
6748
+ this._projectId,
6749
+ this._graphType
6750
+ );
6751
+ }
6600
6752
  _computeEntityInfoMap() {
6601
6753
  const t = this._entityDetails.get(), e = this._entityDocuments.get(), o = this._entityRelationships.get(), r = this._entityOSMMap.get(), s = this._osmWKTMap.get(), a = /* @__PURE__ */ new Set([
6602
6754
  ...Object.keys(t),
@@ -6614,18 +6766,18 @@ ORDER BY DESC(?weight)`, n = await this._api.sparql(
6614
6766
  (f) => s[f] !== void 0 && !u.has(f) && !!u.add(f)
6615
6767
  ).map((f) => ({ osmIRI: f, wkt: s[f] }));
6616
6768
  const m = /* @__PURE__ */ new Map();
6617
- for (const { osm: f, viaRels: E, entityUUID: w } of h.indirect) {
6618
- const x = s[f];
6619
- if (x)
6620
- for (const I of E) {
6769
+ for (const { osm: f, viaRels: _, entityUUID: w } of h.indirect) {
6770
+ const E = s[f];
6771
+ if (E)
6772
+ for (const I of _) {
6621
6773
  const v = `${I}:${w}`, b = m.get(v) ?? { geometries: [], entityUUID: w };
6622
- b.geometries.some((C) => C.osmIRI === f) || (b.geometries.push({ osmIRI: f, wkt: x }), m.set(v, b));
6774
+ b.geometries.some((S) => S.osmIRI === f) || (b.geometries.push({ osmIRI: f, wkt: E }), m.set(v, b));
6623
6775
  }
6624
6776
  }
6625
6777
  m.size > 0 && (g = Array.from(m.entries()).map(
6626
- ([f, { geometries: E, entityUUID: w }]) => ({
6778
+ ([f, { geometries: _, entityUUID: w }]) => ({
6627
6779
  rel: f.split(":")[0],
6628
- geometries: E,
6780
+ geometries: _,
6629
6781
  entityUUID: w
6630
6782
  })
6631
6783
  ));
@@ -6753,10 +6905,10 @@ GROUP BY ?e1Cat ?e2Cat`;
6753
6905
  async _fetchOSMLocations(t) {
6754
6906
  const e = t.filter((n) => !n.includes("/relation/"));
6755
6907
  if (e.length === 0) return;
6756
- const o = e.map((n) => `<${n}>`).join(" "), r = `PREFIX geo: <${A.geo}>
6908
+ const o = e.map((n) => `<${n}>`).join(" "), r = `PREFIX geo: <${R.geo}>
6757
6909
  SELECT * WHERE {
6758
6910
  VALUES ?s { ${o} }
6759
- SERVICE <${cr}> {
6911
+ SERVICE <${kr}> {
6760
6912
  ?s geo:hasGeometry/geo:asWKT ?wkt
6761
6913
  }
6762
6914
  }`, s = await this._api.sparql(
@@ -6770,7 +6922,7 @@ SELECT * WHERE {
6770
6922
  }
6771
6923
  }
6772
6924
  var l = /* @__PURE__ */ ((i) => (i.AUTOMATION = "automation", i.ARCHIVE = "archive", i.AUDIO = "audio", i.BACKUP = "backup", i.BINARY = "binary", i.BIM = "bim", i.CAD = "cad", i.DATA = "data", i.EMAIL = "email", i.FONT = "font", i.GEOSPATIAL = "geospatial", i.IMAGE = "image", i.INSTALLER = "installer", i.MARKUP = "markup", i.MULTIMEDIA = "multimedia", i.PLANNING = "planning", i.PRESENTATION = "presentation", i.SCRIPT = "script", i.SPREADSHEET = "spreadsheet", i.TEXT = "text", i.THREE_D = "3d", i.UNKNOWN = "unknown", i.VIDEO = "video", i))(l || {});
6773
- const lt = {
6925
+ const ct = {
6774
6926
  ".aac": {
6775
6927
  type: l.AUDIO,
6776
6928
  open: !0,
@@ -7631,7 +7783,30 @@ const lt = {
7631
7783
  }
7632
7784
  };
7633
7785
  l.AUDIO + "", l.VIDEO + "", l.IMAGE + "", l.TEXT + "", l.MARKUP + "", l.SCRIPT + "", l.DATA + "", l.ARCHIVE + "", l.INSTALLER + "", l.BINARY + "", l.BACKUP + "", l.AUTOMATION + "", l.PRESENTATION + "", l.SPREADSHEET + "", l.FONT + "", l.GEOSPATIAL + "", l.THREE_D + "", l.CAD + "", l.BIM + "", l.PLANNING + "", l.EMAIL + "", l.MULTIMEDIA + "", l.UNKNOWN + "";
7634
- class ct {
7786
+ const xr = `PREFIX view: <https://qlever.cs.uni-freiburg.de/materializedView/>
7787
+ SELECT ?ext ?totalSize ?docCount
7788
+ WHERE {
7789
+ SERVICE view:docs-by-suffix {
7790
+ _:cfg view:column-ext ?ext ;
7791
+ view:column-totalSize ?totalSize ;
7792
+ view:column-docCount ?docCount .
7793
+ }
7794
+ }`, Cr = `PREFIX view: <https://qlever.cs.uni-freiburg.de/materializedView/>
7795
+ SELECT ?cat ?totalSize ?docCount
7796
+ WHERE {
7797
+ SERVICE view:docs-by-category {
7798
+ _:cfg view:column-cat ?cat ;
7799
+ view:column-totalSize ?totalSize ;
7800
+ view:column-docCount ?docCount .
7801
+ }
7802
+ }`, Ir = `PREFIX view: <https://qlever.cs.uni-freiburg.de/materializedView/>
7803
+ SELECT ?count
7804
+ WHERE {
7805
+ SERVICE view:doc-duplicates {
7806
+ _:cfg view:column-count ?count .
7807
+ }
7808
+ }`;
7809
+ class lt {
7635
7810
  constructor(t, e, o, r = ut, s, a, n = !1) {
7636
7811
  this._api = t, this._projectId = e, this._queryCache = s, this._graphType = a, this._verbose = n, this.baseURL = `${r}${e}/`, this._currentLang = o ?? this._api.language, this.documentInfoMap = this._documentInfoMap.asReadonly(), this.projectDocumentsData = this._projectDocumentsData.asReadonly();
7637
7812
  }
@@ -7644,10 +7819,10 @@ class ct {
7644
7819
  baseURL;
7645
7820
  /** Tracks the language for which `_documentInfoMap` is currently populated. */
7646
7821
  _currentLang;
7647
- _documentInfoMap = new k({});
7822
+ _documentInfoMap = new x({});
7648
7823
  /** Cumulative unique document UUIDs ever passed to request methods (survives cache hits). */
7649
7824
  _seenIds = /* @__PURE__ */ new Set();
7650
- _projectDocumentsData = new k({
7825
+ _projectDocumentsData = new x({
7651
7826
  duplicateCount: 0,
7652
7827
  documentsBySuffix: {},
7653
7828
  documentsByContentCategory: {}
@@ -7693,9 +7868,9 @@ class ct {
7693
7868
  t + e + o,
7694
7869
  async () => {
7695
7870
  const [r, s, a] = await Promise.all([
7696
- this._runDocumentsBySuffixQuery(t),
7697
- this._runDocumentsByContentCategoryQuery(e),
7698
- this._runDuplicateCountQuery(o)
7871
+ this._fetchDocumentsBySuffix(),
7872
+ this._fetchDocumentsByContentCategory(),
7873
+ this._fetchDuplicateCount()
7699
7874
  ]);
7700
7875
  return { duplicateCount: a, documentsBySuffix: r, documentsByContentCategory: s };
7701
7876
  },
@@ -7850,7 +8025,7 @@ WHERE {
7850
8025
  });
7851
8026
  }
7852
8027
  documentsByFileType(t, e = !1) {
7853
- const o = new Set(t), r = Object.values(lt).filter((s) => o.has(s.type)).map((s) => s.suffix);
8028
+ const o = new Set(t), r = Object.values(ct).filter((s) => o.has(s.type)).map((s) => s.suffix);
7854
8029
  return this.documentsBySuffix(r, e);
7855
8030
  }
7856
8031
  async documentsByContentCategory(t, e = !1) {
@@ -7888,7 +8063,7 @@ WHERE {
7888
8063
  });
7889
8064
  }
7890
8065
  documentsByMime(t, e = !1) {
7891
- const o = new Set(t), r = Object.values(lt).filter((s) => o.has(s.mime)).map((s) => s.suffix);
8066
+ const o = new Set(t), r = Object.values(ct).filter((s) => o.has(s.mime)).map((s) => s.suffix);
7892
8067
  return this.documentsBySuffix(r, e);
7893
8068
  }
7894
8069
  // ── Private helpers ────────────────────────────────────────────────────────
@@ -7979,6 +8154,11 @@ GROUP BY ?id ?suffix ?size`, r = await this._api.sparql(o, this._projectId, this
7979
8154
  }), this._documentInfoMap.set(s), this._log(`fetchSimpleDocumentInfoBatch: ${Object.keys(a).length} fetched | cumulative: ${Object.keys(s).length} with metadata / ${this._seenIds.size} seen`), a;
7980
8155
  }
7981
8156
  async _fetchDocumentsBySuffix() {
8157
+ if (this._graphType !== "fuseki") {
8158
+ const e = await this._runDocumentsBySuffixQuery(xr);
8159
+ if (Object.keys(e).length > 0) return e;
8160
+ console.warn(`[CueProjectDocuments] Materialized view "docs-by-suffix" returned no rows for project ${this._projectId} — falling back to live query.`);
8161
+ }
7982
8162
  return this._runDocumentsBySuffixQuery(this._buildDocumentsBySuffixQuery());
7983
8163
  }
7984
8164
  _buildDocumentsBySuffixQuery() {
@@ -8008,6 +8188,11 @@ ORDER BY DESC(?docCount)`;
8008
8188
  }), o;
8009
8189
  }
8010
8190
  async _fetchDocumentsByContentCategory() {
8191
+ if (this._graphType !== "fuseki") {
8192
+ const e = await this._runDocumentsByContentCategoryQuery(Cr);
8193
+ if (Object.keys(e).length > 0) return e;
8194
+ console.warn(`[CueProjectDocuments] Materialized view "docs-by-category" returned no rows for project ${this._projectId} — falling back to live query.`);
8195
+ }
8011
8196
  return this._runDocumentsByContentCategoryQuery(this._buildDocumentsByContentCategoryQuery());
8012
8197
  }
8013
8198
  _buildDocumentsByContentCategoryQuery() {
@@ -8037,6 +8222,14 @@ ORDER BY DESC(?docCount)`;
8037
8222
  }), o;
8038
8223
  }
8039
8224
  async _fetchDuplicateCount() {
8225
+ if (this._graphType !== "fuseki") {
8226
+ const e = await this._api.sparql(Ir, this._projectId, this._graphType);
8227
+ if (e.results.bindings.length > 0) {
8228
+ const o = e.results.bindings[0];
8229
+ return o?.count ? parseInt(o.count.value, 10) : 0;
8230
+ }
8231
+ console.warn(`[CueProjectDocuments] Materialized view "doc-duplicates" returned no rows for project ${this._projectId} — falling back to live query.`);
8232
+ }
8040
8233
  return this._runDuplicateCountQuery(this._buildDuplicateCountQuery());
8041
8234
  }
8042
8235
  _buildDuplicateCountQuery() {
@@ -8058,9 +8251,9 @@ WHERE {
8058
8251
  return o?.count ? parseInt(o.count.value, 10) : 0;
8059
8252
  }
8060
8253
  }
8061
- class hr {
8254
+ class Sr {
8062
8255
  constructor(t, e, { language: o, queryCache: r, rdfBase: s = ut, graphType: a, verbose: n }) {
8063
- this._api = t, this._projectId = e, this.schema = new lr(t, e, o, r, a), this.entities = new we(t, e, s, r, a, n), this.documents = new ct(t, e, o, s, r, a, n), this.availableContentCategories = this.schema.availableContentCategories, this.availableEntityCategories = this.schema.availableEntityCategories, this.availableEntityRelationships = this.schema.availableEntityRelationships, this.schemaReady = this.schema.ready, this.entityInfoMap = this.entities.entityInfoMap, this.entityGraph = this.entities.entityGraph, this.documentInfoMap = this.documents.documentInfoMap, this.projectDocumentsData = this.documents.projectDocumentsData, this.searchResults = this._searchResults.asReadonly(), this.documents.fetchOverview().catch((p) => console.error("[CueProjectView] fetchOverview failed:", p));
8256
+ this._api = t, this._projectId = e, this.schema = new Er(t, e, o, r, a, n), this.entities = new _e(t, e, s, r, a, n), this.documents = new lt(t, e, o, s, r, a, n), this.availableContentCategories = this.schema.availableContentCategories, this.availableEntityCategories = this.schema.availableEntityCategories, this.availableEntityRelationships = this.schema.availableEntityRelationships, this.schemaReady = this.schema.ready, this.entityInfoMap = this.entities.entityInfoMap, this.entityGraph = this.entities.entityGraph, this.documentInfoMap = this.documents.documentInfoMap, this.projectDocumentsData = this.documents.projectDocumentsData, this.searchResults = this._searchResults.asReadonly(), this.documents.fetchOverview().catch((p) => console.error("[CueProjectView] fetchOverview failed:", p));
8064
8257
  }
8065
8258
  _api;
8066
8259
  _projectId;
@@ -8091,7 +8284,7 @@ class hr {
8091
8284
  /** Project document overview (counts by suffix and category). Fetched on init. */
8092
8285
  projectDocumentsData;
8093
8286
  // ── Search state ───────────────────────────────────────────────────────────
8094
- _searchResults = new k(void 0);
8287
+ _searchResults = new x(void 0);
8095
8288
  /** The result of the most recent `search()` call. `undefined` before first search. */
8096
8289
  searchResults;
8097
8290
  _destroyed = !1;
@@ -8178,7 +8371,7 @@ class hr {
8178
8371
  this._destroyed = !0, this._searchResults.set(void 0);
8179
8372
  }
8180
8373
  }
8181
- function Yt(i, t) {
8374
+ function ee(i, t) {
8182
8375
  return new Promise((e) => {
8183
8376
  const o = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map();
8184
8377
  for (const w of i)
@@ -8191,14 +8384,14 @@ function Yt(i, t) {
8191
8384
  s.has(w.contentUUID) ? (s.get(w.contentUUID) || []).some((v) => v.locationUUID === w.locationUUID) || p.push(w) : n.push(w);
8192
8385
  const c = [], h = [];
8193
8386
  for (const w of t) {
8194
- const x = o.get(w.contentUUID);
8195
- x ? x.some((v) => v.locationUUID === w.locationUUID) || h.push(w) : c.push(w);
8387
+ const E = o.get(w.contentUUID);
8388
+ E ? E.some((v) => v.locationUUID === w.locationUUID) || h.push(w) : c.push(w);
8196
8389
  }
8197
8390
  const d = i.length - n.length - p.length, g = i.length, u = g > 0 ? d / g : 1;
8198
8391
  let m = 0, f = 0;
8199
8392
  for (const w of i)
8200
8393
  f += w.size || 0, (s.get(w.contentUUID) || []).some((v) => v.locationUUID === w.locationUUID) && (m += w.size || 0);
8201
- const E = f > 0 ? m / f : 1;
8394
+ const _ = f > 0 ? m / f : 1;
8202
8395
  e({
8203
8396
  localNotOnRemote: n,
8204
8397
  localNotOnRemotePathOnly: p,
@@ -8208,27 +8401,27 @@ function Yt(i, t) {
8208
8401
  totalCount: g,
8209
8402
  syncSize: m,
8210
8403
  totalSize: f,
8211
- synctPctSize: E,
8404
+ synctPctSize: _,
8212
8405
  synctPctCount: u
8213
8406
  });
8214
8407
  });
8215
8408
  }
8216
- const { namedNode: dr, literal: Rr } = j;
8217
- dr("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
8218
- const { namedNode: Ar } = j, { namedNode: gr, literal: Pr } = j;
8219
- gr("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
8220
- function ur(i) {
8409
+ const { namedNode: Tr, literal: Hr } = j;
8410
+ Tr("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
8411
+ const { namedNode: Wr } = j, { namedNode: Rr, literal: Vr } = j;
8412
+ Rr("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
8413
+ function Ar(i) {
8221
8414
  const t = i.split(".");
8222
8415
  return t.length > 1 ? "." + t.pop()?.toLowerCase() : "";
8223
8416
  }
8224
- const { namedNode: mr, literal: Or } = j;
8225
- mr("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
8226
- const { namedNode: wr, literal: Dr } = j;
8227
- wr("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
8228
- function Zt(i, t, e, o, r, s, a, n = !1, p = !1) {
8229
- const c = ur(i), h = D(o), d = `${t}/${h}${c}`;
8230
- a === void 0 && (a = lt[c]?.mime ?? "application/octet-stream");
8231
- const g = eo(i, r);
8417
+ const { namedNode: Pr, literal: Xr } = j;
8418
+ Pr("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
8419
+ const { namedNode: Or, literal: Kr } = j;
8420
+ Or("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
8421
+ function oe(i, t, e, o, r, s, a, n = !1, p = !1) {
8422
+ const c = Ar(i), h = D(o), d = `${t}/${h}${c}`;
8423
+ a === void 0 && (a = ct[c]?.mime ?? "application/octet-stream");
8424
+ const g = io(i, r);
8232
8425
  return {
8233
8426
  name: i,
8234
8427
  blob_name: d,
@@ -8248,25 +8441,25 @@ function Zt(i, t, e, o, r, s, a, n = !1, p = !1) {
8248
8441
  })
8249
8442
  };
8250
8443
  }
8251
- async function U() {
8444
+ async function z() {
8252
8445
  return import(
8253
8446
  /* webpackIgnore: true */
8254
8447
  "fs/promises"
8255
8448
  );
8256
8449
  }
8257
- async function Jt(i) {
8450
+ async function re(i) {
8258
8451
  if (typeof window < "u")
8259
8452
  throw new Error(
8260
8453
  `Cannot read file from path "${i}" in a browser environment. Provide file.data (Uint8Array) instead.`
8261
8454
  );
8262
- const { readFile: t } = await U();
8455
+ const { readFile: t } = await z();
8263
8456
  return t(i);
8264
8457
  }
8265
8458
  let q = null, G = null, H = null;
8266
- function Lr(i) {
8459
+ function Qr(i) {
8267
8460
  H = i, G = null, q = null;
8268
8461
  }
8269
- async function fr() {
8462
+ async function Dr() {
8270
8463
  if (typeof window < "u") {
8271
8464
  if (!H)
8272
8465
  throw new Error(
@@ -8278,7 +8471,7 @@ async function fr() {
8278
8471
  const t = new Uint8Array(await i.arrayBuffer()), o = await import(`${H}/dir_scanner_wasm.mjs`);
8279
8472
  await o.default({ module_or_path: t }), q = o.scan;
8280
8473
  } else {
8281
- const { readFile: i } = await U(), { join: t } = await import(
8474
+ const { readFile: i } = await z(), { join: t } = await import(
8282
8475
  /* webpackIgnore: true */
8283
8476
  "path"
8284
8477
  ), { pathToFileURL: e } = await import(
@@ -8288,7 +8481,7 @@ async function fr() {
8288
8481
  await a.default({ module_or_path: r }), q = a.scan;
8289
8482
  }
8290
8483
  }
8291
- const yr = "qlever", N = 1e3, mt = "cue:pending:";
8484
+ const Lr = "qlever", N = 1e3, mt = "cue:pending:";
8292
8485
  async function wt(i) {
8293
8486
  const { tmpdir: t } = await import(
8294
8487
  /* webpackIgnore: true */
@@ -8299,37 +8492,37 @@ async function wt(i) {
8299
8492
  );
8300
8493
  return e(t(), `cue-sync-pending-${i}.json`);
8301
8494
  }
8302
- async function te(i) {
8495
+ async function se(i) {
8303
8496
  if (typeof window < "u") {
8304
8497
  const t = window.localStorage.getItem(`${mt}${i}`);
8305
8498
  return t ? JSON.parse(t) : null;
8306
8499
  }
8307
8500
  try {
8308
- const t = await (await U()).readFile(await wt(i), "utf-8");
8501
+ const t = await (await z()).readFile(await wt(i), "utf-8");
8309
8502
  return JSON.parse(t);
8310
8503
  } catch {
8311
8504
  return null;
8312
8505
  }
8313
8506
  }
8314
- async function ee(i) {
8507
+ async function ae(i) {
8315
8508
  const t = JSON.stringify(i);
8316
8509
  if (typeof window < "u") {
8317
8510
  window.localStorage.setItem(`${mt}${i.spaceId}`, t);
8318
8511
  return;
8319
8512
  }
8320
- await (await U()).writeFile(await wt(i.spaceId), t, "utf-8");
8513
+ await (await z()).writeFile(await wt(i.spaceId), t, "utf-8");
8321
8514
  }
8322
- async function br(i) {
8515
+ async function qr(i) {
8323
8516
  if (typeof window < "u") {
8324
8517
  window.localStorage.removeItem(`${mt}${i}`);
8325
8518
  return;
8326
8519
  }
8327
8520
  try {
8328
- await (await U()).unlink(await wt(i));
8521
+ await (await z()).unlink(await wt(i));
8329
8522
  } catch {
8330
8523
  }
8331
8524
  }
8332
- class vr {
8525
+ class jr {
8333
8526
  constructor(t, e, o, r) {
8334
8527
  this._auth = t, this._projects = e, this._blob = o, this._gatewayUrl = r;
8335
8528
  }
@@ -8385,7 +8578,7 @@ class vr {
8385
8578
  */
8386
8579
  async flushPendingMetadata(t, e, o) {
8387
8580
  this._legacy = o ?? !1;
8388
- const r = await te(t);
8581
+ const r = await se(t);
8389
8582
  if (!(!r || r.items.length === 0)) {
8390
8583
  console.info(`Trying to upload metadata (${r.items.length} item(s))...`), e && console.info(`Flushing ${r.items.length} pending file location(s) from previous sync ⏳`);
8391
8584
  try {
@@ -8408,22 +8601,22 @@ class vr {
8408
8601
  this._api?.getConsumption(o) ?? Promise.reject(new Error("CueSyncApi is not bound to a CueApi instance")),
8409
8602
  this._fetchUnitCreditMap(s),
8410
8603
  this._fetchTierNames()
8411
- ]), f = (await Yt(t, h)).localNotOnRemote ?? [], E = f.length > 0 ? await this.scanCost(f) : [];
8412
- let w = 0, x = 0;
8413
- for (const v of E) {
8604
+ ]), f = (await ee(t, h)).localNotOnRemote ?? [], _ = f.length > 0 ? await this.scanCost(f) : [];
8605
+ let w = 0, E = 0;
8606
+ for (const v of _) {
8414
8607
  w += v.units;
8415
- const b = g[c], C = b?.[v.ext] ?? 1;
8608
+ const b = g[c], S = b?.[v.ext] ?? 1;
8416
8609
  s && b && !(v.ext in b) && console.info(` Unknown format: .${v.ext} (using default rate of 1 credit/unit)`);
8417
- const P = v.units * C;
8418
- x += P, v.credits = Math.round(P);
8610
+ const P = v.units * S;
8611
+ E += P, v.credits = Math.round(P);
8419
8612
  }
8420
8613
  const I = u[c] ?? c;
8421
8614
  return {
8422
- costRecords: E,
8615
+ costRecords: _,
8423
8616
  tier: c,
8424
8617
  tierName: I,
8425
8618
  unitsToConsume: w,
8426
- creditsToConsume: Math.round(x),
8619
+ creditsToConsume: Math.round(E),
8427
8620
  creditsAvailable: d.creditsAvailable,
8428
8621
  unitsAvailable: d.unitsAvailable,
8429
8622
  filesToUpload: f.length,
@@ -8440,44 +8633,44 @@ class vr {
8440
8633
  const [d, g] = await Promise.all([
8441
8634
  this._listRemoteFiles(h, o, r, a),
8442
8635
  this._api?.getConsumption(o) ?? Promise.reject(new Error("CueSyncApi is not bound to a CueApi instance"))
8443
- ]), { unitsAvailable: u } = g, m = await Yt(t, d);
8636
+ ]), { unitsAvailable: u } = g, m = await ee(t, d);
8444
8637
  a && (console.info(`Total local files: ${t.length}`), console.info(`Total remote files: ${d.length}`), console.info(
8445
8638
  `Total files to sync: ${(m.localNotOnRemote?.length ?? 0) + m.localNotOnRemotePathOnly.length}`
8446
8639
  ));
8447
- let f = m.syncCount, E = m.syncSize, w = 0, x = !1;
8640
+ let f = m.syncCount, _ = m.syncSize, w = 0, E = !1;
8448
8641
  const I = m.localNotOnRemote ?? [];
8449
8642
  if (I.length > 0) {
8450
- const C = (await this.scanCost(I)).reduce((P, ye) => P + ye.units, 0);
8451
- if (C > u)
8643
+ const S = (await this.scanCost(I)).reduce((P, ke) => P + ke.units, 0);
8644
+ if (S > u)
8452
8645
  throw new Error(
8453
- `Insufficient units: ${C} units required but only ${u} available.`
8646
+ `Insufficient units: ${S} units required but only ${u} available.`
8454
8647
  );
8455
8648
  }
8456
8649
  await this._initPendingBatch(o, a), a && I.length && console.info("Syncing missing files ⏳");
8457
8650
  for (const b of I)
8458
8651
  try {
8459
- const C = Zt(
8652
+ const S = oe(
8460
8653
  b.relativePath,
8461
8654
  o,
8462
8655
  s,
8463
8656
  b.md5,
8464
8657
  r
8465
8658
  );
8466
- if (!C.blob_name) throw new Error(`blob_name missing for ${b.relativePath}`);
8467
- const P = b.data ?? new Uint8Array(await Jt(b.fullPath));
8659
+ if (!S.blob_name) throw new Error(`blob_name missing for ${b.relativePath}`);
8660
+ const P = b.data ?? new Uint8Array(await re(b.fullPath));
8468
8661
  await this._blob.uploadRaw(
8469
- C.blob_name,
8662
+ S.blob_name,
8470
8663
  P,
8471
- C
8664
+ S
8472
8665
  ), await this._queueFileLocation({
8473
8666
  relativePath: b.relativePath,
8474
8667
  md5: b.md5,
8475
8668
  size: b.size,
8476
8669
  providerId: r,
8477
8670
  fileContentExists: !1
8478
- }), x = !0, f += 1, E += b.size || 0, this._logProgress(f, m.totalCount, E, m.totalSize, n);
8479
- } catch (C) {
8480
- w += 1, console.error(`[CueSyncApi] Failed to upload file: ${b.fullPath}`), a && console.error("[CueSyncApi] Upload error details:", C);
8671
+ }), E = !0, f += 1, _ += b.size || 0, this._logProgress(f, m.totalCount, _, m.totalSize, n);
8672
+ } catch (S) {
8673
+ w += 1, console.error(`[CueSyncApi] Failed to upload file: ${b.fullPath}`), a && console.error("[CueSyncApi] Upload error details:", S);
8481
8674
  }
8482
8675
  a && m.localNotOnRemotePathOnly.length && console.info(`Syncing missing file locations (on provider "${r}") ⏳`);
8483
8676
  for (const b of m.localNotOnRemotePathOnly)
@@ -8487,23 +8680,23 @@ class vr {
8487
8680
  size: b.size,
8488
8681
  providerId: r,
8489
8682
  fileContentExists: !0
8490
- }), x = !0, f += 1, E += b.size || 0, this._logProgress(f, m.totalCount, E, m.totalSize, n);
8683
+ }), E = !0, f += 1, _ += b.size || 0, this._logProgress(f, m.totalCount, _, m.totalSize, n);
8491
8684
  await this._drainPending(a), this._stopFlushTimer();
8492
8685
  const v = await (this._api?.getConsumption(o) ?? Promise.resolve({ creditsAvailable: 0 }));
8493
8686
  return {
8494
8687
  syncCount: f,
8495
- syncSize: E,
8688
+ syncSize: _,
8496
8689
  failedUploads: w,
8497
8690
  totalCount: m.totalCount,
8498
8691
  totalSize: m.totalSize,
8499
- rdfWritten: x,
8692
+ rdfWritten: E,
8500
8693
  creditsAvailable: v.creditsAvailable
8501
8694
  };
8502
8695
  }
8503
8696
  async _getOrCreateGraph(t, e) {
8504
8697
  const o = this._graphMap.get(t);
8505
8698
  if (o) return o;
8506
- const s = (await this._projects.getProject(t))?.projectSettings?.graph?.type ?? yr, a = s === "qlever" ? `${this._gatewayUrl}${pe}` : `${this._gatewayUrl}${ne}`, n = s === "qlever" ? `${this._gatewayUrl}${go}` : `${this._gatewayUrl}${co}`, p = new Je({
8699
+ const s = (await this._projects.getProject(t))?.projectSettings?.graph?.type ?? Lr, a = s === "qlever" ? `${this._gatewayUrl}${de}` : `${this._gatewayUrl}${he}`, n = s === "qlever" ? `${this._gatewayUrl}${yo}` : `${this._gatewayUrl}${wo}`, p = new so({
8507
8700
  graphType: s,
8508
8701
  queryEndpoint: a,
8509
8702
  updateEndpoint: n,
@@ -8569,7 +8762,7 @@ WHERE {
8569
8762
  }
8570
8763
  async _initPendingBatch(t, e) {
8571
8764
  this._flushTimer !== null && (clearInterval(this._flushTimer), this._flushTimer = null), this._pendingSpaceId = t, this._pendingItems = [];
8572
- const o = await te(t);
8765
+ const o = await se(t);
8573
8766
  if (o && o.items.length > 0) {
8574
8767
  console.info(`Trying to upload metadata from interrupted sync (${o.items.length} item(s))...`), e && console.info(`Flushing ${o.items.length} pending file location(s) from previous sync ⏳`);
8575
8768
  try {
@@ -8590,7 +8783,7 @@ WHERE {
8590
8783
  typeof r == "object" && typeof r.unref == "function" && r.unref(), this._flushTimer = r;
8591
8784
  }
8592
8785
  async _queueFileLocation(t) {
8593
- this._pendingItems.push(t), this._pendingSpaceId && await ee({ spaceId: this._pendingSpaceId, items: this._pendingItems });
8786
+ this._pendingItems.push(t), this._pendingSpaceId && await ae({ spaceId: this._pendingSpaceId, items: this._pendingItems });
8594
8787
  }
8595
8788
  /**
8596
8789
  * Flush all queued file-location items to the commands API in a single batch.
@@ -8605,18 +8798,18 @@ WHERE {
8605
8798
  }
8606
8799
  async _flushBatch(t, e, o) {
8607
8800
  const r = [...t];
8608
- this._pendingSpaceId === e && (this._pendingItems = []), await br(e);
8801
+ this._pendingSpaceId === e && (this._pendingItems = []), await qr(e);
8609
8802
  try {
8610
8803
  for (let s = 0; s < r.length; s += N)
8611
8804
  await this._postFssBatch(r.slice(s, s + N), e);
8612
8805
  o && console.info(`Wrote ${r.length} file location(s) to commands API ✅`);
8613
8806
  } catch (s) {
8614
8807
  const a = [...r, ...this._pendingItems];
8615
- throw this._pendingItems = a, await ee({ spaceId: e, items: a }), s;
8808
+ throw this._pendingItems = a, await ae({ spaceId: e, items: a }), s;
8616
8809
  }
8617
8810
  }
8618
8811
  async _postFssBatch(t, e) {
8619
- const o = this._legacy ? `${this._gatewayUrl}${Lt}?blob=true` : `${this._gatewayUrl}${Lt}`;
8812
+ const o = this._legacy ? `${this._gatewayUrl}${qt}?blob=true` : `${this._gatewayUrl}${qt}`;
8620
8813
  let r;
8621
8814
  try {
8622
8815
  r = await this._auth.authenticatedFetch(o, {
@@ -8646,14 +8839,14 @@ WHERE {
8646
8839
  * shown to the user before or after calling {@link sync}.
8647
8840
  */
8648
8841
  async scanCost(t) {
8649
- if (G || (G = fr()), await G, !q) throw new Error("WASM scan function not initialised");
8842
+ if (G || (G = Dr()), await G, !q) throw new Error("WASM scan function not initialised");
8650
8843
  const e = 200, o = /* @__PURE__ */ new Map();
8651
8844
  for (let r = 0; r < t.length; r += e) {
8652
8845
  const s = t.slice(r, r + e), a = await Promise.all(
8653
8846
  s.map(async (p) => ({
8654
8847
  originalPath: p.relativePath,
8655
8848
  // Use pre-loaded data if available (browser), otherwise read from disk (Node.js).
8656
- data: p.data ?? new Uint8Array(await Jt(p.fullPath))
8849
+ data: p.data ?? new Uint8Array(await re(p.fullPath))
8657
8850
  }))
8658
8851
  ), n = q(a);
8659
8852
  for (const p of n) {
@@ -8713,7 +8906,7 @@ WHERE {
8713
8906
  const { spaceId: o, providerId: r, userId: s, signal: a, onProgress: n } = e;
8714
8907
  if (!t.data)
8715
8908
  throw new Error("syncBrowserFile requires file.data (Uint8Array). Read the file with File.arrayBuffer() first.");
8716
- const p = Zt(t.relativePath, o, s, t.md5, r);
8909
+ const p = oe(t.relativePath, o, s, t.md5, r);
8717
8910
  if (!p.blob_name) throw new Error(`blob_name missing for ${t.relativePath}`);
8718
8911
  await this._blob.uploadRaw(
8719
8912
  p.blob_name,
@@ -8757,7 +8950,7 @@ WHERE {
8757
8950
  s({ percent: a, syncCount: t, totalCount: e, syncSize: o, totalSize: r });
8758
8951
  }
8759
8952
  }
8760
- const oe = {
8953
+ const ie = {
8761
8954
  production: {
8762
8955
  gatewayUrl: "https://accessors-api-gateway-ueyeemwf2a-oa.a.run.app",
8763
8956
  tokenUrl: "https://accessors-api-gateway-ueyeemwf2a-oa.a.run.app/token",
@@ -8777,7 +8970,7 @@ const oe = {
8777
8970
  firestoreEmulatorPort: 8080
8778
8971
  }
8779
8972
  };
8780
- class fe {
8973
+ class Ee {
8781
8974
  auth;
8782
8975
  api;
8783
8976
  projects;
@@ -8805,7 +8998,7 @@ class fe {
8805
8998
  * ```
8806
8999
  */
8807
9000
  get gis() {
8808
- return this._gis || (this._gis = new ir(
9001
+ return this._gis || (this._gis = new mr(
8809
9002
  () => this.api.getAuthHeaders(),
8810
9003
  this._endpoints.gatewayUrl
8811
9004
  )), this._gis;
@@ -8815,30 +9008,29 @@ class fe {
8815
9008
  "Using default SDK app settings. Contact QAECY for your own configuration for any production code."
8816
9009
  );
8817
9010
  const o = t.apiKey ?? Z.apiKey, r = t.appId ?? Z.appId, s = t.measurementId ?? Z.measurementId, a = t.environment ?? "production";
8818
- this._endpoints = { ...oe[a], ...t.endpoints }, this._isEmulator = a === "emulator", this._verbose = t.verbose ?? !1, this._app = be().find((g) => g.name === "[DEFAULT]") ?? ve({
9011
+ this._endpoints = { ...ie[a], ...t.endpoints }, this._isEmulator = a === "emulator", this._verbose = t.verbose ?? !1, this._app = xe().find((g) => g.name === "[DEFAULT]") ?? Ce({
8819
9012
  apiKey: o,
8820
9013
  appId: r,
8821
9014
  measurementId: s,
8822
9015
  authDomain: `${xt}.firebaseapp.com`,
8823
9016
  projectId: xt,
8824
- messagingSenderId: oo
8825
- }), this.auth = new Ut(this._app, this._isEmulator, this._endpoints), this.projects = new Ht(this.auth, this._app, this._isEmulator, this._endpoints), this._storageRaw = S(this._app, St), this._storageProcessed = S(this._app, Tt);
8826
- const n = S(this._app, At), p = S(this._app, Rt), c = S(this._app, Ct), h = S(this._app, Pt);
8827
- this._isEmulator && (X(this._storageRaw, this._endpoints.storageEmulatorHost, this._endpoints.storageEmulatorPort), X(this._storageProcessed, this._endpoints.storageEmulatorHost, this._endpoints.storageEmulatorPort)), this.api = this._buildApi(this.projects);
8828
- const d = new kt({
9017
+ messagingSenderId: no
9018
+ }), this.auth = new $t(this._app, this._isEmulator, this._endpoints), this.projects = new Wt(this.auth, this._app, this._isEmulator, this._endpoints), this._storageRaw = C(this._app, Tt), this._storageProcessed = C(this._app, Rt);
9019
+ const n = C(this._app, Pt), p = C(this._app, At), c = C(this._app, St), h = C(this._app, Ot), d = C(this._app, It);
9020
+ this._isEmulator && (K(this._storageRaw, this._endpoints.storageEmulatorHost, this._endpoints.storageEmulatorPort), K(this._storageProcessed, this._endpoints.storageEmulatorHost, this._endpoints.storageEmulatorPort)), this.api = this._buildApi(this.projects), new Et({
8829
9021
  storageRaw: this._storageRaw,
8830
9022
  storageProcessed: this._storageProcessed,
8831
9023
  storagePublic: n,
8832
9024
  storageLogs: p,
8833
9025
  storageChatSessions: c,
8834
- storagePersistence: h
8835
- });
8836
- this.storage = new zt(d), this.profile = new Wt(
9026
+ storagePersistence: h,
9027
+ storageSessions: d
9028
+ }), this.storage = new Ut(this.auth, this._endpoints.gatewayUrl), this.profile = new Vt(
8837
9029
  this.auth,
8838
9030
  this._app,
8839
9031
  this._isEmulator,
8840
9032
  this._endpoints.gatewayUrl
8841
- ), this.privileges = new Xt(this.auth.isSuperAdmin), this._isEmulator && X(h, this._endpoints.storageEmulatorHost, this._endpoints.storageEmulatorPort), this.cache = new Qt(h);
9033
+ ), this.privileges = new Qt(this.auth.isSuperAdmin), this._isEmulator && K(h, this._endpoints.storageEmulatorHost, this._endpoints.storageEmulatorPort), this.cache = new Yt(h);
8842
9034
  }
8843
9035
  /**
8844
9036
  * Create a `Cue` instance from an already-initialized Firebase app.
@@ -8857,34 +9049,35 @@ class fe {
8857
9049
  * });
8858
9050
  */
8859
9051
  static fromApp(t, e = {}) {
8860
- const o = e.environment ?? "production", r = { ...oe[o], ...e.endpoints }, s = new Ut(t, !1, r), a = new Ht(s, t, !1, r), n = S(t, St), p = S(t, Tt), c = S(t, At), h = S(t, Rt), d = S(t, Ct), g = S(t, Pt), u = new kt({
9052
+ const o = e.environment ?? "production", r = { ...ie[o], ...e.endpoints }, s = new $t(t, !1, r), a = new Wt(s, t, !1, r), n = C(t, Tt), p = C(t, Rt), c = C(t, Pt), h = C(t, At), d = C(t, St), g = C(t, Ot), u = C(t, It), m = new Et({
8861
9053
  storageRaw: n,
8862
9054
  storageProcessed: p,
8863
9055
  storagePublic: c,
8864
9056
  storageLogs: h,
8865
9057
  storageChatSessions: d,
8866
- storagePersistence: g
8867
- }), m = new vr(s, a, u, r.gatewayUrl), f = new $t(s, r.gatewayUrl, a, m);
8868
- m._bindApi(f);
8869
- const E = new Wt(s, t, !1, r.gatewayUrl), w = Object.create(fe.prototype), x = new Xt(s.isSuperAdmin), I = new Qt(g), v = new zt(u);
8870
- return Object.assign(w, {
9058
+ storagePersistence: g,
9059
+ storageSessions: u
9060
+ }), f = new jr(s, a, m, r.gatewayUrl), _ = new Mt(s, r.gatewayUrl, a, f);
9061
+ f._bindApi(_);
9062
+ const w = new Vt(s, t, !1, r.gatewayUrl), E = Object.create(Ee.prototype), I = new Qt(s.isSuperAdmin), v = new Yt(g), b = new Ut(s, r.gatewayUrl);
9063
+ return Object.assign(E, {
8871
9064
  _app: t,
8872
9065
  _endpoints: r,
8873
9066
  _isEmulator: o === "emulator",
8874
9067
  _storageRaw: n,
8875
9068
  _storageProcessed: p,
8876
9069
  auth: s,
8877
- api: f,
9070
+ api: _,
8878
9071
  projects: a,
8879
- profile: E,
8880
- privileges: x,
8881
- cache: I,
8882
- storage: v
8883
- }), w;
9072
+ profile: w,
9073
+ privileges: I,
9074
+ cache: v,
9075
+ storage: b
9076
+ }), E;
8884
9077
  }
8885
9078
  /** Override in subclasses to provide a custom CueApi (e.g. with sync). */
8886
9079
  _buildApi(t) {
8887
- return new $t(this.auth, this._endpoints.gatewayUrl, t);
9080
+ return new Mt(this.auth, this._endpoints.gatewayUrl, t);
8888
9081
  }
8889
9082
  /** Convenience: get the current user's Firebase ID token */
8890
9083
  getToken(t = !1) {
@@ -8909,7 +9102,7 @@ class fe {
8909
9102
  get: (r) => this.cache.getQueryCache(t, r).then((s) => s?.results),
8910
9103
  set: (r, s) => this.cache.setQueryCache(t, r, { query: r, results: s })
8911
9104
  };
8912
- return new hr(this.api, t, { verbose: this._verbose, ...e, queryCache: o });
9105
+ return new Sr(this.api, t, { verbose: this._verbose, ...e, queryCache: o });
8913
9106
  }
8914
9107
  /**
8915
9108
  * Creates a `CueProjectEntities` instance for the given project, with the
@@ -8933,7 +9126,7 @@ class fe {
8933
9126
  get: (r) => this.cache.getQueryCache(t, r).then((s) => s?.results),
8934
9127
  set: (r, s) => this.cache.setQueryCache(t, r, { query: r, results: s })
8935
9128
  };
8936
- return new we(
9129
+ return new _e(
8937
9130
  this.api,
8938
9131
  t,
8939
9132
  e?.rdfBase,
@@ -8964,7 +9157,7 @@ class fe {
8964
9157
  const a = {
8965
9158
  get: (p) => this.cache.getQueryCache(t, p).then((c) => c?.results),
8966
9159
  set: (p, c) => this.cache.setQueryCache(t, p, { query: p, results: c })
8967
- }, n = new ct(
9160
+ }, n = new lt(
8968
9161
  this.api,
8969
9162
  t,
8970
9163
  this.api.language,
@@ -8979,7 +9172,7 @@ class fe {
8979
9172
  get: (s) => this.cache.getQueryCache(t, s).then((a) => a?.results),
8980
9173
  set: (s, a) => this.cache.setQueryCache(t, s, { query: s, results: a })
8981
9174
  };
8982
- return new ct(
9175
+ return new lt(
8983
9176
  this.api,
8984
9177
  t,
8985
9178
  e?.language ?? this.api.language,
@@ -8991,30 +9184,32 @@ class fe {
8991
9184
  }
8992
9185
  }
8993
9186
  export {
8994
- Ct as B,
8995
- fe as C,
9187
+ St as B,
9188
+ Ee as C,
8996
9189
  Kt as R,
8997
- $t as a,
8998
- Ut as b,
8999
- Qt as c,
9000
- bo as d,
9001
- ir as e,
9002
- Xt as f,
9003
- Wt as g,
9004
- ct as h,
9005
- we as i,
9006
- lr as j,
9007
- hr as k,
9008
- Ht as l,
9009
- k as m,
9010
- zt as n,
9011
- vr as o,
9012
- fo as p,
9013
- Lr as q,
9014
- dt as r,
9015
- gt as s,
9016
- Rt as t,
9017
- Pt as u,
9018
- At as v,
9019
- kt as w
9190
+ Mt as a,
9191
+ $t as b,
9192
+ Yt as c,
9193
+ To as d,
9194
+ So as e,
9195
+ mr as f,
9196
+ Qt as g,
9197
+ Vt as h,
9198
+ lt as i,
9199
+ _e as j,
9200
+ Er as k,
9201
+ Sr as l,
9202
+ Wt as m,
9203
+ x as n,
9204
+ Ut as o,
9205
+ jr as p,
9206
+ Co as q,
9207
+ Qr as r,
9208
+ dt as s,
9209
+ gt as t,
9210
+ At as u,
9211
+ Ot as v,
9212
+ Pt as w,
9213
+ It as x,
9214
+ Et as y
9020
9215
  };