Logo Ğ vectoriel simplifié

Le logo Ğ vectoriel actuel est difficile à réutiliser dans de nouvelles images, car il faut tâtonner pour trouver les coordonnées du centre et la bonne taille. Il est également lourd pour ce qu’il est (ce qui reste très léger quand même).

gbreve.svg

J’ai donc fait une nouvelle version :

  • le centre du G est aux coordonnées (0 0)
  • les coordonnées utilisées vont de -1 à 1
  • tout est défini au plus simple (les arrondis sont faits en un arc d’ellipse plutôt qu’en une série de courbes de Bézier ou quadratiques)
  • 496 octets au lieu de 2300 pour l’ancienne version miniaturisée (11ko non miniaturisée)
  • facile à réutiliser
  • les valeurs chiffrées sont issues de calculs trigonométriques simples et non fixés arbitrairement à la souris

Le tracé est très légèrement différent (un peu plus épais, coupe de la mâchoire supérieure du G en rayon à 45° exactement) mais de loin ça ne se voit pas.

<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="-1 -1 2 2">
	<g id="gbreve" transform="scale(0.25)">
		<path id="g" d="M 0.7071,0.7071 A 1,1 0 1,1 0.866,-0.5 L 1.7321,-1 A 2,2 0 1,0 1.4142,1.4142 l 0.3536,0.3536 v -1.4142 h -1.4142 z" fill="#000"/>
		<path id="breve" d="M 1,0 h 1 A 2,2 0 0,0 -0.5176,-1.9319 L -0.2588,-0.9659 A 1,1 0 0,1 1,0 z" transform="translate(0 -3.14159) scale(0.5) rotate(142.5)" fill="#000"/>
	</g>
</svg>

exemples de réutilisation simple – ğréunion

Domaine public (licence CC0) (à moins que l’original ait une licence restrictive ?)

6 « J'aime »

Super boulot ! Merci.

Peux-tu intégrer ces fichiers dans un dépôt git pour nous permettre de facilement les retrouver et pour garder un historique des changements.

Il y a un ce dépôt sur l’organisation Duniter sur GH qui contient la licence Ğ1 et les logos. Le dépôt n’est pas sur notre GitLab.

2 « J'aime »

Par curiosité tu as utilisé un logiciel d’édition SVG où tu as construit ce SVG «à la main » ?

Je l’ai fait à la main dans un éditeur de texte, en faisant les calculs avec Python. Si tu connais un générateur de SVG capable de faire un truc propre à partir d’un script je suis preneur. (j’ai hésité à faire un générateur de logo Ğ en python)

Il y avait jadis un dépôt sur le GitLab mais il n’en subsiste que des forks…

3 « J'aime »

C’est @1000i100 qui avait créé le dépôt communication / G1 · GitLab, mais suite à une mauvaise manip de @inso tous les dépôts créer par 1000i100 avaient été supprimés.

J’en ai recréé certains (Gsper entre autres), mais pour le dépôt communication/G1 je ne sais pas sur quel fork me baser pour le recréer, une suggestion ?

Hélas non :confused:

3 « J'aime »

Hop : Simplified Ğ logo by ZettaScript · Pull Request #7 · duniter/G1 · GitHub

peut tu préciser le fichier et sa licence qui est l’existant pour toi ? et aussi préciser sous quelle licence tu publies le logo et les sources SVG ?

1 « J'aime »

Ce logo étant une traduction de l’ancien, il devrait donc être soumis à la licence de l’ancien, que je ne connais pas. Je le mets donc en domaine public (CC0) jusqu’à preuve du contraire. Pour un logo destiné à être utilisé partout par tout le monde, l’obligation d’attribution serait une contrainte de trop.

3 « J'aime »

Je viens de le remettre

3 « J'aime »

Merci, dans ce cas utilisons notre GitLab.

re-Hop : Merge Requests · communication / G1 · GitLab

2 « J'aime »

Merci pour ce travail ! Pourrais-tu faire une version avec un point en dessous comme celle utilisée sur le site ?

Sinon, je le ferai plus tard, en travaillant sur les illustrations du site.

Comme ça c’est bon ? ou peut-être le point plus bas ?

gbrevedot.svg

2 « J'aime »

Ça me parait bien. Je l’ajoute à la page d’accueil de ce pas :slight_smile: (et en plus ça la rendra plus légère)

1 « J'aime »

Je vais faire une version sans marges pour utilisation sur site web. Pourquoi as-tu mis la viewBox à viewBox="-1 -1 2 2" ? [edit] j’ai mis viewBox="-0.72 -0.72 1.44 1.44"

gbrevedot_color-alt

Marrant, le navigateur ne supporte pas les filets de dégradé.

2 « J'aime »

Quand je l’ouvre dans Inkscape j’ai le même rendu blanc.

Il doit manquer la définition de #meshgradient8278, il est peut-être défini dans ta config ?

https://svgwg.org/svg-next/pservers.html#SolidcolorProperties

Edit: mais sinon c’est joli !

1 « J'aime »

Ah oui, surprenant. Voici à quoi ça ressemble chez moi.

Voilà ma définition du gradient :

gradient
<meshgradient
       inkscape:collect="always"
       id="meshgradient8278"
       gradientUnits="userSpaceOnUse"
       x="-1.4970822"
       y="-1.4106324"
       gradientTransform="scale(0.25)">
      <meshrow
         id="meshrow34969">
        <meshpatch
           id="meshpatch34971">
          <stop
             path="c 0.320706,-0.266816  0.229276,-0.209345  0.482798,-0.351051"
             style="stop-color:#00ff42;stop-opacity:1"
             id="stop34973" />
          <stop
             path="c 0.447558,0.587057  0.97062,1.17638  0.97579,1.52358"
             style="stop-color:#7bff00;stop-opacity:1"
             id="stop34975" />
          <stop
             path="c -0.717587,-0.0703532  -1.29524,-0.673569  -1.82237,-0.604321"
             style="stop-color:#a9b523;stop-opacity:1"
             id="stop34977" />
          <stop
             path="c 0.0953168,-0.234107  0.220202,-0.385542  0.363782,-0.568208"
             style="stop-color:#00ffaa;stop-opacity:1"
             id="stop34979" />
        </meshpatch>
        <meshpatch
           id="meshpatch34981">
          <stop
             path="c 0.163025,-0.116365  0.662241,-0.29822  1.27917,-0.234847"
             id="stop34983" />
          <stop
             path="c 0.772818,0.12799  1.15756,0.402113  1.49073,0.947596"
             style="stop-color:#fff800;stop-opacity:1"
             id="stop34985" />
          <stop
             path="c -1.16597,0.197891  -1.24775,0.35063  -1.79411,0.810831"
             style="stop-color:#fd1900;stop-opacity:1"
             id="stop34987" />
        </meshpatch>
      </meshrow>
      <meshrow
         id="meshrow34989">
        <meshpatch
           id="meshpatch34991">
          <stop
             path="c 0.0171811,0.0675846  -0.00464089,0.0731624  0.0268794,0.141286"
             id="stop34993" />
          <stop
             path="c -0.754019,0.111294  -1.12951,-0.0444738  -1.95714,0.511458"
             style="stop-color:#cd7d3f;stop-opacity:1"
             id="stop34995" />
          <stop
             path="c -0.136209,-0.676474  0.033825,-1.07498  0.107891,-1.25706"
             style="stop-color:#00fffc;stop-opacity:1"
             id="stop34997" />
        </meshpatch>
        <meshpatch
           id="meshpatch34999">
          <stop
             path="c 0.0183614,0.148008  0.0458457,0.933638  0.0522407,1.33858"
             id="stop35001" />
          <stop
             path="c -0.890122,-0.0262041  -1.29058,-0.0157581  -1.81947,-0.386463"
             style="stop-color:#ff0500;stop-opacity:1"
             id="stop35003" />
        </meshpatch>
      </meshrow>
      <meshrow
         id="meshrow35005">
        <meshpatch
           id="meshpatch35007">
          <stop
             path="c 0.0013424,0.727146  -0.02264,1.51795  0.0297133,2.1142"
             id="stop35009" />
          <stop
             path="c -0.652886,-2.05581e-05  -1.01475,-0.158903  -1.46709,-0.59942"
             style="stop-color:#7800ff;stop-opacity:1"
             id="stop35011" />
          <stop
             path="c -0.216952,-0.274451  -0.389317,-0.398178  -0.519763,-1.00332"
             style="stop-color:#0014ff;stop-opacity:1"
             id="stop35013" />
        </meshpatch>
        <meshpatch
           id="meshpatch35015">
          <stop
             path="c 5.51197e-05,0.694533  -0.0224765,1.05335  -0.0166527,1.70933"
             id="stop35017" />
          <stop
             path="c -0.360674,0.0156096  -1.18716,0.00520323  -1.77311,0.018407"
             style="stop-color:#fd00ff;stop-opacity:1"
             id="stop35019" />
        </meshpatch>
      </meshrow>
    </meshgradient>

J’ai dû me tromper de version de fichier. La voilà à nouveau :

gbrevedot_color-alt

Toujours pas…

J’ai essayé en mettant le code du gradient dans <defs>, mais ça ne change rien.

Puisqu’il se passe des choses étranges, voici le fichier inkscape au format texte.

gbrevedot_color.svg
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="512"
   height="512"
   viewBox="-0.72 -0.72 1.44 1.44"
   version="1.1"
   id="svg7"
   sodipodi:docname="gbrevedot_color-alt.svg"
   inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
   inkscape:export-filename="/home/hugo/dev/duniter_website_fr_v2/static/img/gbrevedot_color-alt.png"
   inkscape:export-xdpi="200"
   inkscape:export-ydpi="200">
  <metadata
     id="metadata13">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <defs
     id="defs11">
    <meshgradient
       inkscape:collect="always"
       id="meshgradient8278"
       gradientUnits="userSpaceOnUse"
       x="-1.4970822"
       y="-1.4106324"
       gradientTransform="scale(0.25)">
      <meshrow
         id="meshrow34969">
        <meshpatch
           id="meshpatch34971">
          <stop
             path="c 0.320706,-0.266816  0.229276,-0.209345  0.482798,-0.351051"
             style="stop-color:#00ff42;stop-opacity:1"
             id="stop34973" />
          <stop
             path="c 0.447558,0.587057  0.97062,1.17638  0.97579,1.52358"
             style="stop-color:#7bff00;stop-opacity:1"
             id="stop34975" />
          <stop
             path="c -0.717587,-0.0703532  -1.29524,-0.673569  -1.82237,-0.604321"
             style="stop-color:#a9b523;stop-opacity:1"
             id="stop34977" />
          <stop
             path="c 0.0953168,-0.234107  0.220202,-0.385542  0.363782,-0.568208"
             style="stop-color:#00ffaa;stop-opacity:1"
             id="stop34979" />
        </meshpatch>
        <meshpatch
           id="meshpatch34981">
          <stop
             path="c 0.163025,-0.116365  0.662241,-0.29822  1.27917,-0.234847"
             id="stop34983" />
          <stop
             path="c 0.772818,0.12799  1.15756,0.402113  1.49073,0.947596"
             style="stop-color:#fff800;stop-opacity:1"
             id="stop34985" />
          <stop
             path="c -1.16597,0.197891  -1.24775,0.35063  -1.79411,0.810831"
             style="stop-color:#fd1900;stop-opacity:1"
             id="stop34987" />
        </meshpatch>
      </meshrow>
      <meshrow
         id="meshrow34989">
        <meshpatch
           id="meshpatch34991">
          <stop
             path="c 0.0171811,0.0675846  -0.00464089,0.0731624  0.0268794,0.141286"
             id="stop34993" />
          <stop
             path="c -0.754019,0.111294  -1.12951,-0.0444738  -1.95714,0.511458"
             style="stop-color:#cd7d3f;stop-opacity:1"
             id="stop34995" />
          <stop
             path="c -0.136209,-0.676474  0.033825,-1.07498  0.107891,-1.25706"
             style="stop-color:#00fffc;stop-opacity:1"
             id="stop34997" />
        </meshpatch>
        <meshpatch
           id="meshpatch34999">
          <stop
             path="c 0.0183614,0.148008  0.0458457,0.933638  0.0522407,1.33858"
             id="stop35001" />
          <stop
             path="c -0.890122,-0.0262041  -1.29058,-0.0157581  -1.81947,-0.386463"
             style="stop-color:#ff0500;stop-opacity:1"
             id="stop35003" />
        </meshpatch>
      </meshrow>
      <meshrow
         id="meshrow35005">
        <meshpatch
           id="meshpatch35007">
          <stop
             path="c 0.0013424,0.727146  -0.02264,1.51795  0.0297133,2.1142"
             id="stop35009" />
          <stop
             path="c -0.652886,-2.05581e-05  -1.01475,-0.158903  -1.46709,-0.59942"
             style="stop-color:#7800ff;stop-opacity:1"
             id="stop35011" />
          <stop
             path="c -0.216952,-0.274451  -0.389317,-0.398178  -0.519763,-1.00332"
             style="stop-color:#0014ff;stop-opacity:1"
             id="stop35013" />
        </meshpatch>
        <meshpatch
           id="meshpatch35015">
          <stop
             path="c 5.51197e-05,0.694533  -0.0224765,1.05335  -0.0166527,1.70933"
             id="stop35017" />
          <stop
             path="c -0.360674,0.0156096  -1.18716,0.00520323  -1.77311,0.018407"
             style="stop-color:#fd00ff;stop-opacity:1"
             id="stop35019" />
        </meshpatch>
      </meshrow>
    </meshgradient>
  </defs>
  <sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="1920"
     inkscape:window-height="1007"
     id="namedview9"
     showgrid="false"
     inkscape:zoom="1.0399442"
     inkscape:cx="154.73078"
     inkscape:cy="263.8217"
     inkscape:window-x="0"
     inkscape:window-y="0"
     inkscape:window-maximized="1"
     inkscape:current-layer="svg7"
     inkscape:document-rotation="0" />
  <path
     id="g"
     d="M 0.176775,0.176775 A 0.25,0.25 0 1 1 0.2165,-0.125 L 0.433025,-0.25 A 0.5,0.5 0 1 0 0.35355,0.35355 l 0.0884,0.0884 V 0.0884 H 0.0884 Z"
     fill="#000"
     style="fill:url(#meshgradient8278);fill-opacity:1;stroke-width:0.25" />
  <path
     id="breve"
     d="m -0.09916917,-0.70930232 -0.09916917,0.0760952 a 0.25000001,0.25000001 0 0 0 0.39667658,7.69e-6 l -0.09917292,-0.076104 a 0.125,0.125 0 0 1 -0.19833449,1.11e-6 z"
     fill="#000"
     style="fill:#ffe600;fill-opacity:1;stroke-width:0.125" />
  <circle
     cx="0"
     cy="0.625"
     r="0.088399999"
     fill="#000"
     id="circle4"
     style="fill:#6300ff;fill-opacity:1;stroke-width:0.25" />
  <script
     id="mesh_polyfill"
     type="text/javascript">
!function(){const t=&quot;http://www.w3.org/2000/svg&quot;,e=&quot;http://www.w3.org/1999/xlink&quot;,s=&quot;http://www.w3.org/1999/xhtml&quot;,r=2;if(document.createElementNS(t,&quot;meshgradient&quot;).x)return;const n=(t,e,s,r)=&gt;{let n=new x(.5*(e.x+s.x),.5*(e.y+s.y)),o=new x(.5*(t.x+e.x),.5*(t.y+e.y)),i=new x(.5*(s.x+r.x),.5*(s.y+r.y)),a=new x(.5*(n.x+o.x),.5*(n.y+o.y)),h=new x(.5*(n.x+i.x),.5*(n.y+i.y)),l=new x(.5*(a.x+h.x),.5*(a.y+h.y));return[[t,o,a,l],[l,h,i,r]]},o=t=&gt;{let e=t[0].distSquared(t[1]),s=t[2].distSquared(t[3]),r=.25*t[0].distSquared(t[2]),n=.25*t[1].distSquared(t[3]),o=e&gt;s?e:s,i=r&gt;n?r:n;return 18*(o&gt;i?o:i)},i=(t,e)=&gt;Math.sqrt(t.distSquared(e)),a=(t,e)=&gt;t.scale(2/3).add(e.scale(1/3)),h=t=&gt;{let e,s,r,n,o,i,a,h=new g;return t.match(/(\w+\(\s*[^)]+\))+/g).forEach(t=&gt;{let l=t.match(/[\w.-]+/g),d=l.shift();switch(d){case&quot;translate&quot;:2===l.length?e=new g(1,0,0,1,l[0],l[1]):(console.error(&quot;mesh.js: translate does not have 2 arguments!&quot;),e=new g(1,0,0,1,0,0)),h=h.append(e);break;case&quot;scale&quot;:1===l.length?s=new g(l[0],0,0,l[0],0,0):2===l.length?s=new g(l[0],0,0,l[1],0,0):(console.error(&quot;mesh.js: scale does not have 1 or 2 arguments!&quot;),s=new g(1,0,0,1,0,0)),h=h.append(s);break;case&quot;rotate&quot;:if(3===l.length&amp;&amp;(e=new g(1,0,0,1,l[1],l[2]),h=h.append(e)),l[0]){r=l[0]*Math.PI/180;let t=Math.cos(r),e=Math.sin(r);Math.abs(t)&lt;1e-16&amp;&amp;(t=0),Math.abs(e)&lt;1e-16&amp;&amp;(e=0),a=new g(t,e,-e,t,0,0),h=h.append(a)}else console.error(&quot;math.js: No argument to rotate transform!&quot;);3===l.length&amp;&amp;(e=new g(1,0,0,1,-l[1],-l[2]),h=h.append(e));break;case&quot;skewX&quot;:l[0]?(r=l[0]*Math.PI/180,n=Math.tan(r),o=new g(1,0,n,1,0,0),h=h.append(o)):console.error(&quot;math.js: No argument to skewX transform!&quot;);break;case&quot;skewY&quot;:l[0]?(r=l[0]*Math.PI/180,n=Math.tan(r),i=new g(1,n,0,1,0,0),h=h.append(i)):console.error(&quot;math.js: No argument to skewY transform!&quot;);break;case&quot;matrix&quot;:6===l.length?h=h.append(new g(...l)):console.error(&quot;math.js: Incorrect number of arguments for matrix!&quot;);break;default:console.error(&quot;mesh.js: Unhandled transform type: &quot;+d)}}),h},l=t=&gt;{let e=[],s=t.split(/[ ,]+/);for(let t=0,r=s.length-1;t&lt;r;t+=2)e.push(new x(parseFloat(s[t]),parseFloat(s[t+1])));return e},d=(t,e)=&gt;{for(let s in e)t.setAttribute(s,e[s])},c=(t,e,s,r,n)=&gt;{let o,i,a=[0,0,0,0];for(let h=0;h&lt;3;++h)e[h]&lt;t[h]&amp;&amp;e[h]&lt;s[h]||t[h]&lt;e[h]&amp;&amp;s[h]&lt;e[h]?a[h]=0:(a[h]=.5*((e[h]-t[h])/r+(s[h]-e[h])/n),o=Math.abs(3*(e[h]-t[h])/r),i=Math.abs(3*(s[h]-e[h])/n),a[h]&gt;o?a[h]=o:a[h]&gt;i&amp;&amp;(a[h]=i));return a},u=[[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],[-3,3,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0],[2,-2,0,0,1,1,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0],[0,0,0,0,0,0,0,0,-3,3,0,0,-2,-1,0,0],[0,0,0,0,0,0,0,0,2,-2,0,0,1,1,0,0],[-3,0,3,0,0,0,0,0,-2,0,-1,0,0,0,0,0],[0,0,0,0,-3,0,3,0,0,0,0,0,-2,0,-1,0],[9,-9,-9,9,6,3,-6,-3,6,-6,3,-3,4,2,2,1],[-6,6,6,-6,-3,-3,3,3,-4,4,-2,2,-2,-2,-1,-1],[2,0,-2,0,0,0,0,0,1,0,1,0,0,0,0,0],[0,0,0,0,2,0,-2,0,0,0,0,0,1,0,1,0],[-6,6,6,-6,-4,-2,4,2,-3,3,-3,3,-2,-1,-2,-1],[4,-4,-4,4,2,2,-2,-2,2,-2,2,-2,1,1,1,1]],f=t=&gt;{let e=[];for(let s=0;s&lt;16;++s){e[s]=0;for(let r=0;r&lt;16;++r)e[s]+=u[s][r]*t[r]}return e},p=(t,e,s)=&gt;{const r=e*e,n=s*s,o=e*e*e,i=s*s*s;return t[0]+t[1]*e+t[2]*r+t[3]*o+t[4]*s+t[5]*s*e+t[6]*s*r+t[7]*s*o+t[8]*n+t[9]*n*e+t[10]*n*r+t[11]*n*o+t[12]*i+t[13]*i*e+t[14]*i*r+t[15]*i*o},y=t=&gt;{let e=[],s=[],r=[];for(let s=0;s&lt;4;++s)e[s]=[],e[s][0]=n(t[0][s],t[1][s],t[2][s],t[3][s]),e[s][1]=[],e[s][1].push(...n(...e[s][0][0])),e[s][1].push(...n(...e[s][0][1])),e[s][2]=[],e[s][2].push(...n(...e[s][1][0])),e[s][2].push(...n(...e[s][1][1])),e[s][2].push(...n(...e[s][1][2])),e[s][2].push(...n(...e[s][1][3]));for(let t=0;t&lt;8;++t){s[t]=[];for(let r=0;r&lt;4;++r)s[t][r]=[],s[t][r][0]=n(e[0][2][t][r],e[1][2][t][r],e[2][2][t][r],e[3][2][t][r]),s[t][r][1]=[],s[t][r][1].push(...n(...s[t][r][0][0])),s[t][r][1].push(...n(...s[t][r][0][1])),s[t][r][2]=[],s[t][r][2].push(...n(...s[t][r][1][0])),s[t][r][2].push(...n(...s[t][r][1][1])),s[t][r][2].push(...n(...s[t][r][1][2])),s[t][r][2].push(...n(...s[t][r][1][3]))}for(let t=0;t&lt;8;++t){r[t]=[];for(let e=0;e&lt;8;++e)r[t][e]=[],r[t][e][0]=s[t][0][2][e],r[t][e][1]=s[t][1][2][e],r[t][e][2]=s[t][2][2][e],r[t][e][3]=s[t][3][2][e]}return r};class x{constructor(t,e){this.x=t||0,this.y=e||0}toString(){return`(x=${this.x}, y=${this.y})`}clone(){return new x(this.x,this.y)}add(t){return new x(this.x+t.x,this.y+t.y)}scale(t){return void 0===t.x?new x(this.x*t,this.y*t):new x(this.x*t.x,this.y*t.y)}distSquared(t){let e=this.x-t.x,s=this.y-t.y;return e*e+s*s}transform(t){let e=this.x*t.a+this.y*t.c+t.e,s=this.x*t.b+this.y*t.d+t.f;return new x(e,s)}}class g{constructor(t,e,s,r,n,o){void 0===t?(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0):(this.a=t,this.b=e,this.c=s,this.d=r,this.e=n,this.f=o)}toString(){return`affine: ${this.a} ${this.c} ${this.e} \n       ${this.b} ${this.d} ${this.f}`}append(t){t instanceof g||console.error(&quot;mesh.js: argument to Affine.append is not affine!&quot;);let e=this.a*t.a+this.c*t.b,s=this.b*t.a+this.d*t.b,r=this.a*t.c+this.c*t.d,n=this.b*t.c+this.d*t.d,o=this.a*t.e+this.c*t.f+this.e,i=this.b*t.e+this.d*t.f+this.f;return new g(e,s,r,n,o,i)}}class w{constructor(t,e){this.nodes=t,this.colors=e}paintCurve(t,e){if(o(this.nodes)&gt;r){const s=n(...this.nodes);let r=[[],[]],o=[[],[]];for(let t=0;t&lt;4;++t)r[0][t]=this.colors[0][t],r[1][t]=(this.colors[0][t]+this.colors[1][t])/2,o[0][t]=r[1][t],o[1][t]=this.colors[1][t];let i=new w(s[0],r),a=new w(s[1],o);i.paintCurve(t,e),a.paintCurve(t,e)}else{let s=Math.round(this.nodes[0].x);if(s&gt;=0&amp;&amp;s&lt;e){let r=4*(~~this.nodes[0].y*e+s);t[r]=Math.round(this.colors[0][0]),t[r+1]=Math.round(this.colors[0][1]),t[r+2]=Math.round(this.colors[0][2]),t[r+3]=Math.round(this.colors[0][3])}}}}class m{constructor(t,e){this.nodes=t,this.colors=e}split(){let t=[[],[],[],[]],e=[[],[],[],[]],s=[[[],[]],[[],[]]],r=[[[],[]],[[],[]]];for(let s=0;s&lt;4;++s){const r=n(this.nodes[0][s],this.nodes[1][s],this.nodes[2][s],this.nodes[3][s]);t[0][s]=r[0][0],t[1][s]=r[0][1],t[2][s]=r[0][2],t[3][s]=r[0][3],e[0][s]=r[1][0],e[1][s]=r[1][1],e[2][s]=r[1][2],e[3][s]=r[1][3]}for(let t=0;t&lt;4;++t)s[0][0][t]=this.colors[0][0][t],s[0][1][t]=this.colors[0][1][t],s[1][0][t]=(this.colors[0][0][t]+this.colors[1][0][t])/2,s[1][1][t]=(this.colors[0][1][t]+this.colors[1][1][t])/2,r[0][0][t]=s[1][0][t],r[0][1][t]=s[1][1][t],r[1][0][t]=this.colors[1][0][t],r[1][1][t]=this.colors[1][1][t];return[new m(t,s),new m(e,r)]}paint(t,e){let s,n=!1;for(let t=0;t&lt;4;++t)if((s=o([this.nodes[0][t],this.nodes[1][t],this.nodes[2][t],this.nodes[3][t]]))&gt;r){n=!0;break}if(n){let s=this.split();s[0].paint(t,e),s[1].paint(t,e)}else{new w([...this.nodes[0]],[...this.colors[0]]).paintCurve(t,e)}}}class b{constructor(t){this.readMesh(t),this.type=t.getAttribute(&quot;type&quot;)||&quot;bilinear&quot;}readMesh(t){let e=[[]],s=[[]],r=Number(t.getAttribute(&quot;x&quot;)),n=Number(t.getAttribute(&quot;y&quot;));e[0][0]=new x(r,n);let o=t.children;for(let t=0,r=o.length;t&lt;r;++t){e[3*t+1]=[],e[3*t+2]=[],e[3*t+3]=[],s[t+1]=[];let r=o[t].children;for(let n=0,o=r.length;n&lt;o;++n){let o=r[n].children;for(let r=0,i=o.length;r&lt;i;++r){let i=r;0!==t&amp;&amp;++i;let h,d=o[r].getAttribute(&quot;path&quot;),c=&quot;l&quot;;null!=d&amp;&amp;(c=(h=d.match(/\s*([lLcC])\s*(.*)/))[1]);let u=l(h[2]);switch(c){case&quot;l&quot;:0===i?(e[3*t][3*n+3]=u[0].add(e[3*t][3*n]),e[3*t][3*n+1]=a(e[3*t][3*n],e[3*t][3*n+3]),e[3*t][3*n+2]=a(e[3*t][3*n+3],e[3*t][3*n])):1===i?(e[3*t+3][3*n+3]=u[0].add(e[3*t][3*n+3]),e[3*t+1][3*n+3]=a(e[3*t][3*n+3],e[3*t+3][3*n+3]),e[3*t+2][3*n+3]=a(e[3*t+3][3*n+3],e[3*t][3*n+3])):2===i?(0===n&amp;&amp;(e[3*t+3][3*n+0]=u[0].add(e[3*t+3][3*n+3])),e[3*t+3][3*n+1]=a(e[3*t+3][3*n],e[3*t+3][3*n+3]),e[3*t+3][3*n+2]=a(e[3*t+3][3*n+3],e[3*t+3][3*n])):(e[3*t+1][3*n]=a(e[3*t][3*n],e[3*t+3][3*n]),e[3*t+2][3*n]=a(e[3*t+3][3*n],e[3*t][3*n]));break;case&quot;L&quot;:0===i?(e[3*t][3*n+3]=u[0],e[3*t][3*n+1]=a(e[3*t][3*n],e[3*t][3*n+3]),e[3*t][3*n+2]=a(e[3*t][3*n+3],e[3*t][3*n])):1===i?(e[3*t+3][3*n+3]=u[0],e[3*t+1][3*n+3]=a(e[3*t][3*n+3],e[3*t+3][3*n+3]),e[3*t+2][3*n+3]=a(e[3*t+3][3*n+3],e[3*t][3*n+3])):2===i?(0===n&amp;&amp;(e[3*t+3][3*n+0]=u[0]),e[3*t+3][3*n+1]=a(e[3*t+3][3*n],e[3*t+3][3*n+3]),e[3*t+3][3*n+2]=a(e[3*t+3][3*n+3],e[3*t+3][3*n])):(e[3*t+1][3*n]=a(e[3*t][3*n],e[3*t+3][3*n]),e[3*t+2][3*n]=a(e[3*t+3][3*n],e[3*t][3*n]));break;case&quot;c&quot;:0===i?(e[3*t][3*n+1]=u[0].add(e[3*t][3*n]),e[3*t][3*n+2]=u[1].add(e[3*t][3*n]),e[3*t][3*n+3]=u[2].add(e[3*t][3*n])):1===i?(e[3*t+1][3*n+3]=u[0].add(e[3*t][3*n+3]),e[3*t+2][3*n+3]=u[1].add(e[3*t][3*n+3]),e[3*t+3][3*n+3]=u[2].add(e[3*t][3*n+3])):2===i?(e[3*t+3][3*n+2]=u[0].add(e[3*t+3][3*n+3]),e[3*t+3][3*n+1]=u[1].add(e[3*t+3][3*n+3]),0===n&amp;&amp;(e[3*t+3][3*n+0]=u[2].add(e[3*t+3][3*n+3]))):(e[3*t+2][3*n]=u[0].add(e[3*t+3][3*n]),e[3*t+1][3*n]=u[1].add(e[3*t+3][3*n]));break;case&quot;C&quot;:0===i?(e[3*t][3*n+1]=u[0],e[3*t][3*n+2]=u[1],e[3*t][3*n+3]=u[2]):1===i?(e[3*t+1][3*n+3]=u[0],e[3*t+2][3*n+3]=u[1],e[3*t+3][3*n+3]=u[2]):2===i?(e[3*t+3][3*n+2]=u[0],e[3*t+3][3*n+1]=u[1],0===n&amp;&amp;(e[3*t+3][3*n+0]=u[2])):(e[3*t+2][3*n]=u[0],e[3*t+1][3*n]=u[1]);break;default:console.error(&quot;mesh.js: &quot;+c+&quot; invalid path type.&quot;)}if(0===t&amp;&amp;0===n||r&gt;0){let e=window.getComputedStyle(o[r]).stopColor.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i),a=window.getComputedStyle(o[r]).stopOpacity,h=255;a&amp;&amp;(h=Math.floor(255*a)),e&amp;&amp;(0===i?(s[t][n]=[],s[t][n][0]=Math.floor(e[1]),s[t][n][1]=Math.floor(e[2]),s[t][n][2]=Math.floor(e[3]),s[t][n][3]=h):1===i?(s[t][n+1]=[],s[t][n+1][0]=Math.floor(e[1]),s[t][n+1][1]=Math.floor(e[2]),s[t][n+1][2]=Math.floor(e[3]),s[t][n+1][3]=h):2===i?(s[t+1][n+1]=[],s[t+1][n+1][0]=Math.floor(e[1]),s[t+1][n+1][1]=Math.floor(e[2]),s[t+1][n+1][2]=Math.floor(e[3]),s[t+1][n+1][3]=h):3===i&amp;&amp;(s[t+1][n]=[],s[t+1][n][0]=Math.floor(e[1]),s[t+1][n][1]=Math.floor(e[2]),s[t+1][n][2]=Math.floor(e[3]),s[t+1][n][3]=h))}}e[3*t+1][3*n+1]=new x,e[3*t+1][3*n+2]=new x,e[3*t+2][3*n+1]=new x,e[3*t+2][3*n+2]=new x,e[3*t+1][3*n+1].x=(-4*e[3*t][3*n].x+6*(e[3*t][3*n+1].x+e[3*t+1][3*n].x)+-2*(e[3*t][3*n+3].x+e[3*t+3][3*n].x)+3*(e[3*t+3][3*n+1].x+e[3*t+1][3*n+3].x)+-1*e[3*t+3][3*n+3].x)/9,e[3*t+1][3*n+2].x=(-4*e[3*t][3*n+3].x+6*(e[3*t][3*n+2].x+e[3*t+1][3*n+3].x)+-2*(e[3*t][3*n].x+e[3*t+3][3*n+3].x)+3*(e[3*t+3][3*n+2].x+e[3*t+1][3*n].x)+-1*e[3*t+3][3*n].x)/9,e[3*t+2][3*n+1].x=(-4*e[3*t+3][3*n].x+6*(e[3*t+3][3*n+1].x+e[3*t+2][3*n].x)+-2*(e[3*t+3][3*n+3].x+e[3*t][3*n].x)+3*(e[3*t][3*n+1].x+e[3*t+2][3*n+3].x)+-1*e[3*t][3*n+3].x)/9,e[3*t+2][3*n+2].x=(-4*e[3*t+3][3*n+3].x+6*(e[3*t+3][3*n+2].x+e[3*t+2][3*n+3].x)+-2*(e[3*t+3][3*n].x+e[3*t][3*n+3].x)+3*(e[3*t][3*n+2].x+e[3*t+2][3*n].x)+-1*e[3*t][3*n].x)/9,e[3*t+1][3*n+1].y=(-4*e[3*t][3*n].y+6*(e[3*t][3*n+1].y+e[3*t+1][3*n].y)+-2*(e[3*t][3*n+3].y+e[3*t+3][3*n].y)+3*(e[3*t+3][3*n+1].y+e[3*t+1][3*n+3].y)+-1*e[3*t+3][3*n+3].y)/9,e[3*t+1][3*n+2].y=(-4*e[3*t][3*n+3].y+6*(e[3*t][3*n+2].y+e[3*t+1][3*n+3].y)+-2*(e[3*t][3*n].y+e[3*t+3][3*n+3].y)+3*(e[3*t+3][3*n+2].y+e[3*t+1][3*n].y)+-1*e[3*t+3][3*n].y)/9,e[3*t+2][3*n+1].y=(-4*e[3*t+3][3*n].y+6*(e[3*t+3][3*n+1].y+e[3*t+2][3*n].y)+-2*(e[3*t+3][3*n+3].y+e[3*t][3*n].y)+3*(e[3*t][3*n+1].y+e[3*t+2][3*n+3].y)+-1*e[3*t][3*n+3].y)/9,e[3*t+2][3*n+2].y=(-4*e[3*t+3][3*n+3].y+6*(e[3*t+3][3*n+2].y+e[3*t+2][3*n+3].y)+-2*(e[3*t+3][3*n].y+e[3*t][3*n+3].y)+3*(e[3*t][3*n+2].y+e[3*t+2][3*n].y)+-1*e[3*t][3*n].y)/9}}this.nodes=e,this.colors=s}paintMesh(t,e){let s=(this.nodes.length-1)/3,r=(this.nodes[0].length-1)/3;if(&quot;bilinear&quot;===this.type||s&lt;2||r&lt;2){let n;for(let o=0;o&lt;s;++o)for(let s=0;s&lt;r;++s){let r=[];for(let t=3*o,e=3*o+4;t&lt;e;++t)r.push(this.nodes[t].slice(3*s,3*s+4));let i=[];i.push(this.colors[o].slice(s,s+2)),i.push(this.colors[o+1].slice(s,s+2)),(n=new m(r,i)).paint(t,e)}}else{let n,o,a,h,l,d,u;const x=s,g=r;s++,r++;let w=new Array(s);for(let t=0;t&lt;s;++t){w[t]=new Array(r);for(let e=0;e&lt;r;++e)w[t][e]=[],w[t][e][0]=this.nodes[3*t][3*e],w[t][e][1]=this.colors[t][e]}for(let t=0;t&lt;s;++t)for(let e=0;e&lt;r;++e)0!==t&amp;&amp;t!==x&amp;&amp;(n=i(w[t-1][e][0],w[t][e][0]),o=i(w[t+1][e][0],w[t][e][0]),w[t][e][2]=c(w[t-1][e][1],w[t][e][1],w[t+1][e][1],n,o)),0!==e&amp;&amp;e!==g&amp;&amp;(n=i(w[t][e-1][0],w[t][e][0]),o=i(w[t][e+1][0],w[t][e][0]),w[t][e][3]=c(w[t][e-1][1],w[t][e][1],w[t][e+1][1],n,o));for(let t=0;t&lt;r;++t){w[0][t][2]=[],w[x][t][2]=[];for(let e=0;e&lt;4;++e)n=i(w[1][t][0],w[0][t][0]),o=i(w[x][t][0],w[x-1][t][0]),w[0][t][2][e]=n&gt;0?2*(w[1][t][1][e]-w[0][t][1][e])/n-w[1][t][2][e]:0,w[x][t][2][e]=o&gt;0?2*(w[x][t][1][e]-w[x-1][t][1][e])/o-w[x-1][t][2][e]:0}for(let t=0;t&lt;s;++t){w[t][0][3]=[],w[t][g][3]=[];for(let e=0;e&lt;4;++e)n=i(w[t][1][0],w[t][0][0]),o=i(w[t][g][0],w[t][g-1][0]),w[t][0][3][e]=n&gt;0?2*(w[t][1][1][e]-w[t][0][1][e])/n-w[t][1][3][e]:0,w[t][g][3][e]=o&gt;0?2*(w[t][g][1][e]-w[t][g-1][1][e])/o-w[t][g-1][3][e]:0}for(let s=0;s&lt;x;++s)for(let r=0;r&lt;g;++r){let n=i(w[s][r][0],w[s+1][r][0]),o=i(w[s][r+1][0],w[s+1][r+1][0]),c=i(w[s][r][0],w[s][r+1][0]),x=i(w[s+1][r][0],w[s+1][r+1][0]),g=[[],[],[],[]];for(let t=0;t&lt;4;++t){(d=[])[0]=w[s][r][1][t],d[1]=w[s+1][r][1][t],d[2]=w[s][r+1][1][t],d[3]=w[s+1][r+1][1][t],d[4]=w[s][r][2][t]*n,d[5]=w[s+1][r][2][t]*n,d[6]=w[s][r+1][2][t]*o,d[7]=w[s+1][r+1][2][t]*o,d[8]=w[s][r][3][t]*c,d[9]=w[s+1][r][3][t]*x,d[10]=w[s][r+1][3][t]*c,d[11]=w[s+1][r+1][3][t]*x,d[12]=0,d[13]=0,d[14]=0,d[15]=0,u=f(d);for(let e=0;e&lt;9;++e){g[t][e]=[];for(let s=0;s&lt;9;++s)g[t][e][s]=p(u,e/8,s/8),g[t][e][s]&gt;255?g[t][e][s]=255:g[t][e][s]&lt;0&amp;&amp;(g[t][e][s]=0)}}h=[];for(let t=3*s,e=3*s+4;t&lt;e;++t)h.push(this.nodes[t].slice(3*r,3*r+4));l=y(h);for(let s=0;s&lt;8;++s)for(let r=0;r&lt;8;++r)(a=new m(l[s][r],[[[g[0][s][r],g[1][s][r],g[2][s][r],g[3][s][r]],[g[0][s][r+1],g[1][s][r+1],g[2][s][r+1],g[3][s][r+1]]],[[g[0][s+1][r],g[1][s+1][r],g[2][s+1][r],g[3][s+1][r]],[g[0][s+1][r+1],g[1][s+1][r+1],g[2][s+1][r+1],g[3][s+1][r+1]]]])).paint(t,e)}}}transform(t){if(t instanceof x)for(let e=0,s=this.nodes.length;e&lt;s;++e)for(let s=0,r=this.nodes[0].length;s&lt;r;++s)this.nodes[e][s]=this.nodes[e][s].add(t);else if(t instanceof g)for(let e=0,s=this.nodes.length;e&lt;s;++e)for(let s=0,r=this.nodes[0].length;s&lt;r;++s)this.nodes[e][s]=this.nodes[e][s].transform(t)}scale(t){for(let e=0,s=this.nodes.length;e&lt;s;++e)for(let s=0,r=this.nodes[0].length;s&lt;r;++s)this.nodes[e][s]=this.nodes[e][s].scale(t)}}document.querySelectorAll(&quot;rect,circle,ellipse,path,text&quot;).forEach((r,n)=&gt;{let o=r.getAttribute(&quot;id&quot;);o||(o=&quot;patchjs_shape&quot;+n,r.setAttribute(&quot;id&quot;,o));const i=r.style.fill.match(/^url\(\s*&quot;?\s*#([^\s&quot;]+)&quot;?\s*\)/),a=r.style.stroke.match(/^url\(\s*&quot;?\s*#([^\s&quot;]+)&quot;?\s*\)/);if(i&amp;&amp;i[1]){const a=document.getElementById(i[1]);if(a&amp;&amp;&quot;meshgradient&quot;===a.nodeName){const i=r.getBBox();let l=document.createElementNS(s,&quot;canvas&quot;);d(l,{width:i.width,height:i.height});const c=l.getContext(&quot;2d&quot;);let u=c.createImageData(i.width,i.height);const f=new b(a);&quot;objectBoundingBox&quot;===a.getAttribute(&quot;gradientUnits&quot;)&amp;&amp;f.scale(new x(i.width,i.height));const p=a.getAttribute(&quot;gradientTransform&quot;);null!=p&amp;&amp;f.transform(h(p)),&quot;userSpaceOnUse&quot;===a.getAttribute(&quot;gradientUnits&quot;)&amp;&amp;f.transform(new x(-i.x,-i.y)),f.paintMesh(u.data,l.width),c.putImageData(u,0,0);const y=document.createElementNS(t,&quot;image&quot;);d(y,{width:i.width,height:i.height,x:i.x,y:i.y});let g=l.toDataURL();y.setAttributeNS(e,&quot;xlink:href&quot;,g),r.parentNode.insertBefore(y,r),r.style.fill=&quot;none&quot;;const w=document.createElementNS(t,&quot;use&quot;);w.setAttributeNS(e,&quot;xlink:href&quot;,&quot;#&quot;+o);const m=&quot;patchjs_clip&quot;+n,M=document.createElementNS(t,&quot;clipPath&quot;);M.setAttribute(&quot;id&quot;,m),M.appendChild(w),r.parentElement.insertBefore(M,r),y.setAttribute(&quot;clip-path&quot;,&quot;url(#&quot;+m+&quot;)&quot;),u=null,l=null,g=null}}if(a&amp;&amp;a[1]){const o=document.getElementById(a[1]);if(o&amp;&amp;&quot;meshgradient&quot;===o.nodeName){const i=parseFloat(r.style.strokeWidth.slice(0,-2))*(parseFloat(r.style.strokeMiterlimit)||parseFloat(r.getAttribute(&quot;stroke-miterlimit&quot;))||1),a=r.getBBox(),l=Math.trunc(a.width+i),c=Math.trunc(a.height+i),u=Math.trunc(a.x-i/2),f=Math.trunc(a.y-i/2);let p=document.createElementNS(s,&quot;canvas&quot;);d(p,{width:l,height:c});const y=p.getContext(&quot;2d&quot;);let g=y.createImageData(l,c);const w=new b(o);&quot;objectBoundingBox&quot;===o.getAttribute(&quot;gradientUnits&quot;)&amp;&amp;w.scale(new x(l,c));const m=o.getAttribute(&quot;gradientTransform&quot;);null!=m&amp;&amp;w.transform(h(m)),&quot;userSpaceOnUse&quot;===o.getAttribute(&quot;gradientUnits&quot;)&amp;&amp;w.transform(new x(-u,-f)),w.paintMesh(g.data,p.width),y.putImageData(g,0,0);const M=document.createElementNS(t,&quot;image&quot;);d(M,{width:l,height:c,x:0,y:0});let S=p.toDataURL();M.setAttributeNS(e,&quot;xlink:href&quot;,S);const k=&quot;pattern_clip&quot;+n,A=document.createElementNS(t,&quot;pattern&quot;);d(A,{id:k,patternUnits:&quot;userSpaceOnUse&quot;,width:l,height:c,x:u,y:f}),A.appendChild(M),o.parentNode.appendChild(A),r.style.stroke=&quot;url(#&quot;+k+&quot;)&quot;,g=null,p=null,S=null}}})}();
</script>
</svg>