@wral/studio.ui.search-filter 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,17 @@
1
+ import { S as O } from "./search-filter-B-aiJCKp.js";
2
+ import { DATE_OPS as a, DEFAULT_BOOLEANS as t, DEFAULT_OPERATORS as l, NUM_OPS as o, TEXT_OPS as E, URL_OPS as P, VIDEO_OPS as _, createQueryModel as T, equivalent as i, publicationPreset as A, resolveLabels as L, validateSyntax as s } from "./model.mjs";
3
+ export {
4
+ a as DATE_OPS,
5
+ t as DEFAULT_BOOLEANS,
6
+ l as DEFAULT_OPERATORS,
7
+ o as NUM_OPS,
8
+ O as SearchFilter,
9
+ E as TEXT_OPS,
10
+ P as URL_OPS,
11
+ _ as VIDEO_OPS,
12
+ T as createQueryModel,
13
+ i as equivalent,
14
+ A as publicationPreset,
15
+ L as resolveLabels,
16
+ s as validateSyntax
17
+ };
package/dist/model.mjs ADDED
@@ -0,0 +1,582 @@
1
+ const C = {
2
+ fields: {
3
+ tag: {
4
+ label: "Tag",
5
+ path: "tags.name",
6
+ type: "text",
7
+ hint: "e.g. UNC sports"
8
+ },
9
+ title: {
10
+ label: "Headline",
11
+ path: "metadata.title",
12
+ type: "text",
13
+ hint: "e.g. hurricane"
14
+ },
15
+ body: {
16
+ label: "Summary",
17
+ path: "metadata.description",
18
+ type: "text",
19
+ hint: "e.g. storm damage"
20
+ },
21
+ author: {
22
+ label: "Author",
23
+ path: "metadata.author",
24
+ type: "text",
25
+ hint: "e.g. Brian Murphy"
26
+ },
27
+ uri: {
28
+ label: "Article URL",
29
+ path: "uri",
30
+ type: "url",
31
+ hint: "e.g. https://www.wral.com/sports/"
32
+ },
33
+ site: {
34
+ label: "Site",
35
+ path: "site",
36
+ type: "text",
37
+ hint: "e.g. highschoolot.com"
38
+ },
39
+ date: {
40
+ label: "Published",
41
+ path: "metadata.articlePublishedTime",
42
+ type: "date"
43
+ },
44
+ updated: {
45
+ label: "Updated",
46
+ path: "metadata.articleModifiedTime",
47
+ type: "date"
48
+ },
49
+ // combined hero-video field: "has a video" tests
50
+ // _exists_:metadata.ogVideo, the duration ops filter
51
+ // metadata.ogVideoDuration (seconds).
52
+ video: {
53
+ label: "Has hero video",
54
+ path: "metadata.ogVideo",
55
+ type: "video",
56
+ durationPath: "metadata.ogVideoDuration",
57
+ hint: "duration in seconds, e.g. 60"
58
+ },
59
+ // the default search field: a bare term with no `field:` prefix,
60
+ // matching the backend's full-text default. Used for legacy
61
+ // bare-phrase queries.
62
+ any: {
63
+ label: "Any field",
64
+ path: "",
65
+ type: "text",
66
+ hint: "e.g. hurricane"
67
+ }
68
+ },
69
+ defaults: {
70
+ field: "title",
71
+ conditional: {
72
+ if: { field: "tag", op: "term" },
73
+ then: { field: "uri", op: "under", negate: !0 },
74
+ else: { field: "uri", op: "under" }
75
+ }
76
+ },
77
+ labels: {
78
+ itemNoun: "story",
79
+ itemNounPlural: "stories"
80
+ }
81
+ }, Y = [
82
+ { id: "phrase", label: "contains the phrase" },
83
+ { id: "term", label: "matches the word" },
84
+ { id: "starts", label: "starts with" },
85
+ { id: "fuzzy", label: "sounds like (fuzzy)" },
86
+ { id: "exists", label: "has any value" }
87
+ ], ee = [
88
+ { id: "is", label: "is exactly" },
89
+ { id: "under", label: "is anywhere under" }
90
+ ], te = [
91
+ { id: "after", label: "is on or after" },
92
+ { id: "before", label: "is on or before" },
93
+ { id: "between", label: "is between" }
94
+ ], ne = [
95
+ { id: "gte", label: "is at least" },
96
+ { id: "lte", label: "is at most" },
97
+ { id: "between", label: "is between" }
98
+ ], ie = [
99
+ { id: "exists", label: "has a video" },
100
+ { id: "longer", label: "is longer than (sec)" },
101
+ { id: "shorter", label: "is shorter than (sec)" },
102
+ { id: "between", label: "duration between (sec)" }
103
+ ], P = {
104
+ text: Y,
105
+ url: ee,
106
+ date: te,
107
+ number: ne,
108
+ video: ie
109
+ }, H = [
110
+ { id: "AND", label: "all" },
111
+ { id: "OR", label: "any" }
112
+ ], w = (t) => {
113
+ throw new Error(`search-filter: ${t}`);
114
+ };
115
+ function V(t, i, e) {
116
+ const r = new Set(P[i].map((o) => o.id));
117
+ return (!Array.isArray(t) || !t.length) && w(`${e} must be a non-empty array of { id, label }`), t.map((o) => ((!o || !r.has(o.id)) && w(`${e} has unknown ${i} operator id "${o && o.id}" (known: ${[...r].join(", ")})`), { id: o.id, label: o.label || o.id }));
118
+ }
119
+ function oe(t, i = {}) {
120
+ const e = Object.keys(t || {});
121
+ e.length || w("the fields catalog is empty");
122
+ const r = {};
123
+ for (const o of e) {
124
+ const l = t[o] || {}, a = l.type || "text";
125
+ P[a] || w(`field "${o}" has unknown type "${a}" (known: ${Object.keys(P).join(", ")})`), typeof l.path != "string" && w(`field "${o}" needs a string path ('' targets the backend's default field)`), a === "video" && !l.durationPath && w(`field "${o}" is type video and needs a durationPath`);
126
+ const c = l.ops ? V(l.ops, a, `field "${o}" ops`) : i[a] ? V(i[a], a, `operators.${a}`) : P[a];
127
+ r[o] = {
128
+ label: l.label || o,
129
+ path: l.path,
130
+ type: a,
131
+ hint: l.hint || "",
132
+ durationPath: l.durationPath || "",
133
+ ops: c
134
+ };
135
+ }
136
+ return r;
137
+ }
138
+ function re(t) {
139
+ if (t == null) return H;
140
+ const i = new Set(H.map((e) => e.id));
141
+ return (!Array.isArray(t) || !t.length) && w("booleans must be a non-empty array of { id, label }"), t.map((e) => ((!e || !i.has(e.id)) && w(`unknown boolean operator "${e && e.id}" (known: AND, OR)`), { id: e.id, label: e.label || e.id }));
142
+ }
143
+ let le = 0;
144
+ const A = () => "n" + ++le, S = (t) => String(t).replace(/(["\\])/g, "\\$1"), U = (t) => S(t).replace(/\s+/g, "\\ ");
145
+ function L(t) {
146
+ const i = [];
147
+ let e = 0;
148
+ const r = t.length;
149
+ for (; e < r; ) {
150
+ const o = t[e];
151
+ if (o === " " || o === " " || o === `
152
+ `) {
153
+ e++;
154
+ continue;
155
+ }
156
+ if (o === "(" || o === ")") {
157
+ i.push(o), e++;
158
+ continue;
159
+ }
160
+ let l = "";
161
+ for (; e < r; ) {
162
+ const a = t[e];
163
+ if (a === "\\" && e + 1 < r) {
164
+ l += a + t[e + 1], e += 2;
165
+ continue;
166
+ }
167
+ if (a === " " || a === "(" || a === ")") break;
168
+ if (a === '"') {
169
+ for (l += a, e++; e < r; ) {
170
+ if (l += t[e], t[e] === '"' && t[e - 1] !== "\\") {
171
+ e++;
172
+ break;
173
+ }
174
+ e++;
175
+ }
176
+ continue;
177
+ }
178
+ if (a === "[") {
179
+ for (l += a, e++; e < r; ) {
180
+ if (l += t[e], t[e] === "]") {
181
+ e++;
182
+ break;
183
+ }
184
+ e++;
185
+ }
186
+ continue;
187
+ }
188
+ l += a, e++;
189
+ }
190
+ l === "AND" || l === "OR" || l === "NOT" ? i.push(l) : l === "&&" ? i.push("AND") : l === "||" ? i.push("OR") : i.push({ term: l });
191
+ }
192
+ return i;
193
+ }
194
+ function z(t, i) {
195
+ if (t.startsWith("[")) {
196
+ const l = t.match(/^\[(.+) TO (.+)\]$/) || [null, "*", "*"], a = l[1], c = l[2];
197
+ return a === "*" ? { op: i === "number" ? "lte" : "before", value: c } : c === "*" ? { op: i === "number" ? "gte" : "after", value: a } : { op: "between", value: a, value2: c };
198
+ }
199
+ if (t.startsWith('"'))
200
+ return {
201
+ op: i === "url" ? "under" : "phrase",
202
+ value: t.slice(1, -1).replace(/\\(.)/g, "$1")
203
+ };
204
+ let e = t, r = "";
205
+ return e.endsWith("*") ? (r = "*", e = e.slice(0, -1)) : e.endsWith("~") && (r = "~", e = e.slice(0, -1)), e = e.replace(/\\ /g, " ").replace(/\\(.)/g, "$1"), { op: i === "url" ? "under" : r === "*" ? "starts" : r === "~" ? "fuzzy" : "term", value: e };
206
+ }
207
+ function se(t, i) {
208
+ let e = 0;
209
+ const r = () => t[e], o = () => t[e++];
210
+ function l() {
211
+ let $ = !1;
212
+ for (; r() === "NOT"; )
213
+ $ = !$, o();
214
+ let h;
215
+ if (r() === "(")
216
+ o(), h = c(), r() === ")" && o();
217
+ else {
218
+ const g = o();
219
+ if (!g || typeof g == "string")
220
+ throw new Error("Unexpected token");
221
+ h = i(g);
222
+ }
223
+ return $ && (h.negate = !h.negate), h;
224
+ }
225
+ function a() {
226
+ const $ = l(), h = [$];
227
+ for (; ; ) {
228
+ const g = r();
229
+ if (g === "AND")
230
+ o(), h.push(l());
231
+ else if (g !== void 0 && g !== ")" && g !== "OR") h.push(l());
232
+ else break;
233
+ }
234
+ return h.length === 1 ? $ : {
235
+ id: A(),
236
+ kind: "group",
237
+ op: "AND",
238
+ negate: !1,
239
+ children: h
240
+ };
241
+ }
242
+ function c() {
243
+ const $ = a(), h = [$];
244
+ for (; r() === "OR"; )
245
+ o(), h.push(a());
246
+ return h.length === 1 ? $ : {
247
+ id: A(),
248
+ kind: "group",
249
+ op: "OR",
250
+ negate: !1,
251
+ children: h
252
+ };
253
+ }
254
+ const v = c();
255
+ if (e < t.length) throw new Error("Unexpected trailing tokens");
256
+ return v;
257
+ }
258
+ function ae(t, i) {
259
+ let e = "", r = t;
260
+ return r.startsWith("-") && (e = "-", r = r.slice(1)), M.has(r) || /^[A-Za-z_][\w.$]*:/.test(r) ? t : e + i + ":" + r;
261
+ }
262
+ function E(t) {
263
+ const i = (r) => r && typeof r == "object", e = [];
264
+ for (let r = 0; r < t.length; r++) {
265
+ const o = t[r], l = i(o) && /^(-?)([A-Za-z_][\w.$]*):$/.exec(o.term);
266
+ if (l && t[r + 1] === "(") {
267
+ let a = 0, c = r + 1;
268
+ for (; c < t.length; c++)
269
+ if (t[c] === "(") a++;
270
+ else if (t[c] === ")" && --a === 0) break;
271
+ if (c < t.length) {
272
+ l[1] === "-" && e.push("NOT"), e.push("(");
273
+ for (const v of E(t.slice(r + 2, c)))
274
+ e.push(i(v) ? { term: ae(v.term, l[2]) } : v);
275
+ e.push(")"), r = c;
276
+ continue;
277
+ }
278
+ }
279
+ e.push(o);
280
+ }
281
+ return e;
282
+ }
283
+ function me(t) {
284
+ let i = 0, e = 0;
285
+ for (const r of t)
286
+ if (r === "(" ? i++ : r === ")" ? i-- : r === '"' && e++, i < 0) break;
287
+ return i !== 0 ? "Unbalanced parentheses." : e % 2 !== 0 ? "Unbalanced quotes." : "";
288
+ }
289
+ const M = /* @__PURE__ */ new Set(["AND", "OR", "NOT"]);
290
+ function ue(t) {
291
+ const i = t.indexOf(":");
292
+ return i < 0 ? null : { field: t.slice(0, i), value: t.slice(i + 1) };
293
+ }
294
+ function de(t) {
295
+ const i = ue(t);
296
+ if (!i) return t;
297
+ let e = i.value;
298
+ if (e.length > 1 && e.startsWith('"') && e.endsWith('"')) {
299
+ const r = e.slice(1, -1);
300
+ r && !/\s/.test(r) && (e = r);
301
+ }
302
+ return i.field + ":" + e;
303
+ }
304
+ function fe(t) {
305
+ let i = t.slice();
306
+ for (let e = !0; e; ) {
307
+ e = !1;
308
+ for (let r = 0; r + 2 < i.length; r++)
309
+ if (i[r] === "(" && i[r + 2] === ")" && i[r + 1] !== "(" && i[r + 1] !== ")") {
310
+ i.splice(r, 3, i[r + 1]), e = !0;
311
+ break;
312
+ }
313
+ if (!e && i.length >= 2 && i[0] === "(" && i[i.length - 1] === ")") {
314
+ let r = 0, o = !0;
315
+ for (let l = 0; l < i.length; l++)
316
+ if (i[l] === "(") r++;
317
+ else if (i[l] === ")" && --r === 0 && l !== i.length - 1) {
318
+ o = !1;
319
+ break;
320
+ }
321
+ o && (i = i.slice(1, -1), e = !0);
322
+ }
323
+ }
324
+ return i;
325
+ }
326
+ function ce(t) {
327
+ return t[0] === "!" ? "-" + t.slice(1) : t;
328
+ }
329
+ function D(t) {
330
+ const i = E(L(t)).map((o) => typeof o == "string" ? o : o.term).map(ce), e = [];
331
+ for (let o = 0; o < i.length; o++) {
332
+ const l = i[o];
333
+ if (l === "NOT" && o + 1 < i.length && i[o + 1] !== "(" && !M.has(i[o + 1])) {
334
+ const a = i[++o];
335
+ e.push(a.startsWith("-") ? a.slice(1) : "-" + a);
336
+ } else
337
+ e.push(l);
338
+ }
339
+ return fe(
340
+ e.filter((o) => o !== "AND").map(de)
341
+ ).join(" ");
342
+ }
343
+ function pe(t) {
344
+ const i = (o) => o === "AND" || o === "OR" || o === "NOT", e = (o) => o === ")" || !i(o) && o !== "(", r = (o) => o === "(" || !i(o) && o !== ")" && o[0] !== "-" && o[0] !== "!" && o[0] !== "+";
345
+ for (let o = 0; o + 1 < t.length; o++)
346
+ if (e(t[o]) && r(t[o + 1])) return !0;
347
+ return !1;
348
+ }
349
+ function ge(t, i) {
350
+ if (t === i) return !0;
351
+ try {
352
+ return D(t || "") === D(i || "");
353
+ } catch {
354
+ return !1;
355
+ }
356
+ }
357
+ function $e(t = {}) {
358
+ const i = t.fields == null, e = oe(
359
+ t.fields ?? C.fields,
360
+ t.operators
361
+ ), r = re(t.booleans), o = new Set(r.map((n) => n.id)), l = t.defaults ?? (i ? C.defaults : null), a = Object.keys(e), c = (n) => a.find((s) => e[s].path === n), v = (n, s) => e[n].ops.some((u) => u.id === s), $ = (n, s) => {
362
+ n && (e[n.field] || w(`${s} names unknown field "${n.field}"`), n.op && !v(n.field, n.op) && w(`${s} uses operator "${n.op}" not offered for field "${n.field}"`));
363
+ };
364
+ l?.field && !e[l.field] && w(`defaults.field names unknown field "${l.field}"`), $(l?.conditional?.if, "defaults.conditional.if"), $(l?.conditional?.then, "defaults.conditional.then"), $(l?.conditional?.else, "defaults.conditional.else");
365
+ const h = l?.field || a[0], g = (n = h, s = {}) => ({
366
+ id: A(),
367
+ kind: "rule",
368
+ field: n,
369
+ op: e[n].ops[0].id,
370
+ value: "",
371
+ value2: "",
372
+ negate: !1,
373
+ boost: "",
374
+ ...s
375
+ }), O = (n = r[0].id, s = null) => ({
376
+ id: A(),
377
+ kind: "group",
378
+ op: n,
379
+ negate: !1,
380
+ children: s || [g()]
381
+ }), R = (n) => n ? g(n.field, {
382
+ ...n.op ? { op: n.op } : {},
383
+ ...n.negate ? { negate: !0 } : {}
384
+ }) : g(), Q = () => ({
385
+ id: A(),
386
+ kind: "conditional",
387
+ cond: O("AND", [R(l?.conditional?.if)]),
388
+ then: O("AND", [R(l?.conditional?.then)]),
389
+ els: O("AND", [R(l?.conditional?.else)])
390
+ }), G = () => O("AND", [R(l?.conditional?.else)]);
391
+ function j(n) {
392
+ const s = e[n.field], u = s.path;
393
+ if (s.type === "video") {
394
+ let m = "";
395
+ if (n.op === "exists")
396
+ m = `_exists_:${u}`;
397
+ else {
398
+ const y = (n.value || "").trim(), k = (n.value2 || "").trim();
399
+ n.op === "longer" ? m = y && `${s.durationPath}:[${y} TO *]` : n.op === "shorter" ? m = y && `${s.durationPath}:[* TO ${y}]` : n.op === "between" && (m = y && k && `${s.durationPath}:[${y} TO ${k}]`);
400
+ }
401
+ return m ? n.negate ? "-" + m : m : "";
402
+ }
403
+ const d = u ? `${u}:` : "", f = (n.value || "").trim(), x = (n.value2 || "").trim();
404
+ let p = "";
405
+ if (s.type === "url") {
406
+ if (!f) return "";
407
+ p = n.op === "is" ? `${u}.keyword:"${S(f)}"` : `${d}"${S(f)}"`;
408
+ } else if (s.type === "date" || s.type === "number")
409
+ if (n.op === "between") {
410
+ if (!f || !x) return "";
411
+ p = `${d}[${f} TO ${x}]`;
412
+ } else if (n.op === "after" || n.op === "gte") {
413
+ if (!f) return "";
414
+ p = `${d}[${f} TO *]`;
415
+ } else {
416
+ if (!f) return "";
417
+ p = `${d}[* TO ${f}]`;
418
+ }
419
+ else if (n.op === "exists") {
420
+ if (!u) return "";
421
+ p = `_exists_:${u}`;
422
+ } else {
423
+ if (!f) return "";
424
+ n.op === "phrase" ? p = `${d}"${S(f)}"` : n.op === "term" ? p = `${d}${U(f)}` : n.op === "starts" ? p = `${d}${U(f)}*` : n.op === "fuzzy" && (p = `${d}${U(f)}~`);
425
+ }
426
+ return p ? (n.boost && Number(n.boost) > 0 && n.op !== "exists" && (p += `^${n.boost}`), n.negate && (p = "-" + p), p) : "";
427
+ }
428
+ function Z(n) {
429
+ return n.kind === "rule" ? j(n) : n.kind === "conditional" ? I(n) : T(n);
430
+ }
431
+ function T(n, s = !1) {
432
+ const u = n.children.map(Z).filter(Boolean);
433
+ if (u.length === 0) return "";
434
+ const d = u.join(` ${n.op} `);
435
+ let f = u.length > 1 && !s ? `(${d})` : d;
436
+ return n.negate && (f = u.length > 1 ? `NOT (${d})` : `NOT ${d}`), f;
437
+ }
438
+ function I(n) {
439
+ const s = T(n.cond), u = T(n.then), d = n.els ? T(n.els) : "";
440
+ if (!s) return u || "";
441
+ const f = u ? `(${s} AND ${u})` : `(${s})`;
442
+ return d ? `(${f} OR (NOT (${s}) AND ${d}))` : f;
443
+ }
444
+ function W(n) {
445
+ return T(n, !0) || "";
446
+ }
447
+ function N(n, s) {
448
+ if (s.op && !v(n, s.op))
449
+ throw new Error(`Unsupported operator for ${n}: ${s.op}`);
450
+ return g(n, s);
451
+ }
452
+ function J(n) {
453
+ let s = n.term, u = !1;
454
+ s[0] === "-" || s[0] === "!" ? (u = !0, s = s.slice(1)) : s[0] === "+" && (s = s.slice(1));
455
+ let d = "";
456
+ const f = s.match(/\^(\d+(?:\.\d+)?)$/);
457
+ f && (d = f[1], s = s.slice(0, -f[0].length));
458
+ const x = s.indexOf(":");
459
+ if (x < 0) {
460
+ const b = c("");
461
+ if (!b) throw new Error(`No default field for bare term: ${s}`);
462
+ return N(b, {
463
+ ...z(s, e[b].type),
464
+ negate: u,
465
+ boost: d
466
+ });
467
+ }
468
+ const p = s.slice(0, x), m = s.slice(x + 1);
469
+ if (p === "_exists_") {
470
+ const b = c(m.replace(/^"(.*)"$/, "$1"));
471
+ if (!b) throw new Error(`Unknown field: ${m}`);
472
+ return N(b, { op: "exists", negate: u });
473
+ }
474
+ const y = a.find((b) => e[b].type === "video" && e[b].durationPath === p);
475
+ if (y && m.startsWith("[")) {
476
+ const { op: b, value: X, value2: q } = z(m, "number");
477
+ return N(y, { op: b === "gte" ? "longer" : b === "lte" ? "shorter" : "between", value: X, value2: q || "", negate: u });
478
+ }
479
+ const k = a.find((b) => e[b].type === "url" && p === e[b].path + ".keyword");
480
+ if (k) {
481
+ const b = m.startsWith('"') ? m.slice(1, -1).replace(/\\(.)/g, "$1") : m;
482
+ return N(k, { op: "is", value: b, negate: u });
483
+ }
484
+ const _ = c(p);
485
+ if (!_) throw new Error(`Unknown field: ${p}`);
486
+ return N(_, {
487
+ ...z(m, e[_].type),
488
+ negate: u,
489
+ boost: d
490
+ });
491
+ }
492
+ function B(n) {
493
+ if (!n || !n.trim()) return O(void 0, []);
494
+ const s = se(E(L(n)), J);
495
+ return s.kind === "group" ? s : O(void 0, [s]);
496
+ }
497
+ const F = (n) => n.kind !== "group" || o.has(n.op) && n.children.every(F);
498
+ function K(n) {
499
+ if (!n || !n.trim()) return !0;
500
+ try {
501
+ const s = E(L(n)).map((d) => typeof d == "string" ? d : d.term);
502
+ if (pe(s)) return !1;
503
+ const u = B(n);
504
+ return F(u) ? D(W(u)) === D(n) : !1;
505
+ } catch {
506
+ return !1;
507
+ }
508
+ }
509
+ return {
510
+ fields: e,
511
+ fieldKeys: a,
512
+ groupOps: r,
513
+ defaultField: h,
514
+ // conditionals desugar to OR-of-ANDs, so they're only on offer
515
+ // when both joiners are
516
+ supportsConditionals: o.has("AND") && o.has("OR"),
517
+ newRule: g,
518
+ newGroup: O,
519
+ newConditional: Q,
520
+ newElse: G,
521
+ ruleToLucene: j,
522
+ groupToLucene: T,
523
+ condToLucene: I,
524
+ toLucene: W,
525
+ parseLucene: B,
526
+ roundTrips: K
527
+ };
528
+ }
529
+ const he = (t) => t && t[0].toUpperCase() + t.slice(1);
530
+ function we(t = {}) {
531
+ const i = t.itemNoun || "story", e = t.itemNounPlural || (t.itemNoun ? t.itemNoun + "s" : "stories");
532
+ return {
533
+ itemNoun: i,
534
+ itemNounPlural: e,
535
+ intro: `Describe the ${e} you want in plain language — the query writes itself.`,
536
+ rawUnsupported: "This query uses syntax the visual editor can't represent, so it's shown as raw text.",
537
+ rawButton: "Raw Query",
538
+ visualButton: "Query Builder",
539
+ rawSynced: "Synced.",
540
+ rawSaved: "Saved as raw text — the visual builder can't represent this query. Adjust it to a supported form to switch back.",
541
+ matchPrefix: `${he(e)} must match`,
542
+ matchSuffix: "of these rules",
543
+ empty: `No rules yet, so every ${i} can appear. Add a rule to narrow the collection.`,
544
+ addRule: "Rule",
545
+ addRuleTip: 'Add one condition, like Title contains "storm".',
546
+ addConditional: "If/then",
547
+ addConditionalTip: `Apply conditions only to ${e} that match a test first.`,
548
+ actsHelpRule: "adds a single condition",
549
+ actsHelpConditional: `applies conditions only to certain ${e}`,
550
+ conditionalTitle: "IF / THEN",
551
+ conditionalIf: `If a ${i} matches`,
552
+ conditionalThen: "then include only when",
553
+ conditionalElse: "otherwise include only when",
554
+ removeElse: "remove",
555
+ addElse: "Otherwise branch",
556
+ addSubRule: "Rule",
557
+ addSubRuleTip: "Add another condition to this list.",
558
+ include: "Include",
559
+ exclude: "Exclude",
560
+ ruleTag: "Rule",
561
+ between: "and",
562
+ // sic: "a values." matches the original builder's rendered string
563
+ // (`…a value${plural ? 's' : ''}.`) byte-for-byte
564
+ pendingOne: "Ignored until you enter a value.",
565
+ pendingBoth: "Ignored until you enter a values.",
566
+ ...t
567
+ };
568
+ }
569
+ export {
570
+ te as DATE_OPS,
571
+ H as DEFAULT_BOOLEANS,
572
+ P as DEFAULT_OPERATORS,
573
+ ne as NUM_OPS,
574
+ Y as TEXT_OPS,
575
+ ee as URL_OPS,
576
+ ie as VIDEO_OPS,
577
+ $e as createQueryModel,
578
+ ge as equivalent,
579
+ C as publicationPreset,
580
+ we as resolveLabels,
581
+ me as validateSyntax
582
+ };