@dxos/react-ui-geo 0.7.5-labs.ff2ff30 → 0.7.5-main.b19bfc8

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 (38) hide show
  1. package/dist/lib/browser/index.mjs +146 -81
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +123 -58
  5. package/dist/lib/node/index.cjs.map +3 -3
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +146 -81
  8. package/dist/lib/node-esm/index.mjs.map +3 -3
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/components/Globe/Globe.d.ts +5 -5
  11. package/dist/types/src/components/Globe/Globe.d.ts.map +1 -1
  12. package/dist/types/src/components/Globe/Globe.stories.d.ts +9 -10
  13. package/dist/types/src/components/Globe/Globe.stories.d.ts.map +1 -1
  14. package/dist/types/src/components/Map/Map.d.ts +9 -10
  15. package/dist/types/src/components/Map/Map.d.ts.map +1 -1
  16. package/dist/types/src/components/Map/Map.stories.d.ts +6 -2
  17. package/dist/types/src/components/Map/Map.stories.d.ts.map +1 -1
  18. package/dist/types/src/components/Toolbar/Controls.d.ts +2 -3
  19. package/dist/types/src/components/Toolbar/Controls.d.ts.map +1 -1
  20. package/dist/types/src/components/types.d.ts +2 -1
  21. package/dist/types/src/components/types.d.ts.map +1 -1
  22. package/dist/types/src/hooks/context.d.ts +2 -2
  23. package/dist/types/src/hooks/context.d.ts.map +1 -1
  24. package/dist/types/src/hooks/useTour.d.ts +8 -3
  25. package/dist/types/src/hooks/useTour.d.ts.map +1 -1
  26. package/dist/types/src/util/debug.d.ts.map +1 -1
  27. package/dist/types/src/util/render.d.ts +2 -2
  28. package/dist/types/src/util/render.d.ts.map +1 -1
  29. package/package.json +12 -10
  30. package/src/components/Globe/Globe.stories.tsx +8 -11
  31. package/src/components/Globe/Globe.tsx +56 -32
  32. package/src/components/Map/Map.stories.tsx +28 -6
  33. package/src/components/Map/Map.tsx +93 -82
  34. package/src/components/types.ts +2 -1
  35. package/src/hooks/useDrag.ts +1 -1
  36. package/src/hooks/useTour.ts +31 -19
  37. package/src/util/debug.ts +1 -0
  38. package/src/util/render.ts +18 -4
@@ -5,13 +5,13 @@ import {
5
5
 
6
6
  // packages/ui/react-ui-geo/src/components/Globe/Globe.tsx
7
7
  import * as d37 from "d3";
8
- import React3, { forwardRef, useEffect as useEffect4, useImperativeHandle, useMemo, useRef, useState as useState3 } from "react";
8
+ import React4, { forwardRef, useEffect as useEffect4, useImperativeHandle, useMemo, useRef, useState as useState3 } from "react";
9
9
  import { useResizeDetector } from "react-resize-detector";
10
- import { useDynamicRef } from "@dxos/react-ui";
10
+ import { useDynamicRef, useThemeContext } from "@dxos/react-ui";
11
11
  import { mx } from "@dxos/react-ui-theme";
12
12
 
13
13
  // packages/ui/react-ui-geo/src/hooks/context.tsx
14
- import React, { createContext, useContext } from "react";
14
+ import React2, { createContext, useContext } from "react";
15
15
  import { raise } from "@dxos/debug";
16
16
  import { useControlledState } from "@dxos/react-ui";
17
17
  var GlobeContext = /* @__PURE__ */ createContext(void 0);
@@ -20,7 +20,7 @@ var GlobeContextProvider = ({ children, size, center: _center, scale: _scale, tr
20
20
  const [scale, setScale] = useControlledState(_scale);
21
21
  const [translation, setTranslation] = useControlledState(_translation);
22
22
  const [rotation, setRotation] = useControlledState(_rotation);
23
- return /* @__PURE__ */ React.createElement(GlobeContext.Provider, {
23
+ return /* @__PURE__ */ React2.createElement(GlobeContext.Provider, {
24
24
  value: {
25
25
  size,
26
26
  center,
@@ -350,17 +350,22 @@ var createLayers = (topology, features, styles) => {
350
350
  }
351
351
  return layers;
352
352
  };
353
- var renderLayers = (generator, layers = [], scale) => {
353
+ var renderLayers = (generator, layers = [], scale, styles) => {
354
354
  const context = generator.context();
355
355
  const { canvas: { width, height } } = context;
356
356
  context.reset();
357
- context.clearRect(0, 0, width, height);
358
- layers.forEach(({ path, styles }) => {
357
+ if (styles.background) {
358
+ context.fillStyle = styles.background.fillStyle;
359
+ context.fillRect(0, 0, width, height);
360
+ } else {
361
+ context.clearRect(0, 0, width, height);
362
+ }
363
+ layers.forEach(({ path, styles: styles2 }) => {
359
364
  context.save();
360
365
  let fill = false;
361
366
  let stroke = false;
362
- if (styles) {
363
- Object.entries(styles).forEach(([key, value]) => {
367
+ if (styles2) {
368
+ Object.entries(styles2).forEach(([key, value]) => {
364
369
  if (key === "pointRadius") {
365
370
  generator.pointRadius(value * scale);
366
371
  } else {
@@ -409,7 +414,7 @@ var useDrag = (controller, options = {}) => {
409
414
  };
410
415
  }, [
411
416
  controller,
412
- options
417
+ JSON.stringify(options)
413
418
  ]);
414
419
  };
415
420
  var cancelDrag = (node) => node.on(".drag", null);
@@ -515,11 +520,13 @@ var useSpinner = (controller, options = {}) => {
515
520
  import * as d36 from "d3";
516
521
  import { useEffect as useEffect3, useState as useState2 } from "react";
517
522
  import versor2 from "versor";
523
+ import { log } from "@dxos/log";
524
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-geo/src/hooks/useTour.ts";
518
525
  var TRANSITION_NAME = "globe-tour";
519
526
  var defaultDuration = 1500;
520
- var useTour = (controller, features, options = {}) => {
527
+ var useTour = (controller, points, options = {}) => {
521
528
  const selection2 = d36.selection();
522
- const [running, setRunning] = useState2(false);
529
+ const [running, setRunning] = useState2(options.running ?? false);
523
530
  useEffect3(() => {
524
531
  if (!running) {
525
532
  selection2.interrupt(TRANSITION_NAME);
@@ -533,10 +540,16 @@ var useTour = (controller, features, options = {}) => {
533
540
  alpha: false
534
541
  });
535
542
  const path = d36.geoPath(projection, context).pointRadius(2);
536
- const tilt = 0;
543
+ const tilt = options.tilt ?? 0;
537
544
  let last;
538
545
  try {
539
- for (const next of features.points) {
546
+ const p = [
547
+ ...points
548
+ ];
549
+ if (options.loop) {
550
+ p.push(p[0]);
551
+ }
552
+ for (const next of p) {
540
553
  if (!running) {
541
554
  break;
542
555
  }
@@ -574,13 +587,22 @@ var useTour = (controller, features, options = {}) => {
574
587
  context.fill();
575
588
  }
576
589
  context.restore();
577
- projection.rotate(iv(t2));
578
- setRotation(projection.rotate());
590
+ if (options.autoRotate) {
591
+ projection.rotate(iv(t2));
592
+ setRotation(projection.rotate());
593
+ }
579
594
  });
580
595
  await transition2.end();
581
596
  last = next;
582
597
  }
583
598
  } catch (err) {
599
+ log.catch(err, void 0, {
600
+ F: __dxlog_file,
601
+ L: 112,
602
+ S: void 0,
603
+ C: (f, a) => f(...a)
604
+ });
605
+ } finally {
584
606
  setRunning(false);
585
607
  }
586
608
  });
@@ -591,20 +613,17 @@ var useTour = (controller, features, options = {}) => {
591
613
  }
592
614
  }, [
593
615
  controller,
594
- running
616
+ running,
617
+ JSON.stringify(options)
595
618
  ]);
596
619
  return [
597
- () => {
598
- if (!options.disabled) {
599
- setRunning(true);
600
- }
601
- },
602
- () => setRunning(false)
620
+ running,
621
+ setRunning
603
622
  ];
604
623
  };
605
624
 
606
625
  // packages/ui/react-ui-geo/src/components/Toolbar/Controls.tsx
607
- import React2 from "react";
626
+ import React3 from "react";
608
627
  import { IconButton, Toolbar } from "@dxos/react-ui";
609
628
  var controlPositions = {
610
629
  topleft: "top-2 left-2",
@@ -613,12 +632,12 @@ var controlPositions = {
613
632
  bottomright: "bottom-2 right-2"
614
633
  };
615
634
  var ZoomControls = ({ classNames, onAction }) => {
616
- return /* @__PURE__ */ React2.createElement(Toolbar.Root, {
635
+ return /* @__PURE__ */ React3.createElement(Toolbar.Root, {
617
636
  classNames: [
618
637
  "gap-1",
619
638
  classNames
620
639
  ]
621
- }, /* @__PURE__ */ React2.createElement(IconButton, {
640
+ }, /* @__PURE__ */ React3.createElement(IconButton, {
622
641
  //
623
642
  icon: "ph--plus--regular",
624
643
  label: "zoom in",
@@ -626,7 +645,7 @@ var ZoomControls = ({ classNames, onAction }) => {
626
645
  size: 5,
627
646
  classNames: "px-0 aspect-square",
628
647
  onClick: () => onAction?.("zoom-in")
629
- }), /* @__PURE__ */ React2.createElement(IconButton, {
648
+ }), /* @__PURE__ */ React3.createElement(IconButton, {
630
649
  //
631
650
  icon: "ph--minus--regular",
632
651
  label: "zoom out",
@@ -637,12 +656,12 @@ var ZoomControls = ({ classNames, onAction }) => {
637
656
  }));
638
657
  };
639
658
  var ActionControls = ({ classNames, onAction }) => {
640
- return /* @__PURE__ */ React2.createElement(Toolbar.Root, {
659
+ return /* @__PURE__ */ React3.createElement(Toolbar.Root, {
641
660
  classNames: [
642
661
  "gap-1",
643
662
  classNames
644
663
  ]
645
- }, /* @__PURE__ */ React2.createElement(IconButton, {
664
+ }, /* @__PURE__ */ React3.createElement(IconButton, {
646
665
  //
647
666
  icon: "ph--play--regular",
648
667
  label: "start",
@@ -650,7 +669,7 @@ var ActionControls = ({ classNames, onAction }) => {
650
669
  size: 5,
651
670
  classNames: "px-0 aspect-square",
652
671
  onClick: () => onAction?.("start")
653
- }), /* @__PURE__ */ React2.createElement(IconButton, {
672
+ }), /* @__PURE__ */ React3.createElement(IconButton, {
654
673
  //
655
674
  icon: "ph--globe-hemisphere-west--regular",
656
675
  label: "toggle",
@@ -663,28 +682,45 @@ var ActionControls = ({ classNames, onAction }) => {
663
682
 
664
683
  // packages/ui/react-ui-geo/src/components/Globe/Globe.tsx
665
684
  var defaultStyles = {
666
- background: {
667
- fillStyle: "#111111"
668
- },
669
- water: {
670
- fillStyle: "#123E6A"
671
- },
672
- hex: {
673
- strokeStyle: "green",
674
- fillStyle: "gray",
675
- pointRadius: 1
676
- },
677
- land: {
678
- fillStyle: "#032153"
679
- },
680
- line: {
681
- strokeStyle: "#111111"
685
+ light: {
686
+ background: {
687
+ fillStyle: "#EEE"
688
+ },
689
+ water: {
690
+ fillStyle: "#555"
691
+ },
692
+ land: {
693
+ fillStyle: "#999"
694
+ },
695
+ line: {
696
+ strokeStyle: "darkred"
697
+ },
698
+ point: {
699
+ fillStyle: "#111111",
700
+ strokeStyle: "#111111",
701
+ strokeWidth: 1,
702
+ pointRadius: 0.5
703
+ }
682
704
  },
683
- point: {
684
- fillStyle: "#111111",
685
- strokeStyle: "#111111",
686
- strokeWidth: 1,
687
- pointRadius: 0.5
705
+ dark: {
706
+ background: {
707
+ fillStyle: "#111111"
708
+ },
709
+ water: {
710
+ fillStyle: "#123E6A"
711
+ },
712
+ land: {
713
+ fillStyle: "#032153"
714
+ },
715
+ line: {
716
+ strokeStyle: "#111111"
717
+ },
718
+ point: {
719
+ fillStyle: "#111111",
720
+ strokeStyle: "#111111",
721
+ strokeWidth: 1,
722
+ pointRadius: 0.5
723
+ }
688
724
  }
689
725
  };
690
726
  var projectionMap = {
@@ -701,10 +737,10 @@ var getProjection = (type = "orthographic") => {
701
737
  };
702
738
  var GlobeRoot = ({ classNames, children, ...props }) => {
703
739
  const { ref, width, height } = useResizeDetector();
704
- return /* @__PURE__ */ React3.createElement("div", {
740
+ return /* @__PURE__ */ React4.createElement("div", {
705
741
  ref,
706
742
  className: mx("relative flex grow overflow-hidden", classNames)
707
- }, /* @__PURE__ */ React3.createElement(GlobeContextProvider, {
743
+ }, /* @__PURE__ */ React4.createElement(GlobeContextProvider, {
708
744
  size: {
709
745
  width,
710
746
  height
@@ -712,7 +748,12 @@ var GlobeRoot = ({ classNames, children, ...props }) => {
712
748
  ...props
713
749
  }, children));
714
750
  };
715
- var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topology, features, styles = defaultStyles }, forwardRef3) => {
751
+ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topology, features, styles: _styles }, forwardRef3) => {
752
+ const { themeMode } = useThemeContext();
753
+ const styles = useMemo(() => _styles ?? defaultStyles[themeMode], [
754
+ _styles,
755
+ themeMode
756
+ ]);
716
757
  const [canvas, setCanvas] = useState3(null);
717
758
  const canvasRef = (canvas2) => setCanvas(canvas2);
718
759
  const projection = useMemo(() => getProjection(_projection), [
@@ -780,7 +821,7 @@ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topolog
780
821
  0,
781
822
  0
782
823
  ]);
783
- renderLayers(generator, layers, scale);
824
+ renderLayers(generator, layers, scale, styles);
784
825
  });
785
826
  }
786
827
  }, [
@@ -794,7 +835,7 @@ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topolog
794
835
  if (!size.width || !size.height) {
795
836
  return null;
796
837
  }
797
- return /* @__PURE__ */ React3.createElement("canvas", {
838
+ return /* @__PURE__ */ React4.createElement("canvas", {
798
839
  ref: canvasRef,
799
840
  width: size.width,
800
841
  height: size.height
@@ -802,9 +843,9 @@ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topolog
802
843
  });
803
844
  var GlobeDebug = ({ position = "topleft" }) => {
804
845
  const { size, scale, translation, rotation } = useGlobeContext();
805
- return /* @__PURE__ */ React3.createElement("div", {
846
+ return /* @__PURE__ */ React4.createElement("div", {
806
847
  className: mx("z-10 absolute w-96 p-2 overflow-hidden border border-green-700 rounded", controlPositions[position])
807
- }, /* @__PURE__ */ React3.createElement("pre", {
848
+ }, /* @__PURE__ */ React4.createElement("pre", {
808
849
  className: "font-mono text-xs text-green-700"
809
850
  }, JSON.stringify({
810
851
  size,
@@ -814,28 +855,28 @@ var GlobeDebug = ({ position = "topleft" }) => {
814
855
  }, null, 2)));
815
856
  };
816
857
  var GlobePanel = ({ position, classNames, children }) => {
817
- return /* @__PURE__ */ React3.createElement("div", {
858
+ return /* @__PURE__ */ React4.createElement("div", {
818
859
  className: mx("z-10 absolute overflow-hidden", controlPositions[position], classNames)
819
860
  }, children);
820
861
  };
821
862
  var CustomControl = ({ position, children }) => {
822
- return /* @__PURE__ */ React3.createElement("div", {
863
+ return /* @__PURE__ */ React4.createElement("div", {
823
864
  className: mx("z-10 absolute overflow-hidden", controlPositions[position])
824
865
  }, children);
825
866
  };
826
867
  var Globe = {
827
868
  Root: GlobeRoot,
828
869
  Canvas: GlobeCanvas,
829
- Zoom: ({ onAction, position = "bottomleft", ...props }) => /* @__PURE__ */ React3.createElement(CustomControl, {
870
+ Zoom: ({ onAction, position = "bottomleft", ...props }) => /* @__PURE__ */ React4.createElement(CustomControl, {
830
871
  position,
831
872
  ...props
832
- }, /* @__PURE__ */ React3.createElement(ZoomControls, {
873
+ }, /* @__PURE__ */ React4.createElement(ZoomControls, {
833
874
  onAction
834
875
  })),
835
- Action: ({ onAction, position = "bottomright", ...props }) => /* @__PURE__ */ React3.createElement(CustomControl, {
876
+ Action: ({ onAction, position = "bottomright", ...props }) => /* @__PURE__ */ React4.createElement(CustomControl, {
836
877
  position,
837
878
  ...props
838
- }, /* @__PURE__ */ React3.createElement(ActionControls, {
879
+ }, /* @__PURE__ */ React4.createElement(ActionControls, {
839
880
  onAction
840
881
  })),
841
882
  Debug: GlobeDebug,
@@ -844,13 +885,13 @@ var Globe = {
844
885
 
845
886
  // packages/ui/react-ui-geo/src/components/Map/Map.tsx
846
887
  import "leaflet/dist/leaflet.css";
847
- import { Control, DomEvent, DomUtil, latLngBounds } from "leaflet";
848
- import React4, { forwardRef as forwardRef2, useEffect as useEffect5, useImperativeHandle as useImperativeHandle2 } from "react";
888
+ import L, { Control, DomEvent, DomUtil, latLngBounds } from "leaflet";
889
+ import { forwardRef as forwardRef2, useEffect as useEffect5, useImperativeHandle as useImperativeHandle2 } from "react";
849
890
  import { createRoot } from "react-dom/client";
850
891
  import { MapContainer, Marker, Popup, TileLayer, useMap } from "react-leaflet";
851
892
  import { useResizeDetector as useResizeDetector2 } from "react-resize-detector";
852
893
  import { debounce } from "@dxos/async";
853
- import { Tooltip, ThemeProvider } from "@dxos/react-ui";
894
+ import { ThemeProvider, Tooltip } from "@dxos/react-ui";
854
895
  import { defaultTx, mx as mx2 } from "@dxos/react-ui-theme";
855
896
  var defaults = {
856
897
  // TODO(burdon): Guess location.
@@ -861,7 +902,7 @@ var defaults = {
861
902
  zoom: 4
862
903
  };
863
904
  var MapRoot = ({ classNames, center = defaults.center, zoom = defaults.zoom, ...props }) => {
864
- return /* @__PURE__ */ React4.createElement(MapContainer, {
905
+ return /* @__PURE__ */ React.createElement(MapContainer, {
865
906
  className: mx2("relative flex w-full h-full grow bg-baseSurface", classNames),
866
907
  attributionControl: false,
867
908
  // TODO(burdon): Only if attention.
@@ -872,7 +913,7 @@ var MapRoot = ({ classNames, center = defaults.center, zoom = defaults.zoom, ...
872
913
  ...props
873
914
  });
874
915
  };
875
- var MapCanvas = /* @__PURE__ */ forwardRef2(({ markers = [], center, zoom, onChange }, forwardedRef) => {
916
+ var MapCanvas = /* @__PURE__ */ forwardRef2(({ markers, center, zoom, onChange }, forwardedRef) => {
876
917
  const { ref, width, height } = useResizeDetector2({
877
918
  refreshRate: 200
878
919
  });
@@ -932,20 +973,44 @@ var MapCanvas = /* @__PURE__ */ forwardRef2(({ markers = [], center, zoom, onCha
932
973
  }, [
933
974
  markers
934
975
  ]);
935
- return /* @__PURE__ */ React4.createElement("div", {
976
+ return /* @__PURE__ */ React.createElement("div", {
936
977
  ref,
937
978
  className: "flex w-full h-full overflow-hidden bg-baseSurface"
938
- }, /* @__PURE__ */ React4.createElement(TileLayer, {
979
+ }, /* @__PURE__ */ React.createElement(TileLayer, {
939
980
  className: "dark:filter dark:grayscale dark:invert",
940
981
  url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
941
- }), markers.map(({ id, title, location: { lat, lng } }) => {
942
- return /* @__PURE__ */ React4.createElement(Marker, {
982
+ }), markers?.map(({ id, title, location: { lat, lng } }) => {
983
+ return /* @__PURE__ */ React.createElement(Marker, {
943
984
  key: id,
944
985
  position: {
945
986
  lat,
946
987
  lng
947
- }
948
- }, title && /* @__PURE__ */ React4.createElement(Popup, null, title));
988
+ },
989
+ icon: (
990
+ // TODO(burdon): Create custom icon from bundled assets.
991
+ new L.Icon({
992
+ iconUrl: "https://dxos.network/marker-icon.png",
993
+ iconRetinaUrl: "https://dxos.network/marker-icon-2x.png",
994
+ shadowUrl: "https://dxos.network/marker-shadow.png",
995
+ iconSize: [
996
+ 25,
997
+ 41
998
+ ],
999
+ iconAnchor: [
1000
+ 12,
1001
+ 41
1002
+ ],
1003
+ popupAnchor: [
1004
+ 1,
1005
+ -34
1006
+ ],
1007
+ shadowSize: [
1008
+ 41,
1009
+ 41
1010
+ ]
1011
+ })
1012
+ )
1013
+ }, title && /* @__PURE__ */ React.createElement(Popup, null, title));
949
1014
  }));
950
1015
  });
951
1016
  var CustomControl2 = ({ position, children }) => {
@@ -959,9 +1024,9 @@ var CustomControl2 = ({ position, children }) => {
959
1024
  DomEvent.disableClickPropagation(container);
960
1025
  DomEvent.disableScrollPropagation(container);
961
1026
  const root = createRoot(container);
962
- root.render(/* @__PURE__ */ React4.createElement(ThemeProvider, {
1027
+ root.render(/* @__PURE__ */ React.createElement(ThemeProvider, {
963
1028
  tx: defaultTx
964
- }, /* @__PURE__ */ React4.createElement(Tooltip.Provider, null, children)));
1029
+ }, /* @__PURE__ */ React.createElement(Tooltip.Provider, null, children)));
965
1030
  return container;
966
1031
  };
967
1032
  control.addTo(map);
@@ -978,16 +1043,16 @@ var CustomControl2 = ({ position, children }) => {
978
1043
  var Map = {
979
1044
  Root: MapRoot,
980
1045
  Canvas: MapCanvas,
981
- Zoom: ({ onAction, position = "bottomleft", ...props }) => /* @__PURE__ */ React4.createElement(CustomControl2, {
1046
+ Zoom: ({ onAction, position = "bottomleft", ...props }) => /* @__PURE__ */ React.createElement(CustomControl2, {
982
1047
  position,
983
1048
  ...props
984
- }, /* @__PURE__ */ React4.createElement(ZoomControls, {
1049
+ }, /* @__PURE__ */ React.createElement(ZoomControls, {
985
1050
  onAction
986
1051
  })),
987
- Action: ({ onAction, position = "bottomright", ...props }) => /* @__PURE__ */ React4.createElement(CustomControl2, {
1052
+ Action: ({ onAction, position = "bottomright", ...props }) => /* @__PURE__ */ React.createElement(CustomControl2, {
988
1053
  position,
989
1054
  ...props
990
- }, /* @__PURE__ */ React4.createElement(ActionControls, {
1055
+ }, /* @__PURE__ */ React.createElement(ActionControls, {
991
1056
  onAction
992
1057
  }))
993
1058
  };