@uavs/3d-model-map 0.1.0

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 (89) hide show
  1. package/README.md +392 -0
  2. package/dist/index.js +2116 -0
  3. package/dist/runtime/mars3dCesiumShim.js +34 -0
  4. package/dist/style.css +1 -0
  5. package/dist/types/api/index.d.ts +49 -0
  6. package/dist/types/api/index.d.ts.map +1 -0
  7. package/dist/types/api/mapApiContext.d.ts +5 -0
  8. package/dist/types/api/mapApiContext.d.ts.map +1 -0
  9. package/dist/types/components/RealModelClarityDialog.vue.d.ts +28 -0
  10. package/dist/types/components/RealModelClarityDialog.vue.d.ts.map +1 -0
  11. package/dist/types/components/ThreeDimensionalMap.vue.d.ts +33 -0
  12. package/dist/types/components/ThreeDimensionalMap.vue.d.ts.map +1 -0
  13. package/dist/types/config/map3dConfig.d.ts +33 -0
  14. package/dist/types/config/map3dConfig.d.ts.map +1 -0
  15. package/dist/types/index.d.ts +22 -0
  16. package/dist/types/index.d.ts.map +1 -0
  17. package/dist/types/models/mapMapdataTileOrigin.d.ts +4 -0
  18. package/dist/types/models/mapMapdataTileOrigin.d.ts.map +1 -0
  19. package/dist/types/models/materialModels.d.ts +18 -0
  20. package/dist/types/models/materialModels.d.ts.map +1 -0
  21. package/dist/types/models/materialTilesetOptions.d.ts +26 -0
  22. package/dist/types/models/materialTilesetOptions.d.ts.map +1 -0
  23. package/dist/types/models/useAutoRealModel.d.ts +116 -0
  24. package/dist/types/models/useAutoRealModel.d.ts.map +1 -0
  25. package/dist/types/models/useMaterialModelLabels.d.ts +13 -0
  26. package/dist/types/models/useMaterialModelLabels.d.ts.map +1 -0
  27. package/dist/types/models/useMaterialModelLayers.d.ts +27 -0
  28. package/dist/types/models/useMaterialModelLayers.d.ts.map +1 -0
  29. package/dist/types/pages/ThreeDimensionalMapPage.vue.d.ts +3 -0
  30. package/dist/types/pages/ThreeDimensionalMapPage.vue.d.ts.map +1 -0
  31. package/dist/types/runtime/cesiumRuntime.d.ts +3 -0
  32. package/dist/types/runtime/cesiumRuntime.d.ts.map +1 -0
  33. package/dist/types/runtime/hunanJiangxiMapRuntime.d.ts +13 -0
  34. package/dist/types/runtime/hunanJiangxiMapRuntime.d.ts.map +1 -0
  35. package/dist/types/runtime/mapLifecycle.d.ts +12 -0
  36. package/dist/types/runtime/mapLifecycle.d.ts.map +1 -0
  37. package/dist/types/runtime/mars3dCesiumShim.d.ts +4 -0
  38. package/dist/types/runtime/mars3dCesiumShim.d.ts.map +1 -0
  39. package/dist/types/runtime/mars3dRuntime.d.ts +6 -0
  40. package/dist/types/runtime/mars3dRuntime.d.ts.map +1 -0
  41. package/dist/types/vite/cesium.d.ts +16 -0
  42. package/dist/types/vite/cesium.d.ts.map +1 -0
  43. package/dist/vite/cesium.js +159 -0
  44. package/package.json +74 -0
  45. package/public/img/basemaps/TerrainEllipsoid.png +0 -0
  46. package/public/img/basemaps/TerrainSTK.png +0 -0
  47. package/public/img/basemaps/arcgis.png +0 -0
  48. package/public/img/basemaps/bd-c-bluish.png +0 -0
  49. package/public/img/basemaps/bd-c-dark.png +0 -0
  50. package/public/img/basemaps/bd-c-darkgreen.png +0 -0
  51. package/public/img/basemaps/bd-c-googlelite.png +0 -0
  52. package/public/img/basemaps/bd-c-grassgreen.png +0 -0
  53. package/public/img/basemaps/bd-c-grayscale.png +0 -0
  54. package/public/img/basemaps/bd-c-hardedge.png +0 -0
  55. package/public/img/basemaps/bd-c-light.png +0 -0
  56. package/public/img/basemaps/bd-c-midnight.png +0 -0
  57. package/public/img/basemaps/bd-c-pink.png +0 -0
  58. package/public/img/basemaps/bd-c-redalert.png +0 -0
  59. package/public/img/basemaps/bd-img.png +0 -0
  60. package/public/img/basemaps/bd-vec.png +0 -0
  61. package/public/img/basemaps/bingAerial.png +0 -0
  62. package/public/img/basemaps/bingAerialLabels.png +0 -0
  63. package/public/img/basemaps/bingRoads.png +0 -0
  64. package/public/img/basemaps/bingimage.png +0 -0
  65. package/public/img/basemaps/bingmap.png +0 -0
  66. package/public/img/basemaps/blackMarble.png +0 -0
  67. package/public/img/basemaps/esriNationalGeographic.png +0 -0
  68. package/public/img/basemaps/esriWorldImagery.png +0 -0
  69. package/public/img/basemaps/esriWorldStreetMap.png +0 -0
  70. package/public/img/basemaps/gaode_img.png +0 -0
  71. package/public/img/basemaps/gaode_vec.png +0 -0
  72. package/public/img/basemaps/google_img.png +0 -0
  73. package/public/img/basemaps/google_ter.png +0 -0
  74. package/public/img/basemaps/google_vec.png +0 -0
  75. package/public/img/basemaps/mapQuestOpenStreetMap.png +0 -0
  76. package/public/img/basemaps/mapboxSatellite.png +0 -0
  77. package/public/img/basemaps/mapboxStreets.png +0 -0
  78. package/public/img/basemaps/mapboxTerrain.png +0 -0
  79. package/public/img/basemaps/naturalEarthII.png +0 -0
  80. package/public/img/basemaps/offline.png +0 -0
  81. package/public/img/basemaps/osm.png +0 -0
  82. package/public/img/basemaps/sea.png +0 -0
  83. package/public/img/basemaps/stamenToner.png +0 -0
  84. package/public/img/basemaps/stamenWatercolor.png +0 -0
  85. package/public/img/basemaps/tdt_img.png +0 -0
  86. package/public/img/basemaps/tdt_ter.png +0 -0
  87. package/public/img/basemaps/tdt_vec.png +0 -0
  88. package/public/img/basemaps/tencent_img.png +0 -0
  89. package/public/img/basemaps/tencent_vec.png +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThreeDimensionalMapPage.vue.d.ts","sourceRoot":"","sources":["../../../src/pages/ThreeDimensionalMapPage.vue"],"names":[],"mappings":";AA8CA,wBAKG"}
@@ -0,0 +1,3 @@
1
+ export declare function ensureCesiumLoaded(): Promise<void>;
2
+ export declare function getCesium(): any;
3
+ //# sourceMappingURL=cesiumRuntime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cesiumRuntime.d.ts","sourceRoot":"","sources":["../../../src/runtime/cesiumRuntime.ts"],"names":[],"mappings":"AA0CA,wBAAgB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAQlD;AAED,wBAAgB,SAAS,IAAI,GAAG,CAE/B"}
@@ -0,0 +1,13 @@
1
+ import type { Map } from 'mars3d';
2
+ export declare const HUNAN_JIANGXI_UNION_GLOBE_DEGREES: {
3
+ readonly west: number;
4
+ readonly south: number;
5
+ readonly east: number;
6
+ readonly north: number;
7
+ };
8
+ export declare const IS_MAP_LIMIT_TO_HUNAN_JIANGXI: boolean;
9
+ export declare const HUNAN_JIANGXI_GLOBE_BASE_CSS = "#020202";
10
+ export declare function applyHunanJiangxiBasemapVisibility(map3d: any): void;
11
+ export declare function applyHunanJiangxiSceneOptionsBeforeMapCreated(map3d: any): void;
12
+ export declare function applyHunanJiangxiGlobeClipAfterMapCreated(map: Map): boolean;
13
+ //# sourceMappingURL=hunanJiangxiMapRuntime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hunanJiangxiMapRuntime.d.ts","sourceRoot":"","sources":["../../../src/runtime/hunanJiangxiMapRuntime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAA;AAMjC,eAAO,MAAM,iCAAiC;;;;;CAKpC,CAAA;AAEV,eAAO,MAAM,6BAA6B,SAA6D,CAAA;AACvG,eAAO,MAAM,4BAA4B,YAAY,CAAA;AAKrD,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI,CAsBnE;AAED,wBAAgB,6CAA6C,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI,CAS9E;AAED,wBAAgB,yCAAyC,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAY3E"}
@@ -0,0 +1,12 @@
1
+ export type Mars3dMapInstance = {
2
+ viewer?: {
3
+ useDefaultRenderLoop?: boolean;
4
+ resize?: () => void;
5
+ scene?: {
6
+ requestRender?: () => void;
7
+ };
8
+ };
9
+ };
10
+ export declare function suspendMars3dMap(map: Mars3dMapInstance | null | undefined): void;
11
+ export declare function resumeMars3dMap(map: Mars3dMapInstance | null | undefined): void;
12
+ //# sourceMappingURL=mapLifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapLifecycle.d.ts","sourceRoot":"","sources":["../../../src/runtime/mapLifecycle.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,CAAC,EAAE;QACP,oBAAoB,CAAC,EAAE,OAAO,CAAA;QAC9B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;QACnB,KAAK,CAAC,EAAE;YACN,aAAa,CAAC,EAAE,MAAM,IAAI,CAAA;SAC3B,CAAA;KACF,CAAA;CACF,CAAA;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAIhF;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAM/E"}
@@ -0,0 +1,4 @@
1
+ declare const cesiumProxy: typeof import("mars3d-cesium");
2
+ export default cesiumProxy;
3
+ export declare const Cesium: typeof import("mars3d-cesium");
4
+ //# sourceMappingURL=mars3dCesiumShim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mars3dCesiumShim.d.ts","sourceRoot":"","sources":["../../../src/runtime/mars3dCesiumShim.ts"],"names":[],"mappings":"AAeA,QAAA,MAAM,WAAW,gCAkBf,CAAA;AAEF,eAAe,WAAW,CAAA;AAC1B,eAAO,MAAM,MAAM,gCAAc,CAAA"}
@@ -0,0 +1,6 @@
1
+ export declare function getMars3d(): Promise<typeof import('mars3d')>;
2
+ export declare function ensureMars3dModule(): Promise<{
3
+ mars3d: typeof import("mars3d");
4
+ Cesium: typeof import("mars3d-cesium");
5
+ }>;
6
+ //# sourceMappingURL=mars3dRuntime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mars3dRuntime.d.ts","sourceRoot":"","sources":["../../../src/runtime/mars3dRuntime.ts"],"names":[],"mappings":"AAqBA,wBAAsB,SAAS,IAAI,OAAO,CAAC,cAAc,QAAQ,CAAC,CAAC,CAuBlE;AAED,wBAAsB,kBAAkB;;;GAGvC"}
@@ -0,0 +1,16 @@
1
+ import { type Plugin } from 'vite';
2
+ export declare function createCesiumStaticPlugins(cesiumSource: string): Plugin[];
3
+ export declare function resolveMapdataProxyTarget(env: Record<string, string | undefined>): string | undefined;
4
+ export declare function createMapdataProxy(env: Record<string, string | undefined>): {
5
+ '/mapdata-map'?: {
6
+ target: string;
7
+ changeOrigin: boolean;
8
+ secure: boolean;
9
+ } | undefined;
10
+ '/mapdata'?: {
11
+ target: string;
12
+ changeOrigin: boolean;
13
+ secure: boolean;
14
+ } | undefined;
15
+ };
16
+ //# sourceMappingURL=cesium.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cesium.d.ts","sourceRoot":"","sources":["../../../vite/cesium.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,MAAM,CAAA;AAmGjD,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAsBxE;AA6BD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAErG;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;;;;;;;;;;;EAuBzE"}
@@ -0,0 +1,159 @@
1
+ import { createReadStream, existsSync, statSync } from 'node:fs';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { extname, join, normalize, relative } from 'node:path';
4
+ import { normalizePath } from 'vite';
5
+ import { viteStaticCopy } from 'vite-plugin-static-copy';
6
+ const cesiumPublicPrefix = '/lib/Cesium/';
7
+ const mapPublicRootCandidates = [
8
+ fileURLToPath(new URL('../public', import.meta.url)),
9
+ fileURLToPath(new URL('../../public', import.meta.url))
10
+ ];
11
+ const mapPublicRoot = mapPublicRootCandidates.find((candidate) => existsSync(candidate)) ?? mapPublicRootCandidates[0];
12
+ const normalizedMapPublicRoot = normalizePath(mapPublicRoot);
13
+ const mimeTypes = {
14
+ '.css': 'text/css; charset=utf-8',
15
+ '.js': 'application/javascript; charset=utf-8',
16
+ '.json': 'application/json; charset=utf-8',
17
+ '.wasm': 'application/wasm',
18
+ '.png': 'image/png',
19
+ '.jpg': 'image/jpeg',
20
+ '.jpeg': 'image/jpeg',
21
+ '.gif': 'image/gif',
22
+ '.svg': 'image/svg+xml',
23
+ '.woff': 'font/woff',
24
+ '.woff2': 'font/woff2',
25
+ '.ttf': 'font/ttf'
26
+ };
27
+ function isInsideDir(root, file) {
28
+ const rel = relative(root, file);
29
+ return !!rel && !rel.startsWith('..') && !rel.startsWith('/') && !/^[A-Za-z]:/.test(rel);
30
+ }
31
+ function createCesiumDevServerPlugin(cesiumSource) {
32
+ return {
33
+ name: 'uavs-serve-cesium',
34
+ configureServer(server) {
35
+ server.middlewares.use((req, res, next) => {
36
+ const requestUrl = req.url?.split('?')[0] || '';
37
+ if (!requestUrl.startsWith(cesiumPublicPrefix)) {
38
+ next();
39
+ return;
40
+ }
41
+ const requestPath = decodeURIComponent(requestUrl.slice(cesiumPublicPrefix.length));
42
+ const filePath = normalize(join(cesiumSource, requestPath));
43
+ if (!isInsideDir(cesiumSource, filePath) || !existsSync(filePath)) {
44
+ next();
45
+ return;
46
+ }
47
+ const stat = statSync(filePath);
48
+ if (!stat.isFile()) {
49
+ next();
50
+ return;
51
+ }
52
+ res.statusCode = 200;
53
+ res.setHeader('Content-Type', mimeTypes[extname(filePath).toLowerCase()] || 'application/octet-stream');
54
+ res.setHeader('Content-Length', String(stat.size));
55
+ createReadStream(filePath).pipe(res);
56
+ });
57
+ }
58
+ };
59
+ }
60
+ function createMapPublicAssetsDevServerPlugin(publicRoot) {
61
+ return {
62
+ name: 'uavs-serve-map-public-assets',
63
+ configureServer(server) {
64
+ server.middlewares.use((req, res, next) => {
65
+ const requestUrl = req.url?.split('?')[0] || '';
66
+ if (!requestUrl.startsWith('/img/')) {
67
+ next();
68
+ return;
69
+ }
70
+ const requestPath = decodeURIComponent(requestUrl.slice(1));
71
+ const filePath = normalize(join(publicRoot, requestPath));
72
+ if (!isInsideDir(publicRoot, filePath) || !existsSync(filePath)) {
73
+ next();
74
+ return;
75
+ }
76
+ const stat = statSync(filePath);
77
+ if (!stat.isFile()) {
78
+ next();
79
+ return;
80
+ }
81
+ res.statusCode = 200;
82
+ res.setHeader('Content-Type', mimeTypes[extname(filePath).toLowerCase()] || 'application/octet-stream');
83
+ res.setHeader('Content-Length', String(stat.size));
84
+ createReadStream(filePath).pipe(res);
85
+ });
86
+ }
87
+ };
88
+ }
89
+ export function createCesiumStaticPlugins(cesiumSource) {
90
+ if (!existsSync(join(cesiumSource, 'Cesium.js'))) {
91
+ throw new Error(`Cesium static assets not found. Run pnpm install and check: ${cesiumSource}`);
92
+ }
93
+ const staticCopyPlugins = viteStaticCopy({
94
+ targets: [
95
+ { src: `${cesiumSource}/ThirdParty`, dest: 'lib/Cesium' },
96
+ { src: `${cesiumSource}/Workers`, dest: 'lib/Cesium' },
97
+ { src: `${cesiumSource}/Assets`, dest: 'lib/Cesium' },
98
+ { src: `${cesiumSource}/Widgets`, dest: 'lib/Cesium' },
99
+ { src: `${cesiumSource}/Cesium.js`, dest: 'lib/Cesium' },
100
+ { src: `${normalizedMapPublicRoot}/img/basemaps/*`, dest: 'img/basemaps' }
101
+ ],
102
+ silent: true
103
+ });
104
+ return [
105
+ createCesiumDevServerPlugin(cesiumSource),
106
+ createMapPublicAssetsDevServerPlugin(mapPublicRoot),
107
+ ...(Array.isArray(staticCopyPlugins) ? staticCopyPlugins : [staticCopyPlugins])
108
+ ];
109
+ }
110
+ function resolveBaseOriginProxyTarget(env) {
111
+ const baseUrl = env.VITE_BASE_URL?.trim().replace(/^['"]|['"]$/g, '');
112
+ if (baseUrl && /^https?:\/\//i.test(baseUrl)) {
113
+ try {
114
+ return new URL(baseUrl).origin;
115
+ }
116
+ catch {
117
+ return undefined;
118
+ }
119
+ }
120
+ const baseHost = env.VITE_BASE_HOST?.trim().replace(/^['"]|['"]$/g, '');
121
+ if (baseHost) {
122
+ return /^https?:\/\//i.test(baseHost) ? baseHost.replace(/\/$/, '') : `https://${baseHost}`.replace(/\/$/, '');
123
+ }
124
+ return undefined;
125
+ }
126
+ function resolveMapHostProxyTarget(env) {
127
+ const mapHost = env.VITE_MAP_HOST?.trim().replace(/^['"]|['"]$/g, '');
128
+ if (mapHost) {
129
+ return /^https?:\/\//i.test(mapHost) ? mapHost.replace(/\/$/, '') : `http://${mapHost}`.replace(/\/$/, '');
130
+ }
131
+ return resolveBaseOriginProxyTarget(env);
132
+ }
133
+ export function resolveMapdataProxyTarget(env) {
134
+ return resolveBaseOriginProxyTarget(env) || resolveMapHostProxyTarget(env);
135
+ }
136
+ export function createMapdataProxy(env) {
137
+ const mapdataTarget = resolveMapdataProxyTarget(env);
138
+ const mapdataMapTarget = resolveMapHostProxyTarget(env);
139
+ return {
140
+ ...(mapdataTarget
141
+ ? {
142
+ '/mapdata': {
143
+ target: mapdataTarget,
144
+ changeOrigin: true,
145
+ secure: false
146
+ }
147
+ }
148
+ : {}),
149
+ ...(mapdataMapTarget
150
+ ? {
151
+ '/mapdata-map': {
152
+ target: mapdataMapTarget,
153
+ changeOrigin: true,
154
+ secure: false
155
+ }
156
+ }
157
+ : {})
158
+ };
159
+ }
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "@uavs/3d-model-map",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "description": "UAVS 3D map components based on Vue 3, Mars3D and Cesium.",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://gitee.com/jxzhsz/packages.git",
10
+ "directory": "packages/3d-model-map"
11
+ },
12
+ "homepage": "https://gitee.com/jxzhsz/packages/tree/master/packages/3d-model-map",
13
+ "bugs": {
14
+ "url": "https://gitee.com/jxzhsz/packages/issues"
15
+ },
16
+ "main": "./dist/index.js",
17
+ "module": "./dist/index.js",
18
+ "types": "./dist/types/index.d.ts",
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/types/index.d.ts",
22
+ "import": "./dist/index.js"
23
+ },
24
+ "./vite/cesium": {
25
+ "types": "./dist/types/vite/cesium.d.ts",
26
+ "import": "./dist/vite/cesium.js"
27
+ },
28
+ "./runtime/mars3d-cesium-shim": {
29
+ "types": "./dist/types/runtime/mars3dCesiumShim.d.ts",
30
+ "import": "./dist/runtime/mars3dCesiumShim.js"
31
+ },
32
+ "./style.css": "./dist/style.css"
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "public",
37
+ "README.md"
38
+ ],
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "dependencies": {
43
+ "vite-plugin-static-copy": "2.3.2"
44
+ },
45
+ "peerDependencies": {
46
+ "@turf/turf": "^7.3.5",
47
+ "mars3d": "3.11.2",
48
+ "mars3d-cesium": "1.140.0",
49
+ "vite": "^6.3.5",
50
+ "vue": "^3.5.16"
51
+ },
52
+ "peerDependenciesMeta": {
53
+ "vite": {
54
+ "optional": true
55
+ }
56
+ },
57
+ "devDependencies": {
58
+ "@types/node": "^22.10.2",
59
+ "@vitejs/plugin-vue": "^5.2.4",
60
+ "@turf/turf": "^7.3.5",
61
+ "mars3d": "3.11.2",
62
+ "mars3d-cesium": "1.140.0",
63
+ "typescript": "^5.8.3",
64
+ "vite": "^6.3.5",
65
+ "vue": "^3.5.16",
66
+ "vue-tsc": "^2.2.10"
67
+ },
68
+ "scripts": {
69
+ "build": "vue-tsc -p tsconfig.json --noEmit && vite build && vue-tsc -p tsconfig.build.json && tsc -p tsconfig.vite.json && tsc -p tsconfig.runtime.json",
70
+ "typecheck": "vue-tsc -p tsconfig.json --noEmit",
71
+ "pack:check": "pnpm build && npm pack --dry-run",
72
+ "lint": "eslint src --ext .ts,.vue"
73
+ }
74
+ }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file