@3cr/viewer-browser 0.0.53 → 0.0.57

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 (72) hide show
  1. package/__tests__/index.spec.ts +31 -0
  2. package/components.d.ts +3 -2
  3. package/coverage/3cr-viewer-browser/index.html +116 -0
  4. package/coverage/3cr-viewer-browser/index.ts.html +211 -0
  5. package/coverage/3cr-viewer-browser/src/App.vue.html +313 -0
  6. package/coverage/3cr-viewer-browser/src/components/WebGL3DR.vue.html +442 -0
  7. package/coverage/3cr-viewer-browser/src/components/icons/index.html +116 -0
  8. package/coverage/3cr-viewer-browser/src/components/icons/liver.vue.html +148 -0
  9. package/coverage/3cr-viewer-browser/src/components/index.html +116 -0
  10. package/coverage/3cr-viewer-browser/src/components/loading/LoadingSpinner.vue.html +556 -0
  11. package/coverage/3cr-viewer-browser/src/components/loading/index.html +116 -0
  12. package/coverage/3cr-viewer-browser/src/components/modal/MftpWebGL3DRModal.vue.html +4126 -0
  13. package/coverage/3cr-viewer-browser/src/components/modal/index.html +116 -0
  14. package/coverage/3cr-viewer-browser/src/components/selectors/ValueSelector.vue.html +331 -0
  15. package/coverage/3cr-viewer-browser/src/components/selectors/index.html +116 -0
  16. package/coverage/3cr-viewer-browser/src/components/sliders/DoubleSliderSelector.vue.html +445 -0
  17. package/coverage/3cr-viewer-browser/src/components/sliders/VerticalSliderSelector.vue.html +349 -0
  18. package/coverage/3cr-viewer-browser/src/components/sliders/index.html +131 -0
  19. package/coverage/3cr-viewer-browser/src/helpers/index.html +146 -0
  20. package/coverage/3cr-viewer-browser/src/helpers/layoutOverlayStyle.ts.html +406 -0
  21. package/coverage/3cr-viewer-browser/src/helpers/modelHelper.ts.html +412 -0
  22. package/coverage/3cr-viewer-browser/src/helpers/utils.ts.html +133 -0
  23. package/coverage/3cr-viewer-browser/src/index.html +131 -0
  24. package/coverage/3cr-viewer-browser/src/main.ts.html +124 -0
  25. package/coverage/3cr-viewer-browser/src/plugins/index.html +131 -0
  26. package/coverage/3cr-viewer-browser/src/plugins/index.ts.html +130 -0
  27. package/coverage/3cr-viewer-browser/src/plugins/vuetify.ts.html +220 -0
  28. package/coverage/base.css +224 -0
  29. package/coverage/block-navigation.js +87 -0
  30. package/coverage/favicon.png +0 -0
  31. package/coverage/index.html +251 -0
  32. package/coverage/prettify.css +1 -0
  33. package/coverage/prettify.js +2 -0
  34. package/coverage/sort-arrow-sprite.png +0 -0
  35. package/coverage/sorter.js +196 -0
  36. package/dist/Viewer3CR.js +17 -11
  37. package/dist/Viewer3CR.mjs +11911 -11157
  38. package/dist/Viewer3CR.umd.js +17 -11
  39. package/index.html +4 -1
  40. package/index.ts +46 -11
  41. package/package.json +9 -3
  42. package/src/App.vue +34 -45
  43. package/src/__tests__/app.spec.ts +27 -0
  44. package/src/components/WebGL3DR.vue +49 -37
  45. package/src/components/__tests__/webgl3dr.spec.ts +56 -0
  46. package/src/components/icons/liver.vue +21 -0
  47. package/src/components/loading/LoadingSpinner.vue +34 -12
  48. package/src/components/loading/__tests__/loading-spinner.spec.ts +11 -0
  49. package/src/components/modal/DemoModal.vue +44 -0
  50. package/src/components/modal/MftpWebGL3DRModal.vue +763 -410
  51. package/src/components/modal/__tests__/mftp-webgl-3dr-modal.spec.ts +690 -0
  52. package/src/components/selectors/__tests__/value-selector.spec.ts +35 -0
  53. package/src/components/sliders/DoubleSliderSelector.vue +30 -24
  54. package/src/components/sliders/VerticalSliderSelector.vue +25 -21
  55. package/src/components/sliders/__tests__/double-slider-selector.spec.ts +72 -0
  56. package/src/components/sliders/__tests__/vertical-slider-selector.spec.ts +61 -0
  57. package/src/helpers/__tests__/layout-overlay-style.spec.ts +288 -0
  58. package/src/helpers/__tests__/model-helper.spec.ts +118 -0
  59. package/src/helpers/__tests__/utils.spec.ts +70 -0
  60. package/src/helpers/layoutOverlayStyle.ts +50 -30
  61. package/src/plugins/__tests__/index.spec.ts +19 -0
  62. package/src/plugins/__tests__/vuetify.spec.ts +8 -0
  63. package/src/plugins/index.ts +6 -4
  64. package/src/plugins/vuetify.ts +25 -8
  65. package/test/helper.ts +35 -0
  66. package/test/setup.ts +1 -0
  67. package/tsconfig.json +5 -2
  68. package/vite.config.mts +1 -0
  69. package/vitest.config.mts +44 -0
  70. package/src/components/expansion-panels/ExpansionHeaderMiniMenu.vue +0 -19
  71. package/src/helpers/models.ts +0 -69
  72. /package/src/components/{sliders/SliderSelector.vue → selectors/ValueSelector.vue} +0 -0
@@ -0,0 +1,70 @@
1
+ import { describe, expect, it, vi, beforeEach, afterEach } from "vitest";
2
+ import { fn } from "@vitest/spy";
3
+ import { MockRunOnNewThread, registerEvents, toNumber } from "@/helpers/utils";
4
+
5
+ describe("MockRunOnNewThread", () => {
6
+ beforeEach(() => {
7
+ vi.useFakeTimers();
8
+ });
9
+
10
+ afterEach(() => {
11
+ vi.useRealTimers();
12
+ });
13
+
14
+ it("should MockRunOnNewThread", () => {
15
+ const callback = fn();
16
+
17
+ MockRunOnNewThread(callback);
18
+
19
+ expect(callback).not.toHaveBeenCalledOnce();
20
+
21
+ vi.advanceTimersByTime(1);
22
+ expect(callback).toHaveBeenCalledOnce();
23
+ });
24
+ });
25
+
26
+ describe("toNumber", () => {
27
+ it("should '1'", () => {
28
+ expect(toNumber("1")).toBe(1);
29
+ });
30
+
31
+ it("should '100'", () => {
32
+ expect(toNumber("100")).toBe(100);
33
+ });
34
+
35
+ it("should 1 ", () => {
36
+ expect(toNumber(1)).toBe(1);
37
+ });
38
+
39
+ it("should undefined ", () => {
40
+ expect(toNumber(undefined)).toBe(0);
41
+ });
42
+
43
+ it("should test ", () => {
44
+ expect(toNumber("test")).toBe(NaN);
45
+ });
46
+ });
47
+
48
+ describe("registerEvents", () => {
49
+ it("should registerEvents", () => {
50
+ const fakeEvents = ["drag", "drop"];
51
+ const fakeListener = () => {};
52
+ const fakeElement = {
53
+ addEventListener: fn(),
54
+ } as unknown as HTMLElement;
55
+
56
+ registerEvents(fakeElement, fakeEvents, fakeListener);
57
+
58
+ expect(fakeElement.addEventListener).toHaveBeenCalledTimes(2);
59
+ expect(fakeElement.addEventListener).toHaveBeenNthCalledWith(
60
+ 1,
61
+ fakeEvents[0],
62
+ fakeListener
63
+ );
64
+ expect(fakeElement.addEventListener).toHaveBeenNthCalledWith(
65
+ 2,
66
+ fakeEvents[1],
67
+ fakeListener
68
+ );
69
+ });
70
+ });
@@ -1,28 +1,28 @@
1
- import { AnchorPoint, PositionData } from '@3cr/types-ts';
1
+ import { AnchorPoint, PositionData } from "@3cr/types-ts";
2
2
 
3
- import { toNumber } from '@/helpers/utils';
3
+ import { toNumber } from "@/helpers/utils";
4
4
 
5
5
  export function generateDivStyleForLayout(layout: PositionData) {
6
- const padding = '0px';
7
- const canvas = document.getElementById('unity-canvas');
6
+ const padding = "0px";
7
+ const canvas = document.getElementById("unity-canvas");
8
8
 
9
9
  const props = {} as any;
10
10
 
11
11
  if (layout.Anchor === AnchorPoint.TOP) {
12
- props['left'] = '50%';
13
- props['transform'] = 'translateX(-50%)';
12
+ props["left"] = "50%";
13
+ props["transform"] = "translateX(-50%)";
14
14
  }
15
15
  if (layout.Anchor === AnchorPoint.BOTTOM) {
16
- props['left'] = '50%';
17
- props['transform'] = 'translateX(-50%)';
16
+ props["left"] = "50%";
17
+ props["transform"] = "translateX(-50%)";
18
18
  }
19
19
  if (layout.Anchor === AnchorPoint.LEFT) {
20
- props['top'] = '50%';
21
- props['transform'] = 'translateY(-50%)';
20
+ props["top"] = "50%";
21
+ props["transform"] = "translateY(-50%)";
22
22
  }
23
23
  if (layout.Anchor === AnchorPoint.RIGHT) {
24
- props['top'] = '50%';
25
- props['transform'] = 'translateY(-50%)';
24
+ props["top"] = "50%";
25
+ props["transform"] = "translateY(-50%)";
26
26
  }
27
27
  if (
28
28
  layout.Anchor === AnchorPoint.TOP_LEFT ||
@@ -30,7 +30,7 @@ export function generateDivStyleForLayout(layout: PositionData) {
30
30
  layout.Anchor === AnchorPoint.TOP_RIGHT ||
31
31
  layout.Anchor === AnchorPoint.CENTER
32
32
  ) {
33
- props['top'] = padding;
33
+ props["top"] = padding;
34
34
  }
35
35
  if (
36
36
  layout.Anchor === AnchorPoint.LEFT ||
@@ -38,48 +38,68 @@ export function generateDivStyleForLayout(layout: PositionData) {
38
38
  layout.Anchor === AnchorPoint.TOP_LEFT ||
39
39
  layout.Anchor === AnchorPoint.CENTER
40
40
  ) {
41
- props['left'] = padding;
41
+ props["left"] = padding;
42
42
  }
43
43
  if (
44
44
  layout.Anchor === AnchorPoint.RIGHT ||
45
45
  layout.Anchor === AnchorPoint.TOP_RIGHT ||
46
46
  layout.Anchor === AnchorPoint.BOTTOM_RIGHT
47
47
  ) {
48
- props['right'] = padding;
48
+ props["right"] = padding;
49
49
  }
50
50
  if (
51
51
  layout.Anchor === AnchorPoint.BOTTOM ||
52
52
  layout.Anchor === AnchorPoint.BOTTOM_LEFT ||
53
53
  layout.Anchor === AnchorPoint.BOTTOM_RIGHT
54
54
  ) {
55
- props['bottom'] = '4px';
55
+ props["bottom"] = "4px";
56
56
  }
57
- if (layout.Anchor === AnchorPoint.TOP_LEFT || layout.Anchor === AnchorPoint.CENTER) {
58
- props['border-top-left-radius'] = padding;
57
+ if (
58
+ layout.Anchor === AnchorPoint.TOP_LEFT ||
59
+ layout.Anchor === AnchorPoint.CENTER
60
+ ) {
61
+ props["border-top-left-radius"] = padding;
59
62
  }
60
- if (layout.Anchor === AnchorPoint.TOP_RIGHT || layout.Anchor === AnchorPoint.CENTER) {
61
- props['border-top-right-radius'] = padding;
63
+ if (
64
+ layout.Anchor === AnchorPoint.TOP_RIGHT ||
65
+ layout.Anchor === AnchorPoint.CENTER
66
+ ) {
67
+ props["border-top-right-radius"] = padding;
62
68
  }
63
- if (layout.Anchor === AnchorPoint.BOTTOM_LEFT || layout.Anchor === AnchorPoint.CENTER) {
64
- props['border-bottom-left-radius'] = padding;
69
+ if (
70
+ layout.Anchor === AnchorPoint.BOTTOM_LEFT ||
71
+ layout.Anchor === AnchorPoint.CENTER
72
+ ) {
73
+ props["border-bottom-left-radius"] = padding;
65
74
  }
66
- if (layout.Anchor === AnchorPoint.BOTTOM_RIGHT || layout.Anchor === AnchorPoint.CENTER) {
67
- props['border-bottom-right-radius'] = padding;
75
+ if (
76
+ layout.Anchor === AnchorPoint.BOTTOM_RIGHT ||
77
+ layout.Anchor === AnchorPoint.CENTER
78
+ ) {
79
+ props["border-bottom-right-radius"] = padding;
68
80
  }
69
81
 
70
- props['width'] = `calc(${layout.MaxSize.X * 100}% - ${padding})`;
71
- props['height'] = `calc(${layout.MaxSize.Y * 100}% - ${'2px'})`;
82
+ props["width"] = `calc(${layout.MaxSize.X * 100}% - ${padding})`;
83
+ props["height"] = `calc(${layout.MaxSize.Y * 100}% - ${"2px"})`;
72
84
  if (layout.Anchor === AnchorPoint.CENTER) {
73
- props['width'] = `calc(${layout.MaxSize.X * 100}% - ${padding} - ${padding})`;
74
- props['height'] = `calc(${layout.MaxSize.Y * 100}% - ${'2px'} - ${'2px'})`;
85
+ props["width"] = `calc(${
86
+ layout.MaxSize.X * 100
87
+ }% - ${padding} - ${padding})`;
88
+ props["height"] = `calc(${
89
+ layout.MaxSize.Y * 100
90
+ }% - ${"2px"} - ${"2px"})`;
75
91
  }
76
92
 
77
93
  if (layout.AspectRatio === 1) {
78
94
  if (layout.MaxSize.X === 1) {
79
- props['width'] = `calc(${layout.MaxSize.Y * toNumber(canvas?.offsetHeight)}px)`;
95
+ props["width"] = `calc(${
96
+ layout.MaxSize.Y * toNumber(canvas?.offsetHeight)
97
+ }px)`;
80
98
  }
81
99
  if (layout.MaxSize.Y === 1) {
82
- props['height'] = `calc(${layout.MaxSize.X * toNumber(canvas?.offsetWidth)}px)`;
100
+ props["height"] = `calc(${
101
+ layout.MaxSize.X * toNumber(canvas?.offsetWidth)
102
+ }px)`;
83
103
  }
84
104
  }
85
105
 
@@ -0,0 +1,19 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import vuetify from "@/plugins/vuetify";
3
+ import { fn } from "@vitest/spy";
4
+ import { registerPlugins } from "@/plugins";
5
+ import { App } from "vue";
6
+
7
+ describe("index.ts", () => {
8
+ it("should registerPlugins", () => {
9
+ const app = {
10
+ use: fn(),
11
+ } as unknown as App;
12
+
13
+ expect(app.use).not.toHaveBeenCalledWith(vuetify);
14
+
15
+ registerPlugins(app);
16
+
17
+ expect(app.use).toHaveBeenCalledWith(vuetify);
18
+ });
19
+ });
@@ -0,0 +1,8 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import vuetify from "@/plugins/vuetify";
3
+
4
+ describe("vuetify.ts", () => {
5
+ it("should vuetify base", () => {
6
+ expect(vuetify).toBeTruthy();
7
+ });
8
+ });
@@ -5,11 +5,13 @@
5
5
  */
6
6
 
7
7
  // Plugins
8
- import vuetify from './vuetify'
8
+ import vuetify from "./vuetify";
9
9
 
10
10
  // Types
11
- import type { App } from 'vue'
11
+ import type { App } from "vue";
12
+ import Notifications from "@kyvg/vue3-notification";
12
13
 
13
- export function registerPlugins (app: App) {
14
- app.use(vuetify)
14
+ export function registerPlugins(app: App) {
15
+ app.use(vuetify);
16
+ app.use(Notifications);
15
17
  }
@@ -5,24 +5,41 @@
5
5
  */
6
6
 
7
7
  // Styles
8
- import 'vuetify/styles'
8
+ import "vuetify/styles";
9
9
 
10
10
  // Composables
11
- import { createVuetify } from 'vuetify'
12
- import { aliases, md } from 'vuetify/iconsets/md'
13
- import { mdi } from 'vuetify/iconsets/mdi'
11
+ import { createVuetify, IconProps } from "vuetify";
12
+ import { aliases, md } from "vuetify/iconsets/md";
13
+ import { mdi } from "vuetify/iconsets/mdi";
14
+ import { fa } from "vuetify/iconsets/fa";
15
+ import { h } from "vue";
16
+ import liver from "@/components/icons/liver.vue";
17
+
18
+ const customComponents: any = {
19
+ liver,
20
+ };
14
21
 
15
22
  // https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
23
+ /* istanbul ignore next -- @preserve */
16
24
  export default createVuetify({
17
25
  theme: {
18
- defaultTheme: 'light',
26
+ defaultTheme: "light",
19
27
  },
20
28
  icons: {
21
- defaultSet: 'md',
29
+ defaultSet: "md",
22
30
  aliases,
23
31
  sets: {
24
32
  md,
25
- mdi
33
+ mdi,
34
+ fa,
35
+ custom: {
36
+ /* c8 ignore start */
37
+ component: (props: IconProps) =>
38
+ h(props.tag, [
39
+ h(customComponents[props.icon as string], { class: "v-icon__svg" }),
40
+ ]),
41
+ /* c8 ignore stop */
42
+ },
26
43
  },
27
44
  },
28
- })
45
+ });
package/test/helper.ts ADDED
@@ -0,0 +1,35 @@
1
+ import { mount, shallowMount } from "@vue/test-utils";
2
+ import { createVuetify } from "vuetify";
3
+ import { expect } from "vitest";
4
+
5
+ export function mountVuetify<T>(
6
+ component: T,
7
+ props: any = {},
8
+ stubs: any = {}
9
+ ) {
10
+ const vuetify = createVuetify({});
11
+ return mount(component, {
12
+ props,
13
+ global: {
14
+ plugins: [vuetify],
15
+ stubs,
16
+ },
17
+ });
18
+ }
19
+ export function shallowMountVuetify<T>(component: T, props: any = {}) {
20
+ const vuetify = createVuetify({});
21
+ return shallowMount(component, {
22
+ props,
23
+ global: {
24
+ plugins: [vuetify],
25
+ },
26
+ });
27
+ }
28
+
29
+ export function checkComponentProps(
30
+ component: any,
31
+ propKey: string,
32
+ equal: any
33
+ ) {
34
+ expect(component.props()[propKey] as any).toBe(equal);
35
+ }
package/test/setup.ts ADDED
@@ -0,0 +1 @@
1
+ global.ResizeObserver = require("resize-observer-polyfill");
package/tsconfig.json CHANGED
@@ -12,7 +12,8 @@
12
12
  "module": "ESNext",
13
13
  "moduleResolution": "node",
14
14
  "paths": {
15
- "@/*": ["src/*"]
15
+ "@/*": ["src/*"],
16
+ "~/*": ["test/*"]
16
17
  },
17
18
  "resolveJsonModule": true,
18
19
 
@@ -27,7 +28,9 @@
27
28
  },
28
29
  "include": [
29
30
  "./src/typed-router.d.ts",
30
- "**/*.vue"
31
+ "**/*.ts",
32
+ "**/*.spec.ts",
33
+ "**/*.vue",
31
34
  ],
32
35
  "exclude": ["dist", "node_modules", "cypress"],
33
36
  "references": [{ "path": "./tsconfig.node.json" }]
package/vite.config.mts CHANGED
@@ -68,6 +68,7 @@ if (globalThis.Viewer3CR) {
68
68
  resolve: {
69
69
  alias: {
70
70
  '@': fileURLToPath(new URL('./src', import.meta.url)),
71
+ '~': fileURLToPath(new URL('./test', import.meta.url)),
71
72
  },
72
73
  extensions: [
73
74
  '.js',
@@ -0,0 +1,44 @@
1
+ /// <reference types="vitest" />
2
+ // vitest.config.ts
3
+ import {defineConfig, mergeConfig} from 'vite'
4
+ import viteConfig from "./vite.config.mjs";
5
+
6
+ export default mergeConfig(viteConfig, defineConfig({
7
+ test: {
8
+ globals: true,
9
+ environment: 'jsdom',
10
+ server: {
11
+ deps: {
12
+ inline: ['vuetify'],
13
+ },
14
+ },
15
+ exclude: ['node_modules/**'],
16
+ include: ['**/*.spec.ts'],
17
+ setupFiles: ['/test/setup.ts'],
18
+ coverage: {
19
+ provider: 'v8', // or 'v8',
20
+ enabled: true,
21
+ reporter: ['html'],
22
+ include: ['src/**/*', 'index.ts'],
23
+ exclude: [
24
+ 'coverage/**',
25
+ 'dist/**',
26
+ 'scripts/**',
27
+ '**/[.]**',
28
+ 'packages/*/test?(s)/**',
29
+ '**/*.d.ts',
30
+ '**/virtual:*',
31
+ '**/__x00__*',
32
+ '**/\x00*',
33
+ 'cypress/**',
34
+ 'test?(s)/**',
35
+ 'test?(-*).?(c|m)[jt]s?(x)',
36
+ '**/*{.,-}{test,spec}.?(c|m)[jt]s?(x)',
37
+ '**/__tests__/**',
38
+ '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*',
39
+ '**/vitest.{workspace,projects}.[jt]s?(on)',
40
+ '**/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}',
41
+ ],
42
+ },
43
+ },
44
+ }))
@@ -1,19 +0,0 @@
1
- <template>
2
- <v-expansion-panel-title class="font-weight-bold transparent">
3
- <span
4
- ><v-icon small>{{ props.miniMenu.icon }}</v-icon
5
- >&nbsp;&nbsp;{{ props.miniMenu.text }}</span
6
- >
7
- <v-spacer />
8
- </v-expansion-panel-title>
9
- </template>
10
- <script setup lang="ts">
11
-
12
- export interface Props {
13
- miniMenu: { icon: string; text: string };
14
- }
15
-
16
- const props = withDefaults(defineProps<Props>(), {
17
- miniMenu: () => ({ icon: '', text: '' }),
18
- });
19
- </script>
@@ -1,69 +0,0 @@
1
- export interface FrontEndPayload {
2
- Interface: FrontEndInterfaces;
3
- Action: FrontEndInterfaces;
4
- Message: string;
5
- }
6
- export enum FrontEndInterfaces {
7
- scan_loading = 'scan_loading',
8
- file_management = 'file_management',
9
- view_selection = 'view_selection',
10
- layout = 'layout',
11
- presets = 'presets',
12
- sliders = 'sliders',
13
- scan_orientation = 'scan_orientation',
14
- scan_movement = 'scan_movement',
15
- interactivity = 'interactivity',
16
- }
17
- export enum FrontEndActions {
18
- pong = 'pong',
19
- announcement = 'announcement',
20
- fm02 = 'fm_02',
21
- }
22
- export enum FileManagementActions {
23
- fm01 = 'fm_01',
24
- fm02 = 'fm_02',
25
- }
26
- export enum NotificationActions {
27
- no01 = 'no_01',
28
- no02 = 'no_02',
29
- no03 = 'no_03',
30
- }
31
- export enum ScanOrientationActions {
32
- so01 = 'so_01',
33
- }
34
- export enum PresetActions {
35
- pr01 = 'pr_01',
36
- pr02 = 'pr_02',
37
- }
38
- export enum ScanMovementActions {
39
- sm01 = 'sm_01',
40
- sm02 = 'sm_02',
41
- sm03 = 'sm_03',
42
- sm04 = 'sm_04',
43
- sm05 = 'sm_05',
44
- sm06 = 'sm_06',
45
- sm07 = 'sm_07',
46
- sm08 = 'sm_08',
47
- sm09 = 'sm_09',
48
- sm10 = 'sm_10',
49
- sm11 = 'sm_11',
50
- sm12 = 'sm_12',
51
- }
52
- export enum SliderActions {
53
- sl01 = 'sl_01',
54
- sl02 = 'sl_02',
55
- sl03 = 'sl_03',
56
- sl04 = 'sl_04',
57
- sl05 = 'sl_05',
58
- sl06 = 'sl_06',
59
- sl07 = 'sl_07',
60
- sl08 = 'sl_08',
61
- sl09 = 'sl_09',
62
- sl10 = 'sl_10',
63
- sl11 = 'sl_11',
64
- sl12 = 'sl_12',
65
- sl13 = 'sl_13',
66
- sl14 = 'sl_14',
67
- sl15 = 'sl_15',
68
- sl16 = 'sl_16',
69
- }