diff --git a/dist/colour-analysis.js b/dist/colour-analysis.js
index 280fc39..85e100d 100644
--- a/dist/colour-analysis.js
+++ b/dist/colour-analysis.js
@@ -1 +1 @@
-var ColourAnalysis=function(e){var a={};function r(i){if(a[i])return a[i].exports;var t=a[i]={i:i,l:!1,exports:{}};return e[i].call(t.exports,t,t.exports,r),t.l=!0,t.exports}return r.m=e,r.c=a,r.d=function(e,a,i){r.o(e,a)||Object.defineProperty(e,a,{enumerable:!0,get:i})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,a){if(1&a&&(e=r(e)),8&a)return e;if(4&a&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(r.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&a&&"string"!=typeof e)for(var t in e)r.d(i,t,function(a){return e[a]}.bind(null,t));return i},r.n=function(e){var a=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(a,"a",a),a},r.o=function(e,a){return Object.prototype.hasOwnProperty.call(e,a)},r.p="",r(r.s=0)}([function(e,a,r){"use strict";function i(e){return void 0!=window.colourAnalysisServer?`${window.colourAnalysisServer}${e}`:e}function t(e,a){for(;void 0!=e.getObjectByName(a);){var r=e.getObjectByName(a);r.parent.remove(r)}}function o(e,a,r,i,t){null!=a&&void 0!=a&&(a.innerText=e,function(e,a){for(e.style.opacity=1;a.length>0;){var r=a.shift();window.clearInterval(r),window.clearTimeout(r)}}(a,r),function(e,a,r,i){r=r||5e3,i=i||10,a.push(setTimeout(function(){e.style.opacity=1;var r=setInterval(function(){var a=e.style.opacity;0==a?clearInterval(r):e.style.opacity=a-.01},i);a.push(r)},r))}(a,r,i,t))}function s(e,a,r){o(e,document.getElementById("info"),window.info_id_registry,a,r)}function c(e,a,r){o(e,document.getElementById("warning"),window.warning_id_registry,a,r)}function u(e){var a=Math.round(e.loaded/parseFloat(e.target.getResponseHeader("x-content-length"))*100);s(`${this.name}: ${a}% loaded...`)}r.r(a),window.info_id_registry=new Array,window.warning_id_registry=new Array;class n{constructor(e,a){this._container=e,a={...{renderer:{antialias:!0}},...a},this._renderer=new THREE.WebGLRenderer({antialias:a.renderer.antialias}),this._renderer.setPixelRatio(window.devicePixelRatio),this._renderer.setSize(this._container.clientWidth,this._container.clientHeight),this._container.appendChild(this._renderer.domElement),this._scene=new THREE.Scene,this._observer=new MutationObserver(this.resizeToContainer.bind(this)),this._observer.observe(this._container,{attributes:!0}),window.addEventListener("resize",this.resizeToContainer.bind(this),!1)}get container(){return this._container}set container(e){throw new Error('"container" property is read only!')}get renderer(){return this._renderer}set renderer(e){throw new Error('"renderer" property is read only!')}get scene(){return this._scene}set scene(e){throw new Error('"scene" property is read only!')}removeObjectByName(e){t(this._scene,e)}resizeToContainer(){var e=this._container.clientWidth,a=this._container.clientHeight;this._container.width===e&&this._container.height===a||this._renderer.setSize(e,a)}animate(){requestAnimationFrame(this.animate.bind(this)),this._controls.update(),this.render()}render(){this._renderer.render(this._scene,this._camera)}}class l extends n{constructor(e,a){super(e,a),a={...{camera:{fov:45,up:new THREE.Vector3(0,1,0),near:.001,far:1e3}},...a},this._camera=new THREE.PerspectiveCamera(a.camera.fov,this.container.clientWidth/this.container.clientHeight,a.camera.near,a.camera.far),this._camera.name="perspective-camera",this._camera.up=a.camera.up,this._scene.add(this._camera),this._controls=new THREE.TrackballControls(this._camera,this.container)}get camera(){return this._camera}set camera(e){throw new Error('"camera" property is read only!')}get controls(){return this._controls}set controls(e){throw new Error('"controls" property is read only!')}resizeToContainer(){super.resizeToContainer();var e=this.container.clientWidth,a=this.container.clientHeight;this.container.width===e&&this.container.height===a||(this._camera.aspect=e/a,this._camera.updateProjectionMatrix())}}class h{constructor(e,a){this._parent=e,this._name=a.name||"visual",this._visible=a.visible||!0,this._loadingCallback=a.loadingCallback||u,this._cache={},this._visual=void 0,this._loading=!1}get parent(){return this._parent}set parent(e){void 0!=this._parent&&t(this._parent,this._name),this._parent=e,void 0!=this._visual&&this._parent.add(this._visual)}get name(){return this._name}set name(e){throw new Error('"name" property is read only!')}get visible(){return this._visible}set visible(e){this._visible=e,Object.keys(this._cache).forEach(function(a){this._cache[a].visible=e}.bind(this))}get loadingCallback(){return this._loadingCallback}set loadingCallback(e){this._loadingCallback=e}get cache(){return this._cache}set cache(e){throw new Error('"cache" property is read only!')}get visual(){return this._visual}set visual(e){void 0!=this._parent&&t(this._parent,this._name),this._visual=e,void 0!=this._visual&&this._parent.add(this._visual)}get loading(){return this._loading}set loading(e){throw new Error('"cache" property is read only!')}route(){throw Error("Method must be reimplemented in subclass!")}add(){void 0!=this._parent&&t(this._parent,this._name);var e=this.route();this._loading=!0,e in this._cache?(this._visual=this._cache[e],this._parent.add(this._visual),this._loading=!1):this.fetch(e)}create(e){throw Error("Method must be reimplemented in subclass!")}fetch(e){(new THREE.BufferGeometryLoader).load(e,function(a,r){this._visual=this.create(a),this._cache[e]=this._visual,this._parent.add(this._visual),this._loading=!1}.bind(this),this._loadingCallback.bind(this))}}class p extends h{constructor(e,a){super(e.camera,{...{name:"view-axes-visual"},...a}),this._view=e,this._colourspaceModel=a.colourspaceModel||"CIE xyY"}get view(){return this._view}set view(e){throw new Error('"view" property is read only!')}get colourspaceModel(){return this._colourspaceModel}set colourspaceModel(e){this._colourspaceModel=e,this.add()}route(){return i(`/colourspace-models?colourspaceModel=${encodeURIComponent(this._colourspaceModel)}`)}create(e){var a=new THREE.AxesHelper;return a.geometry.attributes.color.array.set([0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0]),a.name=this.name,a.visible=this.visible,(new THREE.FontLoader).load("https://cdn.rawgit.com/mrdoob/three.js/master/examples/fonts/helvetiker_regular.typeface.json",function(r){[{text:e[this._colourspaceModel][0],colour:"#FF0000",position:{x:-.2,y:-.2,z:1.2}},{text:e[this._colourspaceModel][1],colour:"#00FF00",position:{x:-.2,y:1.2,z:-.05}},{text:e[this._colourspaceModel][2],colour:"#0000FF",position:{x:1.2,y:-.2,z:-.05}}].forEach(function(e){var i=new THREE.TextGeometry(e.text,{font:r,size:.4,height:.1,curveSegments:8}),t=new THREE.MeshBasicMaterial({color:e.colour}),o=new THREE.Mesh(i,t);o.position.set(e.position.x,e.position.y,e.position.z),o.name=e.text,a.add(o)}.bind(this))}.bind(this)),a.onBeforeRender=function(e,a,r,i,t,o){var s=10*this._view.camera.near;this.visual.scale.set(s/20,s/20,s/20);var c=this._view.container.clientWidth/this._view.container.clientHeight,u=this._view.camera.fov*Math.PI/180,n=2*Math.atan(Math.tan(u/2)*c),l=2*Math.tan(n/2)*s,h=2*Math.tan(u/2)*s;this.visual.position.set(-l/2*.85,-h/2*.85,-s);var p=function(e,a){var r=new THREE.Vector3,i=new THREE.Vector3;r.copy(e.position),i.copy(a.target),r.sub(i);var t=Math.sqrt(r.x*r.x+r.y*r.y+r.z*r.z),o=Math.sqrt(r.x*r.x+r.z*r.z);return{x:Math.acos(o/t)*(r.y>0?1:-1),y:Math.acos(r.z/o)*(r.x>0?-1:1),z:0}}(this._view.camera,this._view.controls);this.visual.rotation.set(p.x,p.y,0)}.bind(this),a}fetch(e){var a=new THREE.FileLoader;a.setResponseType("json"),a.load(e,function(a){this.visual=this.create(a),this.cache[e]=this.visual,this._view.camera.add(this.visual),this._loading=!1}.bind(this),u.bind(this))}}class m extends h{constructor(e,a){super(e,{...{name:"colourspace-visual"},...a}),this._colourspace=a.colourspace||"sRGB",this._colourspaceModel=a.colourspaceModel||"CIE xyY",this._segments=a.segments||16,this._uniformColour=a.uniformColour||void 0,this._uniformOpacity=a.uniformOpacity||.75,this._wireframe=a.wireframe||!1,this._wireframeColour=a.wireframeColour||void 0,this._wireframeOpacity=a.wireframeOpacity||1}get colourspace(){return this._colourspace}set colourspace(e){this._colourspace=e,this.add()}get colourspaceModel(){return this._colourspaceModel}set colourspaceModel(e){this._colourspaceModel=e,this.add()}get segments(){return this._segments}set segments(e){this._segments=e,this.add()}get uniformColour(){return this._uniformColour}set uniformColour(e){this._uniformColour=e,this.add()}get uniformOpacity(){return this._uniformOpacity}set uniformOpacity(e){this._uniformOpacity=e,Object.keys(this.cache).forEach(function(a){this.cache[a].material.opacity=e}.bind(this))}get wireframe(){return this._wireframe}set wireframe(e){this._wireframe=e,Object.keys(this.cache).forEach(function(a){this.cache[a].material.wireframe=e}.bind(this))}get wireframeColour(){return this._wireframeColour}set wireframeColour(e){throw new Error('"wireframeOpacity" property is read only!')}get wireframeOpacity(){return this._wireframeOpacity}set wireframeOpacity(e){throw new Error('"wireframeOpacity" property is read only!')}route(){return i("/RGB-colourspace-volume-visual?"+`colourspace=${encodeURIComponent(this._colourspace)}&`+`colourspaceModel=${encodeURIComponent(this._colourspaceModel)}&`+`segments=${this._segments}&`+`wireframe=${this._wireframe}&`)}create(e){var a=new THREE.MeshBasicMaterial({vertexColors:THREE.VertexColors,transparent:!0,opacity:this._uniformOpacity,wireframe:this._wireframe});a.depthWrite=1==this._uniformOpacity;var r=new THREE.Mesh(e,a);return r.name=this.name,r.visible=this.visible,r}}class d extends h{constructor(e,a){super(e,{...{name:"spectral-locus-visual"},...a}),this._colourspace=a.colourspace||"sRGB",this._colourspaceModel=a.colourspaceModel||"CIE xyY",this._uniformColour=a.uniformColour||void 0,this._uniformOpacity=a.uniformOpacity||.75}get colourspace(){return this._colourspace}set colourspace(e){this._colourspace=e,this.add()}get colourspaceModel(){return this._colourspaceModel}set colourspaceModel(e){this._colourspaceModel=e,this.add()}get uniformColour(){return this._uniformColour}set uniformColour(e){this._uniformColour=e,this.add()}get uniformOpacity(){return this._uniformOpacity}set uniformOpacity(e){this._uniformOpacity=e,Object.keys(this.cache).forEach(function(a){this.cache[a].material.opacity=e}.bind(this))}route(){return i("/spectral-locus-visual?"+`colourspace=${encodeURIComponent(this._colourspace)}&`+`colourspaceModel=${encodeURIComponent(this._colourspaceModel)}&`)}create(e){var a=new THREE.LineBasicMaterial({vertexColors:THREE.VertexColors,transparent:!0,opacity:this._uniformOpacity}),r=new THREE.Line(e,a);return r.name=this.name,r.visible=this.visible,r}}class _ extends h{constructor(e,a){super(e,{...{name:"image-scatter-visual"},...a}),this._image=a.image||"Rose.ProPhoto.jpg",this._primaryColourspace=a.primaryColourspace||"sRGB",this._secondaryColourspace=a.secondaryColourspace||"DCI-P3",this._imageColourspace=a.imageColourspace||"Primary",this._colourspaceModel=a.colourspaceModel||"CIE xyY",this._uniformColour=a.uniformColour||void 0,this._uniformOpacity=a.uniformOpacity||.75,this._outOfPrimaryColourspaceGamut=a.outOfPrimaryColourspaceGamut||!1,this._outOfSecondaryColourspaceGamut=a.outOfSecondaryColourspaceGamut||!1,this._subSampling=a.subSampling||25,this._pointSize=a.pointSize||.01,this._saturate=a.saturate||!1}get image(){return this._image}set image(e){this._image=e,this.add()}get imageColourspace(){return this._imageColourspace}set imageColourspace(e){this._imageColourspace=e,this.add()}get primaryColourspace(){return this._primaryColourspace}set primaryColourspace(e){this._primaryColourspace=e,this.add()}get secondaryColourspace(){return this._secondaryColourspace}set secondaryColourspace(e){this._secondaryColourspace=e,this.add()}get imageColourspace(){return this._imageColourspace}set imageColourspace(e){if(!["Primary","Secondary"].includes(e))throw new Error('"imageColourspace" value must be one of ["Primary", "Secondary"]!');this._imageColourspace=e,this.add()}get colourspaceModel(){return this._colourspaceModel}set colourspaceModel(e){this._colourspaceModel=e,this.add()}get uniformColour(){return this._uniformColour}set uniformColour(e){this._uniformColour=e,this.add()}get uniformOpacity(){return this._uniformOpacity}set uniformOpacity(e){this._uniformOpacity=e,Object.keys(this.cache).forEach(function(a){this.cache[a].material.opacity=e}.bind(this))}get outOfPrimaryColourspaceGamut(){return this._outOfPrimaryColourspaceGamut}set outOfPrimaryColourspaceGamut(e){this._outOfPrimaryColourspaceGamut=e,this.add()}get outOfSecondaryColourspaceGamut(){return this._outOfSecondaryColourspaceGamut}set outOfSecondaryColourspaceGamut(e){this._outOfSecondaryColourspaceGamut=e,this.add()}get subSampling(){return this._subSampling}set subSampling(e){this._subSampling=e,this.add()}get pointSize(){return this._pointSize}set pointSize(e){this._pointSize=e,Object.keys(this.cache).forEach(function(a){this.cache[a].material.size=e}.bind(this))}get saturate(){return this._saturate}set saturate(e){this._saturate=e,this.add()}route(){return i(`/RGB-image-scatter-visual/${this._image}?`+`primaryColourspace=${encodeURIComponent(this._primaryColourspace)}&`+`secondaryColourspace=${encodeURIComponent(this._secondaryColourspace)}&`+`imageColourspace=${encodeURIComponent(this._imageColourspace)}&`+`colourspaceModel=${encodeURIComponent(this._colourspaceModel)}&`+`outOfPrimaryColourspaceGamut=${this._outOfPrimaryColourspaceGamut}&`+`outOfSecondaryColourspaceGamut=${this._outOfSecondaryColourspaceGamut}&`+`subSampling=${this._subSampling}&`+`saturate=${this._saturate}&`)}create(e){var a=new THREE.PointsMaterial({vertexColors:THREE.VertexColors,transparent:!0,opacity:this._uniformOpacity,size:this._pointSize}),r=new THREE.Points(e,a);return r.name=this.name,r.visible=this.visible,r}}class y extends l{constructor(e,a){super(e,a),a={...{scene:{background:new THREE.Color("#333333")},fog:{enable:!0,color:"#333333",density:.05},camera:{position:new THREE.Vector3(-3,3,3)},controls:{target:new THREE.Vector3(1/3,.5,1/3)},grid:{enable:!0,size:2,divisions:20,colorCenterLine:"#111111",colorGrid:"#222222"},axes:{enable:!0},image:"Rose.ProPhoto.jpg",colourspaceModel:"CIE xyY",primaryColourspace:"sRGB",secondaryColourspace:"DCI-P3",imageColourspace:"Primary"},...a},this.renderer.sortObjects=!1,this.scene.background=a.scene.background,a.fog.enable&&(this.scene.fog=new THREE.FogExp2(a.fog.color,a.fog.density)),this.camera.position.copy(a.camera.position),this.controls.target=a.controls.target,a.grid.enable&&(this.grid=new THREE.GridHelper(a.grid.size,a.grid.divisions,a.grid.colorCenterLine,a.grid.colorGrid),this.grid.name="grid",this.scene.add(this.grid)),a.axes.enable&&(this.axes=new THREE.AxesHelper,this.axes.geometry.attributes.color.array.set([0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0]),this.axes.name="axes",this.scene.add(this.axes)),this._image=a.image,this._colourspaceModel=a.colourspaceModel,this._primaryColourspace=a.primaryColourspace,this._secondaryColourspace=a.secondaryColourspace,this._imageColourspace=a.imageColourspace,this._viewAxesVisual=void 0,this._spectralLocusVisualGroup=new THREE.Group,this._spectralLocusVisualGroup.name="spectral-locus-visual-group",this._scene.add(this._spectralLocusVisualGroup),this._spectralLocusVisual=void 0,this._secondaryColourspaceVisualGroup=new THREE.Group,this._secondaryColourspaceVisualGroup.name="secondary-colourspace-visual-group",this._scene.add(this._secondaryColourspaceVisualGroup),this._secondaryColourspaceVisual=void 0,this._primaryColourspaceVisualGroup=new THREE.Group,this._primaryColourspaceVisualGroup.name="primary-colourspace-visual-group",this._scene.add(this._primaryColourspaceVisualGroup),this._primaryColourspaceVisual=void 0,this._imageScatterVisualGroup=new THREE.Group,this._imageScatterVisualGroup.name="image-scatter-visual-group",this._scene.add(this._imageScatterVisualGroup),this._imageScatterVisual=void 0,this._imageScatterOverlayVisualGroup=new THREE.Group,this._imageScatterOverlayVisualGroup.name="image-scatter-overlay-visual-group",this._scene.add(this._imageScatterOverlayVisualGroup),this._imageScatterOverlayVisual=void 0}get image(){return this._image}set image(e){this._image=e,void 0!=this._imageScatterVisual&&(this._imageScatterVisual.image=e),void 0!=this._imageScatterOverlayVisual&&(this._imageScatterOverlayVisual.image=e)}get colourspaceModel(){return this._colourspaceModel}set colourspaceModel(e){this._colourspaceModel=e,void 0!=this._viewAxesVisual&&(this._viewAxesVisual.colourspaceModel=e),void 0!=this._spectralLocusVisual&&(this._spectralLocusVisual.colourspaceModel=e),void 0!=this._secondaryColourspaceVisual&&(this._secondaryColourspaceVisual.colourspaceModel=e),void 0!=this._primaryColourspaceVisual&&(this._primaryColourspaceVisual.colourspaceModel=e),void 0!=this._imageScatterVisual&&(this._imageScatterVisual.colourspaceModel=e),void 0!=this._imageScatterOverlayVisual&&(this._imageScatterOverlayVisual.colourspaceModel=e)}get primaryColourspace(){return this._primaryColourspace}set primaryColourspace(e){this._primaryColourspace=e,void 0!=this._primaryColourspaceVisual&&(this._primaryColourspaceVisual.colourspace=e),void 0!=this._imageScatterVisual&&(this._imageScatterVisual.primaryColourspace=e),void 0!=this._imageScatterOverlayVisual&&(this._imageScatterOverlayVisual.primaryColourspace=e)}get secondaryColourspace(){return this._secondaryColourspace}set secondaryColourspace(e){this._secondaryColourspace=e,void 0!=this._secondaryColourspaceVisual&&(this._secondaryColourspaceVisual.colourspace=e),void 0!=this._imageScatterVisual&&(this._imageScatterVisual.secondaryColourspace=e),void 0!=this._imageScatterOverlayVisual&&(this._imageScatterOverlayVisual.secondaryColourspace=e)}get imageColourspace(){return this._imageColourspace}set imageColourspace(e){if(!["Primary","Secondary"].includes(e))throw new Error('"imageColourspace" value must be one of ["Primary", "Secondary"]!');this._imageColourspace=e,void 0!=this._imageScatterVisual&&(this._imageScatterVisual.imageColourspace=e),void 0!=this._imageScatterOverlayVisual&&(this._imageScatterOverlayVisual.imageColourspace=e)}get viewAxesVisual(){return this._viewAxesVisual}set viewAxesVisual(e){throw new Error('"viewAxesVisual" property is read only!')}get spectralLocusVisual(){return this._spectralLocusVisual}set spectralLocusVisual(e){throw new Error('"spectralLocusVisual" property is read only!')}get secondaryColourspaceVisual(){return this._secondaryColourspaceVisual}set secondaryColourspaceVisual(e){throw new Error('"secondaryColourspaceVisual" property is read only!')}get primaryColourspaceVisual(){return this._primaryColourspaceVisual}set primaryColourspaceVisual(e){throw new Error('"primaryColourspaceVisual" property is read only!')}get imageScatterVisual(){return this._imageScatterVisual}set imageScatterVisual(e){throw new Error('"imageScatterVisual" property is read only!')}get imageScatterOverlayVisual(){return this._imageScatterOverlayVisual}set imageScatterOverlayVisual(e){throw new Error('"imageScatterOverlayVisual" property is read only!')}addViewAxesVisual(e){this._viewAxesVisual=new p(this,{...{colourspaceModel:this._colourspaceModel},...e}),this._viewAxesVisual.add()}addSpectralLocusVisual(e){this._spectralLocusVisual=new d(this._spectralLocusVisualGroup,{...{colourspace:this._secondaryColourspace,colourspaceModel:this._colourspaceModel},...e}),this._spectralLocusVisual.add()}addSecondaryColourspaceVisual(e){this._secondaryColourspaceVisual=new m(this._secondaryColourspaceVisualGroup,{...{name:"secondary-colourspace-visual",colourspace:this._secondaryColourspace,colourspaceModel:this._colourspaceModel,wireframe:!0,uniformOpacity:.25},...e}),this._secondaryColourspaceVisual.add()}addPrimaryColourspaceVisual(e){this._primaryColourspaceVisual=new m(this._primaryColourspaceVisualGroup,{...{name:"primary-colourspace-visual",colourspace:this._primaryColourspace,colourspaceModel:this._colourspaceModel},...e}),this._primaryColourspaceVisual.add()}addImageScatterVisual(e){this._imageScatterVisual=new _(this._imageScatterVisualGroup,{...{image:this._image,primaryColourspace:this._primaryColourspace,secondaryColourspace:this._secondaryColourspace,imageColourspace:this._imageColourspace,colourspaceModel:this._colourspaceModel},...e}),this._imageScatterVisual.add()}addImageScatterOverlayVisual(e){this._imageScatterOverlayVisual=new _(this._imageScatterOverlayVisualGroup,{...{name:"image-scatter-overlay-visual",image:this._image,primaryColourspace:this._primaryColourspace,secondaryColourspace:this._secondaryColourspace,imageColourspace:this._imageColourspace,colourspaceModel:this._colourspaceModel,uniformOpacity:.5},...e}),this._imageScatterOverlayVisual.add()}isLoading(){return this._viewAxesVisual.loading||this._spectralLocusVisual.loading||this._secondaryColourspaceVisual.loading||this._primaryColourspaceVisual.loading||this._imageScatterVisual.loading||this._imageScatterOverlayVisual.loading}animate(){void 0!=this._imageScatterOverlayVisual&&void 0!=this._imageScatterOverlayVisual.visual&&(this._imageScatterOverlayVisual.visual.material.opacity=this._imageScatterOverlayVisual.uniformOpacity*(1+Math.sin(.0015*(new Date).getTime()))/2),super.animate()}}class g extends n{constructor(e,a){super(e,a),a={...{camera:{up:new THREE.Vector3(0,1,0),near:.001,far:1e3}},...a};var r=this.container.clientWidth/this.container.clientHeight;this._camera=new THREE.OrthographicCamera(-.5,.5,.5/r,-.5/r,a.camera.near,a.camera.far),this._camera.name="orthographic-camera",this._camera.up=a.camera.up,this._scene.add(this._camera),this._controls=new THREE.OrbitControls(this._camera,this.container),this._controls.enableRotate=!1}get camera(){return this._camera}set camera(e){throw new Error('"camera" property is read only!')}get controls(){return this._controls}set controls(e){throw new Error('"controls" property is read only!')}resizeToContainer(){super.resizeToContainer();var e=this.container.clientWidth,a=this.container.clientHeight;if(this.container.width!==e||this.container.height!==a){this.renderer.setSize(e,a);var r=this.container.clientWidth/this.container.clientHeight;this._camera.top=.5/r,this._camera.bottom=-.5/r,this._camera.updateProjectionMatrix()}}}class C extends h{constructor(e,a){super(e,{...{name:"image-visual"},...a}),this._image=a.image||"Rose.ProPhoto.jpg",this._primaryColourspace=a.primaryColourspace||"sRGB",this._secondaryColourspace=a.secondaryColourspace||"DCI-P3",this._imageColourspace=a.imageColourspace||"Primary",this._uniformOpacity=a.uniformOpacity||1,this._outOfPrimaryColourspaceGamut=a.outOfPrimaryColourspaceGamut||!1,this._outOfSecondaryColourspaceGamut=a.outOfSecondaryColourspaceGamut||!1,this._saturate=a.saturate||!1,this._depth=a.depth||0}get image(){return this._image}set image(e){this._image=e,this.add()}get primaryColourspace(){return this._primaryColourspace}set primaryColourspace(e){this._primaryColourspace=e,this.add()}get secondaryColourspace(){return this._secondaryColourspace}set secondaryColourspace(e){this._secondaryColourspace=e,this.add()}get imageColourspace(){return this._imageColourspace}set imageColourspace(e){if(!["Primary","Secondary"].includes(e))throw new Error('"imageColourspace" value must be one of ["Primary", "Secondary"]!');this._imageColourspace=e,this.add()}get uniformOpacity(){return this._uniformOpacity}set uniformOpacity(e){this._uniformOpacity=e,Object.keys(this.cache).forEach(function(a){this.cache[a].material.opacity=e}.bind(this))}get outOfPrimaryColourspaceGamut(){return this._outOfPrimaryColourspaceGamut}set outOfPrimaryColourspaceGamut(e){this._outOfPrimaryColourspaceGamut=e,this.add()}get outOfSecondaryColourspaceGamut(){return this._outOfSecondaryColourspaceGamut}set outOfSecondaryColourspaceGamut(e){this._outOfSecondaryColourspaceGamut=e,this.add()}get saturate(){return this._saturate}set saturate(e){this._saturate=e,this.add()}get depth(){return this._depth}set depth(e){throw new Error('"depth" property is read only!')}route(){return i(`/image-data/${encodeURIComponent(this._image)}?`+`primaryColourspace=${encodeURIComponent(this._primaryColourspace)}&`+`secondaryColourspace=${encodeURIComponent(this._secondaryColourspace)}&`+`imageColourspace=${encodeURIComponent(this._imageColourspace)}&`+`outOfPrimaryColourspaceGamut=${this._outOfPrimaryColourspaceGamut}&`+`outOfSecondaryColourspaceGamut=${this._outOfSecondaryColourspaceGamut}&`+`saturate=${this._saturate}`)}create(e){var a=new THREE.PlaneGeometry(1,e.height/e.width),r=new THREE.DataTexture(Float32Array.from(e.data),e.width,e.height,THREE.RGBFormat,THREE.FloatType);if(r.needsUpdate=!0,1==this._uniformOpacity)var i=new THREE.MeshBasicMaterial({map:r});else i=new THREE.MeshBasicMaterial({map:r,alphaMap:r,transparent:!0,opacity:this._uniformOpacity});var t=new THREE.Mesh(a,i);return t.name=this.name,t.visible=this.visible,t.position.set(0,this._depth,0),t.rotation.set(THREE.Math.degToRad(-90),0,THREE.Math.degToRad(180)),t.scale.set(-1,1,1),t}fetch(e){var a=new THREE.FileLoader;a.setResponseType("json"),a.load(e,function(a){this.visual=this.create(a),this.cache[e]=this.visual,this.parent.add(this.visual),this._loading=!1}.bind(this),u.bind(this))}}class v extends g{constructor(e,a){super(e,a),a={...{renderer:{gammaOutput:!0},scene:{background:new THREE.Color("#333333")},camera:{position:new THREE.Vector3(0,1,0)},controls:{target:new THREE.Vector3(0,0,0)},image:"Rose.ProPhoto.jpg",colourspaceModel:"CIE xyY",primaryColourspace:"sRGB",secondaryColourspace:"DCI-P3",imageColourspace:"Primary"},...a},this.renderer.gammaOutput=a.renderer.gammaOutput,this.scene.background=a.scene.background,this.camera.position.copy(a.camera.position),this.controls.target=a.controls.target,this._image=a.image,this._colourspaceModel=a.colourspaceModel,this._primaryColourspace=a.primaryColourspace,this._secondaryColourspace=a.secondaryColourspace,this._imageColourspace=a.imageColourspace,this._imageVisualGroup=new THREE.Group,this._imageVisualGroup.name="image-visual-group",this._scene.add(this._imageVisualGroup),this._imageVisual=void 0,this._imageOverlayVisualGroup=new THREE.Group,this._imageOverlayVisualGroup.name="image-overlay-visual-group",this._scene.add(this._imageOverlayVisualGroup),this._imageOverlayVisual=void 0}get image(){return this._image}set image(e){this._image=e,void 0!=this._imageVisual&&(this._imageVisual.image=e),void 0!=this._imageOverlayVisual&&(this._imageOverlayVisual.image=e)}get colourspaceModel(){return this._colourspaceModel}set colourspaceModel(e){this._colourspaceModel=e}get primaryColourspace(){return this._primaryColourspace}set primaryColourspace(e){this._primaryColourspace=e,void 0!=this._imageOverlayVisual&&(this._imageOverlayVisual.primaryColourspace=e)}get secondaryColourspace(){return this._secondaryColourspace}set secondaryColourspace(e){this._secondaryColourspace=e,void 0!=this._imageOverlayVisual&&(this._imageOverlayVisual.secondaryColourspace=e)}get imageColourspace(){return this._imageColourspace}set imageColourspace(e){if(!["Primary","Secondary"].includes(e))throw new Error('"imageColourspace" value must be one of ["Primary", "Secondary"]!');this._imageColourspace=e,void 0!=this._imageOverlayVisual&&(this._imageOverlayVisual.imageColourspace=e)}get imageVisual(){return this._imageVisual}set imageVisual(e){throw new Error('"imageVisual" property is read only!')}get imageOverlayVisual(){return this._imageOverlayVisual}set imageOverlayVisual(e){throw new Error('"imageOverlayVisual" property is read only!')}addImageVisual(e){this._imageVisual=new C(this._imageVisualGroup,{...{name:"image-visual",image:this._image,primaryColourspace:this._primaryColourspace,secondaryColourspace:this._secondaryColourspace,imageColourspace:this._imageColourspace},...e}),this._imageVisual.add()}addImageOverlayVisual(e){this._imageOverlayVisual=new C(this._imageOverlayVisualGroup,{...{name:"image-overlay-visual",image:this._image,primaryColourspace:this._primaryColourspace,secondaryColourspace:this._secondaryColourspace,imageColourspace:this._imageColourspace,uniformOpacity:.5,depth:.5},...e}),this._imageOverlayVisual.add()}isLoading(){return this._imageVisual.loading||this._imageOverlayVisual.loading}animate(){void 0!=this._imageOverlayVisual&&void 0!=this._imageOverlayVisual.visual&&(this._imageOverlayVisual.visual.material.opacity=this._imageOverlayVisual.uniformOpacity*(1+Math.sin(.0015*(new Date).getTime()))/2),super.animate()}}function f(e,a,r,i,t){if("Array"==t.constructor.name)var o=t;else if("Object"==t.constructor.name)o=Object.keys(t);o.sort();for(var s="",r.domElement.children[0].innerHTML=s,r.domElement.children[0].selectedIndex=o.indexOf(i)}function w(e){e=e.domElement.children[0],console.log(e);for(var a=new Array,r=0;r0;){var r=a.shift();window.clearInterval(r),window.clearTimeout(r)}}(a,r),function(e,a,r,i){r=r||5e3,i=i||10,a.push(setTimeout(function(){e.style.opacity=1;var r=setInterval(function(){var a=e.style.opacity;0==a?clearInterval(r):e.style.opacity=a-.01},i);a.push(r)},r))}(a,r,i,t))}function s(e,a,r){o(e,document.getElementById("info"),window.info_id_registry,a,r)}function c(e,a,r){o(e,document.getElementById("warning"),window.warning_id_registry,a,r)}function u(e){var a=Math.round(e.loaded/parseFloat(e.target.getResponseHeader("x-content-length"))*100);s(`${this.name}: ${a}% loaded...`)}r.r(a),window.info_id_registry=new Array,window.warning_id_registry=new Array;class n{constructor(e,a){this._container=e,a={...{renderer:{antialias:!0}},...a},this._renderer=new THREE.WebGLRenderer({antialias:a.renderer.antialias}),this._renderer.setPixelRatio(window.devicePixelRatio),this._renderer.setSize(this._container.clientWidth,this._container.clientHeight),this._container.appendChild(this._renderer.domElement),this._scene=new THREE.Scene,this._observer=new MutationObserver(this.resizeToContainer.bind(this)),this._observer.observe(this._container,{attributes:!0}),window.addEventListener("resize",this.resizeToContainer.bind(this),!1)}get container(){return this._container}set container(e){throw new Error('"container" property is read only!')}get renderer(){return this._renderer}set renderer(e){throw new Error('"renderer" property is read only!')}get scene(){return this._scene}set scene(e){throw new Error('"scene" property is read only!')}removeObjectByName(e){t(this._scene,e)}resizeToContainer(){var e=this._container.clientWidth,a=this._container.clientHeight;this._container.width===e&&this._container.height===a||this._renderer.setSize(e,a)}animate(){requestAnimationFrame(this.animate.bind(this)),this._controls.update(),this.render()}render(){this._renderer.render(this._scene,this._camera)}}class l extends n{constructor(e,a){super(e,a),a={...{camera:{fov:45,up:new THREE.Vector3(0,1,0),near:.001,far:1e3}},...a},this._camera=new THREE.PerspectiveCamera(a.camera.fov,this.container.clientWidth/this.container.clientHeight,a.camera.near,a.camera.far),this._camera.name="perspective-camera",this._camera.up=a.camera.up,this._scene.add(this._camera),this._controls=new THREE.TrackballControls(this._camera,this.container)}get camera(){return this._camera}set camera(e){throw new Error('"camera" property is read only!')}get controls(){return this._controls}set controls(e){throw new Error('"controls" property is read only!')}resizeToContainer(){super.resizeToContainer();var e=this.container.clientWidth,a=this.container.clientHeight;this.container.width===e&&this.container.height===a||(this._camera.aspect=e/a,this._camera.updateProjectionMatrix())}}class h{constructor(e,a){this._parent=e,this._name=a.name||"visual",this._visible=a.visible||!0,this._loadingCallback=a.loadingCallback||u,this._cache={},this._visual=void 0,this._loading=!1}get parent(){return this._parent}set parent(e){void 0!=this._parent&&t(this._parent,this._name),this._parent=e,void 0!=this._visual&&this._parent.add(this._visual)}get name(){return this._name}set name(e){throw new Error('"name" property is read only!')}get visible(){return this._visible}set visible(e){this._visible=e,Object.keys(this._cache).forEach(function(a){this._cache[a].visible=e}.bind(this))}get loadingCallback(){return this._loadingCallback}set loadingCallback(e){this._loadingCallback=e}get cache(){return this._cache}set cache(e){throw new Error('"cache" property is read only!')}get visual(){return this._visual}set visual(e){void 0!=this._parent&&t(this._parent,this._name),this._visual=e,void 0!=this._visual&&this._parent.add(this._visual)}get loading(){return this._loading}set loading(e){throw new Error('"cache" property is read only!')}route(){throw Error("Method must be reimplemented in subclass!")}add(){void 0!=this._parent&&t(this._parent,this._name);var e=this.route();this._loading=!0,e in this._cache?(this._visual=this._cache[e],this._parent.add(this._visual),this._loading=!1):this.fetch(e)}create(e){throw Error("Method must be reimplemented in subclass!")}fetch(e){(new THREE.BufferGeometryLoader).load(e,function(a,r){this._visual=this.create(a),this._cache[e]=this._visual,this._parent.add(this._visual),this._loading=!1}.bind(this),this._loadingCallback.bind(this))}}class p extends h{constructor(e,a){super(e.camera,{...{name:"view-axes-visual"},...a}),this._view=e,this._colourspaceModel=a.colourspaceModel||"CIE xyY"}get view(){return this._view}set view(e){throw new Error('"view" property is read only!')}get colourspaceModel(){return this._colourspaceModel}set colourspaceModel(e){this._colourspaceModel=e,this.add()}route(){return i(`/colourspace-models?colourspaceModel=${encodeURIComponent(this._colourspaceModel)}`)}create(e){var a=new THREE.AxesHelper;return a.geometry.attributes.color.array.set([0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0]),a.name=this.name,a.visible=this.visible,(new THREE.FontLoader).load("https://cdn.rawgit.com/mrdoob/three.js/master/examples/fonts/helvetiker_regular.typeface.json",function(r){[{text:e[this._colourspaceModel][0],colour:"#FF0000",position:{x:-.2,y:-.2,z:1.2}},{text:e[this._colourspaceModel][1],colour:"#00FF00",position:{x:-.2,y:1.2,z:-.05}},{text:e[this._colourspaceModel][2],colour:"#0000FF",position:{x:1.2,y:-.2,z:-.05}}].forEach(function(e){var i=new THREE.TextGeometry(e.text,{font:r,size:.4,height:.1,curveSegments:8}),t=new THREE.MeshBasicMaterial({color:e.colour}),o=new THREE.Mesh(i,t);o.position.set(e.position.x,e.position.y,e.position.z),o.name=e.text,a.add(o)}.bind(this))}.bind(this)),a.onBeforeRender=function(e,a,r,i,t,o){var s=10*this._view.camera.near;this.visual.scale.set(s/20,s/20,s/20);var c=this._view.container.clientWidth/this._view.container.clientHeight,u=this._view.camera.fov*Math.PI/180,n=2*Math.atan(Math.tan(u/2)*c),l=2*Math.tan(n/2)*s,h=2*Math.tan(u/2)*s;this.visual.position.set(-l/2*.85,-h/2*.85,-s);var p=function(e,a){var r=new THREE.Vector3,i=new THREE.Vector3;r.copy(e.position),i.copy(a.target),r.sub(i);var t=Math.sqrt(r.x*r.x+r.y*r.y+r.z*r.z),o=Math.sqrt(r.x*r.x+r.z*r.z);return{x:Math.acos(o/t)*(r.y>0?1:-1),y:Math.acos(r.z/o)*(r.x>0?-1:1),z:0}}(this._view.camera,this._view.controls);this.visual.rotation.set(p.x,p.y,0)}.bind(this),a}fetch(e){var a=new THREE.FileLoader;a.setResponseType("json"),a.load(e,function(a){this.visual=this.create(a),this.cache[e]=this.visual,this._view.camera.add(this.visual),this._loading=!1}.bind(this),u.bind(this))}}class m extends h{constructor(e,a){super(e,{...{name:"colourspace-visual"},...a}),this._colourspace=a.colourspace||"sRGB",this._colourspaceModel=a.colourspaceModel||"CIE xyY",this._segments=a.segments||16,this._uniformColour=a.uniformColour||void 0,this._uniformOpacity=a.uniformOpacity||.75,this._wireframe=a.wireframe||!1,this._wireframeColour=a.wireframeColour||void 0,this._wireframeOpacity=a.wireframeOpacity||1}get colourspace(){return this._colourspace}set colourspace(e){this._colourspace=e,this.add()}get colourspaceModel(){return this._colourspaceModel}set colourspaceModel(e){this._colourspaceModel=e,this.add()}get segments(){return this._segments}set segments(e){this._segments=e,this.add()}get uniformColour(){return this._uniformColour}set uniformColour(e){this._uniformColour=e,this.add()}get uniformOpacity(){return this._uniformOpacity}set uniformOpacity(e){this._uniformOpacity=e,Object.keys(this.cache).forEach(function(a){this.cache[a].material.opacity=e}.bind(this))}get wireframe(){return this._wireframe}set wireframe(e){this._wireframe=e,Object.keys(this.cache).forEach(function(a){this.cache[a].material.wireframe=e}.bind(this))}get wireframeColour(){return this._wireframeColour}set wireframeColour(e){throw new Error('"wireframeOpacity" property is read only!')}get wireframeOpacity(){return this._wireframeOpacity}set wireframeOpacity(e){throw new Error('"wireframeOpacity" property is read only!')}route(){return i("/RGB-colourspace-volume-visual?"+`colourspace=${encodeURIComponent(this._colourspace)}&`+`colourspaceModel=${encodeURIComponent(this._colourspaceModel)}&`+`segments=${this._segments}&`+`wireframe=${this._wireframe}&`)}create(e){var a=new THREE.MeshBasicMaterial({vertexColors:THREE.VertexColors,transparent:!0,opacity:this._uniformOpacity,wireframe:this._wireframe});a.depthWrite=1==this._uniformOpacity;var r=new THREE.Mesh(e,a);return r.name=this.name,r.visible=this.visible,r}}class d extends h{constructor(e,a){super(e,{...{name:"spectral-locus-visual"},...a}),this._colourspace=a.colourspace||"sRGB",this._colourspaceModel=a.colourspaceModel||"CIE xyY",this._uniformColour=a.uniformColour||void 0,this._uniformOpacity=a.uniformOpacity||.75}get colourspace(){return this._colourspace}set colourspace(e){this._colourspace=e,this.add()}get colourspaceModel(){return this._colourspaceModel}set colourspaceModel(e){this._colourspaceModel=e,this.add()}get uniformColour(){return this._uniformColour}set uniformColour(e){this._uniformColour=e,this.add()}get uniformOpacity(){return this._uniformOpacity}set uniformOpacity(e){this._uniformOpacity=e,Object.keys(this.cache).forEach(function(a){this.cache[a].material.opacity=e}.bind(this))}route(){return i("/spectral-locus-visual?"+`colourspace=${encodeURIComponent(this._colourspace)}&`+`colourspaceModel=${encodeURIComponent(this._colourspaceModel)}&`)}create(e){var a=new THREE.LineBasicMaterial({vertexColors:THREE.VertexColors,transparent:!0,opacity:this._uniformOpacity}),r=new THREE.Line(e,a);return r.name=this.name,r.visible=this.visible,r}}class _ extends h{constructor(e,a){super(e,{...{name:"image-scatter-visual"},...a}),this._image=a.image||"Rose.ProPhoto.jpg",this._primaryColourspace=a.primaryColourspace||"sRGB",this._secondaryColourspace=a.secondaryColourspace||"DCI-P3",this._imageColourspace=a.imageColourspace||"Primary",this._colourspaceModel=a.colourspaceModel||"CIE xyY",this._uniformColour=a.uniformColour||void 0,this._uniformOpacity=a.uniformOpacity||.75,this._outOfPrimaryColourspaceGamut=a.outOfPrimaryColourspaceGamut||!1,this._outOfSecondaryColourspaceGamut=a.outOfSecondaryColourspaceGamut||!1,this._subSampling=a.subSampling||25,this._pointSize=a.pointSize||.01,this._saturate=a.saturate||!1}get image(){return this._image}set image(e){this._image=e,this.add()}get imageColourspace(){return this._imageColourspace}set imageColourspace(e){this._imageColourspace=e,this.add()}get primaryColourspace(){return this._primaryColourspace}set primaryColourspace(e){this._primaryColourspace=e,this.add()}get secondaryColourspace(){return this._secondaryColourspace}set secondaryColourspace(e){this._secondaryColourspace=e,this.add()}get imageColourspace(){return this._imageColourspace}set imageColourspace(e){if(!["Primary","Secondary"].includes(e))throw new Error('"imageColourspace" value must be one of ["Primary", "Secondary"]!');this._imageColourspace=e,this.add()}get colourspaceModel(){return this._colourspaceModel}set colourspaceModel(e){this._colourspaceModel=e,this.add()}get uniformColour(){return this._uniformColour}set uniformColour(e){this._uniformColour=e,this.add()}get uniformOpacity(){return this._uniformOpacity}set uniformOpacity(e){this._uniformOpacity=e,Object.keys(this.cache).forEach(function(a){this.cache[a].material.opacity=e}.bind(this))}get outOfPrimaryColourspaceGamut(){return this._outOfPrimaryColourspaceGamut}set outOfPrimaryColourspaceGamut(e){this._outOfPrimaryColourspaceGamut=e,this.add()}get outOfSecondaryColourspaceGamut(){return this._outOfSecondaryColourspaceGamut}set outOfSecondaryColourspaceGamut(e){this._outOfSecondaryColourspaceGamut=e,this.add()}get subSampling(){return this._subSampling}set subSampling(e){this._subSampling=e,this.add()}get pointSize(){return this._pointSize}set pointSize(e){this._pointSize=e,Object.keys(this.cache).forEach(function(a){this.cache[a].material.size=e}.bind(this))}get saturate(){return this._saturate}set saturate(e){this._saturate=e,this.add()}route(){return i(`/RGB-image-scatter-visual/${this._image}?`+`primaryColourspace=${encodeURIComponent(this._primaryColourspace)}&`+`secondaryColourspace=${encodeURIComponent(this._secondaryColourspace)}&`+`imageColourspace=${encodeURIComponent(this._imageColourspace)}&`+`colourspaceModel=${encodeURIComponent(this._colourspaceModel)}&`+`outOfPrimaryColourspaceGamut=${this._outOfPrimaryColourspaceGamut}&`+`outOfSecondaryColourspaceGamut=${this._outOfSecondaryColourspaceGamut}&`+`subSampling=${this._subSampling}&`+`saturate=${this._saturate}&`)}create(e){var a=new THREE.PointsMaterial({vertexColors:THREE.VertexColors,transparent:!0,opacity:this._uniformOpacity,size:this._pointSize}),r=new THREE.Points(e,a);return r.name=this.name,r.visible=this.visible,r}}class y extends l{constructor(e,a){super(e,a),a={...{scene:{background:new THREE.Color("#333333")},fog:{enable:!0,color:"#333333",density:.05},camera:{position:new THREE.Vector3(-3,3,3)},controls:{target:new THREE.Vector3(1/3,.5,1/3)},grid:{enable:!0,size:2,divisions:20,colorCenterLine:"#111111",colorGrid:"#222222"},axes:{enable:!0},image:"Rose.ProPhoto.jpg",colourspaceModel:"CIE xyY",primaryColourspace:"sRGB",secondaryColourspace:"DCI-P3",imageColourspace:"Primary"},...a},this.renderer.sortObjects=!1,this.scene.background=a.scene.background,a.fog.enable&&(this.scene.fog=new THREE.FogExp2(a.fog.color,a.fog.density)),this.camera.position.copy(a.camera.position),this.controls.target=a.controls.target,a.grid.enable&&(this.grid=new THREE.GridHelper(a.grid.size,a.grid.divisions,a.grid.colorCenterLine,a.grid.colorGrid),this.grid.name="grid",this.scene.add(this.grid)),a.axes.enable&&(this.axes=new THREE.AxesHelper,this.axes.geometry.attributes.color.array.set([0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0]),this.axes.name="axes",this.scene.add(this.axes)),this._image=a.image,this._colourspaceModel=a.colourspaceModel,this._primaryColourspace=a.primaryColourspace,this._secondaryColourspace=a.secondaryColourspace,this._imageColourspace=a.imageColourspace,this._viewAxesVisual=void 0,this._spectralLocusVisualGroup=new THREE.Group,this._spectralLocusVisualGroup.name="spectral-locus-visual-group",this._scene.add(this._spectralLocusVisualGroup),this._spectralLocusVisual=void 0,this._secondaryColourspaceVisualGroup=new THREE.Group,this._secondaryColourspaceVisualGroup.name="secondary-colourspace-visual-group",this._scene.add(this._secondaryColourspaceVisualGroup),this._secondaryColourspaceVisual=void 0,this._primaryColourspaceVisualGroup=new THREE.Group,this._primaryColourspaceVisualGroup.name="primary-colourspace-visual-group",this._scene.add(this._primaryColourspaceVisualGroup),this._primaryColourspaceVisual=void 0,this._imageScatterVisualGroup=new THREE.Group,this._imageScatterVisualGroup.name="image-scatter-visual-group",this._scene.add(this._imageScatterVisualGroup),this._imageScatterVisual=void 0,this._imageScatterOverlayVisualGroup=new THREE.Group,this._imageScatterOverlayVisualGroup.name="image-scatter-overlay-visual-group",this._scene.add(this._imageScatterOverlayVisualGroup),this._imageScatterOverlayVisual=void 0}get image(){return this._image}set image(e){this._image=e,void 0!=this._imageScatterVisual&&(this._imageScatterVisual.image=e),void 0!=this._imageScatterOverlayVisual&&(this._imageScatterOverlayVisual.image=e)}get colourspaceModel(){return this._colourspaceModel}set colourspaceModel(e){this._colourspaceModel=e,void 0!=this._viewAxesVisual&&(this._viewAxesVisual.colourspaceModel=e),void 0!=this._spectralLocusVisual&&(this._spectralLocusVisual.colourspaceModel=e),void 0!=this._secondaryColourspaceVisual&&(this._secondaryColourspaceVisual.colourspaceModel=e),void 0!=this._primaryColourspaceVisual&&(this._primaryColourspaceVisual.colourspaceModel=e),void 0!=this._imageScatterVisual&&(this._imageScatterVisual.colourspaceModel=e),void 0!=this._imageScatterOverlayVisual&&(this._imageScatterOverlayVisual.colourspaceModel=e)}get primaryColourspace(){return this._primaryColourspace}set primaryColourspace(e){this._primaryColourspace=e,void 0!=this._primaryColourspaceVisual&&(this._primaryColourspaceVisual.colourspace=e),void 0!=this._imageScatterVisual&&(this._imageScatterVisual.primaryColourspace=e),void 0!=this._imageScatterOverlayVisual&&(this._imageScatterOverlayVisual.primaryColourspace=e)}get secondaryColourspace(){return this._secondaryColourspace}set secondaryColourspace(e){this._secondaryColourspace=e,void 0!=this._secondaryColourspaceVisual&&(this._secondaryColourspaceVisual.colourspace=e),void 0!=this._imageScatterVisual&&(this._imageScatterVisual.secondaryColourspace=e),void 0!=this._imageScatterOverlayVisual&&(this._imageScatterOverlayVisual.secondaryColourspace=e)}get imageColourspace(){return this._imageColourspace}set imageColourspace(e){if(!["Primary","Secondary"].includes(e))throw new Error('"imageColourspace" value must be one of ["Primary", "Secondary"]!');this._imageColourspace=e,void 0!=this._imageScatterVisual&&(this._imageScatterVisual.imageColourspace=e),void 0!=this._imageScatterOverlayVisual&&(this._imageScatterOverlayVisual.imageColourspace=e)}get viewAxesVisual(){return this._viewAxesVisual}set viewAxesVisual(e){throw new Error('"viewAxesVisual" property is read only!')}get spectralLocusVisual(){return this._spectralLocusVisual}set spectralLocusVisual(e){throw new Error('"spectralLocusVisual" property is read only!')}get secondaryColourspaceVisual(){return this._secondaryColourspaceVisual}set secondaryColourspaceVisual(e){throw new Error('"secondaryColourspaceVisual" property is read only!')}get primaryColourspaceVisual(){return this._primaryColourspaceVisual}set primaryColourspaceVisual(e){throw new Error('"primaryColourspaceVisual" property is read only!')}get imageScatterVisual(){return this._imageScatterVisual}set imageScatterVisual(e){throw new Error('"imageScatterVisual" property is read only!')}get imageScatterOverlayVisual(){return this._imageScatterOverlayVisual}set imageScatterOverlayVisual(e){throw new Error('"imageScatterOverlayVisual" property is read only!')}addViewAxesVisual(e){this._viewAxesVisual=new p(this,{...{colourspaceModel:this._colourspaceModel},...e}),this._viewAxesVisual.add()}addSpectralLocusVisual(e){this._spectralLocusVisual=new d(this._spectralLocusVisualGroup,{...{colourspace:this._secondaryColourspace,colourspaceModel:this._colourspaceModel},...e}),this._spectralLocusVisual.add()}addSecondaryColourspaceVisual(e){this._secondaryColourspaceVisual=new m(this._secondaryColourspaceVisualGroup,{...{name:"secondary-colourspace-visual",colourspace:this._secondaryColourspace,colourspaceModel:this._colourspaceModel,wireframe:!0,uniformOpacity:.25},...e}),this._secondaryColourspaceVisual.add()}addPrimaryColourspaceVisual(e){this._primaryColourspaceVisual=new m(this._primaryColourspaceVisualGroup,{...{name:"primary-colourspace-visual",colourspace:this._primaryColourspace,colourspaceModel:this._colourspaceModel},...e}),this._primaryColourspaceVisual.add()}addImageScatterVisual(e){this._imageScatterVisual=new _(this._imageScatterVisualGroup,{...{image:this._image,primaryColourspace:this._primaryColourspace,secondaryColourspace:this._secondaryColourspace,imageColourspace:this._imageColourspace,colourspaceModel:this._colourspaceModel},...e}),this._imageScatterVisual.add()}addImageScatterOverlayVisual(e){this._imageScatterOverlayVisual=new _(this._imageScatterOverlayVisualGroup,{...{name:"image-scatter-overlay-visual",image:this._image,primaryColourspace:this._primaryColourspace,secondaryColourspace:this._secondaryColourspace,imageColourspace:this._imageColourspace,colourspaceModel:this._colourspaceModel,uniformOpacity:.5},...e}),this._imageScatterOverlayVisual.add()}isLoading(){return this._viewAxesVisual.loading||this._spectralLocusVisual.loading||this._secondaryColourspaceVisual.loading||this._primaryColourspaceVisual.loading||this._imageScatterVisual.loading||this._imageScatterOverlayVisual.loading}animate(){void 0!=this._imageScatterOverlayVisual&&void 0!=this._imageScatterOverlayVisual.visual&&(this._imageScatterOverlayVisual.visual.material.opacity=this._imageScatterOverlayVisual.uniformOpacity*(1+Math.sin(.0015*(new Date).getTime()))/2),super.animate()}}class g extends n{constructor(e,a){super(e,a),a={...{camera:{up:new THREE.Vector3(0,1,0),near:.001,far:1e3}},...a};var r=this.container.clientWidth/this.container.clientHeight;this._camera=new THREE.OrthographicCamera(-.5,.5,.5/r,-.5/r,a.camera.near,a.camera.far),this._camera.name="orthographic-camera",this._camera.up=a.camera.up,this._scene.add(this._camera),this._controls=new THREE.OrbitControls(this._camera,this.container),this._controls.enableRotate=!1}get camera(){return this._camera}set camera(e){throw new Error('"camera" property is read only!')}get controls(){return this._controls}set controls(e){throw new Error('"controls" property is read only!')}resizeToContainer(){super.resizeToContainer();var e=this.container.clientWidth,a=this.container.clientHeight;if(this.container.width!==e||this.container.height!==a){this.renderer.setSize(e,a);var r=this.container.clientWidth/this.container.clientHeight;this._camera.top=.5/r,this._camera.bottom=-.5/r,this._camera.updateProjectionMatrix()}}}class C extends h{constructor(e,a){super(e,{...{name:"image-visual"},...a}),this._image=a.image||"Rose.ProPhoto.jpg",this._primaryColourspace=a.primaryColourspace||"sRGB",this._secondaryColourspace=a.secondaryColourspace||"DCI-P3",this._imageColourspace=a.imageColourspace||"Primary",this._uniformOpacity=a.uniformOpacity||1,this._outOfPrimaryColourspaceGamut=a.outOfPrimaryColourspaceGamut||!1,this._outOfSecondaryColourspaceGamut=a.outOfSecondaryColourspaceGamut||!1,this._saturate=a.saturate||!1,this._depth=a.depth||0}get image(){return this._image}set image(e){this._image=e,this.add()}get primaryColourspace(){return this._primaryColourspace}set primaryColourspace(e){this._primaryColourspace=e,this.add()}get secondaryColourspace(){return this._secondaryColourspace}set secondaryColourspace(e){this._secondaryColourspace=e,this.add()}get imageColourspace(){return this._imageColourspace}set imageColourspace(e){if(!["Primary","Secondary"].includes(e))throw new Error('"imageColourspace" value must be one of ["Primary", "Secondary"]!');this._imageColourspace=e,this.add()}get uniformOpacity(){return this._uniformOpacity}set uniformOpacity(e){this._uniformOpacity=e,Object.keys(this.cache).forEach(function(a){this.cache[a].material.opacity=e}.bind(this))}get outOfPrimaryColourspaceGamut(){return this._outOfPrimaryColourspaceGamut}set outOfPrimaryColourspaceGamut(e){this._outOfPrimaryColourspaceGamut=e,this.add()}get outOfSecondaryColourspaceGamut(){return this._outOfSecondaryColourspaceGamut}set outOfSecondaryColourspaceGamut(e){this._outOfSecondaryColourspaceGamut=e,this.add()}get saturate(){return this._saturate}set saturate(e){this._saturate=e,this.add()}get depth(){return this._depth}set depth(e){throw new Error('"depth" property is read only!')}route(){return i(`/image-data/${encodeURIComponent(this._image)}?`+`primaryColourspace=${encodeURIComponent(this._primaryColourspace)}&`+`secondaryColourspace=${encodeURIComponent(this._secondaryColourspace)}&`+`imageColourspace=${encodeURIComponent(this._imageColourspace)}&`+`outOfPrimaryColourspaceGamut=${this._outOfPrimaryColourspaceGamut}&`+`outOfSecondaryColourspaceGamut=${this._outOfSecondaryColourspaceGamut}&`+`saturate=${this._saturate}`)}create(e){var a=new THREE.PlaneGeometry(1,e.height/e.width),r=new THREE.DataTexture(Float32Array.from(e.data),e.width,e.height,THREE.RGBFormat,THREE.FloatType);if(r.needsUpdate=!0,1==this._uniformOpacity)var i=new THREE.MeshBasicMaterial({map:r});else i=new THREE.MeshBasicMaterial({map:r,alphaMap:r,transparent:!0,opacity:this._uniformOpacity});var t=new THREE.Mesh(a,i);return t.name=this.name,t.visible=this.visible,t.position.set(0,this._depth,0),t.rotation.set(THREE.Math.degToRad(-90),0,THREE.Math.degToRad(180)),t.scale.set(-1,1,1),t}fetch(e){var a=new THREE.FileLoader;a.setResponseType("json"),a.load(e,function(a){this.visual=this.create(a),this.cache[e]=this.visual,this.parent.add(this.visual),this._loading=!1}.bind(this),u.bind(this))}}class v extends g{constructor(e,a){super(e,a),a={...{renderer:{gammaOutput:!0},scene:{background:new THREE.Color("#333333")},camera:{position:new THREE.Vector3(0,1,0)},controls:{target:new THREE.Vector3(0,0,0)},image:"Rose.ProPhoto.jpg",colourspaceModel:"CIE xyY",primaryColourspace:"sRGB",secondaryColourspace:"DCI-P3",imageColourspace:"Primary"},...a},this.renderer.gammaOutput=a.renderer.gammaOutput,this.scene.background=a.scene.background,this.camera.position.copy(a.camera.position),this.controls.target=a.controls.target,this._image=a.image,this._colourspaceModel=a.colourspaceModel,this._primaryColourspace=a.primaryColourspace,this._secondaryColourspace=a.secondaryColourspace,this._imageColourspace=a.imageColourspace,this._imageVisualGroup=new THREE.Group,this._imageVisualGroup.name="image-visual-group",this._scene.add(this._imageVisualGroup),this._imageVisual=void 0,this._imageOverlayVisualGroup=new THREE.Group,this._imageOverlayVisualGroup.name="image-overlay-visual-group",this._scene.add(this._imageOverlayVisualGroup),this._imageOverlayVisual=void 0}get image(){return this._image}set image(e){this._image=e,void 0!=this._imageVisual&&(this._imageVisual.image=e),void 0!=this._imageOverlayVisual&&(this._imageOverlayVisual.image=e)}get colourspaceModel(){return this._colourspaceModel}set colourspaceModel(e){this._colourspaceModel=e}get primaryColourspace(){return this._primaryColourspace}set primaryColourspace(e){this._primaryColourspace=e,void 0!=this._imageOverlayVisual&&(this._imageOverlayVisual.primaryColourspace=e)}get secondaryColourspace(){return this._secondaryColourspace}set secondaryColourspace(e){this._secondaryColourspace=e,void 0!=this._imageOverlayVisual&&(this._imageOverlayVisual.secondaryColourspace=e)}get imageColourspace(){return this._imageColourspace}set imageColourspace(e){if(!["Primary","Secondary"].includes(e))throw new Error('"imageColourspace" value must be one of ["Primary", "Secondary"]!');this._imageColourspace=e,void 0!=this._imageOverlayVisual&&(this._imageOverlayVisual.imageColourspace=e)}get imageVisual(){return this._imageVisual}set imageVisual(e){throw new Error('"imageVisual" property is read only!')}get imageOverlayVisual(){return this._imageOverlayVisual}set imageOverlayVisual(e){throw new Error('"imageOverlayVisual" property is read only!')}addImageVisual(e){this._imageVisual=new C(this._imageVisualGroup,{...{name:"image-visual",image:this._image,primaryColourspace:this._primaryColourspace,secondaryColourspace:this._secondaryColourspace,imageColourspace:this._imageColourspace},...e}),this._imageVisual.add()}addImageOverlayVisual(e){this._imageOverlayVisual=new C(this._imageOverlayVisualGroup,{...{name:"image-overlay-visual",image:this._image,primaryColourspace:this._primaryColourspace,secondaryColourspace:this._secondaryColourspace,imageColourspace:this._imageColourspace,uniformOpacity:.5,depth:.5},...e}),this._imageOverlayVisual.add()}isLoading(){return this._imageVisual.loading||this._imageOverlayVisual.loading}animate(){void 0!=this._imageOverlayVisual&&void 0!=this._imageOverlayVisual.visual&&(this._imageOverlayVisual.visual.material.opacity=this._imageOverlayVisual.uniformOpacity*(1+Math.sin(.0015*(new Date).getTime()))/2),super.animate()}}function f(e,a,r,i,t){if("Array"==t.constructor.name)var o=t;else if("Object"==t.constructor.name)o=Object.keys(t);o.sort();for(var s="",r.domElement.children[0].innerHTML=s,r.domElement.children[0].selectedIndex=o.indexOf(i)}function w(e){e=e.domElement.children[0];for(var a=new Array,r=0;r