Browse Source

add 3dlut article

Gregg Tavares 6 years ago
parent
commit
29e5a279bc
57 changed files with 7994 additions and 1 deletions
  1. 85 0
      threejs/3dlut-base-cube-maker.html
  2. 774 0
      threejs/lessons/resources/images/3dlut-amber-lookup.svg
  3. 665 0
      threejs/lessons/resources/images/3dlut-amber.svg
  4. 664 0
      threejs/lessons/resources/images/3dlut-axis.svg
  5. 664 0
      threejs/lessons/resources/images/3dlut-edges.svg
  6. BIN
      threejs/lessons/resources/images/3dlut-photoshop-after.jpg
  7. BIN
      threejs/lessons/resources/images/3dlut-photoshop-before.jpg
  8. 694 0
      threejs/lessons/resources/images/3dlut-rgb.svg
  9. BIN
      threejs/lessons/resources/images/3dlut-screen-capture.jpg
  10. 40 0
      threejs/lessons/resources/images/3dlut-standard-2x2.svg
  11. 733 0
      threejs/lessons/resources/images/3dlut-standard-lookup.svg
  12. 664 0
      threejs/lessons/resources/images/3dlut-standard.svg
  13. BIN
      threejs/lessons/resources/images/identity-lut-s16.png
  14. BIN
      threejs/lessons/resources/images/unfiltered-3dlut.jpg
  15. 2 1
      threejs/lessons/resources/lesson.css
  16. 109 0
      threejs/lessons/resources/threejs-post-processing-3dlut.js
  17. 491 0
      threejs/lessons/threejs-post-processing-3dlut.md
  18. 1 0
      threejs/lessons/toc.html
  19. 98 0
      threejs/resources/drag-and-drop.js
  20. BIN
      threejs/resources/images/beach.jpg
  21. BIN
      threejs/resources/images/lut/3dlut-red-only-s16.png
  22. BIN
      threejs/resources/images/lut/bgy-s8.png
  23. BIN
      threejs/resources/images/lut/black-white-s8n.png
  24. BIN
      threejs/resources/images/lut/blues-s8.png
  25. BIN
      threejs/resources/images/lut/color-negative-s8.png
  26. BIN
      threejs/resources/images/lut/default-s8.png
  27. BIN
      threejs/resources/images/lut/funky-contrast-s8.png
  28. BIN
      threejs/resources/images/lut/googley-s8.png
  29. BIN
      threejs/resources/images/lut/high-contrast-bw-s8.png
  30. BIN
      threejs/resources/images/lut/hue-minus-60-s8.png
  31. BIN
      threejs/resources/images/lut/hue-plus-180-s8.png
  32. BIN
      threejs/resources/images/lut/hue-plus-60-s8.png
  33. BIN
      threejs/resources/images/lut/infrared-s8.png
  34. BIN
      threejs/resources/images/lut/inverse-s8.png
  35. BIN
      threejs/resources/images/lut/monochrome-s8.png
  36. BIN
      threejs/resources/images/lut/nightvision-s8.png
  37. BIN
      threejs/resources/images/lut/posterize-3-lab-s8n.png
  38. BIN
      threejs/resources/images/lut/posterize-3-rgb-s8n.png
  39. BIN
      threejs/resources/images/lut/posterize-4-lab-s8n.png
  40. BIN
      threejs/resources/images/lut/posterize-more-s8n.png
  41. BIN
      threejs/resources/images/lut/posterize-s8n.png
  42. BIN
      threejs/resources/images/lut/radioactive-s8.png
  43. BIN
      threejs/resources/images/lut/red-to-cyan-s8.png
  44. BIN
      threejs/resources/images/lut/saturated-s8.png
  45. BIN
      threejs/resources/images/lut/sepia-s8.png
  46. BIN
      threejs/resources/images/lut/thermal-s8.png
  47. 155 0
      threejs/resources/lut-reader.js
  48. 8 0
      threejs/resources/models/3dbustchallange_submission/license.md
  49. BIN
      threejs/resources/models/3dbustchallange_submission/scene.bin
  50. 652 0
      threejs/resources/models/3dbustchallange_submission/scene.gltf
  51. BIN
      threejs/resources/models/3dbustchallange_submission/textures/lambert1_baseColor-orig.png
  52. BIN
      threejs/resources/models/3dbustchallange_submission/textures/lambert1_baseColor.png
  53. 305 0
      threejs/threejs-postprocessing-3dlut-identity.html
  54. 154 0
      threejs/threejs-postprocessing-3dlut-prep.html
  55. 421 0
      threejs/threejs-postprocessing-3dlut-w-loader.html
  56. 377 0
      threejs/threejs-postprocessing-3dlut.html
  57. 238 0
      threejs/threejs-postprocessing-adobe-lut-to-png-converter.html

+ 85 - 0
threejs/3dlut-base-cube-maker.html

@@ -0,0 +1,85 @@
+<!doctype html>
+<html>
+<meta charset="utf-8">
+<head>
+<title>3DLUT Base Cube Maker</title>
+<style>
+canvas {
+  min-width: 512px;
+  min-height: 32px;
+  image-rendering: pixelated;
+}
+</style>
+</head>
+<body>
+<h1>Color Cube Image Maker</h1>
+<div>size:<input id="size" type="number" value="8" min="2" max="64"/></div>
+<p><button type="button">Save...</button></p>
+<p><canvas></canvas></br>
+<div>( note: actual image size is
+<span id="width"></span>x<span id="height"></span> )</div>
+</p>
+</body>
+<script>
+'use strict';
+
+const ctx = document.querySelector('canvas').getContext('2d');
+
+function drawColorCubeImage(ctx, size) {
+  const canvas = ctx.canvas;
+  canvas.width = size * size;
+  canvas.height = size;
+
+  for (let zz = 0; zz < size; ++zz) {
+    for (let yy = 0; yy < size; ++yy) {
+      for (let xx = 0; xx < size; ++xx) {
+        const r = Math.floor(xx / (size - 1) * 255);
+        const g = Math.floor(yy / (size - 1) * 255);
+        const b = Math.floor(zz / (size - 1) * 255);
+        ctx.fillStyle = `rgb(${r},${g},${b})`;
+        ctx.fillRect(zz * size + xx, yy, 1, 1);
+      }
+    }
+  }
+  document.querySelector('#width').textContent = canvas.width;
+  document.querySelector('#height').textContent = canvas.height;
+}
+
+drawColorCubeImage(ctx, 8);
+
+function handleSizeChange(event) {
+  const elem = event.target;
+  elem.style.background = '';
+  try {
+    const size = parseInt(elem.value);
+    if (size >= 2 && size <= 64) {
+      drawColorCubeImage(ctx, size);
+    }
+  } catch (e) {
+    elem.style.background = 'red';
+  }
+}
+
+const sizeElem = document.querySelector('#size');
+sizeElem.addEventListener('change', handleSizeChange, true);
+
+const saveData = (function() {
+  const a = document.createElement('a');
+  document.body.appendChild(a);
+  a.style.display = 'none';
+  return function saveData(blob, fileName) {
+    const url = window.URL.createObjectURL(blob);
+    a.href = url;
+    a.download = fileName;
+    a.click();
+  };
+}());
+
+document.querySelector('button').addEventListener('click', () => {
+  ctx.canvas.toBlob((blob) => {
+    saveData(blob, `identity-lut-s${ctx.canvas.height}.png`);
+  });
+});
+
+</script>
+</html>

+ 774 - 0
threejs/lessons/resources/images/3dlut-amber-lookup.svg

@@ -0,0 +1,774 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 900 400" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
+    <g id="Input">
+        <g transform="matrix(1,0,0,1,9.47928,-6.33325)">
+            <rect x="33.377" y="171.057" width="178.1" height="113.999" style="fill:rgb(144,244,255);"/>
+        </g>
+        <g transform="matrix(1,0,0,1,9.47928,-6.33325)">
+            <rect x="33.377" y="171.057" width="178.1" height="113.999" style="fill:rgb(144,244,255);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,0.734872,0,179.303)">
+            <rect x="42.856" y="92.197" width="178.1" height="43.091" style="fill:rgb(145,109,0);"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-5.03489,-2.01823)">
+            <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(0,117,5);"/>
+        </g>
+        <g transform="matrix(0.940057,0,0,0.940057,3.17374,-1.88307)">
+            <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(0,117,5);"/>
+        </g>
+        <g transform="matrix(0.850143,0,0,0.850143,15.7252,5.07521)">
+            <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(0,117,5);"/>
+        </g>
+        <g transform="matrix(1,0,0,1,2.28684,-3.71511)">
+            <path d="M80.357,174.727L83.592,184.684L89.827,181.607L88.827,188.488L99.297,188.488L90.827,194.642L95.68,199.62L88.827,200.796L92.062,210.753L83.592,204.599L80.357,210.753L77.122,204.599L68.651,210.753L71.887,200.796L65.034,199.62L69.887,194.642L61.417,188.488L71.887,188.488L70.887,181.607L77.122,184.684L80.357,174.727Z" style="fill:rgb(255,251,18);"/>
+        </g>
+        <g transform="matrix(1.14154,0,0,1,-23.4531,0)">
+            <rect x="131.906" y="236.407" width="8.38" height="10.648" style="fill:rgb(82,75,0);"/>
+        </g>
+    </g>
+    <g id="Result" transform="matrix(1,0,0,1,642.707,0)">
+        <g id="Arrow06-Result">
+            <g>
+                <g transform="matrix(1,0,0,1,9.47928,-6.33325)">
+                    <rect x="33.377" y="171.057" width="178.1" height="113.999" style="fill:rgb(144,244,255);"/>
+                </g>
+                <g transform="matrix(1,0,0,1,9.47928,-6.33325)">
+                    <rect x="33.377" y="171.057" width="178.1" height="113.999" style="fill:rgb(144,244,255);stroke:black;stroke-width:1px;"/>
+                </g>
+            </g>
+            <g id="Effect06-Hue">
+                <g>
+                    <g transform="matrix(1,0,0,1,9.47928,-6.33325)">
+                        <rect x="33.377" y="171.057" width="178.1" height="113.999" style="fill:rgb(251,121,0);"/>
+                    </g>
+                    <g transform="matrix(1,0,0,1,9.47928,-6.33325)">
+                        <rect x="33.377" y="171.057" width="178.1" height="113.999" style="fill:rgb(251,121,0);stroke:black;stroke-width:1px;"/>
+                    </g>
+                </g>
+            </g>
+        </g>
+        <g id="Arrow04-Result">
+            <g transform="matrix(1,0,0,0.734872,0,179.303)">
+                <rect x="42.856" y="92.197" width="178.1" height="43.091" style="fill:rgb(145,109,0);"/>
+            </g>
+            <g id="Effect04-Hue" transform="matrix(1,0,0,0.734872,0,179.303)">
+                <rect x="42.856" y="92.197" width="178.1" height="43.091" style="fill:rgb(251,121,0);"/>
+            </g>
+        </g>
+        <g id="Arrow01-Result">
+            <g>
+                <g transform="matrix(1,0,0,1,-5.03489,-2.01823)">
+                    <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(0,117,5);"/>
+                </g>
+                <g transform="matrix(0.940057,0,0,0.940057,3.17374,-1.88307)">
+                    <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(0,117,5);"/>
+                </g>
+                <g transform="matrix(0.850143,0,0,0.850143,15.7252,5.07521)">
+                    <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(0,117,5);"/>
+                </g>
+            </g>
+            <g id="Effect01-Hue">
+                <g>
+                    <g transform="matrix(1,0,0,1,-5.03489,-2.01823)">
+                        <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(251,121,0);"/>
+                    </g>
+                    <g transform="matrix(0.940057,0,0,0.940057,3.17374,-1.88307)">
+                        <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(251,121,0);"/>
+                    </g>
+                    <g transform="matrix(0.850143,0,0,0.850143,15.7252,5.07521)">
+                        <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(251,121,0);"/>
+                    </g>
+                </g>
+            </g>
+        </g>
+        <g id="Arrow03-Result">
+            <g transform="matrix(1,0,0,1,2.28684,-3.71511)">
+                <path d="M80.357,174.727L83.592,184.684L89.827,181.607L88.827,188.488L99.297,188.488L90.827,194.642L95.68,199.62L88.827,200.796L92.062,210.753L83.592,204.599L80.357,210.753L77.122,204.599L68.651,210.753L71.887,200.796L65.034,199.62L69.887,194.642L61.417,188.488L71.887,188.488L70.887,181.607L77.122,184.684L80.357,174.727Z" style="fill:rgb(255,251,18);"/>
+            </g>
+            <g id="Effect03-Hue" transform="matrix(1,0,0,1,2.28684,-3.71511)">
+                <path d="M80.357,174.727L83.592,184.684L89.827,181.607L88.827,188.488L99.297,188.488L90.827,194.642L95.68,199.62L88.827,200.796L92.062,210.753L83.592,204.599L80.357,210.753L77.122,204.599L68.651,210.753L71.887,200.796L65.034,199.62L69.887,194.642L61.417,188.488L71.887,188.488L70.887,181.607L77.122,184.684L80.357,174.727Z" style="fill:rgb(251,121,0);"/>
+            </g>
+        </g>
+        <g id="Arrow02-Result">
+            <g transform="matrix(1.14154,0,0,1,-23.4531,0)">
+                <rect x="131.906" y="236.407" width="8.38" height="10.648" style="fill:rgb(82,75,0);"/>
+            </g>
+            <g id="Effect02-Hue" transform="matrix(1.14154,0,0,1,-23.4531,0)">
+                <rect x="131.906" y="236.407" width="8.38" height="10.648" style="fill:rgb(251,121,0);"/>
+            </g>
+        </g>
+        <g transform="matrix(1,0,0,1,9.47928,-6.33325)">
+            <g id="Result-Outline">
+                <rect x="33.377" y="171.057" width="178.1" height="113.999" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+        </g>
+    </g>
+    <g id="Back-Arrows">
+        <g id="Arrow06-Output" transform="matrix(0.0599313,-0.987016,0.987016,0.0599313,-53.7464,365.633)">
+            <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                <path d="M133.373,543.235L192.513,758.881" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(-0.960349,0.2788,-0.2788,-0.960349,320.16,918.802)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+            </g>
+        </g>
+        <g id="Arrow06-Input" transform="matrix(0.446757,-0.882157,0.882157,0.446757,-283.977,94.0662)">
+            <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                <path d="M124.812,479.05L192.513,758.881" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(-0.960349,0.2788,-0.2788,-0.960349,320.16,918.802)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+            </g>
+        </g>
+    </g>
+    <g id="_3DLUT" serif:id="3DLUT">
+        <g transform="matrix(1,0,0,1,97.9595,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,97.9595,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,146,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,97.9595,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,73,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,97.9595,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,219,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,97.9595,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,36,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,97.9595,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,182,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,97.9595,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,109,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,97.9595,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,255,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,199.292,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,0,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,199.292,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,145,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,199.292,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,72,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,199.292,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,218,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,199.292,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(142,36,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,199.292,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,182,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,199.292,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,109,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,199.292,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,255,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,148.626,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,0,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,148.626,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(72,145,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,148.626,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,73,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,148.626,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,218,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,148.626,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(72,36,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,148.626,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,182,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,148.626,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(72,109,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,148.626,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,255,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,249.958,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,0,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,249.958,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(219,145,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,249.958,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(219,72,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,249.958,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,218,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,249.958,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(219,36,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,249.958,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,182,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,249.958,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,109,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,249.958,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,255,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,123.293,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,0,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,123.293,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,145,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,123.293,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,72,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,123.293,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,218,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,123.293,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,36,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,123.293,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,182,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,123.293,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,109,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,123.293,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,255,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,224.625,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,0,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,224.625,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,145,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,224.625,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(192,72,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,224.625,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,218,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,224.625,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,36,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,224.625,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,182,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,224.625,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,109,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,224.625,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,255,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,173.959,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,0,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,173.959,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,145,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,173.959,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,72,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,173.959,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,218,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,173.959,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,36,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,173.959,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,182,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,173.959,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,109,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,173.959,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,255,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,275.291,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,0,13);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,275.291,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,145,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,275.291,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,72,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,275.291,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,218,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,275.291,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,36,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,275.291,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,182,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,275.291,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,109,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,275.291,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,255,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,29.8109,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,104.001,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,146);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,66.9062,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,73);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,141.097,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,219);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,48.3585,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,36);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,122.549,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,182);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,85.4538,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,109);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,159.644,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,255);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,131.143,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,0);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,205.333,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,145);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,168.238,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,72);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,242.429,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,218);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,149.691,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,36);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,223.881,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,182);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,186.786,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,109);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,260.976,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,255);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,80.4769,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,0);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,154.667,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,145);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,117.572,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(72,0,72);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,191.763,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,218);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,99.0245,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,36);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,173.215,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,182);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,136.12,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,109);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,210.31,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,255);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,181.809,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,0);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,256,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,145);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,218.904,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,72);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,293.095,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,218);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,200.357,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,36);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,274.547,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,182);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,237.452,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,109);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,311.642,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,255);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,55.1439,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,0);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,129.334,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,145);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,92.2392,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,72);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,166.43,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,218);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,73.6915,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,36);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,147.882,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,182);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,110.787,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,109);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,184.977,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,255);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,156.476,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,0);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,230.666,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,145);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,193.571,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,72);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,267.762,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,218);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,175.024,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,36);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,249.214,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,183);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,212.119,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,109);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,286.309,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,255);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,105.81,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,0);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,180,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,145);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,142.905,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,72);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,217.096,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,218);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,124.358,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,36);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,198.548,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,182);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,161.453,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,109);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,235.643,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,255);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,207.142,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,13,13);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,281.333,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,145);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,244.237,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,72);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,318.428,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,218);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,225.69,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,36);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,299.88,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,182);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,262.785,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,109);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,336.975,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,255);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,348.29,-4.43825)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,0);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,422.282,-51.7595)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,145);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,385.328,-28.0428)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,72);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,459.187,-75.1028)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,218);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,366.809,-16.2902)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,36);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,440.801,-63.5121)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,182);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,403.763,-39.9075)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,109);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,477.707,-87.0314)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,255);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,348.29,96.4328)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,0);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,422.282,49.1116)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,145);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,385.328,72.8283)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,72);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,459.187,25.7683)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,218);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,366.809,84.5809)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,36);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,440.801,37.359)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,182);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,403.763,60.9636)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,109);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,477.707,13.8397)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,255);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,348.29,45.9094)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,72,0);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,422.282,-1.41182)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,142);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,385.328,22.3048)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,72,72);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,459.187,-24.7552)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,218);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,366.809,34.0574)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,72,36);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,440.801,-13.1644)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,182);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,403.763,10.4402)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,109);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,477.707,-36.6837)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,255);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,348.29,146.781)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,0);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,422.282,99.4593)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,142);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,385.328,123.176)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,72);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,459.187,76.1159)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,219,219);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,366.809,134.929)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,36);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,440.801,87.7067)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,182);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,403.763,111.311)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,109);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,477.707,64.1874)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,255);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,348.29,20.6946)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,0);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,422.282,-26.6267)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,142);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,385.328,-2.91002)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,72);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,459.187,-49.97)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,218);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,366.809,8.84258)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,36);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,440.801,-38.3793)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,182);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,403.763,-14.7747)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,109);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,477.707,-61.8986)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,255);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,348.29,121.566)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,0);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,422.282,74.2444)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,142);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,385.328,97.9611)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,72);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,459.187,50.9011)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,218);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,366.809,109.714)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,36);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,440.801,62.4918)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,182);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,403.763,86.0964)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,109);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,477.707,38.9725)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,255);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,348.29,71.0422)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,0);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,422.282,23.721)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,142);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,385.328,47.4376)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,72);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,459.187,0.377653)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,218);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,366.809,59.1902)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,36);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,440.801,11.9684)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,182);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,403.763,35.573)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,109);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,477.707,-11.5509)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,255);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,348.29,171.913)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,0);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,422.282,124.592)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,145);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,385.328,148.309)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,73);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,459.187,101.249)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,218);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,366.809,160.061)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,36);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,440.801,112.839)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,182);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,403.763,136.444)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,109);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,477.707,89.3202)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:white;stroke:black;stroke-width:1.14px;"/>
+        </g>
+    </g>
+    <path id="Effect00-hue" d="M422.752,51.612L274.371,145.724L274.371,348.388L477.638,348.388L625.629,253.297L625.629,51.612L422.752,51.612Z" style="fill:rgb(251,121,0);"/>
+    <g id="Front-Arrows">
+        <g>
+            <g id="Arrow01-Input" transform="matrix(-0.00725653,-0.999974,0.999974,-0.00725653,-129.6,385.888)">
+                <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                    <path d="M156.668,262.889L144.955,402.713" style="fill:none;stroke:black;stroke-width:0.99px;"/>
+                </g>
+                <g transform="matrix(-0.993977,-0.109589,0.109589,-0.993977,204.051,594.659)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                </g>
+            </g>
+            <g id="Arrow01-Output" transform="matrix(0.0870807,-0.984992,0.984992,0.0870807,-57.429,349.296)">
+                <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                    <path d="M141.452,344.114L211.962,814.451" style="fill:none;stroke:black;stroke-width:1px;"/>
+                </g>
+                <g transform="matrix(-0.991923,0.126838,-0.126838,-0.991923,313.621,989.726)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                </g>
+            </g>
+            <g id="Arrow02-Input" transform="matrix(-0.394342,-0.918964,0.918964,-0.394342,-20.7391,483.782)">
+                <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                    <path d="M162.241,236.283L143.059,415.107" style="fill:none;stroke:black;stroke-width:0.99px;"/>
+                </g>
+                <g transform="matrix(-0.993977,-0.109589,0.109589,-0.993977,204.018,599.15)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                </g>
+            </g>
+            <g id="Arrow02-Output" transform="matrix(0.257817,-0.954632,0.954632,0.257817,-51.8064,233.413)">
+                <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                    <path d="M142.892,347.83L207.757,796.402" style="fill:none;stroke:black;stroke-width:1px;"/>
+                </g>
+                <g transform="matrix(-0.991523,0.129928,-0.129928,-0.991523,310.206,970.847)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                </g>
+            </g>
+            <g id="Arrow03-Input" transform="matrix(-0.00725653,-0.999974,0.999974,-0.00725653,-180.334,350.514)">
+                <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                    <path d="M156.668,262.889L39.944,690.63" style="fill:none;stroke:black;stroke-width:0.99px;"/>
+                </g>
+                <g transform="matrix(-0.974209,-0.225649,0.225649,-0.974209,78.8227,890.255)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                </g>
+            </g>
+            <g id="Arrow03-Output" transform="matrix(-0.406151,-0.901573,0.901573,-0.406151,276.05,570.518)">
+                <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                    <path d="M142.034,343.466L164.18,564.489" style="fill:none;stroke:black;stroke-width:1px;"/>
+                </g>
+                <g transform="matrix(-0.991523,0.129928,-0.129928,-0.991523,266.695,733.716)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                </g>
+            </g>
+            <g id="Arrow04-Input" transform="matrix(-0.185534,-0.971272,0.971272,-0.185534,-126.766,464.83)">
+                <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                    <path d="M141.551,340.405L159.904,522.89" style="fill:none;stroke:black;stroke-width:1px;"/>
+                </g>
+                <g transform="matrix(-0.991523,0.129928,-0.129928,-0.991523,262.914,693.466)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                </g>
+            </g>
+            <g id="Arrow04-Output" transform="matrix(0.257817,-0.954632,0.954632,0.257817,1.31472,260.221)">
+                <g>
+                    <g transform="matrix(1,0,0,1.0209,-3.55271e-15,-5.49553)">
+                        <path d="M147.166,344.75L179.991,672.129" style="fill:none;stroke:black;stroke-width:1px;"/>
+                    </g>
+                    <g transform="matrix(-0.991523,0.129928,-0.129928,-0.991523,283.185,845.353)">
+                        <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 665 - 0
threejs/lessons/resources/images/3dlut-amber.svg

@@ -0,0 +1,665 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 500 400" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
+    <g transform="matrix(1,0,0,1,-68.9948,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.9948,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,146,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.9948,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,73,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.9948,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,219,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.9948,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.9948,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.9948,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.9948,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3372,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3372,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3372,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,72,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3372,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3372,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(142,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3372,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3372,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3372,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3288,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3288,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(72,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3288,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,73,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3288,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3288,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(72,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3288,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3288,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(72,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3288,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0033,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0033,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(219,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0033,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(219,72,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0033,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0033,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(219,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0033,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0033,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0033,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6618,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6618,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6618,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,72,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6618,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6618,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6618,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6618,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6618,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6702,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6702,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6702,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(192,72,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6702,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6702,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6702,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6702,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6702,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.00423,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.00423,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.00423,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,72,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.00423,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.00423,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.00423,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.00423,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.00423,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.336,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,0,13);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.336,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.336,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,72,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.336,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.336,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.336,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.336,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.336,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-137.143,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-62.9529,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,146);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-100.048,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,73);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-25.8576,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,219);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-118.596,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-44.4052,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-81.5005,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-7.30994,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-35.8114,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,38.3792,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,1.28388,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,75.4745,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-17.2638,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,56.9268,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,19.8315,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,94.0221,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-86.4774,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-12.2869,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-49.3821,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(72,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,24.8084,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-67.9298,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,6.26079,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-30.8345,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,43.3561,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,14.8546,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,89.0452,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,51.9499,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,126.14,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,33.4023,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,107.593,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,70.4975,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,144.688,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-111.81,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-37.6199,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-74.7152,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-0.524576,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-93.2628,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-19.0722,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-56.1675,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,18.0231,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-10.4784,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,63.7122,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,26.6169,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,100.807,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,8.06924,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,82.2598,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,183);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,45.1645,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,119.355,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-61.1444,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,13.0462,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-24.0491,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,50.1414,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-42.5968,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,31.5938,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-5.50149,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,68.6891,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,40.1876,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,13,13);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,114.378,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,77.2829,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,151.473,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,58.7353,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,132.926,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,95.8306,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,170.021,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.336,-4.43825)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.328,-51.7595)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,145);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.374,-28.0428)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.233,-75.1028)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.855,-16.2902)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.847,-63.5121)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.809,-39.9075)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.752,-87.0314)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.336,96.4328)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.328,49.1116)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,145);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.374,72.8283)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.233,25.7683)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.855,84.5809)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.847,37.359)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.809,60.9636)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.752,13.8397)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.336,45.9094)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,72,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.328,-1.41182)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,142);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.374,22.3048)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,72,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.233,-24.7552)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.855,34.0574)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,72,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.847,-13.1644)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.809,10.4402)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.752,-36.6837)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.336,146.781)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.328,99.4593)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,142);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.374,123.176)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.233,76.1159)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,219,219);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.855,134.929)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.847,87.7067)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.809,111.311)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.752,64.1874)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.336,20.6946)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.328,-26.6267)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,142);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.374,-2.91002)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.233,-49.97)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.855,8.84258)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.847,-38.3793)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.809,-14.7747)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.752,-61.8986)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.336,121.566)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.328,74.2444)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,142);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.374,97.9611)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.233,50.9011)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.855,109.714)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.847,62.4918)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.809,86.0964)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.752,38.9725)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.336,71.0422)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.328,23.721)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,142);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.374,47.4376)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.233,0.377653)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.855,59.1902)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.847,11.9684)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.809,35.573)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.752,-11.5509)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.336,171.913)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.328,124.592)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,145);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.374,148.309)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,73);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.233,101.249)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.855,160.061)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.847,112.839)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.809,136.444)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.752,89.3202)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:white;stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <path d="M458.675,51.612L255.798,51.612L108.019,145.724L108.019,348.388L310.683,348.388L458.675,253.297L458.675,51.612Z" style="fill:rgb(255,218,182); mix-blend-mode: hue;"/>
+    <g id="axes" transform="matrix(1,0,0,1,-0.00640404,-50)">
+        <g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-52.4094,270.607)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(0,-1,1,0,-52.4094,473.361)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(-1,-1.22465e-16,1.22465e-16,-1,151.86,569.465)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(0,255,0);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,-9.01877,24.5561)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(0,255,0);"/>
+            </g>
+            <g transform="matrix(6.21256e-17,-1.01459,1,6.12323e-17,-52.4094,477.765)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(0,255,0);stroke-width:0.99px;"/>
+            </g>
+        </g>
+        <g transform="matrix(0.547017,0.837121,-0.837121,0.547017,240.244,-7.07818)">
+            <g transform="matrix(-1,-1.22465e-16,1.22465e-16,-1,157.286,422.965)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(13,40,242);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,-4.41699,-88.72)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(13,40,242);"/>
+            </g>
+            <g transform="matrix(6.41412e-17,-0.795906,1.01308,1.05301e-16,-49.3679,307.392)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(13,40,242);stroke-width:1.1px;"/>
+            </g>
+            <g transform="matrix(-0.837121,-0.547017,0.547017,-0.837121,67.9116,231.828)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+        </g>
+        <g transform="matrix(1,0,0,1,33.0393,0)">
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+        </g>
+        <g transform="matrix(1,0,0,1,33.0393,0)">
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+            </g>
+        </g>
+        <g transform="matrix(1,0,0,1,33.0393,0)">
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);"/>
+            </g>
+            <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(242,13,13);stroke-width:1px;"/>
+            </g>
+        </g>
+    </g>
+</svg>

+ 664 - 0
threejs/lessons/resources/images/3dlut-axis.svg

@@ -0,0 +1,664 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 500 400" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
+    <g transform="matrix(1,0,0,1,-68.5877,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.5877,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,146,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.5877,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,73,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.5877,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,219,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.5877,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.5877,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.5877,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.5877,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.7444,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.7444,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.7444,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.7444,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.7444,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.7444,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.7444,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.7444,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-17.9217,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-17.9217,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-17.9217,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-17.9217,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-17.9217,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-17.9217,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-17.9217,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-17.9217,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.4104,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.4104,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.4104,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.4104,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.4104,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.4104,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.4104,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.4104,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.2547,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.2547,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.2547,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.2547,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.2547,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.2547,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.2547,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.2547,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,58.0774,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,58.0774,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,58.0774,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,58.0774,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,58.0774,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,58.0774,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,58.0774,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,58.0774,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.41134,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.41134,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.41134,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.41134,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.41134,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.41134,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.41134,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.41134,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.743,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(242,13,13);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.743,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.743,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.743,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.743,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.743,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.743,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.743,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-136.736,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-62.5458,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,146);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-99.6411,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,73);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-25.4505,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,219);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-118.189,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-43.9981,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-81.0934,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-6.90283,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(13,40,242);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-35.4043,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,38.7863,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,1.69099,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,75.8816,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-16.8567,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,57.3339,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,20.2386,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,94.4292,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-86.0703,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-11.8797,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-48.975,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,25.2155,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-67.5227,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,6.6679,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-30.4274,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,43.7632,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,15.2617,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,89.4523,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,52.357,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,126.548,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,33.8094,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,108,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,70.9047,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,145.095,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-111.403,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-37.2128,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-74.308,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-0.117462,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-92.8557,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-18.6651,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-55.7604,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,18.4302,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-10.0713,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,64.1193,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,27.024,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,101.215,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,8.47636,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,82.6669,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,45.5716,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,119.762,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-60.7373,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,13.4533,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-23.642,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,50.5486,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-42.1897,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,32.0009,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-5.09437,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,69.0962,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,40.5947,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(242,13,13);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,114.785,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,77.69,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,151.881,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,59.1424,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,133.333,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,96.2377,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,170.428,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.743,-4.43825)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(242,13,13);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.735,-51.7595)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.781,-28.0428)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.64,-75.1028)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,200.262,-16.2902)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,274.254,-63.5121)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,237.216,-39.9075)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,311.159,-87.0314)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.743,96.4328)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.735,49.1116)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.781,72.8283)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.64,25.7683)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,200.262,84.5809)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,274.254,37.359)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,237.216,60.9636)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,311.159,13.8397)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.743,45.9094)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.735,-1.41182)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.781,22.3048)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.64,-24.7552)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,200.262,34.0574)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,274.254,-13.1644)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,237.216,10.4402)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,311.159,-36.6837)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.743,146.781)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.735,99.4593)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.781,123.176)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.64,76.1159)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,200.262,134.929)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,274.254,87.7067)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,237.216,111.311)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,311.159,64.1874)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.743,20.6946)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.735,-26.6267)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.781,-2.91002)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.64,-49.97)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,200.262,8.84258)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,274.254,-38.3793)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,237.216,-14.7747)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,311.159,-61.8986)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.743,121.566)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.735,74.2444)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.781,97.9611)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.64,50.9011)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,200.262,109.714)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,274.254,62.4918)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,237.216,86.0964)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,311.159,38.9725)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.743,71.0422)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.735,23.721)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.781,47.4376)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.64,0.377653)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,200.262,59.1902)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,274.254,11.9684)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,237.216,35.573)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,311.159,-11.5509)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.743,171.913)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.735,124.592)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.781,148.309)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.64,101.249)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,200.262,160.061)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,274.254,112.839)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,237.216,136.444)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,311.159,89.3202)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:white;stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g id="axes" transform="matrix(1,0,0,1,-0.413519,-50)">
+        <g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-52.4094,270.607)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(0,-1,1,0,-52.4094,473.361)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(-1,-1.22465e-16,1.22465e-16,-1,151.86,569.465)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(0,255,0);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,-9.01877,24.5561)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(0,255,0);"/>
+            </g>
+            <g transform="matrix(6.21256e-17,-1.01459,1,6.12323e-17,-52.4094,477.765)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(0,255,0);stroke-width:0.99px;"/>
+            </g>
+        </g>
+        <g transform="matrix(0.547017,0.837121,-0.837121,0.547017,240.244,-7.07818)">
+            <g transform="matrix(-1,-1.22465e-16,1.22465e-16,-1,157.286,422.965)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(13,40,242);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,-4.41699,-88.72)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(13,40,242);"/>
+            </g>
+            <g transform="matrix(6.41412e-17,-0.795906,1.01308,1.05301e-16,-49.3679,307.392)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(13,40,242);stroke-width:1.1px;"/>
+            </g>
+            <g transform="matrix(-0.837121,-0.547017,0.547017,-0.837121,67.9116,231.828)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+        </g>
+        <g transform="matrix(1,0,0,1,33.0393,0)">
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+        </g>
+        <g transform="matrix(1,0,0,1,33.0393,0)">
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+            </g>
+        </g>
+        <g transform="matrix(1,0,0,1,33.0393,0)">
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);"/>
+            </g>
+            <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(242,13,13);stroke-width:1px;"/>
+            </g>
+        </g>
+    </g>
+</svg>

+ 664 - 0
threejs/lessons/resources/images/3dlut-edges.svg

@@ -0,0 +1,664 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 500 400" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
+    <g transform="matrix(1,0,0,1,-68.9446,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.9446,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,146,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.9446,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,73,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.9446,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,219,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.9446,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.9446,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.9446,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-68.9446,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3875,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3875,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3875,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3875,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3875,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3875,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3875,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3875,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.2786,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.2786,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.2786,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.2786,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.2786,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.2786,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.2786,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.2786,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0535,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0535,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0535,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0535,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0535,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0535,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0535,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,83.0535,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6116,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6116,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6116,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6116,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6116,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6116,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6116,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6116,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.7205,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.7205,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.7205,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.7205,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.7205,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.7205,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.7205,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.7205,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.05444,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.05444,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.05444,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.05444,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.05444,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.05444,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.05444,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(235,235,235);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,7.05444,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.386,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,0,13);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.386,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.386,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,72,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.386,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.386,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.386,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.386,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.386,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-137.093,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-62.9027,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,146);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-99.998,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,73);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-25.8074,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,219);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-118.546,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-44.355,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-81.4503,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-7.25973,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-35.7612,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,38.4294,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,1.33409,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,75.5247,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-17.2136,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,56.977,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,19.8817,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,94.0723,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-86.4272,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-12.2366,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-49.3319,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,24.8586,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-67.8796,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,6.311,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-30.7843,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,43.4063,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,14.9048,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,89.0954,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,52.0001,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,126.191,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,33.4525,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,107.643,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,70.5478,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,144.738,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-111.76,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-37.5697,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-74.6649,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-0.474363,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-93.2126,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-19.022,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-56.1173,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,18.0733,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-10.4282,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,63.7624,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,26.6671,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,100.858,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,8.11946,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,82.31,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,45.2147,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,119.405,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-61.0942,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,13.0964,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-23.9989,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,50.1917,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-42.5466,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,31.644,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-5.45128,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,68.7393,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,40.2378,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,13,13);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,114.428,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,77.3331,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,151.524,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,58.7855,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,132.976,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,95.8808,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,170.071,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.386,-4.43825)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.378,-51.7595)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,145);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.424,-28.0428)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.283,-75.1028)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.905,-16.2902)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.897,-63.5121)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.859,-39.9075)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.803,-87.0314)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.386,96.4328)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.378,49.1116)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.424,72.8283)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.283,25.7683)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.905,84.5809)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.897,37.359)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.859,60.9636)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.803,13.8397)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.386,45.9094)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,72,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.378,-1.41182)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.424,22.3048)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.283,-24.7552)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.905,34.0574)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.897,-13.1644)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.859,10.4402)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.803,-36.6837)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.386,146.781)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.378,99.4593)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.424,123.176)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.283,76.1159)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.905,134.929)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.897,87.7067)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.859,111.311)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.803,64.1874)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.386,20.6946)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.378,-26.6267)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.424,-2.91002)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.283,-49.97)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.905,8.84258)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.897,-38.3793)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.859,-14.7747)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.803,-61.8986)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.386,121.566)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.378,74.2444)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.424,97.9611)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.283,50.9011)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.905,109.714)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.897,62.4918)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.859,86.0964)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.803,38.9725)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.386,71.0422)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.378,23.721)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.424,47.4376)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.283,0.377653)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.905,59.1902)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.897,11.9684)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.859,35.573)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(235,235,235);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.803,-11.5509)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.386,171.913)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.378,124.592)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,145);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.424,148.309)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,73);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.283,101.249)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.905,160.061)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.897,112.839)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.859,136.444)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.803,89.3202)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:white;stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g id="axes" transform="matrix(1,0,0,1,-0.0566172,-50)">
+        <g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-52.4094,270.607)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(0,-1,1,0,-52.4094,473.361)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(-1,-1.22465e-16,1.22465e-16,-1,151.86,569.465)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(0,255,0);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,-9.01877,24.5561)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(0,255,0);"/>
+            </g>
+            <g transform="matrix(6.21256e-17,-1.01459,1,6.12323e-17,-52.4094,477.765)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(0,255,0);stroke-width:0.99px;"/>
+            </g>
+        </g>
+        <g transform="matrix(0.547017,0.837121,-0.837121,0.547017,240.244,-7.07818)">
+            <g transform="matrix(-1,-1.22465e-16,1.22465e-16,-1,157.286,422.965)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(13,40,242);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,-4.41699,-88.72)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(13,40,242);"/>
+            </g>
+            <g transform="matrix(6.41412e-17,-0.795906,1.01308,1.05301e-16,-49.3679,307.392)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(13,40,242);stroke-width:1.1px;"/>
+            </g>
+            <g transform="matrix(-0.837121,-0.547017,0.547017,-0.837121,67.9116,231.828)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+        </g>
+        <g transform="matrix(1,0,0,1,33.0393,0)">
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+        </g>
+        <g transform="matrix(1,0,0,1,33.0393,0)">
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+            </g>
+        </g>
+        <g transform="matrix(1,0,0,1,33.0393,0)">
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);"/>
+            </g>
+            <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(242,13,13);stroke-width:1px;"/>
+            </g>
+        </g>
+    </g>
+</svg>

BIN
threejs/lessons/resources/images/3dlut-photoshop-after.jpg


BIN
threejs/lessons/resources/images/3dlut-photoshop-before.jpg


+ 694 - 0
threejs/lessons/resources/images/3dlut-rgb.svg

@@ -0,0 +1,694 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 54 43" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
+    <g transform="matrix(0.106667,0,0,0.106667,0,0)">
+        <g transform="matrix(1,0,0,1,-69.0012,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-69.0012,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-69.0012,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-69.0012,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-69.0012,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-69.0012,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-69.0012,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-69.0012,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,255,0);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,32.3308,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,32.3308,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,32.3308,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,32.3308,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,32.3308,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,32.3308,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,32.3308,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,32.3308,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-18.3352,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-18.3352,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-18.3352,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-18.3352,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-18.3352,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-18.3352,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-18.3352,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-18.3352,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,82.9969,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,82.9969,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,82.9969,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,82.9969,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,82.9969,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,82.9969,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,82.9969,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,82.9969,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-43.6682,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-43.6682,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-43.6682,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-43.6682,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-43.6682,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-43.6682,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-43.6682,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,-43.6682,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,57.6638,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,57.6638,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,57.6638,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,57.6638,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,57.6638,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,57.6638,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,57.6638,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,57.6638,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,6.99782,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,6.99782,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,6.99782,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,6.99782,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,6.99782,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,6.99782,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,6.99782,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,6.99782,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,108.33,-4.67287)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(242,13,13);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,108.33,96.6592)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,108.33,45.9931)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,108.33,147.325)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,108.33,20.6601)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,108.33,121.992)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,108.33,71.3262)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0,1,108.33,172.658)">
+            <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(204,204,204);stroke:black;stroke-width:1px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-62.9593,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-100.055,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-25.864,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-118.602,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-44.4116,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-81.5069,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-7.31635,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(13,40,242);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-35.8178,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,38.3728,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,1.27747,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,75.4681,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-17.2702,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,56.9204,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,19.8251,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,94.0157,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-86.4838,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-12.2933,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-49.3885,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,24.802,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-67.9362,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,6.25439,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-30.8409,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,43.3497,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,14.8482,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,89.0388,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,51.9435,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,126.134,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,33.3958,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,107.586,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,70.4911,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,144.682,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-111.817,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-37.6263,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-74.7216,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-0.53098,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-93.2692,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-19.0786,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-56.1739,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,18.0167,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-10.4848,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,63.7058,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,26.6105,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,100.801,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,8.06284,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,82.2534,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,45.1581,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,119.349,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-61.1508,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,13.0398,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-24.0555,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,50.135,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-42.6032,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,31.5874,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-5.50789,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,68.6827,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,40.1812,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(242,13,13);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,114.372,-18.37)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,77.2765,5.13517)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,151.467,-41.8752)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,58.7289,16.8878)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,132.919,-30.1226)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,95.8241,-6.61743)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,170.015,-53.6278)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,181.329,-4.43825)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(242,13,13);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,255.321,-51.7595)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,218.368,-28.0428)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,292.227,-75.1028)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,199.848,-16.2902)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,273.841,-63.5121)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,236.802,-39.9075)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,310.746,-87.0314)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,181.329,96.4328)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,255.321,49.1116)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,218.368,72.8283)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,292.227,25.7683)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,199.848,84.5809)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,273.841,37.359)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,236.802,60.9636)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,310.746,13.8397)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,181.329,45.9094)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,255.321,-1.41182)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,218.368,22.3048)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,292.227,-24.7552)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,199.848,34.0574)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,273.841,-13.1644)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,236.802,10.4402)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,310.746,-36.6837)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,181.329,146.781)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,255.321,99.4593)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,218.368,123.176)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,292.227,76.1159)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,199.848,134.929)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,273.841,87.7067)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,236.802,111.311)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,310.746,64.1874)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,181.329,20.6946)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,255.321,-26.6267)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,218.368,-2.91002)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,292.227,-49.97)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,199.848,8.84258)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,273.841,-38.3793)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,236.802,-14.7747)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,310.746,-61.8986)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,181.329,121.566)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,255.321,74.2444)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,218.368,97.9611)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,292.227,50.9011)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,199.848,109.714)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,273.841,62.4918)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,236.802,86.0964)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,310.746,38.9725)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,181.329,71.0422)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,255.321,23.721)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,218.368,47.4376)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,292.227,0.377653)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,199.848,59.1902)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,273.841,11.9684)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,236.802,35.573)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,310.746,-11.5509)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,181.329,171.913)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,255.321,124.592)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,218.368,148.309)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,292.227,101.249)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,199.848,160.061)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,273.841,112.839)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,236.802,136.444)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(204,204,204);stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(0.731033,0,0,1,310.746,89.3202)">
+            <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:white;stroke:black;stroke-width:1.14px;"/>
+        </g>
+        <g transform="matrix(1,0,0.384374,0.665756,-137.15,28.6404)">
+            <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="stroke:black;stroke-width:0.92px;"/>
+        </g>
+        <g id="axes" transform="matrix(1,0,0,1,0,-50)">
+            <g>
+                <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-52.4094,270.607)">
+                    <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+                </g>
+                <g transform="matrix(0,-1,1,0,-52.4094,473.361)">
+                    <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+                </g>
+                <g transform="matrix(-1,-1.22465e-16,1.22465e-16,-1,151.86,569.465)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(0,255,0);"/>
+                </g>
+                <g transform="matrix(1,0,0,1,-9.01877,24.5561)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(0,255,0);"/>
+                </g>
+                <g transform="matrix(6.21256e-17,-1.01459,1,6.12323e-17,-52.4094,477.765)">
+                    <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(0,255,0);stroke-width:0.99px;"/>
+                </g>
+            </g>
+            <g transform="matrix(0.547017,0.837121,-0.837121,0.547017,240.244,-7.07818)">
+                <g transform="matrix(-1,-1.22465e-16,1.22465e-16,-1,157.286,422.965)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(13,40,242);"/>
+                </g>
+                <g transform="matrix(1,0,0,1,-4.41699,-88.72)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(13,40,242);"/>
+                </g>
+                <g transform="matrix(6.41412e-17,-0.795906,1.01308,1.05301e-16,-49.3679,307.392)">
+                    <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(13,40,242);stroke-width:1.1px;"/>
+                </g>
+                <g transform="matrix(-0.837121,-0.547017,0.547017,-0.837121,67.9116,231.828)">
+                    <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+                </g>
+            </g>
+            <g transform="matrix(1,0,0,1,33.0393,0)">
+                <g transform="matrix(1,0,0,1,0,30.6692)">
+                    <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+                </g>
+                <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                    <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+                </g>
+                <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+                </g>
+                <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+                </g>
+                <g transform="matrix(1,0,0,1,0,30.6692)">
+                    <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+                </g>
+            </g>
+            <g transform="matrix(1,0,0,1,33.0393,0)">
+                <g transform="matrix(1,0,0,1,0,30.6692)">
+                    <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+                </g>
+                <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                    <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+                </g>
+                <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-width:3.75px;"/>
+                </g>
+                <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-width:3.75px;"/>
+                </g>
+                <g transform="matrix(1,0,0,1,0,30.6692)">
+                    <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+                </g>
+            </g>
+            <g transform="matrix(1,0,0,1,33.0393,0)">
+                <g transform="matrix(1,0,0,1,0,30.6692)">
+                    <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+                </g>
+                <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                    <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+                </g>
+                <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);"/>
+                </g>
+                <g transform="matrix(0.616525,0,0,0.616525,-5.75519,104.45)">
+                    <text x="43.625px" y="137.344px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:20.833px;">0.0</text>
+                </g>
+                <g transform="matrix(0.616525,0,0,0.616525,105.987,30.5538)">
+                    <text x="43.625px" y="137.344px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:20.833px;">1.0</text>
+                </g>
+                <g transform="matrix(0.616525,0,0,0.616525,-14.9635,126.481)">
+                    <text x="43.625px" y="137.344px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:20.833px;">0.0</text>
+                </g>
+                <g transform="matrix(0.616525,0,0,0.616525,-14.9635,308.481)">
+                    <text x="43.625px" y="137.344px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:20.833px;">1.0</text>
+                </g>
+                <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);"/>
+                </g>
+                <g transform="matrix(1,0,0,1,0,30.6692)">
+                    <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(242,13,13);stroke-width:1px;"/>
+                </g>
+            </g>
+            <g transform="matrix(1,0,0,1,33.0393,0)">
+                <g transform="matrix(0.616525,0,0,0.616525,52.1748,59.5824)">
+                    <text x="43.625px" y="137.344px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:20.833px;stroke:white;stroke-width:6.76px;stroke-linecap:butt;stroke-miterlimit:1.41421;">0.0</text>
+                </g>
+                <g transform="matrix(0.616525,0,0,0.616525,229.266,59.5824)">
+                    <text x="43.625px" y="137.344px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:20.833px;stroke:white;stroke-width:6.76px;stroke-linecap:butt;stroke-miterlimit:1.41421;">1.0</text>
+                </g>
+            </g>
+            <g transform="matrix(1,0,0,1,33.0393,0)">
+                <g transform="matrix(0.616525,0,0,0.616525,52.1748,59.5824)">
+                    <text x="43.625px" y="137.344px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:20.833px;">0.0</text>
+                </g>
+                <g transform="matrix(0.616525,0,0,0.616525,229.266,59.5824)">
+                    <text x="43.625px" y="137.344px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:20.833px;">1.0</text>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

BIN
threejs/lessons/resources/images/3dlut-screen-capture.jpg


+ 40 - 0
threejs/lessons/resources/images/3dlut-standard-2x2.svg

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 140 140" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
+    <g transform="matrix(1,0,0,1,-150.593,-93.9489)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,255,255);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-150.593,-68.6158)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-125.26,-93.9489)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,0,13);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-125.26,-68.6158)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-218.741,-60.6356)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,255,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-200.194,-72.3882)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-193.408,-60.6356)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,13,13);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-174.861,-72.3882)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,-52.2604,-93.7142)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,-33.7411,-105.566)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,-52.2604,-68.5814)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,-33.7411,-80.4334)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:white;stroke:black;stroke-width:1.14px;"/>
+    </g>
+</svg>

+ 733 - 0
threejs/lessons/resources/images/3dlut-standard-lookup.svg

@@ -0,0 +1,733 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 96 43" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
+    <g transform="matrix(0.106667,0,0,0.106667,0,0)">
+        <g id="Input">
+            <g transform="matrix(1,0,0,1,9.47928,-6.33325)">
+                <rect x="33.377" y="171.057" width="178.1" height="113.999" style="fill:rgb(144,244,255);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,9.47928,-6.33325)">
+                <rect x="33.377" y="171.057" width="178.1" height="113.999" style="fill:rgb(144,244,255);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,0.734872,0,179.303)">
+                <rect x="42.856" y="92.197" width="178.1" height="43.091" style="fill:rgb(145,109,0);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,-5.03489,-2.01823)">
+                <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(0,117,5);"/>
+            </g>
+            <g transform="matrix(0.940057,0,0,0.940057,3.17374,-1.88307)">
+                <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(0,117,5);"/>
+            </g>
+            <g transform="matrix(0.850143,0,0,0.850143,15.7252,5.07521)">
+                <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(0,117,5);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,2.28684,-3.71511)">
+                <path d="M80.357,174.727L83.592,184.684L89.827,181.607L88.827,188.488L99.297,188.488L90.827,194.642L95.68,199.62L88.827,200.796L92.062,210.753L83.592,204.599L80.357,210.753L77.122,204.599L68.651,210.753L71.887,200.796L65.034,199.62L69.887,194.642L61.417,188.488L71.887,188.488L70.887,181.607L77.122,184.684L80.357,174.727Z" style="fill:rgb(255,251,18);"/>
+            </g>
+            <g transform="matrix(1.14154,0,0,1,-23.4531,0)">
+                <rect x="131.906" y="236.407" width="8.38" height="10.648" style="fill:rgb(82,75,0);"/>
+            </g>
+        </g>
+        <g id="Result" transform="matrix(1,0,0,1,642.707,0)">
+            <g id="Arrow06-Result">
+                <g transform="matrix(1,0,0,1,9.47928,-6.33325)">
+                    <rect x="33.377" y="171.057" width="178.1" height="113.999" style="fill:rgb(144,244,255);"/>
+                </g>
+                <g transform="matrix(1,0,0,1,9.47928,-6.33325)">
+                    <rect x="33.377" y="171.057" width="178.1" height="113.999" style="fill:rgb(144,244,255);stroke:black;stroke-width:1px;"/>
+                </g>
+            </g>
+            <g id="Arrow04-Result" transform="matrix(1,0,0,0.734872,0,179.303)">
+                <rect x="42.856" y="92.197" width="178.1" height="43.091" style="fill:rgb(145,109,0);"/>
+            </g>
+            <g id="Arrow01-Result">
+                <g transform="matrix(1,0,0,1,-5.03489,-2.01823)">
+                    <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(0,117,5);"/>
+                </g>
+                <g transform="matrix(0.940057,0,0,0.940057,3.17374,-1.88307)">
+                    <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(0,117,5);"/>
+                </g>
+                <g transform="matrix(0.850143,0,0,0.850143,15.7252,5.07521)">
+                    <path d="M136.941,209.056L153.624,238.426L120.259,238.426L136.941,209.056Z" style="fill:rgb(0,117,5);"/>
+                </g>
+            </g>
+            <g id="Arrow03-Result" transform="matrix(1,0,0,1,2.28684,-3.71511)">
+                <path d="M80.357,174.727L83.592,184.684L89.827,181.607L88.827,188.488L99.297,188.488L90.827,194.642L95.68,199.62L88.827,200.796L92.062,210.753L83.592,204.599L80.357,210.753L77.122,204.599L68.651,210.753L71.887,200.796L65.034,199.62L69.887,194.642L61.417,188.488L71.887,188.488L70.887,181.607L77.122,184.684L80.357,174.727Z" style="fill:rgb(255,251,18);"/>
+            </g>
+            <g id="Arrow02-Result" transform="matrix(1.14154,0,0,1,-23.4531,0)">
+                <rect x="131.906" y="236.407" width="8.38" height="10.648" style="fill:rgb(82,75,0);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,9.47928,-6.33325)">
+                <g id="Result-Outline">
+                    <rect x="33.377" y="171.057" width="178.1" height="113.999" style="fill:none;stroke:black;stroke-width:1px;"/>
+                </g>
+            </g>
+        </g>
+        <g id="Back-Arrows">
+            <g id="Arrow06-Output" transform="matrix(0.0599313,-0.987016,0.987016,0.0599313,-53.7464,365.633)">
+                <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                    <path d="M133.373,543.235L192.513,758.881" style="fill:none;stroke:black;stroke-width:1px;"/>
+                </g>
+                <g transform="matrix(-0.960349,0.2788,-0.2788,-0.960349,320.16,918.802)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                </g>
+            </g>
+            <g id="Arrow06-Input" transform="matrix(0.446757,-0.882157,0.882157,0.446757,-283.977,94.0662)">
+                <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                    <path d="M124.812,479.05L192.513,758.881" style="fill:none;stroke:black;stroke-width:1px;"/>
+                </g>
+                <g transform="matrix(-0.960349,0.2788,-0.2788,-0.960349,320.16,918.802)">
+                    <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                </g>
+            </g>
+        </g>
+        <g id="_3DLUT" serif:id="3DLUT">
+            <g transform="matrix(1,0,0,1,97.9595,-4.67287)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,97.9595,96.6592)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,146,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,97.9595,45.9931)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,73,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,97.9595,147.325)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,219,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,97.9595,20.6601)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,36,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,97.9595,121.992)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,182,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,97.9595,71.3262)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,109,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,97.9595,172.658)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,255,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,199.292,-4.67287)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,0,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,199.292,96.6592)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,145,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,199.292,45.9931)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,72,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,199.292,147.325)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,218,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,199.292,20.6601)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(142,36,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,199.292,121.992)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,182,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,199.292,71.3262)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,109,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,199.292,172.658)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,255,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,148.626,-4.67287)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,0,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,148.626,96.6592)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(72,145,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,148.626,45.9931)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,73,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,148.626,147.325)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,218,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,148.626,20.6601)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(72,36,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,148.626,121.992)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,182,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,148.626,71.3262)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(72,109,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,148.626,172.658)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,255,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,249.958,-4.67287)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,0,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,249.958,96.6592)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(219,145,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,249.958,45.9931)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(219,72,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,249.958,147.325)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,218,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,249.958,20.6601)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(219,36,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,249.958,121.992)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,182,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,249.958,71.3262)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,109,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,249.958,172.658)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,255,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,123.293,-4.67287)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,0,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,123.293,96.6592)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,145,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,123.293,45.9931)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,72,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,123.293,147.325)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,218,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,123.293,20.6601)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,36,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,123.293,121.992)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,182,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,123.293,71.3262)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,109,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,123.293,172.658)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,255,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,224.625,-4.67287)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,0,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,224.625,96.6592)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,145,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,224.625,45.9931)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(192,72,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,224.625,147.325)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,218,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,224.625,20.6601)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,36,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,224.625,121.992)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,182,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,224.625,71.3262)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,109,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,224.625,172.658)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,255,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,173.959,-4.67287)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,0,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,173.959,96.6592)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,145,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,173.959,45.9931)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,72,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,173.959,147.325)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,218,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,173.959,20.6601)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,36,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,173.959,121.992)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,182,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,173.959,71.3262)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,109,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,173.959,172.658)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,255,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,275.291,-4.67287)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,0,13);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,275.291,96.6592)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,145,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,275.291,45.9931)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,72,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,275.291,147.325)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,218,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,275.291,20.6601)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,36,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,275.291,121.992)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,182,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,275.291,71.3262)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,109,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,275.291,172.658)">
+                <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,255,0);stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,29.8109,28.6404)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,104.001,-18.37)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,146);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,66.9062,5.13517)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,73);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,141.097,-41.8752)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,219);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,48.3585,16.8878)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,36);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,122.549,-30.1226)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,182);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,85.4538,-6.61743)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,109);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,159.644,-53.6278)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,255);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,131.143,28.6404)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,0);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,205.333,-18.37)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,145);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,168.238,5.13517)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,72);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,242.429,-41.8752)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,218);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,149.691,16.8878)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,36);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,223.881,-30.1226)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,182);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,186.786,-6.61743)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,109);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,260.976,-53.6278)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,255);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,80.4769,28.6404)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,0);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,154.667,-18.37)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,145);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,117.572,5.13517)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(72,0,72);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,191.763,-41.8752)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,218);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,99.0245,16.8878)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,36);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,173.215,-30.1226)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,182);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,136.12,-6.61743)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,109);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,210.31,-53.6278)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,255);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,181.809,28.6404)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,0);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,256,-18.37)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,145);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,218.904,5.13517)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,72);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,293.095,-41.8752)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,218);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,200.357,16.8878)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,36);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,274.547,-30.1226)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,182);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,237.452,-6.61743)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,109);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,311.642,-53.6278)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,255);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,55.1439,28.6404)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,0);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,129.334,-18.37)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,145);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,92.2392,5.13517)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,72);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,166.43,-41.8752)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,218);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,73.6915,16.8878)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,36);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,147.882,-30.1226)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,182);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,110.787,-6.61743)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,109);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,184.977,-53.6278)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,255);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,156.476,28.6404)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,0);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,230.666,-18.37)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,145);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,193.571,5.13517)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,72);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,267.762,-41.8752)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,218);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,175.024,16.8878)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,36);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,249.214,-30.1226)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,183);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,212.119,-6.61743)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,109);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,286.309,-53.6278)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,255);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,105.81,28.6404)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,0);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,180,-18.37)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,145);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,142.905,5.13517)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,72);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,217.096,-41.8752)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,218);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,124.358,16.8878)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,36);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,198.548,-30.1226)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,182);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,161.453,-6.61743)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,109);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,235.643,-53.6278)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,255);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,207.142,28.6404)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,13,13);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,281.333,-18.37)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,145);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,244.237,5.13517)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,72);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,318.428,-41.8752)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,218);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,225.69,16.8878)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,36);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,299.88,-30.1226)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,182);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,262.785,-6.61743)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,109);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(1,0,0.384374,0.665756,336.975,-53.6278)">
+                <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,255);stroke:black;stroke-width:0.92px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,348.29,-4.43825)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,0);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,422.282,-51.7595)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,145);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,385.328,-28.0428)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,72);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,459.187,-75.1028)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,218);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,366.809,-16.2902)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,36);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,440.801,-63.5121)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,182);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,403.763,-39.9075)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,109);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,477.707,-87.0314)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,255);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,348.29,96.4328)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,0);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,422.282,49.1116)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,145);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,385.328,72.8283)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,72);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,459.187,25.7683)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,218);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,366.809,84.5809)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,36);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,440.801,37.359)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,182);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,403.763,60.9636)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,109);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,477.707,13.8397)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,255);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,348.29,45.9094)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,72,0);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,422.282,-1.41182)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,142);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,385.328,22.3048)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,72,72);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,459.187,-24.7552)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,218);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,366.809,34.0574)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,72,36);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,440.801,-13.1644)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,182);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,403.763,10.4402)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,109);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,477.707,-36.6837)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,255);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,348.29,146.781)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,0);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,422.282,99.4593)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,142);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,385.328,123.176)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,72);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,459.187,76.1159)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,219,219);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,366.809,134.929)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,36);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,440.801,87.7067)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,182);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,403.763,111.311)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,109);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,477.707,64.1874)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,255);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,348.29,20.6946)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,0);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,422.282,-26.6267)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,142);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,385.328,-2.91002)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,72);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,459.187,-49.97)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,218);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,366.809,8.84258)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,36);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,440.801,-38.3793)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,182);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,403.763,-14.7747)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,109);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,477.707,-61.8986)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,255);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,348.29,121.566)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,0);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,422.282,74.2444)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,142);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,385.328,97.9611)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,72);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,459.187,50.9011)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,218);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,366.809,109.714)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,36);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,440.801,62.4918)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,182);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,403.763,86.0964)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,109);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,477.707,38.9725)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,255);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,348.29,71.0422)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,0);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,422.282,23.721)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,142);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,385.328,47.4376)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,72);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,459.187,0.377653)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,218);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,366.809,59.1902)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,36);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,440.801,11.9684)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,182);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,403.763,35.573)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,109);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,477.707,-11.5509)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,255);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,348.29,171.913)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,0);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,422.282,124.592)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,145);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,385.328,148.309)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,73);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,459.187,101.249)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,218);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,366.809,160.061)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,36);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,440.801,112.839)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,182);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,403.763,136.444)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,109);stroke:black;stroke-width:1.14px;"/>
+            </g>
+            <g transform="matrix(0.731033,0,0,1,477.707,89.3202)">
+                <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:white;stroke:black;stroke-width:1.14px;"/>
+            </g>
+        </g>
+        <g id="Front-Arrows">
+            <g>
+                <g id="Arrow01-Input" transform="matrix(-0.00725653,-0.999974,0.999974,-0.00725653,-129.6,385.888)">
+                    <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                        <path d="M156.668,262.889L144.955,402.713" style="fill:none;stroke:black;stroke-width:0.99px;"/>
+                    </g>
+                    <g transform="matrix(-0.993977,-0.109589,0.109589,-0.993977,204.051,594.659)">
+                        <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                    </g>
+                </g>
+                <g id="Arrow01-Output" transform="matrix(0.0870807,-0.984992,0.984992,0.0870807,-57.429,349.296)">
+                    <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                        <path d="M141.452,344.114L211.962,814.451" style="fill:none;stroke:black;stroke-width:1px;"/>
+                    </g>
+                    <g transform="matrix(-0.991923,0.126838,-0.126838,-0.991923,313.621,989.726)">
+                        <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                    </g>
+                </g>
+                <g id="Arrow02-Input" transform="matrix(-0.394342,-0.918964,0.918964,-0.394342,-20.7391,483.782)">
+                    <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                        <path d="M162.241,236.283L143.059,415.107" style="fill:none;stroke:black;stroke-width:0.99px;"/>
+                    </g>
+                    <g transform="matrix(-0.993977,-0.109589,0.109589,-0.993977,204.018,599.15)">
+                        <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                    </g>
+                </g>
+                <g id="Arrow02-Output" transform="matrix(0.257817,-0.954632,0.954632,0.257817,-51.8064,233.413)">
+                    <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                        <path d="M142.892,347.83L207.757,796.402" style="fill:none;stroke:black;stroke-width:1px;"/>
+                    </g>
+                    <g transform="matrix(-0.991523,0.129928,-0.129928,-0.991523,310.206,970.847)">
+                        <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                    </g>
+                </g>
+                <g id="Arrow03-Input" transform="matrix(-0.00725653,-0.999974,0.999974,-0.00725653,-180.334,350.514)">
+                    <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                        <path d="M156.668,262.889L39.944,690.63" style="fill:none;stroke:black;stroke-width:0.99px;"/>
+                    </g>
+                    <g transform="matrix(-0.974209,-0.225649,0.225649,-0.974209,78.8227,890.255)">
+                        <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                    </g>
+                </g>
+                <g id="Arrow03-Output" transform="matrix(-0.406151,-0.901573,0.901573,-0.406151,276.05,570.518)">
+                    <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                        <path d="M142.034,343.466L164.18,564.489" style="fill:none;stroke:black;stroke-width:1px;"/>
+                    </g>
+                    <g transform="matrix(-0.991523,0.129928,-0.129928,-0.991523,266.695,733.716)">
+                        <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                    </g>
+                </g>
+                <g id="Arrow04-Input" transform="matrix(-0.185534,-0.971272,0.971272,-0.185534,-126.766,464.83)">
+                    <g transform="matrix(1,0,0,1.0209,0,-5.49553)">
+                        <path d="M141.551,340.405L159.904,522.89" style="fill:none;stroke:black;stroke-width:1px;"/>
+                    </g>
+                    <g transform="matrix(-0.991523,0.129928,-0.129928,-0.991523,262.914,693.466)">
+                        <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                    </g>
+                </g>
+                <g id="Arrow04-Output" transform="matrix(0.257817,-0.954632,0.954632,0.257817,1.31472,260.221)">
+                    <g>
+                        <g transform="matrix(1,0,0,1.0209,-3.55271e-15,-5.49553)">
+                            <path d="M147.166,344.75L179.991,672.129" style="fill:none;stroke:black;stroke-width:1px;"/>
+                        </g>
+                        <g transform="matrix(-0.991523,0.129928,-0.129928,-0.991523,283.185,845.353)">
+                            <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z"/>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 664 - 0
threejs/lessons/resources/images/3dlut-standard.svg

@@ -0,0 +1,664 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 500 400" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
+    <g transform="matrix(1,0,0,1,-69.0012,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-69.0012,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,146,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-69.0012,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,73,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-69.0012,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,219,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-69.0012,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-69.0012,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-69.0012,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-69.0012,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(0,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3308,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3308,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3308,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,72,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3308,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3308,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(142,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3308,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3308,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,32.3308,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(145,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3352,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3352,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(72,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3352,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,73,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3352,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3352,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(72,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3352,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3352,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(72,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-18.3352,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(73,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,82.9969,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,82.9969,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(219,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,82.9969,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(219,72,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,82.9969,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,82.9969,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(219,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,82.9969,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,82.9969,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,82.9969,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(218,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6682,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6682,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6682,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,72,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6682,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6682,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6682,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6682,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,-43.6682,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(36,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6638,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6638,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6638,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(192,72,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6638,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6638,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6638,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6638,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,57.6638,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(182,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,6.99782,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,0,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,6.99782,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,6.99782,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,72,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,6.99782,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,6.99782,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,6.99782,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,6.99782,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,6.99782,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(109,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.33,-4.67287)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,0,13);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.33,96.6592)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,145,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.33,45.9931)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,72,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.33,147.325)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,218,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.33,20.6601)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,36,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.33,121.992)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,182,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.33,71.3262)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,109,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0,1,108.33,172.658)">
+        <rect x="177.014" y="150.396" width="25.333" height="25.333" style="fill:rgb(255,255,0);stroke:black;stroke-width:1px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-137.15,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-62.9593,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,146);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-100.055,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,73);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-25.864,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,219);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-118.602,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-44.4116,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-81.5069,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-7.31635,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(0,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-35.8178,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,38.3728,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,1.27747,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,75.4681,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-17.2702,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,56.9204,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,19.8251,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,94.0157,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(145,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-86.4838,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-12.2933,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-49.3885,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(72,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,24.802,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-67.9362,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,6.25439,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-30.8409,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,43.3497,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(73,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,14.8482,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,89.0388,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,51.9435,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,126.134,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,33.3958,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,107.586,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,70.4911,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,144.682,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(218,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-111.817,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-37.6263,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-74.7216,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-0.53098,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-93.2692,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-19.0786,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-56.1739,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,18.0167,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(36,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-10.4848,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,63.7058,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,26.6105,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,100.801,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,8.06284,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,82.2534,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,183);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,45.1581,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,119.349,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(182,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-61.1508,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,0);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,13.0398,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-24.0555,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,50.135,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-42.6032,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,31.5874,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,-5.50789,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,68.6827,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(109,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,40.1812,28.6404)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,13,13);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,114.372,-18.37)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,145);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,77.2765,5.13517)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,72);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,151.467,-41.8752)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,218);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,58.7289,16.8878)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,36);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,132.919,-30.1226)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,182);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,95.8241,-6.61743)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,109);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(1,0,0.384374,0.665756,170.015,-53.6278)">
+        <path d="M227.68,158.076L202.347,158.076L177.014,175.729L202.347,175.729L227.68,158.076Z" style="fill:rgb(255,0,255);stroke:black;stroke-width:0.92px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.329,-4.43825)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.321,-51.7595)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,145);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.368,-28.0428)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.227,-75.1028)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.848,-16.2902)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.841,-63.5121)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.802,-39.9075)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.746,-87.0314)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,0,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.329,96.4328)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.321,49.1116)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,145);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.368,72.8283)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.227,25.7683)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.848,84.5809)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.841,37.359)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.802,60.9636)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.746,13.8397)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,145,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.329,45.9094)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,72,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.321,-1.41182)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,142);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.368,22.3048)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,72,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.227,-24.7552)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.848,34.0574)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,72,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.841,-13.1644)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.802,10.4402)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.746,-36.6837)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,73,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.329,146.781)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.321,99.4593)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,142);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.368,123.176)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.227,76.1159)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,219,219);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.848,134.929)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.841,87.7067)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.802,111.311)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.746,64.1874)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,218,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.329,20.6946)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.321,-26.6267)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,142);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.368,-2.91002)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.227,-49.97)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.848,8.84258)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.841,-38.3793)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.802,-14.7747)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.746,-61.8986)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,36,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.329,121.566)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.321,74.2444)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,142);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.368,97.9611)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.227,50.9011)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.848,109.714)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.841,62.4918)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.802,86.0964)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.746,38.9725)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,182,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.329,71.0422)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.321,23.721)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,142);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.368,47.4376)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,72);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.227,0.377653)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.848,59.1902)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.841,11.9684)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.802,35.573)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.746,-11.5509)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,109,255);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,181.329,171.913)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,0);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,255.321,124.592)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,145);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,218.368,148.309)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,73);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,292.227,101.249)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,218);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,199.848,160.061)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,36);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,273.841,112.839)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,182);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,236.802,136.444)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:rgb(255,255,109);stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g transform="matrix(0.731033,0,0,1,310.746,89.3202)">
+        <path d="M202.347,138.644L177.014,150.396L177.014,175.729L202.347,163.977L202.347,138.644Z" style="fill:white;stroke:black;stroke-width:1.14px;"/>
+    </g>
+    <g id="axes" transform="matrix(1,0,0,1,0,-50)">
+        <g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-52.4094,270.607)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(0,-1,1,0,-52.4094,473.361)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(-1,-1.22465e-16,1.22465e-16,-1,151.86,569.465)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(0,255,0);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,-9.01877,24.5561)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(0,255,0);"/>
+            </g>
+            <g transform="matrix(6.21256e-17,-1.01459,1,6.12323e-17,-52.4094,477.765)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(0,255,0);stroke-width:0.99px;"/>
+            </g>
+        </g>
+        <g transform="matrix(0.547017,0.837121,-0.837121,0.547017,240.244,-7.07818)">
+            <g transform="matrix(-1,-1.22465e-16,1.22465e-16,-1,157.286,422.965)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(13,40,242);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,-4.41699,-88.72)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(13,40,242);"/>
+            </g>
+            <g transform="matrix(6.41412e-17,-0.795906,1.01308,1.05301e-16,-49.3679,307.392)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(13,40,242);stroke-width:1.1px;"/>
+            </g>
+            <g transform="matrix(-0.837121,-0.547017,0.547017,-0.837121,67.9116,231.828)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+        </g>
+        <g transform="matrix(1,0,0,1,33.0393,0)">
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:white;stroke-opacity:0.54902;stroke-width:8.33px;"/>
+            </g>
+        </g>
+        <g transform="matrix(1,0,0,1,33.0393,0)">
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);stroke:white;stroke-width:3.75px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:white;stroke-width:3.75px;"/>
+            </g>
+        </g>
+        <g transform="matrix(1,0,0,1,33.0393,0)">
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(1,0,0,1,202.664,30.6692)">
+                <path d="M74.974,153.919L74.974,93.741" style="fill:none;stroke:black;stroke-width:1px;"/>
+            </g>
+            <g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-96.1034,234.938)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);"/>
+            </g>
+            <g transform="matrix(6.12323e-17,1,-1,6.12323e-17,448.715,74.0599)">
+                <path d="M80.439,171.077L85.905,190.975L74.974,190.975L80.439,171.077Z" style="fill:rgb(242,13,13);"/>
+            </g>
+            <g transform="matrix(1,0,0,1,0,30.6692)">
+                <path d="M94.871,123.83L257.74,123.83" style="fill:none;stroke:rgb(242,13,13);stroke-width:1px;"/>
+            </g>
+        </g>
+    </g>
+</svg>

BIN
threejs/lessons/resources/images/identity-lut-s16.png


BIN
threejs/lessons/resources/images/unfiltered-3dlut.jpg


+ 2 - 1
threejs/lessons/resources/lesson.css

@@ -211,7 +211,8 @@ code {
   text-align: center;
   max-width: 95%;
 }
-.threejs_center>img {
+.threejs_center>img,
+.threejs_center>object {
   max-width: 100%;
 }
 .threejs_image>img {

+ 109 - 0
threejs/lessons/resources/threejs-post-processing-3dlut.js

@@ -0,0 +1,109 @@
+'use strict';
+
+/* global */
+
+{
+  function makeWaiter() {
+    let resolve;
+    const promise = new Promise((_resolve) => {
+      resolve = _resolve;
+    });
+    return {
+      promise,
+      resolve,
+    };
+  }
+
+  async function getSVGDocument(elem) {
+    let doc = elem.getSVGDocument();
+    if (!doc) {
+      const waiter = makeWaiter();
+      elem.addEventListener('load', waiter.resolve);
+      await waiter.promise;
+      doc = elem.getSVGDocument();
+    }
+    return doc;
+  }
+
+  const diagrams = {
+    lookup: {
+      async init(elem) {
+        const svg = await getSVGDocument(elem);
+        const partsByName = {};
+        [
+          '[id$=-Input]',
+          '[id$=-Output]',
+          '[id$=-Result]',
+        ].map((selector) => {
+          [...svg.querySelectorAll('[id^=Effect]')].forEach((elem) => {
+            // because affinity designer doesn't export blend modes (T_T)
+            // and because I'd prefer not to have to manually fix things as I edit.
+            // I suppose I could add a build process.
+            elem.style.mixBlendMode = elem.id.split('-')[1];
+          });
+          [...svg.querySelectorAll(selector)].forEach((elem) => {
+            const [name, type] = elem.id.split('-');
+            partsByName[name] = partsByName[name] || {};
+            partsByName[name][type] = elem;
+            elem.style.visibility = 'hidden';
+          });
+        });
+        const parts = Object.keys(partsByName).sort().map(k => partsByName[k]);
+        let ndx = 0;
+        let step = 0;
+        let delay = 0;
+        setInterval(() => {
+          const part = parts[ndx];
+          switch (step) {
+            case 0:
+              part.Input.style.visibility = '';
+              ++step;
+              break;
+            case 1:
+              part.Output.style.visibility = '';
+              ++step;
+              break;
+            case 2:
+              part.Result.style.visibility = '';
+              ++step;
+              break;
+            case 3:
+              part.Input.style.visibility = 'hidden';
+              part.Output.style.visibility = 'hidden';
+              ndx = (ndx + 1) % parts.length;
+              if (ndx === 0) {
+                step = 4;
+                delay = 4;
+              } else {
+                step = 0;
+              }
+              break;
+            case 4:
+              --delay;
+              if (delay <= 0) {
+                for (const part of parts) {
+                  for (const elem of Object.values(part)) {
+                    elem.style.visibility = 'hidden';
+                  }
+                }
+                step = 0;
+              }
+              break;
+          }
+        }, 500);
+      },
+    },
+  };
+
+  [...document.querySelectorAll('[data-diagram]')].forEach(createDiagram);
+
+  function createDiagram(base) {
+    const name = base.dataset.diagram;
+    const info = diagrams[name];
+    if (!info) {
+      throw new Error(`no diagram ${name}`);
+    }
+    info.init(base);
+  }
+}
+

+ 491 - 0
threejs/lessons/threejs-post-processing-3dlut.md

@@ -0,0 +1,491 @@
+Title: Three.js Post Processing 3DLUT
+Description: How to implement a 3DLUT Post Process in THREE.js
+
+In the last article we went over [post processing](threejs-post-processing.html).
+On of the common ways to post process is called a LUT or 3DLUT. LUT stands for LookUp Table. A 3DLUT is therefore a 3 dimensional look up table.
+
+How it works is we make a cube of colors. Then we index the cube using the colors of our source image. For each pixel in the original image we look up a position in the cube based on the red, green, and blue colors of the original pixel. The value we pull put of the 3DLUT is the new color.
+
+In Javascript we might do it like this. Imagine the colors are specified in integers from 0 to 255 and we have a large 3 dimensional array 256x256x256 in size. Then for to translate a color through the look up table
+
+    const newColor = lut[origColor.red][origColor.green][origColor.bue]
+
+Of course a 256x256x256 array would be rather large but as we pointed out in [the article on textures](threejs-textures.html) textures are referenced from values of 0.0 to 1.0 regardless of the dimensions of the texture.
+
+Let's imagine an 8x8x8 cube.
+
+<div class="threejs_center"><img src="resources/images/3dlut-rgb.svg" style="width: 500px"></div>
+
+First we might fill in the corners with 0,0,0 corner being pure black, the opposite 1,1,1 corner pure white. 1,0,0 being pure <span style"color:red;">red</span>. 0,1,0 being pure <span style"color:green;">green</span> and 0,0,1 being <span style"color:blue;">blue</span>. 
+
+<div class="threejs_center"><img src="resources/images/3dlut-axis.svg" style="width: 500px"></div>
+
+We'd add in the colors down each axis.
+
+<div class="threejs_center"><img src="resources/images/3dlut-edges.svg" style="width: 500px"></div>
+
+And the colors on edges that use 2 or more channels.
+
+<div class="threejs_center"><img src="resources/images/3dlut-standard.svg" style="width: 500px"></div>
+
+And finally fill in all the colors in between. This is an "identity" 3DLUT. It produces the exact same output as input. If you look up a color you'll get the same color out.
+
+<div class="threejs_center"><object type="image/svg+xml" data="resources/images/3dlut-standard-lookup.svg" data-diagram="lookup" style="width: 600px"></object></div>
+
+If we change the cube to shades of amber though then as we look up colors, we look up the same locations in the 3D lookup table but they produce different output.
+
+<div class="threejs_center"><object type="image/svg+xml" data="resources/images/3dlut-amber-lookup.svg" data-diagram="lookup" style="width: 600px"></object></div>
+
+Using this techinque by supplying a different lookup table we can apply all kinds of effects. Basically any effect that can be computed based only on a single color input. Those effects include adjusting hue, contrast, saturation, color cast, tint, brightness, exposure, levels, curves, posterize, shadows, highlghts, and many others. Even better they can all be combined into a single look up table.
+
+To use it we need a scene to apply it to. Let's throw together a quick scene. We'll start with a glTF file and display it like we covered in [the article on loading a glTF](threejs-load-gltf.html). The model we're loading is [this model](https://sketchfab.com/models/a1d315908e9f45e5a3bc618bdfd2e7ee) by [The Ice Wolves](https://sketchfab.com/sarath.irn.kat005). It uses no lights so I removed the lights.
+
+We'll also add a background image like we covered in [backgrounds and skyboxs](threejs-backgrounds.html).
+
+{{{example url="../threejs-postprocessing-3dlut-prep.html" }}}
+
+Now that we have a scene we need a 3DLUT. The simplest 3DLUT is a 2x2x2 identity LUT where *identity* means nothing happens. It's like multiplying by 1 or doing nothign, even though we're looking up colors in the LUT each color in maps to the same color out.
+
+<div class="threejs_center"><img src="resources/images/3dlut-standard-2x2.svg" style="width: 100px"></div>
+
+WebGL1 doesn't support 3D textures so we'll use 4x2 2D texture and treat it as a 3D texture inside a custom shader where each slice of the cube is spread out horizontally across the texture.
+
+Here's the code to make 4x2 2D texture with the colors required for an identity LUT.
+
+```js
+const makeIdentityLutTexture = function() {
+  const identityLUT = new Uint8Array([
+      0,   0,   0, 255,  // black
+    255,   0,   0, 255,  // red
+      0,   0, 255, 255,  // blue
+    255,   0, 255, 255,  // magenta
+      0, 255,   0, 255,  // green
+    255, 255,   0, 255,  // yellow
+      0, 255, 255, 255,  // cyan
+    255, 255, 255, 255,  // white
+  ]);
+
+  return function(filter) {
+    const texture = new THREE.DataTexture(identityLUT, 4, 2, THREE.RGBAFormat);
+    texture.minFilter = filter;
+    texture.magFilter = filter;
+    texture.needsUpdate = true;
+    texture.flipY = false;
+    return texture;
+  };
+}();
+```
+
+Let's make 2 of them, one filtered and one not
+
+```js
+const lutTextures = [
+  { name: 'identity', size: 2, texture: makeIdentityLutTexture(THREE.LinearFilter) },
+  { name: 'identity not filtered', size: 2, texture: makeIdentityLutTexture(THREE.NearestFilter) },
+];
+```
+
+Taking the example using a custom shader from [the article on post processing](threejs-post-processing.html) lets use these 2 custom shaders instead.
+
+```js
+const lutShader = {
+  uniforms: {
+    tDiffuse: { value: null },
+    lutMap:  { value: null },
+    lutMapSize: { value: 1, },
+  },
+  vertexShader: `
+    varying vec2 vUv;
+    void main() {
+      vUv = uv;
+      gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+    }
+  `,
+  fragmentShader: `
+    #include <common>
+
+    #define FILTER_LUT true
+
+    uniform sampler2D tDiffuse;
+    uniform sampler2D lutMap;
+    uniform float lutMapSize;
+
+    varying vec2 vUv;
+
+    vec4 sampleAs3DTexture(sampler2D tex, vec3 texCoord, float size) {
+      float sliceSize = 1.0 / size;                  // space of 1 slice
+      float slicePixelSize = sliceSize / size;       // space of 1 pixel
+      float width = size - 1.0;
+      float sliceInnerSize = slicePixelSize * width; // space of size pixels
+      float zSlice0 = floor( texCoord.z * width);
+      float zSlice1 = min( zSlice0 + 1.0, width);
+      float xOffset = slicePixelSize * 0.5 + texCoord.x * sliceInnerSize;
+      float yRange = (texCoord.y * width + 0.5) / size;
+      float s0 = xOffset + (zSlice0 * sliceSize);
+
+      #ifdef FILTER_LUT
+
+        float s1 = xOffset + (zSlice1 * sliceSize);
+        vec4 slice0Color = texture2D(tex, vec2(s0, yRange));
+        vec4 slice1Color = texture2D(tex, vec2(s1, yRange));
+        float zOffset = mod(texCoord.z * width, 1.0);
+        return mix(slice0Color, slice1Color, zOffset);
+
+      #else
+
+        return texture2D(tex, vec2( s0, yRange));
+
+      #endif
+    }
+
+    void main() {
+      vec4 originalColor = texture2D(tDiffuse, vUv);
+      gl_FragColor = sampleAs3DTexture(lutMap, originalColor.xyz, lutMapSize);
+    }
+  `,
+};
+
+const lutNearestShader = {
+  uniforms: Object.assign( {}, lutShader.uniforms ),
+  vertexShader: lutShader.vertexShader,
+  fragmentShader: lutShader.fragmentShader.replace('#define FILTER_LUT', '//'),
+};
+```
+
+You can see in the fragment shader there is this line
+
+```glsl
+#define FILTER_LUT true
+```
+
+To generate the second shader we comment out that line.
+
+Then we use them to make 2 custom effects
+
+```js
+const effectLUT = new THREE.ShaderPass(lutShader);
+effectLUT.renderToScreen = true;
+const effectLUTNearest = new THREE.ShaderPass(lutNearestShader);
+effectLUTNearest.renderToScreen = true;
+```
+
+Translating our existing code that draws the background as a separate scene we a `RenderPass` for both the scene drawing the glTF and the scene drawing the background.
+
+```js
+const renderModel = new THREE.RenderPass(scene, camera);
+renderModel.clear = false;  // so we don't clear out the background
+const renderBG = new THREE.RenderPass(sceneBG, cameraBG);
+```
+
+and we can setup our `EffectComposer` to use all the passes
+
+```js
+const rtParameters = {
+  minFilter: THREE.LinearFilter,
+  magFilter: THREE.LinearFilter,
+  format: THREE.RGBFormat,
+};
+const composer = new THREE.EffectComposer(renderer, new THREE.WebGLRenderTarget(1, 1, rtParameters));
+
+composer.addPass(renderBG);
+composer.addPass(renderModel);
+composer.addPass(effectLUT);
+composer.addPass(effectLUTNearest);
+```
+
+Let's make some GUI code to select one lut or the other
+
+```js
+const lutNameIndexMap = {};
+lutTextures.forEach((info, ndx) => {
+  lutNameIndexMap[info.name] = ndx;
+});
+
+const lutSettings = {
+  lut: lutNameIndexMap.identity,
+};
+const gui = new dat.GUI({ width: 300 });
+gui.add(lutSettings, 'lut', lutNameIndexMap);
+```
+
+The last thing to do is turn on one effect or the other, depending on whether or not we want filtering, set the effect to use the selected texture, and render via the `EffectComposer`
+
+```js
+const lutInfo = lutTextures[lutSettings.lut];
+
+const effect = lutInfo.filter ? effectLUT : effectLUTNearest;
+effectLUT.enabled = lutInfo.filter;
+effectLUTNearest.enabled = !lutInfo.filter;
+
+const lutTexture = lutInfo.texture;
+effect.uniforms.lutMap.value = lutTexture;
+effect.uniforms.lutMapSize.value = lutInfo.size;
+
+composer.render(delta);
+```
+
+Given it's the identity 3DLUT nothing changes
+
+{{{example url="../threejs-postprocessing-3dlut-identity.html" }}}
+
+but we select the unfiltered LUT we get something much more interesting
+
+<div class="threejs_center"><img src="resources/images/unfiltered-3dlut.jpg" style="width: 500px"></div>
+
+Why does this happen? Because with filtering on, the GPU linearly interpolates between the colors. With filtering off it does no interpolation so looking up colors in the 3DLUT only gives one of the exact colors in the 3DLUT.
+
+So how do we go about making more interesting 3DLUTs?
+
+First decide on the resolution of the table you want and generate the slices of the lookup cube using a simple script.
+
+```js
+const ctx = document.querySelector('canvas').getContext('2d');
+
+function drawColorCubeImage(ctx, size) {
+  const canvas = ctx.canvas;
+  canvas.width = size * size;
+  canvas.height = size;
+
+  for (let zz = 0; zz < size; ++zz) {
+    for (let yy = 0; yy < size; ++yy) {
+      for (let xx = 0; xx < size; ++xx) {
+        const r = Math.floor(xx / (size - 1) * 255);
+        const g = Math.floor(yy / (size - 1) * 255);
+        const b = Math.floor(zz / (size - 1) * 255);
+        ctx.fillStyle = `rgb(${r},${g},${b})`;
+        ctx.fillRect(zz * size + xx, yy, 1, 1);
+      }
+    }
+  }
+  document.querySelector('#width').textContent = canvas.width;
+  document.querySelector('#height').textContent = canvas.height;
+}
+
+drawColorCubeImage(ctx, 8);
+```
+
+and we need a canvas 
+
+```html
+<canvas></canvas>
+```
+
+then we can generate a identity 3d lookup table for any size.
+
+{{{example url="../3dlut-base-cube-maker.html" }}}
+
+The larger the resolution the more fine adjustments we can make but being a cube of data the size required grows quickly. A size 8 cube only requires 2k but a size 64 cube requires 1meg. So use the smallest that reproduces the effect you want.
+
+Let's set the size to 16 and then click save the file which gives us this file.
+
+<div class="threejs_center"><img src="resources/images/identity-lut-s16.png"></div>
+
+We also need to capture an image of the thing we want to apply the LUT to, in this case the scene we created above before applying any effects. Note that normally we could right click on the scene above and pick "Save As..." but the `OrbitControls` might be preventing right clicking depnding on your OS. In my case I used my OSes screen capture feature to get a screenshot.
+
+<div class="threejs_center"><img src="resources/images/3dlut-screen-capture.jpg" style="width: 600px"></div>
+
+We then go it into an image editor, in my case Photoshop, load up the sample image, and paste the 3DLUT in the top left corner
+
+> note: I first tried dragging and dropping the lut file on top of the image
+> in Photoshop but that didn't work. Photoshop made the image twice a large.
+> I'm guessing it was trying to match DPI or something. Loading the lut file
+> separately and then copying and pasting it into the screen capture worked.
+
+<div class="threejs_center"><img src="resources/images/3dlut-photoshop-before.jpg" style="width: 600px"></div>
+
+We then use any of the color based full image adjustments to adjust the image. For Photoshop most of the adjustments we can use are available under the Image->Adjustments menu.
+
+<div class="threejs_center"><img src="resources/images/3dlut-photoshop-after.jpg" style="width: 600px"></div>
+
+After we've adjusted the image to our liking you can see the 3DLUT slices we placed in the top left corner have the same adjustments applied.
+
+Okay but how do we use it?
+
+First I saved it as a png `3dlut-red-only-s16.png`. To save memory we could have cropped it to just the 16x256 top left corner of the LUT table but just for fun we'll crop it after loading. The good thing about using this method is we can get some idea of the effective of the LUT just by looking at the .png file. The bad thing is of course wasted bandwidth.
+
+Here's some code to load it. The code starts with an identity lut so the texture is usable immediately. It then loads the image, copies out only the 3DLUT part into a canvas, gets the data from the canvas, set it on the texture and sets `needsUpdate` to true to tell THREE.js to get the new data.
+
+```js
+const makeLUTTexture = function() {
+  const imgLoader = new THREE.ImageLoader();
+  const ctx = document.createElement('canvas').getContext('2d');
+
+  return function(info) {
+    const texture = makeIdentityLutTexture(
+        info.filter ? THREE.LinearFilter : THREE.NearestFilter);
+
+    if (info.url) {
+      const lutSize = info.size;
+
+      // set the size to 2 (the identity size). We'll restore it when the
+      // image has loaded. This way the code using the lut doesn't have to
+      // care if the image has loaded or not
+      info.size = 2;
+
+      imgLoader.load(info.url, function(image) {
+        const width = lutSize * lutSize;
+        const height = lutSize;
+        info.size = lutSize;
+        ctx.canvas.width = width;
+        ctx.canvas.height = height;
+        ctx.drawImage(image, 0, 0);
+        const imageData = ctx.getImageData(0, 0, width, height);
+
+        texture.image.data = new Uint8Array(imageData.data.buffer);
+        texture.image.width = width;
+        texture.image.height = height;
+        texture.needsUpdate = true;
+      });
+    }
+
+    return texture;
+  };
+}();
+```
+
+Let's use it to load the lut png we just created.
+
+```js
+const lutTextures = [
+  { name: 'identity',           size: 2, filter: true , },
+  { name: 'identity no filter', size: 2, filter: false, },
++  { name: 'custom',          url: 'resources/images/lut/3dlut-red-only-s16.png' },
+];
+
++lutTextures.forEach((info) => {
++  // if not size set get it from the filename
++  if (!info.size) {
++    // assumes filename ends in '-s<num>[n]'
++    // where <num> is the size of the 3DLUT cube
++    // and [n] means 'no filtering' or 'nearest'
++    //
++    // examples:
++    //    'foo-s16.png' = size:16, filter: true
++    //    'bar-s8n.png' = size:8, filter: false
++    const m = /-s(\d+)(n*)\.[^.]+$/.exec(info.url);
++    if (m) {
++      info.size = parseInt(m[1]);
++      info.filter = info.filter === undefined ? m[2] !== 'n' : info.filter;
++    }
++  }
++
++  info.texture = makeLUTTexture(info);
++});
+```
+
+Above you can see we encoded the size of the LUT into the end of the filename. This makes it easier to pass around LUTs as pngs.
+
+While we're at it lets add a bunch more existing lut png files.
+
+```js
+const lutTextures = [
+  { name: 'identity',           size: 2, filter: true , },
+  { name: 'identity no filter', size: 2, filter: false, },
+  { name: 'custom',          url: 'resources/images/lut/3dlut-red-only-s16.png' },
++  { name: 'monochrome',      url: 'resources/images/lut/monochrome-s8.png' },
++  { name: 'sepia',           url: 'resources/images/lut/sepia-s8.png' },
++  { name: 'saturated',       url: 'resources/images/lut/saturated-s8.png', },
++  { name: 'posterize',       url: 'resources/images/lut/posterize-s8n.png', },
++  { name: 'posterize-3-rgb', url: 'resources/images/lut/posterize-3-rgb-s8n.png', },
++  { name: 'posterize-3-lab', url: 'resources/images/lut/posterize-3-lab-s8n.png', },
++  { name: 'posterize-4-lab', url: 'resources/images/lut/posterize-4-lab-s8n.png', },
++  { name: 'posterize-more',  url: 'resources/images/lut/posterize-more-s8n.png', },
++  { name: 'inverse',         url: 'resources/images/lut/inverse-s8.png', },
++  { name: 'color negative',  url: 'resources/images/lut/color-negative-s8.png', },
++  { name: 'high contrast',   url: 'resources/images/lut/high-contrast-bw-s8.png', },
++  { name: 'funky contrast',  url: 'resources/images/lut/funky-contrast-s8.png', },
++  { name: 'nightvision',     url: 'resources/images/lut/nightvision-s8.png', },
++  { name: 'thermal',         url: 'resources/images/lut/thermal-s8.png', },
++  { name: 'b/w',             url: 'resources/images/lut/black-white-s8n.png', },
++  { name: 'hue +60',         url: 'resources/images/lut/hue-plus-60-s8.png', },
++  { name: 'hue +180',        url: 'resources/images/lut/hue-plus-180-s8.png', },
++  { name: 'hue -60',         url: 'resources/images/lut/hue-minus-60-s8.png', },
++  { name: 'red to cyan',     url: 'resources/images/lut/red-to-cyan-s8.png' },
++  { name: 'blues',           url: 'resources/images/lut/blues-s8.png' },
++  { name: 'infrared',        url: 'resources/images/lut/infrared-s8.png' },
++  { name: 'radioactive',     url: 'resources/images/lut/radioactive-s8.png' },
++  { name: 'goolgey',         url: 'resources/images/lut/googley-s8.png' },
++  { name: 'bgy',             url: 'resources/images/lut/bgy-s8.png' },
+];
+```
+
+And here's a bunch of luts to choose from.
+
+{{{example url="../threejs-postprocessing-3dlut.html" }}}
+
+One last thing, just for fun, it turns out there's a standard LUT format defined by Adobe. If you [search on the net you can find lots of these LUT files](https://www.google.com/search?q=lut+files).
+
+I wrote a quick loader. Unfortunately there's 4 variations of the format but I could only find examples of 1 variation so I couldn't easily test that all variations work.
+
+I also write a quick drag and drop library. Let's use both to make it so you can drag and drop an Adobe LUT file to see it take affect.
+
+First we need the 2 libraries
+
+```html
+<script src="resources/lut-reader.js"></script>
+<script src="resources/drag-and-drop.js"></script>
+```
+
+Then we can use them like this
+
+```js
+dragAndDrop.setup({msg: 'Drop LUT File here'});
+dragAndDrop.onDropFile(readLUTFile);
+
+function readLUTFile(file) {
+  const reader = new FileReader();
+  reader.onload = (e) => {
+    const lut = lutParser.lutTo2D3Drgb8(lutParser.parse(e.target.result));
+    const {size, data, name} = lut;
+    const texture = new THREE.DataTexture(data, size * size, size, THREE.RGBFormat);
+    texture.minFilter = THREE.LinearFilter;
+    texture.needsUpdate = true;
+    texture.flipY = false;
+    const lutTexture = {
+      name: (name && name.toLowerCase().trim() !== 'untitled')
+          ? name
+          : file.name,
+      size: size,
+      filter: true,
+      texture,
+    };
+    lutTextures.push(lutTexture);
+    lutSettings.lut = lutTextures.length - 1;
+    updateGUI();
+  };
+
+  reader.readAsText(file);
+}
+```
+
+and we need to make the GUI update to include the new file(s)
+
+```js
+const lutSettings = {
+  lut: lutNameIndexMap.thermal,
+};
+const gui = new dat.GUI({ width: 300 });
+gui.addFolder('Choose LUT or Drag&Drop LUT File(s)');
+
+let lutGUI;
+function updateGUI() {
+  makeLutNameIndexMap();
+  if (lutGUI) {
+    gui.remove(lutGUI);
+  }
+  lutGUI = gui.add(lutSettings, 'lut', lutNameIndexMap);
+}
+updateGUI();
+```
+
+so you should be able to [download an Adobe LUT](https://www.google.com/search?q=lut+files) and then drag and drop it on the example below.
+
+{{{example url="../threejs-postprocessing-3dlut-w-loader.html" }}}
+
+Note that Adobe LUTs are not designed for online usage. They are large files. You can convert them to smaller files and save as our PNG format by dragging and dropping on the sample below, choosing a size and clicking "Save...".
+
+The sample below is just a modification of the code above. We only draw the background picture, no glTF file. That picture is the an identity lut image created from the script above. We then use the effect to apply whatever LUT file is loaded so the result is the image we'd need to reproduce the LUT file as a PNG.
+
+<script src="resources/threejs-post-processing-3dlut.js"></script>
+
+One thing completely skipped is how the shader itself works. Hopefully we can cover a little more GLSL in the future. For now, if you're curious, you can follow the links in the [post processing article](threejs-post-processing.html) as well as maybe [take a look at this video](https://www.youtube.com/watch?v=rfQ8rKGTVlg#t=24m30s).

+ 1 - 0
threejs/lessons/toc.html

@@ -13,6 +13,7 @@
     <li><a href="/threejs/lessons/threejs-multiple-scenes.html">Multiple Canvases, Multiple Scenes</a></li>    
     <li><a href="/threejs/lessons/threejs-picking.html">Picking Objects with the mouse</a></li>    
     <li><a href="/threejs/lessons/threejs-post-processing.html">Post Processing</a></li>    
+    <li><a href="/threejs/lessons/threejs-post-processing-3dlut.html">Applying a LUT File for effects</a></li>    
   </ul>
   <li>Tips</li>
   <ul>

+ 98 - 0
threejs/resources/drag-and-drop.js

@@ -0,0 +1,98 @@
+'use strict';
+
+(function(){
+  const handlers = {
+    onDropFile: () => {},
+  };
+
+  function setup(options) {
+    const html = `
+    <style>
+      .dragInfo {
+          position: fixed;
+          left: 0;
+          top: 0;
+          width: 100%;
+          height: 100%;
+          background: rgba(0, 0, 0, .9);
+          display: flex;
+          align-items: center;
+          justify-content: center;
+      }
+      .dragInfo>div {
+          padding: 1em;
+          background: blue;
+          color: white;
+          pointer-events: none;
+      }
+      .dragerror div {
+          background: red !important;
+          font-weight: bold;
+          color: white;
+      }
+    </style>
+    <div class="dragInfo" style="display: none;">
+      <div>
+         ${options.msg}
+      </div>
+    </div>
+    `;
+
+    const elem = document.createElement('div');
+    elem.innerHTML = html;
+    document.body.appendChild(elem);
+
+    const dragInfo = document.querySelector('.dragInfo');
+    function showDragInfo(show) {
+      dragInfo.style.display = show ? '' : 'none';
+    }
+
+    document.body.addEventListener('dragenter', () => {
+      showDragInfo(true);
+    });
+
+    const dragElem = dragInfo;
+
+    dragElem.addEventListener('dragover', (e) => {
+      e.preventDefault();
+      return false;
+    });
+
+    dragElem.addEventListener('dragleave', () => {
+      showDragInfo(false);
+      return false;
+    });
+
+    dragElem.addEventListener('dragend', () => {
+      showDragInfo(false);
+      return false;
+    });
+
+    dragElem.addEventListener('drop', (e) => {
+      e.preventDefault();
+      showDragInfo(false);
+      if (e.dataTransfer.items && e.dataTransfer.items) {
+        let fileNdx = 0;
+        for (let i = 0; i < e.dataTransfer.items.length; ++i) {
+          const item = e.dataTransfer.items[i];
+          if (item.kind === 'file') {
+            handlers.onDropFile(item.getAsFile(), fileNdx++);
+          }
+        }
+      }
+
+      return false;
+    });
+
+  }
+
+  function onDropFile(fn) {
+    handlers.onDropFile = fn;
+  }
+
+  window.dragAndDrop = {
+    setup,
+    onDropFile,
+  };
+
+}());

BIN
threejs/resources/images/beach.jpg


BIN
threejs/resources/images/lut/3dlut-red-only-s16.png


BIN
threejs/resources/images/lut/bgy-s8.png


BIN
threejs/resources/images/lut/black-white-s8n.png


BIN
threejs/resources/images/lut/blues-s8.png


BIN
threejs/resources/images/lut/color-negative-s8.png


BIN
threejs/resources/images/lut/default-s8.png


BIN
threejs/resources/images/lut/funky-contrast-s8.png


BIN
threejs/resources/images/lut/googley-s8.png


BIN
threejs/resources/images/lut/high-contrast-bw-s8.png


BIN
threejs/resources/images/lut/hue-minus-60-s8.png


BIN
threejs/resources/images/lut/hue-plus-180-s8.png


BIN
threejs/resources/images/lut/hue-plus-60-s8.png


BIN
threejs/resources/images/lut/infrared-s8.png


BIN
threejs/resources/images/lut/inverse-s8.png


BIN
threejs/resources/images/lut/monochrome-s8.png


BIN
threejs/resources/images/lut/nightvision-s8.png


BIN
threejs/resources/images/lut/posterize-3-lab-s8n.png


BIN
threejs/resources/images/lut/posterize-3-rgb-s8n.png


BIN
threejs/resources/images/lut/posterize-4-lab-s8n.png


BIN
threejs/resources/images/lut/posterize-more-s8n.png


BIN
threejs/resources/images/lut/posterize-s8n.png


BIN
threejs/resources/images/lut/radioactive-s8.png


BIN
threejs/resources/images/lut/red-to-cyan-s8.png


BIN
threejs/resources/images/lut/saturated-s8.png


BIN
threejs/resources/images/lut/sepia-s8.png


BIN
threejs/resources/images/lut/thermal-s8.png


+ 155 - 0
threejs/resources/lut-reader.js

@@ -0,0 +1,155 @@
+'use strict';
+
+(function() {
+
+  function splitOnSpaceHandleQuotesWithEscapes(str, splits = ' \t\n\r') {
+    const strs = [];
+    let quoteType;
+    let escape;
+    let s = [];
+    for (let i = 0; i < str.length; ++i) {
+      const c = str[i];
+      if (escape) {
+        escape = false;
+        s.push(c);
+      } else {
+        if (quoteType) {  // we're inside quotes
+          if (c === quoteType) {
+            quoteType = undefined;
+            strs.push(s.join(''));
+            s = [];
+          } else if (c === '\\') {
+            escape = true;
+          } else {
+            s.push(c);
+          }
+        } else {  // we're not in quotes
+          if (splits.indexOf(c) >= 0) {
+            if (s.length) {
+              strs.push(s.join(''));
+              s = [];
+            }
+          } else if (c === '"' || c === '\'') {
+            if (s.length) {  // its in th middle of a word
+              s.push(c);
+            } else {
+              quoteType = c;
+            }
+          } else {
+            s.push(c);
+          }
+        }
+      }
+    }
+    if (s.length || strs.length === 0) {
+      strs.push(s.join(''));
+    }
+    return strs;
+  }
+
+function parse(str) {
+  const data = [];
+  const lut = {
+    name: 'unknonw',
+    type: '1D',
+    size: 0,
+    data,
+    min: [0, 0, 0],
+    max: [1, 1, 1],
+  };
+
+  const lines = str.split('\n');
+  for (const origLine of lines) {
+    const hashNdx = origLine.indexOf('#');
+    const line = hashNdx >= 0 ? origLine.substring(0, hashNdx) : origLine;
+    const parts = splitOnSpaceHandleQuotesWithEscapes(line);
+    switch (parts[0].toUpperCase()) {
+      case 'TITLE':
+        lut.name = parts[1];
+        break;
+      case 'LUT_1D_SIZE':
+        lut.size = parseInt(parts[1]);
+        lut.type = '1D';
+        break;
+      case 'LUT_3D_SIZE':
+        lut.size = parseInt(parts[1]);
+        lut.type = '3D';
+        break;
+      case 'DOMAIN_MIN':
+        lut.min = parts.slice(1).map(parseFloat);
+        break;
+      case 'DOMAIN_MAX':
+        lut.max = parts.slice(1).map(parseFloat);
+        break;
+      default:
+        if (parts.length === 3) {
+          data.push(...parts.map(parseFloat));
+        }
+        break;
+    }
+  }
+
+  if (!lut.min) {
+    lut.min = data.slice(0, 3);
+    lut.max = data.slice(data.length - 3, data.length);
+  }
+
+  if (!lut.size) {
+    lut.size = data.length / 3;
+  }
+
+  return lut;
+}
+
+function lerp(a, b, t) {
+  return a + (b - a) * t;
+}
+
+function lut1Dto3D(lut) {
+  let src = lut.data;
+  if (src.length / 3 !== lut.size) {
+    src = [];
+    for (let i = 0; i < lut.size; ++i) {
+      const u = i / lut.size * lut.data.length;
+      const i0 = (u | 0) * 3;
+      const i1 = i0 + 3;
+      const t = u % 1;
+      src.push(
+        lerp(lut.data[i0 + 0], lut.data[i1 + 0], t),
+        lerp(lut.data[i0 + 0], lut.data[i1 + 1], t),
+        lerp(lut.data[i0 + 0], lut.data[i1 + 2], t),
+      );
+    }
+  }
+  const data = [];
+  for (let i = 0; i < lut.size * lut.size; ++i) {
+    data.push(...src);
+  }
+  return Object.assign({}, lut, {data});
+}
+
+function lutTo2D3Drgb8(lut) {
+  if (lut.type === '1D') {
+    lut = lut1Dto3D(lut);
+  }
+  const min = lut.min;
+  const max = lut.max;
+  const range = min.map((min, ndx) => {
+    return max[ndx] - min;
+  });
+  const src = lut.data;
+  const data = new Uint8Array(src.length);
+  for (let i = 0; i < src.length; i += 3) {
+    data[i + 0] = (src[i + 0] - min[0]) / range[0] * 255;
+    data[i + 1] = (src[i + 1] - min[1]) / range[1] * 255;
+    data[i + 2] = (src[i + 2] - min[2]) / range[2] * 255;
+  }
+  return Object.assign({}, lut, {data});
+}
+
+window.lutParser = {
+  parse,
+  lutTo2D3Drgb8,
+};
+
+}());

+ 8 - 0
threejs/resources/models/3dbustchallange_submission/license.md

@@ -0,0 +1,8 @@
+Link
+https://sketchfab.com/models/a1d315908e9f45e5a3bc618bdfd2e7ee
+
+Artist: The Ice Wolves
+https://sketchfab.com/sarath.irn.kat005
+
+Licence: CC-BY 4.0
+http://creativecommons.org/licenses/by/4.0/

BIN
threejs/resources/models/3dbustchallange_submission/scene.bin


+ 652 - 0
threejs/resources/models/3dbustchallange_submission/scene.gltf

@@ -0,0 +1,652 @@
+{
+  "accessors": [
+    {
+      "bufferView": 2,
+      "componentType": 5126,
+      "count": 1623,
+      "max": [
+        26.342103958129883,
+        44.458526611328125,
+        22.162557601928711
+      ],
+      "min": [
+        -26.342109680175781,
+        -49.368267059326172,
+        -23.254547119140625
+      ],
+      "type": "VEC3"
+    },
+    {
+      "bufferView": 2,
+      "byteOffset": 19476,
+      "componentType": 5126,
+      "count": 1623,
+      "max": [
+        0.99980086088180542,
+        0.99956494569778442,
+        0.99999696016311646
+      ],
+      "min": [
+        -0.99997776746749878,
+        -0.99999171495437622,
+        -0.99994689226150513
+      ],
+      "type": "VEC3"
+    },
+    {
+      "bufferView": 3,
+      "componentType": 5126,
+      "count": 1623,
+      "max": [
+        0.99999958276748657,
+        0.99989491701126099,
+        0.99940907955169678,
+        1
+      ],
+      "min": [
+        -0.95045214891433716,
+        -0.83363550901412964,
+        -0.99993044137954712,
+        -1
+      ],
+      "type": "VEC4"
+    },
+    {
+      "bufferView": 1,
+      "componentType": 5126,
+      "count": 1623,
+      "max": [
+        0.52699315547943115,
+        0.98908871412277222
+      ],
+      "min": [
+        0.0058180810883641243,
+        0.089957147836685181
+      ],
+      "type": "VEC2"
+    },
+    {
+      "bufferView": 1,
+      "byteOffset": 12984,
+      "componentType": 5126,
+      "count": 1623,
+      "max": [
+        0.52699315547943115,
+        0.98908871412277222
+      ],
+      "min": [
+        0.0058180810883641243,
+        0.089957147836685181
+      ],
+      "type": "VEC2"
+    },
+    {
+      "bufferView": 0,
+      "componentType": 5125,
+      "count": 9276,
+      "max": [
+        1622
+      ],
+      "min": [
+        0
+      ],
+      "type": "SCALAR"
+    },
+    {
+      "bufferView": 2,
+      "byteOffset": 38952,
+      "componentType": 5126,
+      "count": 1187,
+      "max": [
+        43.562625885009766,
+        51.257343292236328,
+        21.261653900146484
+      ],
+      "min": [
+        -43.562625885009766,
+        -71.628257751464844,
+        -68.547996520996094
+      ],
+      "type": "VEC3"
+    },
+    {
+      "bufferView": 2,
+      "byteOffset": 53196,
+      "componentType": 5126,
+      "count": 1187,
+      "max": [
+        0.9997563362121582,
+        0.99704116582870483,
+        0.99988639354705811
+      ],
+      "min": [
+        -0.9997563362121582,
+        -0.30853849649429321,
+        -0.99579799175262451
+      ],
+      "type": "VEC3"
+    },
+    {
+      "bufferView": 3,
+      "byteOffset": 25968,
+      "componentType": 5126,
+      "count": 1187,
+      "max": [
+        0.99999982118606567,
+        0.99770462512969971,
+        0.92844241857528687,
+        1
+      ],
+      "min": [
+        -0.99999982118606567,
+        -0.99113202095031738,
+        -0.94968277215957642,
+        -1
+      ],
+      "type": "VEC4"
+    },
+    {
+      "bufferView": 1,
+      "byteOffset": 25968,
+      "componentType": 5126,
+      "count": 1187,
+      "max": [
+        0.98774683475494385,
+        0.99285948276519775
+      ],
+      "min": [
+        0.0081828190013766289,
+        0.0088025014847517014
+      ],
+      "type": "VEC2"
+    },
+    {
+      "bufferView": 1,
+      "byteOffset": 35464,
+      "componentType": 5126,
+      "count": 1187,
+      "max": [
+        0.98774683475494385,
+        0.99285948276519775
+      ],
+      "min": [
+        0.0081828190013766289,
+        0.0088025014847517014
+      ],
+      "type": "VEC2"
+    },
+    {
+      "bufferView": 0,
+      "byteOffset": 37104,
+      "componentType": 5125,
+      "count": 5049,
+      "max": [
+        1186
+      ],
+      "min": [
+        0
+      ],
+      "type": "SCALAR"
+    },
+    {
+      "bufferView": 2,
+      "byteOffset": 67440,
+      "componentType": 5126,
+      "count": 402,
+      "max": [
+        10.582456588745117,
+        24.046548843383789,
+        14.727596282958984
+      ],
+      "min": [
+        -10.582456588745117,
+        16.288112640380859,
+        10.848380088806152
+      ],
+      "type": "VEC3"
+    },
+    {
+      "bufferView": 2,
+      "byteOffset": 72264,
+      "componentType": 5126,
+      "count": 402,
+      "max": [
+        0.9969174861907959,
+        0.99691706895828247,
+        1
+      ],
+      "min": [
+        -0.9969174861907959,
+        -0.99691760540008545,
+        0.078456476330757141
+      ],
+      "type": "VEC3"
+    },
+    {
+      "bufferView": 3,
+      "byteOffset": 44960,
+      "componentType": 5126,
+      "count": 402,
+      "max": [
+        0.99620389938354492,
+        0.29772281646728516,
+        0.99662953615188599,
+        1
+      ],
+      "min": [
+        -0.75902777910232544,
+        -0.82014578580856323,
+        -0.99662965536117554,
+        -1
+      ],
+      "type": "VEC4"
+    },
+    {
+      "bufferView": 1,
+      "byteOffset": 44960,
+      "componentType": 5126,
+      "count": 402,
+      "max": [
+        0.57162988185882568,
+        0.98086798191070557
+      ],
+      "min": [
+        0.019011896103620529,
+        0.34909945726394653
+      ],
+      "type": "VEC2"
+    },
+    {
+      "bufferView": 1,
+      "byteOffset": 48176,
+      "componentType": 5126,
+      "count": 402,
+      "max": [
+        0.57162988185882568,
+        0.98086798191070557
+      ],
+      "min": [
+        0.019011896103620529,
+        0.34909945726394653
+      ],
+      "type": "VEC2"
+    },
+    {
+      "bufferView": 0,
+      "byteOffset": 57300,
+      "componentType": 5125,
+      "count": 2280,
+      "max": [
+        401
+      ],
+      "min": [
+        0
+      ],
+      "type": "SCALAR"
+    },
+    {
+      "bufferView": 2,
+      "byteOffset": 77088,
+      "componentType": 5126,
+      "count": 657,
+      "max": [
+        86.216232299804688,
+        134.19537353515625,
+        18.238822937011719
+      ],
+      "min": [
+        -86.216232299804688,
+        19.359472274780273,
+        -7.2877330780029297
+      ],
+      "type": "VEC3"
+    },
+    {
+      "bufferView": 2,
+      "byteOffset": 84972,
+      "componentType": 5126,
+      "count": 657,
+      "max": [
+        0.99354755878448486,
+        0.93353867530822754,
+        1
+      ],
+      "min": [
+        -0.99354755878448486,
+        -0.26938742399215698,
+        -0.99995452165603638
+      ],
+      "type": "VEC3"
+    },
+    {
+      "bufferView": 3,
+      "byteOffset": 51392,
+      "componentType": 5126,
+      "count": 657,
+      "max": [
+        1,
+        0.99997246265411377,
+        0.93424397706985474,
+        1
+      ],
+      "min": [
+        -1,
+        -0.99772214889526367,
+        -0.15833774209022522,
+        -1
+      ],
+      "type": "VEC4"
+    },
+    {
+      "bufferView": 1,
+      "byteOffset": 51392,
+      "componentType": 5126,
+      "count": 657,
+      "max": [
+        0.98847508430480957,
+        0.99141353368759155
+      ],
+      "min": [
+        0.19082200527191162,
+        0.047508388757705688
+      ],
+      "type": "VEC2"
+    },
+    {
+      "bufferView": 1,
+      "byteOffset": 56648,
+      "componentType": 5126,
+      "count": 657,
+      "max": [
+        0.98847508430480957,
+        0.99141353368759155
+      ],
+      "min": [
+        0.19082200527191162,
+        0.047508388757705688
+      ],
+      "type": "VEC2"
+    },
+    {
+      "bufferView": 0,
+      "byteOffset": 66420,
+      "componentType": 5125,
+      "count": 2310,
+      "max": [
+        656
+      ],
+      "min": [
+        0
+      ],
+      "type": "SCALAR"
+    }
+  ],
+  "asset": {
+    "extras": {
+      "author": "The Ice Wolves (https://sketchfab.com/sarath.irn.kat005)",
+      "license": "CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)",
+      "source": "https://sketchfab.com/models/a1d315908e9f45e5a3bc618bdfd2e7ee",
+      "title": "3dBustChallange Submission"
+    },
+    "generator": "Sketchfab-4.1.5",
+    "version": "2.0"
+  },
+  "bufferViews": [
+    {
+      "buffer": 0,
+      "byteLength": 75660,
+      "byteOffset": 0,
+      "name": "floatBufferViews",
+      "target": 34963
+    },
+    {
+      "buffer": 0,
+      "byteLength": 61904,
+      "byteOffset": 75660,
+      "byteStride": 8,
+      "name": "floatBufferViews",
+      "target": 34962
+    },
+    {
+      "buffer": 0,
+      "byteLength": 92856,
+      "byteOffset": 137564,
+      "byteStride": 12,
+      "name": "floatBufferViews",
+      "target": 34962
+    },
+    {
+      "buffer": 0,
+      "byteLength": 61904,
+      "byteOffset": 230420,
+      "byteStride": 16,
+      "name": "floatBufferViews",
+      "target": 34962
+    }
+  ],
+  "buffers": [
+    {
+      "byteLength": 292324,
+      "uri": "scene.bin"
+    }
+  ],
+  "extensionsUsed": [
+    "KHR_materials_unlit"
+  ],
+  "images": [
+    {
+      "uri": "textures/lambert1_baseColor.png"
+    }
+  ],
+  "materials": [
+    {
+      "alphaMode": "BLEND",
+      "doubleSided": true,
+      "extensions": {
+        "KHR_materials_unlit": {}
+      },
+      "name": "lambert1",
+      "pbrMetallicRoughness": {
+        "baseColorFactor": [
+          1,
+          1,
+          1,
+          1
+        ],
+        "baseColorTexture": {
+          "index": 0,
+          "texCoord": 0
+        },
+        "metallicFactor": 0,
+        "roughnessFactor": 1
+      }
+    }
+  ],
+  "meshes": [
+    {
+      "name": "head_lambert1_0",
+      "primitives": [
+        {
+          "attributes": {
+            "NORMAL": 1,
+            "POSITION": 0,
+            "TANGENT": 2,
+            "TEXCOORD_0": 3,
+            "TEXCOORD_1": 4
+          },
+          "indices": 5,
+          "material": 0,
+          "mode": 4
+        }
+      ]
+    },
+    {
+      "name": "hair_lambert1_0",
+      "primitives": [
+        {
+          "attributes": {
+            "NORMAL": 7,
+            "POSITION": 6,
+            "TANGENT": 8,
+            "TEXCOORD_0": 9,
+            "TEXCOORD_1": 10
+          },
+          "indices": 11,
+          "material": 0,
+          "mode": 4
+        }
+      ]
+    },
+    {
+      "name": "eyes_lambert1_0",
+      "primitives": [
+        {
+          "attributes": {
+            "NORMAL": 13,
+            "POSITION": 12,
+            "TANGENT": 14,
+            "TEXCOORD_0": 15,
+            "TEXCOORD_1": 16
+          },
+          "indices": 17,
+          "material": 0,
+          "mode": 4
+        }
+      ]
+    },
+    {
+      "name": "crown_lambert1_0",
+      "primitives": [
+        {
+          "attributes": {
+            "NORMAL": 19,
+            "POSITION": 18,
+            "TANGENT": 20,
+            "TEXCOORD_0": 21,
+            "TEXCOORD_1": 22
+          },
+          "indices": 23,
+          "material": 0,
+          "mode": 4
+        }
+      ]
+    }
+  ],
+  "nodes": [
+    {
+      "children": [
+        1
+      ],
+      "name": "RootNode (gltf orientation matrix)",
+      "rotation": [
+        -0.70710678118654746,
+        -0,
+        -0,
+        0.70710678118654757
+      ]
+    },
+    {
+      "children": [
+        2
+      ],
+      "name": "RootNode (model correction matrix)"
+    },
+    {
+      "children": [
+        3
+      ],
+      "matrix": [
+        1,
+        0,
+        0,
+        0,
+        0,
+        0,
+        1,
+        0,
+        0,
+        -1,
+        0,
+        0,
+        0,
+        0,
+        0,
+        1
+      ],
+      "name": "a3eead2a076a4ac4800c4c309a3c180f.fbx"
+    },
+    {
+      "children": [
+        4,
+        6,
+        8,
+        10
+      ],
+      "name": "RootNode"
+    },
+    {
+      "children": [
+        5
+      ],
+      "name": "head"
+    },
+    {
+      "mesh": 0,
+      "name": "head_lambert1_0"
+    },
+    {
+      "children": [
+        7
+      ],
+      "name": "hair"
+    },
+    {
+      "mesh": 1,
+      "name": "hair_lambert1_0"
+    },
+    {
+      "children": [
+        9
+      ],
+      "name": "eyes"
+    },
+    {
+      "mesh": 2,
+      "name": "eyes_lambert1_0"
+    },
+    {
+      "children": [
+        11
+      ],
+      "name": "crown"
+    },
+    {
+      "mesh": 3,
+      "name": "crown_lambert1_0"
+    }
+  ],
+  "samplers": [
+    {
+      "magFilter": 9729,
+      "minFilter": 9987,
+      "wrapS": 10497,
+      "wrapT": 10497
+    }
+  ],
+  "scene": 0,
+  "scenes": [
+    {
+      "name": "OSG_Scene",
+      "nodes": [
+        0
+      ]
+    }
+  ],
+  "textures": [
+    {
+      "sampler": 0,
+      "source": 0
+    }
+  ]
+}
+

BIN
threejs/resources/models/3dbustchallange_submission/textures/lambert1_baseColor-orig.png


BIN
threejs/resources/models/3dbustchallange_submission/textures/lambert1_baseColor.png


+ 305 - 0
threejs/threejs-postprocessing-3dlut-identity.html

@@ -0,0 +1,305 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <title>Three.js - postprocessing - 3DLUT</title>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+    <style>
+    html, body {
+        margin: 0;
+        height: 100%;
+    }
+    #c {
+        width: 100%;
+        height: 100%;
+        display: block;
+    }
+  </style>
+  </head>
+  <body>
+    <canvas id="c"></canvas>
+  </body>
+<script src="resources/threejs/r98/three.js"></script>
+<script src="resources/threejs/r98/js/controls/OrbitControls.js"></script>
+<script src="resources/threejs/r98/js/loaders/GLTFLoader.js"></script>
+<script src="resources/threejs/r98/js/shaders/CopyShader.js"></script>
+<script src="resources/threejs/r98/js/postprocessing/EffectComposer.js"></script>
+<script src="resources/threejs/r98/js/postprocessing/RenderPass.js"></script>
+<script src="resources/threejs/r98/js/postprocessing/ShaderPass.js"></script>
+<script src="../3rdparty/dat.gui.min.js"></script>
+<script>
+'use strict';
+
+/* global THREE, dat */
+
+function main() {
+  const canvas = document.querySelector('#c');
+  const renderer = new THREE.WebGLRenderer({canvas: canvas});
+
+  const fov = 45;
+  const aspect = 2;  // the canvas default
+  const near = 0.1;
+  const far = 100;
+  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
+  camera.position.set(0, 10, 20);
+
+  const controls = new THREE.OrbitControls(camera, canvas);
+  controls.target.set(0, 5, 0);
+  controls.update();
+
+  const makeIdentityLutTexture = function() {
+    const identityLUT = new Uint8Array([
+        0,   0,   0, 255,  // black
+      255,   0,   0, 255,  // red
+        0,   0, 255, 255,  // blue
+      255,   0, 255, 255,  // magenta
+        0, 255,   0, 255,  // green
+      255, 255,   0, 255,  // yellow
+        0, 255, 255, 255,  // cyan
+      255, 255, 255, 255,  // white
+    ]);
+
+    return function(filter) {
+      const texture = new THREE.DataTexture(identityLUT, 4, 2, THREE.RGBAFormat);
+      texture.minFilter = filter;
+      texture.magFilter = filter;
+      texture.needsUpdate = true;
+      texture.flipY = false;
+      return texture;
+    };
+  }();
+
+  const lutTextures = [
+    {
+      name: 'identity',
+      size: 2,
+      filter: true,
+      texture: makeIdentityLutTexture(THREE.LinearFilter),
+    },
+    {
+      name: 'identity not filtered',
+      size: 2,
+      filter: false,
+      texture: makeIdentityLutTexture(THREE.NearestFilter),
+    },
+  ];
+
+  const lutNameIndexMap = {};
+  lutTextures.forEach((info, ndx) => {
+    lutNameIndexMap[info.name] = ndx;
+  });
+
+  const lutSettings = {
+    lut: lutNameIndexMap.identity,
+  };
+  const gui = new dat.GUI({ width: 300 });
+  gui.add(lutSettings, 'lut', lutNameIndexMap);
+
+  const scene = new THREE.Scene();
+
+  const sceneBG = new THREE.Scene();
+  const cameraBG = new THREE.OrthographicCamera(-1, 1, 1, -1, -1, 1);
+
+  let bgMesh;
+  let bgTexture;
+  {
+    const loader = new THREE.TextureLoader();
+    bgTexture = loader.load('resources/images/beach.jpg');
+    const planeGeo = new THREE.PlaneBufferGeometry(2, 2);
+    const planeMat = new THREE.MeshBasicMaterial({
+      map: bgTexture,
+      depthTest: false,
+    });
+    bgMesh = new THREE.Mesh(planeGeo, planeMat);
+    sceneBG.add(bgMesh);
+  }
+
+  function frameArea(sizeToFitOnScreen, boxSize, boxCenter, camera) {
+    const halfSizeToFitOnScreen = sizeToFitOnScreen * 0.5;
+    const halfFovY = THREE.Math.degToRad(camera.fov * .5);
+    const distance = halfSizeToFitOnScreen / Math.tan(halfFovY);
+    // compute a unit vector that points in the direction the camera is now
+    // in the xz plane from the center of the box
+    const direction = (new THREE.Vector3())
+        .subVectors(camera.position, boxCenter)
+        .multiply(new THREE.Vector3(1, 0, 1))
+        .normalize();
+
+    // move the camera to a position distance units way from the center
+    // in whatever direction the camera was from the center already
+    camera.position.copy(direction.multiplyScalar(distance).add(boxCenter));
+
+    // pick some near and far values for the frustum that
+    // will contain the box.
+    camera.near = boxSize / 100;
+    camera.far = boxSize * 100;
+
+    camera.updateProjectionMatrix();
+
+    // point the camera to look at the center of the box
+    camera.lookAt(boxCenter.x, boxCenter.y, boxCenter.z);
+  }
+
+  {
+    const gltfLoader = new THREE.GLTFLoader();
+    gltfLoader.load('resources/models/3dbustchallange_submission/scene.gltf', (gltf) => {
+      const root = gltf.scene;
+      scene.add(root);
+
+      root.updateMatrixWorld();
+      // compute the box that contains all the stuff
+      // from root and below
+      const box = new THREE.Box3().setFromObject(root);
+
+      const boxSize = box.getSize(new THREE.Vector3()).length();
+      const boxCenter = box.getCenter(new THREE.Vector3());
+      frameArea(boxSize * 0.4, boxSize, boxCenter, camera);
+
+      // update the Trackball controls to handle the new size
+      controls.maxDistance = boxSize * 10;
+      controls.target.copy(boxCenter);
+      controls.update();
+    });
+  }
+
+  const lutShader = {
+    uniforms: {
+      tDiffuse: { value: null },  // the previous pass's result
+      lutMap:  { value: null },
+      lutMapSize: { value: 1, },
+    },
+    vertexShader: `
+      varying vec2 vUv;
+      void main() {
+        vUv = uv;
+        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+      }
+    `,
+    fragmentShader: `
+      #include <common>
+
+      #define FILTER_LUT true
+
+      uniform sampler2D tDiffuse;
+      uniform sampler2D lutMap;
+      uniform float lutMapSize;
+
+      varying vec2 vUv;
+
+      vec4 sampleAs3DTexture(sampler2D tex, vec3 texCoord, float size) {
+        float sliceSize = 1.0 / size;                  // space of 1 slice
+        float slicePixelSize = sliceSize / size;       // space of 1 pixel
+        float width = size - 1.0;
+        float sliceInnerSize = slicePixelSize * width; // space of size pixels
+        float zSlice0 = floor( texCoord.z * width);
+        float zSlice1 = min( zSlice0 + 1.0, width);
+        float xOffset = slicePixelSize * 0.5 + texCoord.x * sliceInnerSize;
+        float yRange = (texCoord.y * width + 0.5) / size;
+        float s0 = xOffset + (zSlice0 * sliceSize);
+
+        #ifdef FILTER_LUT
+
+          float s1 = xOffset + (zSlice1 * sliceSize);
+          vec4 slice0Color = texture2D(tex, vec2(s0, yRange));
+          vec4 slice1Color = texture2D(tex, vec2(s1, yRange));
+          float zOffset = mod(texCoord.z * width, 1.0);
+          return mix(slice0Color, slice1Color, zOffset);
+
+        #else
+
+          return texture2D(tex, vec2( s0, yRange));
+
+        #endif
+      }
+
+      void main() {
+        vec4 originalColor = texture2D(tDiffuse, vUv);
+        gl_FragColor = sampleAs3DTexture(lutMap, originalColor.xyz, lutMapSize);
+      }
+    `,
+  };
+
+  const lutNearestShader = {
+    uniforms: Object.assign( {}, lutShader.uniforms ),
+    vertexShader: lutShader.vertexShader,
+    fragmentShader: lutShader.fragmentShader.replace('#define FILTER_LUT', '//'),
+  };
+
+  const effectLUT = new THREE.ShaderPass(lutShader);
+  effectLUT.renderToScreen = true;
+  const effectLUTNearest = new THREE.ShaderPass(lutNearestShader);
+  effectLUTNearest.renderToScreen = true;
+
+  const renderModel = new THREE.RenderPass(scene, camera);
+  renderModel.clear = false;  // so we don't clear out the background
+  const renderBG = new THREE.RenderPass(sceneBG, cameraBG);
+
+  renderModel.clear = false;
+
+  const rtParameters = {
+    minFilter: THREE.LinearFilter,
+    magFilter: THREE.LinearFilter,
+    format: THREE.RGBFormat,
+  };
+  const composer = new THREE.EffectComposer(renderer, new THREE.WebGLRenderTarget(1, 1, rtParameters));
+
+  composer.addPass(renderBG);
+  composer.addPass(renderModel);
+  composer.addPass(effectLUT);
+  composer.addPass(effectLUTNearest);
+
+  function resizeRendererToDisplaySize(renderer) {
+    const canvas = renderer.domElement;
+    const width = canvas.clientWidth * window.devicePixelRatio | 0;
+    const height = canvas.clientHeight * window.devicePixelRatio | 0;
+
+    const needResize = canvas.width !== width || canvas.height !== height;
+    if (needResize) {
+      renderer.setSize(width, height, false);
+    }
+    return needResize;
+  }
+
+  let then = 0;
+  function render(now) {
+    now *= 0.001;  // convert to seconds
+    const delta = now - then;
+    then = now;
+
+    if (resizeRendererToDisplaySize(renderer)) {
+      const canvas = renderer.domElement;
+      const canvasAspect = canvas.clientWidth / canvas.clientHeight;
+      camera.aspect = canvasAspect;
+      camera.updateProjectionMatrix();
+      composer.setSize(canvas.width, canvas.height);
+
+      // scale the background plane to keep the image's
+      // aspect correct.
+      // Note the image may not have loaded yet.
+      const imageAspect = bgTexture.image ? bgTexture.image.width / bgTexture.image.height : 1;
+      const aspect = imageAspect / canvasAspect;
+      bgMesh.scale.x = aspect > 1 ? aspect : 1;
+      bgMesh.scale.y = aspect > 1 ? 1 : 1 / aspect;
+    }
+
+    const lutInfo = lutTextures[lutSettings.lut];
+
+    const effect = lutInfo.filter ? effectLUT : effectLUTNearest;
+    effectLUT.enabled = lutInfo.filter;
+    effectLUTNearest.enabled = !lutInfo.filter;
+
+    const lutTexture = lutInfo.texture;
+    effect.uniforms.lutMap.value = lutTexture;
+    effect.uniforms.lutMapSize.value = lutInfo.size;
+
+    composer.render(delta);
+
+    requestAnimationFrame(render);
+  }
+
+  requestAnimationFrame(render);
+}
+
+main();
+</script>
+</html>

+ 154 - 0
threejs/threejs-postprocessing-3dlut-prep.html

@@ -0,0 +1,154 @@
+<!-- Licensed under a BSD license. See license.html for license -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
+    <title>Three.js - Post Processing 3DLUT (not) - prep</title>
+    <style>
+    html, body {
+        margin: 0;
+        height: 100%;
+    }
+    #c {
+        width: 100%;
+        height: 100%;
+        display: block;
+    }
+    </style>
+  </head>
+  <body>
+    <canvas id="c"></canvas>
+  </body>
+<script src="resources/threejs/r94/three.js"></script>
+<script src="resources/threejs/r94/js/controls/OrbitControls.js"></script>
+<script src="resources/threejs/r94/js/loaders/GLTFLoader.js"></script>
+<script>
+'use strict';
+
+/* global THREE */
+
+function main() {
+  const canvas = document.querySelector('#c');
+  const renderer = new THREE.WebGLRenderer({canvas: canvas});
+  renderer.autoClearColor = false;
+
+  const fov = 45;
+  const aspect = 2;  // the canvas default
+  const near = 0.1;
+  const far = 100;
+  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
+  camera.position.set(0, 10, 20);
+
+  const controls = new THREE.OrbitControls(camera, canvas);
+  controls.target.set(0, 5, 0);
+  controls.update();
+
+  const scene = new THREE.Scene();
+
+  const sceneBG = new THREE.Scene();
+  const cameraBG = new THREE.OrthographicCamera(-1, 1, 1, -1, -1, 1);
+
+  let bgMesh;
+  let bgTexture;
+  {
+    const loader = new THREE.TextureLoader();
+    bgTexture = loader.load('resources/images/beach.jpg');
+    const planeGeo = new THREE.PlaneBufferGeometry(2, 2);
+    const planeMat = new THREE.MeshBasicMaterial({
+      map: bgTexture,
+      depthTest: false,
+    });
+    bgMesh = new THREE.Mesh(planeGeo, planeMat);
+    sceneBG.add(bgMesh);
+  }
+
+  function frameArea(sizeToFitOnScreen, boxSize, boxCenter, camera) {
+    const halfSizeToFitOnScreen = sizeToFitOnScreen * 0.5;
+    const halfFovY = THREE.Math.degToRad(camera.fov * .5);
+    const distance = halfSizeToFitOnScreen / Math.tan(halfFovY);
+    // compute a unit vector that points in the direction the camera is now
+    // in the xz plane from the center of the box
+    const direction = (new THREE.Vector3())
+        .subVectors(camera.position, boxCenter)
+        .multiply(new THREE.Vector3(1, 0, 1))
+        .normalize();
+
+    // move the camera to a position distance units way from the center
+    // in whatever direction the camera was from the center already
+    camera.position.copy(direction.multiplyScalar(distance).add(boxCenter));
+
+    // pick some near and far values for the frustum that
+    // will contain the box.
+    camera.near = boxSize / 100;
+    camera.far = boxSize * 100;
+
+    camera.updateProjectionMatrix();
+
+    // point the camera to look at the center of the box
+    camera.lookAt(boxCenter.x, boxCenter.y, boxCenter.z);
+  }
+
+  {
+    const gltfLoader = new THREE.GLTFLoader();
+    gltfLoader.load('resources/models/3dbustchallange_submission/scene.gltf', (gltf) => {
+      const root = gltf.scene;
+      scene.add(root);
+
+      // compute the box that contains all the stuff
+      // from root and below
+      const box = new THREE.Box3().setFromObject(root);
+
+      const boxSize = box.getSize(new THREE.Vector3()).length();
+      const boxCenter = box.getCenter(new THREE.Vector3());
+
+      // set the camera to frame the box
+      frameArea(boxSize * 0.4, boxSize, boxCenter, camera);
+
+      // update the Trackball controls to handle the new size
+      controls.maxDistance = boxSize * 10;
+      controls.target.copy(boxCenter);
+      controls.update();
+    });
+  }
+
+  function resizeRendererToDisplaySize(renderer) {
+    const canvas = renderer.domElement;
+    const width = canvas.clientWidth;
+    const height = canvas.clientHeight;
+    const needResize = canvas.width !== width || canvas.height !== height;
+    if (needResize) {
+      renderer.setSize(width, height, false);
+    }
+    return needResize;
+  }
+
+  function render() {
+    if (resizeRendererToDisplaySize(renderer)) {
+      const canvas = renderer.domElement;
+      const canvasAspect = canvas.clientWidth / canvas.clientHeight;
+      camera.aspect = canvasAspect;
+      camera.updateProjectionMatrix();
+
+      // scale the background plane to keep the image's
+      // aspect correct.
+      // Note the image may not have loaded yet.
+      const imageAspect = bgTexture.image ? bgTexture.image.width / bgTexture.image.height : 1;
+      const aspect = imageAspect / canvasAspect;
+      bgMesh.scale.x = aspect > 1 ? aspect : 1;
+      bgMesh.scale.y = aspect > 1 ? 1 : 1 / aspect;
+    }
+
+    renderer.render(sceneBG, cameraBG);
+    renderer.render(scene, camera);
+
+    requestAnimationFrame(render);
+  }
+
+  requestAnimationFrame(render);
+}
+
+main();
+</script>
+</html>
+

+ 421 - 0
threejs/threejs-postprocessing-3dlut-w-loader.html

@@ -0,0 +1,421 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <title>Three.js - postprocessing - 3DLUT w/loader</title>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+    <style>
+    html, body {
+        margin: 0;
+        height: 100%;
+    }
+    #c {
+        width: 100%;
+        height: 100%;
+        display: block;
+    }
+  </style>
+  </head>
+  <body>
+    <canvas id="c"></canvas>
+  </body>
+<script src="resources/threejs/r98/three.js"></script>
+<script src="resources/threejs/r98/js/controls/OrbitControls.js"></script>
+<script src="resources/threejs/r98/js/loaders/GLTFLoader.js"></script>
+<script src="resources/threejs/r98/js/shaders/CopyShader.js"></script>
+<script src="resources/threejs/r98/js/postprocessing/EffectComposer.js"></script>
+<script src="resources/threejs/r98/js/postprocessing/RenderPass.js"></script>
+<script src="resources/threejs/r98/js/postprocessing/ShaderPass.js"></script>
+<script src="../3rdparty/dat.gui.min.js"></script>
+<script src="resources/lut-reader.js"></script>
+<script src="resources/drag-and-drop.js"></script>
+<script>
+'use strict';
+
+/* global THREE, dat, dragAndDrop, lutParser */
+
+function main() {
+  const canvas = document.querySelector('#c');
+  const renderer = new THREE.WebGLRenderer({canvas: canvas});
+
+  const fov = 45;
+  const aspect = 2;  // the canvas default
+  const near = 0.1;
+  const far = 100;
+  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
+  camera.position.set(0, 10, 20);
+
+  const controls = new THREE.OrbitControls(camera, canvas);
+  controls.target.set(0, 5, 0);
+  controls.update();
+
+  const lutTextures = [
+    { name: 'identity',           size: 2, filter: true , },
+    { name: 'identity no filter', size: 2, filter: false, },
+    { name: 'custom',          url: 'resources/images/lut/3dlut-red-only-s16.png' },
+    { name: 'monochrome',      url: 'resources/images/lut/monochrome-s8.png' },
+    { name: 'sepia',           url: 'resources/images/lut/sepia-s8.png' },
+    { name: 'saturated',       url: 'resources/images/lut/saturated-s8.png', },
+    { name: 'posterize',       url: 'resources/images/lut/posterize-s8n.png', },
+    { name: 'posterize-3-rgb', url: 'resources/images/lut/posterize-3-rgb-s8n.png', },
+    { name: 'posterize-3-lab', url: 'resources/images/lut/posterize-3-lab-s8n.png', },
+    { name: 'posterize-4-lab', url: 'resources/images/lut/posterize-4-lab-s8n.png', },
+    { name: 'posterize-more',  url: 'resources/images/lut/posterize-more-s8n.png', },
+    { name: 'inverse',         url: 'resources/images/lut/inverse-s8.png', },
+    { name: 'color negative',  url: 'resources/images/lut/color-negative-s8.png', },
+    { name: 'high contrast',   url: 'resources/images/lut/high-contrast-bw-s8.png', },
+    { name: 'funky contrast',  url: 'resources/images/lut/funky-contrast-s8.png', },
+    { name: 'nightvision',     url: 'resources/images/lut/nightvision-s8.png', },
+    { name: 'thermal',         url: 'resources/images/lut/thermal-s8.png', },
+    { name: 'b/w',             url: 'resources/images/lut/black-white-s8n.png', },
+    { name: 'hue +60',         url: 'resources/images/lut/hue-plus-60-s8.png', },
+    { name: 'hue +180',        url: 'resources/images/lut/hue-plus-180-s8.png', },
+    { name: 'hue -60',         url: 'resources/images/lut/hue-minus-60-s8.png', },
+    { name: 'red to cyan',     url: 'resources/images/lut/red-to-cyan-s8.png' },
+    { name: 'blues',           url: 'resources/images/lut/blues-s8.png' },
+    { name: 'infrared',        url: 'resources/images/lut/infrared-s8.png' },
+    { name: 'radioactive',     url: 'resources/images/lut/radioactive-s8.png' },
+    { name: 'goolgey',         url: 'resources/images/lut/googley-s8.png' },
+    { name: 'bgy',             url: 'resources/images/lut/bgy-s8.png' },
+  ];
+
+  const makeIdentityLutTexture = function() {
+    const identityLUT = new Uint8Array([
+        0,   0,   0, 255,  // black
+      255,   0,   0, 255,  // red
+        0,   0, 255, 255,  // blue
+      255,   0, 255, 255,  // magenta
+        0, 255,   0, 255,  // green
+      255, 255,   0, 255,  // yellow
+        0, 255, 255, 255,  // cyan
+      255, 255, 255, 255,  // white
+    ]);
+
+    return function(filter) {
+      const texture = new THREE.DataTexture(identityLUT, 4, 2, THREE.RGBAFormat);
+      texture.minFilter = filter;
+      texture.magFilter = filter;
+      texture.needsUpdate = true;
+      texture.flipY = false;
+      return texture;
+    };
+  }();
+
+  const makeLUTTexture = function() {
+    const imgLoader = new THREE.ImageLoader();
+    const ctx = document.createElement('canvas').getContext('2d');
+
+    return function(info) {
+      const texture = makeIdentityLutTexture(
+          info.filter ? THREE.LinearFilter : THREE.NearestFilter);
+
+      if (info.url) {
+        const lutSize = info.size;
+
+        // set the size to 2 (the identity size). We'll restore it when the
+        // image has loaded. This way the code using the lut doesn't have to
+        // care if the image has loaded or not
+        info.size = 2;
+
+        imgLoader.load(info.url, function(image) {
+          const width = lutSize * lutSize;
+          const height = lutSize;
+          info.size = lutSize;
+          ctx.canvas.width = width;
+          ctx.canvas.height = height;
+          ctx.drawImage(image, 0, 0);
+          const imageData = ctx.getImageData(0, 0, width, height);
+
+          texture.image.data = new Uint8Array(imageData.data.buffer);
+          texture.image.width = width;
+          texture.image.height = height;
+          texture.needsUpdate = true;
+        });
+      }
+
+      return texture;
+    };
+  }();
+
+
+  lutTextures.forEach((info) => {
+    // if not size set get it from the filename
+    if (!info.size) {
+      // assumes filename ends in '-s<num>[n]'
+      // where <num> is the size of the 3DLUT cube
+      // and [n] means 'no filtering' or 'nearest'
+      //
+      // examples:
+      //    'foo-s16.png' = size:16, filter: true
+      //    'bar-s8n.png' = size:8, filter: false
+      const m = /-s(\d+)(n*)\.[^.]+$/.exec(info.url);
+      if (m) {
+        info.size = parseInt(m[1]);
+        info.filter = info.filter === undefined ? m[2] !== 'n' : info.filter;
+      }
+    }
+
+    info.texture = makeLUTTexture(info);
+  });
+
+  let lutNameIndexMap = {};
+  function makeLutNameIndexMap() {
+    lutNameIndexMap = {};
+    lutTextures.forEach((info, ndx) => {
+      lutNameIndexMap[info.name] = ndx;
+    });
+  }
+  makeLutNameIndexMap();  // called so we can set lutSettings below
+
+  const lutSettings = {
+    dummy: () => {},
+    lut: lutNameIndexMap.thermal,
+  };
+  const gui = new dat.GUI({ width: 300 });
+  gui.addFolder('Choose LUT or Drag&Drop LUT File(s)');
+
+  let lutGUI;
+  function updateGUI() {
+    makeLutNameIndexMap();
+    if (lutGUI) {
+      gui.remove(lutGUI);
+    }
+    lutGUI = gui.add(lutSettings, 'lut', lutNameIndexMap);
+  }
+  updateGUI();
+
+  const scene = new THREE.Scene();
+
+  const sceneBG = new THREE.Scene();
+  const cameraBG = new THREE.OrthographicCamera(-1, 1, 1, -1, -1, 1);
+
+  let bgMesh;
+  let bgTexture;
+  {
+    const loader = new THREE.TextureLoader();
+    bgTexture = loader.load('resources/images/beach.jpg');
+    const planeGeo = new THREE.PlaneBufferGeometry(2, 2);
+    const planeMat = new THREE.MeshBasicMaterial({
+      map: bgTexture,
+      depthTest: false,
+    });
+    bgMesh = new THREE.Mesh(planeGeo, planeMat);
+    sceneBG.add(bgMesh);
+  }
+
+  function frameArea(sizeToFitOnScreen, boxSize, boxCenter, camera) {
+    const halfSizeToFitOnScreen = sizeToFitOnScreen * 0.5;
+    const halfFovY = THREE.Math.degToRad(camera.fov * .5);
+    const distance = halfSizeToFitOnScreen / Math.tan(halfFovY);
+    // compute a unit vector that points in the direction the camera is now
+    // in the xz plane from the center of the box
+    const direction = (new THREE.Vector3())
+        .subVectors(camera.position, boxCenter)
+        .multiply(new THREE.Vector3(1, 0, 1))
+        .normalize();
+
+    // move the camera to a position distance units way from the center
+    // in whatever direction the camera was from the center already
+    camera.position.copy(direction.multiplyScalar(distance).add(boxCenter));
+
+    // pick some near and far values for the frustum that
+    // will contain the box.
+    camera.near = boxSize / 100;
+    camera.far = boxSize * 100;
+
+    camera.updateProjectionMatrix();
+
+    // point the camera to look at the center of the box
+    camera.lookAt(boxCenter.x, boxCenter.y, boxCenter.z);
+  }
+
+  {
+    const gltfLoader = new THREE.GLTFLoader();
+    gltfLoader.load('resources/models/3dbustchallange_submission/scene.gltf', (gltf) => {
+      const root = gltf.scene;
+      scene.add(root);
+
+      root.updateMatrixWorld();
+      // compute the box that contains all the stuff
+      // from root and below
+      const box = new THREE.Box3().setFromObject(root);
+
+      const boxSize = box.getSize(new THREE.Vector3()).length();
+      const boxCenter = box.getCenter(new THREE.Vector3());
+      frameArea(boxSize * 0.4, boxSize, boxCenter, camera);
+
+      // update the Trackball controls to handle the new size
+      controls.maxDistance = boxSize * 10;
+      controls.target.copy(boxCenter);
+      controls.update();
+    });
+  }
+
+  const lutShader = {
+    uniforms: {
+      tDiffuse: { value: null },
+      lutMap:  { value: null },
+      lutMapSize: { value: 1, },
+    },
+    vertexShader: `
+      varying vec2 vUv;
+      void main() {
+        vUv = uv;
+        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+      }
+    `,
+    fragmentShader: `
+      #include <common>
+
+      #define FILTER_LUT true
+
+      uniform sampler2D tDiffuse;
+      uniform sampler2D lutMap;
+      uniform float lutMapSize;
+
+      varying vec2 vUv;
+
+      vec4 sampleAs3DTexture(sampler2D tex, vec3 texCoord, float size) {
+        float sliceSize = 1.0 / size;                  // space of 1 slice
+        float slicePixelSize = sliceSize / size;       // space of 1 pixel
+        float width = size - 1.0;
+        float sliceInnerSize = slicePixelSize * width; // space of size pixels
+        float zSlice0 = floor( texCoord.z * width);
+        float zSlice1 = min( zSlice0 + 1.0, width);
+        float xOffset = slicePixelSize * 0.5 + texCoord.x * sliceInnerSize;
+        float yRange = (texCoord.y * width + 0.5) / size;
+        float s0 = xOffset + (zSlice0 * sliceSize);
+
+        #ifdef FILTER_LUT
+
+          float s1 = xOffset + (zSlice1 * sliceSize);
+          vec4 slice0Color = texture2D(tex, vec2(s0, yRange));
+          vec4 slice1Color = texture2D(tex, vec2(s1, yRange));
+          float zOffset = mod(texCoord.z * width, 1.0);
+          return mix(slice0Color, slice1Color, zOffset);
+
+        #else
+
+          return texture2D(tex, vec2( s0, yRange));
+
+        #endif
+      }
+
+      void main() {
+        vec4 originalColor = texture2D(tDiffuse, vUv);
+        gl_FragColor = sampleAs3DTexture(lutMap, originalColor.xyz, lutMapSize);
+      }
+    `,
+  };
+
+  const lutNearestShader = {
+    uniforms: Object.assign( {}, lutShader.uniforms ),
+    vertexShader: lutShader.vertexShader,
+    fragmentShader: lutShader.fragmentShader.replace('#define FILTER_LUT', '//'),
+  };
+
+  const effectLUT = new THREE.ShaderPass(lutShader);
+  effectLUT.renderToScreen = true;
+  const effectLUTNearest = new THREE.ShaderPass(lutNearestShader);
+  effectLUTNearest.renderToScreen = true;
+
+  const renderModel = new THREE.RenderPass(scene, camera);
+  renderModel.clear = false;  // so we don't clear out the background
+  const renderBG = new THREE.RenderPass(sceneBG, cameraBG);
+
+  const rtParameters = {
+    minFilter: THREE.LinearFilter,
+    magFilter: THREE.LinearFilter,
+    format: THREE.RGBFormat,
+  };
+  const composer = new THREE.EffectComposer(renderer, new THREE.WebGLRenderTarget(1, 1, rtParameters));
+
+  composer.addPass(renderBG);
+  composer.addPass(renderModel);
+  composer.addPass(effectLUT);
+  composer.addPass(effectLUTNearest);
+
+  function resizeRendererToDisplaySize(renderer) {
+    const canvas = renderer.domElement;
+    const width = canvas.clientWidth * window.devicePixelRatio | 0;
+    const height = canvas.clientHeight * window.devicePixelRatio | 0;
+
+    const needResize = canvas.width !== width || canvas.height !== height;
+    if (needResize) {
+      renderer.setSize(width, height, false);
+    }
+    return needResize;
+  }
+
+  let then = 0;
+  function render(now) {
+    now *= 0.001;  // convert to seconds
+    const delta = now - then;
+    then = now;
+
+    if (resizeRendererToDisplaySize(renderer)) {
+      const canvas = renderer.domElement;
+      const canvasAspect = canvas.clientWidth / canvas.clientHeight;
+      camera.aspect = canvasAspect;
+      camera.updateProjectionMatrix();
+      composer.setSize(canvas.width, canvas.height);
+
+      // scale the background plane to keep the image's
+      // aspect correct.
+      // Note the image may not have loaded yet.
+      const imageAspect = bgTexture.image ? bgTexture.image.width / bgTexture.image.height : 1;
+      const aspect = imageAspect / canvasAspect;
+      bgMesh.scale.x = aspect > 1 ? aspect : 1;
+      bgMesh.scale.y = aspect > 1 ? 1 : 1 / aspect;
+    }
+
+    const lutInfo = lutTextures[ lutSettings.lut ];
+
+    const effect = lutInfo.filter ? effectLUT : effectLUTNearest;
+    effectLUT.enabled = lutInfo.filter;
+    effectLUTNearest.enabled = !lutInfo.filter;
+
+    const lutTexture = lutInfo.texture;
+    effect.uniforms.lutMap.value = lutTexture;
+    effect.uniforms.lutMapSize.value = lutInfo.size;
+
+    composer.render(delta);
+
+    requestAnimationFrame(render);
+  }
+
+  requestAnimationFrame(render);
+
+  dragAndDrop.setup({msg: 'Drop LUT File here'});
+  dragAndDrop.onDropFile(readLUTFile);
+
+  function readLUTFile(file) {
+    const reader = new FileReader();
+    reader.onload = (e) => {
+      const lut = lutParser.lutTo2D3Drgb8(lutParser.parse(e.target.result));
+      const {size, data, name} = lut;
+      const texture = new THREE.DataTexture(data, size * size, size, THREE.RGBFormat);
+      texture.minFilter = THREE.LinearFilter;
+      texture.needsUpdate = true;
+      texture.flipY = false;
+      const lutTexture = {
+        name: (name && name.toLowerCase().trim() !== 'untitled')
+          ? name
+          : file.name,
+        size: size,
+        filter: true,
+        texture,
+      };
+      lutTextures.push(lutTexture);
+      lutSettings.lut = lutTextures.length - 1;
+      updateGUI();
+
+    };
+
+    reader.readAsText(file);
+  }
+}
+
+main();
+</script>
+</html>

+ 377 - 0
threejs/threejs-postprocessing-3dlut.html

@@ -0,0 +1,377 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <title>Three.js - postprocessing - 3DLUT</title>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+    <style>
+    html, body {
+        margin: 0;
+        height: 100%;
+    }
+    #c {
+        width: 100%;
+        height: 100%;
+        display: block;
+    }
+  </style>
+  </head>
+  <body>
+    <canvas id="c"></canvas>
+  </body>
+<script src="resources/threejs/r98/three.js"></script>
+<script src="resources/threejs/r98/js/controls/OrbitControls.js"></script>
+<script src="resources/threejs/r98/js/loaders/GLTFLoader.js"></script>
+<script src="resources/threejs/r98/js/shaders/CopyShader.js"></script>
+<script src="resources/threejs/r98/js/postprocessing/EffectComposer.js"></script>
+<script src="resources/threejs/r98/js/postprocessing/RenderPass.js"></script>
+<script src="resources/threejs/r98/js/postprocessing/ShaderPass.js"></script>
+<script src="../3rdparty/dat.gui.min.js"></script>
+<script src="resources/lut-reader.js"></script>
+<script src="resources/drag-and-drop.js"></script>
+<script>
+'use strict';
+
+/* global THREE, dat */
+
+function main() {
+  const canvas = document.querySelector('#c');
+  const renderer = new THREE.WebGLRenderer({canvas: canvas});
+
+  const fov = 45;
+  const aspect = 2;  // the canvas default
+  const near = 0.1;
+  const far = 100;
+  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
+  camera.position.set(0, 10, 20);
+
+  const controls = new THREE.OrbitControls(camera, canvas);
+  controls.target.set(0, 5, 0);
+  controls.update();
+
+  const lutTextures = [
+    { name: 'identity',           size: 2, filter: true , },
+    { name: 'identity no filter', size: 2, filter: false, },
+    { name: 'custom',          url: 'resources/images/lut/3dlut-red-only-s16.png' },
+    { name: 'monochrome',      url: 'resources/images/lut/monochrome-s8.png' },
+    { name: 'sepia',           url: 'resources/images/lut/sepia-s8.png' },
+    { name: 'saturated',       url: 'resources/images/lut/saturated-s8.png', },
+    { name: 'posterize',       url: 'resources/images/lut/posterize-s8n.png', },
+    { name: 'posterize-3-rgb', url: 'resources/images/lut/posterize-3-rgb-s8n.png', },
+    { name: 'posterize-3-lab', url: 'resources/images/lut/posterize-3-lab-s8n.png', },
+    { name: 'posterize-4-lab', url: 'resources/images/lut/posterize-4-lab-s8n.png', },
+    { name: 'posterize-more',  url: 'resources/images/lut/posterize-more-s8n.png', },
+    { name: 'inverse',         url: 'resources/images/lut/inverse-s8.png', },
+    { name: 'color negative',  url: 'resources/images/lut/color-negative-s8.png', },
+    { name: 'high contrast',   url: 'resources/images/lut/high-contrast-bw-s8.png', },
+    { name: 'funky contrast',  url: 'resources/images/lut/funky-contrast-s8.png', },
+    { name: 'nightvision',     url: 'resources/images/lut/nightvision-s8.png', },
+    { name: 'thermal',         url: 'resources/images/lut/thermal-s8.png', },
+    { name: 'b/w',             url: 'resources/images/lut/black-white-s8n.png', },
+    { name: 'hue +60',         url: 'resources/images/lut/hue-plus-60-s8.png', },
+    { name: 'hue +180',        url: 'resources/images/lut/hue-plus-180-s8.png', },
+    { name: 'hue -60',         url: 'resources/images/lut/hue-minus-60-s8.png', },
+    { name: 'red to cyan',     url: 'resources/images/lut/red-to-cyan-s8.png' },
+    { name: 'blues',           url: 'resources/images/lut/blues-s8.png' },
+    { name: 'infrared',        url: 'resources/images/lut/infrared-s8.png' },
+    { name: 'radioactive',     url: 'resources/images/lut/radioactive-s8.png' },
+    { name: 'goolgey',         url: 'resources/images/lut/googley-s8.png' },
+    { name: 'bgy',             url: 'resources/images/lut/bgy-s8.png' },
+  ];
+
+  const makeIdentityLutTexture = function() {
+    const identityLUT = new Uint8Array([
+        0,   0,   0, 255,  // black
+      255,   0,   0, 255,  // red
+        0,   0, 255, 255,  // blue
+      255,   0, 255, 255,  // magenta
+        0, 255,   0, 255,  // green
+      255, 255,   0, 255,  // yellow
+        0, 255, 255, 255,  // cyan
+      255, 255, 255, 255,  // white
+    ]);
+
+    return function(filter) {
+      const texture = new THREE.DataTexture(identityLUT, 4, 2, THREE.RGBAFormat);
+      texture.minFilter = filter;
+      texture.magFilter = filter;
+      texture.needsUpdate = true;
+      texture.flipY = false;
+      return texture;
+    };
+  }();
+
+  const makeLUTTexture = function() {
+    const imgLoader = new THREE.ImageLoader();
+    const ctx = document.createElement('canvas').getContext('2d');
+
+    return function(info) {
+      const texture = makeIdentityLutTexture(
+          info.filter ? THREE.LinearFilter : THREE.NearestFilter);
+
+      if (info.url) {
+        const lutSize = info.size;
+
+        // set the size to 2 (the identity size). We'll restore it when the
+        // image has loaded. This way the code using the lut doesn't have to
+        // care if the image has loaded or not
+        info.size = 2;
+
+        imgLoader.load(info.url, function(image) {
+          const width = lutSize * lutSize;
+          const height = lutSize;
+          info.size = lutSize;
+          ctx.canvas.width = width;
+          ctx.canvas.height = height;
+          ctx.drawImage(image, 0, 0);
+          const imageData = ctx.getImageData(0, 0, width, height);
+
+          texture.image.data = new Uint8Array(imageData.data.buffer);
+          texture.image.width = width;
+          texture.image.height = height;
+          texture.needsUpdate = true;
+        });
+      }
+
+      return texture;
+    };
+  }();
+
+
+  lutTextures.forEach((info) => {
+    // if not size set get it from the filename
+    if (!info.size) {
+      // assumes filename ends in '-s<num>[n]'
+      // where <num> is the size of the 3DLUT cube
+      // and [n] means 'no filtering' or 'nearest'
+      //
+      // examples:
+      //    'foo-s16.png' = size:16, filter: true
+      //    'bar-s8n.png' = size:8, filter: false
+      const m = /-s(\d+)(n*)\.[^.]+$/.exec(info.url);
+      if (m) {
+        info.size = parseInt(m[1]);
+        info.filter = info.filter === undefined ? m[2] !== 'n' : info.filter;
+      }
+    }
+
+    info.texture = makeLUTTexture(info);
+  });
+
+  const lutNameIndexMap = {};
+  lutTextures.forEach((info, ndx) => {
+    lutNameIndexMap[info.name] = ndx;
+  });
+
+  const lutSettings = {
+    lut: lutNameIndexMap.custom,
+  };
+  const gui = new dat.GUI({ width: 300 });
+  gui.add(lutSettings, 'lut', lutNameIndexMap);
+
+  const scene = new THREE.Scene();
+
+  const sceneBG = new THREE.Scene();
+  const cameraBG = new THREE.OrthographicCamera(-1, 1, 1, -1, -1, 1);
+
+  let bgMesh;
+  let bgTexture;
+  {
+    const loader = new THREE.TextureLoader();
+    bgTexture = loader.load('resources/images/beach.jpg');
+    const planeGeo = new THREE.PlaneBufferGeometry(2, 2);
+    const planeMat = new THREE.MeshBasicMaterial({
+      map: bgTexture,
+      depthTest: false,
+    });
+    bgMesh = new THREE.Mesh(planeGeo, planeMat);
+    sceneBG.add(bgMesh);
+  }
+
+  function frameArea(sizeToFitOnScreen, boxSize, boxCenter, camera) {
+    const halfSizeToFitOnScreen = sizeToFitOnScreen * 0.5;
+    const halfFovY = THREE.Math.degToRad(camera.fov * .5);
+    const distance = halfSizeToFitOnScreen / Math.tan(halfFovY);
+    // compute a unit vector that points in the direction the camera is now
+    // in the xz plane from the center of the box
+    const direction = (new THREE.Vector3())
+        .subVectors(camera.position, boxCenter)
+        .multiply(new THREE.Vector3(1, 0, 1))
+        .normalize();
+
+    // move the camera to a position distance units way from the center
+    // in whatever direction the camera was from the center already
+    camera.position.copy(direction.multiplyScalar(distance).add(boxCenter));
+
+    // pick some near and far values for the frustum that
+    // will contain the box.
+    camera.near = boxSize / 100;
+    camera.far = boxSize * 100;
+
+    camera.updateProjectionMatrix();
+
+    // point the camera to look at the center of the box
+    camera.lookAt(boxCenter.x, boxCenter.y, boxCenter.z);
+  }
+
+  {
+    const gltfLoader = new THREE.GLTFLoader();
+    gltfLoader.load('resources/models/3dbustchallange_submission/scene.gltf', (gltf) => {
+      const root = gltf.scene;
+      scene.add(root);
+
+      root.updateMatrixWorld();
+      // compute the box that contains all the stuff
+      // from root and below
+      const box = new THREE.Box3().setFromObject(root);
+
+      const boxSize = box.getSize(new THREE.Vector3()).length();
+      const boxCenter = box.getCenter(new THREE.Vector3());
+      frameArea(boxSize * 0.4, boxSize, boxCenter, camera);
+
+      // update the Trackball controls to handle the new size
+      controls.maxDistance = boxSize * 10;
+      controls.target.copy(boxCenter);
+      controls.update();
+    });
+  }
+
+  const lutShader = {
+    uniforms: {
+      tDiffuse: { value: null },
+      lutMap:  { value: null },
+      lutMapSize: { value: 1, },
+    },
+    vertexShader: `
+      varying vec2 vUv;
+      void main() {
+        vUv = uv;
+        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+      }
+    `,
+    fragmentShader: `
+      #include <common>
+
+      #define FILTER_LUT true
+
+      uniform sampler2D tDiffuse;
+      uniform sampler2D lutMap;
+      uniform float lutMapSize;
+
+      varying vec2 vUv;
+
+      vec4 sampleAs3DTexture(sampler2D tex, vec3 texCoord, float size) {
+        float sliceSize = 1.0 / size;                  // space of 1 slice
+        float slicePixelSize = sliceSize / size;       // space of 1 pixel
+        float width = size - 1.0;
+        float sliceInnerSize = slicePixelSize * width; // space of size pixels
+        float zSlice0 = floor( texCoord.z * width);
+        float zSlice1 = min( zSlice0 + 1.0, width);
+        float xOffset = slicePixelSize * 0.5 + texCoord.x * sliceInnerSize;
+        float yRange = (texCoord.y * width + 0.5) / size;
+        float s0 = xOffset + (zSlice0 * sliceSize);
+
+        #ifdef FILTER_LUT
+
+          float s1 = xOffset + (zSlice1 * sliceSize);
+          vec4 slice0Color = texture2D(tex, vec2(s0, yRange));
+          vec4 slice1Color = texture2D(tex, vec2(s1, yRange));
+          float zOffset = mod(texCoord.z * width, 1.0);
+          return mix(slice0Color, slice1Color, zOffset);
+
+        #else
+
+          return texture2D(tex, vec2( s0, yRange));
+
+        #endif
+      }
+
+      void main() {
+        vec4 originalColor = texture2D(tDiffuse, vUv);
+        gl_FragColor = sampleAs3DTexture(lutMap, originalColor.xyz, lutMapSize);
+      }
+    `,
+  };
+
+  const lutNearestShader = {
+    uniforms: Object.assign( {}, lutShader.uniforms ),
+    vertexShader: lutShader.vertexShader,
+    fragmentShader: lutShader.fragmentShader.replace('#define FILTER_LUT', '//'),
+  };
+
+  const effectLUT = new THREE.ShaderPass(lutShader);
+  effectLUT.renderToScreen = true;
+  const effectLUTNearest = new THREE.ShaderPass(lutNearestShader);
+  effectLUTNearest.renderToScreen = true;
+
+  const renderModel = new THREE.RenderPass(scene, camera);
+  renderModel.clear = false;  // so we don't clear out the background
+  const renderBG = new THREE.RenderPass(sceneBG, cameraBG);
+
+  const rtParameters = {
+    minFilter: THREE.LinearFilter,
+    magFilter: THREE.LinearFilter,
+    format: THREE.RGBFormat,
+  };
+  const composer = new THREE.EffectComposer(renderer, new THREE.WebGLRenderTarget(1, 1, rtParameters));
+
+  composer.addPass(renderBG);
+  composer.addPass(renderModel);
+  composer.addPass(effectLUT);
+  composer.addPass(effectLUTNearest);
+
+  function resizeRendererToDisplaySize(renderer) {
+    const canvas = renderer.domElement;
+    const width = canvas.clientWidth * window.devicePixelRatio | 0;
+    const height = canvas.clientHeight * window.devicePixelRatio | 0;
+
+    const needResize = canvas.width !== width || canvas.height !== height;
+    if (needResize) {
+      renderer.setSize(width, height, false);
+    }
+    return needResize;
+  }
+
+  let then = 0;
+  function render(now) {
+    now *= 0.001;  // convert to seconds
+    const delta = now - then;
+    then = now;
+
+    if (resizeRendererToDisplaySize(renderer)) {
+      const canvas = renderer.domElement;
+      const canvasAspect = canvas.clientWidth / canvas.clientHeight;
+      camera.aspect = canvasAspect;
+      camera.updateProjectionMatrix();
+      composer.setSize(canvas.width, canvas.height);
+
+      // scale the background plane to keep the image's
+      // aspect correct.
+      // Note the image may not have loaded yet.
+      const imageAspect = bgTexture.image ? bgTexture.image.width / bgTexture.image.height : 1;
+      const aspect = imageAspect / canvasAspect;
+      bgMesh.scale.x = aspect > 1 ? aspect : 1;
+      bgMesh.scale.y = aspect > 1 ? 1 : 1 / aspect;
+    }
+
+    const lutInfo = lutTextures[ lutSettings.lut ];
+
+    const effect = lutInfo.filter ? effectLUT : effectLUTNearest;
+    effectLUT.enabled = lutInfo.filter;
+    effectLUTNearest.enabled = !lutInfo.filter;
+
+    const lutTexture = lutInfo.texture;
+    effect.uniforms.lutMap.value = lutTexture;
+    effect.uniforms.lutMapSize.value = lutInfo.size;
+
+    composer.render(delta);
+
+    requestAnimationFrame(render);
+  }
+
+  requestAnimationFrame(render);
+}
+
+main();
+</script>
+</html>

+ 238 - 0
threejs/threejs-postprocessing-adobe-lut-to-png-converter.html

@@ -0,0 +1,238 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <title>Three.js - postprocessing - 3DLUT w/loader</title>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+    <style>
+    body {
+      min-height: 100vh;
+      font-family: monospace;
+      background: #222;
+      color: white;
+    }
+    canvas {
+      min-width: 512px;
+      image-rendering: pixelated;
+    }
+  </style>
+  </head>
+  <body>
+    <h1>Adobe LUT to PNG converter</h1>
+    <p>Drag and drop a LUT file here</p>
+    <div>size:<input id="size" type="number" value="8" min="2" max="64"/></div>
+    <p id="result"></p>
+    <p><button type="button">Save...</button></p>
+    <canvas id="c"></canvas>
+  </body>
+<script src="resources/threejs/r98/three.js"></script>
+<script src="resources/threejs/r98/js/shaders/CopyShader.js"></script>
+<script src="resources/threejs/r98/js/postprocessing/EffectComposer.js"></script>
+<script src="resources/threejs/r98/js/postprocessing/RenderPass.js"></script>
+<script src="resources/threejs/r98/js/postprocessing/ShaderPass.js"></script>
+<script src="resources/lut-reader.js"></script>
+<script src="resources/drag-and-drop.js"></script>
+<script>
+'use strict';
+
+/* global THREE, dragAndDrop, lutParser */
+
+function main() {
+  const canvas = document.querySelector('#c');
+  const renderer = new THREE.WebGLRenderer({canvas: canvas});
+
+  const makeIdentityLutTexture = function() {
+    const identityLUT = new Uint8Array([
+        0,   0,   0, 255,  // black
+      255,   0,   0, 255,  // red
+        0,   0, 255, 255,  // blue
+      255,   0, 255, 255,  // magenta
+        0, 255,   0, 255,  // green
+      255, 255,   0, 255,  // yellow
+        0, 255, 255, 255,  // cyan
+      255, 255, 255, 255,  // white
+    ]);
+
+    return function(filter) {
+      const texture = new THREE.DataTexture(identityLUT, 4, 2, THREE.RGBAFormat);
+      texture.minFilter = filter;
+      texture.magFilter = filter;
+      texture.needsUpdate = true;
+      texture.flipY = false;
+      return texture;
+    };
+  }();
+
+  const sceneBG = new THREE.Scene();
+  const cameraBG = new THREE.OrthographicCamera(-1, 1, 1, -1, -1, 1);
+
+  const ctx = document.createElement('canvas').getContext('2d');
+  function drawColorCubeImage(ctx, size) {
+    const canvas = ctx.canvas;
+    canvas.width = size * size;
+    canvas.height = size;
+
+    for (let zz = 0; zz < size; ++zz) {
+      for (let yy = 0; yy < size; ++yy) {
+        for (let xx = 0; xx < size; ++xx) {
+          const r = Math.floor(xx / (size - 1) * 255);
+          const g = Math.floor(yy / (size - 1) * 255);
+          const b = Math.floor(zz / (size - 1) * 255);
+          ctx.fillStyle = `rgb(${r},${g},${b})`;
+          ctx.fillRect(zz * size + xx, yy, 1, 1);
+        }
+      }
+    }
+  }
+
+  const idTexture = new THREE.CanvasTexture(ctx.canvas);
+  idTexture.magFilter = THREE.NearestFilter;
+  idTexture.minFilter = THREE.NearestFilter;
+
+  {
+    const planeGeo = new THREE.PlaneBufferGeometry(2, 2);
+    const planeMat = new THREE.MeshBasicMaterial({
+      map: idTexture,
+      depthTest: false,
+    });
+    sceneBG.add(new THREE.Mesh(planeGeo, planeMat));
+  }
+
+  const lutShader = {
+    uniforms: {
+      tDiffuse: { value: null },
+      lutMap:  { value: null },
+      lutMapSize: { value: 1, },
+    },
+    vertexShader: `
+      varying vec2 vUv;
+      void main() {
+        vUv = uv;
+        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+      }
+    `,
+    fragmentShader: `
+      #include <common>
+
+      #define FILTER_LUT true
+
+      uniform sampler2D tDiffuse;
+      uniform sampler2D lutMap;
+      uniform float lutMapSize;
+
+      varying vec2 vUv;
+
+      vec4 sampleAs3DTexture(sampler2D tex, vec3 texCoord, float size) {
+        float sliceSize = 1.0 / size;                  // space of 1 slice
+        float slicePixelSize = sliceSize / size;       // space of 1 pixel
+        float width = size - 1.0;
+        float sliceInnerSize = slicePixelSize * width; // space of size pixels
+        float zSlice0 = floor( texCoord.z * width);
+        float zSlice1 = min( zSlice0 + 1.0, width);
+        float xOffset = slicePixelSize * 0.5 + texCoord.x * sliceInnerSize;
+        float yRange = (texCoord.y * width + 0.5) / size;
+        float s0 = xOffset + (zSlice0 * sliceSize);
+
+        #ifdef FILTER_LUT
+
+          float s1 = xOffset + (zSlice1 * sliceSize);
+          vec4 slice0Color = texture2D(tex, vec2(s0, yRange));
+          vec4 slice1Color = texture2D(tex, vec2(s1, yRange));
+          float zOffset = mod(texCoord.z * width, 1.0);
+          return mix(slice0Color, slice1Color, zOffset);
+
+        #else
+
+          return texture2D(tex, vec2( s0, yRange));
+
+        #endif
+      }
+
+      void main() {
+        vec4 originalColor = texture2D(tDiffuse, vUv);
+        gl_FragColor = sampleAs3DTexture(lutMap, originalColor.xyz, lutMapSize);
+      }
+    `,
+  };
+
+  const effectLUT = new THREE.ShaderPass(lutShader);
+  effectLUT.renderToScreen = true;
+
+  const renderBG = new THREE.RenderPass(sceneBG, cameraBG);
+
+  const rtParameters = {
+    minFilter: THREE.NearestFilter,
+    magFilter: THREE.NearestFilter,
+    format: THREE.RGBFormat,
+  };
+  const composer = new THREE.EffectComposer(renderer, new THREE.WebGLRenderTarget(1, 1, rtParameters));
+
+  composer.addPass(renderBG);
+  composer.addPass(effectLUT);
+
+  let name = 'identity';
+  const lutTexture = makeIdentityLutTexture(THREE.LinearFilter);
+  effectLUT.uniforms.lutMap.value = lutTexture;
+  effectLUT.uniforms.lutMapSize.value = 2;
+
+  const sizeElem = document.querySelector('#size');
+  sizeElem.addEventListener('change', render);
+
+  function render() {
+    const size = parseInt(sizeElem.value);
+    renderer.setSize(size * size, size, false);
+    composer.setSize(size * size, size);
+
+    drawColorCubeImage(ctx, size);
+    idTexture.needsUpdate = true;
+
+    composer.render(0);
+  }
+  render();
+
+  dragAndDrop.setup({msg: 'Drop LUT File here'});
+  dragAndDrop.onDropFile(readLUTFile);
+
+  function readLUTFile(file) {
+    const reader = new FileReader();
+    reader.onload = (e) => {
+      const lut = lutParser.lutTo2D3Drgb8(lutParser.parse(e.target.result));
+
+      effectLUT.uniforms.lutMapSize.value = lut.size;
+
+      lutTexture.image.data = lut.data;
+      lutTexture.image.width = lut.size * lut.size;
+      lutTexture.image.height = lut.size;
+      lutTexture.format = THREE.RGBFormat;
+      lutTexture.needsUpdate = true;
+
+      render();
+      name = `${file.name || lut.name || 'untitled'}`;
+      document.querySelector('#result').textContent = `loaded: ${name}`;
+    };
+
+    reader.readAsText(file);
+  }
+
+  const saveData = (function() {
+    const a = document.createElement('a');
+    document.body.appendChild(a);
+    a.style.display = 'none';
+    return function saveData(blob, fileName) {
+      const url = window.URL.createObjectURL(blob);
+      a.href = url;
+      a.download = fileName;
+      a.click();
+    };
+  }());
+
+  document.querySelector('button').addEventListener('click', () => {
+    renderer.domElement.toBlob((blob) => {
+      saveData(blob, `${name}-s${renderer.domElement.height}.png`);
+    });
+  });
+}
+
+main();
+</script>
+</html>