class Runescape{constructor(){this.mondrian=null,this.txList=[]}launch(t,i,e){this.blockHeight=`${t}`,console.log("blockHeight",this.blockHeight),this.txValueCache=i,this.parcelId=e?Number(e.split(":").pop()):null,this.loadRoutine()}async loadRoutine(){const t=document.createElement("div");t.setAttribute("id","css3d"),document.body.appendChild(t),document.getElementById("css3d").style="margin: 0; overflow: hidden; position: absolute; top: 0px;",window.THREE=await import("/content/0d013bb60fc5bf5a6c77da7371b07dc162ebc7d7f3af0ff3bd00ae5f0c546445i0");const{default:i}=await import("/content/036f12ea42d0fd664948e952b61f4c2f0d04e5672e7a7b3e2c33ac2544b6b1a7i0"),{iframe3DRenderer:e,iframe3D:o}=await import("/content/3b7fd16da25b50dc8042cee1b0ef7947c4ef83993fb9c74420d24bec94824155i0");if(await this.fetchData(),null===this.parcelId)for(let t=0;t<this.txList.length;t++)this.txList[t].size=this.logTxSize(this.txList[t].value);let s=0;for(let t of this.txList)s+=t.size*t.size;let n=Math.ceil(Math.sqrt(s));this.mondrian=new MondrianLayout(n,n),i.install({THREE:THREE});const l=window.innerWidth,r=window.innerHeight,h=new THREE.Clock,a=new THREE.Scene,d=new THREE.PerspectiveCamera(90,l/r,.01,1e3);d.position.set(0,n/1.6+2,0);const p=new e;p.setSize(l,r),document.getElementById("css3d").appendChild(p.domElement);const x=new THREE.WebGLRenderer({powerPreference:"high-performance",antialias:!0,alpha:!0});x.setSize(l,r),x.shadowMap.enabled=!0,x.setClearColor(0,0),x.setPixelRatio(window.devicePixelRatio),x.shadowMap.type=THREE.PCFSoftShadowMap;let c=new THREE.HemisphereLight(16777215,0,2);a.add(c);let f=new THREE.DirectionalLight(16777215,1);f.position.set(-10,100,-10),f.target.position.set(0,0,0),f.castShadow=!0,a.add(f),document.getElementById("root").appendChild(x.domElement);const w=new i(d,x.domElement),u=new i(d,p.domElement);let g=13576336;this.blockHeight<84e4&&(g=16356896);const m=new THREE.MeshStandardMaterial({color:g,wireframe:!1});for(let t=0;t<this.txList.length;t++){const i=this.mondrian.place(this.txList[t].size),e=.5*i.r,o=new THREE.Mesh(new THREE.BoxGeometry(.9*i.r,.2*i.r,.9*i.r),m);a.add(o),o.position.set(i.position.x-n/2+e,.1*i.r/2,i.position.y-n/2+e)}const y=new THREE.Group;y.add(new function(t,i,e,s,n,l,r,h){const a=document.createElement("div");a.style.width="350px",a.style.height="350px",a.style.backgroundColor="transparent",a.style.border="0px",a.style.overflow="hidden";const d=document.createElement("iframe");d.style.overflow="hidden",d.style.width="350px",d.style.height="350px",d.style.border="0px",d.setAttribute("scrolling","no"),d.src=t.includes("http")?t:`/content/${t}`,a.appendChild(d);const p=new o(a);return p.position.set(0,.75,0),p.rotation.set(0-Math.PI/2,0,0),p.scale.set(1/85,1/85,1/85),p}("7068d620cc1081d6d2f4b35372020f4d83b5f330679a71df75520984c38b6e24i0",0,.75,0,0,0,0,85)),a.add(y),x.render(a,d);let E=!0;!function t(){const i=h.getDelta(),e=(h.getElapsedTime(),w.update(i));u.update(i),E&&(p.render(a,d),x.render(a,d)),requestAnimationFrame(t),e&&(E=!0)}()}async fetchData(){const t=await fetch(this.txValueCache).then((t=>t.text()));if(t){let i=t.split(/\r?\n/);this.txList=new Array(i.length);for(let t=0;t<i.length;t++){let e=parseInt(i[t]);this.txList[t]={value:e}}}}logTxSize(t){if(0===t)return 1;let i=Math.ceil(Math.log10(t))-5;return Math.min(Number.MAX_SAFE_INTEGER,Math.max(1,i))}}class MondrianLayout{constructor(t,i){this.width=t,this.height=i,this.xMax=0,this.yMax=0,this.rowOffset=0,this.rows=[],this.txMap=[]}getSize(){return{width:this.xMax,height:this.yMax}}getRow(t){let i=t.y-this.rowOffset;return i<this.rows.length?this.rows[i]:null}getSlot(t){let i=this.getRow(t);return null!==i&&i.map.hasOwnProperty(t.x)?i.map[t.x]:null}addRow(){let t={y:this.rows.length+this.rowOffset,slots:[],map:{},max:0};return this.rows.push(t),t}addSlot(t){if(t.r<=0)return null;let i=this.getSlot(t.position);if(null!==i)return i.r=Math.max(i.r,t.r),i;{let i=this.getRow(t.position);if(null===i)return null;let e=i.slots.findIndex((i=>i.position.x>t.position.x));return-1===e?i.slots.push(t):i.slots.splice(e,0,t),i.map[t.position.x]=t,t}}removeSlot(t){let i=this.getRow(t.position);if(null!==i){delete i.map[t.position.x];let e=i.slots.findIndex((i=>i.position.x===t.position.x));-1!==e&&i.slots.splice(e,1)}}fillSlot(t,i){let e={left:t.position.x,right:t.position.x+i,bottom:t.position.y,top:t.position.y+i};this.removeSlot(t);for(let o=t.position.y;o<e.top;o++){let s=this.getRow({x:t.position.x,y:o});if(null!==s){let n=[],l=0;for(let i of s.slots)if(!(i.position.x+i.r<e.left||i.position.x>=e.right)){n.push(i);let e=Math.max(0,i.position.x+i.r-(t.position.x+t.r));l=Math.max(l,e)}e.right<this.width&&!s.map.hasOwnProperty(e.right)&&this.addSlot({position:{x:e.right,y:o},r:t.r-i+l});for(let i of n)i.r=t.position.x-i.position.x,0===i.r&&this.removeSlot(i)}else this.addRow(),t.position.x>0&&this.addSlot({position:{x:0,y:o},r:t.position.x}),e.right<this.width&&this.addSlot({position:{x:e.right,y:o},r:this.width-e.right})}for(let e=Math.max(0,t.position.y-i);e<t.position.y;e++){let o=this.getRow({x:t.position.x,y:e});if(null!==o)for(let e=0;e<o.slots.length;e++){let s=o.slots[e];if(s.position.x<t.position.x+i&&s.position.x+s.r>t.position.x&&s.position.y+s.r>=t.position.y){let i=s.r;s.r=t.position.y-s.position.y;let e={x:s.position.x+s.r,y:s.position.y,width:i-s.r,height:s.r};for(;e.width>0&&e.height>0;)e.width<=e.height?(this.addSlot({position:{x:e.x,y:e.y},r:e.width}),e.y+=e.width,e.height-=e.width):(this.addSlot({position:{x:e.x,y:e.y},r:e.height}),e.x+=e.height,e.width-=e.height)}}}return{position:t.position,r:i}}place(t){let i={},e=!1,o=null;for(let i of this.rows){for(let s of i.slots)if(s.r>=t){e=!0,o=this.fillSlot(s,t);break}if(e)break}if(!e){let i=this.addRow(),e=this.addSlot({position:{x:0,y:i.y},r:this.width});o=this.fillSlot(e,t)}for(let t=0;t<o.r;t++)for(let e=0;e<o.r;e++)this.setTxMapCell({x:o.position.x+t,y:o.position.y+e},i);return o.position.x+o.r>this.xMax&&(this.xMax=o.position.x+o.r),o.position.y+o.r>this.yMax&&(this.yMax=o.position.y+o.r),o}setTxMapCell(t,i){let e=t.y-this.rowOffset;if(e>=0&&e<this.height&&t.x>=0&&t.x<this.width){let o=e*this.width+t.x;o>=0&&o<this.txMap.length&&(this.txMap[o]=i)}}}