@realsee/dnalogel 4.0.0-webgpu.3 → 4.0.0-webgpu.4
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.
- package/CHANGELOG.md +6 -0
- package/dist/floorplan.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +270 -35
- package/dist/index.js.map +1 -0
- package/dist/internal/{BasePlugin-CT5K8m36.js → BasePlugin-DC5m72La.js} +3 -3
- package/dist/internal/{BasePlugin-CT5K8m36.js.map → BasePlugin-DC5m72La.js.map} +1 -1
- package/dist/internal/BasePluginWithData-D_0W46_q.js +7 -0
- package/dist/internal/{BasePluginWithData-9z4tpAT4.js.map → BasePluginWithData-D_0W46_q.js.map} +1 -1
- package/dist/internal/{BetterTween-BX0aTvP1.js → BetterTween-DmptqE8m.js} +2 -2
- package/dist/internal/{BetterTween-BX0aTvP1.js.map → BetterTween-DmptqE8m.js.map} +1 -1
- package/dist/internal/{CSS3DRenderPlugin-ccSpcvwd.js → CSS3DRenderPlugin-CEatgl0m.js} +3 -3
- package/dist/internal/CSS3DRenderPlugin-CEatgl0m.js.map +1 -0
- package/dist/internal/{Controller-Csut_kcH.js → Controller-D6o4OGWJ.js} +8 -8
- package/dist/internal/{Controller-Csut_kcH.js.map → Controller-D6o4OGWJ.js.map} +1 -1
- package/dist/internal/{FiveDomEvents-3H9NvDOz.js → FiveDomEvents-BUBLFzti.js} +2 -2
- package/dist/internal/{FiveDomEvents-3H9NvDOz.js.map → FiveDomEvents-BUBLFzti.js.map} +1 -1
- package/dist/internal/FivePuppet-C6QmVY70.js +67 -0
- package/dist/internal/FivePuppet-C6QmVY70.js.map +1 -0
- package/dist/internal/{PointHelper-D565h9b_.js → PointHelper-DIhgdjY2.js} +48 -48
- package/dist/internal/{PointHelper-D565h9b_.js.map → PointHelper-DIhgdjY2.js.map} +1 -1
- package/dist/internal/{Polygon-CBGvYUfJ.js → Polygon-D3xIL1Pl.js} +30 -30
- package/dist/internal/{Polygon-CBGvYUfJ.js.map → Polygon-D3xIL1Pl.js.map} +1 -1
- package/dist/internal/{Prism-Dm5ESkgg.js → Prism-CJlyAEAU.js} +13 -13
- package/dist/internal/{Prism-Dm5ESkgg.js.map → Prism-CJlyAEAU.js.map} +1 -1
- package/dist/internal/{Rectangle-D-zkDycu.js → Rectangle-BpL9lNKU.js} +118 -129
- package/dist/internal/Rectangle-BpL9lNKU.js.map +1 -0
- package/dist/internal/{Work-DF8j5GnL.js → Work-BE4AgdwH.js} +9 -9
- package/dist/internal/{Work-DF8j5GnL.js.map → Work-BE4AgdwH.js.map} +1 -1
- package/dist/internal/{animationFrame-XGKHIeQK.js → animationFrame-CacKXN8l.js} +14 -3
- package/dist/internal/animationFrame-CacKXN8l.js.map +1 -0
- package/dist/internal/{area-maker-Bd9l2pIp.js → area-maker-Bnhx4SkH.js} +4 -4
- package/dist/internal/{area-maker-Bd9l2pIp.js.map → area-maker-Bnhx4SkH.js.map} +1 -1
- package/dist/internal/{boundingBox-DvCor5Hd.js → boundingBox-CIqXgNXW.js} +2 -2
- package/dist/internal/{boundingBox-DvCor5Hd.js.map → boundingBox-CIqXgNXW.js.map} +1 -1
- package/dist/internal/{camera-movement-CwI7UqUk.js → camera-movement-C1pwfMk_.js} +2 -2
- package/dist/internal/camera-movement-C1pwfMk_.js.map +1 -0
- package/dist/internal/{changeMode-BVGYCoqu.js → changeMode-D_I2AOjH.js} +2 -2
- package/dist/internal/{changeMode-BVGYCoqu.js.map → changeMode-D_I2AOjH.js.map} +1 -1
- package/dist/internal/{controller-BWkZT0l1.js → controller-DIDtFrBE.js} +1991 -2050
- package/dist/internal/controller-DIDtFrBE.js.map +1 -0
- package/dist/internal/{cruise-C3F0eNQ-.js → cruise-B50Tcq66.js} +2 -2
- package/dist/internal/{cruise-C3F0eNQ-.js.map → cruise-B50Tcq66.js.map} +1 -1
- package/dist/internal/{current-pano-image-DKUWluR-.js → current-pano-image-BCFr6njt.js} +4 -4
- package/dist/internal/{current-pano-image-DKUWluR-.js.map → current-pano-image-BCFr6njt.js.map} +1 -1
- package/dist/internal/{defaultUrls-CjKkS9k9.js → defaultUrls-CfMtGzqM.js} +14 -3
- package/dist/internal/defaultUrls-CfMtGzqM.js.map +1 -0
- package/dist/internal/{fire-scene-CczaBz2_.js → fire-scene-BzZGvyh_.js} +9 -4
- package/dist/internal/fire-scene-BzZGvyh_.js.map +1 -0
- package/dist/internal/{fiveModelLoad-mg-TnpnM.js → fiveModelLoad-BUIBYxzp.js} +2 -2
- package/dist/internal/{fiveModelLoad-mg-TnpnM.js.map → fiveModelLoad-BUIBYxzp.js.map} +1 -1
- package/dist/internal/{floorplan-KWlIsTvO.js → floorplan-C8BGw87S.js} +5 -5
- package/dist/internal/{floorplan-KWlIsTvO.js.map → floorplan-C8BGw87S.js.map} +1 -1
- package/dist/internal/{generatePolygonGeometry-B_5JFq8y.js → generatePolygonGeometry-BOnzdCaG.js} +181 -178
- package/dist/internal/generatePolygonGeometry-BOnzdCaG.js.map +1 -0
- package/dist/internal/{lookObject-wesf8xt6.js → lookObject-DuRab5wf.js} +2 -2
- package/dist/internal/{lookObject-wesf8xt6.js.map → lookObject-DuRab5wf.js.map} +1 -1
- package/dist/internal/{measure-BX6boAC7.js → measure-B4jFwdQ6.js} +5 -5
- package/dist/internal/{measure-BX6boAC7.js.map → measure-B4jFwdQ6.js.map} +1 -1
- package/dist/internal/{model-chassis-compass-InVNmOAQ.js → model-chassis-compass-C6NTVMLo.js} +2 -2
- package/dist/internal/{model-chassis-compass-InVNmOAQ.js.map → model-chassis-compass-C6NTVMLo.js.map} +1 -1
- package/dist/internal/{model-entry-door-guide-wZbyY77a.js → model-entry-door-guide-DnGTLY2s.js} +2 -2
- package/dist/internal/{model-entry-door-guide-wZbyY77a.js.map → model-entry-door-guide-DnGTLY2s.js.map} +1 -1
- package/dist/internal/{model-maker-uO8xlTuO.js → model-maker-B1mnDdKY.js} +15 -15
- package/dist/internal/{model-maker-uO8xlTuO.js.map → model-maker-B1mnDdKY.js.map} +1 -1
- package/dist/internal/{model-tv-video-DzXb2JRf.js → model-tv-video-BP-7HoDC.js} +2 -2
- package/dist/internal/{model-tv-video-DzXb2JRf.js.map → model-tv-video-BP-7HoDC.js.map} +1 -1
- package/dist/internal/{model-view-CBeeMM98.js → model-view-BWUU0-uq.js} +2 -2
- package/dist/internal/{model-view-CBeeMM98.js.map → model-view-BWUU0-uq.js.map} +1 -1
- package/dist/internal/object3d-helper-CbRRhnLV.js +7 -0
- package/dist/internal/{object3d-helper-DDYsVPN6.js.map → object3d-helper-CbRRhnLV.js.map} +1 -1
- package/dist/internal/{pano-compass-jSr629BP.js → pano-compass-BRTM0dCc.js} +7 -7
- package/dist/internal/{pano-compass-jSr629BP.js.map → pano-compass-BRTM0dCc.js.map} +1 -1
- package/dist/internal/{pano-door-label-DKoYIKLa.js → pano-door-label-BLjYGZrr.js} +3 -3
- package/dist/internal/{pano-door-label-DKoYIKLa.js.map → pano-door-label-BLjYGZrr.js.map} +1 -1
- package/dist/internal/{pano-measure-DW9mdx1O.js → pano-measure-BIgCWkVJ.js} +14 -14
- package/dist/internal/{pano-measure-DW9mdx1O.js.map → pano-measure-BIgCWkVJ.js.map} +1 -1
- package/dist/internal/{pano-ruler-pro-D7q0Ob21.js → pano-ruler-pro-D9yTbHJz.js} +2 -2
- package/dist/internal/{pano-ruler-pro-D7q0Ob21.js.map → pano-ruler-pro-D9yTbHJz.js.map} +1 -1
- package/dist/internal/{pano-spatial-tag-D0qn-__S.js → pano-spatial-tag-B7Gxn3BS.js} +3 -3
- package/dist/internal/{pano-spatial-tag-D0qn-__S.js.map → pano-spatial-tag-B7Gxn3BS.js.map} +1 -1
- package/dist/internal/{pano-tag-BW5MXXws.js → pano-tag-Bchz-jED.js} +2 -2
- package/dist/internal/{pano-tag-BW5MXXws.js.map → pano-tag-Bchz-jED.js.map} +1 -1
- package/dist/internal/{pano-video-Bmud_CAn.js → pano-video-BufYQMqo.js} +3 -3
- package/dist/internal/{pano-video-Bmud_CAn.js.map → pano-video-BufYQMqo.js.map} +1 -1
- package/dist/internal/{pipeline-DDqgb1gw.js → pipeline-t_3IMXKB.js} +4 -4
- package/dist/internal/{pipeline-DDqgb1gw.js.map → pipeline-t_3IMXKB.js.map} +1 -1
- package/dist/internal/{sculpt-BNkLJR6p.js → sculpt-BCK4PMwL.js} +64 -63
- package/dist/internal/{sculpt-BNkLJR6p.js.map → sculpt-BCK4PMwL.js.map} +1 -1
- package/dist/internal/tagPosition-DA9YguT8.js +176 -0
- package/dist/internal/tagPosition-DA9YguT8.js.map +1 -0
- package/dist/internal/withResolvers-DVr4bnnk.js +15 -0
- package/dist/internal/withResolvers-DVr4bnnk.js.map +1 -0
- package/dist/plugins/area-maker.js +1 -1
- package/dist/plugins/camera-movement.js +1 -1
- package/dist/plugins/cruise.js +2 -2
- package/dist/plugins/css3d-render.js +1 -1
- package/dist/plugins/current-pano-image.js +1 -1
- package/dist/plugins/digital-performance.d.ts +1 -1
- package/dist/plugins/digital-performance.js +1 -1
- package/dist/plugins/fire-scene.d.ts +1 -1
- package/dist/plugins/fire-scene.js +1 -1
- package/dist/plugins/guide-line.js +1 -1
- package/dist/plugins/measure.js +1 -1
- package/dist/plugins/model-chassis-compass.js +1 -1
- package/dist/plugins/model-entry-door-guide.js +1 -1
- package/dist/plugins/model-maker.d.ts +1 -1
- package/dist/plugins/model-maker.js +1 -1
- package/dist/plugins/model-tv-video.js +1 -1
- package/dist/plugins/model-view.js +1 -1
- package/dist/plugins/object3d-helper.d.ts +1 -1
- package/dist/plugins/object3d-helper.js +3 -1
- package/dist/plugins/pano-compass.js +1 -1
- package/dist/plugins/pano-door-label.js +1 -1
- package/dist/plugins/pano-measure.js +1 -1
- package/dist/plugins/pano-ruler-pro.js +1 -1
- package/dist/plugins/pano-spatial-tag.js +1 -1
- package/dist/plugins/pano-tag.d.ts +1 -1
- package/dist/plugins/pano-tag.js +4 -1
- package/dist/plugins/pano-video.js +1 -1
- package/dist/plugins/pipeline.js +1 -1
- package/dist/plugins/sculpt.d.ts +1 -1
- package/dist/plugins/sculpt.js +7 -1
- package/dist/types/public/index.d.ts +2 -0
- package/dist/types/public/plugins/digital-performance.d.ts +1 -0
- package/dist/types/public/plugins/fire-scene.d.ts +1 -0
- package/dist/types/public/plugins/model-maker.d.ts +1 -0
- package/dist/types/public/plugins/object3d-helper.d.ts +1 -0
- package/dist/types/public/plugins/pano-tag.d.ts +2 -0
- package/dist/types/public/plugins/sculpt.d.ts +8 -0
- package/dist/types/public/utils.d.ts +5 -0
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +16 -50
- package/package.json +1 -1
- package/dist/internal/BasePluginWithData-9z4tpAT4.js +0 -7
- package/dist/internal/CSS3DRenderPlugin-ccSpcvwd.js.map +0 -1
- package/dist/internal/Rectangle-D-zkDycu.js.map +0 -1
- package/dist/internal/animationFrame-XGKHIeQK.js.map +0 -1
- package/dist/internal/blink-DD_0mH-m.js +0 -113
- package/dist/internal/blink-DD_0mH-m.js.map +0 -1
- package/dist/internal/camera-movement-CwI7UqUk.js.map +0 -1
- package/dist/internal/controller-BWkZT0l1.js.map +0 -1
- package/dist/internal/defaultUrls-CjKkS9k9.js.map +0 -1
- package/dist/internal/fire-scene-CczaBz2_.js.map +0 -1
- package/dist/internal/generatePolygonGeometry-B_5JFq8y.js.map +0 -1
- package/dist/internal/object3d-helper-DDYsVPN6.js +0 -7
- package/dist/utils.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PointHelper-D565h9b_.js","names":["createPlaneMesh","createLineMesh","createBallMesh","__toESM","bindFiveOwner","LineMesh","generateBehindFiveElement","CSS3DSprite","CSS3DObjectPlus","getFiveModel","waitFiveModelLoaded","THREERaycaster","rayOnLine","THREE","Magnifier","Subscribe","five","options","context","m","Hammer","element","point","newScale","newWidth","newHeight","imageWidth","imageHeight","revision","renderSize","projected","x","y","readWidth","width","scale","readHeight","height","pixelRatio","hidden","pixelsPromise","object","visible","pixels","error","canvasClientRect","containerDomRect","maxOffsetX","maxOffsetY","minOffsetX","minOffsetY","left","right","top","position2d","clientWidth","clientHeight","canvas","offsetRange","offsetX","event","offsetY","translateX","translateY","sessions","activeSessions","disposedOwners","frontScene","behindScene","legacyOwners","belongsToFive","scene","legacyScenes","mode","sceneMap","initialCSS3DRender","addScene","map","sceneKey","key","removeScene","sceneOrKey","maps","session","removed","addFrontScene","removeFrontScene","addBehindScene","removeBehindScene","scenesForOwner","existing","front","ICSS3DRenderer","behind","pending","disposed","dispose","onFiveDispose","ownedHere","root","movedToAnotherScene","wrapper","behindWrapper","ICSS3DSprite","createPlaneMesh$1","group","fill","border","createCrossline","length","style","lineX","lineY","createLineMesh$1","zPath","zGeometry","zMaterial","createRingMesh","geometry","material","createBallMesh$1","ballGeometry","ballMaterial","createCSSBallMesh","img","cssMesh","PointHelper2","lineLength","intersect","normal","lookAtPosition","mesh","PointSelectorHelper","pointHelper","PointHelper","config","updateMagnifier","navigatorTouchPoints","isTouchDevice","createIntersectionFace","Vector3","getRaycasterByNdcPosition","position","raycaster","getIntersectByRaycaster","realIntersect","getRealIntersectByRaycaster","getVirtualIntersectByRaycaster","distance","CURSOR_NOT_ALLOW_URL","_vector3","disableFiveEvent","PointSelector","cursorError","outOfFive","enabled","defaultMagnifierParams","fiveElement","points","intersection","cancel","render","clientX","clientY","timestamp","success","moved","ndcPosition","realIntersection","intersectionPoint","virtualIntersection","targetIntersect","mouseNdcPosition","size","adherePlane","newPoint","adhereLine","closestPoint","projectPoint","positionOffset","_point","pointIsVisible","cameraToPointDistance","mouseX","mouseY","mousePosition","POINT_HELPER_TEXTURE_URL","rangePieceImg","html_default","createPlaneMesh","planGeometry","planTextureUrl","planTexture","planMaterial","createLineMesh","colors","uv","i","createBallMesh","ballMesh","createBorderMesh","radius","borderMesh","contentElement"],"sources":["../../src/shared-utils/three/Magnifier.ts","../../src/shared-utils/CSS3DRender/index.ts","../../src/CSS3DRenderPlugin/utils/three/CSS3DSprite.ts","../../src/shared-utils/three/PointSelector/utils/PointHelper2.ts","../../src/shared-utils/three/PointSelector/utils/PointSelectorHelper.ts","../../src/shared-utils/isTouchDevice.ts","../../src/shared-utils/three/createIntersectionFace.ts","../../src/shared-utils/five/getRaycasterByNdcPosition.ts","../../src/shared-utils/five/getPosition.ts","../../src/shared-utils/three/PointSelector/utils/contents.ts","../../src/shared-utils/three/PointSelector/index.ts","../../src/shared-utils/three/Assets/index.ts","../../src/shared-utils/three/PointSelector/utils/html.ts","../../src/shared-utils/three/PointSelector/utils/PointHelper.ts"],"sourcesContent":["import type { Five, SubscribeEventMap } from '@realsee/five-webgpu'\n\nimport type Hammer from 'hammerjs'\nimport * as THREE from 'three/webgpu'\nimport { Subscribe } from '../Subscribe'\n\ninterface MagnifierConfig {\n /** 允许拖动放大镜 */\n dragEnabled: boolean\n /** renderWithPoint 时,是否应该自动更新放大镜的位置 */\n autoFixPCPosition: boolean\n /** 放大镜初始位置应该设置在容器的哪个位置 */\n initialPosition: { left: string; top: string }\n /** 是否跳过全景图渲染 */\n skipPanorama: boolean\n}\n\ninterface MagnifierEvent extends SubscribeEventMap {\n wantsPanGesture: (event: (typeof Hammer)['Input']) => boolean\n}\n\n/** 放大镜配置参数 */\nexport interface MagnifierParameter extends Partial<MagnifierConfig> {\n width?: number\n height?: number\n scale?: number\n}\n\nexport class Magnifier {\n public width: number\n public height: number\n public containerDom?: Element\n public hooks = new Subscribe<MagnifierEvent>()\n public canvas = document.createElement('canvas')\n public config: MagnifierConfig\n public state = { enabled: false }\n\n private five: Five\n private scale: number\n private offset = { x: 0, y: 0 }\n private context: CanvasRenderingContext2D\n private renderCenter: THREE.Vector3 | { x: number; y: number } = new THREE.Vector3()\n private hammer?: InstanceType<typeof Hammer>\n private offsetRange?: { min: { x: number; y: number }; max: { x: number; y: number } }\n private isPanning = false\n private isDisposed = false\n private imageData: ImageData = new ImageData(1, 1)\n private pendingRender?: Promise<void>\n private renderRevision = 0\n private invalidatedRevision = -1\n\n public constructor(five: Five, options: MagnifierParameter) {\n if (!five.renderer) {\n console.error('Five Render 未初始化')\n return\n }\n\n this.five = five\n this.scale = options?.scale ?? 2\n this.width = options?.width ?? 190\n this.height = options?.height ?? options?.width ?? 190\n this.config = {\n dragEnabled: options?.dragEnabled || false,\n autoFixPCPosition: options?.autoFixPCPosition || false,\n initialPosition: options?.initialPosition || { left: '0', top: '0' },\n skipPanorama: options?.skipPanorama || false,\n }\n\n const context = this.canvas.getContext('2d')\n if (!context) throw new Error('CANNOT CREATE CONTEXT2D')\n this.context = context\n\n if (this.config.dragEnabled) {\n void import('hammerjs').then(({ default: Hammer }) => {\n if (this.isDisposed) return\n this.hammer = new Hammer(this.canvas)\n this.hammer.on('pan', this.onPan)\n this.hammer.on('panstart', this.onPanstart)\n this.hammer.on('panend', this.onPanend)\n })\n }\n this.initStyle()\n }\n\n public enable() {\n if (this.isDisposed || this.state.enabled) return\n this.state.enabled = true\n if (this.containerDom) this._appendTo(this.containerDom)\n return this\n }\n\n public disable() {\n if (!this.state.enabled) return\n this.state.enabled = false\n this.invalidatedRevision = this.renderRevision\n this.canvas.style.visibility = 'hidden'\n this.canvas.remove()\n return this\n }\n\n public dispose() {\n if (this.isDisposed) return\n this.isDisposed = true\n this.clear()\n this.disable()\n this.hammer?.destroy()\n }\n\n /** 把放大镜放到某一个容器中 */\n public appendTo(element: Element) {\n if (this.containerDom) this.containerDom?.removeChild(this.canvas)\n this.containerDom = element\n if (this.state.enabled) this._appendTo(element)\n return this\n }\n\n /** 清除放大镜渲染内容 */\n public clear() {\n this.invalidatedRevision = this.renderRevision\n this.context?.clearRect(0, 0, this.canvas.width, this.canvas.height)\n return this\n }\n\n /** 放大传入点位周围的内容 */\n public renderWithPoint(point: THREE.Vector3) {\n if (!this.containerDom) return\n if (!this.state.enabled) return\n this.renderCenter = point\n this.render()\n if (this.config.autoFixPCPosition) this.autoFixPCPosition()\n }\n\n /** 放大传入点位周围的内容 */\n public renderWithScreenPoint(point: { x: number; y: number }) {\n if (!this.containerDom) return\n if (!this.state.enabled) return\n this.renderCenter = point\n this.render()\n if (this.config.autoFixPCPosition) this.autoFixPCPosition()\n }\n\n public resetOffset() {\n this.offset = { x: 0, y: 0 }\n this.canvas.style.transform = `translate3d(${0}px, ${0}px, 100px)`\n }\n\n /** 更新放大镜的缩放比例 */\n public updateScale(newScale: number) {\n if (newScale > 0) {\n this.scale = newScale\n this.invalidatedRevision = this.renderRevision\n }\n }\n\n /** 更新放大镜的尺寸 */\n public updateSize(newWidth: number, newHeight?: number) {\n if (newWidth > 0) {\n this.width = newWidth\n this.height = newHeight || newWidth\n\n // 更新canvas样式\n const pixelRatio = 1\n this.canvas.setAttribute('width', (this.width * pixelRatio).toString())\n this.canvas.setAttribute('height', (this.height * pixelRatio).toString())\n this.canvas.style.width = this.width + 'px'\n this.canvas.style.height = this.height + 'px'\n\n // 重新初始化ImageData\n const imageWidth = Math.floor(this.width * pixelRatio)\n const imageHeight = Math.floor(this.height * pixelRatio)\n this.imageData = new ImageData(imageWidth, imageHeight)\n\n // 清除之前的渲染内容\n this.clear()\n }\n }\n\n public render(): Promise<void> {\n this.renderRevision += 1\n if (!this.pendingRender) {\n this.pendingRender = this.renderLatest().finally(() => { this.pendingRender = undefined })\n }\n return this.pendingRender\n }\n\n private async renderLatest() {\n while (!this.isDisposed && this.state.enabled && this.containerDom && this.five.renderer) {\n const revision = this.renderRevision\n const { scale, width, height } = this\n const renderSize = this.five.renderer.getSize(new THREE.Vector2())\n const point = this.renderCenter\n const projected = point instanceof THREE.Vector3 ? point.clone().project(this.five.camera) : null\n const x = projected ? ((projected.x + 1) / 2) * renderSize.x : point.x\n const y = projected ? ((projected.y + 1) / 2) * renderSize.y : renderSize.y - point.y\n\n // Five accepts integer dimensions and pixel ratios. Keep fractional zoom\n // in the CSS size instead of expecting an impossible fractional readback.\n const readWidth = Math.max(1, Math.round(width / scale))\n const readHeight = Math.max(1, Math.round(height / scale))\n const pixelRatio = Math.max(1, Math.ceil(scale))\n const imageWidth = readWidth * pixelRatio\n const imageHeight = readHeight * pixelRatio\n const hidden = new Map<THREE.Object3D, boolean>()\n let pixelsPromise: ReturnType<Five['getPixels']>\n\n try {\n this.five.scene.traverse((object) => {\n if ((object as THREE.Object3D & { disableGetPixel?: boolean }).disableGetPixel) {\n hidden.set(object, object.visible)\n object.visible = false\n }\n })\n try {\n // getPixels renders synchronously before its asynchronous GPU readback.\n pixelsPromise = this.five.getPixels({\n x: x - readWidth / 2,\n y: y - readHeight / 2,\n width: readWidth,\n height: readHeight,\n pixelRatio,\n skipPanorama: this.config.skipPanorama,\n flipY: true,\n })\n } finally {\n hidden.forEach((visible, object) => { object.visible = visible })\n }\n const pixels = await pixelsPromise\n if (this.isDisposed || !this.state.enabled) return\n if (this.invalidatedRevision === this.renderRevision) return\n if (revision !== this.renderRevision) continue\n if (pixels.length !== imageWidth * imageHeight * 4) {\n console.warn('Magnifier: Invalid pixel data length')\n return\n }\n if (this.imageData.width !== imageWidth || this.imageData.height !== imageHeight) {\n this.imageData = new ImageData(imageWidth, imageHeight)\n }\n this.canvas.width = imageWidth\n this.canvas.height = imageHeight\n this.imageData.data.set(pixels)\n this.context.putImageData(this.imageData, 0, 0)\n this.canvas.style.visibility = 'visible'\n } catch (error) {\n console.error('Magnifier: Failed to read pixels', error)\n }\n if (revision === this.renderRevision) return\n }\n }\n\n private _appendTo(element: Element) {\n this.resetOffset()\n element.appendChild(this.canvas)\n if (!this.offsetRange) {\n const canvasClientRect = this.canvas.getBoundingClientRect()\n const containerDomRect = element.getBoundingClientRect()\n const maxOffsetX = containerDomRect.right - canvasClientRect.right\n const maxOffsetY = containerDomRect.bottom - canvasClientRect.bottom\n const minOffsetX = containerDomRect.left - canvasClientRect.left\n const minOffsetY = containerDomRect.top - canvasClientRect.top\n this.offsetRange = {\n min: { x: minOffsetX, y: minOffsetY },\n max: { x: maxOffsetX, y: maxOffsetY },\n }\n }\n }\n\n private autoFixPCPosition() {\n if (!this.containerDom) return\n const { width, height } = this\n const { clientWidth, clientHeight } = this.containerDom\n\n const [left, right, top] = (() => {\n if ((this.renderCenter as any).isVector3) {\n const position2d = (this.renderCenter as THREE.Vector3).clone().project(this.five.camera)\n\n return [\n //\n ((position2d.x + 1) / 2) * clientWidth,\n (-(position2d.x - 1) / 2) * clientWidth,\n (-(position2d.y - 1) / 2) * clientHeight,\n ]\n } else {\n return [this.renderCenter.x, clientWidth - this.renderCenter.x, this.renderCenter.y]\n }\n })()\n\n if (left < 183) {\n this.canvas.style.top = -height / 2 + 'px'\n this.canvas.style.left = 90 + 'px'\n } else if (top < 183) {\n this.canvas.style.top = 90 + 'px'\n this.canvas.style.left = -width / 2 + 'px'\n } else if (right < 183) {\n this.canvas.style.top = -height / 2 + 'px'\n this.canvas.style.left = -width - 90 + 'px'\n } else {\n this.canvas.style.left = -width / 2 + 'px'\n this.canvas.style.top = -height - 90 + 'px'\n }\n this.canvas.style.transform = `translate3d(${left}px, ${top}px, 10px)`\n this.offset = { x: left, y: top }\n }\n\n private initStyle() {\n const canvas = this.canvas\n canvas.classList.add('five-plugin__magnifier')\n canvas.style.position = 'absolute'\n canvas.style.pointerEvents = this.config.dragEnabled ? 'all' : 'none'\n canvas.style.borderRadius = '50%'\n canvas.style.zIndex = '99'\n const pixelRatio = 1\n canvas.setAttribute('width', (this.width * pixelRatio).toString())\n canvas.setAttribute('height', (this.height * pixelRatio).toString())\n canvas.style.border = '2px solid rgba(255,255,255,0.20)'\n canvas.style.width = this.width + 'px'\n canvas.style.height = this.height + 'px'\n canvas.style.top = this.config.initialPosition.top\n canvas.style.left = this.config.initialPosition.left\n canvas.style.transform = 'translate(0,0,100px)'\n canvas.style.visibility = 'hidden'\n\n if (this.config.dragEnabled) {\n this.canvas.style.cursor = 'pointer'\n }\n }\n\n private getPanOffset(event: (typeof Hammer)['Input'], offsetRange: { min: { x: number; y: number }; max: { x: number; y: number } }) {\n const {\n min: { x: minOffsetX, y: minOffsetY },\n max: { x: maxOffsetX, y: maxOffsetY },\n } = offsetRange\n const offsetX = this.offset.x + event.deltaX\n const offsetY = this.offset.y + event.deltaY\n const translateX = Math.min(Math.max(offsetX, minOffsetX), maxOffsetX)\n const translateY = Math.min(Math.max(offsetY, minOffsetY), maxOffsetY)\n return { translateX, translateY }\n }\n\n private onPanstart = () => {\n this.isPanning = true\n this.canvas.style.boxShadow = '0 2px 30px 0 rgba(0,0,0,0.20)'\n }\n\n private onPan = (event: (typeof Hammer)['Input']) => {\n if (!this.isPanning) return\n if (!this.offsetRange) return\n const prevented = this.hooks.emit('wantsPanGesture', event)\n if (prevented) return\n\n const { translateX, translateY } = this.getPanOffset(event, this.offsetRange)\n this.canvas.style.transform = `translate3d(${translateX}px, ${translateY}px, 100px)`\n }\n\n private onPanend = (event: (typeof Hammer)['Input']) => {\n this.isPanning = false\n this.canvas.style.boxShadow = 'none'\n if (!this.offsetRange) return\n const { translateX, translateY } = this.getPanOffset(event, this.offsetRange)\n this.canvas.style.transform = `translate3d(${translateX}px, ${translateY}px, 100px)`\n this.offset = { x: translateX, y: translateY }\n }\n}\n","import type * as THREE from 'three/webgpu'\nimport { ICSS3DRenderer } from '../../CSS3DRenderPlugin/utils/three/CSS3DRenderer'\nimport type { Five } from '@realsee/five-webgpu'\nimport { waitFiveModelLoaded } from '../five/fiveModelLoad'\nimport { generateBehindFiveElement } from '../../CSS3DRenderPlugin/utils/generateBehindFiveElement'\nimport type { CSS3DObjectPlus } from './CSS3DObject'\n\ntype CSSScene = THREE.Scene | CSS3DObjectPlus\ntype SceneMode = 'front' | 'behind'\ninterface CSSSession {\n five: Five\n front: Map<string, CSSScene>\n behind: Map<string, CSSScene>\n dispose: () => void\n}\nconst sessions = new WeakMap<Five, CSSSession>()\nconst activeSessions = new Set<CSSSession>()\nconst disposedOwners = new WeakSet<Five>()\n// Existing calls without an owner stay supported. Their scene ancestry is\n// checked every frame, including objects added after construction or reparented.\nconst frontScene = new Map<string, CSSScene>()\nconst behindScene = new Map<string, CSSScene>()\nconst legacyOwners = new WeakMap<CSSScene, Five>()\n\nfunction belongsToFive(scene: CSSScene, five: Five) {\n for (let object: THREE.Object3D | null = scene; object; object = object.parent) {\n if (object === five.scene) return true\n }\n return false\n}\nfunction legacyScenes(mode: SceneMode) {\n return mode === 'front' ? frontScene : behindScene\n}\nfunction sceneMap(mode: SceneMode, five?: Five) {\n if (!five) return legacyScenes(mode)\n initialCSS3DRender(five)\n return sessions.get(five)?.[mode]\n}\nfunction addScene(mode: SceneMode, scene: CSSScene, key?: string, five?: Five): boolean {\n if (!scene) return false\n const map = sceneMap(mode, five),\n sceneKey = key || scene.uuid\n if (!map || map.has(sceneKey)) return false\n map.set(sceneKey, scene)\n return true\n}\nfunction removeScene(mode: SceneMode, sceneOrKey: CSSScene | string, five?: Five): boolean {\n if (!sceneOrKey) return false\n const maps = five\n ? [sessions.get(five)?.[mode]]\n : [legacyScenes(mode), ...Array.from(activeSessions, (session) => session[mode])]\n let removed = false\n for (const map of maps) {\n if (!map) continue\n if (typeof sceneOrKey === 'string') removed = map.delete(sceneOrKey) || removed\n else for (const [key, scene] of map) if (scene === sceneOrKey) removed = map.delete(key) || removed\n }\n return removed\n}\n/** Add a front scene; the optional owner keeps identical keys in separate Five sessions. */\nexport function addFrontScene(scene: CSSScene, key?: string, five?: Five): boolean {\n return addScene('front', scene, key, five)\n}\nexport function removeFrontScene(sceneOrKey: CSSScene | string, five?: Five): boolean {\n return removeScene('front', sceneOrKey, five)\n}\nexport function addBehindScene(scene: CSSScene, key?: string, five?: Five): boolean {\n return addScene('behind', scene, key, five)\n}\nexport function removeBehindScene(sceneOrKey: CSSScene | string, five?: Five): boolean {\n return removeScene('behind', sceneOrKey, five)\n}\n/** The existing no-argument clear functions retain their explicit global semantics. */\nexport function clearFrontScenes(): void {\n frontScene.clear()\n for (const session of activeSessions) session.front.clear()\n}\nexport function clearBehindScenes(): void {\n behindScene.clear()\n for (const session of activeSessions) session.behind.clear()\n}\nexport function clearAllScenes(): void {\n clearFrontScenes()\n clearBehindScenes()\n}\n\nfunction* scenesForOwner(session: CSSSession, mode: SceneMode): Iterable<CSSScene> {\n yield* session[mode].values()\n for (const scene of legacyScenes(mode).values()) {\n if (belongsToFive(scene, session.five)) {\n legacyOwners.set(scene, session.five)\n yield scene\n }\n }\n}\n\nexport function initialCSS3DRender(five: Five) {\n const existing = sessions.get(five)\n if (existing) return existing.dispose\n if (disposedOwners.has(five)) return () => {}\n const front = new ICSS3DRenderer('front'),\n behind = new ICSS3DRenderer('behind')\n front.domElementWrapper.style.zIndex = '1'\n const pending = new AbortController()\n let disposed = false\n const dispose = () => {\n if (disposed) return\n disposed = true\n pending.abort()\n five.off('dispose', onFiveDispose)\n front.dispose()\n behind.dispose()\n session.front.clear()\n session.behind.clear()\n for (const map of [frontScene, behindScene]) {\n for (const [key, scene] of map) {\n const ownedHere = belongsToFive(scene, five)\n let root: THREE.Object3D = scene\n while (root.parent) root = root.parent\n // A legacy object may already be in another scene before that owner's\n // next frame updates the observation. Do not erase its new registry entry.\n const movedToAnotherScene = !ownedHere && (root as THREE.Scene).isScene === true\n if (ownedHere || (legacyOwners.get(scene) === five && !movedToAnotherScene)) map.delete(key)\n }\n }\n if (sessions.get(five) === session) sessions.delete(five)\n activeSessions.delete(session)\n }\n const onFiveDispose = () => {\n disposedOwners.add(five)\n dispose()\n }\n const session: CSSSession = { five, front: new Map(), behind: new Map(), dispose }\n sessions.set(five, session)\n activeSessions.add(session)\n five.on('dispose', onFiveDispose)\n waitFiveModelLoaded(five, pending.signal).then(() => {\n if (disposed) return\n const wrapper = five.getElement()?.parentElement\n if (!wrapper) {\n // A host can detach its canvas before Five emits public dispose. Treat\n // that async mount as cancelled and release this session's resources.\n // A later append may create a fresh session through the normal entry.\n dispose()\n return\n }\n const behindWrapper = generateBehindFiveElement(five)\n if (!behindWrapper) {\n console.error('initialCSS3DRender: behindWrapper is not exist')\n return\n }\n front.appendToElement(wrapper)\n front.renderCss3dObjectEveryFrame(() => scenesForOwner(session, 'front'), five.camera)\n behind.appendToElement(behindWrapper)\n behind.renderCss3dObjectEveryFrame(() => scenesForOwner(session, 'behind'), five.camera)\n })\n return dispose\n}\n","import { CSS3DSprite } from '../../../shared-utils/three/CSS3DRenderer'\n\nexport class ICSS3DSprite extends CSS3DSprite {\n public isCSS3DSprite = true\n public isCSS3DObject = true\n}\n","import { bindFiveOwner } from '../../../five/getFiveFromParentChain'\nimport * as THREE from 'three/webgpu'\nimport type { Intersection } from '../../../../typings/typings'\nimport { initialCSS3DRender } from '../../../five/initialCSS3DRender'\nimport type { Five } from '@realsee/five-webgpu'\nimport { LineMesh, type LineMeshStyle } from '../../../../Sculpt/Meshes/Line'\nimport type { PointHelperAbstract } from './typing'\nimport { ICSS3DSprite } from '../../../../CSS3DRenderPlugin/utils/three/CSS3DSprite'\n\n\nexport interface MouseGroupParameter {\n isMobile?: boolean\n useNormalVector?: boolean // 是否展示法向量\n ballColor?: number // 法向量小球色值\n}\n\nfunction createPlaneMesh() {\n const radius = 0.2\n const group = new THREE.Group()\n const fill = new THREE.Mesh(\n new THREE.CircleGeometry(radius - 0.01, 64),\n new THREE.MeshBasicMaterial({ color: 0xffffff, opacity: 0.2, side: THREE.DoubleSide, depthTest: false, transparent: true }),\n )\n const border = new THREE.Mesh(\n new THREE.RingGeometry(radius - 0.01, radius, 64),\n new THREE.MeshBasicMaterial({ color: 0xffffff, opacity: 0.3, side: THREE.DoubleSide, depthTest: false, transparent: true }),\n )\n group.add(fill, border)\n return group\n}\n\nfunction createCrossline() {\n const length = 0.5\n const group = new THREE.Group()\n const style: Partial<LineMeshStyle> = {\n lineWidth: 1,\n lineColor: 0x33ffdd,\n lineOpacity: 0.7,\n occlusionVisibility: true,\n }\n const lineX = new LineMesh({ points: [{ x: -length }, { x: length }], ...style, lineColor: 0x33ffdd })\n const lineY = new LineMesh({ points: [{ y: -length }, { y: length }], ...style, lineColor: 0x33ffdd })\n\n group.add(lineX, lineY)\n return group\n}\n\nfunction createLineMesh(length: number) {\n // 法向量垂直管\n const zPath = new THREE.CurvePath<THREE.Vector3>()\n zPath.add(new THREE.LineCurve3(new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, length)))\n const zGeometry = new THREE.TubeGeometry(zPath, 32, 0.003)\n const zMaterial = new THREE.MeshBasicMaterial({\n color: 0xa7c3ff,\n depthTest: false,\n transparent: true, // 必须要开启透明度,要和PlaneMesh一起渲染\n })\n const zMesh = new THREE.Mesh(zGeometry, zMaterial)\n return zMesh\n}\n\nfunction createRingMesh() {\n // 法向量圆环\n const geometry = new THREE.RingGeometry(0.03, 0.035, 64)\n const material = new THREE.MeshBasicMaterial({\n color: 0xffffff,\n depthTest: false,\n transparent: true, // 必须要开启透明度,要和PlaneMesh一起渲染\n side: THREE.DoubleSide,\n })\n const ringMesh = new THREE.Mesh(geometry, material)\n return ringMesh\n}\n\nfunction createBallMesh() {\n // mesh 球\n const ballGeometry = new THREE.SphereGeometry(0.018, 32, 32)\n const ballMaterial = new THREE.MeshBasicMaterial({\n color: 0x4d97ff,\n depthTest: false,\n transparent: true, // 必须要开启透明度,要和PlaneMesh一起渲染\n })\n const ballMesh = new THREE.Mesh(ballGeometry, ballMaterial)\n\n return ballMesh\n}\n\nfunction createCSSBallMesh() {\n // css 球\n const img = document.createElement('img')\n img.src =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAVCAMAAAB8FU7dAAAAw1BMVEUAAACDuuiAsu11q/x8r/+HxtKHxtKIx9J4ut6Hx9Jcn/uNwNlmmf+RuP9ppf9orel3ud2HxtJrpf9oremev/9ppP9orelQmP9ZoPWSuP92q/9cnv9prel4ut53qv9orelYoPWIxdJPmP+HxtGRuP9oo/+Suf9Qmf92q/+RuP+DsP9Pmv+FxdFtre2SyMiRuP9PmP+evv9ppf9cnv+rxf9orepZofV4ut52q/+Dsf+Esv+5y/93q/9aofbF0f93rP9qpf8IzZ1iAAAAL3RSTlMAEg4s3dK5nodgVQoF/Pf39vbt7evr39rV1NTOzs6srJ+fiIZ9fWlpW09ERCwcHMH8LhIAAADRSURBVBjTjdDHkoMwEIThBrzOm3POOQwSYCRhe/f9n2p75FD2zX/VXL5qOAjzkixLsFL6fOFF5PwpXUj/eEwx7Oh9Jq+FdV5MqZkXlU9K4KZsmqY02x/A8LSwv14o0ylJWkP087WVhDfcjmjj5b/E3+CEpDPdGY58C7tKfzSiiA9uB4dV/NIF7yVQ7AGuq0lOIzrvnLP2Et2aMzUqryge8FVX0Zjl5XkG3KsR593pM2zVEScjvbMU7IdGjF19IzZ43Ceyve4Ai5Jep93u9BJs3j/gXjHbRgy31AAAAABJRU5ErkJggg=='\n const cssMesh = new ICSS3DSprite(img)\n img.style.pointerEvents = 'none'\n cssMesh.scale.set(0.003, 0.003, 0.003)\n\n return cssMesh\n}\n\nexport class PointHelper2 extends THREE.Object3D implements PointHelperAbstract {\n public disableGetPixel = true\n public planeMesh: ReturnType<typeof createPlaneMesh>\n public ringMesh: ReturnType<typeof createRingMesh>\n public crossline: ReturnType<typeof createCrossline>\n public lineMesh: ReturnType<typeof createLineMesh>\n public ballMesh: ReturnType<typeof createBallMesh>\n public cssBallMesh: ReturnType<typeof createCSSBallMesh>\n\n public constructor(five: Five) {\n super()\n bindFiveOwner(this, five)\n\n const lineLength = 0.18\n this.planeMesh = createPlaneMesh()\n this.ringMesh = createRingMesh()\n this.crossline = createCrossline()\n this.lineMesh = createLineMesh(lineLength)\n this.ballMesh = createBallMesh()\n this.cssBallMesh = createCSSBallMesh()\n\n this.ballMesh.position.setZ(lineLength)\n this.cssBallMesh.position.setZ(lineLength)\n\n this.planeMesh.renderOrder = 0\n this.ringMesh.renderOrder = 1\n this.crossline.renderOrder = 2\n this.lineMesh.renderOrder = 3\n this.ballMesh.renderOrder = 4\n\n // 暂时移除 crossline,之后产品要再加上\n this.add(this.planeMesh, this.lineMesh, this.ballMesh, this.ringMesh, this.cssBallMesh)\n\n initialCSS3DRender(five)\n }\n\n public updateWithIntersect(intersect: Intersection) {\n if (!intersect.face) return\n\n const normal = (() => {\n const normal = intersect.face.normal.clone().normalize()\n // 地面\n if (normal.y > 0.99) return new THREE.Vector3(0, 1, 0)\n\n // 天花板\n if (normal.y < -0.99) return new THREE.Vector3(0, -1, 0)\n\n // 标准墙面\n if (normal.x > 0.99) return new THREE.Vector3(1, 0, 0)\n if (normal.x < -0.99) return new THREE.Vector3(-1, 0, 0)\n if (normal.z > 0.99) return new THREE.Vector3(0, 0, 1)\n if (normal.z < -0.99) return new THREE.Vector3(0, 0, -1)\n\n // 斜墙\n if (normal.y < 0.01 && normal.y > -0.01) return new THREE.Vector3(normal.x, 0, normal.z)\n\n return normal\n })()\n\n const lookAtPosition = new THREE.Vector3().addVectors(intersect.point, normal)\n this.position.copy(intersect.point)\n this.lookAt(lookAtPosition)\n }\n\n public show() {\n this.visible = true\n this.add(this.cssBallMesh)\n }\n\n public hide() {\n this.visible = false\n this.remove(this.cssBallMesh)\n }\n\n public dispose() {\n this.traverse((object) => {\n const mesh = object as THREE.Mesh\n mesh.geometry?.dispose()\n if (mesh.material) {\n const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material]\n materials.forEach((material) => material.dispose())\n }\n })\n this.cssBallMesh.element.remove()\n this.removeFromParent()\n }\n}\n","import * as THREE from 'three/webgpu'\nimport type { Five } from '@realsee/five-webgpu'\nimport { Magnifier, PointHelper } from '../..'\nimport type { Intersection } from '../../../../typings/typings'\nimport { Subscribe } from '../../../Subscribe'\nimport { PointHelper2 } from './PointHelper2'\nimport type { PointHelperAbstract } from './typing'\n\nexport interface PointSelectorHelperConfig {\n magnifier?: Magnifier | null\n magnifierParams?: ConstructorParameters<typeof Magnifier>[1]\n pointHelper?: PointHelperAbstract | 'default' | 'highlight' | null\n container?: Element\n skipPanorama?: boolean\n}\n\ntype EventMap = {\n intersectionUpdate: (intersection: PointIntersection) => void\n /** 功能开启 */\n enabled: () => void\n /** 功能关闭 */\n disabled: () => void\n}\n\nexport interface PointIntersection extends Intersection {\n /**\n * @description 被吸附\n */\n isAdsorbed?: boolean\n /**\n * @description 原始焦点\n */\n originalPoint?: THREE.Vector3\n /**\n * @description 虚拟生成的点\n */\n isVirtual?: boolean\n /**\n * @description 射线\n */\n raycaster?: THREE.Raycaster\n /**\n * @description 如果开启了吸附并且吸附到了平面,这里会有吸附的平面\n */\n adherePlane?: THREE.Plane\n /**\n * @description 如果开启了吸附并且吸附到了点,这里会有吸附的点\n */\n adherePoint?: THREE.Vector3\n /**\n * @description 如果开启了吸附并且吸附到了线,这里会有吸附的线\n */\n adhereLine?: THREE.Line3\n}\n\nexport class PointSelectorHelper {\n public five: Five\n public hooks = new Subscribe<EventMap>()\n public position: PointIntersection | null = null\n public magnifier: Magnifier | null = null\n public pointHelper: PointHelperAbstract | null = null\n public state = { enabled: false, visible: true }\n private group = new THREE.Group()\n\n public constructor(five: Five, options?: PointSelectorHelperConfig) {\n this.five = five\n\n this.magnifier =\n options?.magnifier !== undefined ? options.magnifier : new Magnifier(five, { dragEnabled: true, ...options?.magnifierParams, skipPanorama: options?.skipPanorama ?? false })\n\n let pointHelper: PointHelperAbstract | null = null\n if (options?.pointHelper === 'default' || options?.pointHelper === undefined) {\n pointHelper = new PointHelper(five)\n // pointHelper = new PointHelper2(five)\n } else if (options?.pointHelper === 'highlight') {\n pointHelper = new PointHelper2(five)\n } else if (options?.pointHelper === null) {\n pointHelper = null\n } else {\n pointHelper = options.pointHelper\n }\n this.pointHelper = pointHelper\n\n this.group.name = 'five-point-selector'\n this.five.scene.add(this.group)\n this.magnifier?.appendTo(options.container ?? five.getElement()?.parentElement ?? document.body)\n }\n\n public show = () => {\n if (this.state.visible) return\n this.state.visible = true\n this.pointHelper?.show()\n this.magnifier?.enable()\n this.five.needsRender = true\n }\n\n public hide = () => {\n if (!this.state.visible) return\n this.state.visible = false\n this.pointHelper?.hide()\n this.magnifier?.disable()\n this.five.needsRender = true\n }\n\n public enable() {\n if (this.state.enabled) return\n this.state.enabled = true\n if (this.pointHelper) {\n this.group.add(this.pointHelper)\n }\n this.magnifier?.enable()\n this.five.needsRender = true\n this.hooks.emit('enabled')\n }\n\n public disable() {\n if (!this.state.enabled) return\n this.state.enabled = false\n if (this.pointHelper) {\n this.group.remove(this.pointHelper)\n }\n this.magnifier?.disable()\n this.hooks.emit('disabled')\n }\n\n public dispose() {\n this.hooks.off()\n this.disable()\n this.abortUpdateMagnifier()\n this.magnifier?.dispose()\n this.magnifier = null\n this.pointHelper?.dispose()\n this.pointHelper = null\n this.group.removeFromParent()\n }\n\n public updateWithIntersect = (intersect?: Intersection, config: { emitEvent: boolean } = { emitEvent: true }) => {\n if (!intersect) return\n this.abortUpdateMagnifier()\n this.position = intersect\n if (config.emitEvent) this.hooks.emit('intersectionUpdate', intersect)\n\n // update pointer helper\n this.pointHelper?.updateWithIntersect(intersect)\n // update magnifier\n // 因为 Magnifier 的渲染依赖场景渲染 ,所以需要在场景渲染完成后再渲染 Magnifier\n const updateMagnifier = () => this.magnifier?.renderWithPoint(intersect.point)\n this.abortUpdateMagnifier = () => this.five.off('renderFrame', updateMagnifier)\n this.five.once('renderFrame', updateMagnifier)\n\n this.five.needsRender = true\n }\n\n private abortUpdateMagnifier: () => any = () => {}\n}\n","const navigatorTouchPoints = typeof navigator === 'undefined' ? 0 : navigator.maxTouchPoints || (navigator as any).msMaxTouchPoints || 0\n\nexport const isTouchDevice = typeof window !== 'undefined' && ('ontouchstart' in window || navigatorTouchPoints > 0)\n","import { Vector3, type Face } from 'three/webgpu'\n\nexport function createIntersectionFace(normal = new Vector3()): Face {\n return { a: 0, b: 0, c: 0, normal, materialIndex: 0 }\n}\n","import type { Five } from '@realsee/five-webgpu'\nimport * as THREE from 'three/webgpu'\n\nexport function getRaycasterByNdcPosition(five: Five, position: { x: number; y: number }) {\n const { x: left, y: top } = position\n const x = left * 2 - 1\n const y = top * 2 - 1\n const raycaster = new THREE.Raycaster()\n raycaster.setFromCamera(new THREE.Vector2(x, y), five.camera)\n raycaster.params.Points.threshold = 0.02\n return raycaster\n}\n","import * as THREE from 'three/webgpu'\nimport type { Five, Intersection } from '@realsee/five-webgpu'\nimport { getRaycasterByNdcPosition } from './getRaycasterByNdcPosition'\nimport { getFiveModel } from './getFiveModel'\nimport { createIntersectionFace } from '../three/createIntersectionFace'\n\ninterface IIntersection extends THREE.Intersection {\n raycaster: THREE.Raycaster\n isVirtual: boolean\n}\n\n/**\n * @description 根据 ndc 坐标获取 Intersect\n */\nexport function getIntersectByNdcPosition(\n five: Five,\n position: { x: number; y: number },\n config?: { virtualPoint?: boolean },\n): IIntersection | undefined {\n const raycaster = getRaycasterByNdcPosition(five, position)\n return getIntersectByRaycaster(five, raycaster, config)\n}\n\n/**\n * @description 根据射线获取 Intersect\n */\nexport function getIntersectByRaycaster(\n five: Five,\n raycaster: THREE.Raycaster,\n config?: { virtualPoint?: boolean },\n): IIntersection | undefined {\n const realIntersect = getRealIntersectByRaycaster(five, raycaster)\n if (!config?.virtualPoint) {\n return realIntersect\n } else {\n return realIntersect ?? getVirtualIntersectByRaycaster(raycaster)\n }\n}\n\nexport function getVirtualIntersectByRaycaster(raycaster: THREE.Raycaster, distance: number = 3): IIntersection {\n const position = new THREE.Vector3().addVectors(\n raycaster.ray.origin,\n raycaster.ray.direction.clone().normalize().multiplyScalar(distance),\n )\n const normal = raycaster.ray.direction.clone().negate()\n const virtualIntersect = {\n distance,\n point: position,\n object: new THREE.Object3D(),\n face: createIntersectionFace(normal),\n raycaster,\n isVirtual: true,\n }\n return virtualIntersect\n}\n\nexport function getRealIntersectByRaycaster(five: Five, raycaster: THREE.Raycaster): IIntersection {\n const model = getFiveModel(five)\n const intersects = model.intersectRaycaster(raycaster) as Intersection[]\n const intersect = intersects[0]\n if (intersect) {\n return { ...intersect, raycaster, isVirtual: false }\n }\n}\n","export const CURSOR_NOT_ALLOW_URL = `url(\"data:image/svg+xml,%3Csvg width='12px' height='12px' viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cpath d='M6,12 C9.3137085,12 12,9.3137085 12,6 C12,2.6862915 9.3137085,0 6,0 C2.6862915,0 0,2.6862915 0,6 C0,9.3137085 2.6862915,12 6,12 Z' fill='%23FF5959'%3E%3C/path%3E%3Cg transform='translate(2, 2)' stroke='%23FFFFFF'%3E%3Ccircle cx='4' cy='4' r='4'%3E%3C/circle%3E%3Cline x1='1.07141075' y1='1.23997894' x2='6.64700843' y2='6.81557662'%3E%3C/line%3E%3C/g%3E%3C/g%3E%3C/svg%3E\") 6 6, auto`\n","\n\n\n\n\nimport type { Five } from '@realsee/five-webgpu'\nimport { PointSelectorHelper, type PointIntersection, type PointSelectorHelperConfig } from './utils/PointSelectorHelper'\nimport { isTouchDevice } from '../../isTouchDevice'\nimport type { MagnifierParameter } from '../Magnifier'\nimport type { Intersection, Vector3 } from 'three/webgpu'\nimport * as THREE from 'three/webgpu'\nimport { createIntersectionFace } from '../createIntersectionFace'\nimport { Subscribe } from '../../Subscribe'\nimport { getIntersectByRaycaster, getVirtualIntersectByRaycaster } from '../../five/getPosition'\nimport { getRaycasterByNdcPosition } from '../../five/getRaycasterByNdcPosition'\nimport type { LiteralString } from '../../../typings/utils.type'\nimport { CURSOR_NOT_ALLOW_URL } from './utils/contents'\nimport { rayOnLine } from '../../../Sculpt/utils/three/rayOnLine'\nimport { THREERaycaster } from '../core/Raycaster'\n\nexport type { PointIntersection }\n\nconst _vector3 = new THREE.Vector3()\n\nconst disableFiveEvent = (): false => false\n\nexport type ActionIfNoIntersection = LiteralString<'virtualPoint' | 'lastPoint' | 'disable'>\n\nexport type AdherePoint = Vector3 & {\n normal?: THREE.Vector3\n /**\n * @description 被模型遮挡也能看到的点\n */\n IsAlwaysVisible?: boolean\n}\n\ntype PointerSelectorMode = 'fixed' | 'cursor'\n\ninterface Config {\n /**\n * @description: 选点的两种模式, 'fixed' 为固定选点为屏幕中心点,拖动five画布来更新点,'cursor' 为跟随鼠标移动来更新点, 'auto' 则根据设备类型自动选择\n * @default: 'auto'\n */\n mode: PointerSelectorMode | 'auto'\n /**\n * @description 当鼠标位置没有模型时的行为\n * ```markdown\n * virtualPoint: 生成一个虚拟点\n * lastPoint: 选点器停留在上一个点处\n * disable: 禁止选点\n * ```\n * @default 'virtualPoint'\n */\n actionIfNoIntersection: ActionIfNoIntersection\n helper: PointSelectorHelperConfig\n /**\n * @description 是否跳过全景图渲染\n * @default false\n */\n skipPanorama: boolean\n /**\n * five 6.7.0 特性,可配置是否自定义拾取点过滤函数\n */\n hitFilter?: (intersect: Intersection) => boolean\n}\n\nexport type PointSelectorConfig = Partial<Config>\n\ntype EventMap = {\n /**\n * @description 与模型交点更新时触发,移出监听范围时为null\n */\n intersectionUpdate: (intersection?: PointIntersection | null) => void\n /**\n * @description 试图打点,返回false则不打点\n */\n wantsSelect: (intersection?: PointIntersection | null) => boolean | void\n /**\n * @description 打点成功\n */\n select: (intersection?: PointIntersection | null) => void\n /**\n * @description 功能开启\n */\n enable: () => void\n /**\n * @description 功能关闭\n */\n disable: () => void\n}\n\n/**\n * @description: 在屏幕上选点\n */\nexport class PointSelector extends Subscribe<EventMap> {\n public get position() {\n if (this.outOfFive) return undefined\n return this.pointSelectorHelper.position\n }\n\n /**\n * @description: 不在 five canvas 上时为 true\n */\n public get outOfFive() {\n return this._outOfFive\n }\n\n public get enabled() {\n return this._enabled\n }\n\n public get cursorError() {\n return this._cursorError\n }\n\n public set cursorError(cursorError: boolean) {\n this._cursorError = cursorError\n this.five.getElement().style.cursor = cursorError ? CURSOR_NOT_ALLOW_URL : ''\n cursorError ? this.pointSelectorHelper.hide() : this.pointSelectorHelper.show()\n }\n\n public _cursorError = false\n\n public actionIfNoIntersection: ActionIfNoIntersection = 'virtualPoint'\n\n public plane?: THREE.Plane | null\n\n /**\n * @description 结果区别:vertical: 射线和模型的交点在plane上的投影点;onlyPlane: 不论射线和模型是否有交点,都为射线和plane的焦点;onlyVirtual: 仅当射线和模型没有交点时,为射线和plane的焦点\n */\n public planeMode: 'vertical' | 'onlyPlane' | 'onlyVirtual' = 'onlyVirtual'\n\n /**\n * @description 射线没有命中模型时,是否一律禁止点选\n * @default false\n */\n public disableIfNoIntersection = false\n\n public readonly pointSelectorHelper: PointSelectorHelper\n\n public five: Five\n\n /**\n * @description 吸附功能总开关,方便临时的一键开启/关闭\n */\n private adhereEnabled = true\n\n /**\n * @description 吸附半径\n */\n public adhereRadius = 0.1\n\n /**\n * @description 吸附面\n */\n public adherePlane: THREE.Plane[] = []\n\n /**\n * @description 吸附线\n */\n public adhereLine: THREE.Line3[] = []\n\n private set outOfFive(outOfFive: boolean) {\n this._outOfFive = outOfFive\n }\n private _outOfFive = false\n\n private set enabled(enabled: boolean) {\n this._enabled = enabled\n }\n private _enabled = false\n\n private mode: PointerSelectorMode\n\n /** 长按屏幕的动作触发后为true,手指抬起后为false */\n private pressDown = false\n\n /** 一组吸附的点,光标靠近这些点时,会将helper以及放大镜的位置设置为这些点 */\n private adherePoints: ((params: { intersection: PointIntersection; pointSelectorInstance: PointSelector }) => AdherePoint[]) | null\n\n /** 有值时表明处于按压检查阶段 */\n private setPressDown?: ReturnType<typeof setTimeout>\n\n private lastFiveHelperVisible?: boolean\n\n private lastIntersection?: PointIntersection\n\n private mousePosition: { clientX: number; clientY: number } | null\n\n private _mouseDownInfo: { clientX: number; clientY: number; timestamp: number } | null\n\n private _touchStartInfo: { clientX: number; clientY: number; timestamp: number } | null\n\n private config: PointSelectorConfig = {}\n\n private get mouseNdcPosition(): { x: number; y: number } | null {\n if (!this.mousePosition) return null\n return this.mousePositionToNdcPosition(this.mousePosition)\n }\n\n public constructor(five: Five, config?: PointSelectorConfig) {\n super()\n this.five = five\n\n this.config = { ...this.config, ...config }\n\n this.actionIfNoIntersection = config?.actionIfNoIntersection ?? 'virtualPoint'\n\n const mode = config?.mode ?? 'auto'\n if (mode === 'auto') {\n this.mode = isTouchDevice ? 'fixed' : 'cursor'\n } else {\n this.mode = mode\n }\n\n const defaultMagnifierParams: MagnifierParameter = {\n autoFixPCPosition: this.mode === 'cursor',\n initialPosition: this.mode === 'fixed' ? { left: '35%', top: '20%' } : undefined,\n }\n\n this.pointSelectorHelper = new PointSelectorHelper(this.five, {\n ...config?.helper,\n magnifierParams: {\n ...defaultMagnifierParams,\n ...config?.helper?.magnifierParams,\n },\n skipPanorama: config?.skipPanorama ?? false,\n })\n\n // 刚开始的时候,因为没有选点,所以不显示,后面鼠标移动了或者点了之后才显示\n this.pointSelectorHelper.hide()\n }\n\n public enable() {\n if (this.enabled) return\n this.enabled = true\n\n // 设置一些初始化的值\n this.outOfFive = false\n\n this.pointSelectorHelper.enable()\n // 刚开始的时候,因为没有选点,所以不显示,后面鼠标移动了或者点了之后才显示\n this.pointSelectorHelper.hide()\n\n const fiveElement = this.five.getElement()\n\n if (!fiveElement) throw new Error('five element not found')\n\n // 添加一堆监听\n if (this.mode === 'cursor') {\n // 鼠标选点 / 触摸屏选点\n\n this.five.on('wantsMoveToPano', disableFiveEvent)\n this.five.on('wantsChangeMode', disableFiveEvent)\n this.five.on('wantsTapGesture', disableFiveEvent)\n\n // touch 设备事件\n fiveElement.addEventListener('touchstart', this.onTouchStart, { passive: true })\n fiveElement.addEventListener('touchmove', this.onTouchMove)\n fiveElement.addEventListener('touchend', this.onTouchEnd)\n fiveElement.addEventListener('touchcancel', this.onTouchCancel)\n // PC 设备事件\n fiveElement.addEventListener('mousedown', this.onMouseDown)\n fiveElement.addEventListener('mouseup', this.onMouseUp)\n fiveElement.addEventListener('mousemove', this.updateByMousePosition)\n fiveElement.addEventListener('wheel', this.onMouseWheel)\n fiveElement.addEventListener('mouseenter', this.onMouseEnter)\n fiveElement.addEventListener('mouseout', this.onMouseLeave)\n\n this.five.on('wantsPanGesture', this.onFiveWantsPanGesture)\n } else if (this.mode === 'fixed') {\n // 固定在屏幕中心的\n this.five.on('panoArrived', this.renderScreenCenter)\n this.five.on('panGesture', this.renderScreenCenter)\n this.five.on('interiaPan', this.renderScreenCenter)\n this.renderScreenCenter() // enable 时,自动加载屏幕中心点, 而不是动一下屏幕才加载\n this.pointSelectorHelper.show()\n }\n\n // shared\n document.addEventListener('keydown', this.onKeyDown)\n document.addEventListener('keyup', this.onKeyUp)\n this.pointSelectorHelper.hooks.on('intersectionUpdate', this.emitIntersectionUpdate)\n this.lastFiveHelperVisible = this.five.helperVisible\n this.five.helperVisible = false\n\n this.emit('enable')\n }\n\n public disable() {\n this.onTouchCancel()\n if (!this.enabled) return\n this.enabled = false\n\n this.adherePoints = null\n this.adhereLine = []\n this.adherePlane = []\n this.plane = undefined\n\n this.pointSelectorHelper.disable()\n this.five.getElement().style.cursor = ''\n\n // 移除一堆监听\n const fiveElement = this.five.getElement()\n this.five.off('wantsPanGesture', this.onFiveWantsPanGesture)\n this.five.off('wantsMoveToPano', disableFiveEvent)\n this.five.off('wantsChangeMode', disableFiveEvent)\n this.five.off('wantsTapGesture', disableFiveEvent)\n\n this.five.helperVisible = this.lastFiveHelperVisible\n\n fiveElement?.removeEventListener('touchstart', this.onTouchStart)\n fiveElement?.removeEventListener('touchmove', this.onTouchMove)\n fiveElement?.removeEventListener('touchend', this.onTouchEnd)\n fiveElement?.removeEventListener('touchcancel', this.onTouchCancel)\n\n fiveElement?.removeEventListener('mousedown', this.onMouseDown)\n fiveElement?.removeEventListener('mouseup', this.onMouseUp)\n fiveElement?.removeEventListener('mousemove', this.updateByMousePosition)\n fiveElement?.removeEventListener('wheel', this.onMouseWheel)\n fiveElement?.removeEventListener('mouseenter', this.onMouseEnter)\n fiveElement?.removeEventListener('mouseout', this.onMouseLeave)\n\n this.five.off('panoArrived', this.renderScreenCenter)\n this.five.off('panGesture', this.renderScreenCenter)\n this.five.off('interiaPan', this.renderScreenCenter)\n\n document.removeEventListener('keydown', this.onKeyDown)\n document.removeEventListener('keyup', this.onKeyUp)\n this.pointSelectorHelper.hooks.off('intersectionUpdate', this.emitIntersectionUpdate)\n\n this.emit('disable')\n }\n\n public dispose() {\n this.disable()\n this.pointSelectorHelper.dispose()\n this.off()\n }\n\n public setAdherePoints(\n points: AdherePoint[] | ((params: { intersection: PointIntersection; pointSelectorInstance: PointSelector }) => AdherePoint[]) | null,\n ) {\n if (!points) {\n this.adherePoints = null\n } else if (typeof points === 'function') {\n this.adherePoints = points\n } else {\n this.adherePoints = () => points\n }\n }\n\n /**\n * @description: 主动触发一次选点\n * @return: select 是否成功\n */\n public select = (intersection?: PointIntersection) => {\n if (intersection) this.updatePointSelectorHelperIntersect(intersection)\n\n const cancel = this.emit('wantsSelect', this.position)\n if (!cancel) {\n this.pointSelectorHelper.hide()\n this.emit('select', this.position)\n console.debug(this.position)\n }\n return !cancel\n }\n\n private onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Shift') this.adhereEnabled = false\n }\n\n private onKeyUp = (e: KeyboardEvent) => {\n if (e.key === 'Shift') this.adhereEnabled = true\n }\n\n private onMouseWheel = (e: MouseEvent) => {\n this.updateByMousePosition(e)\n\n const render = () => this.updateByMousePosition()\n this.five.off('render.prepare', render)\n this.five.on('render.prepare', render)\n setTimeout(() => {\n this.five.off('render.prepare', render)\n }, 200)\n }\n\n /**\n * @description: 鼠标进入five canvas时\n */\n private onEnter = () => {\n if (!this.cursorError) {\n this.pointSelectorHelper.show()\n }\n this.outOfFive = false\n }\n\n /**\n * @description: 鼠标进入five canvas时\n */\n private onMouseEnter = () => {\n this.onEnter()\n this.emit('intersectionUpdate', this.position)\n }\n\n /**\n * @description: 鼠标离开five canvas时\n */\n private onMouseLeave = () => {\n this.pointSelectorHelper.hide()\n this.outOfFive = true\n this.emit('intersectionUpdate', undefined)\n }\n\n private onMouseDown = (e: MouseEvent) => {\n this._mouseDownInfo = {\n clientX: e.clientX,\n clientY: e.clientY,\n timestamp: performance.now(),\n }\n }\n\n private onMouseUp = (e: MouseEvent) => {\n if (!this._mouseDownInfo) return\n\n const { clientX, clientY, timestamp } = this._mouseDownInfo\n\n if (Math.abs(e.clientX - clientX) < 2 && Math.abs(e.clientY - clientY) < 2 && performance.now() - timestamp < 500) {\n this.select()\n } else {\n this._mouseDownInfo = null\n }\n }\n\n private onTouchCancel = () => {\n if (this.setPressDown) clearTimeout(this.setPressDown)\n this.setPressDown = undefined\n this.pressDown = false\n this._touchStartInfo = null\n }\n\n private onTouchStart = (e: TouchEvent) => {\n this.onTouchCancel()\n if (e.touches.length !== 1) return\n this._touchStartInfo = {\n clientX: e.touches[0].clientX,\n clientY: e.touches[0].clientY,\n timestamp: performance.now(),\n }\n\n this.setPressDown = setTimeout(() => {\n this.setPressDown = undefined\n\n // 触发长按事件\n this.mousePosition = {\n clientX: e.touches[0].clientX,\n clientY: e.touches[0].clientY,\n }\n if (!this.mouseNdcPosition) return\n const success = this.updateByNdcPosition(this.mouseNdcPosition)\n this.pressDown = success\n }, 200)\n }\n\n private onTouchMove = (e: TouchEvent) => {\n if (e.touches.length !== 1) { this.onTouchCancel(); return }\n if (this.setPressDown) {\n let moved = false\n\n if (this._touchStartInfo) {\n const { clientX, clientY } = this._touchStartInfo\n if (Math.abs(e.touches[0].clientX - clientX) > 2 || Math.abs(e.touches[0].clientY - clientY) > 2) {\n moved = true\n }\n }\n\n if (moved) {\n clearTimeout(this.setPressDown)\n this.setPressDown = undefined\n }\n\n return\n }\n\n // 触发拖动事件\n if (this.pressDown) {\n this.mousePosition = {\n clientX: e.touches[0].clientX,\n clientY: e.touches[0].clientY,\n }\n if (!this.mouseNdcPosition) return\n this.updateByNdcPosition(this.mouseNdcPosition)\n }\n }\n\n private onTouchEnd = (e: TouchEvent) => {\n if (this.setPressDown) {\n clearTimeout(this.setPressDown)\n this.setPressDown = undefined\n return\n }\n\n // 触发完成事件\n if (this.pressDown) {\n setTimeout(() => {\n this.pressDown = false\n }, 100) // 慢点结束,不然有可能触发five事件\n this.select()\n }\n }\n\n private updateByMousePosition = (event?: MouseEvent) => {\n const fiveElement = this.five.getElement()\n if (!fiveElement) return\n\n if (!event || event?.buttons !== 0) {\n this.pointSelectorHelper.hide()\n // 鼠标按下时不更新\n return\n } else {\n this.pointSelectorHelper.show()\n }\n\n if (event) {\n this.mousePosition = {\n clientX: event.clientX,\n clientY: event.clientY,\n }\n }\n\n this.updateByNdcPosition(this.mouseNdcPosition)\n }\n\n /**\n * @description: 根据鼠标位置计算焦点位置并更新\n */\n private updateByNdcPosition = (ndcPosition: { x: number; y: number }) => {\n const raycaster = getRaycasterByNdcPosition(this.five, ndcPosition)\n\n if (this.config.hitFilter) {\n raycaster.hitFilter = this.config.hitFilter\n }\n\n let realIntersection: PointIntersection = getIntersectByRaycaster(this.five, raycaster)\n if (realIntersection) {\n if (this.plane && this.planeMode === 'vertical') {\n realIntersection = {\n ...realIntersection,\n point: this.plane.projectPoint(realIntersection.point, new THREE.Vector3()),\n face: createIntersectionFace(this.plane.normal.clone()),\n originalPoint: realIntersection.point.clone(),\n }\n }\n\n if (this.plane && this.planeMode === 'onlyPlane') {\n const intersectionPoint = raycaster.ray.intersectPlane(this.plane, _vector3)\n if (!intersectionPoint) return false\n realIntersection = {\n distance: this.five.camera.position.distanceTo(intersectionPoint),\n point: intersectionPoint.clone(),\n originalPoint: realIntersection.point.clone(),\n face: createIntersectionFace(this.plane.normal.clone()),\n raycaster,\n }\n }\n\n this.updatePointSelectorHelperIntersect(realIntersection)\n this.lastIntersection = realIntersection\n\n return true\n }\n\n if (this.disableIfNoIntersection) {\n this.updatePointSelectorHelperIntersect(null)\n return false\n }\n if (this.plane) {\n const intersectionPoint = raycaster.ray.intersectPlane(this.plane, _vector3)\n if (intersectionPoint) {\n const virtualIntersection = {\n distance: this.five.camera.position.distanceTo(intersectionPoint),\n point: intersectionPoint.clone(),\n object: new THREE.Object3D(),\n face: createIntersectionFace(this.plane.normal.clone()),\n raycaster,\n isVirtual: true,\n }\n this.updatePointSelectorHelperIntersect(virtualIntersection)\n return true\n }\n }\n\n if (this.actionIfNoIntersection === 'lastPoint') {\n this.updatePointSelectorHelperIntersect(this.lastIntersection)\n return true\n } else if (this.actionIfNoIntersection === 'virtualPoint') {\n const virtualIntersection = getVirtualIntersectByRaycaster(raycaster, this.lastIntersection?.distance)\n virtualIntersection.face = createIntersectionFace(this.lastIntersection?.face?.normal)\n virtualIntersection.isVirtual = true\n this.lastIntersection = virtualIntersection\n this.updatePointSelectorHelperIntersect(virtualIntersection)\n return true\n } else if (this.actionIfNoIntersection === 'disable') {\n this.updatePointSelectorHelperIntersect(null)\n return false\n }\n }\n\n /**\n * @description: 更新 pointSelectorHelper 的焦点位置\n */\n private updatePointSelectorHelperIntersect = (intersect?: PointIntersection | null) => {\n if (!intersect) {\n this.pointSelectorHelper.hide()\n this.pointSelectorHelper.position = intersect\n this.emit('intersectionUpdate', intersect)\n this.five.getElement().style.cursor = CURSOR_NOT_ALLOW_URL\n return\n }\n\n this.onEnter()\n if (!this.cursorError) this.five.getElement().style.cursor = ''\n\n // 有吸附点的话,就吸附到最近的点.adherePoints\n const targetIntersect = { ...intersect }\n\n if (this.adhereEnabled && this.mouseNdcPosition && this.five.renderer) {\n const mouseNdcPosition = {\n x: this.mouseNdcPosition.x,\n y: 1 - this.mouseNdcPosition.y,\n }\n const size = this.five.renderer!.getSize(new THREE.Vector2())\n\n if (this.adhereEnabled && typeof this.adherePoints === 'function' && typeof this.adhereRadius === 'number') {\n // // ========== 吸附面 ==========\n for (const adherePlane of this.adherePlane) {\n const distance = adherePlane.distanceToPoint(intersect.point)\n let newPoint = adherePlane.projectPoint(intersect.point, new THREE.Vector3())\n if (!this.plane || this.plane.distanceToPoint(newPoint) < 0.01) {\n newPoint = this.plane?.projectPoint(newPoint, new THREE.Vector3()) ?? newPoint\n if (distance < this.adhereRadius) {\n targetIntersect.point = newPoint.clone()\n targetIntersect.adherePoint = newPoint.clone()\n if (!this.plane) {\n targetIntersect.face = createIntersectionFace(adherePlane.normal.clone())\n }\n targetIntersect.isAdsorbed = true\n }\n }\n }\n\n // ========== 吸附线 ==========\n for (const adhereLine of this.adhereLine) {\n let newPoint = adhereLine.closestPointToPoint(intersect.point, false, new THREE.Vector3())\n if (newPoint.distanceTo(intersect.point) < this.adhereRadius) {\n if (!this.plane || this.plane.distanceToPoint(newPoint) < 0.01) {\n newPoint = this.plane?.projectPoint(newPoint, new THREE.Vector3()) ?? newPoint\n targetIntersect.point = newPoint.clone()\n targetIntersect.adhereLine = adhereLine.clone()\n targetIntersect.isAdsorbed = true\n }\n } else {\n const closestPoint = rayOnLine({\n raycaster: new THREERaycaster(this.five.camera.position, intersect.point.clone().sub(this.five.camera.position).normalize()),\n line: adhereLine,\n clampToLine: false,\n })\n const projectPoint = closestPoint.clone().project(this.five.camera)\n if (projectPoint.z <= 1) {\n const ndcPosition = {\n x: (projectPoint.x + 1) / 2,\n y: (1 - projectPoint.y) / 2,\n }\n\n const positionOffset = {\n x: Math.abs(ndcPosition.x - mouseNdcPosition.x) * size.width,\n y: Math.abs(ndcPosition.y - mouseNdcPosition.y) * size.height,\n }\n\n let newPoint = closestPoint.clone()\n if (positionOffset.x < 10 && positionOffset.y < 10) {\n if (!this.plane || this.plane.distanceToPoint(newPoint) < 0.01) {\n newPoint = this.plane?.projectPoint(newPoint, new THREE.Vector3()) ?? newPoint\n targetIntersect.point = newPoint.clone()\n targetIntersect.adhereLine = adhereLine.clone()\n targetIntersect.isAdsorbed = true\n }\n }\n }\n }\n }\n\n // ========== 吸附点 ==========\n for (const _point of this.adherePoints({ intersection: intersect, pointSelectorInstance: this })) {\n const point = _point\n point.IsAlwaysVisible = _point.IsAlwaysVisible\n\n if (this.plane && this.plane.distanceToPoint(point) > 0.01) continue\n\n const distance = point.distanceTo(intersect.point)\n if (distance < this.adhereRadius) {\n // 1. 距离吸附判断\n targetIntersect.point = this.plane?.projectPoint(point, new THREE.Vector3()) ?? point.clone()\n if (!this.plane && _point.normal) targetIntersect.face = createIntersectionFace(_point.normal)\n targetIntersect.isAdsorbed = true\n\n break\n } else {\n // 2. 屏幕位置吸附判断\n const projectPoint = point.clone().project(this.five.camera)\n if (projectPoint.z > 1) continue // 屏幕外的点不吸附\n const size = this.five.renderer!.getSize(new THREE.Vector2())\n\n const ndcPosition = {\n x: (projectPoint.x + 1) / 2,\n y: (1 - projectPoint.y) / 2,\n }\n\n const positionOffset = {\n x: Math.abs(ndcPosition.x - mouseNdcPosition.x) * size.width,\n y: Math.abs(ndcPosition.y - mouseNdcPosition.y) * size.height,\n }\n\n if (positionOffset.x < 10 && positionOffset.y < 10) {\n // 2.1 满足屏幕位置吸附条件,还需要判断点是否可见\n let pointIsVisible = false\n if (point.IsAlwaysVisible) {\n pointIsVisible = true\n } else {\n // 碰撞检测\n const raycaster = new THREE.Raycaster()\n raycaster.setFromCamera(new THREE.Vector2(ndcPosition.x, ndcPosition.y), this.five.camera)\n const intersect = this.five.model.intersectRaycaster(raycaster)[0]\n const distanceError = 0.1\n const cameraToPointDistance = this.five.camera.position.distanceTo(point)\n if (intersect && intersect.distance < cameraToPointDistance + distanceError) {\n pointIsVisible = true\n }\n }\n\n if (pointIsVisible) {\n targetIntersect.point = point.clone()\n if (!this.plane && _point.normal) {\n targetIntersect.face = createIntersectionFace(_point.normal)\n }\n targetIntersect.isAdsorbed = true\n break\n }\n }\n }\n }\n }\n }\n this.pointSelectorHelper.updateWithIntersect(targetIntersect, { emitEvent: false }) // 关掉pointSelectorHelper的事件,自己手动触发,否则会触发两次\n this.emit('intersectionUpdate', targetIntersect)\n }\n\n private mousePositionToNdcPosition = (mousePosition: { clientX: number; clientY: number }) => {\n const fiveElement = this.five.getElement()\n if (!fiveElement) return null\n\n const { top, left, width, height } = fiveElement.getBoundingClientRect()\n\n const { clientX: mouseX, clientY: mouseY } = mousePosition\n return {\n x: (mouseX - left) / width,\n y: 1 - (mouseY - top) / height,\n }\n }\n\n private onFiveWantsPanGesture = (): false | void => {\n if (this.pressDown) return false\n }\n\n private renderScreenCenter = () => {\n this.updateByNdcPosition({ x: 0.5, y: 0.5 })\n }\n\n private emitIntersectionUpdate = (intersection: PointIntersection) => {\n this.emit('intersectionUpdate', intersection)\n }\n}\n","/** PointHelper 纹理贴图 */\nexport const POINT_HELPER_TEXTURE_URL = `data:image/png;base64,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`\n\nexport const POINT_DOM_HELPER_IMAGE =\n 'data:image/svg+xml;base64,PHN2ZwogIHdpZHRoPSI2NyIKICBoZWlnaHQ9IjY3IgogIHZpZXdCb3g9IjAgMCA2NyA2NyIKICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCj4KICA8ZGVmcz4KICAgIDxsaW5lYXJHcmFkaWVudCB4MT0iNTAlIiB5MT0iMCUiIHgyPSI1MCUiIHkyPSIxMDAlIiBpZD0iYSI+CiAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIG9mZnNldD0iMCUiIC8+CiAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIHN0b3Atb3BhY2l0eT0iLjM5NiIgb2Zmc2V0PSIxMDAlIiAvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICAgIDxsaW5lYXJHcmFkaWVudCB4MT0iNTAlIiB5MT0iMCUiIHgyPSI1MCUiIHkyPSIxMDAlIiBpZD0iYiI+CiAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIG9mZnNldD0iMCUiIC8+CiAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIG9mZnNldD0iMTAwJSIgLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CiAgPC9kZWZzPgogIDxwYXRoCiAgICBkPSJNMzQuOTAzIDc0LjI2OGEyOS45NjMgMjkuOTYzIDAgMCAwIDExLjY0OCAyLjM0YzMuOTE4IDAgNy42Ni0uNzUgMTEuMDkzLTIuMTEzbDEuOTc2IDEuOTc3YTMyLjUzMSAzMi41MzEgMCAwIDEtMTMuMDY5IDIuNzIgMzIuNTIgMzIuNTIgMCAwIDEtMTMuNjA5LTIuOTYzek03Ni4wNSAzMy4zMzNjLjkxIDEuMzQ3IDEuMjIyIDIuMTM5IDEuNDIyIDIuNzI4YTMyLjYwMiAzMi42MDIgMCAwIDEgMS43MjIgMTAuNDljMCAzLjg0OS0uNjY2IDcuNTQyLTEuODkgMTAuOTdhMzUuMzQgMzUuMzQgMCAwIDEtLjc4IDEuOTQ0LjUwOC41MDggMCAwIDEtLjYzLjI4M2wtMS4yOTktMS4yMjdjLjEzNi0xLjQ5Ni4zNTEtMi4wNzYuNDktMi40OTVhMzAuMDI3IDMwLjAyNyAwIDAgMCAxLjUyNC05LjQ3NSAzMC4wNCAzMC4wNCAwIDAgMC0xLjQwOC05LjExNiAzNi4xODMgMzYuMTgzIDAgMCAwLS43Ni0yLjA4NWwxLjI2Ni0xLjg4NGEuNTA4LjUwOCAwIDAgMSAuMzQzLS4xMzN6bS01OS40MzQuNTgxbDEuNjczIDEuMjNjLS4wODUgMS40LS4yNjcgMS45MTYtLjM4NiAyLjI5YTMwLjA0IDMwLjA0IDAgMCAwLTEuNDA4IDkuMTE3YzAgMy4yNDcuNTE1IDYuMzc0IDEuNDY4IDkuMzAzLjEwNy4zMy4yNjguNzguNDggMS4zNDZsLTEuMjg0IDEuODkzYS41MDcuNTA3IDAgMCAxLS42NzQuMDExYy0uNDI2LS44OTMtLjYzLTEuNDIxLS43Ny0xLjgyNWEzMi41OTQgMzIuNTk0IDAgMCAxLTEuODA0LTEwLjcyOGMwLTMuODY3LjY3Mi03LjU3NiAxLjkwNi0xMS4wMTguMTIzLS4zNDUuMjk4LS43OTEuNTI1LTEuMzQyYS41MDYuNTA2IDAgMCAxIC4yNzQtLjI3N3pNNDYuNTUxIDEzLjkxYzMuNzM1IDAgNy4zMjQuNjI3IDEwLjY2NyAxLjc4Mi40MjcuMTQ4Ljk5MS4zNjUgMS42OS42NTFsLS45NSAxLjk0NGMtMS41NzctLjE0NC0yLjIyMy0uMzY4LTIuNjg4LS41MDhhMzAuMDU2IDMwLjA1NiAwIDAgMC04LjcxOS0xLjI4NWMtMy41NSAwLTYuOTU3LjYxNi0xMC4xMTkgMS43NDYtLjI2OS4wOTctLjYyOS4yMzUtMS4wNzkuNDE1bC0xLjg5OC0xLjI3Yy42NjQtMS4wMjIgMS4wMzUtMS4xNzYgMS4zMjUtMS4yODlhMzIuNDUzIDMyLjQ1MyAwIDAgMSA4Ljc3LTIuMDVjLjk4OS0uMDkgMS45OS0uMTM2IDMuMDAxLS4xMzZ6IgogICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEyLjcxOCAtMTIuNzE4KSIKICAgIGZpbGw9InVybCgjYSkiCiAgICBzdHJva2U9InVybCgjYikiCiAgICBzdHJva2Utd2lkdGg9Ii41NSIKICAgIGZpbGwtcnVsZT0iZXZlbm9kZCIKICAgIG9wYWNpdHk9Ii42IgogIC8+Cjwvc3ZnPgo='\n","export const rangePieceImg =\n 'data:image/png;base64,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'\n\nexport const rangePieceIntersectImg =\n 'data:image/png;base64,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'\n\nexport default `\n <style>\n .range-piece__container {\n position: absolute;\n top: 39%;\n left: 50%;\n margin-left: -54px;\n width: 108px;\n height: 108px;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: pieceContainer 0.3s ease-in-out;\n animation-fill-mode: forwards;\n }\n .range-piece__content {\n width: 100%;\n height: 100%;\n background-image: url(${rangePieceImg});\n opacity: 0.4;\n background-size: 100%;\n background-repeat: no-repeat;\n transition: linear transform 0.1s;\n }\n .range-piece__content--active {\n animation: dotting ease-in-out 0.5s;\n }\n .range-piece__aim {\n width: 100%;\n height: 100%;\n opacity: 1;\n position: absolute;\n background: url(${rangePieceIntersectImg}) center / contain no-repeat;\n }\n @keyframes dotting {\n 0% {\n opacity: 0.4;\n transform: scale(1);\n }\n 50% {\n opacity: 1;\n transform: scale(0.8);\n }\n 100% {\n opacity: 0.4;\n transform: scale(1);\n }\n }\n @keyframes pieceContainer {\n from {\n top: 49%;\n }\n to {\n top: 39%;\n }\n }\n </style>\n <div class=\"range-piece__container\">\n <div class='range-piece__content'></div>\n <div class=\"range-piece__aim\"></div>\n </div>\n`\n","import * as THREE from 'three/webgpu'\nimport { POINT_HELPER_TEXTURE_URL } from '../../Assets'\nimport type { Intersection } from '../../../../typings/typings'\nimport type { PointHelperAbstract } from './typing'\nimport { CSS3DObjectPlus } from '../../../../CSS3DRenderPlugin/utils/three/CSS3DObject'\nimport { rangePieceImg } from './html'\nimport { initialCSS3DRender } from '../../../five/initialCSS3DRender'\nimport type { Five } from '@realsee/five-webgpu'\n\n\nexport interface MouseGroupParameter {\n isMobile?: boolean\n useNormalVector?: boolean // 是否展示法向量\n ballColor?: number // 法向量小球色值\n}\n\nfunction createPlaneMesh() {\n // TODO: 改成参数传入\n // 底部纹理贴图面片\n const planGeometry = new THREE.PlaneGeometry(0.4, 0.4)\n const planTextureUrl = POINT_HELPER_TEXTURE_URL\n const planTexture = new THREE.TextureLoader().load(planTextureUrl)\n planTexture.colorSpace = THREE.SRGBColorSpace\n planTexture.minFilter = THREE.LinearFilter\n const planMaterial = new THREE.MeshBasicMaterial({\n map: planTexture,\n transparent: true,\n depthTest: false,\n })\n const planMesh = new THREE.Mesh(planGeometry, planMaterial)\n return planMesh\n}\n\nfunction createLineMesh() {\n // 法向量垂直管\n const zPath = new THREE.CurvePath<THREE.Vector3>()\n zPath.add(new THREE.LineCurve3(new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, 0.1)))\n const zGeometry = new THREE.TubeGeometry(zPath, 8, 0.003)\n const colors = new Float32Array(zGeometry.getAttribute('position').count * 4)\n const uv = zGeometry.getAttribute('uv')\n for (let i = 0; i < uv.count; i++) colors.set([1, 1, 1, 1 - uv.getX(i)], i * 4)\n zGeometry.setAttribute('color', new THREE.BufferAttribute(colors, 4))\n const zMaterial = new THREE.MeshBasicMaterial({\n vertexColors: true,\n depthTest: false,\n transparent: true,\n })\n const zMesh = new THREE.Mesh(zGeometry, zMaterial)\n return zMesh\n}\n\nfunction createBallMesh() {\n // 法向量圆球\n const ballGeometry = new THREE.SphereGeometry(0.01, 20, 20)\n const ballMaterial = new THREE.MeshBasicMaterial({\n color: 0x9ded6b,\n depthTest: false,\n transparent: true,\n side: THREE.DoubleSide,\n })\n const ballMesh = new THREE.Mesh(ballGeometry, ballMaterial)\n ballMesh.position.set(0, 0, 0.1)\n return ballMesh\n}\n\nfunction createBorderMesh() {\n const radius = 0.2\n const borderMesh = new CSS3DObjectPlus({\n pointerEvents: 'none',\n cornerPoints: [\n new THREE.Vector3(-radius, radius, 0),\n new THREE.Vector3(-radius, -radius, 0),\n new THREE.Vector3(radius, -radius, 0),\n new THREE.Vector3(radius, radius, 0),\n ],\n })\n\n const contentElement = document.createElement('div')\n contentElement.style.width = '100%'\n contentElement.style.height = '100%'\n contentElement.style.backgroundImage = `url(${rangePieceImg})`\n contentElement.style.backgroundSize = '100%'\n contentElement.style.backgroundRepeat = 'no-repeat'\n\n borderMesh.container.appendChild(contentElement)\n\n return borderMesh\n}\n\ntype PlanMesh = ReturnType<typeof createPlaneMesh>\ntype LineMesh = ReturnType<typeof createLineMesh>\ntype BallMesh = ReturnType<typeof createBallMesh>\ntype BorderMesh = ReturnType<typeof createBorderMesh>\n\nexport class PointHelper extends THREE.Object3D implements PointHelperAbstract {\n public planeMesh: PlanMesh\n public lineMesh: LineMesh\n public ballMesh: BallMesh\n public borderMesh: BorderMesh\n private five: Five\n\n public constructor(five: Five) {\n super()\n this.planeMesh = createPlaneMesh()\n this.lineMesh = createLineMesh()\n this.ballMesh = createBallMesh()\n this.borderMesh = createBorderMesh()\n\n this.addEventListener('added', () => {\n this.add(this.planeMesh, this.lineMesh, this.ballMesh, this.borderMesh)\n })\n\n this.addEventListener('removed', () => {\n this.remove(this.planeMesh, this.lineMesh, this.ballMesh, this.borderMesh)\n })\n\n initialCSS3DRender(five)\n\n this.five = five\n }\n\n public updateWithIntersect(intersect: Intersection) {\n const lookAtPosition = intersect?.face?.normal\n ? new THREE.Vector3().addVectors(intersect.point, intersect.face.normal)\n : this.five.camera.position\n this.position.copy(intersect.point)\n this.lookAt(lookAtPosition)\n }\n\n public show() {\n this.visible = true\n if (!this.borderMesh.parent) {\n this.add(this.borderMesh)\n }\n }\n\n public hide() {\n this.visible = false\n this.remove(this.borderMesh)\n }\n\n public dispose() {\n this.planeMesh.material.map?.dispose()\n for (const mesh of [this.planeMesh, this.lineMesh, this.ballMesh]) {\n mesh.geometry.dispose(); mesh.material.dispose()\n }\n this.borderMesh.dispose()\n this.removeFromParent()\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PointHelper-DIhgdjY2.js","names":["createPlaneMesh","createLineMesh","createBallMesh","__toESM","bindFiveOwner","LineMesh","generateBehindFiveElement","CSS3DSprite","CSS3DObjectPlus","getFiveModel","waitFiveModelLoaded","THREERaycaster","rayOnLine","THREE","Magnifier","Subscribe","five","options","context","m","Hammer","element","point","newScale","newWidth","newHeight","imageWidth","imageHeight","revision","renderSize","projected","x","y","readWidth","width","scale","readHeight","height","pixelRatio","hidden","pixelsPromise","object","visible","pixels","error","canvasClientRect","containerDomRect","maxOffsetX","maxOffsetY","minOffsetX","minOffsetY","left","right","top","position2d","clientWidth","clientHeight","canvas","offsetRange","offsetX","event","offsetY","translateX","translateY","sessions","activeSessions","disposedOwners","frontScene","behindScene","legacyOwners","belongsToFive","scene","legacyScenes","mode","sceneMap","initialCSS3DRender","addScene","map","sceneKey","key","removeScene","sceneOrKey","maps","session","removed","addFrontScene","removeFrontScene","addBehindScene","removeBehindScene","scenesForOwner","existing","front","ICSS3DRenderer","behind","pending","disposed","dispose","onFiveDispose","ownedHere","root","movedToAnotherScene","wrapper","behindWrapper","ICSS3DSprite","createPlaneMesh$1","group","fill","border","createCrossline","length","style","lineX","lineY","createLineMesh$1","zPath","zGeometry","zMaterial","createRingMesh","geometry","material","createBallMesh$1","ballGeometry","ballMaterial","createCSSBallMesh","img","cssMesh","PointHelper2","lineLength","intersect","normal","lookAtPosition","mesh","PointSelectorHelper","pointHelper","PointHelper","config","updateMagnifier","navigatorTouchPoints","isTouchDevice","createIntersectionFace","Vector3","getRaycasterByNdcPosition","position","raycaster","getIntersectByRaycaster","realIntersect","getRealIntersectByRaycaster","getVirtualIntersectByRaycaster","distance","CURSOR_NOT_ALLOW_URL","_vector3","disableFiveEvent","PointSelector","cursorError","outOfFive","enabled","defaultMagnifierParams","fiveElement","points","intersection","cancel","render","clientX","clientY","timestamp","success","moved","ndcPosition","realIntersection","intersectionPoint","virtualIntersection","targetIntersect","mouseNdcPosition","size","adherePlane","newPoint","adhereLine","closestPoint","projectPoint","positionOffset","_point","pointIsVisible","cameraToPointDistance","mouseX","mouseY","mousePosition","POINT_HELPER_TEXTURE_URL","rangePieceImg","html_default","createPlaneMesh","planGeometry","planTextureUrl","planTexture","planMaterial","createLineMesh","colors","uv","i","createBallMesh","ballMesh","createBorderMesh","radius","borderMesh","contentElement"],"sources":["../../src/shared-utils/three/Magnifier.ts","../../src/shared-utils/CSS3DRender/index.ts","../../src/CSS3DRenderPlugin/utils/three/CSS3DSprite.ts","../../src/shared-utils/three/PointSelector/utils/PointHelper2.ts","../../src/shared-utils/three/PointSelector/utils/PointSelectorHelper.ts","../../src/shared-utils/isTouchDevice.ts","../../src/shared-utils/three/createIntersectionFace.ts","../../src/shared-utils/five/getRaycasterByNdcPosition.ts","../../src/shared-utils/five/getPosition.ts","../../src/shared-utils/three/PointSelector/utils/contents.ts","../../src/shared-utils/three/PointSelector/index.ts","../../src/shared-utils/three/Assets/index.ts","../../src/shared-utils/three/PointSelector/utils/html.ts","../../src/shared-utils/three/PointSelector/utils/PointHelper.ts"],"sourcesContent":["import type { Five, SubscribeEventMap } from '@realsee/five-webgpu'\n\nimport type Hammer from 'hammerjs'\nimport * as THREE from 'three/webgpu'\nimport { Subscribe } from '../Subscribe'\n\ninterface MagnifierConfig {\n /** 允许拖动放大镜 */\n dragEnabled: boolean\n /** renderWithPoint 时,是否应该自动更新放大镜的位置 */\n autoFixPCPosition: boolean\n /** 放大镜初始位置应该设置在容器的哪个位置 */\n initialPosition: { left: string; top: string }\n /** 是否跳过全景图渲染 */\n skipPanorama: boolean\n}\n\ninterface MagnifierEvent extends SubscribeEventMap {\n wantsPanGesture: (event: (typeof Hammer)['Input']) => boolean\n}\n\n/** 放大镜配置参数 */\nexport interface MagnifierParameter extends Partial<MagnifierConfig> {\n width?: number\n height?: number\n scale?: number\n}\n\nexport class Magnifier {\n public width: number\n public height: number\n public containerDom?: Element\n public hooks = new Subscribe<MagnifierEvent>()\n public canvas = document.createElement('canvas')\n public config: MagnifierConfig\n public state = { enabled: false }\n\n private five: Five\n private scale: number\n private offset = { x: 0, y: 0 }\n private context: CanvasRenderingContext2D\n private renderCenter: THREE.Vector3 | { x: number; y: number } = new THREE.Vector3()\n private hammer?: InstanceType<typeof Hammer>\n private offsetRange?: { min: { x: number; y: number }; max: { x: number; y: number } }\n private isPanning = false\n private isDisposed = false\n private imageData: ImageData = new ImageData(1, 1)\n private pendingRender?: Promise<void>\n private renderRevision = 0\n private invalidatedRevision = -1\n\n public constructor(five: Five, options: MagnifierParameter) {\n if (!five.renderer) {\n console.error('Five Render 未初始化')\n return\n }\n\n this.five = five\n this.scale = options?.scale ?? 2\n this.width = options?.width ?? 190\n this.height = options?.height ?? options?.width ?? 190\n this.config = {\n dragEnabled: options?.dragEnabled || false,\n autoFixPCPosition: options?.autoFixPCPosition || false,\n initialPosition: options?.initialPosition || { left: '0', top: '0' },\n skipPanorama: options?.skipPanorama || false,\n }\n\n const context = this.canvas.getContext('2d')\n if (!context) throw new Error('CANNOT CREATE CONTEXT2D')\n this.context = context\n\n if (this.config.dragEnabled) {\n void import('hammerjs').then(({ default: Hammer }) => {\n if (this.isDisposed) return\n this.hammer = new Hammer(this.canvas)\n this.hammer.on('pan', this.onPan)\n this.hammer.on('panstart', this.onPanstart)\n this.hammer.on('panend', this.onPanend)\n })\n }\n this.initStyle()\n }\n\n public enable() {\n if (this.isDisposed || this.state.enabled) return\n this.state.enabled = true\n if (this.containerDom) this._appendTo(this.containerDom)\n return this\n }\n\n public disable() {\n if (!this.state.enabled) return\n this.state.enabled = false\n this.invalidatedRevision = this.renderRevision\n this.canvas.style.visibility = 'hidden'\n this.canvas.remove()\n return this\n }\n\n public dispose() {\n if (this.isDisposed) return\n this.isDisposed = true\n this.clear()\n this.disable()\n this.hammer?.destroy()\n }\n\n /** 把放大镜放到某一个容器中 */\n public appendTo(element: Element) {\n if (this.containerDom) this.containerDom?.removeChild(this.canvas)\n this.containerDom = element\n if (this.state.enabled) this._appendTo(element)\n return this\n }\n\n /** 清除放大镜渲染内容 */\n public clear() {\n this.invalidatedRevision = this.renderRevision\n this.context?.clearRect(0, 0, this.canvas.width, this.canvas.height)\n return this\n }\n\n /** 放大传入点位周围的内容 */\n public renderWithPoint(point: THREE.Vector3) {\n if (!this.containerDom) return\n if (!this.state.enabled) return\n this.renderCenter = point\n this.render()\n if (this.config.autoFixPCPosition) this.autoFixPCPosition()\n }\n\n /** 放大传入点位周围的内容 */\n public renderWithScreenPoint(point: { x: number; y: number }) {\n if (!this.containerDom) return\n if (!this.state.enabled) return\n this.renderCenter = point\n this.render()\n if (this.config.autoFixPCPosition) this.autoFixPCPosition()\n }\n\n public resetOffset() {\n this.offset = { x: 0, y: 0 }\n this.canvas.style.transform = `translate3d(${0}px, ${0}px, 100px)`\n }\n\n /** 更新放大镜的缩放比例 */\n public updateScale(newScale: number) {\n if (newScale > 0) {\n this.scale = newScale\n this.invalidatedRevision = this.renderRevision\n }\n }\n\n /** 更新放大镜的尺寸 */\n public updateSize(newWidth: number, newHeight?: number) {\n if (newWidth > 0) {\n this.width = newWidth\n this.height = newHeight || newWidth\n\n // 更新canvas样式\n const pixelRatio = 1\n this.canvas.setAttribute('width', (this.width * pixelRatio).toString())\n this.canvas.setAttribute('height', (this.height * pixelRatio).toString())\n this.canvas.style.width = this.width + 'px'\n this.canvas.style.height = this.height + 'px'\n\n // 重新初始化ImageData\n const imageWidth = Math.floor(this.width * pixelRatio)\n const imageHeight = Math.floor(this.height * pixelRatio)\n this.imageData = new ImageData(imageWidth, imageHeight)\n\n // 清除之前的渲染内容\n this.clear()\n }\n }\n\n public render(): Promise<void> {\n this.renderRevision += 1\n if (!this.pendingRender) {\n this.pendingRender = this.renderLatest().finally(() => { this.pendingRender = undefined })\n }\n return this.pendingRender\n }\n\n private async renderLatest() {\n while (!this.isDisposed && this.state.enabled && this.containerDom && this.five.renderer) {\n const revision = this.renderRevision\n const { scale, width, height } = this\n const renderSize = this.five.renderer.getSize(new THREE.Vector2())\n const point = this.renderCenter\n const projected = point instanceof THREE.Vector3 ? point.clone().project(this.five.camera) : null\n const x = projected ? ((projected.x + 1) / 2) * renderSize.x : point.x\n const y = projected ? ((projected.y + 1) / 2) * renderSize.y : renderSize.y - point.y\n\n // Five accepts integer dimensions and pixel ratios. Keep fractional zoom\n // in the CSS size instead of expecting an impossible fractional readback.\n const readWidth = Math.max(1, Math.round(width / scale))\n const readHeight = Math.max(1, Math.round(height / scale))\n const pixelRatio = Math.max(1, Math.ceil(scale))\n const imageWidth = readWidth * pixelRatio\n const imageHeight = readHeight * pixelRatio\n const hidden = new Map<THREE.Object3D, boolean>()\n let pixelsPromise: ReturnType<Five['getPixels']>\n\n try {\n this.five.scene.traverse((object) => {\n if ((object as THREE.Object3D & { disableGetPixel?: boolean }).disableGetPixel) {\n hidden.set(object, object.visible)\n object.visible = false\n }\n })\n try {\n // getPixels renders synchronously before its asynchronous GPU readback.\n pixelsPromise = this.five.getPixels({\n x: x - readWidth / 2,\n y: y - readHeight / 2,\n width: readWidth,\n height: readHeight,\n pixelRatio,\n skipPanorama: this.config.skipPanorama,\n flipY: true,\n })\n } finally {\n hidden.forEach((visible, object) => { object.visible = visible })\n }\n const pixels = await pixelsPromise\n if (this.isDisposed || !this.state.enabled) return\n if (this.invalidatedRevision === this.renderRevision) return\n if (revision !== this.renderRevision) continue\n if (pixels.length !== imageWidth * imageHeight * 4) {\n console.warn('Magnifier: Invalid pixel data length')\n return\n }\n if (this.imageData.width !== imageWidth || this.imageData.height !== imageHeight) {\n this.imageData = new ImageData(imageWidth, imageHeight)\n }\n this.canvas.width = imageWidth\n this.canvas.height = imageHeight\n this.imageData.data.set(pixels)\n this.context.putImageData(this.imageData, 0, 0)\n this.canvas.style.visibility = 'visible'\n } catch (error) {\n console.error('Magnifier: Failed to read pixels', error)\n }\n if (revision === this.renderRevision) return\n }\n }\n\n private _appendTo(element: Element) {\n this.resetOffset()\n element.appendChild(this.canvas)\n if (!this.offsetRange) {\n const canvasClientRect = this.canvas.getBoundingClientRect()\n const containerDomRect = element.getBoundingClientRect()\n const maxOffsetX = containerDomRect.right - canvasClientRect.right\n const maxOffsetY = containerDomRect.bottom - canvasClientRect.bottom\n const minOffsetX = containerDomRect.left - canvasClientRect.left\n const minOffsetY = containerDomRect.top - canvasClientRect.top\n this.offsetRange = {\n min: { x: minOffsetX, y: minOffsetY },\n max: { x: maxOffsetX, y: maxOffsetY },\n }\n }\n }\n\n private autoFixPCPosition() {\n if (!this.containerDom) return\n const { width, height } = this\n const { clientWidth, clientHeight } = this.containerDom\n\n const [left, right, top] = (() => {\n if ((this.renderCenter as any).isVector3) {\n const position2d = (this.renderCenter as THREE.Vector3).clone().project(this.five.camera)\n\n return [\n //\n ((position2d.x + 1) / 2) * clientWidth,\n (-(position2d.x - 1) / 2) * clientWidth,\n (-(position2d.y - 1) / 2) * clientHeight,\n ]\n } else {\n return [this.renderCenter.x, clientWidth - this.renderCenter.x, this.renderCenter.y]\n }\n })()\n\n if (left < 183) {\n this.canvas.style.top = -height / 2 + 'px'\n this.canvas.style.left = 90 + 'px'\n } else if (top < 183) {\n this.canvas.style.top = 90 + 'px'\n this.canvas.style.left = -width / 2 + 'px'\n } else if (right < 183) {\n this.canvas.style.top = -height / 2 + 'px'\n this.canvas.style.left = -width - 90 + 'px'\n } else {\n this.canvas.style.left = -width / 2 + 'px'\n this.canvas.style.top = -height - 90 + 'px'\n }\n this.canvas.style.transform = `translate3d(${left}px, ${top}px, 10px)`\n this.offset = { x: left, y: top }\n }\n\n private initStyle() {\n const canvas = this.canvas\n canvas.classList.add('five-plugin__magnifier')\n canvas.style.position = 'absolute'\n canvas.style.pointerEvents = this.config.dragEnabled ? 'all' : 'none'\n canvas.style.borderRadius = '50%'\n canvas.style.zIndex = '99'\n const pixelRatio = 1\n canvas.setAttribute('width', (this.width * pixelRatio).toString())\n canvas.setAttribute('height', (this.height * pixelRatio).toString())\n canvas.style.border = '2px solid rgba(255,255,255,0.20)'\n canvas.style.width = this.width + 'px'\n canvas.style.height = this.height + 'px'\n canvas.style.top = this.config.initialPosition.top\n canvas.style.left = this.config.initialPosition.left\n canvas.style.transform = 'translate(0,0,100px)'\n canvas.style.visibility = 'hidden'\n\n if (this.config.dragEnabled) {\n this.canvas.style.cursor = 'pointer'\n }\n }\n\n private getPanOffset(event: (typeof Hammer)['Input'], offsetRange: { min: { x: number; y: number }; max: { x: number; y: number } }) {\n const {\n min: { x: minOffsetX, y: minOffsetY },\n max: { x: maxOffsetX, y: maxOffsetY },\n } = offsetRange\n const offsetX = this.offset.x + event.deltaX\n const offsetY = this.offset.y + event.deltaY\n const translateX = Math.min(Math.max(offsetX, minOffsetX), maxOffsetX)\n const translateY = Math.min(Math.max(offsetY, minOffsetY), maxOffsetY)\n return { translateX, translateY }\n }\n\n private onPanstart = () => {\n this.isPanning = true\n this.canvas.style.boxShadow = '0 2px 30px 0 rgba(0,0,0,0.20)'\n }\n\n private onPan = (event: (typeof Hammer)['Input']) => {\n if (!this.isPanning) return\n if (!this.offsetRange) return\n const prevented = this.hooks.emit('wantsPanGesture', event)\n if (prevented) return\n\n const { translateX, translateY } = this.getPanOffset(event, this.offsetRange)\n this.canvas.style.transform = `translate3d(${translateX}px, ${translateY}px, 100px)`\n }\n\n private onPanend = (event: (typeof Hammer)['Input']) => {\n this.isPanning = false\n this.canvas.style.boxShadow = 'none'\n if (!this.offsetRange) return\n const { translateX, translateY } = this.getPanOffset(event, this.offsetRange)\n this.canvas.style.transform = `translate3d(${translateX}px, ${translateY}px, 100px)`\n this.offset = { x: translateX, y: translateY }\n }\n}\n","import type * as THREE from 'three/webgpu'\nimport { ICSS3DRenderer } from '../../CSS3DRenderPlugin/utils/three/CSS3DRenderer'\nimport type { Five } from '@realsee/five-webgpu'\nimport { waitFiveModelLoaded } from '../five/fiveModelLoad'\nimport { generateBehindFiveElement } from '../../CSS3DRenderPlugin/utils/generateBehindFiveElement'\nimport type { CSS3DObjectPlus } from './CSS3DObject'\n\ntype CSSScene = THREE.Scene | CSS3DObjectPlus\ntype SceneMode = 'front' | 'behind'\ninterface CSSSession {\n five: Five\n front: Map<string, CSSScene>\n behind: Map<string, CSSScene>\n dispose: () => void\n}\nconst sessions = new WeakMap<Five, CSSSession>()\nconst activeSessions = new Set<CSSSession>()\nconst disposedOwners = new WeakSet<Five>()\n// Existing calls without an owner stay supported. Their scene ancestry is\n// checked every frame, including objects added after construction or reparented.\nconst frontScene = new Map<string, CSSScene>()\nconst behindScene = new Map<string, CSSScene>()\nconst legacyOwners = new WeakMap<CSSScene, Five>()\n\nfunction belongsToFive(scene: CSSScene, five: Five) {\n for (let object: THREE.Object3D | null = scene; object; object = object.parent) {\n if (object === five.scene) return true\n }\n return false\n}\nfunction legacyScenes(mode: SceneMode) {\n return mode === 'front' ? frontScene : behindScene\n}\nfunction sceneMap(mode: SceneMode, five?: Five) {\n if (!five) return legacyScenes(mode)\n initialCSS3DRender(five)\n return sessions.get(five)?.[mode]\n}\nfunction addScene(mode: SceneMode, scene: CSSScene, key?: string, five?: Five): boolean {\n if (!scene) return false\n const map = sceneMap(mode, five),\n sceneKey = key || scene.uuid\n if (!map || map.has(sceneKey)) return false\n map.set(sceneKey, scene)\n return true\n}\nfunction removeScene(mode: SceneMode, sceneOrKey: CSSScene | string, five?: Five): boolean {\n if (!sceneOrKey) return false\n const maps = five\n ? [sessions.get(five)?.[mode]]\n : [legacyScenes(mode), ...Array.from(activeSessions, (session) => session[mode])]\n let removed = false\n for (const map of maps) {\n if (!map) continue\n if (typeof sceneOrKey === 'string') removed = map.delete(sceneOrKey) || removed\n else for (const [key, scene] of map) if (scene === sceneOrKey) removed = map.delete(key) || removed\n }\n return removed\n}\n/** Add a front scene; the optional owner keeps identical keys in separate Five sessions. */\nexport function addFrontScene(scene: CSSScene, key?: string, five?: Five): boolean {\n return addScene('front', scene, key, five)\n}\nexport function removeFrontScene(sceneOrKey: CSSScene | string, five?: Five): boolean {\n return removeScene('front', sceneOrKey, five)\n}\nexport function addBehindScene(scene: CSSScene, key?: string, five?: Five): boolean {\n return addScene('behind', scene, key, five)\n}\nexport function removeBehindScene(sceneOrKey: CSSScene | string, five?: Five): boolean {\n return removeScene('behind', sceneOrKey, five)\n}\n/** The existing no-argument clear functions retain their explicit global semantics. */\nexport function clearFrontScenes(): void {\n frontScene.clear()\n for (const session of activeSessions) session.front.clear()\n}\nexport function clearBehindScenes(): void {\n behindScene.clear()\n for (const session of activeSessions) session.behind.clear()\n}\nexport function clearAllScenes(): void {\n clearFrontScenes()\n clearBehindScenes()\n}\n\nfunction* scenesForOwner(session: CSSSession, mode: SceneMode): Iterable<CSSScene> {\n yield* session[mode].values()\n for (const scene of legacyScenes(mode).values()) {\n if (belongsToFive(scene, session.five)) {\n legacyOwners.set(scene, session.five)\n yield scene\n }\n }\n}\n\nexport function initialCSS3DRender(five: Five) {\n const existing = sessions.get(five)\n if (existing) return existing.dispose\n if (disposedOwners.has(five)) return () => {}\n const front = new ICSS3DRenderer('front'),\n behind = new ICSS3DRenderer('behind')\n front.domElementWrapper.style.zIndex = '1'\n const pending = new AbortController()\n let disposed = false\n const dispose = () => {\n if (disposed) return\n disposed = true\n pending.abort()\n five.off('dispose', onFiveDispose)\n front.dispose()\n behind.dispose()\n session.front.clear()\n session.behind.clear()\n for (const map of [frontScene, behindScene]) {\n for (const [key, scene] of map) {\n const ownedHere = belongsToFive(scene, five)\n let root: THREE.Object3D = scene\n while (root.parent) root = root.parent\n // A legacy object may already be in another scene before that owner's\n // next frame updates the observation. Do not erase its new registry entry.\n const movedToAnotherScene = !ownedHere && (root as THREE.Scene).isScene === true\n if (ownedHere || (legacyOwners.get(scene) === five && !movedToAnotherScene)) map.delete(key)\n }\n }\n if (sessions.get(five) === session) sessions.delete(five)\n activeSessions.delete(session)\n }\n const onFiveDispose = () => {\n disposedOwners.add(five)\n dispose()\n }\n const session: CSSSession = { five, front: new Map(), behind: new Map(), dispose }\n sessions.set(five, session)\n activeSessions.add(session)\n five.on('dispose', onFiveDispose)\n waitFiveModelLoaded(five, pending.signal).then(() => {\n if (disposed) return\n const wrapper = five.getElement()?.parentElement\n if (!wrapper) {\n // A host can detach its canvas before Five emits public dispose. Treat\n // that async mount as cancelled and release this session's resources.\n // A later append may create a fresh session through the normal entry.\n dispose()\n return\n }\n const behindWrapper = generateBehindFiveElement(five)\n if (!behindWrapper) {\n console.error('initialCSS3DRender: behindWrapper is not exist')\n return\n }\n front.appendToElement(wrapper)\n front.renderCss3dObjectEveryFrame(() => scenesForOwner(session, 'front'), five.camera)\n behind.appendToElement(behindWrapper)\n behind.renderCss3dObjectEveryFrame(() => scenesForOwner(session, 'behind'), five.camera)\n })\n return dispose\n}\n","import { CSS3DSprite } from '../../../shared-utils/three/CSS3DRenderer'\n\nexport class ICSS3DSprite extends CSS3DSprite {\n public isCSS3DSprite = true\n public isCSS3DObject = true\n}\n","import { bindFiveOwner } from '../../../five/getFiveFromParentChain'\nimport * as THREE from 'three/webgpu'\nimport type { Intersection } from '../../../../typings/typings'\nimport { initialCSS3DRender } from '../../../five/initialCSS3DRender'\nimport type { Five } from '@realsee/five-webgpu'\nimport { LineMesh, type LineMeshStyle } from '../../../../Sculpt/Meshes/Line'\nimport type { PointHelperAbstract } from './typing'\nimport { ICSS3DSprite } from '../../../../CSS3DRenderPlugin/utils/three/CSS3DSprite'\n\n\nexport interface MouseGroupParameter {\n isMobile?: boolean\n useNormalVector?: boolean // 是否展示法向量\n ballColor?: number // 法向量小球色值\n}\n\nfunction createPlaneMesh() {\n const radius = 0.2\n const group = new THREE.Group()\n const fill = new THREE.Mesh(\n new THREE.CircleGeometry(radius - 0.01, 64),\n new THREE.MeshBasicMaterial({ color: 0xffffff, opacity: 0.2, side: THREE.DoubleSide, depthTest: false, transparent: true }),\n )\n const border = new THREE.Mesh(\n new THREE.RingGeometry(radius - 0.01, radius, 64),\n new THREE.MeshBasicMaterial({ color: 0xffffff, opacity: 0.3, side: THREE.DoubleSide, depthTest: false, transparent: true }),\n )\n group.add(fill, border)\n return group\n}\n\nfunction createCrossline() {\n const length = 0.5\n const group = new THREE.Group()\n const style: Partial<LineMeshStyle> = {\n lineWidth: 1,\n lineColor: 0x33ffdd,\n lineOpacity: 0.7,\n occlusionVisibility: true,\n }\n const lineX = new LineMesh({ points: [{ x: -length }, { x: length }], ...style, lineColor: 0x33ffdd })\n const lineY = new LineMesh({ points: [{ y: -length }, { y: length }], ...style, lineColor: 0x33ffdd })\n\n group.add(lineX, lineY)\n return group\n}\n\nfunction createLineMesh(length: number) {\n // 法向量垂直管\n const zPath = new THREE.CurvePath<THREE.Vector3>()\n zPath.add(new THREE.LineCurve3(new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, length)))\n const zGeometry = new THREE.TubeGeometry(zPath, 32, 0.003)\n const zMaterial = new THREE.MeshBasicMaterial({\n color: 0xa7c3ff,\n depthTest: false,\n transparent: true, // 必须要开启透明度,要和PlaneMesh一起渲染\n })\n const zMesh = new THREE.Mesh(zGeometry, zMaterial)\n return zMesh\n}\n\nfunction createRingMesh() {\n // 法向量圆环\n const geometry = new THREE.RingGeometry(0.03, 0.035, 64)\n const material = new THREE.MeshBasicMaterial({\n color: 0xffffff,\n depthTest: false,\n transparent: true, // 必须要开启透明度,要和PlaneMesh一起渲染\n side: THREE.DoubleSide,\n })\n const ringMesh = new THREE.Mesh(geometry, material)\n return ringMesh\n}\n\nfunction createBallMesh() {\n // mesh 球\n const ballGeometry = new THREE.SphereGeometry(0.018, 32, 32)\n const ballMaterial = new THREE.MeshBasicMaterial({\n color: 0x4d97ff,\n depthTest: false,\n transparent: true, // 必须要开启透明度,要和PlaneMesh一起渲染\n })\n const ballMesh = new THREE.Mesh(ballGeometry, ballMaterial)\n\n return ballMesh\n}\n\nfunction createCSSBallMesh() {\n // css 球\n const img = document.createElement('img')\n img.src =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAVCAMAAAB8FU7dAAAAw1BMVEUAAACDuuiAsu11q/x8r/+HxtKHxtKIx9J4ut6Hx9Jcn/uNwNlmmf+RuP9ppf9orel3ud2HxtJrpf9oremev/9ppP9orelQmP9ZoPWSuP92q/9cnv9prel4ut53qv9orelYoPWIxdJPmP+HxtGRuP9oo/+Suf9Qmf92q/+RuP+DsP9Pmv+FxdFtre2SyMiRuP9PmP+evv9ppf9cnv+rxf9orepZofV4ut52q/+Dsf+Esv+5y/93q/9aofbF0f93rP9qpf8IzZ1iAAAAL3RSTlMAEg4s3dK5nodgVQoF/Pf39vbt7evr39rV1NTOzs6srJ+fiIZ9fWlpW09ERCwcHMH8LhIAAADRSURBVBjTjdDHkoMwEIThBrzOm3POOQwSYCRhe/f9n2p75FD2zX/VXL5qOAjzkixLsFL6fOFF5PwpXUj/eEwx7Oh9Jq+FdV5MqZkXlU9K4KZsmqY02x/A8LSwv14o0ylJWkP087WVhDfcjmjj5b/E3+CEpDPdGY58C7tKfzSiiA9uB4dV/NIF7yVQ7AGuq0lOIzrvnLP2Et2aMzUqryge8FVX0Zjl5XkG3KsR593pM2zVEScjvbMU7IdGjF19IzZ43Ceyve4Ai5Jep93u9BJs3j/gXjHbRgy31AAAAABJRU5ErkJggg=='\n const cssMesh = new ICSS3DSprite(img)\n img.style.pointerEvents = 'none'\n cssMesh.scale.set(0.003, 0.003, 0.003)\n\n return cssMesh\n}\n\nexport class PointHelper2 extends THREE.Object3D implements PointHelperAbstract {\n public disableGetPixel = true\n public planeMesh: ReturnType<typeof createPlaneMesh>\n public ringMesh: ReturnType<typeof createRingMesh>\n public crossline: ReturnType<typeof createCrossline>\n public lineMesh: ReturnType<typeof createLineMesh>\n public ballMesh: ReturnType<typeof createBallMesh>\n public cssBallMesh: ReturnType<typeof createCSSBallMesh>\n\n public constructor(five: Five) {\n super()\n bindFiveOwner(this, five)\n\n const lineLength = 0.18\n this.planeMesh = createPlaneMesh()\n this.ringMesh = createRingMesh()\n this.crossline = createCrossline()\n this.lineMesh = createLineMesh(lineLength)\n this.ballMesh = createBallMesh()\n this.cssBallMesh = createCSSBallMesh()\n\n this.ballMesh.position.setZ(lineLength)\n this.cssBallMesh.position.setZ(lineLength)\n\n this.planeMesh.renderOrder = 0\n this.ringMesh.renderOrder = 1\n this.crossline.renderOrder = 2\n this.lineMesh.renderOrder = 3\n this.ballMesh.renderOrder = 4\n\n // 暂时移除 crossline,之后产品要再加上\n this.add(this.planeMesh, this.lineMesh, this.ballMesh, this.ringMesh, this.cssBallMesh)\n\n initialCSS3DRender(five)\n }\n\n public updateWithIntersect(intersect: Intersection) {\n if (!intersect.face) return\n\n const normal = (() => {\n const normal = intersect.face.normal.clone().normalize()\n // 地面\n if (normal.y > 0.99) return new THREE.Vector3(0, 1, 0)\n\n // 天花板\n if (normal.y < -0.99) return new THREE.Vector3(0, -1, 0)\n\n // 标准墙面\n if (normal.x > 0.99) return new THREE.Vector3(1, 0, 0)\n if (normal.x < -0.99) return new THREE.Vector3(-1, 0, 0)\n if (normal.z > 0.99) return new THREE.Vector3(0, 0, 1)\n if (normal.z < -0.99) return new THREE.Vector3(0, 0, -1)\n\n // 斜墙\n if (normal.y < 0.01 && normal.y > -0.01) return new THREE.Vector3(normal.x, 0, normal.z)\n\n return normal\n })()\n\n const lookAtPosition = new THREE.Vector3().addVectors(intersect.point, normal)\n this.position.copy(intersect.point)\n this.lookAt(lookAtPosition)\n }\n\n public show() {\n this.visible = true\n this.add(this.cssBallMesh)\n }\n\n public hide() {\n this.visible = false\n this.remove(this.cssBallMesh)\n }\n\n public dispose() {\n this.traverse((object) => {\n const mesh = object as THREE.Mesh\n mesh.geometry?.dispose()\n if (mesh.material) {\n const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material]\n materials.forEach((material) => material.dispose())\n }\n })\n this.cssBallMesh.element.remove()\n this.removeFromParent()\n }\n}\n","import * as THREE from 'three/webgpu'\nimport type { Five } from '@realsee/five-webgpu'\nimport { Magnifier, PointHelper } from '../..'\nimport type { Intersection } from '../../../../typings/typings'\nimport { Subscribe } from '../../../Subscribe'\nimport { PointHelper2 } from './PointHelper2'\nimport type { PointHelperAbstract } from './typing'\n\nexport interface PointSelectorHelperConfig {\n magnifier?: Magnifier | null\n magnifierParams?: ConstructorParameters<typeof Magnifier>[1]\n pointHelper?: PointHelperAbstract | 'default' | 'highlight' | null\n container?: Element\n skipPanorama?: boolean\n}\n\ntype EventMap = {\n intersectionUpdate: (intersection: PointIntersection) => void\n /** 功能开启 */\n enabled: () => void\n /** 功能关闭 */\n disabled: () => void\n}\n\nexport interface PointIntersection extends Intersection {\n /**\n * @description 被吸附\n */\n isAdsorbed?: boolean\n /**\n * @description 原始焦点\n */\n originalPoint?: THREE.Vector3\n /**\n * @description 虚拟生成的点\n */\n isVirtual?: boolean\n /**\n * @description 射线\n */\n raycaster?: THREE.Raycaster\n /**\n * @description 如果开启了吸附并且吸附到了平面,这里会有吸附的平面\n */\n adherePlane?: THREE.Plane\n /**\n * @description 如果开启了吸附并且吸附到了点,这里会有吸附的点\n */\n adherePoint?: THREE.Vector3\n /**\n * @description 如果开启了吸附并且吸附到了线,这里会有吸附的线\n */\n adhereLine?: THREE.Line3\n}\n\nexport class PointSelectorHelper {\n public five: Five\n public hooks = new Subscribe<EventMap>()\n public position: PointIntersection | null = null\n public magnifier: Magnifier | null = null\n public pointHelper: PointHelperAbstract | null = null\n public state = { enabled: false, visible: true }\n private group = new THREE.Group()\n\n public constructor(five: Five, options?: PointSelectorHelperConfig) {\n this.five = five\n\n this.magnifier =\n options?.magnifier !== undefined ? options.magnifier : new Magnifier(five, { dragEnabled: true, ...options?.magnifierParams, skipPanorama: options?.skipPanorama ?? false })\n\n let pointHelper: PointHelperAbstract | null = null\n if (options?.pointHelper === 'default' || options?.pointHelper === undefined) {\n pointHelper = new PointHelper(five)\n // pointHelper = new PointHelper2(five)\n } else if (options?.pointHelper === 'highlight') {\n pointHelper = new PointHelper2(five)\n } else if (options?.pointHelper === null) {\n pointHelper = null\n } else {\n pointHelper = options.pointHelper\n }\n this.pointHelper = pointHelper\n\n this.group.name = 'five-point-selector'\n this.five.scene.add(this.group)\n this.magnifier?.appendTo(options.container ?? five.getElement()?.parentElement ?? document.body)\n }\n\n public show = () => {\n if (this.state.visible) return\n this.state.visible = true\n this.pointHelper?.show()\n this.magnifier?.enable()\n this.five.needsRender = true\n }\n\n public hide = () => {\n if (!this.state.visible) return\n this.state.visible = false\n this.pointHelper?.hide()\n this.magnifier?.disable()\n this.five.needsRender = true\n }\n\n public enable() {\n if (this.state.enabled) return\n this.state.enabled = true\n if (this.pointHelper) {\n this.group.add(this.pointHelper)\n }\n this.magnifier?.enable()\n this.five.needsRender = true\n this.hooks.emit('enabled')\n }\n\n public disable() {\n if (!this.state.enabled) return\n this.state.enabled = false\n if (this.pointHelper) {\n this.group.remove(this.pointHelper)\n }\n this.magnifier?.disable()\n this.hooks.emit('disabled')\n }\n\n public dispose() {\n this.hooks.off()\n this.disable()\n this.abortUpdateMagnifier()\n this.magnifier?.dispose()\n this.magnifier = null\n this.pointHelper?.dispose()\n this.pointHelper = null\n this.group.removeFromParent()\n }\n\n public updateWithIntersect = (intersect?: Intersection, config: { emitEvent: boolean } = { emitEvent: true }) => {\n if (!intersect) return\n this.abortUpdateMagnifier()\n this.position = intersect\n if (config.emitEvent) this.hooks.emit('intersectionUpdate', intersect)\n\n // update pointer helper\n this.pointHelper?.updateWithIntersect(intersect)\n // update magnifier\n // 因为 Magnifier 的渲染依赖场景渲染 ,所以需要在场景渲染完成后再渲染 Magnifier\n const updateMagnifier = () => this.magnifier?.renderWithPoint(intersect.point)\n this.abortUpdateMagnifier = () => this.five.off('renderFrame', updateMagnifier)\n this.five.once('renderFrame', updateMagnifier)\n\n this.five.needsRender = true\n }\n\n private abortUpdateMagnifier: () => any = () => {}\n}\n","const navigatorTouchPoints = typeof navigator === 'undefined' ? 0 : navigator.maxTouchPoints || (navigator as any).msMaxTouchPoints || 0\n\nexport const isTouchDevice = typeof window !== 'undefined' && ('ontouchstart' in window || navigatorTouchPoints > 0)\n","import { Vector3, type Face } from 'three/webgpu'\n\nexport function createIntersectionFace(normal = new Vector3()): Face {\n return { a: 0, b: 0, c: 0, normal, materialIndex: 0 }\n}\n","import type { Five } from '@realsee/five-webgpu'\nimport * as THREE from 'three/webgpu'\n\nexport function getRaycasterByNdcPosition(five: Five, position: { x: number; y: number }) {\n const { x: left, y: top } = position\n const x = left * 2 - 1\n const y = top * 2 - 1\n const raycaster = new THREE.Raycaster()\n raycaster.setFromCamera(new THREE.Vector2(x, y), five.camera)\n raycaster.params.Points.threshold = 0.02\n return raycaster\n}\n","import * as THREE from 'three/webgpu'\nimport type { Five, Intersection } from '@realsee/five-webgpu'\nimport { getRaycasterByNdcPosition } from './getRaycasterByNdcPosition'\nimport { getFiveModel } from './getFiveModel'\nimport { createIntersectionFace } from '../three/createIntersectionFace'\n\ninterface IIntersection extends THREE.Intersection {\n raycaster: THREE.Raycaster\n isVirtual: boolean\n}\n\n/**\n * @description 根据 ndc 坐标获取 Intersect\n */\nexport function getIntersectByNdcPosition(\n five: Five,\n position: { x: number; y: number },\n config?: { virtualPoint?: boolean },\n): IIntersection | undefined {\n const raycaster = getRaycasterByNdcPosition(five, position)\n return getIntersectByRaycaster(five, raycaster, config)\n}\n\n/**\n * @description 根据射线获取 Intersect\n */\nexport function getIntersectByRaycaster(\n five: Five,\n raycaster: THREE.Raycaster,\n config?: { virtualPoint?: boolean },\n): IIntersection | undefined {\n const realIntersect = getRealIntersectByRaycaster(five, raycaster)\n if (!config?.virtualPoint) {\n return realIntersect\n } else {\n return realIntersect ?? getVirtualIntersectByRaycaster(raycaster)\n }\n}\n\nexport function getVirtualIntersectByRaycaster(raycaster: THREE.Raycaster, distance: number = 3): IIntersection {\n const position = new THREE.Vector3().addVectors(\n raycaster.ray.origin,\n raycaster.ray.direction.clone().normalize().multiplyScalar(distance),\n )\n const normal = raycaster.ray.direction.clone().negate()\n const virtualIntersect = {\n distance,\n point: position,\n object: new THREE.Object3D(),\n face: createIntersectionFace(normal),\n raycaster,\n isVirtual: true,\n }\n return virtualIntersect\n}\n\nexport function getRealIntersectByRaycaster(five: Five, raycaster: THREE.Raycaster): IIntersection {\n const model = getFiveModel(five)\n const intersects = model.intersectRaycaster(raycaster) as Intersection[]\n const intersect = intersects[0]\n if (intersect) {\n return { ...intersect, raycaster, isVirtual: false }\n }\n}\n","export const CURSOR_NOT_ALLOW_URL = `url(\"data:image/svg+xml,%3Csvg width='12px' height='12px' viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cpath d='M6,12 C9.3137085,12 12,9.3137085 12,6 C12,2.6862915 9.3137085,0 6,0 C2.6862915,0 0,2.6862915 0,6 C0,9.3137085 2.6862915,12 6,12 Z' fill='%23FF5959'%3E%3C/path%3E%3Cg transform='translate(2, 2)' stroke='%23FFFFFF'%3E%3Ccircle cx='4' cy='4' r='4'%3E%3C/circle%3E%3Cline x1='1.07141075' y1='1.23997894' x2='6.64700843' y2='6.81557662'%3E%3C/line%3E%3C/g%3E%3C/g%3E%3C/svg%3E\") 6 6, auto`\n","\n\n\n\n\nimport type { Five } from '@realsee/five-webgpu'\nimport { PointSelectorHelper, type PointIntersection, type PointSelectorHelperConfig } from './utils/PointSelectorHelper'\nimport { isTouchDevice } from '../../isTouchDevice'\nimport type { MagnifierParameter } from '../Magnifier'\nimport type { Intersection, Vector3 } from 'three/webgpu'\nimport * as THREE from 'three/webgpu'\nimport { createIntersectionFace } from '../createIntersectionFace'\nimport { Subscribe } from '../../Subscribe'\nimport { getIntersectByRaycaster, getVirtualIntersectByRaycaster } from '../../five/getPosition'\nimport { getRaycasterByNdcPosition } from '../../five/getRaycasterByNdcPosition'\nimport type { LiteralString } from '../../../typings/utils.type'\nimport { CURSOR_NOT_ALLOW_URL } from './utils/contents'\nimport { rayOnLine } from '../../../Sculpt/utils/three/rayOnLine'\nimport { THREERaycaster } from '../core/Raycaster'\n\nexport type { PointIntersection }\n\nconst _vector3 = new THREE.Vector3()\n\nconst disableFiveEvent = (): false => false\n\nexport type ActionIfNoIntersection = LiteralString<'virtualPoint' | 'lastPoint' | 'disable'>\n\nexport type AdherePoint = Vector3 & {\n normal?: THREE.Vector3\n /**\n * @description 被模型遮挡也能看到的点\n */\n IsAlwaysVisible?: boolean\n}\n\ntype PointerSelectorMode = 'fixed' | 'cursor'\n\ninterface Config {\n /**\n * @description: 选点的两种模式, 'fixed' 为固定选点为屏幕中心点,拖动five画布来更新点,'cursor' 为跟随鼠标移动来更新点, 'auto' 则根据设备类型自动选择\n * @default: 'auto'\n */\n mode: PointerSelectorMode | 'auto'\n /**\n * @description 当鼠标位置没有模型时的行为\n * ```markdown\n * virtualPoint: 生成一个虚拟点\n * lastPoint: 选点器停留在上一个点处\n * disable: 禁止选点\n * ```\n * @default 'virtualPoint'\n */\n actionIfNoIntersection: ActionIfNoIntersection\n helper: PointSelectorHelperConfig\n /**\n * @description 是否跳过全景图渲染\n * @default false\n */\n skipPanorama: boolean\n /**\n * five 6.7.0 特性,可配置是否自定义拾取点过滤函数\n */\n hitFilter?: (intersect: Intersection) => boolean\n}\n\nexport type PointSelectorConfig = Partial<Config>\n\ntype EventMap = {\n /**\n * @description 与模型交点更新时触发,移出监听范围时为null\n */\n intersectionUpdate: (intersection?: PointIntersection | null) => void\n /**\n * @description 试图打点,返回false则不打点\n */\n wantsSelect: (intersection?: PointIntersection | null) => boolean | void\n /**\n * @description 打点成功\n */\n select: (intersection?: PointIntersection | null) => void\n /**\n * @description 功能开启\n */\n enable: () => void\n /**\n * @description 功能关闭\n */\n disable: () => void\n}\n\n/**\n * @description: 在屏幕上选点\n */\nexport class PointSelector extends Subscribe<EventMap> {\n public get position() {\n if (this.outOfFive) return undefined\n return this.pointSelectorHelper.position\n }\n\n /**\n * @description: 不在 five canvas 上时为 true\n */\n public get outOfFive() {\n return this._outOfFive\n }\n\n public get enabled() {\n return this._enabled\n }\n\n public get cursorError() {\n return this._cursorError\n }\n\n public set cursorError(cursorError: boolean) {\n this._cursorError = cursorError\n this.five.getElement().style.cursor = cursorError ? CURSOR_NOT_ALLOW_URL : ''\n cursorError ? this.pointSelectorHelper.hide() : this.pointSelectorHelper.show()\n }\n\n public _cursorError = false\n\n public actionIfNoIntersection: ActionIfNoIntersection = 'virtualPoint'\n\n public plane?: THREE.Plane | null\n\n /**\n * @description 结果区别:vertical: 射线和模型的交点在plane上的投影点;onlyPlane: 不论射线和模型是否有交点,都为射线和plane的焦点;onlyVirtual: 仅当射线和模型没有交点时,为射线和plane的焦点\n */\n public planeMode: 'vertical' | 'onlyPlane' | 'onlyVirtual' = 'onlyVirtual'\n\n /**\n * @description 射线没有命中模型时,是否一律禁止点选\n * @default false\n */\n public disableIfNoIntersection = false\n\n public readonly pointSelectorHelper: PointSelectorHelper\n\n public five: Five\n\n /**\n * @description 吸附功能总开关,方便临时的一键开启/关闭\n */\n private adhereEnabled = true\n\n /**\n * @description 吸附半径\n */\n public adhereRadius = 0.1\n\n /**\n * @description 吸附面\n */\n public adherePlane: THREE.Plane[] = []\n\n /**\n * @description 吸附线\n */\n public adhereLine: THREE.Line3[] = []\n\n private set outOfFive(outOfFive: boolean) {\n this._outOfFive = outOfFive\n }\n private _outOfFive = false\n\n private set enabled(enabled: boolean) {\n this._enabled = enabled\n }\n private _enabled = false\n\n private mode: PointerSelectorMode\n\n /** 长按屏幕的动作触发后为true,手指抬起后为false */\n private pressDown = false\n\n /** 一组吸附的点,光标靠近这些点时,会将helper以及放大镜的位置设置为这些点 */\n private adherePoints: ((params: { intersection: PointIntersection; pointSelectorInstance: PointSelector }) => AdherePoint[]) | null\n\n /** 有值时表明处于按压检查阶段 */\n private setPressDown?: ReturnType<typeof setTimeout>\n\n private lastFiveHelperVisible?: boolean\n\n private lastIntersection?: PointIntersection\n\n private mousePosition: { clientX: number; clientY: number } | null\n\n private _mouseDownInfo: { clientX: number; clientY: number; timestamp: number } | null\n\n private _touchStartInfo: { clientX: number; clientY: number; timestamp: number } | null\n\n private config: PointSelectorConfig = {}\n\n private get mouseNdcPosition(): { x: number; y: number } | null {\n if (!this.mousePosition) return null\n return this.mousePositionToNdcPosition(this.mousePosition)\n }\n\n public constructor(five: Five, config?: PointSelectorConfig) {\n super()\n this.five = five\n\n this.config = { ...this.config, ...config }\n\n this.actionIfNoIntersection = config?.actionIfNoIntersection ?? 'virtualPoint'\n\n const mode = config?.mode ?? 'auto'\n if (mode === 'auto') {\n this.mode = isTouchDevice ? 'fixed' : 'cursor'\n } else {\n this.mode = mode\n }\n\n const defaultMagnifierParams: MagnifierParameter = {\n autoFixPCPosition: this.mode === 'cursor',\n initialPosition: this.mode === 'fixed' ? { left: '35%', top: '20%' } : undefined,\n }\n\n this.pointSelectorHelper = new PointSelectorHelper(this.five, {\n ...config?.helper,\n magnifierParams: {\n ...defaultMagnifierParams,\n ...config?.helper?.magnifierParams,\n },\n skipPanorama: config?.skipPanorama ?? false,\n })\n\n // 刚开始的时候,因为没有选点,所以不显示,后面鼠标移动了或者点了之后才显示\n this.pointSelectorHelper.hide()\n }\n\n public enable() {\n if (this.enabled) return\n this.enabled = true\n\n // 设置一些初始化的值\n this.outOfFive = false\n\n this.pointSelectorHelper.enable()\n // 刚开始的时候,因为没有选点,所以不显示,后面鼠标移动了或者点了之后才显示\n this.pointSelectorHelper.hide()\n\n const fiveElement = this.five.getElement()\n\n if (!fiveElement) throw new Error('five element not found')\n\n // 添加一堆监听\n if (this.mode === 'cursor') {\n // 鼠标选点 / 触摸屏选点\n\n this.five.on('wantsMoveToPano', disableFiveEvent)\n this.five.on('wantsChangeMode', disableFiveEvent)\n this.five.on('wantsTapGesture', disableFiveEvent)\n\n // touch 设备事件\n fiveElement.addEventListener('touchstart', this.onTouchStart, { passive: true })\n fiveElement.addEventListener('touchmove', this.onTouchMove)\n fiveElement.addEventListener('touchend', this.onTouchEnd)\n fiveElement.addEventListener('touchcancel', this.onTouchCancel)\n // PC 设备事件\n fiveElement.addEventListener('mousedown', this.onMouseDown)\n fiveElement.addEventListener('mouseup', this.onMouseUp)\n fiveElement.addEventListener('mousemove', this.updateByMousePosition)\n fiveElement.addEventListener('wheel', this.onMouseWheel)\n fiveElement.addEventListener('mouseenter', this.onMouseEnter)\n fiveElement.addEventListener('mouseout', this.onMouseLeave)\n\n this.five.on('wantsPanGesture', this.onFiveWantsPanGesture)\n } else if (this.mode === 'fixed') {\n // 固定在屏幕中心的\n this.five.on('panoArrived', this.renderScreenCenter)\n this.five.on('panGesture', this.renderScreenCenter)\n this.five.on('interiaPan', this.renderScreenCenter)\n this.renderScreenCenter() // enable 时,自动加载屏幕中心点, 而不是动一下屏幕才加载\n this.pointSelectorHelper.show()\n }\n\n // shared\n document.addEventListener('keydown', this.onKeyDown)\n document.addEventListener('keyup', this.onKeyUp)\n this.pointSelectorHelper.hooks.on('intersectionUpdate', this.emitIntersectionUpdate)\n this.lastFiveHelperVisible = this.five.helperVisible\n this.five.helperVisible = false\n\n this.emit('enable')\n }\n\n public disable() {\n this.onTouchCancel()\n if (!this.enabled) return\n this.enabled = false\n\n this.adherePoints = null\n this.adhereLine = []\n this.adherePlane = []\n this.plane = undefined\n\n this.pointSelectorHelper.disable()\n this.five.getElement().style.cursor = ''\n\n // 移除一堆监听\n const fiveElement = this.five.getElement()\n this.five.off('wantsPanGesture', this.onFiveWantsPanGesture)\n this.five.off('wantsMoveToPano', disableFiveEvent)\n this.five.off('wantsChangeMode', disableFiveEvent)\n this.five.off('wantsTapGesture', disableFiveEvent)\n\n this.five.helperVisible = this.lastFiveHelperVisible\n\n fiveElement?.removeEventListener('touchstart', this.onTouchStart)\n fiveElement?.removeEventListener('touchmove', this.onTouchMove)\n fiveElement?.removeEventListener('touchend', this.onTouchEnd)\n fiveElement?.removeEventListener('touchcancel', this.onTouchCancel)\n\n fiveElement?.removeEventListener('mousedown', this.onMouseDown)\n fiveElement?.removeEventListener('mouseup', this.onMouseUp)\n fiveElement?.removeEventListener('mousemove', this.updateByMousePosition)\n fiveElement?.removeEventListener('wheel', this.onMouseWheel)\n fiveElement?.removeEventListener('mouseenter', this.onMouseEnter)\n fiveElement?.removeEventListener('mouseout', this.onMouseLeave)\n\n this.five.off('panoArrived', this.renderScreenCenter)\n this.five.off('panGesture', this.renderScreenCenter)\n this.five.off('interiaPan', this.renderScreenCenter)\n\n document.removeEventListener('keydown', this.onKeyDown)\n document.removeEventListener('keyup', this.onKeyUp)\n this.pointSelectorHelper.hooks.off('intersectionUpdate', this.emitIntersectionUpdate)\n\n this.emit('disable')\n }\n\n public dispose() {\n this.disable()\n this.pointSelectorHelper.dispose()\n this.off()\n }\n\n public setAdherePoints(\n points: AdherePoint[] | ((params: { intersection: PointIntersection; pointSelectorInstance: PointSelector }) => AdherePoint[]) | null,\n ) {\n if (!points) {\n this.adherePoints = null\n } else if (typeof points === 'function') {\n this.adherePoints = points\n } else {\n this.adherePoints = () => points\n }\n }\n\n /**\n * @description: 主动触发一次选点\n * @return: select 是否成功\n */\n public select = (intersection?: PointIntersection) => {\n if (intersection) this.updatePointSelectorHelperIntersect(intersection)\n\n const cancel = this.emit('wantsSelect', this.position)\n if (!cancel) {\n this.pointSelectorHelper.hide()\n this.emit('select', this.position)\n console.debug(this.position)\n }\n return !cancel\n }\n\n private onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Shift') this.adhereEnabled = false\n }\n\n private onKeyUp = (e: KeyboardEvent) => {\n if (e.key === 'Shift') this.adhereEnabled = true\n }\n\n private onMouseWheel = (e: MouseEvent) => {\n this.updateByMousePosition(e)\n\n const render = () => this.updateByMousePosition()\n this.five.off('render.prepare', render)\n this.five.on('render.prepare', render)\n setTimeout(() => {\n this.five.off('render.prepare', render)\n }, 200)\n }\n\n /**\n * @description: 鼠标进入five canvas时\n */\n private onEnter = () => {\n if (!this.cursorError) {\n this.pointSelectorHelper.show()\n }\n this.outOfFive = false\n }\n\n /**\n * @description: 鼠标进入five canvas时\n */\n private onMouseEnter = () => {\n this.onEnter()\n this.emit('intersectionUpdate', this.position)\n }\n\n /**\n * @description: 鼠标离开five canvas时\n */\n private onMouseLeave = () => {\n this.pointSelectorHelper.hide()\n this.outOfFive = true\n this.emit('intersectionUpdate', undefined)\n }\n\n private onMouseDown = (e: MouseEvent) => {\n this._mouseDownInfo = {\n clientX: e.clientX,\n clientY: e.clientY,\n timestamp: performance.now(),\n }\n }\n\n private onMouseUp = (e: MouseEvent) => {\n if (!this._mouseDownInfo) return\n\n const { clientX, clientY, timestamp } = this._mouseDownInfo\n\n if (Math.abs(e.clientX - clientX) < 2 && Math.abs(e.clientY - clientY) < 2 && performance.now() - timestamp < 500) {\n this.select()\n } else {\n this._mouseDownInfo = null\n }\n }\n\n private onTouchCancel = () => {\n if (this.setPressDown) clearTimeout(this.setPressDown)\n this.setPressDown = undefined\n this.pressDown = false\n this._touchStartInfo = null\n }\n\n private onTouchStart = (e: TouchEvent) => {\n this.onTouchCancel()\n if (e.touches.length !== 1) return\n this._touchStartInfo = {\n clientX: e.touches[0].clientX,\n clientY: e.touches[0].clientY,\n timestamp: performance.now(),\n }\n\n this.setPressDown = setTimeout(() => {\n this.setPressDown = undefined\n\n // 触发长按事件\n this.mousePosition = {\n clientX: e.touches[0].clientX,\n clientY: e.touches[0].clientY,\n }\n if (!this.mouseNdcPosition) return\n const success = this.updateByNdcPosition(this.mouseNdcPosition)\n this.pressDown = success\n }, 200)\n }\n\n private onTouchMove = (e: TouchEvent) => {\n if (e.touches.length !== 1) { this.onTouchCancel(); return }\n if (this.setPressDown) {\n let moved = false\n\n if (this._touchStartInfo) {\n const { clientX, clientY } = this._touchStartInfo\n if (Math.abs(e.touches[0].clientX - clientX) > 2 || Math.abs(e.touches[0].clientY - clientY) > 2) {\n moved = true\n }\n }\n\n if (moved) {\n clearTimeout(this.setPressDown)\n this.setPressDown = undefined\n }\n\n return\n }\n\n // 触发拖动事件\n if (this.pressDown) {\n this.mousePosition = {\n clientX: e.touches[0].clientX,\n clientY: e.touches[0].clientY,\n }\n if (!this.mouseNdcPosition) return\n this.updateByNdcPosition(this.mouseNdcPosition)\n }\n }\n\n private onTouchEnd = (e: TouchEvent) => {\n if (this.setPressDown) {\n clearTimeout(this.setPressDown)\n this.setPressDown = undefined\n return\n }\n\n // 触发完成事件\n if (this.pressDown) {\n setTimeout(() => {\n this.pressDown = false\n }, 100) // 慢点结束,不然有可能触发five事件\n this.select()\n }\n }\n\n private updateByMousePosition = (event?: MouseEvent) => {\n const fiveElement = this.five.getElement()\n if (!fiveElement) return\n\n if (!event || event?.buttons !== 0) {\n this.pointSelectorHelper.hide()\n // 鼠标按下时不更新\n return\n } else {\n this.pointSelectorHelper.show()\n }\n\n if (event) {\n this.mousePosition = {\n clientX: event.clientX,\n clientY: event.clientY,\n }\n }\n\n this.updateByNdcPosition(this.mouseNdcPosition)\n }\n\n /**\n * @description: 根据鼠标位置计算焦点位置并更新\n */\n private updateByNdcPosition = (ndcPosition: { x: number; y: number }) => {\n const raycaster = getRaycasterByNdcPosition(this.five, ndcPosition)\n\n if (this.config.hitFilter) {\n raycaster.hitFilter = this.config.hitFilter\n }\n\n let realIntersection: PointIntersection = getIntersectByRaycaster(this.five, raycaster)\n if (realIntersection) {\n if (this.plane && this.planeMode === 'vertical') {\n realIntersection = {\n ...realIntersection,\n point: this.plane.projectPoint(realIntersection.point, new THREE.Vector3()),\n face: createIntersectionFace(this.plane.normal.clone()),\n originalPoint: realIntersection.point.clone(),\n }\n }\n\n if (this.plane && this.planeMode === 'onlyPlane') {\n const intersectionPoint = raycaster.ray.intersectPlane(this.plane, _vector3)\n if (!intersectionPoint) return false\n realIntersection = {\n distance: this.five.camera.position.distanceTo(intersectionPoint),\n point: intersectionPoint.clone(),\n originalPoint: realIntersection.point.clone(),\n face: createIntersectionFace(this.plane.normal.clone()),\n raycaster,\n }\n }\n\n this.updatePointSelectorHelperIntersect(realIntersection)\n this.lastIntersection = realIntersection\n\n return true\n }\n\n if (this.disableIfNoIntersection) {\n this.updatePointSelectorHelperIntersect(null)\n return false\n }\n if (this.plane) {\n const intersectionPoint = raycaster.ray.intersectPlane(this.plane, _vector3)\n if (intersectionPoint) {\n const virtualIntersection = {\n distance: this.five.camera.position.distanceTo(intersectionPoint),\n point: intersectionPoint.clone(),\n object: new THREE.Object3D(),\n face: createIntersectionFace(this.plane.normal.clone()),\n raycaster,\n isVirtual: true,\n }\n this.updatePointSelectorHelperIntersect(virtualIntersection)\n return true\n }\n }\n\n if (this.actionIfNoIntersection === 'lastPoint') {\n this.updatePointSelectorHelperIntersect(this.lastIntersection)\n return true\n } else if (this.actionIfNoIntersection === 'virtualPoint') {\n const virtualIntersection = getVirtualIntersectByRaycaster(raycaster, this.lastIntersection?.distance)\n virtualIntersection.face = createIntersectionFace(this.lastIntersection?.face?.normal)\n virtualIntersection.isVirtual = true\n this.lastIntersection = virtualIntersection\n this.updatePointSelectorHelperIntersect(virtualIntersection)\n return true\n } else if (this.actionIfNoIntersection === 'disable') {\n this.updatePointSelectorHelperIntersect(null)\n return false\n }\n }\n\n /**\n * @description: 更新 pointSelectorHelper 的焦点位置\n */\n private updatePointSelectorHelperIntersect = (intersect?: PointIntersection | null) => {\n if (!intersect) {\n this.pointSelectorHelper.hide()\n this.pointSelectorHelper.position = intersect\n this.emit('intersectionUpdate', intersect)\n this.five.getElement().style.cursor = CURSOR_NOT_ALLOW_URL\n return\n }\n\n this.onEnter()\n if (!this.cursorError) this.five.getElement().style.cursor = ''\n\n // 有吸附点的话,就吸附到最近的点.adherePoints\n const targetIntersect = { ...intersect }\n\n if (this.adhereEnabled && this.mouseNdcPosition && this.five.renderer) {\n const mouseNdcPosition = {\n x: this.mouseNdcPosition.x,\n y: 1 - this.mouseNdcPosition.y,\n }\n const size = this.five.renderer!.getSize(new THREE.Vector2())\n\n if (this.adhereEnabled && typeof this.adherePoints === 'function' && typeof this.adhereRadius === 'number') {\n // // ========== 吸附面 ==========\n for (const adherePlane of this.adherePlane) {\n const distance = adherePlane.distanceToPoint(intersect.point)\n let newPoint = adherePlane.projectPoint(intersect.point, new THREE.Vector3())\n if (!this.plane || this.plane.distanceToPoint(newPoint) < 0.01) {\n newPoint = this.plane?.projectPoint(newPoint, new THREE.Vector3()) ?? newPoint\n if (distance < this.adhereRadius) {\n targetIntersect.point = newPoint.clone()\n targetIntersect.adherePoint = newPoint.clone()\n if (!this.plane) {\n targetIntersect.face = createIntersectionFace(adherePlane.normal.clone())\n }\n targetIntersect.isAdsorbed = true\n }\n }\n }\n\n // ========== 吸附线 ==========\n for (const adhereLine of this.adhereLine) {\n let newPoint = adhereLine.closestPointToPoint(intersect.point, false, new THREE.Vector3())\n if (newPoint.distanceTo(intersect.point) < this.adhereRadius) {\n if (!this.plane || this.plane.distanceToPoint(newPoint) < 0.01) {\n newPoint = this.plane?.projectPoint(newPoint, new THREE.Vector3()) ?? newPoint\n targetIntersect.point = newPoint.clone()\n targetIntersect.adhereLine = adhereLine.clone()\n targetIntersect.isAdsorbed = true\n }\n } else {\n const closestPoint = rayOnLine({\n raycaster: new THREERaycaster(this.five.camera.position, intersect.point.clone().sub(this.five.camera.position).normalize()),\n line: adhereLine,\n clampToLine: false,\n })\n const projectPoint = closestPoint.clone().project(this.five.camera)\n if (projectPoint.z <= 1) {\n const ndcPosition = {\n x: (projectPoint.x + 1) / 2,\n y: (1 - projectPoint.y) / 2,\n }\n\n const positionOffset = {\n x: Math.abs(ndcPosition.x - mouseNdcPosition.x) * size.width,\n y: Math.abs(ndcPosition.y - mouseNdcPosition.y) * size.height,\n }\n\n let newPoint = closestPoint.clone()\n if (positionOffset.x < 10 && positionOffset.y < 10) {\n if (!this.plane || this.plane.distanceToPoint(newPoint) < 0.01) {\n newPoint = this.plane?.projectPoint(newPoint, new THREE.Vector3()) ?? newPoint\n targetIntersect.point = newPoint.clone()\n targetIntersect.adhereLine = adhereLine.clone()\n targetIntersect.isAdsorbed = true\n }\n }\n }\n }\n }\n\n // ========== 吸附点 ==========\n for (const _point of this.adherePoints({ intersection: intersect, pointSelectorInstance: this })) {\n const point = _point\n point.IsAlwaysVisible = _point.IsAlwaysVisible\n\n if (this.plane && this.plane.distanceToPoint(point) > 0.01) continue\n\n const distance = point.distanceTo(intersect.point)\n if (distance < this.adhereRadius) {\n // 1. 距离吸附判断\n targetIntersect.point = this.plane?.projectPoint(point, new THREE.Vector3()) ?? point.clone()\n if (!this.plane && _point.normal) targetIntersect.face = createIntersectionFace(_point.normal)\n targetIntersect.isAdsorbed = true\n\n break\n } else {\n // 2. 屏幕位置吸附判断\n const projectPoint = point.clone().project(this.five.camera)\n if (projectPoint.z > 1) continue // 屏幕外的点不吸附\n const size = this.five.renderer!.getSize(new THREE.Vector2())\n\n const ndcPosition = {\n x: (projectPoint.x + 1) / 2,\n y: (1 - projectPoint.y) / 2,\n }\n\n const positionOffset = {\n x: Math.abs(ndcPosition.x - mouseNdcPosition.x) * size.width,\n y: Math.abs(ndcPosition.y - mouseNdcPosition.y) * size.height,\n }\n\n if (positionOffset.x < 10 && positionOffset.y < 10) {\n // 2.1 满足屏幕位置吸附条件,还需要判断点是否可见\n let pointIsVisible = false\n if (point.IsAlwaysVisible) {\n pointIsVisible = true\n } else {\n // 碰撞检测\n const raycaster = new THREE.Raycaster()\n raycaster.setFromCamera(new THREE.Vector2(ndcPosition.x, ndcPosition.y), this.five.camera)\n const intersect = this.five.model.intersectRaycaster(raycaster)[0]\n const distanceError = 0.1\n const cameraToPointDistance = this.five.camera.position.distanceTo(point)\n if (intersect && intersect.distance < cameraToPointDistance + distanceError) {\n pointIsVisible = true\n }\n }\n\n if (pointIsVisible) {\n targetIntersect.point = point.clone()\n if (!this.plane && _point.normal) {\n targetIntersect.face = createIntersectionFace(_point.normal)\n }\n targetIntersect.isAdsorbed = true\n break\n }\n }\n }\n }\n }\n }\n this.pointSelectorHelper.updateWithIntersect(targetIntersect, { emitEvent: false }) // 关掉pointSelectorHelper的事件,自己手动触发,否则会触发两次\n this.emit('intersectionUpdate', targetIntersect)\n }\n\n private mousePositionToNdcPosition = (mousePosition: { clientX: number; clientY: number }) => {\n const fiveElement = this.five.getElement()\n if (!fiveElement) return null\n\n const { top, left, width, height } = fiveElement.getBoundingClientRect()\n\n const { clientX: mouseX, clientY: mouseY } = mousePosition\n return {\n x: (mouseX - left) / width,\n y: 1 - (mouseY - top) / height,\n }\n }\n\n private onFiveWantsPanGesture = (): false | void => {\n if (this.pressDown) return false\n }\n\n private renderScreenCenter = () => {\n this.updateByNdcPosition({ x: 0.5, y: 0.5 })\n }\n\n private emitIntersectionUpdate = (intersection: PointIntersection) => {\n this.emit('intersectionUpdate', intersection)\n }\n}\n","/** PointHelper 纹理贴图 */\nexport const POINT_HELPER_TEXTURE_URL = `data:image/png;base64,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`\n\nexport const POINT_DOM_HELPER_IMAGE =\n 'data:image/svg+xml;base64,PHN2ZwogIHdpZHRoPSI2NyIKICBoZWlnaHQ9IjY3IgogIHZpZXdCb3g9IjAgMCA2NyA2NyIKICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCj4KICA8ZGVmcz4KICAgIDxsaW5lYXJHcmFkaWVudCB4MT0iNTAlIiB5MT0iMCUiIHgyPSI1MCUiIHkyPSIxMDAlIiBpZD0iYSI+CiAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIG9mZnNldD0iMCUiIC8+CiAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIHN0b3Atb3BhY2l0eT0iLjM5NiIgb2Zmc2V0PSIxMDAlIiAvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICAgIDxsaW5lYXJHcmFkaWVudCB4MT0iNTAlIiB5MT0iMCUiIHgyPSI1MCUiIHkyPSIxMDAlIiBpZD0iYiI+CiAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIG9mZnNldD0iMCUiIC8+CiAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIG9mZnNldD0iMTAwJSIgLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CiAgPC9kZWZzPgogIDxwYXRoCiAgICBkPSJNMzQuOTAzIDc0LjI2OGEyOS45NjMgMjkuOTYzIDAgMCAwIDExLjY0OCAyLjM0YzMuOTE4IDAgNy42Ni0uNzUgMTEuMDkzLTIuMTEzbDEuOTc2IDEuOTc3YTMyLjUzMSAzMi41MzEgMCAwIDEtMTMuMDY5IDIuNzIgMzIuNTIgMzIuNTIgMCAwIDEtMTMuNjA5LTIuOTYzek03Ni4wNSAzMy4zMzNjLjkxIDEuMzQ3IDEuMjIyIDIuMTM5IDEuNDIyIDIuNzI4YTMyLjYwMiAzMi42MDIgMCAwIDEgMS43MjIgMTAuNDljMCAzLjg0OS0uNjY2IDcuNTQyLTEuODkgMTAuOTdhMzUuMzQgMzUuMzQgMCAwIDEtLjc4IDEuOTQ0LjUwOC41MDggMCAwIDEtLjYzLjI4M2wtMS4yOTktMS4yMjdjLjEzNi0xLjQ5Ni4zNTEtMi4wNzYuNDktMi40OTVhMzAuMDI3IDMwLjAyNyAwIDAgMCAxLjUyNC05LjQ3NSAzMC4wNCAzMC4wNCAwIDAgMC0xLjQwOC05LjExNiAzNi4xODMgMzYuMTgzIDAgMCAwLS43Ni0yLjA4NWwxLjI2Ni0xLjg4NGEuNTA4LjUwOCAwIDAgMSAuMzQzLS4xMzN6bS01OS40MzQuNTgxbDEuNjczIDEuMjNjLS4wODUgMS40LS4yNjcgMS45MTYtLjM4NiAyLjI5YTMwLjA0IDMwLjA0IDAgMCAwLTEuNDA4IDkuMTE3YzAgMy4yNDcuNTE1IDYuMzc0IDEuNDY4IDkuMzAzLjEwNy4zMy4yNjguNzguNDggMS4zNDZsLTEuMjg0IDEuODkzYS41MDcuNTA3IDAgMCAxLS42NzQuMDExYy0uNDI2LS44OTMtLjYzLTEuNDIxLS43Ny0xLjgyNWEzMi41OTQgMzIuNTk0IDAgMCAxLTEuODA0LTEwLjcyOGMwLTMuODY3LjY3Mi03LjU3NiAxLjkwNi0xMS4wMTguMTIzLS4zNDUuMjk4LS43OTEuNTI1LTEuMzQyYS41MDYuNTA2IDAgMCAxIC4yNzQtLjI3N3pNNDYuNTUxIDEzLjkxYzMuNzM1IDAgNy4zMjQuNjI3IDEwLjY2NyAxLjc4Mi40MjcuMTQ4Ljk5MS4zNjUgMS42OS42NTFsLS45NSAxLjk0NGMtMS41NzctLjE0NC0yLjIyMy0uMzY4LTIuNjg4LS41MDhhMzAuMDU2IDMwLjA1NiAwIDAgMC04LjcxOS0xLjI4NWMtMy41NSAwLTYuOTU3LjYxNi0xMC4xMTkgMS43NDYtLjI2OS4wOTctLjYyOS4yMzUtMS4wNzkuNDE1bC0xLjg5OC0xLjI3Yy42NjQtMS4wMjIgMS4wMzUtMS4xNzYgMS4zMjUtMS4yODlhMzIuNDUzIDMyLjQ1MyAwIDAgMSA4Ljc3LTIuMDVjLjk4OS0uMDkgMS45OS0uMTM2IDMuMDAxLS4xMzZ6IgogICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEyLjcxOCAtMTIuNzE4KSIKICAgIGZpbGw9InVybCgjYSkiCiAgICBzdHJva2U9InVybCgjYikiCiAgICBzdHJva2Utd2lkdGg9Ii41NSIKICAgIGZpbGwtcnVsZT0iZXZlbm9kZCIKICAgIG9wYWNpdHk9Ii42IgogIC8+Cjwvc3ZnPgo='\n","export const rangePieceImg =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANgAAADYCAYAAACJIC3tAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAA2KADAAQAAAABAAAA2AAAAADs6jNqAABAAElEQVR4Aey9C7ClZ1Wu29253yAkJGBCQoAEdBOCbkSgkIMKKgSjIJvLPket2qVyDiLi8VLiPvFSp8ACEUuUAsXN3orgQQoBUVBBvLCFjbg1CiiICSEEwiUESELu6e4znn/OZ/a7Rn//XKuTbO1e7aj65jvGO94xvu///+9bc625Vjo7d/yb/WvegZ3/QpPv/Rea59+maXfgX+oBt2kPi/DO3tsDrb+zh+jO1h8WD/VAL/JAH+KB9j8c9AdyD7eq3aqu39+tHpKt6uh/INq+nsM+vqMP8nC9cVu9X+t0dzR3IPd83aG4oznnX1ev5t9weQfWPex/u0mLO7CVezTS3BnOez/qYS5x3aYf5e4Ml/Pij3p1zWEbb/UBHk43aCv3ZKRJLn3u3YHGeb97bebw123wnjuQuGs3m8t1jerMHXa42cM7XG7IZvdhlE/uzvjc46z3no84cyMcbezOZXxnfOfPHnLiupyabY8H+hC32w1Zd/09Nxcnry9yv/TFOS55/LSsTX5uEye/mT/Kb5VzLamXS9wsn9pt5c89uG11kYOLWXfdPWcs0k7/jmL2WOeTO1DLzbyZb/6OImuz1nX2WH6kzdy29N0g2/LiBhe17nozN/LlRjjimB5+Lmc+ER+zZhFt/TU392a+eTB9ZpvjzK1Dcpg9F9G+1zl+n2IbeUduo2vZ7FLmNm3yI18OvDM+68v6jLs/iuHWWd+4Geuvw8zh95i1y21lHXP6OX5dz0M25wM/ZC9giwufu87k9UcIl/wdiVlq9si4+8SY+kU0/zra+HIi1frgOr/nRvqu6f2JMXWLaN/rHL9PsQ28w+kdrD+u3Lz64DrffCJ9M9ZPfuTLgRh1aT3O3MjvG9ZYpEYf7P4oVpdIH9YmR5wGbx4+/dQdFv7hcMBGGzU5fbD7cgeKbJ6syVg/cZ1PbivGxk7LWD+x+8QHMnIufGq9f/ogBq8/EYfLy+FwwPqzdBPA64PdlxN3LTXGB4p9vlEMh9H7jlhu4pEvB3ZfruOepXbE9zWice364MjQzeVG+kOSOxwPmA/KjQB2X64fqs1i60bIvDnPKE4O/0Ctb1jjESaHnyMPFWvOGB/jXlBjDIfZlzr8jmgOGzvcDpgb3AecMX6OPEwjf8RlffeZU04fxODTepy5db6bW43xCOGSx/cgMX+PzdHbHD73oR8yeDT2IT4sbbsfsLmNmjx+H6PDIwemb62ccUc2GBzWMblJsHxRl9zIZzN3S04/Eb8P5pPj0BD3g1XUxHG9Hqy5dTqffUV6HBa23Q/YuofIw3Zj6Hf00ICb+dSq6X1Yh5z+jl/5lV+57+Me97jzTzvttAedeOKJ5xx55JFn7tq168SdO3cezSjhUTV4RkfUsHe5q0Owe+/evbtLe1vh7cXfsnv37mtuueWWT95www0fu/LKK//pjW984wde9KIXfW5ZY63oYUr0QLFeD5AHhZh1YPogWk2tMbnObSWn5pDGvDGH9IXMLD6vTz8RP4ebOBHfgVY/NfLZa+X/wA/8wKnPe97zHnfmmWc+8rjjjvuqOkT3qj7HLOcuWNncRlwJtugwdxp9b96zZ8/nb7rppn+og/fun/zJn3zXW97yluuLJ8fgoHRfDsyhfsTZY4TVZr/Dhm7bWn8Q2+1C8/r0wfQ9KHD6HiI5446Zx5/ietd48OMf//innXTSSY+sd5evqME7ETksN5Q+aH4SLXWdM9dxs/rso0/NTbfffvsnbrzxxr/9wAc+8MePecxj3recl5yHJ325EapLxHeUu7p2OC19uW2D3uxtc0HtQvL69MHR6IerH6ZRTJ9dz3nOc079qZ/6qWeeeuqpj6tv8x5YHO9OmJsnN9ki86//6j1gJfjYrXXg/vGqq65665Oe9KTXf+hDH7qluNFhGnFco7zXSzy6B3KVXuXxt515Y7fdhS0vKK+vbyhjDxbx6BANue/93u+9x0te8pJnn3zyyRfVOxTf8lHvxhJZhjw+1uMFO//a9T2er1xkur7H1sPnqO8o93zq+uuvf+ery370R3/0k5X3AO0OX87DZOw96Mh8cFr6ctsGuaHb2by+EcId0OF6whOecOLrXve6769D9R/q56izq54ebiA2FuaGMddxodr3Sh6jTi2xfkdyaf8r6umZ96Y+Q9n76Wuvvfb1T3ziE3/lfe97382V9yCNkGuB994kFr26R90n3lbmw9lWFxUX4/Ul4vfhZurvVtOnd5dccskjzz///Ivr27+vqVo0bqA8VM7B9OQxOPxE+M4Zk8MOpnrW433hOuqDyt3v+8M//MMfv+iiiy4lrpGHjLV7uEQ4R7mr6+s+8bay3BTb6sKWF+P1JeLnmDtcu/70T//0wd/wDd/w23xQsezHJuHjcAwfs3fG+MnjyyVarxZMn7wmb+x8Gcsl5nz0yJha+1qTGvKp96CBu9/61rc+6ju+4zsuLz8PmD51/YAVNfVzLmNwW5o3dzteXF6bPtjH7AGrn0E+VIfr9KrhqzQHyz7lrswNuCLCyRy+G7SvIUp27OF3WjXv7YW3VYJxa/n8josPHfbWt6fHVJ7flfHp5FGFR1Z+4irua2RexmizF706QPjd+vrtDR5dnz7+6gknnHBx+R6qxNG89JfHx4i3rR3Ov2je9KHWxr1Hidg0/V0rNx595jaJB8pD7AblF8NfrE/sruaXwvWzzcc+/vGPf/S3fuu3Pvhrv/Zr19CwbK7nIrv/69T7uc997ulPecpTzj3nnHMecI973OPs448//n71re05dShPrpJ83nkY8Ocs16HPt857r7nmmr+eK/o3fnEHfODb8X7ktemDfbj58zBM/m233fam2pyPqRreRTxk6+4Vvdl8DOeps7T3S3WQLqsN+f43vOENf/IjP/Ijl1fezVru5KPHkl8wi9cRnzX6YtZO/stf/vL7X3jhhV9/73vf+6HHHHPM+XXoTqsE10pvRv48VeHQpr8uqS8Of3LUUUf9H6XgcGadB5d++PYGMeNFtIj1tx3OPoxtcqVeXyJ+jn7AOBzYkfUucMRll1327tqI51Xst2tTMl6o91C5Wa+vb5/eX7+8/f2nPvWpf1m/V2IDYmwu5naT6ZsDMTfjItr6K/20kU9f1ojtPffcc49885vf/IQHPOABT6i/MDm/ON7lXBNfUDw45U68h+tP63D978XRT40HDc6DJcI5yt1wffDb1vIhbMeL9PoS8ftg0zHgOSz4E5511llH1Ldvf748ZLcWz8ZTx7dcaHmX+tx11133F695zWte+0M/9EOXLzUF+5kbqmMXmu/8uph1dUsu/a7b8731u72f//mf/+761vLC+vb4PiVAzyHhmrnOI+td/c+OPvpo37k8VJVaHTQOHGsfHS6vSaQufeJtZetu+Ha4UK8vET8HGwdbHaqlTzyN+9znPkdcccUVf7Y8ZGycqR+H6otf/OJbLr744t945Stf+aWlvmAy5yQYbSK5jnN6eHqqJ+6Wc+p3zBp62TP77q1vY+/xMz/zM8+uP/d6Uh22U0q3t/6O8Q/qZ7ofKN9DJHrQ6IHvIO6jqA3XkPOS21bmzd9WFxUXk9eHb6wP8k5l7LsXcR64I84444xdH/nIR36uPjV7dH0Vv+ztb3/7y77zO7/zw0ud9aCWfm4ifVF9xumbB+HpK8Kl5Zzpq0kuffrZk8OBye156EMfelT9HvDI+iX7dUveg5VIHTVy+PYyB4eJ3Z+S2+klb/J2ui6vJa8P31ifQ5S+71pw/bB54FKvD2JoRsaGUuPm6khdcuqTx09TY3+QNRirVScmn3PK94ORBwTfQS2+h0odMWYMYqO55BaKbfaaH9tus0tbezlsNDebvjEPHB/UN2ajeIh6Ho0byl5FrQw9hsZ+clOiXuxJbI+RJnN9PalXl0jemHnSnN8exmj0RbjR9ZKnv4gu56PmsLHD7YDx0HNDuhF44Lkh3ABwHgg5a9S7eeyLTg5NmjV+he+51DsPms67SdFkL3R9Hc5JH/SMrIfP/vpgDmp6bG3ycBo81ueUX2S38evhcsDcWD5sUR5MYwOwofg2ESPum4SYzWyOjQ7n5uk9K7XK6aunxj7WG6NNMw+nr5Z+Hjh8+7tOauA088T2ALMv90EdvIez64jtbb11lVr1WOeT21bmBtpOF+VDFrk2fb+6E7vp8B1qM4YbGRo3Enk3HHxuQnxz6DKG7/FIa52IpvvWieTVgcwzWpu6XmcsUp/a7hsndj/vGb6Wvty2wO36DuYDE/NhwTHYOObxNXkRPvPW5ob14KbWDak++6efvfVH67KmIzXObz2x8+cXknx3o4/6Pp+8GuI+7N95YvqZz7XQz/XgY+ixfp8W7CH+6o09xC9jtXwfEui1iYj0QR807+LJ45svd7V50Y90cmwUe1IH7+Zx062LqemWddkPnXHOr2+fjLu+a3Iucx6SXDe+I/P6ohqR+ckRayM/OXWHLOYDOGQvYrlwrqVfzyhOHT6HAhMz76Gyz0hjTqSXmwROP3l8zBxovdwkuAMvOac9RdsZ51xyaOAzlzH+3CGytufh5dSAWs4Fl/OpOSQxb+oheQG16H4NxiLXpQ/y8DwoHiA1qcM3VtfrrQPpq77zxFrfTPCdy176I6TWOe1hTA4zJs919D5oMOv1s04O9KCI5ozp03uZU5vIPFmTtanDP+TsUP+Qw02QiG/MA8kYPw+LuhEmh++Dd5Mad2RODD43lhyY1uudV03m8XMtaOTU97y8WtF5sn/X5vrRqbUHiMZexOn3tZlXA9oTP3m0mSM+5OxQPmA+HB+M6EMg5jBgmcPnwZkzD3bzMMFTp/ngRwgnTw0bUC5jeqnDx1xb8vqg+dTK9Xxq8LOPcXLr6sllPutG86eWuTS0mj6obw5M3vkyf0j4ows7FBae6x75W+W41n7QspYcsRsGPXFq4DR5N0SPU6cGzv7o812DHJx5a+Qyrw9uZnP11PW5Rhwa10K+r7nn1Yr2BLGul5uSy3znzB3UeKi+g7FBsMT053LJp09t1vPAjdOnBnNDoMHX9HuNsYherbXON0I5tCMfLvne27rR/CMOPdb7qAUz5/yZdz2po6c8vpacvqjmkMRD8SJYc193vgvxIDI/8pNLPTwbwncucpi8daN4odz3qhYmN1ny+9T75pDrc9jDeuI5jT06WgNvP3z7yOcccFjqjZPTF6eiqNsKj4aR81sn9r7GByUeau9g3niRm9r9jDMPb04kn4dTTebRaGrVwePnw7c2OXXmjBP1s7ecuK6e+axNHbWafK4Njth6taBc6tNHY8/057g5nlrnwsdG81jfc4uKg/DVBR+ES1stqa/RuCMFcunLgfkQk0ePpca8/CSIl8xLdy5j/JzfmkQ1cFmrxvqO5JNT33FOA48xp58Kyk2J5Ytc7yOPLP0em0v0muGcnzottes4cwcV+hX5oFpUWww32JvspkvsOcvVGKOT64hGbt09UZOYfvaRh9PkOpJPTt86Ub7jqF6NtV2TcfrWdbwjmrzn6WfvfH5dY465R2afUe6g4A72Bbo+sN/85PDVjnSp9carJ9YXu2aOd66e7/UZWyMn2mMury7z6fc8OY3extaA+urAfAfLOnL26H7GqRnxmU9fbXIjH47B2vqnl/Q4qMyHelAtarmY0drgHN7k1OmLtOp+xpmXF8lpyaVP3hh0TdaJajJObfpo1MN3c57OZ6zGeuPUOKcac503L48O39i8PKipI1bnWozF1KyrV0dd72XdQYMH81/TewO5WdxIRpqcN9m4a4hHteqsV9fnlQfdDNmv16PTRjo4eWszpnazefg2Vs1Ib27UV446/a4nh5nX7zrzyeuD5q33HQc+89bIo0+OGBtxi8xB+po34GBZojfZtYH6rlHOh2ReRDfy7wiXvaxnXje5XOrw01IjD5frz82jP9LCWafOXuTSH2nhtN4n+fTpmd86Zk4fdD1i51ybeTF16ZNnWJc5fXuI8AeNsfCD0VwX6M3VN5frTk4d+fTVqxV9gMai9aM6a8yNtGrop9/18Jhzpk7f+pEOjTry3bcGvlty1q3j5jS9xnnmePLmQP3k53y1ifq9hnhkeT9H+buUO9i+RcyLd9NxwfjG3lDj/NRPzhoQoyZ1E7l8Sd56EQm+cy5LVuuBn9P6Dpc19uk1zpE16dOj18jJe43OMao3Zy2x9QfCodWcx/l9pyNv/0T8tFE9ee9Jake+63eOkaZz1nS+x32tPb9pvNWJNm20FNyV/ehlP9AbmJzrSu2Im6u3JzXZV37EZX/r1I9iOevEXJNcx9TkHPqJvdZ4nYYclhrm7D8rqQGx1BtPieWL9ea8jrm6XIc19hvlNutj7V2NrmXLfbnwO2p3pnYrc/KVTXOuRG8ynDx6fXHEjXKpm/Opc1402FyvnjO2XkweX8u+ciN0TfRLk08O33n7O03qslf61idal7qRLweytjyE9lOTPTtnnbzXSSxnPUh+nY1q1unJbblms8n7RAeq7/WbxfYHuQjQkbF9Ug+n1nxyW6lX3+uN+3ydX1fv/L2m8+ZF55zTwc9Z1nSdueQ713PO03nWCJf1qaHOvD6IpU4/tQvVvgOZc2U9NXmvrLsj6DrW1W5Fs1rQukbmXLzxHG5V1+tdsPVg+t7A5Owx4vIdEF32M15Xb8/UwrmOXpu67qe216uVB+Wcb0mthVE9BfazuMcjPnt1fcYH4qsVc21wDK93TmNNauEwa8R8fgvF+lfrumqOR7cuN/XZ6iI2092R/Ghx9gHJZ6zPwkc+3By/roYctq52Li/vWumhTw6b48jNaa0Dt2L0wZxrEe17dZ6uM96n3Lhpeh1x56jNPvpi5jtHzJr9tm+dNnNzfl6/c8GtM3WpuTNc9tmwqTYkIli3wFFuxEW7WZc6bzii3sd8vjPBdZ2fSsnPYc6hRo51jObJ9akFsexhnHryGaPRrDUPeh2pgV9nWe986olHP3dZg87+cuqTt5/cKO51ag70IDlHx7w2csbpyzE3/pzZ23zG6ZPv8Rxnr7UTKxotrnObxfbaCtpLpIYLMwb1yWH9MMCpEeGwrM9c+uiyJ7E24nstWg/IKJcc16bWOcDUJD/n94dPfXLpk8tDoDY1zJNx+pmD7/UjbXIjX050DmOxz4UODkPDyFif/MjsS+5A/V6zX//NJh/lk5vzmShz+00cBDovrNfkzeo549zwcqLTEDvgsm9u7uyVtfi93rqcK/1RvVyiNbkmOO9J18qrEVOnr9ZY7HyP0cGt43Peruu1mc8cvn3UyI3e7VgXpsYauXwm5NSRX2f2EdHqd8ycPdUYr5CLW2c9n/HIH3H2N9cXAz/irAOzVr9j6nrOeJ0mc+lTy2CN6/pQk6ZWNDeKvX5yfR7rtoq9V9bZWw05/VEu8+mnNutTo+81dZ35RPw8WJmzHg7zPuZanGuhWLzKqTeX/bpvPIf0MNd9+0/YJ92QrCDzI19uDulnrvdmgeb059Ba9KnJdxx7daS2cz3O/plzLnuQ61zW9lzG9kjOueyR6FwjzpyYmu4zX1rG1ieHNuP0Mwff69X2nDH1owPU6/z2Va1550t0TbkX4LScWy7R3onpoyUecfYxZ7xCFjpnmRv5cmD69OvxaA403MD+tj7SwnER9k0NnPxmSF1q6OmDkUeDETNyXjWiOtEbbV4kjxFnv5x/ErS8nHXGI1Rj/8TUw2v61sLLdY28OKc1D476Zn6kMd/nz/nom5axPcknn3p950rsfo+pTa73Mp7wQP8W0QWDW/GZRN00YbywSP5NENBNTlp9vwh50Jxc1sGpQTfSoMfycC+Yxas9ktNf1w/Nulrz9srrlst6rzNz+nltqct6tXBq0vf61YHkNd9BiK0zv25+653TOPvoZy45ah3Omfnkku/3tK8breb6ch59NSCc8+mDm5pFXZi8fmL3iUecfc0Zd/Si1PUY/eiC1JPHZ6CTlzOu1GTGIqS+uBlHvm9QY3uAuZ7smb7XZh25NPvIGYvyoL3we961pKbXkOv5kQYO63prE12HnHXiHG8e1LzHxPS1t746Y3rjj8x5wa0MeqTOGMTst4jqdW7i5PVBBw3051BNIj7GQqhzQembB/MrKDFmDT512Dp0LnT51S1rnB+UR4/JZR95MevhsOwzl7en+V5HrEac4+A1tJp1W+GypvvZp/sjLVyfU07ePiNeDsRSy/3K+zv3XKfCpTbr5eEYmL7I3tMfYdbgY+g22Fa/RewXZLwVZMK8GfgsRHTxxurhvXFqzIHdnEM0bw9jUI3oelKjDo159eZSP8p1LuPegxzzYOmzfuc3l4jfzXow/a7LWB1c97su45FvPYh5Xfhy+FjmFszG+ZPD78/TfmLm4fr9y/n0QYdf1K0zZu40a5lDP/OTn4vZL1mEizZH3Ac9DmRQj17k5zAGsWgO1PAzTh6fiyTvxabWHDpNLahWDo2cfsZwWvL4OdSAqcvYewGHr9mnx/1a1InqsxfcaH5rzBmrN845vb85T9bLy83F8nn9oxo5dHlN8A57uH+IefOQ33XOOecccdttt/3m3r17L9+zZ8973vjGN56zzKNx0C99+yeWZNbQbbD9iMoml41HvhdALv0N2je/+c1nf/M3f/P3XHPNNf/zvve97x+X1oc0Qrjk06/UZPlVhbmwnJOazqsBscyP4q1y9OnzUYs5xyLaGPe61HjNqZnjUkMPdfZzbdwz1yOnVsz6Oc2cNufbisa50I7msoc59Kzfa9AfoVr25I6zzjpr1xVXXPH2nTt3PrTC62ucUAftn3bt2vVN5Ts/yD3aCmaNfpVORryyaQGraGvO6II8XOCG8fa3v/0BT37yk997wgkn/NDZZ5/9m7fccst/KQ1fadTh51ce+xe94YYSY1yAmkRzeYHkRyZvPZqsI1aDryWX+uRTKw86zOd1yCVmLXzW41tvDuzWa7Kn609N1qvdCjfSUjfinVd0fmPnk7eHMbrOmQM37Kv73Oc+R8Th+kzlL6vx+TpsX/l7v/d7Dwy9daK9srd+lW3NKOgml8ikNu++ccdJX2/LrzvyyCO/ser/ucY9a5xy++23v+2oo476/vIxblgOOL6S+C7ljferC3k5fCzX6jrh0bEuLXNwWTeK5dDRa7N69aBmjWt2TvLppx6/653fnLXyifZK5P5ljTnrzBNj4iLa9zzoQc58R/WpgUudfud7rTrn5Fnm88w9R23GO88444xdV1555R/UO9UFlft0jc8iKju6xlfdeuutf3jMMcc8q3zX6h4D+0Ajl/qiV/X64GS5WLlELsyHAq8PejH6xDmOePzjH398Ha5HF39tjS/XuKLGNcU96eabb+adDL3vZvRhYNmTOG+0utTKqVVPf8w8aK7XT8J4sUZKfY+T775xn5Me5tLvnOtXY16UT8THUmOcnH7HqXhZby7r+7WgyYEWjRxxt3W57N+vnz7k7U9ML6zjro985CM/G4eLA2btzeVff/TRR3/Tgx70IA4b8zhcWyK5jPtclR5bXgAKC7u6NzfuizKe8PWvfz1fHY6p8fllQy7wihrX1FeOC7/85S+/tHx7+a2iPeAxcMRNyeULfTF7WbtgFzdWX4160AdmDsyeau0rwqfJi+TwGVwDZqwmsefUd6RX1pHHer2xuUlUL30t5tXbW76jefWjezXi6INZn769zFHP6Gsl748UWYPvfZny9WMJX9xvqcHhwuyJf3WNY9/97nf/p0Lq1o0+T8k3XAOxhnZlLn5FLJ0U6Sfi5xgu7pRTTnla6W6twTuYFwd+vMaX6gb8h2c84xknlU999q9wGFOrTk2uw7yIBlOjP5HxknnoXh/SLc2PPte5rl4t+pw360f3xzpRfce5PLxGDWNufnWg/Tt3R+p7L+bXek4eVIfG4T3icGE768eTywt5h+ITRWpyfKni20477bRnFI72r33nsMo23At0+xmN58zG5C2W67jfAn/4h3/4lPpB8pyq/WKNvDB87KYau/7mb/6GA5j19Cbuc1AH1y1584n6zks9XI7eM3P61onyzm9sXpzjzXfs/ajX7JVIbl1sruuSz/6j+dFiidarz/wkXurVyY1Qzag/evPWGs/pp/30rne961eXBacUsk4HNP4Xao+e+4IXvOCM8kd7cLQP5+am537mAk0YZxMnyQXo89VCHzTeefXVVz/nnve8548V9+Ea/PyF0ZcLwy6oj0o/V98jP7b8/OFRH/SG6FOXPnnmxdL3OuD1vSY4LHljuUmw1MiJqc055UVy+qI9yOmLncv6zNHLONE5rBPh05LXF9Hhsybus9bz8mjQku+a5PDzOtUmpl/yVT/7+5ztQ4zvH0u4/+CmbxHJ1++83l2HiAP2QeIazlPujuNrPPjaa6991cknn/zi8rkex+4t+PRCDzrK3TeHi4Z04fiaHNiHFwiPvyGubw+fWNxtNTxc5a4e2gnlH/OFL3zhrYXW2QOdPfExYixvjuuRU7NQ7r/eOd4+5kG5RPM5T/rmQdZEzmtTl2uFky93NSc+Zh60T+etV0tekxOTxx/Vyrl+4+whlz2yd16j6wYxc4to/zWMeo9qXA99R2ulP7ld9bvX3y88tsaJNTgMmD1vKP/Wk0466RsLJ/0S6U/sPGJRGzhjMA39ZDTpZrIjOidKdCGrBZ5//vnH1DvTA0vP97lcjF8Vyp38Uwt3P+c5z/mvhdkLrWuSL2p1Q+Aw0BtL7A3DV4OP9VzGmbeuY+p7zpg++qADPi2vjb7WoNFPTdamRq2YOjiHvNegHtzq/NakXk5kHn0RznnxMXPigt2nyznMiaMcfdaO5z//+ewx3o3usWzkIRO/WHv1fhdccAGHkHtPv47r5qAteUxcRI0w2ZsxWQ6/DUzUR3fE5Zdf/rT605SfK/+jNfgZLI0b9bB6677siCOO+I7yuVA4bsI69IaIJV9tklw7/Fw8l/Oayfsgk7MfeSxzc/EkDK19RXqkr76jc6sV0eF3G3Fo5MXk7GFOTI2cSC6fhdrM64Ppp9b7kJy+6D1gf2HEfU92btqLaOvDjrfUr4buX/7f1mAd9sPn4D3o0ksv/c/nnXfeG8vnmvz2EHR0ntjh9YmVWlyvC4YYGQtZN6jP/BSfeeaZFxXPwvIDDhZTP3bt5VPDoz772c/+UWHWu5bkSrK6GfhY3pwFs//D67xxrhUue3lzusZa9a4PvdzSXcX2lVdLnPVeszpwbn57imqtlZ+rV+f81ltnfh1vDuSanItY65y6zI98OXG0rryPc32p4xq9tzuXe+2o4vjRBKPWXnzCvaf+hO/CQte+Dku2nw5uaC5ilOwXuG5Scj64nfVXGg+teFp4YV7M3vqB825wL33pS99ciLkGb1jq+5yLivkLHK05a/C9sfjZn9i14KeO2N7yWWtOHGm8P/ZSK8qDmjVo1HVfDTVqrFcLdp05tWDWcw1qRLXGqc/6fv2Z07eHPZPHH81vjWhNzmct3HTNv/RLv8TP+sR3XyK+NbwRXLvcs94j0XlGWGUrIz80Gq2zbIzORslvWEz9fReHi09nvlDDC0k8ud7Frq4Dxi+f6UPOfuVumMObAI85v7x95VOTHPxoHvs4v5pRn9RmXh4Os5doXlyo9l2LOhDr8YJdvKpRZy5r0jcvWu9aQLgNz3Aphle3pPa7//DOl5o+T+bw7SuqVwc6P5o+el4tvLbifuEXfuFz7LlKnFwje03fVRX3xRonvfWtb+VPqqgbjaJXfPpojRMn0gOWIptPgngZadSKux796Ec/dlnDXy1zMZgXxXwn3nTTTXwv7NzkMfunnxw8fZwrdfhazglnD3GOs77nna9j6rOm833zug77qZc3tqe6OUx91uiP7nP28n6h13ct6uwlJm8NOW1Unznr1dlDhE/fWtDa5NDaK/P6O2vPXVIaPknk8wJ7gwwO2I7HPOYxTyhY1Qx8ZObxu5HTJr/ffJOgYhtuCe92t7s9rGpvr3FjDS/AC7o7fetvxN5RqLkBiZ3TnEi9OXsaz63La0td9sPPvsRqu5+x1+K8o/Wbo07L3nJganPN6jtmLb7zZx9467xGY3KYcc6pn/lJHC9ev5TziuSdUw3ofMnJm8v587rQGeP7zoOPUe+cfX3k9/7DP/zDO5e66UeUpV4tf5t424knnvjQpcZrGWFJpvl6Dn4/ywvaL1kETbDEbLzIxoT1vey5RfZ3L3TcFD6xue2iiy7688I0LxSO/sRyoFy5q7WYh0vfOOt6/dproEHZqCc8tSOT73OhzRx+DnupyWcil5i18n2O7KleTY/VipvN70bPPnmvzDvfCJ0rkX4+M3h7ymWcdWp7vZqpvv6TqT8rgt/Lsgex7Mfe/HJ90nhOode1Dku2eqb4s5Y3M0U01/RFeXDDIi688EI+peG35h4wLsJR7o671cfzn7jqqqv4wdILhLd3auFTQ4xxM7BRbsQt1Pte1YhmiJPz2sjru05QrTl0mpx6eTF5tebEEW+diFYd65GXM7anCD+3fvvM1VonOpe94c3Jdcz5zVkzqu+c9dbQw3e11K7y7Dn2Xul8B0s99dfVOHm5h4m9LjBNHi5z6a/0cwfMYosS8YfjxS9+8WMrR08W64WK1BxX3wv/c2HWmwc1eqDBRH1z9pAX5a0zJo8Zi50zBnNNxJh9XUdq7KmGXOfMZa/U4NNbyxyc9fJyxuKo3lpyuf6sSU3vbZyY1y+fPbK3eVGdGtG1dZ33E16N81sroknbu9x7xxWJBqPWwZvCrhe+8IVfX2i+3Mnsmby+ObUbMB+kCQuNRRvN4Y76XcKjlmIPGKEXwLvbzk9/+tN/t+TIjQy9X12Yi1izF9hzqdFHg6nPWH4SDF7Qju5Procye2aLPp+51KZvPpG8mo7oOmdsD+LOmUtU45pHOTm1xPpgjtTC0zfvmb459YmpgTfWJ3bApbF3GGlTfe29vy+SedmL1ovs2R33v//9H1mQ1zPnI++GdoPlBrLRBkEFc/x+uvrPT76qSP5Knr+QZ+FeKL9g5hOcHfVR6P8AZ6zPtapvenT073pkcBqakamxfqSDcw569Br7jnjvq/3n6ns+e4362yf7qzOXPeVEc84jnzjn9xrvDXy/f2rV9J7EGLrN6ifhUoefPc2xT+Bdhz2N0e38gz/4g/fh1F48qcbk8lJGwJ695fjjj38wxBbMtYNp8hNnUlLkAebgo83Nxq76Hvcv6hfJ1H2gBr0WV7GX3y/vfFDF9yjkKwQ8P4dxY8T0/Rmt49SvajB81wtqzG8OrmtSa07dgaK9ep+5+ZMfzZUcvuY8Wd99tHLcS2qI05I3J6LTT9Qnv9V6dWCaMT2zr/4I5eyT95o9Seze1Af9V6XIrfZyHSy+wPOx/EdqpFFzfuWPqL9N5NtE9t5WBteUg/WuBhNvZky8FeMQ8TE872BOkHUn1gH8dBJrfOecQ0rJmbcVMXObE8nDa/IgJi6i/evN9zr1oP03mz97jHx6JZ/PCB4zv4j2xT2vLvms73n7ieSZf109WvP4Xr+8Oe9P8uZE60HNHPW9B5rMEzu/enHKLfcg303ZK/HG2sP8Kd9Wzbln9fnwRiIbgProjFf4rGc965Ti+a9HOWCYp5q3L74SnFD/otTHSZSRS9twE5YJOHTegJxfruOopxrXikYuEb/PAeegDrNGrUjOOZKDx+DyfqsBs6c8NWnwDvTqRLTmQXvC66s1FtFg5kXyjsxbBzqX3Kh2lKOfPKi/WX1q9cVeyxza1H+5B/ln29C6D8nh8/uwIy+++OLTC8n3UdRk8gT4s5ZfnRStK8jG6if8ru/6Ln7+wvwF8yKqG1d2TAW7brzxxk8uSfp4U6D6nNPNCN5YpCat15vr6x3Vq+k9ks/71HU5l77zqBXl1YnmE/Ed/WDKp55exvqpM9c5eWq6mRNdf/agpsed6/V9HmN0ozmsVyeqTdS3hlhuxw033PCpirmf/PEvlnkO2I4nPOEJ/DgzMnrady6f/PTzUhL62WizhlP+fve73wOWxSzSRYscsB31H79ducwRpqkDsUR9vsIwlzE61yYHyonoNLlEa7vGGFSTdfDG+BqcwzpRfUdq4dBlTl/egyYPpl/hZMk7Nwl4Y3sa9z49th7ErEs/uUnUXkbrVzKaz96jvnB5PWoT8TfYF7/4xSuWxDH1hR+XFwdvDnwafj+wjP6MOTM3q/OC5xrI26DjKn/3u9/9/svAd7Bp0cuL4D9m21H/ndjHC+gxXdkS9eExYzHnlENnn8zLkceIMXERLV7ntH2OuXp4tfRyDjnr4LnPatQlZp46zZp8TnLWox1xc7xaerJWY5E6DQ6by3mt5lNvnUhOvZyx9fBY9sHP658Ey5es10/Ez3jHxz72sSuWtcfUjy7+CKJm+vGm/tzvnNK4BuT4jozxu2XdfgvfkKzKHvdmq/jYY489swL+FIWh8fPXnhr8bLbjLW95y2UmGnojvNBMm4NjPW5GeOJeA+e6e65SG3Lq4LVe7/yiOnCzejTWiXCa9eQ05weTz/zIT84ecok5Z/q5vhHvWjKnT/+sdz45Ed4aOH341BBjcJiInzX6+bMUnDz6DVb/jPvHIGpP9ncwerB3b69/UpC9PGe9d4831OVi8N28IMOPP9OX24C7d+9+U328ycLeW0PbyTtYXcyDCs+s/MMrwYU4+PADnz8OlhPJcWOJvfmiF5XrL9l0Y80Rs24suaxJX53azK3zpwmWc1i7Wa+sST/r7ZGoFuReoAcxUb/H8iBmHnR0vsfWjHhz9gL7+rqGPhjPWLM+Y3x5nql92YP4DPcjPhrG8KP6+iTxryvHz2Ifrb1p3wqnPo+q/FX1X9s/pWL24LrBus27b+nnnl1twOKm5uDIWHQ3L2zK8RWhBEyWxrsXk5HjH79hcsyLEuf6q19U7XuF7zWjuNerGfHkcuybbeFZA6ZP1r4L5f4x/FwNtX4hQOca5LL3yFcv0gPL2DpxtBZzHRfdFq/mNqtH5/qpRD+qMWdfYnxja1JnLzTmR3rz6tWCX2a/1mC/Jo9/e/HTjzTl08NR7gZzzg3kMljl8iZ04UrUiuYm5NtA3olYJIODxUeIvIvxlYR/YXXO0Pf50I7m6hy13dAkn771IEbOfPpTsl7UzcVZYx+14FbrU4dPL/7r8J3vfe97v/P6669/TX2X8Jc13oMPR44Jyibtwp1e5QnSD8nKzfVDeg1irydOrtfbOOutAdftud7LeeDx7ekcoFzWzmmtu4U9yd4sYvVus/Q5dNOPNIqXiJYxsjl+eLGz4uo8l4P3HSwXPF10fUXYVRfDn6Jg3pBFtHilHl70ZiWq7/WuqdfLgw56jOpT6zxy1hjfkXp6WG9/kQ1nTiS383u+53vuWf++5K8+6lGP+qn6b5UeUt9iH8/AhyNXvx45bVk/Whd9tA29izSend/CQu8tFH7ORR97gebkitqvHk5LXfrk7aVWLvm5ObNX6vmifyt7cvkO1nvyJsEBy3o0Gvy6XOpWB6wX9NiiWazF8nsFv0XkglajLojvj30HG/X2BoCZ1wfVyBW1wdRkXg7hunpz6KyRA+XMgxg8A+u4YBevo5y1zrNBU+9OO375l3/5hfXp7Ndlo/TJvfzlL38B2jL72Sel+H0eOLTw5uRAzF7qFuz+r9aD1nTOeP/qBWNdzrWO631Sm1/k0Zmbajhg7MkazsXaHLuXe3nSHsDLhjmsW/d2jWZYZHFDnnJ+izgtuBbLz2H8neK6dzBaeYGt7X4hOkxcRPvH8oneULis9zq3sgY06rN39pNX13O5jq6ZtH/xF3/xnesOlxOgQbuM181jiRqR+fsa1CaqgcO3Xk2PU69GHOWsF9WCcNTkvF1nPP1oQtHAJk0drFvYk+zNwSHjTYIfabZqo2tZ1W52wFbCLTgsigOGcSHTqAsg5quFB4w4DYE3T95FT8WSSzQn3TWjXtY4F7Vdl9xIb77fsz4/Os1c9jMnqjGe1vWQhzzkyRKb4VKb15PzJU8rc7bN+c2J5oi7D6cu/d5XjXzG+lmffp+TOGvoqSb7q+m5SbPci9M7WB2y/l3X7spP3xLY8M5g3yx3phcHjMWu3p5robX+6VNELmb6M5TBBNwMbkTeDH1vVJapHeXQ9byxPeytVl5UT3/XRs75Mp+9sl4/a3oPYuuda6Wv/2ziATbZDJdaeym3p+uVV0de35wov1qPiWVN53OOdbW0GWnlxXU9zKEdWfZ3nRt0y714xPJwqRf5FJEfae4SuysPWF/Q9BE9h6xGz41iboY3RFTXG2R+5MNZYz5Rf13/Xq8WtD+YvXpsj6y1XrRXarJn8pv5WcfcDDkxe8Ax+jrVJi9HffrEGJyD2Fq1Irn01WZtz2dN6pLH10b15hJd4+pNIZN3hX9XHjC+PaQfi/b7YA4Z72r84Dj9PWL568wL7uhNlaeHvogGPzF1+Bo66+B8IL2+67Ime9ljlFcHjvLJ6e+tP4y+LAvX+Uut1z03jy3yWtWOOPUd0c5tSNdPTe8Jl/nU4GPkqVMnkkuDNyc637r6Sbvci7fzxT/60J/r4t3LH3Xg7pTdlQeMPzNhcV7whFxEGW+76w6YN6dfTPL2TU59ctykjPWtpwbOQazBobMmNVmvfoQjnf1G+s5N9R/84Aff0hNz8VJL3Whuy9bl1Kxbp/1B74t6kT59HnOdd05QDf5m/bueOG1Ub36aZ7kX+cKPNgc69jB7+S6xzQ4Yk2/V8oC5aL/S7a7f3/jLu7yZ9lbvetQ4vwivVk1y9JNXl7WZQ2tOhNO2Wt979ph+9u85+M5N8WMf+9g31f+36v0uZg7RoF3m7SVmGRwj15Lzd23GWQNvnKjv3MQ5qMscsTXq4LTk1GW9vjjS2EuctB6wQvcntfoHesCc1zk2oBu6i3q8oWgU1DsVB4wPOqh1IK3UXr5aeMDgunHheaOcX06kLrWjPjm3enX2NRazvxzY5xrV9/nUZE99c9k7OfipX/0fQXb84A/+4MXrDhk5NGitC4TTcn59cvjD+S1cojVd22Qb+lGTY6TtnLHzOK8or24OnXeYr4N1NHuyBnlesi8HbO4Tb/Rzlj1WGg/YiihnKFzy63L8Ipl+aNT51/R8i+gBM1eylcFxU0QSxvjJW99RPZiGzqHGvNrei3hdjvrU2G/UB86vjtaBcFqvm/jXvva1V9f/Q/j//Ku/+qv/t/6H8R+s3yXeyMCHq9z/habE1lPnuvHhR/PLo8GsB7PenHlzHdHBbVaPTvP6qbG/OVFezDnkQNfT64w3IHuxhj9nUe9gTf5Kyf4bapfazhlnzeSv+4Vaim0Awu+Xq68G/PkJ/+acOZBPELl4PuQgh/WbIbehrsipviFazZvdv0hYh865ROewh1ryaqzLnPpE9F1jj8zZL2vlej283IS8Oz3ykY/k5zF/Jss8esz58N24yWc+eXpljC8n9jyxpib7y4nkMGIHMbxrTY05tPYV7akm0X2QGvIj4x2Mf3+D76ww58fngPlXR8Rarr3P0WNrVn8qBTErmsk5oXX8nqsf2OlTxLoQ/iNM/qERLwTMkb3UlGS/NVljjtj54bCuWbD7Xu1vXc4tZx8wuTlejZg6/DTXrBZ0pA5fPjH5kd+vP2vxe43xIrPxGcl1tE+/lyMdh8g1kM8affjUEGPOk7l+kMypzevXF+mJfyJ7cvnFnzrXCLKH/Z1t712plTnfighnlXOxkdvPXYn3ywRRX2n5VoX/bRF6FsqY/pq+gAN29Pd93/fxD+Nwgd28Abke+nTtaC1qMoc/V5861tHrrZ3WjyDMXFCTm7w+9fhp5pzTnPxmsf1GmFzO7Vyiuj6XPMiYu/5eR2xNzzFnDvOJ5J27r9G498hYDT3ls3/6O9mDdbj4Sw3/y3vyeb3H1V7+Qhat8V33rCQ39EjUG/R4VVOL+mQFLHx6F+OrQw3yBXu5mB1PecpT7g8OrN8kJH1tOTd+1qAfxVmTmuTTTw395nLyICPn1hfVpA4fE1ObvLXrOHukFj2WnDr5ROeH0+CsF8nZxxpiffKa9cQHUk+d/ZzLHqKH37x7xRidPfBX9vSnP33ag8s9yd70TQANe/fo2sufWBVs7uScqDfELsw2G5KSyyJzoEPJ3vrHRD6+DKZ3sfoq4VdRtPzf3HfU/wP3HLDMi8+bCe8c8OmT6+Yacp6s0acufed0Dfbtcdakbz11vQZOrZgaOXQYMSM3DDE1qU2/UpPJgXP+UroWej3inD/Xb26uoevoNVk3ytnPtYjJ61OfPdR2Hn1yU839ypaN2JNTbexV9u6O5V4mpzlHR/Oz2A+YQhsR50TmxZWu/kGby5ek3ybyTwXw18popgN2yimn3MfCht6IXI+cUnN9PanDd034mjVgP5DqyFlPnTy+lvVw9jXfkbzD3jl/6tGpsW9HarPeGvuM1kyOGgy9PSeiXqyRV5Nr6Tlr4a2HS18NaL2+c3TeOdFlr5wna9CxL9Qm6qNZ2amnnuoevIG9iVXScQLC+h+if2xZIL8M9wPXMqtjcYqs7rE8ONvoTW960z8thSwSXX2iPD1XroEfGncfd9xxZyw1ADfAm5Bz5g1Tjk6NNeZAc/hq5UA586BGPrXwcxy5zea3Hkxzk6+rz3WkTx/rsye+axWT09/s+tG5LpF++h3XzeWcaPSpN16wG1+dS7ROHNXDuS50+qLzqZvi5T/OxJ9J8UkhnIMe0zvY6173OvcyXFpqk9ef5jAo3Ou7QnAbXAt6Y+MVvuxlL+MHQ35B5zvYhtq6oOuPPvroc5bdvQnLcHVziO2J33X5BcH+qcta+JFZJ6ZmxGUeX41onjhH8vqgdanlOjNWo34Uq0eDGYu950I1/w5onah+hPbOHHXYna1fdNn/2Sef+0Lf+VOnD057vf7jVN7B+Pdh+IJlDUjMv/h7y6tf/Wr+7XqvI7HoyeQI8GdtswNG4doG0RkdC5v+LyrU1Z9H+XsGZF+o/4PgmThh3pygJheeQc/UELNm85krej++16sRrZ9D6jV8Y5Fc+sSuLfXwadagndPB57vWnC43Sp+DGq/NemO1WW9OpEaznrjz6snhG6eOnAafuvRTg28v+URy2cs+I5x09a9FnVU1q08JY4+SZ+96uMrd1KhZa3MHjEKHDYzncMftt9/+6RKfXGPaGPUtIhc6PcD6eeya8o//xV/8xbML6UEO6zdjwS5euwbW+fHdHHKgHHnqzRFjxqlNTh9tr3c95DC0mDWJ8FmfOetYa1pq4LOeOPP68Jg9xQW7sUadtaDXlJz3sM+f9ebkQMw++GrkRHKY8ySfPppRDO+6Rbh1trP23lm1D/kOi71IX++/c9yt3sE+s2wiN4dL2Wp96PazPGA26qI5fj9d/QnPh4rkZzD+2ausq3Xvnb5qfNu3fdsjKpfzVrgybtbohvXFo4Eb6bO+1zmRGutHOjjnoA6tHHE3e8mrdS550F5ybjRj0Hp9c/CafuLIR++c5HNNxNagw8zLd7QXqD8VLl+yXl/sus3q1VsP6pPTT17f3KT79m//dvYeH8uzF6drWn5OwP3nv/Y4sfbwPxZuxaj3vqR+Az/a6KMiGlg4h/yzxH+1nIlfKPMt4h4GfhlvvXvOPPPMhyw1HbgZzu0NQpM3qdcQZ80on5zaOc58oj41+K5HPjG/Ino95FNjn87Jd0xd9k8/NdSbs1fPE3dO7Qjh0qwXzdkz5zcnju7fiFPfUS289xjUH+3pqebe9773Q0vHJ9sesGmP0qjsVF4uu+wy9rDXtQ6Rd/P6V/xoMSZtTmyh3BCf//znv6+03NxpsdQtv01Ezyc319UHHQ8qP82bAzfdiEwu/Tk+pbmm5PXJa6nFH/V3XeasF+3V0c3VdcYidfjG+j22v7yxKD+H6lyXccdeP5eH997gU+c9GsVwGDrHRCxfnFeux53vedciP3ede+tTbP6F6WurIZ8NoHcwxz1r7PmJn/iJ9y55OE2dc8Drm1O7AecOmMW9URbbeIXvfOc7+d3C50o0LbbQDzrUfL4+6LjvySfzY9oGy/lMyIneSFAuEb8/aDhH76vWftaDGA/KWjlrjBP1UwPnoCeWMX7Ob15Um5sGzlhUR50mJ3aemBzWNcmpmYRLbd4beGLXQozZU4TLe6OmX39qem3mqNdcI3n2tDry+HvrC/uO+m6Kn8E+T8xYfndV7rR29uxn2cMQZc5t7wW7j1eTvP4K5w6YApvnZPpqQLm99UHHRytmsZjvYFNQF/epco5929ve9uiJWNTh5g1ZpiaAz5zrIZl8j9VZL6LDzK/zsz++10jNOsve6uxFzl7mun40jzVdSw8568RR/9SO8vZT57pHWnLm0+/zW2vvjEd+zm1f5yGnL2YPOOvh1ex8xzvewZ47tt4A+BBDDeg4tf7nfOxd43VYsg09iIe27oAxAeZE6cvth9ddd93flZD/9ov/Fef0DlZfKXhLru8Wp/+F7J4LLrjgWyrGvCE5FzyxaxvlrFOb64DTkrcPuawnHuWyNr86q01MP/vZw6/4mbOnGnLJqSWf9WpEdZvh3BqzLnvKOz9x3jfX5PpFNGlz8yafPrX26mjOvcFczufajNFqex/2sIex5/j5i7+Z5d3MXyFxHXevcXT9B6x/U9jn7HFJNmiMwf3MhdJEs6GxqMb8CPe8//3v/+/LgntZuPw5jJDfnn++/pmxry2k3odU7spyHsi8YemTUwtvTo68Zs5YVJv53GTyInoHPdLvPclZJ3Y9cTe5xKxHnzl9+xiL8iP0Wu0vorUejkEsV+7KrBHViCthc+wJje9ImT17zt7uH3XUmrMP8c4TTjjh4YV8ezj9BcdyT3r9pyN+97vf/Z4C9HMDmTn8NHkQm9ADtqCWpMFSZCF0Fst7kVN84YUXfqC+SnyptPxCD878hJX7VH31OKM+EDmtcpq9iPNmyidaozZjOXpkTfpojPExYkxcRPt0qfdhzmmttZ+1qZfbikZt1lvnXOs0mbMHyPPwPuFjmTf2+dnH658KljXmrCdn764jRuecxvYgdg45ET5zuX/VUK9N3E//9E+fXj+enOG7VyXz5y8096ncdU972tP+gdzMKHqVSx/9rOUCu6gXzk0sv3oQ9XPYX1ezr6hhf3uBvEXvfO5zn3thYZp9RPrlDfXGUqPG+ozxfXhZo08+zdoRnzp8tSNeTk3vt67enOi9zJ7m7J+55PS9B7kOc9YmquuoJu+ffdSONH1+69HiO6y111xvdOasAeljrXOkbueznvWsb1vq2HvmRPboGbfeeit7Vs77bzzCkq+M/NA8AMNkkaPGyfWFTPEVV1zx9qo9sgZ/3Dt9tVh+YlNfKPZeXdxNp59++jcVos8eFa5ulj55/cTRjV0o9732tZrxhog+mLm8PGjPka/OvmrFzMul1ryohjh1+t671KvN+5N9zINZnxr7i1kj5z0zBvXRm7fWHOi8Pls0WtbJieayF/6Ip2aa6173utf/Vj7/BfP0CaJ7cZlnjx5Z/zEIexb9ZqMk+2nghjZ3wJgkzUnh9BO9YXB7nvSkJ/1RId/rnl0DSy3xx+vj+gue+tSn8lcfUw1kmTccTvPmzcXZ23WgtYf1oJy91MmLXQufOevsY07MvPNnj6xLvq/ffh2zv/WJ5LNXzqefaH84fVHOuF+PfNclT06j3h4gOrUjX23W64NZQ5x7aG/99caJtdceUofrE0stn7ahw6g9u8bNF110EXuW2Psm2j+xZPsZ+f1sdMAUdqQ4J9F3IeA0PvrRj95aF/Ghiv05zI/rqeGTnMsKj3rFK17xzEKNHDfTfvD65DDnTMwHMOdbb4+p2fLFGjX2ls8ac6kljza57hvby1iUt0/y5kRy5kVymvnslbq8p8nrz9Xbz3rng9fUGGdPOOKsN28P6+Hl8NWN/KxJXZXt2PvKV77yGYX8l/aXEtdY/XXRMj67zFxizQAAIERJREFUfqT5YP03YLeSU9PQeUdY0g3rI15ZHjAXt0qWIzdq7GLI4W+Ir7nmmncWxx9WTr8Ti49F+bsp/ij4+vpnx76jkI9LrQW9YfianLEon+sk53r11RHjY2rEBbtvfnnQGjWJ5HPd5uAxMf3Oea3wrhXfkbX4mD1GmhHnHIvqfa9qnddrtT9Kc/uq9nno6N37WC9aYX9jUA3Y51KvxliEd9iLmDXtqT+PYo9dv9xz5DH1fNJ93Oc//3nevSb9Es13rPSqlhwmLqLF64rLA5aC9BWDfbgoeeM9r3rVq3639Bye+y3rCqZ6NNil9cnOeWeddRb/0CP18GK5K5OHcJ7uG4Mjyzr7waWp2Yw3r94eXlfnySdnveuwXo0or84682Lq8FOXsb551wuP5TzZW19cqPfpiec2u1rQeTuq6XyP1eU65cTM7f3t3/7t8+oL+7mV/KelYPq97NJHe06N3fUp45sKmc9Bzl6iuUqtzDWuiO6sO2DZ0EZyHV3QCi+++OLP1beJfOzJBWK+NePXF5S9/EHw7V/7tV/rAes9iemH4Ws+TJEcvrE6+xGbU6sGzN4ZZ728WlEeTHM+12/OOhE+fXXymcPPeE7TexhnffZJX604l5PnOvVFar3+5PTNjeboGmO0+BnLcY/hxRX/5Cc/+T8R1P/Xmr/QmPLL33+hZx0PqH34j7/+67/Or5XIO5zLnsYdq2S4LvjJ5g4YjTT9xD6RC9uA9f8QfkM14YMM/x2E6RPFeud6bI371n8a8Jo3v/nNN1bebxO9IJE15LzGOX9y6fsg1ZLDjMnbe0rEi7waYyT6oL68HOvHsl6tSF7fOjCvXc1IZ806Tc/12LnslYg210+MqSHndcJp5o1B86BzJp9+1o/mR4ulTt/+07rq7w/vX7ov1167fqqomvgEkT15wmc+85nfKUQ/Gtm3+7SE09KXW/2eSmIoqmRvbuyiejzxT3ziE19btV+u8e+ixzfUBT/opptu+p2TTjrpZ4PPHvj0ADF8zJgbnybfOXmRPL4PTj1cDnhjNb1GXm3GcvTQF+c4+UXFxvkzp5+o7xyifEfzORd+3ldqrEsdXL8XXYd+xNkn54Hz+ZoHqc8ezimf6F6B0999/fXX85cZJ9V++/fRz55fVdwN3/qt3/r/LWuomxs5l/VilW2wDfzcO5gV2RjOYtAL0e+L233JJZfcUr/Ae0dpz67BL56/scZX3nzzza+vP5f6v8unxncv+xQ18WByxnKg3NJdrS9jdWrzQcmB+dCtSex+xtRjyeE7puRM3hyY9cb2EOG992pADB4T8a3rSA6D17IvnLmslTdnrXxHa73v5JnHuciTMy8WNVw7POb81oP2nPDBD37wS+sTwvfUAXt4jYfFuxcfvp1Te/OP6n/9xK+TXI9Irxz2hcM6LtjB67oDZhPLcsL0nTzRhe554xvf+HPVgG8Dn1zjQXVRr6v/LsfDpY5+HDSx3NXNwoe3P3G3/lDM++CIc83mE80nl755eqbJw6WfGnzWPzJqtKxPnry55PXNqct+3c/1W5919hJ7vbGYPbKPebFffz6brFOX+dGaXR96hjE4cVddddXuc84555n1M9hfcsiKf1gN7ME19tZ/mvKyQuvFVT2aTUalVxr8/SwXbjI5L3IOOaDm0pebsP4PIPeuXz4/rT4O/VD946N/XjUsHEvER8+FYsTpT+SStw6OGsw59e03yqtJTN+aziVPDuO6XU+uYUrWS9bouzY0c5w97aNWnjr7dM4aeWNRvteTz1zXZz59anovudSxZp8pPL7X4bzw1iaHLt8QiHNQZ16c8ve973131u+53lC/cP760lxR48z6cOPv6h3tovJzLtZDvBlmjX6VTUa8MhYwMvlE/NHgYka8HP3xNfwNi1jG3mxQc/EjvZreG340t7qO6kXmsl7tKAeHdc2CnedH+eScX+5Asd8r65N3js6NtHDqErlunxl85qjB5PSNRfmOmSen5b1m36GD80CJcI5yd+ysd7Kd9QcQL6t/tu1xdbiufMMb3vC9z3zmM68kWUYfhgcr/eSSt8b6RPzJcsFyYPIuVC7jrfi9X86DnwvNmN6Zw8dAcyCWaC4fgJrUyYFY5pjDhzUll3l7pzbz+Obkk5ur95p6jdcsb/1cLG+/Xk++cxlblwen16hXC8qpHeXUiGgxYrk5VMf1O+C6D+dzI4d1dA5y+qBjswOlTux9iFfG76BG5qLIdT/jUa0cC8ASXRQXgXkx9jRPLuuI09Az0OiTt89m2LXq4THjRNeTeX11xCMd+REvZ32P6dcNTer11dnDOLHnPEjrNDlf6pjX55h8nyNz3Xf+vAbrRWoybw84NebBXJN5EB7c6thMX60mcw7jDTh3wBDlojPuPrGWk+kn4jusAfNi5NW5DvuQz5z5RH17JWZOP3vDyWedmsyln1p7WENOv9cQmwOtzRp8LfVyc2hf8/aX773kU7/Op16j1np5ubl55K0DrRXt4Tx+Z5Jacl1HjHngjNXdEVx0XLzaT67HE+9FKErMnH7iVnz6qcve+Cwocy4QDt9857OmZFMPteZGKGdNIj7WNcbiSDMVLl9Sl9oR75qzvvu9Lmu632uN53TyIANjvowncsnhqxv563LosZGmz2cMup6peFkP1+8L+eStHenQaugw50xfTsxc943BDbaVdzAKcqHpb2i2DHLRUC6wI326dtlixVuv1rmtUy8vwqeffbqfOnxjEb2WnL440sCZZ834c2s3T82dNXv1uegLZ97YNRKnZb2+iC79rNPPPO8kXr886Nxy1natPDjSymcu373g141en9pRDm5T8+LmhJkf+XJzSF9zfY68Eerg1Js3VtP7yI90cJ3P2F6py7y868pc1roGdZmjZu5aRvyo15xOPmucOzF18MSuK/25mlG9fTK3mW9e7D0673rgGaP7r6bnNtNb55yJ6aMjHnG9h/EK172DIeqLzlhfXDUtx8XA5eJGMfVq9NF1M2dv5xXR64vZI793n9NaBzKcK/VyqSWPWdPrqXF+daC8vvXEaeicL/mRn+vTt97YuuTTzzx+5rKHfNe4VvOiOhDLXsT9+s2LaDS1ORc5tWD61olz+RG/ro/9hujihskiR/nk5nz6ZW6uf/Kp54Iy7r755N3AciBDLXPJ6YtqrIXHjLPPiEvtVLh8USuXsT3nauVdGzji7CMuZRP0mszhmxfNZ4zfe5vvmPW9bt23iL3PKLYfc+irc96+TvnN0D4iev2OmbOvGuMVbvYOhpBFd+vcZnGv77EL7OgNk3cekT76aPAZ6sudTE1i16gVR72sR5PzWZOYWn3QOjFr0rcmufR7PfHIOm8sOo8xPfDl7SnnzzVd1+uzDt9+qUuN/cHUpK8elKevPtgH2nVmLZoD9XvNfvPc0QNmI2+aMTjiMj/yRzXJ4Xvx8iL99EEHPDaK5SfBUtM5c513ruThWJ85YzUZw3WzrvPGWT/y5+rznunbU8x1yzlH5qyfm8vaRGvg0h9pnHOU6/W5Btdof3PGYvZNv+czTr+vIXvM+ls5YBS76LlGdySfi8fPeK6fvOjaMrYPHMNYLZiWtfJyYueJey7nUb8Oqaem97FG3r5qjXu9vPWivCgPds4YpL9zoNXUjGJz1qNJrteYm9Pl/K4ntfaTU5994dZZatXdGc4eE271gCHebKE23qpOvTi6KHuJaPF7bA9+DsscPDG9sy41c3nX0/Pw/ee9oiazb9b0XNabE603nkP7k9f3Gq1x/caiusynry6x512nvJg1+PJicqnNvLycc1krb5x6coysMb8ZZt/UzvGpmfUP5IDR5I4sfHbymYRziMp6DC8nenNFa9V23jrzIjoPERyWWmI0Wubw+zzq5K1dp7UGtL/1cN2H6+Y88PTwgwbizBFj9kxcZBav1oAjzRxnj6zvHHHPz8Ujrf28p8Z3BJ13Xe1WNDsO9IDlhD705O4qn97ZP302viYvwnPhxHIiOa1zHqbOo+9cxvjO1zF1zjvql1w+tLn67NX9rdTP9bVWTJ0cKC+6htTAzeV7zp693r5zqN48sUMO7OvIHH7v0/OjeMs1d+aAjSbe7GJGNSMu++iD+tToi3McPGa9N4cYX0SDZb8Fs+81c/q93h7OY7X6jJ0fLn01idbb13nFUb3a7IOffNanLjXJW0+d74hoGXCa9WLyctaAcnO6zve5er36uxIPeI67+oDd2YvxYdPHG9jRXPJcOLGcmkR8DE3eqM1qMm+9mH1GXK9VA44s16Y/6tFrXYc15Ed13qe5enh7rdP0nHHOn5x+7z3Sdw21XkvmRrXOc1dhzneHeh5sBywvwps64ry56zRZp9/rsl4/MW+wvL069nyP0cP1nsaplxvNkTn7wY3qU2svtYnpqwOzXk2+a6lVJ67j1djPOOczJ7cVjVrnHuHoHo10dxl3MB8wLtIbIuaFw3nj8VPT/c3y9O01cFjyGcPnRui61OKnqbXeGI3XhN/ngEtTO1efWnz18s5PbA+5rrUmcZ1mlINj5FzZb85Xn3m4/KU3uZEua/7F/YP1gM3dKPmOeeO2klOv1hiEk++bxFzfKL0+4/Ttm1z6ufnkR2uYm7/X91p7gpnTF9URy4mZ6z4arlEt2Dnzauixzjcnpj7vZ+bRHBR2sB4wb443UITHZ3BDk69wFY/yqdUXqcWM82HJLRQbX82pN0bl+sSsRJe89alJXz1c1iWf+q4zl/NkH/PWiV6PaL3ziqlHow4e6/ULdh9vLPZ6eHukRm6kV/evigf7AePmcBMZ3ERvaLkrTh/E1Iibcevy/cH1nuZHfHLMgcFZMxHxMtKnFt/69Ed10XY/N3tm0p7J4asXk+vaHo9qRtxcT7QMr1tdctmP/EFlh8oB86a5mRK9wXJo5/xRLuvT73P2WmNr1IvyrAV/tCY11ozQenPZR26EOefcPJ03dk5Qf24Oa0R1GeMz7KcG7Dpz8s5vbL7XJn/Q+IfKAfPhcOO44VjH5NL3AfnLZHLYXL0P0vxCvU/fY/tnz+67fnvbo6O9nFt91suNtJ2zf9bLgfLp9/6jXNa5VnSY9emrB3ve+tRQi6kV57hJfDC+HAoHjPuWG8cH0u+nvFrrRmitNXMae4F9bFbjHOrcQPLZu+fU3Bm0Z+JcPzXkXdecNnnq0ozFzOnTv1vq+/yZ0wdHfXrff/X4UDlg3ihvqg8BlFMjbpZLXfrZb64HvA879fTJGnOJbg7RuUdInfOQNxaTw9+K2c/5XVuvTT59dMaiPXsPYnOiGn+fZtzz8qJ5Uf6gxvy7voN6ocvFeXNF6PR94F4LD9E8mL4auF5HLrn0uWfEoPePeDSK3tBnFI/WhA7L3/OsW/9CvfFVfe+f67QCDuuY3CRYauyZnLVyYOq6rz6vsdf2GmLrUnvQ+ofaO1jeSG+0mDl9cvmQurbHHJh8iB4m+qH1QBmL9lFv3BG9Ri7ngpfTzxgubS4nDzKw9BfMPi415qzpsdpcd3Lovd8d7QlvfR4u9dmj+8SHlB15SK1232J5qD6kfexGLx8YmV7jxsgqavIQWQfC55zWJzpnctRi9mVT9bx94Rn2KXelxe9mn6zvGueVR+u1yIGjueWpcU0gX5jzOsz1tVOPmQcZqcPf7KD1mio5NOxQfgfrd5gHhYmLaOOrDzo3GHqGG9H6RDWJdM5YvX3y3qrLmpEvJ9rTGOxmb7WgGzK5kc61imqYA84+xqDmvTQGU2/c88Zz9dZ5HeoPSTxU38G82T4EEMuHJieaM0avD7o5RDdYbj5qjPGznhiznpx9p8TyxRrXAzoXEuuX8tUc8llvfzlr6NdzvV6ttSK8tdmHekydaF9yatRljN+1zoNes0YcadQe9OhNOugXumaB+QDcqHld+qA+7dBiIrn01cJZK1JnXkwO3w2ir67z5kE0mYdL2yyPts9jLHaNPPPqoyH220B883DGIAanNrHr0Mrha3LMb09RzSGJh/o7GDc9H4QPCj43S+rgzflA5ajPHH4/dMTo+BbQue1jrlKrutSw+dC4Cc2J1NnLdcBp6Jyj6zKHnrw9xK6hl0bOnnDWW8Oa1ZDX5NTDw2k5t9dNDp44jbqszdwh6Xvxh+TiZxbNNfGQcvMoletIjYMcviifHP3k9ROdv28gNG4yNPRIjRw6jHgrRh8s6+F6PInqpefkRedlbfqgA505uPTVyKOV009c55M7pG07vIP1B8DDxEA3HrG+m4sDpAaO4cHLWD8xdVU21ZJPUy/nulIHlx+GELsm0HnokTwxfeAw5yJW5zziJFy+yHWth9181vD/0Ib3MOHn/GqTUyOicU5967YlbscDxoPigWI+7EW0ePVhk2MDqyUrl7wcOoY5Y+rskRx8zo9PXm6E2Sfz1pm3dx5ANeTwja2hn3pzaNO8NjgOErHrsA+cB1FfDagOP3n9oie+x/DbzrbrAePh+aB9aG4qcmwMbKSB9+GjQ8OY87OH2qyv0snkQHRsUpDYYS83t/nkS77a+PLW+27oHHmdctY7PzG5NOeHwydPb3yMviPf9aJ3PntbI0+fbW/b9YCNHhwPlocM+pBzI7E5GGgS5ZMryaQTyWGi/Rfs4lXOjdkPg3zORyV1GJg1rBPLOYm9RnmR+szZixrM9SVmDd8iWp/fLlJLLziMGg3fIcd6usbctsPD5YDlJvMBd86Hy8N388LhM3aecsopO0888cSjPvGJT3gw6WGfjpUamjo3mcgmxbenvk3UkR/lXLP9qdvMt6dzeF3wc8P51YKux35qnD97OddhgT6Uw+Ji4yJ98FD4xiN/yt3jHvc44rOf/ex/u+KKK/725ptv/oV3vvOdX72s4x5yOEC+YIFy8ObkO6YmtelnP/3so1YcaVKvj94Bl+tXs+t3f/d3z7vyyiv/4/K68hAVtd/9g9PUGh926Mbajhee16YP9sFGgmOjdZw2Wb1zTYfryCOPfPzevXs/vnPnzvuU9sg9e/Zcce21177tpS996e+88IUv/HxxGD1G1jebsUjNnD/q17mcd+Qn12uJnRvc84IXvOD0Zz/72U87+eSTL9y1a9e5CG688cbfOOGEE36qXL4dRAfyDua7GGguObTZX7/oFY+/7Wyzm34oX3Bemz7YhwfMr9getOmr+T3vec+dn/70p1+zPFx/VAfsj+tgnXjEEUd8dR20h1e/s2vsvv322y+pbx1//8UvfvGfvupVr/pSzFPuhk3k5uqITjNnvBX0GrtWXjTPHMnt/e7v/u4TX/SiFz353ve+N4fq/Mrvquv9VOElNe7F9da793877rjjLq64HyYPloeO/gwPmtckX6mVmVsR28XJG7xdrsnryGvTB3Pk4YIn5oBNh+2000474qqrrvqt5eH6w9ps76jcjt27d9tvR2260+uwPbzwYZU6uUadvz2fuOGGGy659NJL3/PjP/7j733Xu951I3XN3FQi6Tm/lQ7D1ZqWWWOR3lyXtvexj33sCfXu+3XnnXfeI+pny6+pazi3Bl9Yrq5rvaSu828Kr6agrnFv5f5jja9bHrL/p2gPmcgcHrQ8WPgYecdELF/gtqV587fjxeW14Rvrg3nA9KcDdq973euIT33qU6+tjfXNtck4XH88ukkettJxsu5XeF5twvNKe04NNuvtxV923XXX/c+PfOQj73/Tm9700Ze85CWfKR7LjYXvGtmQ+uiwzOuL5j1AyU/F9bLz6U9/+t2e//znP/zcc899RH2r99X1LnX/4rnePXV9nyz858K/L/xEXBe9tJ1V88wKHlGH7NX1Tvafy/dA+c7lwRKp74N+2Td9ctvG+kPcNhdWF5LXhm+sD3qowNU488wzd9WHGb9dh+Vbiudgva0OifUVTr322xRuSgRVe2Rt1vvXhvTAnV00c2A3Vb9P33bbbZ/48pe//Imrr776sksuueSff/Znf/bSj370o7ctJNPrfnNELt3V2h7xiEcc+2M/9mMPuOCCCx5w6qmn3q8O0tn1DnyfGveugrsti26vtV1Z/qUc/vqC8LHyb3H9tfZ183LI+MDjEbfccst/OfbYY59fPofJQW36xH0U9W8HjJtwKNtq09VF4Bvrg/2AwR3x4Q9/+OFf+ZVf+ary71vj+hr/vcZ7alznQatNtle/eIxaNpIINxkbtzbtsbWp71t1pxd5rxqn18bG59tKajDqb61xc2lvLryp8Kaqv7Hmwr+hOL4tPa76HL/E4wqPZVSKcRySGtq1Vce3edMo/xPV6+NVf2s7UK5btF7kYFXpHvCMIp9T46T6IvHrRx999E+Un4cq/X64iDGx+1Nyu7zkg9gu1+R15LXpgznygMGv3sXKP+Lyyy//trPOOuvZdTi+tmI2zQdr/FVtsg/XJuNbP/RsFPvnpoHbL1ebmhre4fbg18E4qsLTqx8H7p7lH1+Dg3LMcnB4Vn5x2C2OOjC3VH6K8Yvni8DVxV0NFje9IzIfhcxZPutybSJpfG3D+mt9rJP78Kga59S4rXr9j3r3/Y2v+IqveEvFHiqQPiJ+H0VtmCvnJbdtzI2xbS4oLiSvTR/sIw9ZHrCV/yd/8ifnP+Yxj/n++kr9rVV/9xq8q72/xl/XJv5Ubb5p8y4PXNGT9U2zszYk72STthSsA404bf6psl7ULWv2cjCWub0cEGI0IrnQrOqXNcDa+esaeEd2jh1eU9Xdr8aja/z7GsfUgb2yPq5/46tf/er/+rznPe+zxXE9fXBdcKB+uasYLq3HmTukfR7udrW8Nn1wNDxM5PTF6UMP+Ac+8IFH1y+YL6qf0Z5Rm5uP6PkQ4ws1+GDg72uDXlYbkx/2+cBjtVmJl8ZGci1yojk320inZvokk4NmcaE5ubX1UcdhomY6YOWTOrfGBTUeUuO0GjfXryH+rD6k+c2HPOQhf1lxHqjRhxv9cE39qw5Lf8EsOP1thaOHsF0uMK9NH5wbHigQjfHqgAW3qz6Nu2d9Bb+ofk/2LfUBwtdU7uga/Iz0T8vxz4X5aeHOOnT0ZYOBaZ1bF/ccfTq3Lt67PER8EeDnKbT8LPjAGg+q8e9q8HPcjfWO+Pdf+MIX3vXc5z73d8quKy4P1jqfnnnIiBlY+sZTYju+9Ae9na4xr00/EZ/hgdL3YPVYfj984hOfeOIrXvGKb6mfRR53zDHHfHX15Ks+dm2NS2tcUYMPFz5ZG5pD6OZmE3rwoA/I/v92zZ+3jiqI4kaKG0MTpUCisEXSgYRER0PpypU/hBt/Bxdu/CVc+oNEokqBRGVRIAGFU2AJhcgIpEDBnPfeLz6MZ++760eQvJuR9p0zZ+bevf/Ga69f9BVdlk/KxVNJBUSHKiT5gSoefRNF17O49LTS20W9qv8hfv17cXl5+fzw8PBF/A9Qf79RLK2C8hj5FFLG6PJtsWUuf1L2dgMmNavlZPLc5KPBHSk0xzvFFH1UcfpZxM7Pz58eHBx8HU+3r+Lp9nm8cKDgNDJ9peoqLr3Vu17513H4f4vD779e6kmjw/kvWxXJQm/wR9FWbyd1X7040aXX9CqqJ3Fh12/evPn26urqm7Ozs+fxd5V+IPDkcfQCcq5xVD5FRR+6HxpcKFvMZUmn98mBm97MbouJuTFXikE6nKKRDxdmXmneJnP5W0dHR4+Pj4+/3Nvb+yK+MfHZ9vb2bsh6Va+3g5gOmr7xoRcov6/wz8C/7Vq8EQxfb/T0qyv4YfCP7NKbSI0V+yueTr/E31E/xv/dvo+vdF1eXFx8F9/i+DUSOPhCCsJ5VUBDmrfzfsVlGV1bJEztY3EApjYpm4/PD+4oni8vKsXWFVXOz/3ha1jisg/ijeTWycnJJ/v7+093d3c/3dnZ+Ti0J1F8j/X0iaeeLr2uVxHperTCgC0VGoWn4vkjrtfxN9PreKq9in8Av7q5uXkZT6af42taP52enr6MJ5Xa+QHPBeA+hebYw72PivsYxGXKm6yx4VOdYJ4fvjBzNApGPrwX6aNCrTE6XCiT7pZ9j7V4Pqz4FbomTgGJu4/ei7R31Jjly8Cld9dHnwTqp+JcTRvtB5mNB7UuOlQqLiG5jspVnL4Ua10RvtOPa5nLd+PePkaPi3us4tK4yMcXUkho+BmrXNqA6l8mf5Y21wLThuuw+sYPHV6KywtN7Xiq0VersOibHB02tBZXTOa5S2X56eNHdy1zfGHmaCAFVfmtGOMQcg+0dT55k8G5FZg2mMOaed5U4iokGYVGkXgczVFthnxiQpnyMOdowqzr/pW5Dq/QNfHWlQuKXNcZCzGhDFx6M/uceoFpc6uD6Ro5fhDQdBxyYamtX+S6Rv+uqS/XK1+ajLyl1//pc1Ar/ApdE9/04n70K99tSPecyfH7buRDWoihOaK3UDGP42fUemQttyOnQtcyl99rfogrjibMvPLJc9RY3Iejt1AxTO0mb1N/gmkDtZEcdt9Q9HUbTZ735cUkfcj3GLxC18Rl1ZiXkfozz8N9eIWuiVf+Ok0j8rb4juKzs7Gb+JAXaGiurldcGrrjWK618zbuZ1750lpGEZDjPryFHss8+7qHa5XvmrgbbV2bJGfDJzm5YlKt+Xqs4mgV9moaUs51jSGTg9+L+eDig+oH7uicnEoj1kLFZLRferefQ/ptxoTYfTfyIS/Bujl7fB0nPha1frkNa4qOD2Z96KBmHR9Uf/BN0ftinPSJ79iKed5keN60yUyscyKt+efYkO86PKOG09IYLjn43s41+NCBzTo+qPZw8D7aunH0xsmbHFYbOrlJdkxo3TpUcdc24Rqet6/8jiksUrxYJLR8j43lVd+LAdiH92nyvGje2HnNvp5tz5pUOa45113G+owst0PPOHSYsz7Gz7m6Z6X1jiXnzcLv3cBZLMbAJHvWqMrp0aochtGKkePYOvw5ln3106v5PYfa5ZzZ+mM3cbYLtZp473q18oZiQ/p917wqGPU1pK+LMY5We3Le42oF/utNnePCjlnD3tzevLzevYe/N0/9j8nN45m9f9+NnP3CdSzApms7tv2mhbBp+44lmV/K2E2c3wq92xn/X+v/vnje7T4O9v4PRqxOxnwQYu4AAAAASUVORK5CYII='\n\nexport const rangePieceIntersectImg =\n 'data:image/png;base64,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'\n\nexport default `\n <style>\n .range-piece__container {\n position: absolute;\n top: 39%;\n left: 50%;\n margin-left: -54px;\n width: 108px;\n height: 108px;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: pieceContainer 0.3s ease-in-out;\n animation-fill-mode: forwards;\n }\n .range-piece__content {\n width: 100%;\n height: 100%;\n background-image: url(${rangePieceImg});\n opacity: 0.4;\n background-size: 100%;\n background-repeat: no-repeat;\n transition: linear transform 0.1s;\n }\n .range-piece__content--active {\n animation: dotting ease-in-out 0.5s;\n }\n .range-piece__aim {\n width: 100%;\n height: 100%;\n opacity: 1;\n position: absolute;\n background: url(${rangePieceIntersectImg}) center / contain no-repeat;\n }\n @keyframes dotting {\n 0% {\n opacity: 0.4;\n transform: scale(1);\n }\n 50% {\n opacity: 1;\n transform: scale(0.8);\n }\n 100% {\n opacity: 0.4;\n transform: scale(1);\n }\n }\n @keyframes pieceContainer {\n from {\n top: 49%;\n }\n to {\n top: 39%;\n }\n }\n </style>\n <div class=\"range-piece__container\">\n <div class='range-piece__content'></div>\n <div class=\"range-piece__aim\"></div>\n </div>\n`\n","import * as THREE from 'three/webgpu'\nimport { POINT_HELPER_TEXTURE_URL } from '../../Assets'\nimport type { Intersection } from '../../../../typings/typings'\nimport type { PointHelperAbstract } from './typing'\nimport { CSS3DObjectPlus } from '../../../../CSS3DRenderPlugin/utils/three/CSS3DObject'\nimport { rangePieceImg } from './html'\nimport { initialCSS3DRender } from '../../../five/initialCSS3DRender'\nimport type { Five } from '@realsee/five-webgpu'\n\n\nexport interface MouseGroupParameter {\n isMobile?: boolean\n useNormalVector?: boolean // 是否展示法向量\n ballColor?: number // 法向量小球色值\n}\n\nfunction createPlaneMesh() {\n // TODO: 改成参数传入\n // 底部纹理贴图面片\n const planGeometry = new THREE.PlaneGeometry(0.4, 0.4)\n const planTextureUrl = POINT_HELPER_TEXTURE_URL\n const planTexture = new THREE.TextureLoader().load(planTextureUrl)\n planTexture.colorSpace = THREE.SRGBColorSpace\n planTexture.minFilter = THREE.LinearFilter\n const planMaterial = new THREE.MeshBasicMaterial({\n map: planTexture,\n transparent: true,\n depthTest: false,\n })\n const planMesh = new THREE.Mesh(planGeometry, planMaterial)\n return planMesh\n}\n\nfunction createLineMesh() {\n // 法向量垂直管\n const zPath = new THREE.CurvePath<THREE.Vector3>()\n zPath.add(new THREE.LineCurve3(new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, 0.1)))\n const zGeometry = new THREE.TubeGeometry(zPath, 8, 0.003)\n const colors = new Float32Array(zGeometry.getAttribute('position').count * 4)\n const uv = zGeometry.getAttribute('uv')\n for (let i = 0; i < uv.count; i++) colors.set([1, 1, 1, 1 - uv.getX(i)], i * 4)\n zGeometry.setAttribute('color', new THREE.BufferAttribute(colors, 4))\n const zMaterial = new THREE.MeshBasicMaterial({\n vertexColors: true,\n depthTest: false,\n transparent: true,\n })\n const zMesh = new THREE.Mesh(zGeometry, zMaterial)\n return zMesh\n}\n\nfunction createBallMesh() {\n // 法向量圆球\n const ballGeometry = new THREE.SphereGeometry(0.01, 20, 20)\n const ballMaterial = new THREE.MeshBasicMaterial({\n color: 0x9ded6b,\n depthTest: false,\n transparent: true,\n side: THREE.DoubleSide,\n })\n const ballMesh = new THREE.Mesh(ballGeometry, ballMaterial)\n ballMesh.position.set(0, 0, 0.1)\n return ballMesh\n}\n\nfunction createBorderMesh() {\n const radius = 0.2\n const borderMesh = new CSS3DObjectPlus({\n pointerEvents: 'none',\n cornerPoints: [\n new THREE.Vector3(-radius, radius, 0),\n new THREE.Vector3(-radius, -radius, 0),\n new THREE.Vector3(radius, -radius, 0),\n new THREE.Vector3(radius, radius, 0),\n ],\n })\n\n const contentElement = document.createElement('div')\n contentElement.style.width = '100%'\n contentElement.style.height = '100%'\n contentElement.style.backgroundImage = `url(${rangePieceImg})`\n contentElement.style.backgroundSize = '100%'\n contentElement.style.backgroundRepeat = 'no-repeat'\n\n borderMesh.container.appendChild(contentElement)\n\n return borderMesh\n}\n\ntype PlanMesh = ReturnType<typeof createPlaneMesh>\ntype LineMesh = ReturnType<typeof createLineMesh>\ntype BallMesh = ReturnType<typeof createBallMesh>\ntype BorderMesh = ReturnType<typeof createBorderMesh>\n\nexport class PointHelper extends THREE.Object3D implements PointHelperAbstract {\n public planeMesh: PlanMesh\n public lineMesh: LineMesh\n public ballMesh: BallMesh\n public borderMesh: BorderMesh\n private five: Five\n\n public constructor(five: Five) {\n super()\n this.planeMesh = createPlaneMesh()\n this.lineMesh = createLineMesh()\n this.ballMesh = createBallMesh()\n this.borderMesh = createBorderMesh()\n\n this.addEventListener('added', () => {\n this.add(this.planeMesh, this.lineMesh, this.ballMesh, this.borderMesh)\n })\n\n this.addEventListener('removed', () => {\n this.remove(this.planeMesh, this.lineMesh, this.ballMesh, this.borderMesh)\n })\n\n initialCSS3DRender(five)\n\n this.five = five\n }\n\n public updateWithIntersect(intersect: Intersection) {\n const lookAtPosition = intersect?.face?.normal\n ? new THREE.Vector3().addVectors(intersect.point, intersect.face.normal)\n : this.five.camera.position\n this.position.copy(intersect.point)\n this.lookAt(lookAtPosition)\n }\n\n public show() {\n this.visible = true\n if (!this.borderMesh.parent) {\n this.add(this.borderMesh)\n }\n }\n\n public hide() {\n this.visible = false\n this.remove(this.borderMesh)\n }\n\n public dispose() {\n this.planeMesh.material.map?.dispose()\n for (const mesh of [this.planeMesh, this.lineMesh, this.ballMesh]) {\n mesh.geometry.dispose(); mesh.material.dispose()\n }\n this.borderMesh.dispose()\n this.removeFromParent()\n }\n}\n"],"mappings":"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"}
|