@saltcorn/data 0.9.6-beta.8 → 0.9.6

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.
Files changed (76) hide show
  1. package/dist/base-plugin/actions.d.ts +30 -2
  2. package/dist/base-plugin/actions.d.ts.map +1 -1
  3. package/dist/base-plugin/actions.js +36 -14
  4. package/dist/base-plugin/actions.js.map +1 -1
  5. package/dist/base-plugin/index.d.ts +382 -256
  6. package/dist/base-plugin/index.d.ts.map +1 -1
  7. package/dist/base-plugin/types.d.ts +382 -287
  8. package/dist/base-plugin/types.d.ts.map +1 -1
  9. package/dist/base-plugin/types.js +259 -18
  10. package/dist/base-plugin/types.js.map +1 -1
  11. package/dist/base-plugin/viewtemplates/edit.d.ts.map +1 -1
  12. package/dist/base-plugin/viewtemplates/edit.js +7 -8
  13. package/dist/base-plugin/viewtemplates/edit.js.map +1 -1
  14. package/dist/base-plugin/viewtemplates/feed.d.ts +9 -4
  15. package/dist/base-plugin/viewtemplates/feed.d.ts.map +1 -1
  16. package/dist/base-plugin/viewtemplates/feed.js +20 -9
  17. package/dist/base-plugin/viewtemplates/feed.js.map +1 -1
  18. package/dist/base-plugin/viewtemplates/list.d.ts.map +1 -1
  19. package/dist/base-plugin/viewtemplates/list.js +18 -2
  20. package/dist/base-plugin/viewtemplates/list.js.map +1 -1
  21. package/dist/base-plugin/viewtemplates/room.js +1 -1
  22. package/dist/base-plugin/viewtemplates/room.js.map +1 -1
  23. package/dist/base-plugin/viewtemplates/viewable_fields.js +1 -1
  24. package/dist/base-plugin/viewtemplates/viewable_fields.js.map +1 -1
  25. package/dist/db/state.d.ts +1 -0
  26. package/dist/db/state.d.ts.map +1 -1
  27. package/dist/db/state.js +3 -0
  28. package/dist/db/state.js.map +1 -1
  29. package/dist/models/config.d.ts.map +1 -1
  30. package/dist/models/config.js +15 -1
  31. package/dist/models/config.js.map +1 -1
  32. package/dist/models/expression.d.ts.map +1 -1
  33. package/dist/models/expression.js +17 -7
  34. package/dist/models/expression.js.map +1 -1
  35. package/dist/models/field.d.ts.map +1 -1
  36. package/dist/models/field.js +8 -3
  37. package/dist/models/field.js.map +1 -1
  38. package/dist/models/notification.d.ts +2 -0
  39. package/dist/models/notification.d.ts.map +1 -1
  40. package/dist/models/notification.js +6 -0
  41. package/dist/models/notification.js.map +1 -1
  42. package/dist/models/page.d.ts.map +1 -1
  43. package/dist/models/page.js +5 -11
  44. package/dist/models/page.js.map +1 -1
  45. package/dist/models/table.d.ts +1 -1
  46. package/dist/models/table.d.ts.map +1 -1
  47. package/dist/models/table.js +42 -10
  48. package/dist/models/table.js.map +1 -1
  49. package/dist/models/trigger.d.ts +6 -1
  50. package/dist/models/trigger.d.ts.map +1 -1
  51. package/dist/models/trigger.js +17 -2
  52. package/dist/models/trigger.js.map +1 -1
  53. package/dist/models/view.d.ts.map +1 -1
  54. package/dist/models/view.js +5 -10
  55. package/dist/models/view.js.map +1 -1
  56. package/dist/tests/actions.test.js +14 -4
  57. package/dist/tests/actions.test.js.map +1 -1
  58. package/dist/tests/auxtest.test.js +7 -1
  59. package/dist/tests/auxtest.test.js.map +1 -1
  60. package/dist/tests/calc.test.js +78 -2
  61. package/dist/tests/calc.test.js.map +1 -1
  62. package/dist/tests/exact_views.test.js +3 -3
  63. package/dist/tests/exact_views.test.js.map +1 -1
  64. package/dist/tests/models.test.js +1 -1
  65. package/dist/tests/table.test.js +17 -1
  66. package/dist/tests/table.test.js.map +1 -1
  67. package/dist/tests/view.test.js +5 -1
  68. package/dist/tests/view.test.js.map +1 -1
  69. package/dist/utils.d.ts +4 -2
  70. package/dist/utils.d.ts.map +1 -1
  71. package/dist/utils.js +33 -0
  72. package/dist/utils.js.map +1 -1
  73. package/dist/web-mobile-commons.d.ts.map +1 -1
  74. package/dist/web-mobile-commons.js +7 -1
  75. package/dist/web-mobile-commons.js.map +1 -1
  76. package/package.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../base-plugin/types.js"],"names":[],"mappings":";gBAugBa,MAAM;oBAEN,MAAM;;IAQL,+CA6EX;IAMS;;gBAK+D;;;;;YAehE,6BAAyB;;;;;;;YAKzB,mCACiE;;;;;;;;YAKjE,mCAA+C;;;;;;;;;;;;;;YAc/C,4DAIJ;;;;;;;;;;;;;;;YAkBI,yDAGG;;;;;;;;YAUH,yDAAmE;;;;;;;;YAWnE,mCAA6B;;;;;;;;;;YAapB;;;;;;;;;;;;;;;;;;;;;iBAwCb;;YACI,6FAsFG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAiDH,6FAyCF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAyCE,6FAqBF;;;;;;;;;;;;;;;;YA4BE,8FAkBF;;;;;;;;;;;;;;;;;;;;YA2BE,8FAkBF;;;;;;;;;;;;;;YAiBE,8FAcyB;;;;;;;;;;;;;;;YAczB,8FAYoB;;;;;;;;;;YAWpB,8FAWD;;;;IAOF,0CAQL;;QAYK;;mBAAmB;QAMZ;;mBAAyD;;IAOpE,+FAYC;IAMkB,iFAEwB;;;kBAuBlC,MAAM;;sBAEN,MAAM;;;;IAUP;;;gBAAoD;;;;;;;;;;;;;;;;;;YAkBrD,uCAAc;;;;;;;;;;;;;;;;YAwBd,8FAwBJ;;;;;YA9vCS;;;;gBAOb;;;;;;;;YAII,yGAmBD;;;;YAGU;;;;gBAOb;;;;;;;;;;YAOI,qHAmCJ;;;;YAaa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiDb;;;;;;YAII,0DAoEJ;;;;YAuBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgDb;;;;;;YAGI,0DAoCJ;;;;;;;;;;;;;;;;YAUI,qHA6BJ;;;;;;;;YA45BiB;;;;;gBAOb;;;;;;YAGI,0DAWF;;;;;;YAIW;;;;;gBAOb;;;;;;YAGI,qHAsBJ;;;;;wBAGM,MAAM,EAAE;;IASE,qEACoB;;IAKnC,0CAWL;;IAMC,0DAKC;;;;kBAscQ,MAAM;;sBAEN,MAAM;;;;IAMP,uCAAa;;;;;;;;YAed,8CAaG;;;;;;;;;YAUH,oCAKG;;;;;;;;YAWH,sDAAyD;;;;;;;;;;;;;;;;;;;;;;YAyBzD,8FAgBJ;;;;;;;;;YAKI,8FAoBJ;;;;;;;;;;;;;;;;YA6BI,8FAsCE;;;;;wBAGA,MAAM,EAAE;;IAOC,2EAMnB;IAKK,kDAUL;;IAKW,8CAAU;IAKd,0CAAwB;IAItB,sCAAiB;;;;kBA3chB,MAAM;;sBAEN,MAAM;;;;IAOP,uCAAa;;wBACZ,MAAM,EAAE;;;;;;;;YAuBV,0DAOJ;;;;;;;;;YAWI,8CAKG;;;;;;;;;;;;;;;YAkBH,4DAYJ;;;;;;;;YAUI,iDAKJ;;;;;;;;YAWI,iDAGJ;;;;;;;;;;;YAaI,8FAkBD;;;;;;;;;;;YAaC,8FAkBD;;;;;;QASD,qBAAgB;;;IAOjB,yDAWL;;IAKS,sCAA2C;;;;kBA7V1C,MAAM;;sBAEN,MAAM;;;;IAUP;;;iBAAmD;;;;;;;;;;;;;;;;;YAkBpD,uCAAc;;;;;;;;;;;;;;;;;YAkBd,8FAoBD;;;;;;;;;;;;;;;;;;;YAzpCH,qHAaD;;;;;;;;;wBAspCO,MAAM,EAAE;;IAWb,+DAYL;;IAMC,mEAKC;;;;kBArMQ,MAAM;;sBAEN,MAAM;;;;IAOP,uCAAY;;;;;;;;YAeb,oCAMG;;;;;;;;;;;;YAYH,8FAWD;;;;;;wBAGG,MAAM,EAAE;;IAMb,0CAOL;;IAIS,sCAET;;;;;;;;;;;;;;;;;;;IAvtCI,0DAGJ"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../base-plugin/types.js"],"names":[],"mappings":"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"}
@@ -15,6 +15,7 @@ const { getState } = require("../db/state");
15
15
  const { localeDate, localeDateTime } = require("@saltcorn/markup");
16
16
  const { freeVariables, eval_expression } = require("../models/expression");
17
17
  const Table = require("../models/table");
18
+ const User = require("../models/user");
18
19
  const _ = require("underscore");
19
20
  const { interpolate } = require("../utils");
20
21
  const { sqlFun, sqlBinOp } = require("@saltcorn/db-common/internal");
@@ -288,12 +289,38 @@ const heat_cell = (type) => ({
288
289
  RedAmberGreen: `hsl(${100 * pcnt},100%, 50%)`,
289
290
  WhiteToRed: `hsl(0,100%, ${100 * (1 - pcnt / 2)}%)`,
290
291
  }[attrs.color_scale];
292
+ function getLuminance(hexColor) {
293
+ const r = parseInt(hexColor.substr(1, 2), 16) / 255;
294
+ const g = parseInt(hexColor.substr(3, 2), 16) / 255;
295
+ const b = parseInt(hexColor.substr(5, 2), 16) / 255;
296
+ const a = [r, g, b].map((v) => {
297
+ return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
298
+ });
299
+ return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
300
+ }
301
+ function hslToHex(h, s, l) {
302
+ l /= 100;
303
+ const a = (s * Math.min(l, 1 - l)) / 100;
304
+ const f = (n) => {
305
+ const k = (n + h / 30) % 12;
306
+ const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
307
+ return Math.round(255 * color)
308
+ .toString(16)
309
+ .padStart(2, "0"); // convert to Hex and prefix "0" if needed
310
+ };
311
+ return `#${f(0)}${f(8)}${f(4)}`;
312
+ }
313
+ const [h, s, l] = backgroundColor.match(/\d+/g).map(Number);
314
+ const hexColor = hslToHex(h, s, l);
315
+ const luminance = getLuminance(hexColor);
316
+ const textColor = luminance > 0.5 ? "#000000" : "#FFFFFF";
291
317
  return div({
292
318
  class: "px-2",
293
319
  style: {
294
320
  width: "100%",
295
321
  height: `${attrs.em_height || 1}em`,
296
322
  backgroundColor,
323
+ color: textColor,
297
324
  },
298
325
  }, text(v));
299
326
  },
@@ -374,26 +401,155 @@ const number_stepper = (name, v, attrs, cls, fieldname, id) => div({ class: "inp
374
401
  * @param {string} optsStr
375
402
  * @returns {string[]}
376
403
  */
377
- const getStrOptions = (v, optsStr) => typeof optsStr === "string"
378
- ? optsStr
379
- .split(",")
380
- .map((o) => o.trim())
381
- .map((o) => option({ value: text_attr(o), ...(eqStr(v, o) && { selected: true }) }, text_attr(o)))
382
- : optsStr.map((o, ix) => o && typeof o.name !== "undefined" && typeof o.label !== "undefined"
383
- ? option({
384
- value: o.name,
385
- ...((eqStr(v, o.name) ||
386
- (ix === 0 && typeof v === "undefined" && o.disabled)) && {
387
- selected: true,
388
- }),
389
- ...(o.disabled && { disabled: true }),
390
- }, o.label)
391
- : option({ value: o, ...(eqStr(v, o) && { selected: true }) }, o));
404
+ const getStrOptions = (v, optsStr, exclude_values_string) => {
405
+ const exclude_values = exclude_values_string
406
+ ? new Set(exclude_values_string
407
+ .split(",")
408
+ .map((o) => o.trim())
409
+ .filter(Boolean))
410
+ : new Set([]);
411
+ return typeof optsStr === "string"
412
+ ? optsStr
413
+ .split(",")
414
+ .map((o) => o.trim())
415
+ .filter((o) => eqStr(v, o) || !exclude_values.has(o))
416
+ .map((o) => option({ value: text_attr(o), ...(eqStr(v, o) && { selected: true }) }, text_attr(o)))
417
+ : optsStr.map((o, ix) => o && typeof o.name !== "undefined" && typeof o.label !== "undefined"
418
+ ? option({
419
+ value: o.name,
420
+ ...((eqStr(v, o.name) ||
421
+ (ix === 0 && typeof v === "undefined" && o.disabled)) && {
422
+ selected: true,
423
+ }),
424
+ ...(o.disabled && { disabled: true }),
425
+ }, o.label)
426
+ : option({ value: o, ...(eqStr(v, o) && { selected: true }) }, o));
427
+ };
392
428
  const join_fields_in_formula = (fml) => {
393
429
  if (!fml)
394
430
  return [];
395
431
  return [...freeVariables(fml)];
396
432
  };
433
+ const to_locale_string = {
434
+ description: "Show as in locale-sensitive representation",
435
+ configFields: (field) => [
436
+ {
437
+ type: "String",
438
+ name: "locale",
439
+ label: "Locale",
440
+ sublabel: "Blank for default user locale",
441
+ },
442
+ {
443
+ type: "String",
444
+ name: "style",
445
+ label: "Style",
446
+ required: true,
447
+ attributes: {
448
+ options: ["decimal", "currency", "percent", "unit"],
449
+ },
450
+ },
451
+ {
452
+ type: "String",
453
+ name: "currency",
454
+ label: "Currency",
455
+ sublabel: "ISO 4217. Example: USD or EUR",
456
+ required: true,
457
+ showIf: { style: "currency" },
458
+ },
459
+ {
460
+ type: "String",
461
+ name: "currencyDisplay",
462
+ label: "Currency display",
463
+ required: true,
464
+ showIf: { style: "currency" },
465
+ attributes: {
466
+ options: ["symbol", "code", "narrrowSymbol", "name"],
467
+ },
468
+ },
469
+ {
470
+ type: "String",
471
+ name: "unit",
472
+ label: "Unit",
473
+ required: true,
474
+ showIf: { style: "unit" },
475
+ attributes: {
476
+ options: [
477
+ "acre",
478
+ "bit",
479
+ "byte",
480
+ "celsius",
481
+ "centimeter",
482
+ "day",
483
+ "degree",
484
+ "fahrenheit",
485
+ "fluid-ounce",
486
+ "foot",
487
+ "gallon",
488
+ "gigabit",
489
+ "gigabyte",
490
+ "gram",
491
+ "hectare",
492
+ "hour",
493
+ "inch",
494
+ "kilobit",
495
+ "kilobyte",
496
+ "kilogram",
497
+ "kilometer",
498
+ "liter",
499
+ "megabit",
500
+ "megabyte",
501
+ "meter",
502
+ "microsecond",
503
+ "mile",
504
+ "mile-scandinavian",
505
+ "milliliter",
506
+ "millimeter",
507
+ "millisecond",
508
+ "minute",
509
+ "month",
510
+ "nanosecond",
511
+ "ounce",
512
+ "percent",
513
+ "petabyte",
514
+ "pound",
515
+ "second",
516
+ "stone",
517
+ "terabit",
518
+ "terabyte",
519
+ "week",
520
+ "yard",
521
+ "year",
522
+ ],
523
+ },
524
+ },
525
+ {
526
+ type: "String",
527
+ name: "unitDisplay",
528
+ label: "Unit display",
529
+ required: true,
530
+ showIf: { style: "unit" },
531
+ attributes: {
532
+ options: ["short", "narrow", "long"],
533
+ },
534
+ },
535
+ ],
536
+ isEdit: false,
537
+ run: (v, req, attrs = {}) => {
538
+ const v1 = typeof v === "string" ? +v : v;
539
+ if (typeof v1 === "number") {
540
+ const locale_ = attrs.locale || locale(req);
541
+ return v1.toLocaleString(locale_, {
542
+ style: attrs.style,
543
+ currency: attrs.currency,
544
+ currencyDisplay: attrs.currencyDisplay,
545
+ unit: attrs.unit,
546
+ unitDisplay: attrs.unitDisplay,
547
+ });
548
+ }
549
+ else
550
+ return "";
551
+ },
552
+ };
397
553
  /**
398
554
  * string type
399
555
  * @namespace
@@ -403,6 +559,7 @@ const join_fields_in_formula = (fml) => {
403
559
  const string = {
404
560
  /** @type {string} */
405
561
  name: "String",
562
+ description: "A sequence of unicode characters of any length.",
406
563
  /** @type {string} */
407
564
  sql_name: "text",
408
565
  js_type: "string",
@@ -516,6 +673,46 @@ const string = {
516
673
  description: "Show as a code block",
517
674
  run: (s) => (s ? pre(code(text_attr(s || ""))) : ""),
518
675
  },
676
+ monospace_block: {
677
+ isEdit: false,
678
+ configFields: [
679
+ {
680
+ name: "max_init_height",
681
+ label: "Max initial rows",
682
+ sublabel: "Only show this many rows until the user clicks",
683
+ type: "Integer",
684
+ },
685
+ { name: "copy_btn", label: "Copy button", type: "Bool" },
686
+ ],
687
+ description: "Show as a monospace block",
688
+ run: (s, req, attrs = {}) => {
689
+ if (!s)
690
+ return "";
691
+ const copy_btn = attrs.copy_btn
692
+ ? button({
693
+ class: "btn btn-secondary btn-sm monospace-copy-btn m-1 d-none-prefer",
694
+ onclick: "copy_monospace_block(this)",
695
+ }, i({ class: "fas fa-copy" }))
696
+ : "";
697
+ if (!attrs.max_init_height)
698
+ return (copy_btn +
699
+ pre({
700
+ class: "monospace-block",
701
+ }, s));
702
+ const lines = s.split("\n");
703
+ if (lines.length <= attrs.max_init_height)
704
+ return (copy_btn +
705
+ pre({
706
+ class: "monospace-block",
707
+ }, s));
708
+ return (copy_btn +
709
+ pre({
710
+ class: "monospace-block",
711
+ onclick: `monospace_block_click(this)`,
712
+ }, lines.slice(0, attrs.max_init_height).join("\n") + "\n...") +
713
+ pre({ class: "d-none" }, s));
714
+ },
715
+ },
519
716
  ellipsize: {
520
717
  isEdit: false,
521
718
  configFields: [
@@ -603,6 +800,16 @@ const string = {
603
800
  },
604
801
  ]
605
802
  : []),
803
+ ...(field.attributes.options && field.attributes.options.length > 0
804
+ ? [
805
+ {
806
+ name: "exclude_values",
807
+ label: "Exclude values",
808
+ sublabel: "Comma-separated list of value to exclude from the dropdown select",
809
+ type: "String",
810
+ },
811
+ ]
812
+ : []),
606
813
  {
607
814
  name: "placeholder",
608
815
  label: "Placeholder",
@@ -655,13 +862,13 @@ const string = {
655
862
  }, attrs.placeholder && (required || attrs.force_required)
656
863
  ? [
657
864
  option({ value: "", disabled: true, selected: !v }, attrs.placeholder),
658
- ...getStrOptions(v, attrs.options),
865
+ ...getStrOptions(v, attrs.options, attrs.exclude_values),
659
866
  ]
660
867
  : required || attrs.force_required
661
- ? getStrOptions(v, attrs.options)
868
+ ? getStrOptions(v, attrs.options, attrs.exclude_values)
662
869
  : [
663
870
  option({ value: "" }, attrs.neutral_label || ""),
664
- ...getStrOptions(v, attrs.options),
871
+ ...getStrOptions(v, attrs.options, attrs.exclude_values),
665
872
  ])
666
873
  : attrs.options
667
874
  ? none_available(required)
@@ -1060,6 +1267,7 @@ const is_valid_regexp = (s) => {
1060
1267
  const int = {
1061
1268
  /** @type {string} */
1062
1269
  name: "Integer",
1270
+ description: "Whole numbers, positive and negative.",
1063
1271
  /** @type {string} */
1064
1272
  sql_name: "int",
1065
1273
  js_type: "number",
@@ -1184,6 +1392,34 @@ const int = {
1184
1392
  label({ for: `input${text_attr(nm)}-${starVal}` }, i({ class: "fas fa-star" }))));
1185
1393
  },
1186
1394
  },
1395
+ to_locale_string,
1396
+ role_select: {
1397
+ isEdit: true,
1398
+ blockDisplay: true,
1399
+ description: "Select a user role",
1400
+ fill_options: async (field) => {
1401
+ const roles = await User.get_roles();
1402
+ field.options = roles;
1403
+ },
1404
+ run: (nm, v, attrs, cls, required, field) => {
1405
+ return select({
1406
+ class: [
1407
+ "form-control",
1408
+ "form-select",
1409
+ cls,
1410
+ attrs.selectizable ? "selectizable" : false,
1411
+ ],
1412
+ name: text_attr(nm),
1413
+ "data-fieldname": text_attr(field.name),
1414
+ id: `input${text_attr(nm)}`,
1415
+ disabled: attrs.disabled,
1416
+ onChange: attrs.onChange,
1417
+ onBlur: attrs.onChange,
1418
+ autocomplete: "off",
1419
+ required: true,
1420
+ }, field.options.map(({ id, role }) => option({ value: id, selected: v == id }, role)));
1421
+ },
1422
+ },
1187
1423
  },
1188
1424
  /** @type {object[]} */
1189
1425
  attributes: [
@@ -1233,6 +1469,7 @@ const int = {
1233
1469
  const color = {
1234
1470
  /** @type {string} */
1235
1471
  name: "Color",
1472
+ description: "Colors, defined as Red, Green and Blue with 256 level each",
1236
1473
  /** @type {string} */
1237
1474
  sql_name: "text",
1238
1475
  js_type: "string",
@@ -1314,6 +1551,7 @@ const color = {
1314
1551
  const float = {
1315
1552
  /** @type {string} */
1316
1553
  name: "Float",
1554
+ description: "Floating-point numbers",
1317
1555
  /** @type {string} */
1318
1556
  sql_name: "double precision",
1319
1557
  js_type: "number",
@@ -1382,6 +1620,7 @@ const float = {
1382
1620
  heat_cell: heat_cell("Float"),
1383
1621
  above_input: float_number_limit("gte"),
1384
1622
  below_input: float_number_limit("lte"),
1623
+ to_locale_string,
1385
1624
  show_with_html,
1386
1625
  },
1387
1626
  /** @type {object[]} */
@@ -1446,6 +1685,7 @@ const logit = (x) => {
1446
1685
  const date = {
1447
1686
  /** @type {string} */
1448
1687
  name: "Date",
1688
+ description: "Dates, with or without time",
1449
1689
  /** @type {string} */
1450
1690
  sql_name: "timestamptz",
1451
1691
  js_type: "Date",
@@ -1656,6 +1896,7 @@ const date = {
1656
1896
  const bool = {
1657
1897
  /** @type {string} */
1658
1898
  name: "Bool",
1899
+ description: "Boolean values: true or false",
1659
1900
  /** @type {string} */
1660
1901
  sql_name: "boolean",
1661
1902
  js_type: "boolean",