From d1f59b517608f8556cb583038e023226f74d46f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Rebelo?= Date: Wed, 26 Jul 2023 01:16:11 +0200 Subject: [PATCH] feat: Visual Semantics metric #54 --- src/@evoposter/evaluator/src/index.mjs | 2 + .../evaluator/src/metrics/LayoutSemantics.mjs | 1 - .../evaluator/src/metrics/VisualSemantics.mjs | 102 ++++++++++++++++++ src/@evoposter/evaluator/src/utils.js | 8 ++ src/client/controllers/Poster.js | 3 + src/public/app.js | 4 +- 6 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 src/@evoposter/evaluator/src/metrics/VisualSemantics.mjs diff --git a/src/@evoposter/evaluator/src/index.mjs b/src/@evoposter/evaluator/src/index.mjs index aa385d3..4eaa962 100644 --- a/src/@evoposter/evaluator/src/index.mjs +++ b/src/@evoposter/evaluator/src/index.mjs @@ -10,6 +10,7 @@ import * as Legibility from "./metrics/Legibility.mjs"; import * as GridAppropriateSize from "./metrics/GridAppropriateSize.mjs"; import * as LayoutSemantics from "./metrics/LayoutSemantics.mjs"; +import * as VisualSemantics from "./metrics/VisualSemantics.mjs"; export const info = () => { console.log ("Evaluator working"); @@ -18,5 +19,6 @@ export const info = () => { export const legibility = Legibility.compute; export const gridAppropriateSize = GridAppropriateSize.compute; export const layoutSemantics = LayoutSemantics.compute; +export const visualSemantics = VisualSemantics.compute; export { info as default }; \ No newline at end of file diff --git a/src/@evoposter/evaluator/src/metrics/LayoutSemantics.mjs b/src/@evoposter/evaluator/src/metrics/LayoutSemantics.mjs index 7107523..626213d 100644 --- a/src/@evoposter/evaluator/src/metrics/LayoutSemantics.mjs +++ b/src/@evoposter/evaluator/src/metrics/LayoutSemantics.mjs @@ -22,7 +22,6 @@ */ import {arrMean, arrSum} from "../utils.js"; -import {sumArr} from "../../../../client/utils.js"; let dist = null; diff --git a/src/@evoposter/evaluator/src/metrics/VisualSemantics.mjs b/src/@evoposter/evaluator/src/metrics/VisualSemantics.mjs new file mode 100644 index 0000000..94abdb4 --- /dev/null +++ b/src/@evoposter/evaluator/src/metrics/VisualSemantics.mjs @@ -0,0 +1,102 @@ +/** + * Visual Semantics + * + * Measure the appropriate of the visual features + * based on the importance of the content + * it considers that most important parts of content + * are those have more emotions related + * + * return the mean of difference between all textboxes, + * a value between 1 (good) and 0 (bad) + * + * + * Sérgio M. Rebelo + * CDV lab. (CMS, CISUC, Portugal) + * srebelo[at]dei.uc.pt + * + * v1.0.0 November 2023 + */ +import {arrMax, arrMean, arrMin, map} from "../utils.js"; + +// by tradition, use more that a method to emphasize the text is considered typecrime +// this method enables turn on/off this, using the param allowMultiple +export const compute = (textboxes, dist, allowMultiple = false) => { + const fontWeight = 1-checkDifferenceVariableFeature(textboxes.map((b) => b["weight"]), dist.map((e) => e[3])); + const fontStretch = 1-checkDifferenceVariableFeature(textboxes.map((b) => b["font-stretch"]), dist.map((e) => e[3])); + + console.log (`fontWeight=`, fontWeight); + console.log (`fontStretch=`, fontStretch); + + // type design + + + // way of combine and only checks one + return [fontWeight, fontStretch]; +} + +const checkDifferenceVariableFeature = (currentFeatures, dist) => { + + // max feature range + const maxFeature = arrMax(currentFeatures); + const minFeature = arrMin(currentFeatures); + const range = Math.abs(maxFeature - minFeature); + + // semantic data range + const maxSemantic = arrMax(dist); + const minSemantic = arrMin(dist); + + // create target feature values + const target = dist.map((e) => { + // The most neutral sentence are the most regular + let v = map(e, minSemantic, maxSemantic, 0, range); + v = v > range ? range : v; + v = v < 0 ? 0 : v; + return v; + }); + + // distance to target + const current = []; + for (let i in currentFeatures) { + let w = currentFeatures[i]; + let currentDistance = Math.abs(w - minFeature); + let dif = Math.abs(currentDistance - target[i]); + current.push(dif); + } + + return arrMean(current)/range; +} + + +// check if the important part of text are typeset in a bolder typeface +const checkWeightFeature = (current, dist) => { + + // semantic data range + const maxSemantic = arrMax(dist); + const minSemantic = arrMin(dist); + + // max feature range + const maxFeature = arrMax(current); + const minFeature = arrMin(current); + + // create target feature values + const probs = dist.map((e) => { + let v = e[3]/maxSemantic * maxFeature; + if (e[3] === minSemantic) { + v = minFeature; + } + return v; + }); + + // calculate distance + let distance = []; + for (let i in current) { + let w = current[i] + let value = Math.abs(w-probs[i]); + distance.push(value); + } + + return arrMean(distance)/Math.abs(maxFeature-minFeature); +} + + +export { compute as default }; \ No newline at end of file diff --git a/src/@evoposter/evaluator/src/utils.js b/src/@evoposter/evaluator/src/utils.js index 8b3411f..7d0623e 100644 --- a/src/@evoposter/evaluator/src/utils.js +++ b/src/@evoposter/evaluator/src/utils.js @@ -10,3 +10,11 @@ export const arrMean = (arr) => { export const arrSum = (arr) => { return arr.reduce((partialSum, a) => partialSum + a, 0); } + +export const arrMax = (arr) => { + return Math.max(...arr); +} + +export const arrMin = (arr) => { + return Math.min(...arr); +} \ No newline at end of file diff --git a/src/client/controllers/Poster.js b/src/client/controllers/Poster.js index e728443..6b2dabc 100644 --- a/src/client/controllers/Poster.js +++ b/src/client/controllers/Poster.js @@ -226,6 +226,9 @@ class Poster { evaluate = async (dist) => { this.phenotype = await this.draw(); const layoutSemantics = evaluator.layoutSemantics(this.genotype["grid"]["rows"]["l"], dist, `RELATIVE`, this.genotype["size"]); + const visualSemantics = evaluator.visualSemantics(this.genotype["textboxes"], dist); + + console.log (`visualSemantics`, visualSemantics); this.fitness = layoutSemantics; diff --git a/src/public/app.js b/src/public/app.js index e1f5f70..85692c3 100644 --- a/src/public/app.js +++ b/src/public/app.js @@ -339,7 +339,7 @@ const ae=2;class le{constructor(e){}get _$AU(){return this._$AM._$AU}_$AT(e,t,r) `:U}
- `}createRenderRoot(){return this}}customElements.define("header-section",Me);var Te={solid:(e,t)=>{e.background(t)},gradient:(e,t,r)=>{push();const o=e.drawingContext;e.background(t);let s=e.height;const n=o.createLinearGradient(0,0,0,s);n.addColorStop(0,t),n.addColorStop(.25,t),n.addColorStop(.75,r),n.addColorStop(1,r),o.fillStyle=n,o.fillRect(0,0,e.width,s),pop()},triangle:(e,t,r)=>{push(),e.background(t),e.noStroke(),e.fill(r),e.triangle(0,0,0,e.height,e.width,e.height),pop()}};const Ce=(e,t,r,o,s)=>o+(e-t)/(r-t)*(s-o),Ae=e=>{const t=e.reduce(((e,t)=>e+t),0);return t/e.length||0},ke=(e,t)=>Ce(e=(e=e>=0?0:e)<=-t?-t:e,-t,0,1,0),Oe=(e,t)=>(e=Math.abs(e),Ce(e=e>t?t:e,t,0,1,0)),Le=(e,t)=>Oe(e=e>=0?e/3:e,t),Pe=(e=[],t,r="OVERSET",o=1)=>{let s=[],n=t*o;for(let o of e){let e=t-o,i=1;switch(r){case"JUSTIFY":i=Oe(e,n);break;case"ATTEMPT_JUSTIFY":i=Le(e,n);break;default:i=ke(e,n)}s.push(i)}return Ae([...s])},Re=(e,t,r=[],o=[],s={left:0,top:0,right:0,bottom:0})=>{let n=!1,i="",a=Math.abs(s.top)+Math.abs(s.bottom);for(let e of r)a+=parseFloat(e);let l=Math.abs(s.left)+Math.abs(s.right);for(let e of o)l+=parseFloat(e);return l=Math.round(l),a=Math.round(a),a>t?(n=!0,i+=`Grid height is bigger than container (grid:${a}, container:${t}). `):ae?(n=!0,i+=`Grid width is bigger than container (grid:${l}, container:${e}). `):l{"RELATIVE"!==r&&"FIXED"!==r&&(r="RELATIVE");let s=0;"RELATIVE"===r?s=e.reduce(((e,t)=>e+t),0):"FIXED"===r&&(s=o.height-(o.height*o.margin[1]+o.height*o.margin[3]));const n=e.map((e=>e/s));let i=[];for(let e in t){const r=Math.abs(t[e][3]-n[e]);i.push(r)}return 1-Ae(i)};function De(e,t,r){return Math.max(t,Math.min(e,r))}function Fe(e){return(e%360+360)%360}function Ne(e){var t,r;return Fe(function(e,t){var r;return e*(null!==(r={rad:180/Math.PI,grad:.9,turn:360}[t.toLowerCase()])&&void 0!==r?r:1)}(parseFloat(e),null!==(r=null===(t=e.match(/deg|rad|grad|turn/i))||void 0===t?void 0:t[0])&&void 0!==r?r:"deg"))}function Ue(e){return new RegExp(`^${e.source}$`,e.flags)}function Be(e){return e.slice(1).filter((e=>void 0!==e))}const Ge=/[+-]?(?=\.\d|\d)\d*(?:\.\d+)?(?:[eE][+-]?\d+)?/,ze=/(?=[,\s])\s*(?:,\s*)?/,Ve=/\s*[,\/]\s*/,$e=Ge.source,He=ze.source,qe=new RegExp(`hsla?\\(\\s*(${$e}(?:deg|rad|grad|turn)?)${He}(${$e})%${He}(${$e})%(?:${Ve.source}(${$e}%?))?\\s*\\)`,"i");const We={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aqua:"#00FFFF",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blue:"#0000FF",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",fuchsia:"#FF00FF",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",goldenrod:"#DAA520",gold:"#FFD700",gray:"#808080",green:"#008000",greenyellow:"#ADFF2F",grey:"#808080",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavenderblush:"#FFF0F5",lavender:"#E6E6FA",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgray:"#D3D3D3",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",lime:"#00FF00",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",maroon:"#800000",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",navy:"#000080",oldlace:"#FDF5E6",olive:"#808000",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",purple:"#800080",rebeccapurple:"#663399",red:"#FF0000",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",silver:"#C0C0C0",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",teal:"#008080",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",white:"#FFFFFF",whitesmoke:"#F5F5F5",yellow:"#FFFF00",yellowgreen:"#9ACD32"};const Xe=/[0-9a-fA-F]/.source,Ye=new RegExp(`#(${Xe}{2})(${Xe}{2})(${Xe}{2})(${Xe}{2})?`),Ze=new RegExp(`#(${Xe})(${Xe})(${Xe})(${Xe})?`);const Je=Ge.source,Qe=ze.source,Ke=new RegExp(`rgba?\\(\\s*(${Je}%?)${Qe}(${Je}%?)${Qe}(${Je}%?)(?:${Ve.source}(${Je}%?))?\\s*\\)`,"i");function et(e){return{r:De(e.r,0,255),g:De(e.g,0,255),b:De(e.b,0,255),a:De(e.a,0,1)}}function tt(e){if("transparent"===(e=e.trim()).toLowerCase())return{r:0,g:0,b:0,a:0};const t=We[e.toLowerCase()];let r;return t&&(e=t),null!==(r=function(e){var t;const r=null!==(t=Ue(Ye).exec(e))&&void 0!==t?t:Ue(Ze).exec(e);return r?Be(r):null}(e))?function(e){var t;const r=e.map((e=>(1===e.length&&(e=`${e}${e}`),parseInt(e,16)))),o=(null!==(t=r[3])&&void 0!==t?t:255)/255;return{r:r[0],g:r[1],b:r[2],a:o}}(r):null!==(r=function(e){const t=Ue(Ke).exec(e);return t?Be(t):null}(e))?function(e){var t;const r=e.map(((e,t)=>{let r=parseFloat(e);return e.indexOf("%")>-1&&(r*=.01,t<3&&(r*=255)),r}));return et({r:r[0],g:r[1],b:r[2],a:null!==(t=r[3])&&void 0!==t?t:1})}(r):null}function rt(e){return{h:Fe(e.h),s:De(e.s,0,100),l:De(e.l,0,100),a:De(e.a,0,1)}}function ot(e){const t=tt(e);return t?function(e){const{r:t,g:r,b:o,a:s}=et(e),n=t/255,i=r/255,a=o/255,l=Math.max(n,i,a),c=Math.min(n,i,a),u=l-c,d=(c+l)/2;let h=NaN,p=0;if(0!==u){switch(p=(l-d)/Math.min(d,1-d),l){case n:h=(i-a)/u+(iparseFloat(e)));let s=null!==(t=o[3])&&void 0!==t?t:1;return(null===(r=e[3])||void 0===r?void 0:r.indexOf("%"))>-1&&(s*=.01),rt({h:Ne(e[0]),s:o[1],l:o[2],a:s})}(t):null}function nt(e){return`rgba(${(e=function(e){return{r:Math.round(e.r),g:Math.round(e.g),b:Math.round(e.b),a:e.a}}(e)).r}, ${e.g}, ${e.b}, ${e.a})`}function it(e){const t=function(e){return"number"==typeof e.h&&"number"==typeof e.s&&"number"==typeof e.l&&"number"==typeof e.a}(e)?function(e){const{h:t,s:r,l:o,a:s}=rt(e),n=t||0,i=r/100,a=o/100;function l(e){const t=(e+n/30)%12,r=i*Math.min(a,1-a);return a-r*Math.max(-1,Math.min(t-3,9-t,1))}return{r:255*l(0),g:255*l(8),b:255*l(4),a:s}}(e):et(e);return 1===t.a?function(e){const t=(((255&Math.round(e.r))<<16)+((255&Math.round(e.g))<<8)+(255&Math.round(e.b))).toString(16).toUpperCase();return`#${"000000".substring(t.length)}${t}`}(t):nt(t)}var at=(e,t)=>{if("number"!=typeof t||0===t)return e;const r=function(e){var t;const r=null!==(t=st(e))&&void 0!==t?t:ot(e);if(null===r)throw new Error("Invalid color string");return r}(e),o=(r.h+t)%360;return it(Object.assign(Object.assign({},r),{h:o}))};var lt=(e,t)=>"number"!=typeof t||0===t?e:at(e,30*t);var ct=(e,t)=>{if("number"!=typeof t||0===t)return e;let r=0,o=t<0?-1:1,s=0;for(;s!==t;)s+=o,r+=s%2!=0?180*o:30*o;return at(e,r)};const ut=()=>{const e=ht();return dt(e)},dt=e=>{const t=ct(e,1);return{baseColour:e,colorA:t,colorB:lt(t,Math.round(4*Math.random()-2))}},ht=()=>{const e=[Math.round(255*Math.random()),Math.round(255*Math.random()),Math.round(255*Math.random())].map((e=>e.toString(16).padStart(2,"0")));return`#${e.join("")}`};class pt{#d=!1;#h=!1;constructor(e,t,r=null,o=null){this.id=`${t}-${e}`,this.n=e,this.generation=t,this.ready=!1,r=JSON.parse(JSON.stringify(r)),this.fitness=1,this.constraint=0,this.metrics={legibility:1,gridAppropriateness:1},this.sentencesLenght=[];const s=null===o?r.size.height:o.size.height;this.maxFontSize=se.typography.maxSize*s,this.minFontSize=se.typography.minSize*s,this.genotype=null===o?this.#p(r):o,this.#d=null===r||r.display.grid,this.phenotype=null}copy=()=>{const e=this.genotype.grid,t=new mt(JSON.parse(JSON.stringify(e.size)),JSON.parse(JSON.stringify(e.v)),JSON.parse(JSON.stringify(e.h)),JSON.parse(JSON.stringify(e.defaultMargins)),JSON.parse(JSON.stringify(e.gwper)),JSON.parse(JSON.stringify(e.ghper))),r=JSON.parse(JSON.stringify(this.genotype.size)),o=JSON.parse(JSON.stringify(this.genotype.textboxes));for(let e in o)o[e].color=color(this.genotype.textboxes[e].color);const s=JSON.parse(JSON.stringify(this.genotype.background));s.colors[0]=color(this.genotype.background.colors[0]),s.colors[1]=color(this.genotype.background.colors[1]);let n=[];for(let e of this.genotype.images){const t={scale:e.scale,src:e.src,x:e.x,y:e.y};n.push(t)}const i={grid:t,textboxes:o,size:r,background:s,typography:JSON.parse(JSON.stringify(this.genotype.typography)),images:n};return new pt(this.n,this.generation,null,i)};#p=e=>{const t=ut(),r=new mt({width:e.size.width,height:e.size.height,margin:e.size.margin},2,e.sentences.length,JSON.parse(JSON.stringify(e.size.margin))),o=[],s=0===e.typography.verticalAlignment?Math.round(Math.random()*(se.textAlignmentOptions.length-2)+1):e.typography.verticalAlignment;for(let n in e.sentences){const i=e.sentences[n],a=Math.round(Math.random()*(e.typography.typefaces.length-1));let l=e.typography.typefaces[a].stretch;l.map((e=>isNaN(e)?100:parseInt(e))),l.length<2&&l.push(100);let c=e.typography.typefaces[a].weight,u=Math.round(Math.random()*(e.typography.weight.max-e.typography.weight.min)+e.typography.weight.min);u=Math.max(c[0],Math.min(u,c[1]));let d=Math.round(Math.random()*(e.typography.stretch.max-e.typography.stretch.min)+e.typography.stretch.min);d=Math.max(l[0],Math.min(d,l[1]));const h=se.availableTypefacesInfo[se.availableTypefaces[a]].leading;let p=Math.round(r.rows.l[0])/h;p+=Math.round(-p*se.typography.range+Math.random()*(p*se.typography.range)),p=Math.max(Math.round(e.size.height*se.typography.minSize),Math.min(Math.round(e.size.height*se.typography.maxSize),p)),r.defineRow(n,p*h,s);const f=0===e.typography.textAlignment?Math.round(Math.random()*(se.textAlignmentTbOptions.length-2)+1):e.typography.textAlignment;o.push({content:i,weight:u,"font-stretch":d,alignment:f,size:p,typeface:e.typography.typefaces[a].family,color:e.typography.color.random?t.baseColour:color(e.typography.color.value),uppercase:e.typography.uppercase})}const n=[];for(let t of e.images){const r=t.src,o=loadImage(r,(async t=>{await t.resize(0,e.size.height),t.ready=!0}));n.push({x:Math.random(),y:Math.random(),scale:Math.random(),src:o})}return{grid:r,textboxes:o,size:{width:e.size.width,height:e.size.height,margin:e.size.margin},background:{style:0===e.background.style?Math.round(1+Math.random()*(se.background.availableStyles.length-2)):e.background.style,colors:[e.background.color.random?t.colorA:color(e.background.color.valueA),e.background.color.random?t.colorB:color(e.background.color.valueB)]},typography:{verticalAlignment:s},images:n}};draw=async()=>{this.ready=!0,this.phenotype=createGraphics(this.genotype.size.width,this.genotype.size.height),this.phenotype.id=this.n;const e=Object.keys(Te)[this.genotype.background.style-1];return(0,Te[e])(this.phenotype,this.genotype.background.colors[0],this.genotype.background.colors[1]),this.ready=await this.#f(this.phenotype),await this.typeset(this.phenotype),this.#h&&(pg.textSize(10),pg.fill(0),pg.text(`${this.id}+${this.genotype.typography.verticalAlignment}+style=${this.genotype.background.style}\nfitness=${this.fitness}`,20,20)),(this.#d||this.#h)&&this.genotype.grid.display(this.phenotype),this.phenotype};evaluate=async e=>{this.phenotype=await this.draw();const t=Ie(this.genotype.grid.rows.l,e,"RELATIVE",this.genotype.size);this.fitness=t;const r=Pe(this.sentencesLenght,this.genotype.grid.getAvailableWidth(),"OVERSET"),o=Re(this.genotype.size.width,this.genotype.size.height,this.genotype.grid.rows.l,this.genotype.grid.columns.l,this.genotype.grid.marginsPos);return this.constraint=r+o,this.metrics.legibility=r,this.metrics.gridAppropriateness=o,{fitness:this.fitness,constraints:this.constraint}};typeset=async e=>{this.sentencesLenght=[],e.push(),e.translate(e.width/2,e.height/2);const t=e.drawingContext;for(let r in this.genotype.textboxes){const o=this.genotype.textboxes[r];let s=o.alignment,n=LEFT;2===s?n=CENTER:3===s&&(n=RIGHT),e.textAlign(n,BASELINE);let i=this.genotype.grid.col(s-1,!1),a=this.genotype.grid.row(parseInt(r)+1,!1);e.fill(o.color),t.font=`${o.weight} ${ft(o["font-stretch"])} ${o.size}px ${o.typeface}`,drawingContext.font=`${o.weight} ${ft(o["font-stretch"])} ${o.size}px ${o.typeface}`;let l=!0===o.uppercase?o.content.toUpperCase():o.content;e.text(l,i,a);const c=t.measureText(l).width;this.sentencesLenght.push(c)}e.pop()};#f=async e=>{let t=!0;for(let r of this.genotype.images)if(void 0!==r.src&&r.src.hasOwnProperty("ready")){if(r.src.ready){let t=e.width*r.x,o=e.height*r.y;e.imageMode(CENTER),e.image(r.src,t,o,r.src.width*r.scale,r.src.height*r.scale)}}else t=!1;return t};toggleGrid=(e=null)=>{null===e&&(e=!this.#d),this.#d=e,this.draw(null,"n/d")}}const ft=e=>e>-10&&e<=50?"ultra-condensed":e>50&&e<=62.5?"extra-condensed":e>62.5&&e<=75?"condensed":e>75&&e<=87.5?"semi-condensed":e>87.5&&e<=100?"normal":e>100&&e<=112.5?"semi-expanded":e>112.5&&e<=125?"expanded":e>125&&e<=150?"extra-expanded":"ultra-expanded";class mt{constructor(e,t=12,r=24,o,s=.03,n=null){null===n&&(n=s),this.pos=createVector(e.width/2,e.height/2),this.size=JSON.parse(JSON.stringify(e)),this.defaultMargins=o,this.v=t,this.h=r,this.gwper=s,this.ghper=n,this.gapw=this.size.width*this.gwper,this.gaph=this.size.height*this.ghper,this.regular=!0,this.verticalSpace=[],this.marginsPos={},this.columns={},this.columns.y={},this.columns.center={},this.columns.gap={},this.rows={},this.rows.x={},this.rows.center={},this.rows.gap={},this.def()}export=()=>({pos:[this.pos.x,this.pos.y,this.pos.z],size:this.size,defaultMargins:this.defaultMargins,v:this.v,h:this.h,gapw:this.gapw,gaph:this.gaph,marginsPos:this.marginsPos,columns:this.columns,rows:this.rows});copy=()=>new mt(JSON.parse(JSON.stringify(this.size)),JSON.parse(JSON.stringify(this.v)),JSON.parse(JSON.stringify(this.h)),JSON.parse(JSON.stringify(this.defaultMargins)),JSON.parse(JSON.stringify(this.gwper)),JSON.parse(JSON.stringify(this.ghper)));updateMarginsBasedOnSize=(e=0,t=1,r,o=this.size.height)=>{const s=t*r;let n=this.size.height-s;0===e&&(n/=2),(0===e||1===e)&&this.size.margin[1]{0===e&&(t/=2),(0===e||1===e)&&this.size.margin[1]{this.size.margin=this.defaultMargins,this.marginsPos.left=this.size.margin[0]*this.size.width,this.marginsPos.top=this.size.margin[1]*this.size.height,this.marginsPos.right=this.size.margin[2]*this.size.width,this.marginsPos.bottom=this.size.margin[3]*this.size.height,this.def()};def=()=>{this.#m(),this.#y(),this.#g()};update=(e=null,t=null)=>{null!==e&&e!==this.v&&console.log(`grid updated from ${this.v} to ${e}`)};defineRow=(e,t,r)=>{this.regular=!1;const o=this.rows.l[e];this.rows.l[e]=t;let s=this.rows.l[e]-o;s=2===r?s/2:s,this.marginsPos.bottom,this.size.height,r<=2&&(this.size.margin[3]=(this.marginsPos.bottom-s)/this.size.height),r>=2&&(this.size.margin[1]=(this.marginsPos.top-s)/this.size.height),this.def()};#m=()=>{this.marginsPos.left=this.size.margin[0]*this.size.width,this.marginsPos.top=this.size.margin[1]*this.size.height,this.marginsPos.right=this.size.margin[2]*this.size.width,this.marginsPos.bottom=this.size.margin[3]*this.size.height};getSpace=()=>{const e=this.rows.l.reduce(((e,t)=>e+t),0)/this.rows.l.length;return{centre:{col:this.columns.l,row:e},gap:{col:this.columns.l-this.gapw/2,row:e-this.gaph/2}}};#y=()=>{this.columns.y.top=-this.size.height/2+this.marginsPos.top,this.columns.y.bottom=this.size.height/2-this.marginsPos.bottom;const e=(this.size.width-(this.marginsPos.left+this.marginsPos.right))/this.v;let t=[];for(let r=0;r0&&t{this.rows.x.left=-this.size.width/2+this.marginsPos.left,this.rows.x.right=this.size.width/2-this.marginsPos.right;const t=e;this.rows.l=t;let r=-this.size.height/2+this.marginsPos.top;for(let e=0;e0&&e{this.rows.x.left=-this.size.width/2+this.marginsPos.left,this.rows.x.right=this.size.width/2-this.marginsPos.right;const e=(this.size.height-(this.marginsPos.top+this.marginsPos.bottom))/this.h;if(null===this.verticalSpace||this.verticalSpace.length!==this.h||this.regular){this.verticalSpace=[];for(let t=0;tthis.h?r+=parseInt(this.rows.l[e-1]):r+=parseInt(this.rows.l[e]),this.rows.gap[e]={},e>0&&ee=0?t?this.columns.center[e]:this.columns.gap[e].right:(console.error(`this col dod not exists in grid. requested number ${e}`),0);row=(e,t=!1)=>e=0?t?this.rows.center[e]:this.rows.gap[e].top:(console.error(`this row do not exists in grid. requested number ${e}`),0);getAvailableWidth=(e=!0)=>{if(e){return this.size.width-this.size.width*this.size.margin[0]-this.size.width*this.size.margin[2]}return this.size.width};width=(e,t=!1,r=!1)=>e0?t||e===this.v?this.columns.l*e:r?this.columns.l*e-this.gapw/2:this.columns.l*e-this.gapw:(console.error(`side bigger than grid. requested side ${e}`),0);height=(e,t=!1,r=!1)=>e0?t||e===this.h?this.rows.l*e:r?this.rows.l*e-this.gaph/2:this.rows.l*e-this.gaph:(console.error(`side bigger than row grid. requested side ${e}`),0);display=(e,t=!0,r=!0,o=!0)=>{e.push(),e.translate(this.size.width/2,this.size.height/2),r&&this.#v(e),o&&this.#b(e),t&&this.#_(e),e.pop()};#_=(e,t="#0000ff")=>{e.push(),e.stroke(t),e.rectMode(CORNER),e.noFill(),e.rect(this.rows.x.left,this.columns.y.top,this.size.width-(this.marginsPos.left+this.marginsPos.right),this.size.height-(this.marginsPos.top+this.marginsPos.bottom)),e.pop()};#v=(e,t="#ff00ff",r="#009800")=>{e.push(),e.stroke(t);for(let t of Object.keys(this.columns.center)){const r=this.columns.center[t];e.line(r,this.columns.y.top,r,this.columns.y.bottom)}e.stroke(r);for(let t of Object.keys(this.columns.gap)){const r=this.columns.gap[t];"0"!==t&&t!==""+this.v&&(e.line(r.left,this.columns.y.top,r.left,this.columns.y.bottom),e.line(r.right,this.columns.y.top,r.right,this.columns.y.bottom))}e.pop()};#b=(e,t="#ff00ff",r="#009800")=>{e.push(),e.stroke(t);for(let t of Object.keys(this.rows.center)){const r=this.rows.center[t];e.line(this.rows.x.left,r,this.rows.x.right,r)}e.stroke(r);for(let t of Object.keys(this.rows.gap)){t=parseInt(t);const r=this.rows.gap[t];0!==t&&t!==this.h&&(e.text(t,this.rows.x.left+this.rows.x.right/2,r.top),e.line(this.rows.x.left,r.top,this.rows.x.right,r.top),e.line(this.rows.x.left,r.bottom,this.rows.x.right,r.bottom))}e.pop()}}class yt{#w;#x;constructor(e,t){this.size=e.evo.popSize,this.params=e,this.population=[],this.generations=0,this.ready=!1,this.evolving=!1,this.pause=!1,this.#x=t,this.targetSemanticLayout=this.#j(this.#x),console.log("targetSemanticLayout",this.targetSemanticLayout),this.#w=[],this.updated=!0,this.log={config:this.params,generations:[]},this.initialisation()}initialisation=async()=>{this.updated=!0,this.generations=0,this.#S();for(let e=0;ee.typeface));for(const e of r)-1===this.#w.indexOf(e)&&this.#w.push(e)}await this.evaluate(),this.updated=!0};evolve=async()=>{await this.#S(),document.getElementById("generation-number").textContent=this.generations;const e=[],t=parseInt(this.params.evo.eliteSize);for(let r=0;re.fitness)),o=this.population.map((e=>e.constraint));const s=await this.#E(r,o);for(let r=t;r{this.evolve()}),100):(this.evolving=!1,console.group("stats"),console.log(this.log),console.groupEnd())};uniformCrossover=(e,t)=>{const r=e.copy();t=t.copy(),Math.random()>.5&&(r.genotype.typography.verticalAlignment=t.genotype.typography.verticalAlignment);for(const e in r.genotype.textboxes)Math.random()>.5&&(r.genotype.textboxes[e]=t.genotype.textboxes[e]);r.genotype.grid=new mt(this.params.size,2,this.params.sentences.length,this.params.size.margin);for(const e in r.genotype.textboxes){const t=r.genotype.textboxes[e],o=se.availableTypefacesInfo[t.typeface].leading;r.genotype.grid.defineRow(e,t.size*o,r.genotype.typography.verticalAlignment)}if(Math.random()>.5&&(r.genotype.background.style=t.genotype.background.style),Math.random()>.5){r.genotype.background.colors[0]=t.genotype.background.colors[0],r.genotype.background.colors[1]=t.genotype.background.colors[1];for(const e in r.genotype.textboxes)r.genotype.textboxes[e].color=t.genotype.textboxes[e].color}else{let t=e.genotype.textboxes[0].color,o=t.levels?color(t.levels[0],t.levels[1],t.levels[2]):color(t);for(const e in r.genotype.textboxes)r.genotype.textboxes[e].color=o}for(const e in r.genotype.images)Math.random()>.5&&(r.genotype.images[e]=t.genotype.images[e]);return r};mutate=e=>{let t=this.params.evo.mutationProb;if(Math.random()1){const e=Math.round(Math.random()*(this.params.typography.typefaces.length-1));n=e,s.typeface=this.params.typography.typefaces[e].family}if(Math.random()<2*t){let t=Math.round(s.size+-5+5*Math.random());t=Math.min(Math.max(t,e.minFontSize),e.maxFontSize),s.size=t,r=!0}if(Math.random(){for(let t of this.population)t.toggleGrid(e);this.updated=!0};evaluate=async()=>{for(let e of this.population)await e.evaluate(this.targetSemanticLayout);await this.#T()};#E=async(e,t,r=.45)=>{let o=this.population.length,s=Array.from(Array(o).keys());for(let n=0;ne[s[i+1]]||t[s[i]]>t[s[i+1]])&&(me(s,i,i+1),n=!1)}if(n)break;n=!0}return s};#T=async()=>{this.population=this.population.sort(((e,t)=>t.fitness-t.constraint-(e.fitness-e.constraint))),console.log("best individual=",this.population[0].fitness,this.population[0].constraint)};copy=e=>JSON.parse(JSON.stringify(e));#M=(e,t=5,r=2,o=2)=>{t=te-t));let i=n.map((e=>o-2*e*(o-1)/(this.population.length-1)));const a=ye(i);i=i.map((e=>e/a)),i=(e=>{for(let t=e.length-1;t>0;t--){const r=Math.floor(Math.random()*(t+1));[e[t],e[r]]=[e[r],e[t]]}return e})(i);for(let e=0;e{for(let e of this.#w){if(!document.fonts.check(`12px ${e}`))return!1}return!0};#S=()=>{document.querySelectorAll("canvas:not(#defaultCanvas0)").forEach((e=>{e.remove()}))};draw=async()=>{this.updated=!1;const e=this.population.length{for(let e in this.population){const t=this.population[e];save(t.phenotype,`${Date.now()}-${this.generations}-${e}`)}};#j=(e,t=.1)=>{let r=[];for(let o of e.lexicon.sentences){let e=o.emotions.data.recognisedEmotions.length,s=o.emotions.data.recognisedEmotions.map((e=>e[0])),n=o.emotions.data.recognisedEmotions.reduce(((e,t)=>e+t[1]),0);n+=t,r.push([e,s,n])}const o=ye(r.map((e=>e[2])));return r=r.map((e=>[e[0],e[1],e[2],Math.round(e[2]/o*100)/100])),r}}window.preload=()=>{},window.setup=()=>{window.app=document.createElement("app-evo"),document.querySelector("main").appendChild(app),noCanvas(),noLoop(),frameRate(25)},window.draw=()=>{if(window.app.screen<3)return null;window.app.population.updated&&(push(),background(window.app.backgroundColor),window.app.population.draw(),pop())},window.windowResized=()=>{if(window.app.screen<2)return null},window.keyPressed=()=>{if(window.app.screen<2)return null};class gt extends re{static properties={screen:0,results:{},evolving:!1};constructor(){super(),this.results=null,this.screen=0,this.evolving=!1;const e=this.#A();this.config={evo:{popSize:se.evolution.popSize,noGen:se.evolution.noGen,crossoverProb:se.evolution.crossoverProb,mutationProb:se.evolution.mutationProb,eliteSize:se.evolution.eliteSize},size:{width:se.visualisationGrid.width,height:se.visualisationGrid.height,margin:se.visualisationGrid.posterMargins},images:[],sentences:null,background:{style:0,color:{random:!0,valueA:se.background.defaultColors[0],valueB:se.background.defaultColors[1]},lock:[!1,!1]},typography:{verticalAlignment:0,color:{random:!0,value:se.typography.defaultColor},textAlignment:0,typefaces:e.typefaces,weight:e.weight,stretch:e.stretch,uppercase:!1,texboxAlignment:0,lock:[!1,!1,!1,!1,!1,!1,!1,!1]},display:{grid:!0}},this.population=null,this.errorMessage=new he,this.resultsContainer=new de,this.inputForm=new ie(this.analyse,this.resultsContainer,this.errorMessage),this.header=new Me,this.initPopForm=new Ee(this.config,this.#k,this.population,this.errorMessage),document.getElementById("defaultCanvas0").style.visibility="visible",this.backgroundColor=getComputedStyle(document.documentElement).getPropertyValue("--main-bg-color")}#A=()=>{const e={typefaces:[],weight:{min:Number.MAX_VALUE,max:Number.MIN_VALUE},stretch:{min:Number.MAX_VALUE,max:Number.MIN_VALUE}};for(let t of Array.from(document.fonts))if(se.availableTypefaces.includes(t.family)){let r=t.stretch.replaceAll("%","").split(" ").map((e=>parseInt(e)));e.stretch.min>r[0]&&(e.stretch.min=r[0]),e.stretch.maxparseInt(e)));e.weight.min>o[0]&&(e.weight.min=o[0]),e.weight.max{const e=this.inputForm.data();let t=`/${e.shouldDivide?"text":`lines/${e.delimiter}`}/${e.lang}/${e.textContent}`;fetch(t).then((e=>e.json())).then((e=>{this.results=e,!1===e.success&&this.errorMessage.set(e),this.resultsContainer.set(this.results),this.inputForm.dis(),this.screen=1})).catch((e=>{this.errorMessage.set(e)}))};setupEvolution=e=>{e.preventDefault(),this.screen=2,this.config.images=Array.from(document.querySelectorAll("#input-images img")),this.#O(),this.#k()};#k=(e=!1)=>{e&&this.#O(),background(this.backgroundColor),null!==this.results?(null==this.config.sentences&&(this.config.sentences=this.results.sentences),this.population=new yt(this.config,this.results),this.initPopForm.pop=this.population,this.screen=3,this.header.showControls()):this.errorMessage.set({msg:"text input not defined. Not possible to init population"})};#O=()=>{let e=se.visiblePosters,t=Math.ceil(e/Math.floor(windowWidth/this.config.size.width));t*=this.config.size.height+2*se.visualisationGrid.marginY,createCanvas(windowWidth,t),loop()};#L=()=>F` + `}createRenderRoot(){return this}}customElements.define("header-section",Me);var Te={solid:(e,t)=>{e.background(t)},gradient:(e,t,r)=>{push();const o=e.drawingContext;e.background(t);let s=e.height;const n=o.createLinearGradient(0,0,0,s);n.addColorStop(0,t),n.addColorStop(.25,t),n.addColorStop(.75,r),n.addColorStop(1,r),o.fillStyle=n,o.fillRect(0,0,e.width,s),pop()},triangle:(e,t,r)=>{push(),e.background(t),e.noStroke(),e.fill(r),e.triangle(0,0,0,e.height,e.width,e.height),pop()}};const Ce=(e,t,r,o,s)=>o+(e-t)/(r-t)*(s-o),Ae=e=>{const t=e.reduce(((e,t)=>e+t),0);return t/e.length||0},ke=e=>Math.max(...e),Oe=e=>Math.min(...e),Le=(e,t)=>Ce(e=(e=e>=0?0:e)<=-t?-t:e,-t,0,1,0),Pe=(e,t)=>(e=Math.abs(e),Ce(e=e>t?t:e,t,0,1,0)),Re=(e,t)=>Pe(e=e>=0?e/3:e,t),Ie=(e,t)=>{const r=ke(e),o=Oe(e),s=Math.abs(r-o),n=ke(t),i=Oe(t),a=t.map((e=>{let t=Ce(e,i,n,0,s);return t=t>s?s:t,t=t<0?0:t,t})),l=[];for(let t in e){let r=e[t],s=Math.abs(r-o),n=Math.abs(s-a[t]);l.push(n)}return Ae(l)/s},De=(e=[],t,r="OVERSET",o=1)=>{let s=[],n=t*o;for(let o of e){let e=t-o,i=1;switch(r){case"JUSTIFY":i=Pe(e,n);break;case"ATTEMPT_JUSTIFY":i=Re(e,n);break;default:i=Le(e,n)}s.push(i)}return Ae([...s])},Fe=(e,t,r=[],o=[],s={left:0,top:0,right:0,bottom:0})=>{let n=!1,i="",a=Math.abs(s.top)+Math.abs(s.bottom);for(let e of r)a+=parseFloat(e);let l=Math.abs(s.left)+Math.abs(s.right);for(let e of o)l+=parseFloat(e);return l=Math.round(l),a=Math.round(a),a>t?(n=!0,i+=`Grid height is bigger than container (grid:${a}, container:${t}). `):ae?(n=!0,i+=`Grid width is bigger than container (grid:${l}, container:${e}). `):l{"RELATIVE"!==r&&"FIXED"!==r&&(r="RELATIVE");let s=0;"RELATIVE"===r?s=e.reduce(((e,t)=>e+t),0):"FIXED"===r&&(s=o.height-(o.height*o.margin[1]+o.height*o.margin[3]));const n=e.map((e=>e/s));let i=[];for(let e in t){const r=Math.abs(t[e][3]-n[e]);i.push(r)}return 1-Ae(i)},Ue=(e,t,r=!1)=>{const o=Ie(e.map((e=>e.weight)),t.map((e=>e[3]))),s=Ie(e.map((e=>e["font-stretch"])),t.map((e=>e[3])));return console.log("fontWeight=",o),console.log("fontStretch=",s),[o,s]};function Be(e,t,r){return Math.max(t,Math.min(e,r))}function Ge(e){return(e%360+360)%360}function ze(e){var t,r;return Ge(function(e,t){var r;return e*(null!==(r={rad:180/Math.PI,grad:.9,turn:360}[t.toLowerCase()])&&void 0!==r?r:1)}(parseFloat(e),null!==(r=null===(t=e.match(/deg|rad|grad|turn/i))||void 0===t?void 0:t[0])&&void 0!==r?r:"deg"))}function Ve(e){return new RegExp(`^${e.source}$`,e.flags)}function $e(e){return e.slice(1).filter((e=>void 0!==e))}const He=/[+-]?(?=\.\d|\d)\d*(?:\.\d+)?(?:[eE][+-]?\d+)?/,qe=/(?=[,\s])\s*(?:,\s*)?/,We=/\s*[,\/]\s*/,Xe=He.source,Ye=qe.source,Ze=new RegExp(`hsla?\\(\\s*(${Xe}(?:deg|rad|grad|turn)?)${Ye}(${Xe})%${Ye}(${Xe})%(?:${We.source}(${Xe}%?))?\\s*\\)`,"i");const Je={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aqua:"#00FFFF",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blue:"#0000FF",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",fuchsia:"#FF00FF",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",goldenrod:"#DAA520",gold:"#FFD700",gray:"#808080",green:"#008000",greenyellow:"#ADFF2F",grey:"#808080",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavenderblush:"#FFF0F5",lavender:"#E6E6FA",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgray:"#D3D3D3",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",lime:"#00FF00",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",maroon:"#800000",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",navy:"#000080",oldlace:"#FDF5E6",olive:"#808000",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",purple:"#800080",rebeccapurple:"#663399",red:"#FF0000",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",silver:"#C0C0C0",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",teal:"#008080",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",white:"#FFFFFF",whitesmoke:"#F5F5F5",yellow:"#FFFF00",yellowgreen:"#9ACD32"};const Qe=/[0-9a-fA-F]/.source,Ke=new RegExp(`#(${Qe}{2})(${Qe}{2})(${Qe}{2})(${Qe}{2})?`),et=new RegExp(`#(${Qe})(${Qe})(${Qe})(${Qe})?`);const tt=He.source,rt=qe.source,ot=new RegExp(`rgba?\\(\\s*(${tt}%?)${rt}(${tt}%?)${rt}(${tt}%?)(?:${We.source}(${tt}%?))?\\s*\\)`,"i");function st(e){return{r:Be(e.r,0,255),g:Be(e.g,0,255),b:Be(e.b,0,255),a:Be(e.a,0,1)}}function nt(e){if("transparent"===(e=e.trim()).toLowerCase())return{r:0,g:0,b:0,a:0};const t=Je[e.toLowerCase()];let r;return t&&(e=t),null!==(r=function(e){var t;const r=null!==(t=Ve(Ke).exec(e))&&void 0!==t?t:Ve(et).exec(e);return r?$e(r):null}(e))?function(e){var t;const r=e.map((e=>(1===e.length&&(e=`${e}${e}`),parseInt(e,16)))),o=(null!==(t=r[3])&&void 0!==t?t:255)/255;return{r:r[0],g:r[1],b:r[2],a:o}}(r):null!==(r=function(e){const t=Ve(ot).exec(e);return t?$e(t):null}(e))?function(e){var t;const r=e.map(((e,t)=>{let r=parseFloat(e);return e.indexOf("%")>-1&&(r*=.01,t<3&&(r*=255)),r}));return st({r:r[0],g:r[1],b:r[2],a:null!==(t=r[3])&&void 0!==t?t:1})}(r):null}function it(e){return{h:Ge(e.h),s:Be(e.s,0,100),l:Be(e.l,0,100),a:Be(e.a,0,1)}}function at(e){const t=nt(e);return t?function(e){const{r:t,g:r,b:o,a:s}=st(e),n=t/255,i=r/255,a=o/255,l=Math.max(n,i,a),c=Math.min(n,i,a),u=l-c,d=(c+l)/2;let h=NaN,p=0;if(0!==u){switch(p=(l-d)/Math.min(d,1-d),l){case n:h=(i-a)/u+(iparseFloat(e)));let s=null!==(t=o[3])&&void 0!==t?t:1;return(null===(r=e[3])||void 0===r?void 0:r.indexOf("%"))>-1&&(s*=.01),it({h:ze(e[0]),s:o[1],l:o[2],a:s})}(t):null}function ct(e){return`rgba(${(e=function(e){return{r:Math.round(e.r),g:Math.round(e.g),b:Math.round(e.b),a:e.a}}(e)).r}, ${e.g}, ${e.b}, ${e.a})`}function ut(e){const t=function(e){return"number"==typeof e.h&&"number"==typeof e.s&&"number"==typeof e.l&&"number"==typeof e.a}(e)?function(e){const{h:t,s:r,l:o,a:s}=it(e),n=t||0,i=r/100,a=o/100;function l(e){const t=(e+n/30)%12,r=i*Math.min(a,1-a);return a-r*Math.max(-1,Math.min(t-3,9-t,1))}return{r:255*l(0),g:255*l(8),b:255*l(4),a:s}}(e):st(e);return 1===t.a?function(e){const t=(((255&Math.round(e.r))<<16)+((255&Math.round(e.g))<<8)+(255&Math.round(e.b))).toString(16).toUpperCase();return`#${"000000".substring(t.length)}${t}`}(t):ct(t)}var dt=(e,t)=>{if("number"!=typeof t||0===t)return e;const r=function(e){var t;const r=null!==(t=lt(e))&&void 0!==t?t:at(e);if(null===r)throw new Error("Invalid color string");return r}(e),o=(r.h+t)%360;return ut(Object.assign(Object.assign({},r),{h:o}))};var ht=(e,t)=>"number"!=typeof t||0===t?e:dt(e,30*t);var pt=(e,t)=>{if("number"!=typeof t||0===t)return e;let r=0,o=t<0?-1:1,s=0;for(;s!==t;)s+=o,r+=s%2!=0?180*o:30*o;return dt(e,r)};const ft=()=>{const e=yt();return mt(e)},mt=e=>{const t=pt(e,1);return{baseColour:e,colorA:t,colorB:ht(t,Math.round(4*Math.random()-2))}},yt=()=>{const e=[Math.round(255*Math.random()),Math.round(255*Math.random()),Math.round(255*Math.random())].map((e=>e.toString(16).padStart(2,"0")));return`#${e.join("")}`};class gt{#d=!1;#h=!1;constructor(e,t,r=null,o=null){this.id=`${t}-${e}`,this.n=e,this.generation=t,this.ready=!1,r=JSON.parse(JSON.stringify(r)),this.fitness=1,this.constraint=0,this.metrics={legibility:1,gridAppropriateness:1},this.sentencesLenght=[];const s=null===o?r.size.height:o.size.height;this.maxFontSize=se.typography.maxSize*s,this.minFontSize=se.typography.minSize*s,this.genotype=null===o?this.#p(r):o,this.#d=null===r||r.display.grid,this.phenotype=null}copy=()=>{const e=this.genotype.grid,t=new bt(JSON.parse(JSON.stringify(e.size)),JSON.parse(JSON.stringify(e.v)),JSON.parse(JSON.stringify(e.h)),JSON.parse(JSON.stringify(e.defaultMargins)),JSON.parse(JSON.stringify(e.gwper)),JSON.parse(JSON.stringify(e.ghper))),r=JSON.parse(JSON.stringify(this.genotype.size)),o=JSON.parse(JSON.stringify(this.genotype.textboxes));for(let e in o)o[e].color=color(this.genotype.textboxes[e].color);const s=JSON.parse(JSON.stringify(this.genotype.background));s.colors[0]=color(this.genotype.background.colors[0]),s.colors[1]=color(this.genotype.background.colors[1]);let n=[];for(let e of this.genotype.images){const t={scale:e.scale,src:e.src,x:e.x,y:e.y};n.push(t)}const i={grid:t,textboxes:o,size:r,background:s,typography:JSON.parse(JSON.stringify(this.genotype.typography)),images:n};return new gt(this.n,this.generation,null,i)};#p=e=>{const t=ft(),r=new bt({width:e.size.width,height:e.size.height,margin:e.size.margin},2,e.sentences.length,JSON.parse(JSON.stringify(e.size.margin))),o=[],s=0===e.typography.verticalAlignment?Math.round(Math.random()*(se.textAlignmentOptions.length-2)+1):e.typography.verticalAlignment;for(let n in e.sentences){const i=e.sentences[n],a=Math.round(Math.random()*(e.typography.typefaces.length-1));let l=e.typography.typefaces[a].stretch;l.map((e=>isNaN(e)?100:parseInt(e))),l.length<2&&l.push(100);let c=e.typography.typefaces[a].weight,u=Math.round(Math.random()*(e.typography.weight.max-e.typography.weight.min)+e.typography.weight.min);u=Math.max(c[0],Math.min(u,c[1]));let d=Math.round(Math.random()*(e.typography.stretch.max-e.typography.stretch.min)+e.typography.stretch.min);d=Math.max(l[0],Math.min(d,l[1]));const h=se.availableTypefacesInfo[se.availableTypefaces[a]].leading;let p=Math.round(r.rows.l[0])/h;p+=Math.round(-p*se.typography.range+Math.random()*(p*se.typography.range)),p=Math.max(Math.round(e.size.height*se.typography.minSize),Math.min(Math.round(e.size.height*se.typography.maxSize),p)),r.defineRow(n,p*h,s);const f=0===e.typography.textAlignment?Math.round(Math.random()*(se.textAlignmentTbOptions.length-2)+1):e.typography.textAlignment;o.push({content:i,weight:u,"font-stretch":d,alignment:f,size:p,typeface:e.typography.typefaces[a].family,color:e.typography.color.random?t.baseColour:color(e.typography.color.value),uppercase:e.typography.uppercase})}const n=[];for(let t of e.images){const r=t.src,o=loadImage(r,(async t=>{await t.resize(0,e.size.height),t.ready=!0}));n.push({x:Math.random(),y:Math.random(),scale:Math.random(),src:o})}return{grid:r,textboxes:o,size:{width:e.size.width,height:e.size.height,margin:e.size.margin},background:{style:0===e.background.style?Math.round(1+Math.random()*(se.background.availableStyles.length-2)):e.background.style,colors:[e.background.color.random?t.colorA:color(e.background.color.valueA),e.background.color.random?t.colorB:color(e.background.color.valueB)]},typography:{verticalAlignment:s},images:n}};draw=async()=>{this.ready=!0,this.phenotype=createGraphics(this.genotype.size.width,this.genotype.size.height),this.phenotype.id=this.n;const e=Object.keys(Te)[this.genotype.background.style-1];return(0,Te[e])(this.phenotype,this.genotype.background.colors[0],this.genotype.background.colors[1]),this.ready=await this.#f(this.phenotype),await this.typeset(this.phenotype),this.#h&&(pg.textSize(10),pg.fill(0),pg.text(`${this.id}+${this.genotype.typography.verticalAlignment}+style=${this.genotype.background.style}\nfitness=${this.fitness}`,20,20)),(this.#d||this.#h)&&this.genotype.grid.display(this.phenotype),this.phenotype};evaluate=async e=>{this.phenotype=await this.draw();const t=Ne(this.genotype.grid.rows.l,e,"RELATIVE",this.genotype.size),r=Ue(this.genotype.textboxes,e);console.log("visualSemantics",r),this.fitness=t;const o=De(this.sentencesLenght,this.genotype.grid.getAvailableWidth(),"OVERSET"),s=Fe(this.genotype.size.width,this.genotype.size.height,this.genotype.grid.rows.l,this.genotype.grid.columns.l,this.genotype.grid.marginsPos);return this.constraint=o+s,this.metrics.legibility=o,this.metrics.gridAppropriateness=s,{fitness:this.fitness,constraints:this.constraint}};typeset=async e=>{this.sentencesLenght=[],e.push(),e.translate(e.width/2,e.height/2);const t=e.drawingContext;for(let r in this.genotype.textboxes){const o=this.genotype.textboxes[r];let s=o.alignment,n=LEFT;2===s?n=CENTER:3===s&&(n=RIGHT),e.textAlign(n,BASELINE);let i=this.genotype.grid.col(s-1,!1),a=this.genotype.grid.row(parseInt(r)+1,!1);e.fill(o.color),t.font=`${o.weight} ${vt(o["font-stretch"])} ${o.size}px ${o.typeface}`,drawingContext.font=`${o.weight} ${vt(o["font-stretch"])} ${o.size}px ${o.typeface}`;let l=!0===o.uppercase?o.content.toUpperCase():o.content;e.text(l,i,a);const c=t.measureText(l).width;this.sentencesLenght.push(c)}e.pop()};#f=async e=>{let t=!0;for(let r of this.genotype.images)if(void 0!==r.src&&r.src.hasOwnProperty("ready")){if(r.src.ready){let t=e.width*r.x,o=e.height*r.y;e.imageMode(CENTER),e.image(r.src,t,o,r.src.width*r.scale,r.src.height*r.scale)}}else t=!1;return t};toggleGrid=(e=null)=>{null===e&&(e=!this.#d),this.#d=e,this.draw(null,"n/d")}}const vt=e=>e>-10&&e<=50?"ultra-condensed":e>50&&e<=62.5?"extra-condensed":e>62.5&&e<=75?"condensed":e>75&&e<=87.5?"semi-condensed":e>87.5&&e<=100?"normal":e>100&&e<=112.5?"semi-expanded":e>112.5&&e<=125?"expanded":e>125&&e<=150?"extra-expanded":"ultra-expanded";class bt{constructor(e,t=12,r=24,o,s=.03,n=null){null===n&&(n=s),this.pos=createVector(e.width/2,e.height/2),this.size=JSON.parse(JSON.stringify(e)),this.defaultMargins=o,this.v=t,this.h=r,this.gwper=s,this.ghper=n,this.gapw=this.size.width*this.gwper,this.gaph=this.size.height*this.ghper,this.regular=!0,this.verticalSpace=[],this.marginsPos={},this.columns={},this.columns.y={},this.columns.center={},this.columns.gap={},this.rows={},this.rows.x={},this.rows.center={},this.rows.gap={},this.def()}export=()=>({pos:[this.pos.x,this.pos.y,this.pos.z],size:this.size,defaultMargins:this.defaultMargins,v:this.v,h:this.h,gapw:this.gapw,gaph:this.gaph,marginsPos:this.marginsPos,columns:this.columns,rows:this.rows});copy=()=>new bt(JSON.parse(JSON.stringify(this.size)),JSON.parse(JSON.stringify(this.v)),JSON.parse(JSON.stringify(this.h)),JSON.parse(JSON.stringify(this.defaultMargins)),JSON.parse(JSON.stringify(this.gwper)),JSON.parse(JSON.stringify(this.ghper)));updateMarginsBasedOnSize=(e=0,t=1,r,o=this.size.height)=>{const s=t*r;let n=this.size.height-s;0===e&&(n/=2),(0===e||1===e)&&this.size.margin[1]{0===e&&(t/=2),(0===e||1===e)&&this.size.margin[1]{this.size.margin=this.defaultMargins,this.marginsPos.left=this.size.margin[0]*this.size.width,this.marginsPos.top=this.size.margin[1]*this.size.height,this.marginsPos.right=this.size.margin[2]*this.size.width,this.marginsPos.bottom=this.size.margin[3]*this.size.height,this.def()};def=()=>{this.#m(),this.#y(),this.#g()};update=(e=null,t=null)=>{null!==e&&e!==this.v&&console.log(`grid updated from ${this.v} to ${e}`)};defineRow=(e,t,r)=>{this.regular=!1;const o=this.rows.l[e];this.rows.l[e]=t;let s=this.rows.l[e]-o;s=2===r?s/2:s,this.marginsPos.bottom,this.size.height,r<=2&&(this.size.margin[3]=(this.marginsPos.bottom-s)/this.size.height),r>=2&&(this.size.margin[1]=(this.marginsPos.top-s)/this.size.height),this.def()};#m=()=>{this.marginsPos.left=this.size.margin[0]*this.size.width,this.marginsPos.top=this.size.margin[1]*this.size.height,this.marginsPos.right=this.size.margin[2]*this.size.width,this.marginsPos.bottom=this.size.margin[3]*this.size.height};getSpace=()=>{const e=this.rows.l.reduce(((e,t)=>e+t),0)/this.rows.l.length;return{centre:{col:this.columns.l,row:e},gap:{col:this.columns.l-this.gapw/2,row:e-this.gaph/2}}};#y=()=>{this.columns.y.top=-this.size.height/2+this.marginsPos.top,this.columns.y.bottom=this.size.height/2-this.marginsPos.bottom;const e=(this.size.width-(this.marginsPos.left+this.marginsPos.right))/this.v;let t=[];for(let r=0;r0&&t{this.rows.x.left=-this.size.width/2+this.marginsPos.left,this.rows.x.right=this.size.width/2-this.marginsPos.right;const t=e;this.rows.l=t;let r=-this.size.height/2+this.marginsPos.top;for(let e=0;e0&&e{this.rows.x.left=-this.size.width/2+this.marginsPos.left,this.rows.x.right=this.size.width/2-this.marginsPos.right;const e=(this.size.height-(this.marginsPos.top+this.marginsPos.bottom))/this.h;if(null===this.verticalSpace||this.verticalSpace.length!==this.h||this.regular){this.verticalSpace=[];for(let t=0;tthis.h?r+=parseInt(this.rows.l[e-1]):r+=parseInt(this.rows.l[e]),this.rows.gap[e]={},e>0&&ee=0?t?this.columns.center[e]:this.columns.gap[e].right:(console.error(`this col dod not exists in grid. requested number ${e}`),0);row=(e,t=!1)=>e=0?t?this.rows.center[e]:this.rows.gap[e].top:(console.error(`this row do not exists in grid. requested number ${e}`),0);getAvailableWidth=(e=!0)=>{if(e){return this.size.width-this.size.width*this.size.margin[0]-this.size.width*this.size.margin[2]}return this.size.width};width=(e,t=!1,r=!1)=>e0?t||e===this.v?this.columns.l*e:r?this.columns.l*e-this.gapw/2:this.columns.l*e-this.gapw:(console.error(`side bigger than grid. requested side ${e}`),0);height=(e,t=!1,r=!1)=>e0?t||e===this.h?this.rows.l*e:r?this.rows.l*e-this.gaph/2:this.rows.l*e-this.gaph:(console.error(`side bigger than row grid. requested side ${e}`),0);display=(e,t=!0,r=!0,o=!0)=>{e.push(),e.translate(this.size.width/2,this.size.height/2),r&&this.#v(e),o&&this.#b(e),t&&this.#_(e),e.pop()};#_=(e,t="#0000ff")=>{e.push(),e.stroke(t),e.rectMode(CORNER),e.noFill(),e.rect(this.rows.x.left,this.columns.y.top,this.size.width-(this.marginsPos.left+this.marginsPos.right),this.size.height-(this.marginsPos.top+this.marginsPos.bottom)),e.pop()};#v=(e,t="#ff00ff",r="#009800")=>{e.push(),e.stroke(t);for(let t of Object.keys(this.columns.center)){const r=this.columns.center[t];e.line(r,this.columns.y.top,r,this.columns.y.bottom)}e.stroke(r);for(let t of Object.keys(this.columns.gap)){const r=this.columns.gap[t];"0"!==t&&t!==""+this.v&&(e.line(r.left,this.columns.y.top,r.left,this.columns.y.bottom),e.line(r.right,this.columns.y.top,r.right,this.columns.y.bottom))}e.pop()};#b=(e,t="#ff00ff",r="#009800")=>{e.push(),e.stroke(t);for(let t of Object.keys(this.rows.center)){const r=this.rows.center[t];e.line(this.rows.x.left,r,this.rows.x.right,r)}e.stroke(r);for(let t of Object.keys(this.rows.gap)){t=parseInt(t);const r=this.rows.gap[t];0!==t&&t!==this.h&&(e.text(t,this.rows.x.left+this.rows.x.right/2,r.top),e.line(this.rows.x.left,r.top,this.rows.x.right,r.top),e.line(this.rows.x.left,r.bottom,this.rows.x.right,r.bottom))}e.pop()}}class _t{#w;#x;constructor(e,t){this.size=e.evo.popSize,this.params=e,this.population=[],this.generations=0,this.ready=!1,this.evolving=!1,this.pause=!1,this.#x=t,this.targetSemanticLayout=this.#j(this.#x),console.log("targetSemanticLayout",this.targetSemanticLayout),this.#w=[],this.updated=!0,this.log={config:this.params,generations:[]},this.initialisation()}initialisation=async()=>{this.updated=!0,this.generations=0,this.#S();for(let e=0;ee.typeface));for(const e of r)-1===this.#w.indexOf(e)&&this.#w.push(e)}await this.evaluate(),this.updated=!0};evolve=async()=>{await this.#S(),document.getElementById("generation-number").textContent=this.generations;const e=[],t=parseInt(this.params.evo.eliteSize);for(let r=0;re.fitness)),o=this.population.map((e=>e.constraint));const s=await this.#E(r,o);for(let r=t;r{this.evolve()}),100):(this.evolving=!1,console.group("stats"),console.log(this.log),console.groupEnd())};uniformCrossover=(e,t)=>{const r=e.copy();t=t.copy(),Math.random()>.5&&(r.genotype.typography.verticalAlignment=t.genotype.typography.verticalAlignment);for(const e in r.genotype.textboxes)Math.random()>.5&&(r.genotype.textboxes[e]=t.genotype.textboxes[e]);r.genotype.grid=new bt(this.params.size,2,this.params.sentences.length,this.params.size.margin);for(const e in r.genotype.textboxes){const t=r.genotype.textboxes[e],o=se.availableTypefacesInfo[t.typeface].leading;r.genotype.grid.defineRow(e,t.size*o,r.genotype.typography.verticalAlignment)}if(Math.random()>.5&&(r.genotype.background.style=t.genotype.background.style),Math.random()>.5){r.genotype.background.colors[0]=t.genotype.background.colors[0],r.genotype.background.colors[1]=t.genotype.background.colors[1];for(const e in r.genotype.textboxes)r.genotype.textboxes[e].color=t.genotype.textboxes[e].color}else{let t=e.genotype.textboxes[0].color,o=t.levels?color(t.levels[0],t.levels[1],t.levels[2]):color(t);for(const e in r.genotype.textboxes)r.genotype.textboxes[e].color=o}for(const e in r.genotype.images)Math.random()>.5&&(r.genotype.images[e]=t.genotype.images[e]);return r};mutate=e=>{let t=this.params.evo.mutationProb;if(Math.random()1){const e=Math.round(Math.random()*(this.params.typography.typefaces.length-1));n=e,s.typeface=this.params.typography.typefaces[e].family}if(Math.random()<2*t){let t=Math.round(s.size+-5+5*Math.random());t=Math.min(Math.max(t,e.minFontSize),e.maxFontSize),s.size=t,r=!0}if(Math.random(){for(let t of this.population)t.toggleGrid(e);this.updated=!0};evaluate=async()=>{for(let e of this.population)await e.evaluate(this.targetSemanticLayout);await this.#T()};#E=async(e,t,r=.45)=>{let o=this.population.length,s=Array.from(Array(o).keys());for(let n=0;ne[s[i+1]]||t[s[i]]>t[s[i+1]])&&(me(s,i,i+1),n=!1)}if(n)break;n=!0}return s};#T=async()=>{this.population=this.population.sort(((e,t)=>t.fitness-t.constraint-(e.fitness-e.constraint))),console.log("best individual=",this.population[0].fitness,this.population[0].constraint)};copy=e=>JSON.parse(JSON.stringify(e));#M=(e,t=5,r=2,o=2)=>{t=te-t));let i=n.map((e=>o-2*e*(o-1)/(this.population.length-1)));const a=ye(i);i=i.map((e=>e/a)),i=(e=>{for(let t=e.length-1;t>0;t--){const r=Math.floor(Math.random()*(t+1));[e[t],e[r]]=[e[r],e[t]]}return e})(i);for(let e=0;e{for(let e of this.#w){if(!document.fonts.check(`12px ${e}`))return!1}return!0};#S=()=>{document.querySelectorAll("canvas:not(#defaultCanvas0)").forEach((e=>{e.remove()}))};draw=async()=>{this.updated=!1;const e=this.population.length{for(let e in this.population){const t=this.population[e];save(t.phenotype,`${Date.now()}-${this.generations}-${e}`)}};#j=(e,t=.1)=>{let r=[];for(let o of e.lexicon.sentences){let e=o.emotions.data.recognisedEmotions.length,s=o.emotions.data.recognisedEmotions.map((e=>e[0])),n=o.emotions.data.recognisedEmotions.reduce(((e,t)=>e+t[1]),0);n+=t,r.push([e,s,n])}const o=ye(r.map((e=>e[2])));return r=r.map((e=>[e[0],e[1],e[2],Math.round(e[2]/o*100)/100])),r}}window.preload=()=>{},window.setup=()=>{window.app=document.createElement("app-evo"),document.querySelector("main").appendChild(app),noCanvas(),noLoop(),frameRate(25)},window.draw=()=>{if(window.app.screen<3)return null;window.app.population.updated&&(push(),background(window.app.backgroundColor),window.app.population.draw(),pop())},window.windowResized=()=>{if(window.app.screen<2)return null},window.keyPressed=()=>{if(window.app.screen<2)return null};class wt extends re{static properties={screen:0,results:{},evolving:!1};constructor(){super(),this.results=null,this.screen=0,this.evolving=!1;const e=this.#A();this.config={evo:{popSize:se.evolution.popSize,noGen:se.evolution.noGen,crossoverProb:se.evolution.crossoverProb,mutationProb:se.evolution.mutationProb,eliteSize:se.evolution.eliteSize},size:{width:se.visualisationGrid.width,height:se.visualisationGrid.height,margin:se.visualisationGrid.posterMargins},images:[],sentences:null,background:{style:0,color:{random:!0,valueA:se.background.defaultColors[0],valueB:se.background.defaultColors[1]},lock:[!1,!1]},typography:{verticalAlignment:0,color:{random:!0,value:se.typography.defaultColor},textAlignment:0,typefaces:e.typefaces,weight:e.weight,stretch:e.stretch,uppercase:!1,texboxAlignment:0,lock:[!1,!1,!1,!1,!1,!1,!1,!1]},display:{grid:!0}},this.population=null,this.errorMessage=new he,this.resultsContainer=new de,this.inputForm=new ie(this.analyse,this.resultsContainer,this.errorMessage),this.header=new Me,this.initPopForm=new Ee(this.config,this.#k,this.population,this.errorMessage),document.getElementById("defaultCanvas0").style.visibility="visible",this.backgroundColor=getComputedStyle(document.documentElement).getPropertyValue("--main-bg-color")}#A=()=>{const e={typefaces:[],weight:{min:Number.MAX_VALUE,max:Number.MIN_VALUE},stretch:{min:Number.MAX_VALUE,max:Number.MIN_VALUE}};for(let t of Array.from(document.fonts))if(se.availableTypefaces.includes(t.family)){let r=t.stretch.replaceAll("%","").split(" ").map((e=>parseInt(e)));e.stretch.min>r[0]&&(e.stretch.min=r[0]),e.stretch.maxparseInt(e)));e.weight.min>o[0]&&(e.weight.min=o[0]),e.weight.max{const e=this.inputForm.data();let t=`/${e.shouldDivide?"text":`lines/${e.delimiter}`}/${e.lang}/${e.textContent}`;fetch(t).then((e=>e.json())).then((e=>{this.results=e,!1===e.success&&this.errorMessage.set(e),this.resultsContainer.set(this.results),this.inputForm.dis(),this.screen=1})).catch((e=>{this.errorMessage.set(e)}))};setupEvolution=e=>{e.preventDefault(),this.screen=2,this.config.images=Array.from(document.querySelectorAll("#input-images img")),this.#O(),this.#k()};#k=(e=!1)=>{e&&this.#O(),background(this.backgroundColor),null!==this.results?(null==this.config.sentences&&(this.config.sentences=this.results.sentences),this.population=new _t(this.config,this.results),this.initPopForm.pop=this.population,this.screen=3,this.header.showControls()):this.errorMessage.set({msg:"text input not defined. Not possible to init population"})};#O=()=>{let e=se.visiblePosters,t=Math.ceil(e/Math.floor(windowWidth/this.config.size.width));t*=this.config.size.height+2*se.visualisationGrid.marginY,createCanvas(windowWidth,t),loop()};#L=()=>F`
`:U} - `}createRenderRoot(){return this}}customElements.define("app-evo",gt);export{gt as App}; + `}createRenderRoot(){return this}}customElements.define("app-evo",wt);export{wt as App};