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="576px",a.style.height="576px",a.style.backgroundColor="transparent",a.style.border="0px",a.style.overflow="hidden";const d=document.createElement("iframe");d.style.overflow="hidden",d.style.width="576px",d.style.height="576px",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/135,1/135,1/135),p}("fa1277e5a4090fa72b2d2caacc0def9e4cb9651a6d38099e65364b02cea514f8i0",0,.75,0,0,0,0,135)),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)}}}