@yuneta/gobj-ui 7.23.38 → 7.23.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1381,14 +1381,32 @@ because opening a popover per node to learn it is not reading a tree:
1381
1381
  | On the card | Says |
1382
1382
  |---|---|
1383
1383
  | Colour (border + left bar) | the ROLE: sky = the yuno, emerald = a service, amber = a pure child, pink = a volatil one, violet = a plain child |
1384
- | Status pill | `stopped` / `running` / `playing`, coloured. `running` and `playing` are not the same thing: a gobj that runs and does not play is PAUSED, which is what the popover calls it in full |
1384
+ | Status pill | a SYMBOL and, where there is room, the word: `▶` playing, `‖` running but not playing (PAUSED, which is what the popover calls it in full), `■` stopped, `⊘` disabled. The symbol and not only a colour, because a dot has one shape and stopped is the state that has to be seen |
1385
1385
  | Badges | `service`, `pure child`, `volatil child`, `disabled`, `bottom` (it has a bottom gobj), `commands` (its gclass exposes commands) |
1386
1386
  | Its own line | the FSM state |
1387
1387
  | Dashed border, dimmed | disabled — that branch is out of the game |
1388
1388
 
1389
1389
  The popover adds the rest (`full name`, `parent`, `bottom gobj`, `traces`,
1390
1390
  `flags`, how many children a fold is hiding) and shows only the rows that have
1391
- an answer.
1391
+ an answer. Its two state rows are `status` and **`fsm state`** — different
1392
+ keys on purpose: they used to be `status` and `state`, which every Spanish app
1393
+ translated to the same word, so the popover showed *Estado: Parado* directly
1394
+ above *Estado: ST_IDLE*.
1395
+
1396
+ **The find box** matches gclass, name, full name and FSM state; a match wears
1397
+ an amber ring over its role colour (the card still has to say what it IS) and
1398
+ the chip counts them, because a graph that did not move looks the same whether
1399
+ nothing matched or the match was already on screen. A find is a REBUILD — an
1400
+ html node paints no G6 state, so the highlight lives in the card's own markup —
1401
+ which is why the box is rate-limited, and why the view is preserved: somebody
1402
+ who typed a letter did not ask to be moved.
1403
+
1404
+ **A service the app creates is the app's to START.** `c_yuno`'s `mt_play` starts
1405
+ only the DEFAULT service, so anything else stays stopped unless its creator
1406
+ starts it — and a gclass with no `mt_start` (`C_YUI_WINDOW_MANAGER` builds its
1407
+ dock in `mt_create` and runs off events) WORKS stopped, which is how one shipped
1408
+ that way in two apps: nothing failed, it just read `!!C_YUI_WINDOW_MANAGER` in
1409
+ every trace line and *stopped* in this view.
1392
1410
 
1393
1411
  **It draws DESCRIPTORS, not gobjs** (`gobj_tree_model.js`), which is what lets
1394
1412
  this same view show a **backend** yuno. A descriptor is plain data whose field
@@ -10921,10 +10921,6 @@ function make_toolbar$5(gobj) {
10921
10921
  "span",
10922
10922
  { class: "JSON_GRAPH_FIND_COUNT" },
10923
10923
  ""
10924
- ], [
10925
- "span",
10926
- { i18n: "matches" },
10927
- "matches"
10928
10924
  ]]
10929
10925
  ]]);
10930
10926
  let center_items = [];
@@ -11442,7 +11438,7 @@ function collect_foldable_paths(value, path, out, is_root) {
11442
11438
  * move looks the same whether nothing matched or the match
11443
11439
  * was already on screen.
11444
11440
  ************************************************************/
11445
- function update_find_result(gobj) {
11441
+ function update_find_result$1(gobj) {
11446
11442
  let priv = gobj.priv;
11447
11443
  if (!priv.$find_result || !priv.$find_count) return;
11448
11444
  if ((0, _yuneta_gobj_js.empty_string)(priv.search)) {
@@ -11450,7 +11446,7 @@ function update_find_result(gobj) {
11450
11446
  priv.$find_count.textContent = "";
11451
11447
  return;
11452
11448
  }
11453
- priv.$find_count.textContent = String(priv.match_count);
11449
+ priv.$find_count.textContent = (0, i18next.t)("matches", { count: priv.match_count });
11454
11450
  priv.$find_result.classList.remove("is-hidden");
11455
11451
  }
11456
11452
  /************************************************************
@@ -11707,7 +11703,7 @@ function ac_change_layout$2(gobj, event, kw, src) {
11707
11703
  edge: { type: cfg.edge_type }
11708
11704
  });
11709
11705
  refresh_json(gobj);
11710
- update_find_result(gobj);
11706
+ update_find_result$1(gobj);
11711
11707
  return 0;
11712
11708
  }
11713
11709
  /************************************************************
@@ -11736,7 +11732,7 @@ function ac_toggle_fold(gobj, event, kw, src) {
11736
11732
  }
11737
11733
  priv.pending_keep = keep_of(gobj, kw && kw.keep || path);
11738
11734
  refresh_json(gobj, { preserve_view: true });
11739
- update_find_result(gobj);
11735
+ update_find_result$1(gobj);
11740
11736
  return 0;
11741
11737
  }
11742
11738
  /************************************************************
@@ -11747,11 +11743,11 @@ function ac_toggle_fold(gobj, event, kw, src) {
11747
11743
  * keystroke is unusable. The count says whether there is
11748
11744
  * anything to look for elsewhere.
11749
11745
  ************************************************************/
11750
- function ac_find_nodes$2(gobj, event, kw, src) {
11746
+ function ac_find_nodes$3(gobj, event, kw, src) {
11751
11747
  let priv = gobj.priv;
11752
11748
  priv.search = (kw && kw.text || "").trim().toLowerCase();
11753
11749
  refresh_json(gobj, { preserve_view: true });
11754
- update_find_result(gobj);
11750
+ update_find_result$1(gobj);
11755
11751
  return 0;
11756
11752
  }
11757
11753
  /************************************************************
@@ -11763,7 +11759,7 @@ function ac_expand_all$2(gobj, event, kw, src) {
11763
11759
  priv.collapsed.clear();
11764
11760
  priv.reserved.clear();
11765
11761
  refresh_json(gobj);
11766
- update_find_result(gobj);
11762
+ update_find_result$1(gobj);
11767
11763
  return 0;
11768
11764
  }
11769
11765
  /************************************************************
@@ -11780,7 +11776,7 @@ function ac_collapse_all$2(gobj, event, kw, src) {
11780
11776
  priv.collapsed = new Set(paths);
11781
11777
  priv.reserved.clear();
11782
11778
  refresh_json(gobj);
11783
- update_find_result(gobj);
11779
+ update_find_result$1(gobj);
11784
11780
  return 0;
11785
11781
  }
11786
11782
  /************************************************************
@@ -12054,7 +12050,7 @@ function create_gclass$13(gclass_name) {
12054
12050
  ],
12055
12051
  [
12056
12052
  "EV_FIND_NODES",
12057
- ac_find_nodes$2,
12053
+ ac_find_nodes$3,
12058
12054
  null
12059
12055
  ],
12060
12056
  [
@@ -16132,6 +16128,21 @@ function node_status(d) {
16132
16128
  if (!d || !d.running) return "stopped";
16133
16129
  return d.playing ? "playing" : "running";
16134
16130
  }
16131
+ var STATUS_SYMBOLS = {
16132
+ "playing": "▶︎",
16133
+ "running": "‖",
16134
+ "stopped": "■︎"
16135
+ };
16136
+ var DISABLED_SYMBOL = "⊘";
16137
+ /************************************************************
16138
+ * The symbol of a node's status, which is what the reader
16139
+ * actually sees first. `disabled` overrides the rest: a
16140
+ * disabled gobj is not going to run whatever it is doing now.
16141
+ ************************************************************/
16142
+ function node_status_symbol(d) {
16143
+ if (d && d.disabled) return DISABLED_SYMBOL;
16144
+ return STATUS_SYMBOLS[node_status(d)] || STATUS_SYMBOLS.stopped;
16145
+ }
16135
16146
  /************************************************************
16136
16147
  * The i18n key of the status, which is NOT the status itself:
16137
16148
  * a gobj that runs and does not play is PAUSED to the reader,
@@ -16260,7 +16271,7 @@ function node_labels(t) {
16260
16271
  full_name: t("full name"),
16261
16272
  role: t("role"),
16262
16273
  status: t("status"),
16263
- state: t("state"),
16274
+ fsm_state: t("fsm state"),
16264
16275
  disabled: t("disabled"),
16265
16276
  parent: t("parent"),
16266
16277
  bottom_gobj: t("bottom gobj"),
@@ -16289,8 +16300,8 @@ function node_info_rows(d, t) {
16289
16300
  rows.push([f.name, d.name || "—"]);
16290
16301
  if (d.fullname && d.fullname !== d.shortname) rows.push([f.full_name, d.fullname]);
16291
16302
  rows.push([f.role, L.role[role_i18n_key(node_role(d))]]);
16292
- rows.push([f.status, L.status[node_status_key(d)]]);
16293
- rows.push([f.state, d.state || "—"]);
16303
+ rows.push([f.status, node_status_symbol(d) + " " + L.status[node_status_key(d)]]);
16304
+ rows.push([f.fsm_state, d.state || "—"]);
16294
16305
  if (d.disabled) rows.push([f.disabled, f.yes]);
16295
16306
  if (d.parent) rows.push([f.parent, d.parent]);
16296
16307
  if (d.bottom_gobj) rows.push([f.bottom_gobj, d.bottom_gobj]);
@@ -16772,6 +16783,12 @@ var PRIVATE_DATA$9 = {
16772
16783
  theme: null,
16773
16784
  theme_observer: null,
16774
16785
  $layout_select: null,
16786
+ search: "",
16787
+ match_count: 0,
16788
+ find_timer: null,
16789
+ $find_input: null,
16790
+ $find_result: null,
16791
+ $find_count: null,
16775
16792
  $popover: null,
16776
16793
  $popover_title: null,
16777
16794
  $popover_body: null,
@@ -16917,6 +16934,7 @@ var NODE_SIZES = {
16917
16934
  /***************************************************************
16918
16935
  * Shared card typography.
16919
16936
  ***************************************************************/
16937
+ var FIND_MATCH_COLOR = "#D9A23F";
16920
16938
  var GT_FONT = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif";
16921
16939
  /***************************************************************
16922
16940
  * Theme-aware card palette derived from the role colour.
@@ -17289,11 +17307,103 @@ function destroy_ui$4(gobj) {
17289
17307
  /************************************************************
17290
17308
  * Toolbar
17291
17309
  ************************************************************/
17310
+ /************************************************************
17311
+ * The find box and its count.
17312
+ *
17313
+ * A tree of a real yuno is a hundred cards, and the only way
17314
+ * to locate one was to read them all. The COUNT is what makes
17315
+ * it honest: a graph that did not move looks the same whether
17316
+ * nothing matched or the match was already on screen -- the
17317
+ * same reason the JSON graph carries one, and the same
17318
+ * drawing, because the two sit in the same console.
17319
+ ************************************************************/
17320
+ function make_find_items(gobj) {
17321
+ let priv = gobj.priv;
17322
+ let $find_input = (0, _yuneta_gobj_js.createElement2)([
17323
+ "input",
17324
+ {
17325
+ class: "GOBJ_TREE_FIND_INPUT input",
17326
+ type: "text",
17327
+ placeholder: (0, i18next.t)("search"),
17328
+ "data-i18n-placeholder": "search",
17329
+ "aria-label": (0, i18next.t)("search"),
17330
+ "data-i18n-aria-label": "search"
17331
+ },
17332
+ [],
17333
+ { input: (evt) => {
17334
+ evt.stopPropagation();
17335
+ let text = evt.target.value.trim();
17336
+ if (priv.find_timer) clearTimeout(priv.find_timer);
17337
+ priv.find_timer = setTimeout(function() {
17338
+ priv.find_timer = null;
17339
+ (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_FIND_NODES", { text }, gobj);
17340
+ }, 250);
17341
+ } }
17342
+ ]);
17343
+ let $find_control = (0, _yuneta_gobj_js.createElement2)([
17344
+ "div",
17345
+ {
17346
+ class: "GOBJ_TREE_FIND control has-icons-left",
17347
+ style: "margin-left:.5rem; margin-right:.5rem; max-width:12rem; min-width:7rem;"
17348
+ },
17349
+ [$find_input, [
17350
+ "span",
17351
+ { class: "icon is-left" },
17352
+ [["i", { class: "yi-magnifying-glass" }]]
17353
+ ]]
17354
+ ]);
17355
+ attach_clear($find_control, $find_input);
17356
+ priv.$find_input = $find_input;
17357
+ return [$find_control, [
17358
+ "div",
17359
+ {
17360
+ class: "GOBJ_TREE_FIND_RESULT is-hidden",
17361
+ style: "display:flex; align-items:center; gap:.3rem; margin-right:.5rem; font-size:.85rem;"
17362
+ },
17363
+ [[
17364
+ "span",
17365
+ { class: "GOBJ_TREE_FIND_COUNT" },
17366
+ ""
17367
+ ]]
17368
+ ]];
17369
+ }
17370
+ /************************************************************
17371
+ * Does this node answer the current find term?
17372
+ *
17373
+ * What a reader types is a gclass, a name or a state -- the
17374
+ * three things a card shows. The full name is searched too,
17375
+ * because it is what the popover shows and what a log line
17376
+ * carries.
17377
+ ************************************************************/
17378
+ function node_matches(d, term) {
17379
+ if (!term) return false;
17380
+ return [
17381
+ d.gclass,
17382
+ d.name,
17383
+ d.fullname,
17384
+ d.state
17385
+ ].filter((x) => typeof x === "string").join(" ").toLowerCase().indexOf(term) >= 0;
17386
+ }
17387
+ /************************************************************
17388
+ * Repaint the count chip. Hidden while nothing is typed:
17389
+ * "0 matches" beside an empty box says nothing.
17390
+ ************************************************************/
17391
+ function update_find_result(gobj) {
17392
+ let priv = gobj.priv;
17393
+ if (!priv.$find_result || !priv.$find_count) return;
17394
+ if (!priv.search) {
17395
+ priv.$find_result.classList.add("is-hidden");
17396
+ priv.$find_count.textContent = "";
17397
+ return;
17398
+ }
17399
+ priv.$find_count.textContent = (0, i18next.t)("matches", { count: priv.match_count });
17400
+ priv.$find_result.classList.remove("is-hidden");
17401
+ }
17292
17402
  function make_toolbar$1(gobj) {
17293
17403
  let priv = gobj.priv;
17294
17404
  let toolbar_wide = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "wide");
17295
17405
  let current_layout = (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "layout");
17296
- let left_items = yui_graph_fold_items(gobj, toolbar_wide);
17406
+ let left_items = yui_graph_fold_items(gobj, toolbar_wide).concat(make_find_items(gobj));
17297
17407
  let center_items = [];
17298
17408
  let right_items = [];
17299
17409
  center_items = yui_graph_camera_items(gobj, priv.graph, toolbar_wide);
@@ -17344,6 +17454,8 @@ function make_toolbar$1(gobj) {
17344
17454
  right_items
17345
17455
  ]
17346
17456
  ]);
17457
+ priv.$find_result = $toolbar.querySelector(".GOBJ_TREE_FIND_RESULT");
17458
+ priv.$find_count = $toolbar.querySelector(".GOBJ_TREE_FIND_COUNT");
17347
17459
  (0, _yuneta_gobj_js.refresh_language)($toolbar, i18next.t);
17348
17460
  return $toolbar;
17349
17461
  }
@@ -17519,26 +17631,32 @@ function render_toggle_html(node_id, collapsed, num_children, cs) {
17519
17631
  /************************************************************
17520
17632
  * HTML for the status pill: what the gobj is DOING.
17521
17633
  *
17522
- * A dot plus a word, and the word is dropped in the compact
17523
- * card where there is no room for it -- the colour still
17524
- * carries it, and the `title` says it in full either way.
17634
+ * A SYMBOL plus a word, and the word is dropped in the
17635
+ * compact card where there is no room for it.
17636
+ *
17637
+ * The symbol carries the state on its own, which a dot never
17638
+ * did: a dot has one shape, so telling running from stopped
17639
+ * meant telling green from red at 10 pixels -- and stopped is
17640
+ * the one that has to be seen. Play, pause and stop are also
17641
+ * the framework's own three verbs, not a borrowed metaphor.
17525
17642
  ************************************************************/
17526
17643
  function render_status_html(d, ss, labels, with_label) {
17527
17644
  let full = d.disabled ? labels.field.disabled : labels.status[node_status_key(d)] || node_status_key(d);
17528
17645
  let label = d.disabled ? labels.field.disabled : labels.status_short[node_status(d)] || node_status(d);
17646
+ let symbol = node_status_symbol(d);
17529
17647
  if (!with_label) return `<span title="${(0, _yuneta_gobj_js.escapeHtml)(full)}" style="
17530
17648
  flex: 0 0 auto;
17531
- width: 10px; height: 10px; border-radius: 50%;
17532
- background: ${ss.dot};
17533
- box-shadow: 0 0 0 2px ${ss.bg};
17534
17649
  margin-left: 6px;
17535
- "></span>`;
17650
+ color: ${ss.dot};
17651
+ font-size: 11px;
17652
+ line-height: 1;
17653
+ ">${(0, _yuneta_gobj_js.escapeHtml)(symbol)}</span>`;
17536
17654
  return `<span title="${(0, _yuneta_gobj_js.escapeHtml)(full)}" style="
17537
17655
  flex: 0 0 auto;
17538
17656
  display: inline-flex;
17539
17657
  align-items: center;
17540
17658
  gap: 4px;
17541
- padding: 1px 7px 1px 5px;
17659
+ padding: 1px 7px 1px 6px;
17542
17660
  background: ${ss.bg};
17543
17661
  color: ${ss.fg};
17544
17662
  border-radius: 9px;
@@ -17546,7 +17664,8 @@ function render_status_html(d, ss, labels, with_label) {
17546
17664
  font-weight: 700;
17547
17665
  line-height: 1.45;
17548
17666
  white-space: nowrap;
17549
- "><span style="width:7px; height:7px; border-radius:50%; background:${ss.dot};"></span>${(0, _yuneta_gobj_js.escapeHtml)(label)}</span>`;
17667
+ "><span style="color:${ss.dot}; font-size:11px; line-height:1;"
17668
+ >${(0, _yuneta_gobj_js.escapeHtml)(symbol)}</span>${(0, _yuneta_gobj_js.escapeHtml)(label)}</span>`;
17550
17669
  }
17551
17670
  /************************************************************
17552
17671
  * HTML for the badges: what the gobj IS, besides its colour.
@@ -17593,6 +17712,12 @@ function build_gobj_nodes(gobj, d, nodes, edges, parent_id, compact, labels) {
17593
17712
  let height = size.h;
17594
17713
  let border_width = category === "yuno" || category === "service" ? 2 : 1;
17595
17714
  let border_style = d.disabled ? "dashed" : "solid";
17715
+ if (node_matches(d, priv.search)) {
17716
+ priv.match_count++;
17717
+ border_width = 3;
17718
+ border_style = "solid";
17719
+ cs = Object.assign({}, cs, { border: FIND_MATCH_COLOR });
17720
+ }
17596
17721
  let children = d.children || [];
17597
17722
  let num_children = children.length;
17598
17723
  let has_children = num_children > 0;
@@ -17717,6 +17842,7 @@ function load_tree(gobj) {
17717
17842
  }
17718
17843
  let layout_cfg = get_layout_cfg((0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "layout"));
17719
17844
  let labels = node_labels(i18next.t);
17845
+ priv.match_count = 0;
17720
17846
  let anchor = priv.pending_anchor || null;
17721
17847
  let preserve_view = !!priv.pending_preserve_view;
17722
17848
  priv.pending_anchor = null;
@@ -18146,6 +18272,23 @@ var GobjLanesHLayout = class extends _antv_g6.BaseLayout {
18146
18272
  /************************************************************
18147
18273
  *
18148
18274
  ************************************************************/
18275
+ /************************************************************
18276
+ * EV_FIND_NODES {text}
18277
+ *
18278
+ * The cards carry the highlight in their own markup (an html
18279
+ * node paints no G6 state), so finding is a REBUILD -- which
18280
+ * is also why the box is rate-limited. The view is preserved:
18281
+ * a reader who typed a letter did not ask to be moved.
18282
+ ************************************************************/
18283
+ function ac_find_nodes$2(gobj, event, kw, src) {
18284
+ let priv = gobj.priv;
18285
+ let text = String(kw && kw.text || "").trim().toLowerCase();
18286
+ if (text === priv.search) return 0;
18287
+ priv.search = text;
18288
+ refresh_tree(gobj, { preserve_view: true });
18289
+ update_find_result(gobj);
18290
+ return 0;
18291
+ }
18149
18292
  function ac_refresh$3(gobj, event, kw, src) {
18150
18293
  save_view_state(gobj);
18151
18294
  refresh_tree(gobj);
@@ -18499,6 +18642,7 @@ function ac_language_changed$3(gobj, event, kw, src) {
18499
18642
  if ($container) (0, _yuneta_gobj_js.refresh_language)($container, i18next.t);
18500
18643
  hide_popover(gobj);
18501
18644
  refresh_tree(gobj);
18645
+ update_find_result(gobj);
18502
18646
  return 0;
18503
18647
  }
18504
18648
  /***************************
@@ -18519,6 +18663,7 @@ function create_gclass$9(gclass_name) {
18519
18663
  return -1;
18520
18664
  }
18521
18665
  __gclass__$9 = (0, _yuneta_gobj_js.gclass_create)(gclass_name, [
18666
+ ["EV_FIND_NODES", 0],
18522
18667
  ["EV_REFRESH", 0],
18523
18668
  ["EV_THEME", 0],
18524
18669
  ["EV_CHANGE_LAYOUT", 0],
@@ -18539,6 +18684,11 @@ function create_gclass$9(gclass_name) {
18539
18684
  ["EV_GCLASS_CLOSED", 0],
18540
18685
  ["EV_LANGUAGE_CHANGED", 0]
18541
18686
  ], [["ST_IDLE", [
18687
+ [
18688
+ "EV_FIND_NODES",
18689
+ ac_find_nodes$2,
18690
+ null
18691
+ ],
18542
18692
  [
18543
18693
  "EV_REFRESH",
18544
18694
  ac_refresh$3,
@@ -20007,11 +20157,7 @@ function build_body(shell, t) {
20007
20157
  let $count = (0, _yuneta_gobj_js.createElement2)([
20008
20158
  "span",
20009
20159
  { class: "ROUTEMAP_COUNT is-size-7 has-text-grey is-hidden" },
20010
- [$count_n, [
20011
- "span",
20012
- { i18n: "matches" },
20013
- "matches"
20014
- ]]
20160
+ [$count_n]
20015
20161
  ]);
20016
20162
  let $refs_input = (0, _yuneta_gobj_js.createElement2)(["input", {
20017
20163
  class: "ROUTEMAP_REFS_INPUT",
@@ -20049,7 +20195,7 @@ function build_body(shell, t) {
20049
20195
  if ($root_li) filter_li($root_li, q, false, __show_refs__);
20050
20196
  if (q === "") $count.classList.add("is-hidden");
20051
20197
  else {
20052
- $count_n.textContent = $tree.querySelectorAll(".ROUTEMAP_MATCH").length;
20198
+ $count_n.textContent = t("matches", { count: $tree.querySelectorAll(".ROUTEMAP_MATCH").length });
20053
20199
  $count.classList.remove("is-hidden");
20054
20200
  }
20055
20201
  };
@@ -57983,10 +58129,6 @@ function make_toolbar(gobj) {
57983
58129
  "span",
57984
58130
  { class: "GRAPH_FIND_COUNT" },
57985
58131
  ""
57986
- ], [
57987
- "span",
57988
- { i18n: "matches" },
57989
- "matches"
57990
58132
  ]]
57991
58133
  ]]
57992
58134
  ],
@@ -59042,7 +59184,7 @@ function ac_find_result(gobj, event, kw, src) {
59042
59184
  $count.textContent = "";
59043
59185
  return 0;
59044
59186
  }
59045
- $count.textContent = String(kw && kw.matches || 0);
59187
+ $count.textContent = (0, i18next.t)("matches", { count: kw && kw.matches || 0 });
59046
59188
  $result.classList.remove("is-hidden");
59047
59189
  return 0;
59048
59190
  }