@3cr/viewer-browser 0.0.52 → 0.0.55

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 (71) hide show
  1. package/README.md +108 -81
  2. package/__tests__/index.spec.ts +31 -0
  3. package/components.d.ts +2 -2
  4. package/coverage/3cr-viewer-browser/index.html +116 -0
  5. package/coverage/3cr-viewer-browser/index.ts.html +211 -0
  6. package/coverage/3cr-viewer-browser/src/App.vue.html +313 -0
  7. package/coverage/3cr-viewer-browser/src/components/WebGL3DR.vue.html +442 -0
  8. package/coverage/3cr-viewer-browser/src/components/icons/index.html +116 -0
  9. package/coverage/3cr-viewer-browser/src/components/icons/liver.vue.html +148 -0
  10. package/coverage/3cr-viewer-browser/src/components/index.html +116 -0
  11. package/coverage/3cr-viewer-browser/src/components/loading/LoadingSpinner.vue.html +556 -0
  12. package/coverage/3cr-viewer-browser/src/components/loading/index.html +116 -0
  13. package/coverage/3cr-viewer-browser/src/components/modal/MftpWebGL3DRModal.vue.html +3931 -0
  14. package/coverage/3cr-viewer-browser/src/components/modal/index.html +116 -0
  15. package/coverage/3cr-viewer-browser/src/components/selectors/ValueSelector.vue.html +331 -0
  16. package/coverage/3cr-viewer-browser/src/components/selectors/index.html +116 -0
  17. package/coverage/3cr-viewer-browser/src/components/sliders/DoubleSliderSelector.vue.html +445 -0
  18. package/coverage/3cr-viewer-browser/src/components/sliders/VerticalSliderSelector.vue.html +349 -0
  19. package/coverage/3cr-viewer-browser/src/components/sliders/index.html +131 -0
  20. package/coverage/3cr-viewer-browser/src/helpers/index.html +146 -0
  21. package/coverage/3cr-viewer-browser/src/helpers/layoutOverlayStyle.ts.html +406 -0
  22. package/coverage/3cr-viewer-browser/src/helpers/modelHelper.ts.html +412 -0
  23. package/coverage/3cr-viewer-browser/src/helpers/utils.ts.html +133 -0
  24. package/coverage/3cr-viewer-browser/src/index.html +131 -0
  25. package/coverage/3cr-viewer-browser/src/main.ts.html +124 -0
  26. package/coverage/3cr-viewer-browser/src/plugins/index.html +131 -0
  27. package/coverage/3cr-viewer-browser/src/plugins/index.ts.html +130 -0
  28. package/coverage/3cr-viewer-browser/src/plugins/vuetify.ts.html +220 -0
  29. package/coverage/base.css +224 -0
  30. package/coverage/block-navigation.js +87 -0
  31. package/coverage/favicon.png +0 -0
  32. package/coverage/index.html +251 -0
  33. package/coverage/prettify.css +1 -0
  34. package/coverage/prettify.js +2 -0
  35. package/coverage/sort-arrow-sprite.png +0 -0
  36. package/coverage/sorter.js +196 -0
  37. package/dist/Viewer3CR.js +17 -11
  38. package/dist/Viewer3CR.mjs +5352 -5183
  39. package/dist/Viewer3CR.umd.js +17 -11
  40. package/index.html +4 -1
  41. package/index.ts +16 -12
  42. package/package.json +8 -3
  43. package/src/App.vue +1 -9
  44. package/src/__tests__/app.spec.ts +27 -0
  45. package/src/components/WebGL3DR.vue +49 -37
  46. package/src/components/__tests__/webgl3dr.spec.ts +56 -0
  47. package/src/components/icons/liver.vue +21 -0
  48. package/src/components/loading/__tests__/loading-spinner.spec.ts +11 -0
  49. package/src/components/modal/MftpWebGL3DRModal.vue +662 -394
  50. package/src/components/modal/__tests__/mftp-webgl-3dr-modal.spec.ts +690 -0
  51. package/src/components/selectors/__tests__/value-selector.spec.ts +35 -0
  52. package/src/components/sliders/DoubleSliderSelector.vue +30 -24
  53. package/src/components/sliders/VerticalSliderSelector.vue +25 -21
  54. package/src/components/sliders/__tests__/double-slider-selector.spec.ts +72 -0
  55. package/src/components/sliders/__tests__/vertical-slider-selector.spec.ts +61 -0
  56. package/src/helpers/__tests__/layout-overlay-style.spec.ts +288 -0
  57. package/src/helpers/__tests__/model-helper.spec.ts +118 -0
  58. package/src/helpers/__tests__/utils.spec.ts +70 -0
  59. package/src/helpers/layoutOverlayStyle.ts +50 -30
  60. package/src/plugins/__tests__/index.spec.ts +19 -0
  61. package/src/plugins/__tests__/vuetify.spec.ts +8 -0
  62. package/src/plugins/vuetify.ts +25 -8
  63. package/test/helper.ts +35 -0
  64. package/test/setup.ts +1 -0
  65. package/tsconfig.json +5 -2
  66. package/vite.config.mts +1 -0
  67. package/vitest.config.mts +44 -0
  68. package/README2.md +0 -201
  69. package/src/components/expansion-panels/ExpansionHeaderMiniMenu.vue +0 -19
  70. package/src/helpers/models.ts +0 -69
  71. /package/src/components/{sliders/SliderSelector.vue → selectors/ValueSelector.vue} +0 -0
package/index.html CHANGED
@@ -4,7 +4,10 @@
4
4
  <head>
5
5
  <meta charset="UTF-8" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Welcome to Vuetify 3</title>
7
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
8
+ <link href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" rel="stylesheet">
9
+
10
+ <title>Welcome to Vuetify 3</title>
8
11
  </head>
9
12
 
10
13
  <body>
package/index.ts CHANGED
@@ -1,8 +1,7 @@
1
- import {registerVersion} from "@3cr/sdk-browser";
2
- import {ComponentPublicInstance, createApp} from "vue";
3
- import {registerPlugins} from "./src/plugins";
4
- import {App as BrowserViewer} from './src/main';
5
-
1
+ import { registerVersion } from "@3cr/sdk-browser";
2
+ import { ComponentPublicInstance, createApp } from "vue";
3
+ import { registerPlugins } from "./src/plugins";
4
+ import { App as BrowserViewer } from "./src/main";
6
5
 
7
6
  export interface LoadViewerPayload {
8
7
  Url: string;
@@ -13,26 +12,31 @@ export interface MftpDecryptionKey {
13
12
  Iv: string;
14
13
  }
15
14
 
16
- let mountedApp: ComponentPublicInstance | undefined = undefined
15
+ let mountedApp: ComponentPublicInstance | undefined = undefined;
17
16
 
18
17
  export async function registerViewer(version: string) {
19
- const newElement = document.createElement('div')
18
+ const newElement = document.createElement("div");
20
19
 
21
20
  newElement.style.width = "0";
22
21
  newElement.style.height = "0";
23
22
 
24
23
  document.body.appendChild(newElement);
25
24
 
26
- const app = createApp(BrowserViewer)
27
- registerPlugins(app)
25
+ const app = createApp(BrowserViewer);
26
+ registerPlugins(app);
28
27
 
29
28
  mountedApp = app.mount(newElement);
30
29
  await registerVersion(version);
31
30
  }
32
31
 
33
- export async function loadViewer(payload: LoadViewerPayload | undefined = undefined): Promise<void> {
32
+ // TODO: accept callbacks for each function we want the parent to handle
33
+ export async function loadViewer(
34
+ payload: LoadViewerPayload | undefined = undefined
35
+ ): Promise<void> {
34
36
  if (!mountedApp) {
35
- throw new Error('Please call `registerViewer(version: string, idSelector: string)` first');
37
+ throw new Error(
38
+ "Please call `registerViewer(version: string, idSelector: string)` first"
39
+ );
36
40
  }
37
- await (mountedApp as any).loadInstance(payload)
41
+ await (mountedApp as any).loadInstance(payload);
38
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@3cr/viewer-browser",
3
- "version": "0.0.52",
3
+ "version": "0.0.55",
4
4
  "main": "./dist/Viewer3CR.umd.js",
5
5
  "module": "dist/Viewer3CR.umd.js",
6
6
  "homepage": "https://docs.3cr.singular.health",
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@3cr/sdk-browser": "^1.0.13",
23
- "@3cr/types-ts": "^1.0.3",
23
+ "@3cr/types-ts": "^1.0.9",
24
24
  "@mdi/font": "6.2.95",
25
25
  "@mdi/js": "^7.4.47",
26
26
  "roboto-fontface": "*",
@@ -31,11 +31,16 @@
31
31
  "@babel/types": "^7.24.0",
32
32
  "@types/node": "^20.11.25",
33
33
  "@vitejs/plugin-vue": "^5.0.4",
34
- "@vue/test-utils": "^2.4.1",
34
+ "@vitest/coverage-istanbul": "^1.4.0",
35
+ "@vitest/coverage-v8": "^1.4.0",
36
+ "@vitest/ui": "^1.4.0",
37
+ "@vue/test-utils": "^2.4.5",
35
38
  "aws-sdk": "^2.1594.0",
39
+ "jsdom": "^24.0.0",
36
40
  "material-design-icons-iconfont": "^6.7.0",
37
41
  "mime-types": "^2.1.35",
38
42
  "randomstring": "^1.3.0",
43
+ "resize-observer-polyfill": "^1.5.1",
39
44
  "sass": "^1.71.1",
40
45
  "typescript": "^5.4.2",
41
46
  "unplugin-fonts": "^1.1.1",
package/src/App.vue CHANGED
@@ -17,15 +17,7 @@ const payload = ref<LoadViewerPayload>({
17
17
  Key:"KUc722X1y4w42M+jCf9a3+6EGz66z7UMWK3m2aMqGxM="
18
18
  }
19
19
  });
20
- // const payload = ref<LoadViewerPayload>(
21
- // {
22
- // Url:"https://webgl-3dr.singular.health/test_scans/8bdddee1-e581-485d-827d-6aa12eef2fc8/Head+Axial+Axial.3vxl",
23
- // DecryptionKey: {
24
- // Iv:"x856FgjpYDsRhIa3BFj5cg==",
25
- // Key:"OWjSMiL/ewUV1V6fGybhKcTyiysTPsIMp2DjdVoOUGI="
26
- // }
27
- // }
28
- // );
20
+
29
21
  const mftpWebGL3DRModal = ref<typeof MftpWebGL3DRModal | null>(null)
30
22
  defineExpose({
31
23
  loadInstance
@@ -0,0 +1,27 @@
1
+ import { expect, describe, it, vi } from "vitest";
2
+ import { shallowMountVuetify } from "~/helper";
3
+ import App from "@/App.vue";
4
+
5
+ const wrapper = shallowMountVuetify(App);
6
+
7
+ vi.mock("@3cr/sdk-browser", async (importOriginal) => {
8
+ const mod = (await importOriginal()) as object;
9
+ return {
10
+ ...mod,
11
+ // replace some exports
12
+ registerVersion: vi.fn(),
13
+ createInstance: vi.fn(),
14
+ executePayload: vi.fn(),
15
+ registerOnPayloadHandler: vi.fn(),
16
+ };
17
+ });
18
+
19
+ describe("App.vue", () => {
20
+ it("should inflate component", () => {
21
+ expect(wrapper).toBeTruthy();
22
+ });
23
+ it("should loadScan", async () => {
24
+ await wrapper.vm.loadInstance();
25
+ expect(wrapper).toBeTruthy();
26
+ });
27
+ });
@@ -1,5 +1,10 @@
1
1
  <template>
2
- <div id="screenshotWindow" class="" @mouseover="emit('hover', true)" @mouseout="emit('hover', false)">
2
+ <div
3
+ id="screenshotWindow"
4
+ class=""
5
+ @mouseover="emit('hover', true)"
6
+ @mouseout="emit('hover', false)"
7
+ >
3
8
  <canvas
4
9
  id="unity-canvas"
5
10
  width="100%"
@@ -19,10 +24,19 @@
19
24
  </div>
20
25
  </template>
21
26
  <script setup lang="ts">
22
- import {defineEmits, nextTick, onMounted, ref} from 'vue';
27
+ import { defineEmits, nextTick, onMounted, ref } from "vue";
23
28
 
24
- import { createInstance, executePayload, registerOnPayloadHandler } from '@3cr/sdk-browser';
25
- import {FrontEndInterfaces, FrontEndPayload} from '@3cr/sdk-browser/types/payload';
29
+ import {
30
+ createInstance,
31
+ executePayload,
32
+ registerOnPayloadHandler,
33
+ } from "@3cr/sdk-browser";
34
+ import {
35
+ FrontEndInterfaces,
36
+ FrontEndPayload,
37
+ } from "@3cr/sdk-browser/types/payload";
38
+
39
+ const unityInstance = ref<any>(null);
26
40
 
27
41
  const emit = defineEmits<{
28
42
  instance_loaded: [void];
@@ -32,76 +46,74 @@ const emit = defineEmits<{
32
46
 
33
47
  defineExpose({
34
48
  sendPayload,
35
- snap,
36
-
49
+ receiveMessageFromUnity,
37
50
  });
38
51
 
39
52
  onMounted(async () => {
40
- await nextTick()
41
- const canvas = document.querySelector('#unity-canvas') as HTMLCanvasElement;
53
+ await nextTick();
54
+ const canvas = document.querySelector("#unity-canvas") as HTMLCanvasElement;
42
55
 
43
56
  await registerOnPayloadHandler(receiveMessageFromUnity);
44
57
 
58
+ /* c8 ignore start */
45
59
  if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
46
60
  // Mobile device style: fill the whole browser client area with the game canvas:
47
- const meta = document.createElement('meta');
48
- meta.name = 'viewport';
49
- meta.content = 'width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes';
50
- document.getElementsByTagName('head')[0].appendChild(meta);
61
+ const meta = document.createElement("meta");
62
+ meta.name = "viewport";
63
+ meta.content =
64
+ "width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes";
65
+ document.getElementsByTagName("head")[0].appendChild(meta);
51
66
 
52
- canvas.style.width = '100%';
53
- canvas.style.height = '80vh';
54
- canvas.style.position = 'fixed';
67
+ canvas.style.width = "100%";
68
+ canvas.style.height = "80vh";
69
+ canvas.style.position = "fixed";
55
70
 
56
- document.body.style.textAlign = 'left';
71
+ document.body.style.textAlign = "left";
57
72
  }
58
- await nextTick()
73
+ /* c8 ignore stop */
74
+ await nextTick();
59
75
  unityInstance.value = await createInstance(canvas);
60
76
 
61
- await nextTick()
77
+ await nextTick();
62
78
 
63
- if (navigator.storage && navigator.storage.estimate) {
79
+ /* c8 ignore start */
80
+ if (navigator.storage) {
64
81
  const quota = await navigator.storage.estimate();
65
82
  if (quota) {
66
83
  const percentageUsed = (quota.usage! / quota.quota!) * 100;
67
84
  console.log(`You've used ${percentageUsed}% of the available storage.`);
68
85
  const remaining = quota.quota! - quota.usage!;
69
86
  console.log(`You can write up to ${remaining} more bytes.`);
70
-
71
87
  }
72
88
  }
73
- emit('instance_loaded')
89
+ /* c8 ignore stop */
90
+
91
+ emit("instance_loaded");
74
92
  // Overlay scroll events to the container instance
75
- const fixedDiv = document.getElementById('parent-canvas');
76
- fixedDiv?.addEventListener('wheel', function (e: WheelEvent) {
93
+ const fixedDiv = document.getElementById("parent-canvas");
94
+ /* c8 ignore start */
95
+ fixedDiv?.addEventListener("wheel", function (e: WheelEvent) {
77
96
  e.preventDefault();
78
- const evt = new WheelEvent('wheel', {
97
+ const evt = new WheelEvent("wheel", {
79
98
  deltaY: e.deltaY,
80
99
  });
81
100
  canvas.dispatchEvent(evt);
82
101
  });
83
102
  fixedDiv?.addEventListener(
84
- 'contextmenu',
103
+ "contextmenu",
85
104
  function (ev) {
86
105
  ev.preventDefault();
87
- const evt = new MouseEvent('contextmenu', {});
106
+ const evt = new MouseEvent("contextmenu", {});
88
107
  canvas.dispatchEvent(evt);
89
108
  },
90
- false,
109
+ false
91
110
  );
92
- })
111
+ /* c8 ignore stop */
112
+ });
93
113
  async function sendPayload(payload: string) {
94
114
  await executePayload(JSON.parse(payload));
95
115
  }
96
116
  function receiveMessageFromUnity(json: FrontEndPayload) {
97
- emit('on_payload', json.Interface, json.Action, json.Message);
98
- }
99
- function snap() {
117
+ emit("on_payload", json.Interface, json.Action, json.Message);
100
118
  }
101
- // function snapCanvas(canvas: HTMLCanvasElement) {
102
- // // this.$emit('screenshot', canvas);
103
- // }
104
-
105
- const unityInstance = ref<any>(null);
106
-
107
119
  </script>
@@ -0,0 +1,56 @@
1
+ import { expect, test, vi } from "vitest";
2
+ import WebGL3DR from "../WebGL3DR.vue";
3
+ import { registerOnPayloadHandler, createInstance } from "@3cr/sdk-browser";
4
+ import { mountVuetify } from "~/helper";
5
+ import { FileManagementActions, FrontEndInterfaces } from "@3cr/types-ts";
6
+
7
+ vi.mock("@3cr/sdk-browser", async (importOriginal) => {
8
+ const mod = (await importOriginal()) as object;
9
+ return {
10
+ ...mod,
11
+ registerVersion: vi.fn(),
12
+ createInstance: vi.fn(),
13
+ executePayload: vi.fn(),
14
+ registerOnPayloadHandler: vi.fn(),
15
+ };
16
+ });
17
+
18
+ const wrapper = mountVuetify(WebGL3DR);
19
+
20
+ test("registers payload handler", () => {
21
+ expect(registerOnPayloadHandler).toHaveBeenCalled();
22
+ });
23
+ test("creates instance", () => {
24
+ expect(createInstance).toHaveBeenCalled();
25
+ });
26
+ test("creates instance", () => {
27
+ wrapper.vm.receiveMessageFromUnity({
28
+ Action: FileManagementActions.fm01 as any,
29
+ Message: "testing message",
30
+ Interface: FrontEndInterfaces.file_management as any,
31
+ });
32
+
33
+ expect(wrapper.emitted()["on_payload"]).toStrictEqual([
34
+ ["file_management", "fm_01", "testing message"],
35
+ ]);
36
+ });
37
+
38
+ test("scrolling", () => {
39
+ const parentCanvas = wrapper.find("#parent-canvas");
40
+ parentCanvas.trigger("wheel");
41
+ });
42
+
43
+ test("mouseover", () => {
44
+ const parentCanvas = wrapper.find("#screenshotWindow");
45
+ parentCanvas.trigger("mouseover");
46
+
47
+ expect(wrapper.emitted()["hover"]).toStrictEqual([[true]]);
48
+ });
49
+
50
+ test("mouseout", () => {
51
+ const parentCanvas = wrapper.find("#screenshotWindow");
52
+ parentCanvas.trigger("mouseover");
53
+ parentCanvas.trigger("mouseout");
54
+
55
+ expect(wrapper.emitted()["hover"]).toStrictEqual([[true], [true], [false]]);
56
+ });
@@ -0,0 +1,21 @@
1
+ <template>
2
+ <svg
3
+ version="1.1"
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ x="0px"
6
+ y="0px"
7
+ viewBox="0 0 100 125"
8
+ >
9
+ <g>
10
+ <path
11
+ d="M58.355,24.95c0,0-1.507,2.912-1.83,7.202c-0.263,3.507,0.686,11.987,1.338,14.719
12
+ c0.776,3.244,2.289,4.015,5.194,4.081c2.904,0.064,9.256-3.611,10.933-4.511c1.539-0.824,9.579-5.862,18.858-15.958
13
+ c0.565-0.615,3.947-5.196,0.141-6.338c-2.401-0.721-28.486-2.227-31.397-2.028c-2.912,0.199-15.201-0.224-17.393-0.566
14
+ c-1.672-0.26-15.038-2.543-26.261,3.018C6.715,30.128,4.773,37.822,4.773,45.939c0,6.012,2.826,9.781,5.405,18.088
15
+ c2.386,7.685,4.956,13.356,5.994,15.462c0.351,0.71,2.582,2.7,4.718,1.69c2.137-1.009,15.874-17.219,20.704-20.546
16
+ c4.832-3.325,14.231-5.497,14.323-9.52c0.091-4.022-0.587-20.948-2.675-22.053c-2.088-1.105-0.901-3.289-0.451-3.445
17
+ C54.538,25.009,58.692,24.486,58.355,24.95z"
18
+ />
19
+ </g>
20
+ </svg>
21
+ </template>
@@ -0,0 +1,11 @@
1
+ import { expect, describe, it } from "vitest";
2
+ import { mountVuetify } from "~/helper";
3
+ import LoadingSpinner from "@/components/loading/LoadingSpinner.vue";
4
+
5
+ const wrapper = mountVuetify(LoadingSpinner);
6
+
7
+ describe("LoadingSpinner.vue", () => {
8
+ it("should inflate component", () => {
9
+ expect(wrapper).toBeTruthy();
10
+ });
11
+ });