From 76c8e1f115c801e493d0ae18dc510d9c190e2351 Mon Sep 17 00:00:00 2001 From: Nic Barker Date: Mon, 10 Feb 2025 16:14:13 +1300 Subject: [PATCH] [Examples/clay-official-website] Update web renderer example to latest API --- clay.h | 12 + .../build/clay/index.html | 320 ++++++++++-------- .../build/clay/index.wasm | Bin 111977 -> 117506 bytes examples/clay-official-website/index.html | 320 ++++++++++-------- examples/clay-official-website/main.c | 57 ++-- 5 files changed, 401 insertions(+), 308 deletions(-) diff --git a/clay.h b/clay.h index d4b2896..57a9d10 100644 --- a/clay.h +++ b/clay.h @@ -424,6 +424,11 @@ typedef struct { void* customData; } Clay_CustomRenderData; +typedef struct { + bool horizontal; + bool vertical; +} Clay_ScrollRenderData; + typedef struct { Clay_Color color; Clay_CornerRadius cornerRadius; @@ -436,6 +441,7 @@ typedef union { Clay_ImageRenderData image; Clay_CustomRenderData custom; Clay_BorderRenderData border; + Clay_ScrollRenderData scroll; } Clay_RenderData; // Miscellaneous Structs & Enums --------------------------------- @@ -2249,6 +2255,12 @@ void Clay__CalculateFinalLayout(void) { } case CLAY__ELEMENT_CONFIG_TYPE_SCROLL: { renderCommand.commandType = CLAY_RENDER_COMMAND_TYPE_SCISSOR_START; + renderCommand.renderData = CLAY__INIT(Clay_RenderData) { + .scroll = { + .horizontal = elementConfig->config.scrollElementConfig->horizontal, + .vertical = elementConfig->config.scrollElementConfig->vertical, + } + }; break; } case CLAY__ELEMENT_CONFIG_TYPE_IMAGE: { diff --git a/examples/clay-official-website/build/clay/index.html b/examples/clay-official-website/build/clay/index.html index 0eab546..1e07d31 100644 --- a/examples/clay-official-website/build/clay/index.html +++ b/examples/clay-official-website/build/clay/index.html @@ -86,6 +86,10 @@ ]; let elementCache = {}; let imageCache = {}; + let dimensionsDefinition = { type: 'struct', members: [ + {name: 'width', type: 'float'}, + {name: 'height', type: 'float'}, + ]}; let colorDefinition = { type: 'struct', members: [ {name: 'r', type: 'float' }, {name: 'g', type: 'float' }, @@ -101,9 +105,12 @@ {name: 'chars', type: 'uint32_t' }, {name: 'baseChars', type: 'uint32_t' }, ]}; - let borderDefinition = { type: 'struct', members: [ - {name: 'width', type: 'uint32_t'}, - {name: 'color', ...colorDefinition}, + let borderWidthDefinition = { type: 'struct', members: [ + {name: 'left', type: 'uint16_t'}, + {name: 'right', type: 'uint16_t'}, + {name: 'top', type: 'uint16_t'}, + {name: 'bottom', type: 'uint16_t'}, + {name: 'betweenChildren', type: 'uint16_t'}, ]}; let cornerRadiusDefinition = { type: 'struct', members: [ {name: 'topLeft', type: 'float'}, @@ -111,44 +118,53 @@ {name: 'bottomLeft', type: 'float'}, {name: 'bottomRight', type: 'float'}, ]}; - let rectangleConfigDefinition = { name: 'rectangle', type: 'struct', members: [ - { name: 'color', ...colorDefinition }, - { name: 'link', ...stringDefinition }, - { name: 'cursorPointer', type: 'uint8_t' }, - ]}; - let borderConfigDefinition = { name: 'text', type: 'struct', members: [ - { name: 'left', ...borderDefinition }, - { name: 'right', ...borderDefinition }, - { name: 'top', ...borderDefinition }, - { name: 'bottom', ...borderDefinition }, - { name: 'betweenChildren', ...borderDefinition }, - ]}; let textConfigDefinition = { name: 'text', type: 'struct', members: [ - { name: 'textColor', ...colorDefinition }, - { name: 'fontId', type: 'uint16_t' }, - { name: 'fontSize', type: 'uint16_t' }, - { name: 'letterSpacing', type: 'uint16_t' }, - { name: 'lineSpacing', type: 'uint16_t' }, - { name: 'wrapMode', type: 'uint32_t' }, - { name: 'disablePointerEvents', type: 'uint8_t' } + { name: 'textColor', ...colorDefinition }, + { name: 'fontId', type: 'uint16_t' }, + { name: 'fontSize', type: 'uint16_t' }, + { name: 'letterSpacing', type: 'uint16_t' }, + { name: 'lineSpacing', type: 'uint16_t' }, + { name: 'wrapMode', type: 'uint8_t' }, + { name: 'disablePointerEvents', type: 'uint8_t' }, + { name: '_padding', type: 'uint16_t' }, ]}; - let scrollConfigDefinition = { name: 'text', type: 'struct', members: [ + let textRenderDataDefinition = { type: 'struct', members: [ + { name: 'stringContents', ...stringSliceDefinition }, + { name: 'textColor', ...colorDefinition }, + { name: 'fontId', type: 'uint16_t' }, + { name: 'fontSize', type: 'uint16_t' }, + { name: 'letterSpacing', type: 'uint16_t' }, + { name: 'lineHeight', type: 'uint16_t' }, + ]}; + let rectangleRenderDataDefinition = { type: 'struct', members: [ + { name: 'backgroundColor', ...colorDefinition }, + { name: 'cornerRadius', ...cornerRadiusDefinition }, + ]}; + let imageRenderDataDefinition = { type: 'struct', members: [ + { name: 'backgroundColor', ...colorDefinition }, + { name: 'cornerRadius', ...cornerRadiusDefinition }, + { name: 'sourceDimensions', ...dimensionsDefinition }, + { name: 'imageData', type: 'uint32_t' }, + ]}; + let customRenderDataDefinition = { type: 'struct', members: [ + { name: 'backgroundColor', ...colorDefinition }, + { name: 'cornerRadius', ...cornerRadiusDefinition }, + { name: 'customData', type: 'uint32_t' }, + ]}; + let borderRenderDataDefinition = { type: 'struct', members: [ + { name: 'color', ...colorDefinition }, + { name: 'cornerRadius', ...cornerRadiusDefinition }, + { name: 'width', ...borderWidthDefinition }, + { name: 'padding', type: 'uint16_t'} + ]}; + let scrollRenderDataDefinition = { type: 'struct', members: [ { name: 'horizontal', type: 'bool' }, { name: 'vertical', type: 'bool' }, ]}; - let imageConfigDefinition = { name: 'image', type: 'struct', members: [ - { name: 'imageData', type: 'uint32_t' }, - { name: 'sourceDimensions', type: 'struct', members: [ - { name: 'width', type: 'float' }, - { name: 'height', type: 'float' }, - ]}, - { name: 'sourceURL', ...stringDefinition } - ]}; - let customConfigDefinition = { name: 'custom', type: 'struct', members: [ - { name: 'customData', type: 'uint32_t' }, - ]} - let sharedConfigDefinition = { name: 'shared', type: 'struct', members: [ - { name: 'cornerRadius', ...cornerRadiusDefinition }, + let customHTMLDataDefinition = { type: 'struct', members: [ + { name: 'link', ...stringDefinition }, + { name: 'cursorPointer', type: 'uint8_t' }, + { name: 'disablePointerEvents', type: 'uint8_t' }, ]}; let renderCommandDefinition = { name: 'CLay_RenderCommand', @@ -160,14 +176,19 @@ { name: 'width', type: 'float' }, { name: 'height', type: 'float' }, ]}, - { name: 'config', type: 'uint32_t'}, - { name: 'textOrSharedConfig', type: 'union', members: [ - { name: 'text', ...stringSliceDefinition }, - { name: 'sharedConfig', type: 'uint32_t' } + { name: 'renderData', type: 'union', members: [ + { name: 'rectangle', ...rectangleRenderDataDefinition }, + { name: 'text', ...textRenderDataDefinition }, + { name: 'image', ...imageRenderDataDefinition }, + { name: 'custom', ...customRenderDataDefinition }, + { name: 'border', ...borderRenderDataDefinition }, + { name: 'scroll', ...scrollRenderDataDefinition }, ]}, - { name: 'zIndex', type: 'int32_t' }, + { name: 'userData', type: 'uint32_t'}, { name: 'id', type: 'uint32_t' }, - { name: 'commandType', type: 'uint32_t', }, + { name: 'zIndex', type: 'int16_t' }, + { name: 'commandType', type: 'uint8_t' }, + { name: '_padding', type: 'uint8_t' }, ] }; @@ -190,6 +211,7 @@ case 'uint32_t': return 4; case 'int32_t': return 4; case 'uint16_t': return 2; + case 'int16_t': return 2; case 'uint8_t': return 1; case 'bool': return 1; default: { @@ -219,6 +241,7 @@ case 'uint32_t': return { value: memoryDataView.getUint32(address, true), __size: 4 }; case 'int32_t': return { value: memoryDataView.getUint32(address, true), __size: 4 }; case 'uint16_t': return { value: memoryDataView.getUint16(address, true), __size: 2 }; + case 'int16_t': return { value: memoryDataView.getInt16(address, true), __size: 2 }; case 'uint8_t': return { value: memoryDataView.getUint8(address, true), __size: 1 }; case 'bool': return { value: memoryDataView.getUint8(address, true), __size: 1 }; default: { @@ -340,7 +363,7 @@ memoryDataView.setFloat32(addressOfOffset, -container.scrollLeft, true); memoryDataView.setFloat32(addressOfOffset + 4, -container.scrollTop, true); } - } + }, }, }; const { instance } = await WebAssembly.instantiateStreaming( @@ -348,13 +371,15 @@ ); memoryDataView = new DataView(new Uint8Array(instance.exports.memory.buffer).buffer); scratchSpaceAddress = instance.exports.__heap_base.value; - heapSpaceAddress = instance.exports.__heap_base.value + 1024; + let clayScratchSpaceAddress = instance.exports.__heap_base.value + 1024; + heapSpaceAddress = instance.exports.__heap_base.value + 2048; let arenaAddress = scratchSpaceAddress + 8; window.instance = instance; createMainArena(arenaAddress, heapSpaceAddress); memoryDataView.setFloat32(instance.exports.__heap_base.value, window.innerWidth, true); memoryDataView.setFloat32(instance.exports.__heap_base.value + 4, window.innerHeight, true); instance.exports.Clay_Initialize(arenaAddress, instance.exports.__heap_base.value); + instance.exports.SetScratchMemory(arenaAddress, clayScratchSpaceAddress); renderCommandSize = getStructTotalSize(renderCommandDefinition); renderLoop(); } @@ -368,6 +393,22 @@ return false; } + function SetElementBackgroundColorAndRadius(element, cornerRadius, backgroundColor) { + element.style.backgroundColor = `rgba(${backgroundColor.r.value}, ${backgroundColor.g.value}, ${backgroundColor.b.value}, ${backgroundColor.a.value / 255})`; + if (cornerRadius.topLeft.value > 0) { + element.style.borderTopLeftRadius = cornerRadius.topLeft.value + 'px'; + } + if (cornerRadius.topRight.value > 0) { + element.style.borderTopRightRadius = cornerRadius.topRight.value + 'px'; + } + if (cornerRadius.bottomLeft.value > 0) { + element.style.borderBottomLeftRadius = cornerRadius.bottomLeft.value + 'px'; + } + if (cornerRadius.bottomRight.value > 0) { + element.style.borderBottomRightRadius = cornerRadius.bottomRight.value + 'px'; + } + } + function renderLoopHTML() { let capacity = memoryDataView.getInt32(scratchSpaceAddress, true); let length = memoryDataView.getInt32(scratchSpaceAddress + 4, true); @@ -375,7 +416,7 @@ let scissorStack = [{ nextAllocation: { x: 0, y: 0 }, element: htmlRoot, nextElementIndex: 0 }]; let previousId = 0; for (let i = 0; i < length; i++, arrayOffset += renderCommandSize) { - let entireRenderCommandMemory = new Uint32Array(memoryDataView.buffer.slice(arrayOffset, arrayOffset + renderCommandSize)); + let entireRenderCommandMemory = new Uint8Array(memoryDataView.buffer.slice(arrayOffset, arrayOffset + renderCommandSize)); let renderCommand = readStructAtAddress(arrayOffset, renderCommandDefinition); let parentElement = scissorStack[scissorStack.length - 1]; let element = null; @@ -384,13 +425,12 @@ let elementType = 'div'; switch (renderCommand.commandType.value & 0xff) { case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: { - if (readStructAtAddress(renderCommand.config.value, rectangleConfigDefinition).link.length.value > 0) { - elementType = 'a'; - } + // if (readStructAtAddress(renderCommand.renderData.rectangle.value, rectangleRenderDataDefinition).link.length.value > 0) { TODO reimplement links + // elementType = 'a'; + // } break; } case CLAY_RENDER_COMMAND_TYPE_IMAGE: { - console.log('test5'); elementType = 'img'; break; } default: break; @@ -443,93 +483,82 @@ break; } case (CLAY_RENDER_COMMAND_TYPE_RECTANGLE): { - let config = readStructAtAddress(renderCommand.config.value, rectangleConfigDefinition); - let sharedConfig = readStructAtAddress( renderCommand.textOrSharedConfig.sharedConfig.value, sharedConfigDefinition); - let configMemory = new Uint8Array(memoryDataView.buffer.slice(renderCommand.config.value, renderCommand.config.value + config.__size)); - let linkContents = config.link.length.value > 0 ? textDecoder.decode(new Uint8Array(memoryDataView.buffer.slice(config.link.chars.value, config.link.chars.value + config.link.length.value))) : 0; - memoryDataView.setUint32(0, renderCommand.id.value, true); - if (linkContents.length > 0 && (window.mouseDownThisFrame || window.touchDown) && instance.exports.Clay_PointerOver(0)) { - window.location.href = linkContents; - } - if (!dirty && !MemoryIsDifferent(configMemory, elementData.previousMemoryConfig, config.__size)) { + let config = renderCommand.renderData.rectangle; + let configMemory = JSON.stringify(config); + if (configMemory === elementData.previousMemoryConfig) { break; } - if (linkContents.length > 0) { - element.href = linkContents; + + SetElementBackgroundColorAndRadius(element, config.cornerRadius, config.backgroundColor); + if (renderCommand.userData.value !== 0) { + let customData = readStructAtAddress(renderCommand.userData.value, customHTMLDataDefinition); + + let linkContents = customData.link.length.value > 0 ? textDecoder.decode(new Uint8Array(memoryDataView.buffer.slice(customData.link.chars.value, customData.link.chars.value + customData.link.length.value))) : 0; + memoryDataView.setUint32(0, renderCommand.id.value, true); + if (linkContents.length > 0 && (window.mouseDownThisFrame || window.touchDown) && instance.exports.Clay_PointerOver(0)) { + window.location.href = linkContents; + } + if (linkContents.length > 0) { + element.href = linkContents; + } + + if (linkContents.length > 0 || customData.cursorPointer.value) { + element.style.pointerEvents = 'all'; + element.style.cursor = 'pointer'; + } } - if (linkContents.length > 0 || config.cursorPointer.value) { - element.style.pointerEvents = 'all'; - element.style.cursor = 'pointer'; - } elementData.previousMemoryConfig = configMemory; - let color = config.color; - element.style.backgroundColor = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; - if (sharedConfig.cornerRadius.topLeft.value > 0) { - element.style.borderTopLeftRadius = sharedConfig.cornerRadius.topLeft.value + 'px'; - } - if (sharedConfig.cornerRadius.topRight.value > 0) { - element.style.borderTopRightRadius = sharedConfig.cornerRadius.topRight.value + 'px'; - } - if (sharedConfig.cornerRadius.bottomLeft.value > 0) { - element.style.borderBottomLeftRadius = sharedConfig.cornerRadius.bottomLeft.value + 'px'; - } - if (sharedConfig.cornerRadius.bottomRight.value > 0) { - element.style.borderBottomRightRadius = sharedConfig.cornerRadius.bottomRight.value + 'px'; - } + break; } case (CLAY_RENDER_COMMAND_TYPE_BORDER): { - let config = readStructAtAddress(renderCommand.config.value, borderConfigDefinition); - let sharedConfig = readStructAtAddress( renderCommand.textOrSharedConfig.sharedConfig.value, sharedConfigDefinition); - let configMemory = new Uint8Array(memoryDataView.buffer.slice(renderCommand.config.value, renderCommand.config.value + config.__size)); - if (!dirty && !MemoryIsDifferent(configMemory, elementData.previousMemoryConfig, config.__size)) { + let config = renderCommand.renderData.border; + let configMemory = JSON.stringify(config); + if (configMemory === elementData.previousMemoryConfig) { break; } + let color = config.color; elementData.previousMemoryConfig = configMemory; - if (config.left.width.value > 0) { - let color = config.left.color; - element.style.borderLeft = `${config.left.width.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` + if (config.width.left.value > 0) { + element.style.borderLeft = `${config.width.left.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` } - if (config.right.width.value > 0) { - let color = config.right.color; - element.style.borderRight = `${config.right.width.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` + if (config.width.right.value > 0) { + element.style.borderRight = `${config.width.right.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` } - if (config.top.width.value > 0) { - let color = config.top.color; - element.style.borderTop = `${config.top.width.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` + if (config.width.top.value > 0) { + element.style.borderTop = `${config.width.top.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` } - if (config.bottom.width.value > 0) { - let color = config.bottom.color; - element.style.borderBottom = `${config.bottom.width.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` + if (config.width.bottom.value > 0) { + element.style.borderBottom = `${config.width.bottom.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` } - if (sharedConfig.cornerRadius.topLeft.value > 0) { - element.style.borderTopLeftRadius = sharedConfig.cornerRadius.topLeft.value + 'px'; + if (config.cornerRadius.topLeft.value > 0) { + element.style.borderTopLeftRadius = config.cornerRadius.topLeft.value + 'px'; } - if (sharedConfig.cornerRadius.topRight.value > 0) { - element.style.borderTopRightRadius = sharedConfig.cornerRadius.topRight.value + 'px'; + if (config.cornerRadius.topRight.value > 0) { + element.style.borderTopRightRadius = config.cornerRadius.topRight.value + 'px'; } - if (sharedConfig.cornerRadius.bottomLeft.value > 0) { - element.style.borderBottomLeftRadius = sharedConfig.cornerRadius.bottomLeft.value + 'px'; + if (config.cornerRadius.bottomLeft.value > 0) { + element.style.borderBottomLeftRadius = config.cornerRadius.bottomLeft.value + 'px'; } - if (sharedConfig.cornerRadius.bottomRight.value > 0) { - element.style.borderBottomRightRadius = sharedConfig.cornerRadius.bottomRight.value + 'px'; + if (config.cornerRadius.bottomRight.value > 0) { + element.style.borderBottomRightRadius = config.cornerRadius.bottomRight.value + 'px'; } break; } case (CLAY_RENDER_COMMAND_TYPE_TEXT): { - let config = readStructAtAddress(renderCommand.config.value, textConfigDefinition); - let configMemory = new Uint8Array(memoryDataView.buffer.slice(renderCommand.config.value, renderCommand.config.value + config.__size)); - let textContents = renderCommand.textOrSharedConfig.text; - let stringContents = new Uint8Array(memoryDataView.buffer.slice(textContents.chars.value, textContents.chars.value + textContents.length.value)); - if (MemoryIsDifferent(configMemory, elementData.previousMemoryConfig, config.__size)) { + let config = renderCommand.renderData.text; + let customData = readStructAtAddress(renderCommand.userData.value, customHTMLDataDefinition); + let configMemory = JSON.stringify(config); + let stringContents = new Uint8Array(memoryDataView.buffer.slice(config.stringContents.chars.value, config.stringContents.chars.value + config.stringContents.length.value)); + if (configMemory !== elementData.previousMemoryConfig) { element.className = 'text'; let textColor = config.textColor; let fontSize = Math.round(config.fontSize.value * GLOBAL_FONT_SCALING_FACTOR); element.style.color = `rgba(${textColor.r.value}, ${textColor.g.value}, ${textColor.b.value}, ${textColor.a.value})`; element.style.fontFamily = fontsById[config.fontId.value]; element.style.fontSize = fontSize + 'px'; - element.style.pointerEvents = config.disablePointerEvents.value ? 'none' : 'all'; + element.style.pointerEvents = customData.disablePointerEvents.value ? 'none' : 'all'; elementData.previousMemoryConfig = configMemory; } if (stringContents.length !== elementData.previousMemoryText.length || MemoryIsDifferent(stringContents, elementData.previousMemoryText, stringContents.length)) { @@ -540,7 +569,11 @@ } case (CLAY_RENDER_COMMAND_TYPE_SCISSOR_START): { scissorStack.push({ nextAllocation: { x: renderCommand.boundingBox.x.value, y: renderCommand.boundingBox.y.value }, element, nextElementIndex: 0 }); - let config = readStructAtAddress(renderCommand.config.value, scrollConfigDefinition); + let config = renderCommand.renderData.scroll; + let configMemory = JSON.stringify(config); + if (configMemory === elementData.previousMemoryConfig) { + break; + } if (config.horizontal.value) { element.style.overflowX = 'scroll'; element.style.pointerEvents = 'auto'; @@ -549,6 +582,7 @@ element.style.overflowY = 'scroll'; element.style.pointerEvents = 'auto'; } + elementData.previousMemoryConfig = configMemory; break; } case (CLAY_RENDER_COMMAND_TYPE_SCISSOR_END): { @@ -556,9 +590,9 @@ break; } case (CLAY_RENDER_COMMAND_TYPE_IMAGE): { - console.log('test1'); - let config = readStructAtAddress(renderCommand.config.value, imageConfigDefinition); - let srcContents = new Uint8Array(memoryDataView.buffer.slice(config.sourceURL.chars.value, config.sourceURL.chars.value + config.sourceURL.length.value)); + let config = renderCommand.renderData.image; + let imageURL = readStructAtAddress(config.imageData.value, stringDefinition); + let srcContents = new Uint8Array(memoryDataView.buffer.slice(imageURL.chars.value, imageURL.chars.value + imageURL.length.value)); if (srcContents.length !== elementData.previousMemoryText.length || MemoryIsDifferent(srcContents, elementData.previousMemoryText, srcContents.length)) { element.src = textDecoder.decode(srcContents); } @@ -566,6 +600,9 @@ break; } case (CLAY_RENDER_COMMAND_TYPE_CUSTOM): break; + default: { + console.log("Error: unhandled render command"); + } } } @@ -602,8 +639,8 @@ break; } case (CLAY_RENDER_COMMAND_TYPE_RECTANGLE): { - let config = readStructAtAddress(renderCommand.config.value, rectangleConfigDefinition); - let color = config.color; + let config = renderCommand.renderData.rectangle; + let color = config.backgroundColor; ctx.beginPath(); window.canvasContext.fillStyle = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; window.canvasContext.roundRect( @@ -615,33 +652,35 @@ ctx.fill(); ctx.closePath(); // Handle link clicks - let linkContents = config.link.length.value > 0 ? textDecoder.decode(new Uint8Array(memoryDataView.buffer.slice(config.link.chars.value, config.link.chars.value + config.link.length.value))) : 0; - memoryDataView.setUint32(0, renderCommand.id.value, true); - if (linkContents.length > 0 && (window.mouseDownThisFrame || window.touchDown) && instance.exports.Clay_PointerOver(0)) { - window.location.href = linkContents; + if (renderCommand.userData.value !== 0) { + let customData = readStructAtAddress(renderCommand.userData.value, customHTMLDataDefinition); + let linkContents = customData.link.length.value > 0 ? textDecoder.decode(new Uint8Array(memoryDataView.buffer.slice(customData.link.chars.value, customData.link.chars.value + customData.link.length.value))) : 0; + memoryDataView.setUint32(0, renderCommand.id.value, true); + if (linkContents.length > 0 && (window.mouseDownThisFrame || window.touchDown) && instance.exports.Clay_PointerOver(0)) { + window.location.href = linkContents; + } } break; } case (CLAY_RENDER_COMMAND_TYPE_BORDER): { - let config = readStructAtAddress(renderCommand.config.value, borderConfigDefinition); + let config = renderCommand.renderData.border; + let color = config.color; ctx.beginPath(); ctx.moveTo(boundingBox.x.value * scale, boundingBox.y.value * scale); // Top Left Corner if (config.cornerRadius.topLeft.value > 0) { - let lineWidth = config.top.width.value; + let lineWidth = config.width.top.value; let halfLineWidth = lineWidth / 2; ctx.moveTo((boundingBox.x.value + halfLineWidth) * scale, (boundingBox.y.value + config.cornerRadius.topLeft.value + halfLineWidth) * scale); - let color = config.top.color; ctx.lineWidth = lineWidth * scale; ctx.strokeStyle = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; ctx.arcTo((boundingBox.x.value + halfLineWidth) * scale, (boundingBox.y.value + halfLineWidth) * scale, (boundingBox.x.value + config.cornerRadius.topLeft.value + halfLineWidth) * scale, (boundingBox.y.value + halfLineWidth) * scale, config.cornerRadius.topLeft.value * scale); ctx.stroke(); } // Top border - if (config.top.width.value > 0) { - let lineWidth = config.top.width.value; + if (config.width.top.value > 0) { + let lineWidth = config.width.top.value; let halfLineWidth = lineWidth / 2; - let color = config.top.color; ctx.lineWidth = lineWidth * scale; ctx.strokeStyle = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; ctx.moveTo((boundingBox.x.value + config.cornerRadius.topLeft.value + halfLineWidth) * scale, (boundingBox.y.value + halfLineWidth) * scale); @@ -650,19 +689,17 @@ } // Top Right Corner if (config.cornerRadius.topRight.value > 0) { - let lineWidth = config.top.width.value; + let lineWidth = config.width.top.value; let halfLineWidth = lineWidth / 2; ctx.moveTo((boundingBox.x.value + boundingBox.width.value - config.cornerRadius.topRight.value - halfLineWidth) * scale, (boundingBox.y.value + halfLineWidth) * scale); - let color = config.top.color; ctx.lineWidth = lineWidth * scale; ctx.strokeStyle = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; ctx.arcTo((boundingBox.x.value + boundingBox.width.value - halfLineWidth) * scale, (boundingBox.y.value + halfLineWidth) * scale, (boundingBox.x.value + boundingBox.width.value - halfLineWidth) * scale, (boundingBox.y.value + config.cornerRadius.topRight.value + halfLineWidth) * scale, config.cornerRadius.topRight.value * scale); ctx.stroke(); } // Right border - if (config.right.width.value > 0) { - let color = config.right.color; - let lineWidth = config.right.width.value; + if (config.width.right.value > 0) { + let lineWidth = config.width.right.value; let halfLineWidth = lineWidth / 2; ctx.lineWidth = lineWidth * scale; ctx.strokeStyle = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; @@ -672,8 +709,7 @@ } // Bottom Right Corner if (config.cornerRadius.bottomRight.value > 0) { - let color = config.top.color; - let lineWidth = config.top.width.value; + let lineWidth = config.width.top.value; let halfLineWidth = lineWidth / 2; ctx.moveTo((boundingBox.x.value + boundingBox.width.value - halfLineWidth) * scale, (boundingBox.y.value + boundingBox.height.value - config.cornerRadius.bottomRight.value - halfLineWidth) * scale); ctx.lineWidth = lineWidth * scale; @@ -682,9 +718,8 @@ ctx.stroke(); } // Bottom Border - if (config.bottom.width.value > 0) { - let color = config.bottom.color; - let lineWidth = config.bottom.width.value; + if (config.width.bottom.value > 0) { + let lineWidth = config.width.bottom.value; let halfLineWidth = lineWidth / 2; ctx.lineWidth = lineWidth * scale; ctx.strokeStyle = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; @@ -694,8 +729,7 @@ } // Bottom Left Corner if (config.cornerRadius.bottomLeft.value > 0) { - let color = config.bottom.color; - let lineWidth = config.bottom.width.value; + let lineWidth = config.width.bottom.value; let halfLineWidth = lineWidth / 2; ctx.moveTo((boundingBox.x.value + config.cornerRadius.bottomLeft.value + halfLineWidth) * scale, (boundingBox.y.value + boundingBox.height.value - halfLineWidth) * scale); ctx.lineWidth = lineWidth * scale; @@ -704,9 +738,8 @@ ctx.stroke(); } // Left Border - if (config.left.width.value > 0) { - let color = config.left.color; - let lineWidth = config.left.width.value; + if (config.width.left.value > 0) { + let lineWidth = config.width.left.value; let halfLineWidth = lineWidth / 2; ctx.lineWidth = lineWidth * scale; ctx.strokeStyle = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; @@ -718,8 +751,8 @@ break; } case (CLAY_RENDER_COMMAND_TYPE_TEXT): { - let config = readStructAtAddress(renderCommand.config.value, textConfigDefinition); - let textContents = renderCommand.text; + let config = renderCommand.renderData.text; + let textContents = config.stringContents; let stringContents = new Uint8Array(memoryDataView.buffer.slice(textContents.chars.value, textContents.chars.value + textContents.length.value)); let fontSize = config.fontSize.value * GLOBAL_FONT_SCALING_FACTOR * scale; ctx.font = `${fontSize}px ${fontsById[config.fontId.value]}`; @@ -742,8 +775,9 @@ break; } case (CLAY_RENDER_COMMAND_TYPE_IMAGE): { - let config = readStructAtAddress(renderCommand.config.value, imageConfigDefinition); - let src = textDecoder.decode(new Uint8Array(memoryDataView.buffer.slice(config.sourceURL.chars.value, config.sourceURL.chars.value + config.sourceURL.length.value))); + let config = renderCommand.renderData.image; + let imageURL = readStructAtAddress(config.imageData.value, stringDefinition); + let src = textDecoder.decode(new Uint8Array(memoryDataView.buffer.slice(imageURL.chars.value, imageURL.chars.value + imageURL.length.value))); if (!imageCache[src]) { imageCache[src] = { image: new Image(), diff --git a/examples/clay-official-website/build/clay/index.wasm b/examples/clay-official-website/build/clay/index.wasm index 91fa130e75d619678e4c0ff373494d615f218211..1173dc4509ab650078d979a2e073faa919cc4b53 100755 GIT binary patch literal 117506 zcmd443!Gl(UEg^w@7!;%F1BS$R?hosY>#fX0*<8EPNNgYjuR3RLYBDOkl5G?_SkV8 z+hNUqoaoImv;!zG$P+pQ(M}g_89>khi*^8QnWfrxXjPaNeah@2U_M2((?ztitv;Ws zpQ>cPzyI@`+srFzlm-?jnseUg{Ll0Jpa1>&KbI3c{px4JAPB-I2cHU$1y9Atj`6p~ zU;iUK_EdE27=Hu)g?1CDM4(@AFkc9s>d*`P3b`LR_67UTioOs;?}}>Ay!iC@Zu!j7 zr(ga2D@Q+e^!3*s|NKkOy!QNOUkco#J3sgNqpy7Lw?FgBXJ35r!=L{2t49lfFn;pm zL0qfVLjLimqoXs7xQjc3uCDH&I|zdw{&seS-TW7Jb$5h8cO3L~1>IpsXLond5%B+x zpsTOT{_F4OId{FmK&>NunOZyIFnG4}w)j|>E}yOS9ShQlL;9;9UBBCLcjsr0e&(~U zd~X!o{wTfp)ccOU_UPwddFAL!uRZ$NmtLbU!O&)V@S*2l`jA0>`}68fKmPn{&prC|%TGV^{A=HvzVxhv4GwHGxNkrD+6SNh-p_viwf8>%nWHbg z3Ta*q-o7<^^pVd#PgAda`)kw{eAAE>zyGD@Uwi)P7uD7`JIttK4Q3B+H_-p#FCGQ6*WUkZaQLou zW$N4eUwZcF>%lu+r5@uCf6viZf`=Uz)UgJI_dfmF)4?NK*3@RD@5;&Y-lO03`S1SF zXP-U#*h^1;*NaD=4gSg<_QLyLUH9bOB|5zL;`1+kclOE=#|#Mc*z3^orKewXm^|_H zOV5_!Qdc#Ye(34feTN_Y?B`#4EqIT6LJe!5JUX1=&yx=oBL3*p&pdbZr{2%?$vCW2Ej@br zwP&95V)gMM$MpBU^7Q}o_$yC;=4kL_-={wH+|j3B{?vCp{p!&;>gfrCH0+D_MIY(? z#Xso$cog*gdKgB>cD48~NRt`!DzFVgh}w?Xfsf0?OO)8 zCc(idNNOtR9&JSZVP6ub_0hB&sPyN4o(g%M291c~U?iG5OGz^viRuTV9SPU|M#z)y z(InU%1&88*A72g+Mq9at4+ZrkPU78B-5w<2CPT~qsF`Hc;h98zXTvZobs#D_Ko`O^ zcmiB$o(_Cq02CvSVwnEtzwJ<@C`XSQLyv2JgFXtq(4!Znm*~+}3cG|}ltdmqC{aQ$ zotUHEMksnvO*c41uZ=eNMV~3>{T%zS@3+G+ZjZeo-HdgyK4gdoZ4r+>;#~V1u|qtg z>kSZ(*CQSn;$p(+L8zuK!2MXANMMgRPFYRA(>F#Nfk>KnDCqmYuiv2(Gw4_NK{1Ak zkBv6tyrsaAt66ijqAk}nKWSU2Wpw!SV<6r0JgoFB?E62fqE^zCim1^C6SYhmN|=^3 zfmX_*W}1+RTI@wFcA{3+gtDkrMJ$QL9VhI~2s(zN2x<6%?GU%DGkw2#eHMwcf1xrr z`72TuCv#F3$yu}JB~839q%f(im$u)jTCbAw|HZ4%RH-Xf#OZ~U=Yb%2I57TnI~Afd z{o-HlPR-q*Q?WWF<0!Ec^CUefrRnQ`xjVJ;jq21NRmHDl5HM3_wXyj%%x5HH7bZ0s zyP6q0d4ukzyuqUUsxH@hkq$H#FqQcdDS2i|qQdrjMR2@U>W+ytQZCy*PIx#H9gq0gFFkP4AQmOEiuvPQzlSm$1(_04 zMZ{D^|D(PymmFKY63Z67twe4k>El#qe|BMlx3%PA!>i}KhSkR=mMpEoSqa%jcNyok* z7)`&_{bDmtJHIE1UnOqqpxs6XHOo#61bu{%a_b6%oTcsOE>3%1Y<8r5-;;E_ntrJj zy=cf{eub{9u|qZTv>jm3HxUtZT8JO+5AHN-L`P)35$*x#(TMmL_e0(&Z4u}4=ZWoL zsdzp7mhBA}0X75~TUUZMU16Ys7s$IpZ59vL*7R7dijjzcLp>1c!K=8-kimq=Q!3fK zuH^Q0C0o~&><_k8N<@@E)C+Rz_5El^p)K>l3(Zm>QHTz*w-9HHjMH=RsP)d71&BhJ zCJ1#@MJDdYJLcEz>ku0wSwT8xj_0b7mr8^`w;~n?&gCe7tB9MIirvR zkPSd#EPVLV~i3iOHlQ8NXb1Ly+kL~pA#B2 z@r13dCA2{Sdo~tJ(w9dYkT}vv+u4pJ?)$@S(crPpFZiMPe4GoVw5|}BS~?wLG8|(@ zqBAjU3+r#1DeFw2dM!;p^K!FGakbgfX3t{~rzY`j^g0dpqT18!Ls*;rdOQ+M#Yvy% z?<}gxsJ^E}$O3@@qbObHroS;jFIpHOXxdYuDTtZK&T^H^&c=u0ma{FR$v~N~OUCU% zF&8vWf=0RnXE$g+pKSENkj>dwd{> z(M1R1^pToDxu@E}fwmnS$~wqRe`APltcKRXftz-4HFVI)P`QInoCkad5tkkbL1UmV z=}mg--!InPWz-bzbP~f!PqwP()&CRcfREI~MI+KF*5^Sy6ImCe%Nm zEB*6K9aO9Xdtj>duOaJ$P@1^WS+0|DvloV;j@dg2q2%ofo@B)^!p=l~|4*U5O2pv9 z%y68>J7kt|b}h2k06itkNSHb8E#ownaaPCzT|rh}=AqzruN087*SWb{q}cpgBs4;7 zXP)PU1kh`ckZWl4WK=N8fc1*yaT#kl0(iJ0<-U;7dgs-FT%&FQ`l! zjpcc+{W3(B6q!YM%6T2%Ek}EkFy0|!iSC%knUu#-myQ#-;ic$Um<-f0w=KA}CpsQC z6h&P%@0H@Z&;BA$6zWI%b;kX=%Ge3XuwWU3_N^Etd#BO)XuyAsO(5IjZa2Hj7D(jp zs-XV4y`e6~su&{RnD{#oSF;*v9gG%r%PUz_avn^MxYv@- z`lLjo(V1-Wl{Ypyv%tGf^Uh|?TjP1l3u<|JZOe3cUd@5QSzTelS(N2 z_lN{9%ZVyIq>lI!CzA)GS=Hlo@3gP-G*y1Y!538~gJNrc-jU{}WHUcDe{y>x6T-e^ zOR_Z?*xuM;vfaRcL7`?(qnEp+kN)<_A{y(w3qwesvUteiY`uoCnEIvDC3yhDgVD6m zb0TocV>%6{2f);E{eZM_DAUGt!cmrRQf$pBdy;q4#EDhTQmUU+oe*}y*F8bqiGgNB zxQqUINm5Vg`IejDBk71Z+#4uL`Z9HS+y zDR-}{Iv3A#GeNNu5WOlLk6&gi0^%wGn{ohOBlTgiAaE@*CPw^No}H!v&d1cHK~k4_ z;*(**O@E^c%;%kUX5&6L;WDWN2g7PY1-QDKte>ob0ViGM2!7m#C^h*$uozR`rjrQ1 z=3|C>(u?6nOklx-)=N#8X2Zccew@Lil7@88EM~f`pd8xHT;;)NSZ_aK$tenG=1H?y z5BA$+&XVB|DZYHt`+!(5jBTIQwI7EWyYX+*k@Mr9(b^{{uRRnz>3aC2R8W9PZ>fJt z=lwBSpZ_@b1iiR!Rr*hxYhj1EInXE+~(9e9faNlkI5L+nUMSOHQtZu#m*B3o z(%aEidTAZLBE8)70@M=B{z|InHJ-Is8%5I0oV_47w{sH=E8mKb3 z9cyUdO-HTo2cxhfGabnb&CosYRTCf;mV+FJG+TKQl=^xq?Gzdq80V5oS?al@&tXxk z%aQHKa%7f+&V=U%Ip}hBtSmM(jI7kw=x~6TCp8u}xUoSl`D>ESUyZ}gj24SQP7KHC z0%gKZtRX&zse~_PQwiRUQ2M&}B4PT7*|AbGt<-N65J`AKil}5-n2wkrWcf7LbrQ}p zVvi)Da>kDwibo8vno@HU3YI~m^*7+JCKS+dSoJ`tDJzIF+;lnFbhZ_fH@t36S+U$O zjX2a1P#HDQ-W`u?y5SHQ8$a=429z5<&*h}knxkeYIeen@jB}pe9k3=(2{e?_0y@8_m zb#J2r>@FQ`b`~ZIhGa?WeiO`n3D^EcKdh3~@l17dT*DM1l?eid`%l~qN`KifIg#v? z{h{4AAgDwV+#%W?!m^k@C+H!+x$S3IPB96F2f`h1H3v@UX6IYY!4u6Pf}o*KZa-`Z z;V!u&L9(ETKU7f1RUt9q=j;iETU}K|zbBIN>s$Mh?xZ72$SHf(1Q}^ZXZp3T#h+_- ze0ZS4xNU6MX{b0hC>3pxWj3H)85`7m0}c7}W`m0{Z^DT>tU)zzff>w$L3(Iu6Jqei zQIIqif|xPmt|~JmnPJ8Z7I{H;D%dJ!NGLOA)Lm8ewaln*fEiBpME6Fg!X&9=8la2f zmd#vs7~&1$WResK6KxNK$%}6_hl;LjP4r`{jQ(|A?{53L7t6Z64zi~9=#*>xg@fpq z^i9g!okj$-y5GZy$t4Ru^%w-Gf#}!%YZvoR8#>y$~P4WTA!5`eN7cRU{{Cqt6zUvV1XOkj=0iV(PIpuU>3-}^rC=2-T?f6mC9@Y%p-t3Yo?Ru-hqJQErOl+fHW1D_? zE2f-eGOg4XZgquqs{l%!384npS)b!`Sxi<8TwiS7D8$A&T$kX$rr3Iz*SI1zFFUDu zIiIYr49iwaYtkSNDQ$60<7@pI#9z6g?HQZ!o+FiEIre}F3#~W6himw{HDOBh5ItlD zPI*J>0MvSwrPWdL4!3k0n{+UG6687_3O?qL`%0`HNi*GAZOUuk$hr@_ltB4mHQD%BwZSn$zE_PTX9x-Mfi7tf< zMYt||%QNTZS<1sgJ!VvN4qa39*?~oxa_PtFkdU;x4UFcvYGgFWe83bm5OihXL^@-O zq|6IxEsl)kC8FbzXhm!D&{k|1t4u~Lo#2Z3dx_zgQ)Fcbv|M7FGh#`wKiFX&DG7*r zaI>v+iaDeo#oOksz6vHp`{ zurv-~8>YIrKBW>-0=%yn_N$>*hayb)ct%m`^%E9!e9|F6CKw@(g$wg(Gzwv9>7vZKMxC1+XP2f89T>VGCN=a^$)Igl2% z4KriPXni+WODS0rB!#Le>xc9q(c4CM$7rt}*%(=6^`Z=e>EOt%IyhG|f6qm#J^h3Y zl!!KMy34K?3;tZBQ(g5RHGY_xL-0PB@@GY=Or!*<|9LQK<3g=X>qv(lXI8T#{dan< z@QO?oBT?A^El=wv*is-H5X#VD3{X1wEhfC!OLbgJOva#;H?%)p8^I?W2QL zlirNu<8VBKkO-)J6|wbcuGXIu!xuKn@CDHm=v!j=YP6o=>h@ZOt86X99eHlfaOU-l z;pYm5pQ|ujiS?OKxrv~}8AK3q^;*Q>tk5Dj>lTC(6QD&F8?4cyQlb)*nAu-$oL%zs z+=X3Ig0h|cWu7~4IdZ*OBZK5@9Tn6OcgR4)!=-kD3YQG<7(z`h+x0$*@Z%x0bWb zY~)F*sW}}?qV%lXt3tm#$i^7UAAHI2DG443-ynGe=ZFEk8?iwQ>~JHMJc;O67^=EF zdD_O<75weV_{B|sqX*=fsG(!|Dma%%Y{##0byd?kJ?jHrn~egCH?+bmWb|jQl0hui zzUI0>A7w2DW0F@|A%m;Hs_+g0ucg?C^DM*_lnZeg3~CWj(p~?Xj=IK_3uZca=cj)f zl3Th_)!-hNZQ$*?xKRroSR09SgY3_xU2HD;D@myW%V zj(jG^%G~sS!>Cf{qUzjYGs{+|rjc8r`c3(qB`67w2>gTk3H2gj@HEHdNgsxlic71@ z8(n6gDZCOfdf~cS^f-NYl!e&Df0oHUBN2m6ACweWq=b7+qudiqy~hY}F*K>$2!-n`n2MXl z4%60*0=N3OB!@vFbz)*>RX10q)?M8T)ZJOCdw=i)p-jqn_=;IF*_83{;gE$TZmUwI zF=zCtlQGm>{BZaeI##tp0?xMx+x)`Ffh*_pub4+Wv}F@ zL4##qOfwS(#z#!xk*5!sW_!!kUd-J*E|I>U#|_s^ab9024uI-`(dsO&?RX(QE@4N{ zwDQo#;D)<6`h-Fw?9xNQ2a#=?)#y+{x?A#v;nL86z|MC~OC*v`!XQ~W6|Pt+$Jm3o zV65^HB&H$DoUhm1#N@m%TGx~Fgf1}`TK1f76A#Hxx+Df*e=;?`Y;ic9>;QS`u~Zh# z_1)6Kl51>anE&--hisJB@4aY8zL2vc9hM0jCQn2qY-RfpZzJ7L@awnXzqV0i)N=GR z!dP?ZEYqNxhS(o`)a|}-QcK$936bjA`j^Zub}C9{U=}?H6`>>I%X|obuNIN&Pij&G z(Q%P#kBe0QOBShOS=bmNJQS(Y-r7jDTajvd(gqK;vbvQ`)LcZy4hc9@HBqH>Tssrx z2LD+~?)t*$C$!4bk>VKWnt__LrnN@MhWIj2%pEqZ-poKnYYdc@h?EVK#_s+%-JmZ1 z&aE?0Gu}Y;=Zf4vnugwnP_~>c7wP-HsF>v>)fo-Lu2vu(6{4J_3`9Amk-dk-(lE>+cfKo+trIUCaN>{hcbOuGk&% z1n*EqM>bn%Px>{k^vR)$6jS)@sqH46X`>km%ZH63A`>>=I|O_V9L=dVHi+9*B_0QRZ3L@|`z z3iA-uu&f;-6~jB_x>l%Nm0j|!ExXp3E67@7KyDC>;;p^Q4uTy|8AK~`5Z64!RR=+u zKZ7{#A;!6?Ph)mXOLgEFt(8d+!SXC&N|HOPMWY6=YTr zrB;w`gFtT#0=FxO;i8TO55Z`{Am$xJi5?d`1d*IUoOcjR8fJJbdx(o3V#z@;la)bS z_7E!`f>D6**j7MX^$=G)#HxcR^>!L6i*u~@Fg&Il)k_eQ9%8~n9Cr{UdXVw6I?i|q z23f+RRL40FG4CPHI*0{Hn-@nSeXC^5gR~q7$;1re8dDHr`xSq^YS(fzOO&WHWTXs| zjMN%L7JVz{eJcyDl@h9?F|3Xy4{^akl<*jrveC*ISK-rA&|M#O%Gvi%wFz&RS*z0d z7A{+=7f6@|=4$XlLFu#$WvZH?e3L)zLV&=VyYD89>^3JWLx&NH@&hlhF}ZK&h9Gu_ z%tL=e)(5+kd50Suc2VBqj~_?xeP33!Z%?(=8c+dzZ98c%9u^8HhRu0{pAX*Cdx#Lk zC_Z0eEGu1%TrGQakOh4PQX=_;hdAyb#_d|xxRV}&#g9hvNe5A?W5z?A@(|OyV!aCS zIqxAB?1|-X*9gZM4>2nU7|Tj})lt&Pc@M!*)i_CNS9O$h@{)&GwkMW76-3DbO?vT} z@Zxh^SBU!@GZK9h-L)qq(7{+Bn{;-mE$11?Y-Ab8dc^-$9L<_{G_c}63T9DA+cPWqEhw?y#P&~~xaP0&U( z6fBg{wu$_t-&Voe;^clshMF4!7qGR|a|J`nSvI552r0+4q!n8z&-uKLye@jb37!d6 z;LR&|S^y{v(@+yuy^X$PsL?AUGnDihmO~8|7WJUL1cS=j_9gu!T0~MeSE&7C{lC;4 znoPnsn_AV=`^oLe&{rCgrNLa5I+DR`8Qu+qsWjbH>aEKheNc%TWmwFhx!C{_O9Pd4 zlEi~bS|xSMd@Kcwa%5seXBg?S-dvM;Y$f7Xmlr5UfbGrR!x&(e*1p-O)92n~=o6By zT!&D;Mxb66@|Fx}04L_!g#TTVg);p#l&-(o2%!ih9ZdQ~R0<3Eebx$?cFmWR{psC3 zw_^=L`=_O4(HHWikjqS8ht4(>5(0*&LmkOOILvYf4A{J7+mzi&C&MhwfUDUZ9cRJu zyf_Ll`5!k2jLGn}Bk;B(Ga^0dUFl9)liqY2=9!zm%+O$D((u&=9L`uzHh$0zu@_zY zrIlQz@u=JFh}ZSI9W6a8$CWK2a>E+juuZ1n!1>?qXc5ebGh8yavfJ^Bt(DG}brAs# zDv!iq(Aze}-_0Rs*68-@$&i^faySmnp|->3x|uc5L&H| z)=e8cMEp0{Vj}Cd$yqlt71tph^xaH#xjk47* ztxZ~zxW$y-{Ysi!8R)W5rg<9zzZG`ja>B+?bR<5)Zik^}T}x%^NICm8Ist9mj*YWr zi?`dvBvM~bwtOo$E$$b*m&F;7*v|7#re#17S2WH!vLt5fwM=Wg8 zOnWyo?&z>zuMx1LfD^Da&dGrL-Glxr zT)lwnha%))OcjjDu_xf@c6mUs$ug{R&GYG0U> zwN8_@Em$7Ku>|K^j2vv3dLYy+TA!|?Z#A@srAJn=v0YpoZtQTqqsv>EiI=bKWI@|o zjk_NW_^)vXB-p8;^g`Hpo38U=BXN%!$z6>mk8k7OuAEA=8zi@7gc>dpYWV9T)T;T< z4G90s^c~=Kbg~6wrjx@)r>%W#RB~k4mLQkg@Dvj1dyLT(>}YOs4w3t$DRECbiiNtl zUTnIFUUWFguP2+H(A?%$M`38aIjKp2atpOlsaf7AF`lAsfGfmshG4VBF~b^)Y?d~g zIk<;&*wU|spG*H+$UYMgTt|bgQcgX97R`I1M)SV)c4Fi7ke#5)#41q=*Nlm$w4)jp zfsFFD0X%L%Q}?DdabS&Qx><|03J1V{SCV{Pl*fH=<)3*8h0eOX|}AH z+hYI%JJe8d4Ko7Vf^q1+}q|2w2E z;8VA;W6`wSEu&#==_n-Iim! zwM#Z4OtvR?z1bAu`3JG@hCsJ@lese|)Xu^vegnM6fei}d0qDe>MJ1YY(Q`p2=Q@V) zuMo*;ITW)6JwtNv!*UeejeE?SHjp}bkA|o`l=l0_TixTjd)$w#Qdw?9x%WoYRM>?L zX%<}EnhGb)#vP!Co7sWH$w|9kz5%vV;K778p-SU+i(ZD3+nbwYJFw}age~>`nEI{6 zGJ?XO#Lh-gG2$?UWipMFNdhn}Z_pTGPPsXR2*6?sNAo=zPKk|Zsz+}Qgc>aPUo6pO zkyc-FH@fINuG4O9!eAP^kqqaNOLE6|Dt2i&%@v&yOa1#!lgZ)a4n#Fq=v^RBI}&oq zVR8qeXd3*T`0^^DM6^T^*5p^{K@Ar9NS2w2P11P2$Q8O&N zgE4=<4S%;u5~z+bBWuvzFqYl9otP{9%$v;y9FSb^{3X~RyLB#X>@xM1iFCq-4`S{l z*@e1c{y6Vzw0UQ;+5Pe(Uq9Y-Wwx%(4P*PpqL2g_WK2RL>fikdWTFwJjAzvbLX*Dj z^Ud0;N$mxj&5etJ5Q0TwmcL_I;RvB6<)&GgTH5;(1KZvgUq}zUq8Y$7czCgolPWlSCE1wN0I|YsC44Cr> zx`+H+V3IcpxM-28n8j4628WTRv+-~!5hfIDegZ}JCct5{ufWC$e1XuvBMCmtyPQ^% zID`_dW;SUr<0RukIN)XI>4;YsptE<+2-m@O`*h%uq#_V;V?#|Xz}AS%qj>oDpL6)bD2 zm?NZ$6~_p3ozB=m7l7iR%3JKlRc2pHlNQ(S##NS_r$AS`QQFc67Jjb@sUHZ;Iwz$K zcAzLCx$cujWbRFq_HM)$$;)d6Ejr8a*6r`2s|s1QZIZ=EekTKOQel_Y|JyjY_Ey6t zXgUxT)>+w8>eb;P6xj}dZf$k42S!sS{JAcfVYy{?uWXb~E20z76*@^hwcdl2Dp|Jf zMsE^IPvIw%jUbir7ZiK6xSyjgm_zqQi(N1PW*dkg0$R+8-L~CabT&P)95AU7?4)(p zb(LsI{pTGLTw(&xm`ZUwux~;GckCM??~i@sSfq{8U`aFpx_YFAI~C22kq3==c?6w` z7CGMG6G&)dA-dV&sVKHv0ZEB_HP0FKDP`Y@kBeF=5;Te-biw(^cd9GSj z`onsoeqFIHVk&J~-_=rcKp}!7&Iz*Eo;V)D*v)=Du4`nwG+$Jrj@!u#b@Hve3ywP3 zl*aX`vmojKUD-)$vMqWHL63ndJqE;KaAQRw2gg~=BYH5GBzkaC+&X$#r)`6edajt< z(ZsGy%@o2e5*dZ@^bRH&)cgsGL5#%>o1iVH1<$tH*9%I*^xtC&W;Ut@Ga?tz>rH{k zg*;!+1{k@piiC(F7Yi9hu4pZ}nnW<<$~uXCqFy)CLl3DNuFwpC zRwg&_EsZYc0I>}+vST*+80A*t>vkwp8>P;ar~`C`IzDr1J9EG~b12!lD@oH_2jkR0 z0iog>SKv5~iplhw&d8F;oYb0q$V}_qiMxDq`&UFMTYSz+Yom;jNw=3HO*F94Cu(eh zF5GF2ZWb|UQ#}M~5Q~~5F}+iX97@aoO6rE&bCCl#I@^O-z)>h$|95?L8yAIut{(5< zrdzVef$5emEov09tk)nyRx~X9=m3(>YV{IN-B~)h`P?YRSGz1oxH-mGyTBOeD#k8I z$S}_K{rk<3HDzB*CVitgt!xyh72yPQ1t-}K9n-Uwg_50ap(J}*G*0d$YoY?eP;^OK zi@R8fCmSQxGP@z6kjw~zE0Rc6P0K!5jdB$(Trr<@jiWU*W}%mCc`)usM0Yg(tS{x;wmE*3y0V1*=>-uHaM_5j*o#4$DMjppA$y z24-w45#c}(ct9r7<$X{?D7{S#&d&5GcqBVKklSJ7NQZI6Cn4cmHieZdZD}&1WMXuY*zRBW@bjc2fE_by&<+V8d$Ia)~05(!dLMJ22`hVoX}^{g;9`|Cf zm{)S9YID<)Dx1whuw21AGk7esMg@$-Sa(#i$n8hO8i3k}m>ccM#g{wU-F!qmCE5X9 z*}&nvEzEWPEgL2{|At`;($mXenv{Iege7j~*9}X$?i||@Qb{h_| z(U9Z+?hkRm-gVn%gj}aK+QspWc5z%?1iI42c3qQiiI8){4*GZMyis0t$p}s~EcbQ7 zQ9xg)TG!Wcr5vK&>gxo{0;my|vi$VxKxEF z=v;cQ^=Ng_^@zkZme}`5Xa4PuTSE#aqV#?ydh-4a6OOFu9|nOgav;BTF^f7hO2$&y zL@7C<81XRLUWu3*CJ9GVVY4J<l1!8w_+zB85`dBDZC_LMI;C$ zyXXleNwcQBn;o{J?-i7SOtOtP3^F4(z9O_CuZ|ZYAHkrCK$InQwnEWD)vS7@MW`N) zl{1NuSU7D4o&1Pp_N2n%`u^aKCXwv7*w$rVqk7q|Nla!gk}kd#mUijvD2loj5K#Bw z&nX{5tf4pFJ$b?o^VV=(;0vA6h*i+8xP87UA-_6il%)FIxZw3eQVc%PGy zlkPVg*_*0KsFA?1psJ>50p|rpTt^*x!dL9?Zbl+TR9d&igD~5L1>pzy&De9eiKEVw zvD_!+WUNi2${=4i8Otg7*j#q_F*K1_x!rw{*I$N575(ih*7O0IWzpBi40BE~vMoN> z4^ro(7(iD{v0Ikb;Wx!uLP&l=!(cnFR0%-R!DI^{Hmg2NB(bJ8ic?p|1(3d+Eq^ zKNS4?!6ZoTeIV?AIJ~S|6mmGZkI>eg$n&dgsYGKrktebfc_N+2!|j*ci9GCR=cRPD zW0b$LpKjX671d8EdE*3_v&JioXdl_EH>ArQ8+7=~3iW`lSSX3cwb)V*QXBfVtw~V7 zLj>o*IE1R6+^2Z0?vCfFD-&9?5x7ondyCV{_z_to%nvfFd41Tgkys<_5sOT1#J*c* z8DZMi*eb0x&9wxmhT2L9Nh55it+{~y#vWa|8+()8x(w=4YnaXkjeSV+eq~C$!L)6E zm`cA-TQ-fMJqs^mlOk_62_r#@p-_{hCNAwsZpX&v$}I_sMcdwN66R|`6;&oyiBfL{ z&HLYEBPzz=M6%}uJ-I)*|3tF)L}RZEz))%{DspSS zF|_=O3Pa0TV(?K%Ra;x*?e+wC<6X4`N;N2BeQTBggR~|qw&(=#=9XYl0tj>^pW{uy zeo0?$0``kU`^^MMbN45EBxn1Ry^^r~62WdR%B^~n?=Jgzt1trlF#(Nzs;RI6lpV%E z8+fwMtZg&e-nictV79k6_UU-S_C^QmDTgRrsnsOUC6aV+R#^fq@yc0JvCQuEEe=_I z$HL!HnV&h+A^xlwyzF37nIC+E1x$Z2;#+X>K^hdTVF zavYZ1o4wX%=N4OH*v?`b@#s_D?NaaiMK3ebvfJj;6Uw~dmf6mkHkdPQUx{f2F^%EI z8keMVjPmK{P!7eh1oGC5S4{FWyQDq1NAok_f<^F*V?6I7D6E23Fp1N{-eoIs(zss^ zp7=%=Oq03$#-8X%;X4rqX48{Bdc-7psHDHmpNEw7Ws~PBzCZsVF=I~9A#c8);X`(; z5)?FnYev{5&eJqF6FK_f`=>Odvni~rXmVx{y9U%hZ|ZbpnVGsc?Q;F|burVU6||+M zj7YMNsi%^?=hkXCfwojrm$xz6JdkMs*&(Uy=TFnt@lc|( ziFoKHU+YZ1-X-9=fbVj^+i)9xY_{E|UX$&5z+5bXo!oy|Gyk~$!_ktiSPaRz%!y6( zqZ`S===fmLfjh_LiMh~}Q2U|a$KEc7wi^bfuRj;Kv!Q08(&pIJ!m=R$N-d!LY0P)i2T9&YsO-1Y>bV?SZ;I1&MK3oJs@s8o->vrAI6yxCt|Wdvs+wB-a4T{ zfJ+1zUww8NP{&ilU(o^3JN`m=I&0_itg-&>csd)=RiJN;r`sGSx8*#&Gw11@Ri2`R zGq6cKy)1Sq(&KY4x>X2eJUy*no~LJY?|6Et*C|Prr~h66x5U#G-bh!Br%J5kJf)}| zPy4USQ$`|NG@2v8W_1yXfI!0s4HA$CvnpD7#L0hu*Wm~cbeiX{E!|}7Ff9Z*J;qm@ zBS=w(;6P)9`3e_F+}{_O3CKN^jWA{IG#5?ugzIquyv^ z(tb24F~QW?bQPlp4HlFwz?^PI%r$6}hXFC(z(3&}@=P{9%D;@!WjpSGRU%i?WKxLG zRIZIT2~%atAS82dNwx^ar&{~lj#yb(>WmpT`ZOR$*~O{mZSt_Eo#4+aP6fKMyxSUY z^r!9v)wZA&bP`ZwH#+NCwTmjywk|_BatK59s^M*qE2&h6D>wc6%1=7GQCw$*E6~Z7 z@```X{0{)q!RKPF(hLt`IJYcM}1J|9c$%NC*AtV*thRQyX5at1Z@NW;$3ZvtQ z&|JTKbOO=46p{@oC%FZq!7%FpmV+_Y+bd4d$OZwsXwkMjxmN z(rL$>>U2pvL7EnGfUc}b@)BfOwGwkQQ6jCw{RYz130-k}s#kH#_yAq%N_Jsf_PNvq z%LRT*t{D4yUO?Inz`hsVQZE~k76zgtMHt$dE$ZY$Fq#Oo^_*`vyYZdL0e5``BJ$|L zPrhPa+6i+e(#SUh`N6Kv&LE89PUg5QJpvAI1F1cRl&#=+AONMQ0ga;qeb5F7ZFq2j zoP0WgT#{_@QC}jju*E&MsLj&R7Q>;XyIfGWOF$OX?Sk1!vOBhjaToC+Z76@8AKMu4 zM!eDw6)t+*}sw)DZTPe&1zd=(JE|3G=M3 zN`W4ZPU*Ij&u5b|#5w90O`wN!x&^g5tTq_y$r%U!x&uFrv3VfeEQ_k1Zsq7Zd;W0v zTU_;ZxqqYIE|GOfw@zR#>Xvz3M5Ywtb}AC;v`DB^kr20eB($vhmaq^AHGVS(O;Q zP?eaL$RLR^(#{Q-p^==(sZUsEVQ`hslnZPVk4cq-4h!LxnYe{@2esfq3oZjI>**)x^-;5qNfXt z-QDC*jyFXfZ*vBgkfYl>IHN-TTqN*=W!sqPY<50aW*PMj2g`mr8#8TK<(+t8 zOl(|Zk%n2k5_}i^jU^`)|uFluk$$Xll6y_FMx(Mdv$hAT|2dn^X~5xc(xG zTn5R+rgiFNM7?V;j%u;x_|{cngSNZ$8sF@B6QqhN7;SStjH{x_DX9??QjP_-nBC7K z>DEnpWQ8OBCjJOf_ zZWlW3)`r8)$!(7|vuJ8_wJAjs6uD+- zQM0)CsBKzvZXvqnMEcPjn;Nkhk~(Qfn=c{dsA!4t^A2(%m_x13@S|z{!s94=(yi=? ze&gltx2Ehj_L6m}O!L_;t*(SLEDA@$L|32OaPOJOC?iPlF(3n`fDf}Zl%+iI>mv%_ z-J<4unfx^8m`<%9EZ?UToF6Rz0UL0%d}M=zi@yxDV4cn&Gb4k=%jxE%Feo5KhbIjw3GIhCq|4HH9%&=*xN=^j+xX* zEIodoyXSyByXWX@JMKs2kLWXEd~RgKfoQCzdx7-(dqBwVrKj(4AUbtQ_W~L6_kifI zrloroQ?Y%VFGlWh&}7Tf)qU=Mi@(>K9O`A|ym_0y-KUi+RPum>zQf-OnnU-j9Oyf_ zJ^pq>{4Q>%->!u#aXSA^?kx_^vwI-#_P5l#QY#L=Bln= z{$`HQR#QOpw?%`yShnbn&yLgXhr{UyDJL|Y(DlNdf>O=Y+Z(82is~oTq}1V|;EZ%2 zK9Xbc3!G_8yJx=%&~1!A1 z-tL;g;z+p1-i}gcRt{ z_cpQ>4^-%}_yEf8T?haR^rE20ovw45P{_K88JRdB!nMY6&d0gclQ9)x2U_|Kn~vj? z=jD^Hs#P9b;aYic*%yonavsRj{?)wT)PZCh9JpULQqxowi@~{0Yb{1g498+zQ$=5D zjkP9Ps`rXeJ9(R!BQKdVhob8+C%G3xkp9fiOWKCDgzOQf$Vq^v6RrqTPOe8*@d(#KM4#(bi#N(9LZy(g>=nmv+o)ww3;=Y+GDxeWpE6(9 z81Q4wWmX&atEE=NlO1g6*`o)unZ4a3%MGRK$sWj@+%Jo~2Z;>wt>zod<(0Y%}#%K3_LzQ&J z9Sd>u&~>Fw`#|4BNi7m;r=)pM^mQxg*}aG2Wnr-l7PqFP3@7)>t7lQG#wVGcGEr30 zhRy4>q2S%wJ+QJc$fw1UGecsfD$H3)QF~VY!%1W1ajHrANaFaOZzwAnoPvCEb5>3d z(LT`s|FLp>4`U%=F$EU4%u1Vx;gI+HG)c*rt9d`xo8^)}odzEqs2Qg{VF>`T1<8Bl z#^Pj;cVb-S#G=X=Pfwi_<3?*qaZ4K|>bSZCbh4*3w9^qyH^esXOBcn294cr zu%NOe*)39Akd4dL0x)^gT61_0d8G#w8<0}6?k#7Ck>=;{)uB zJntM;lp{S$3*@|u=WN7N2D9kKWe)&zAq`;2$2Tw}yUMPf4Veh0isBUL8<+?mPx&}Z zQZ+YX0aq@Rd(>9eM?ammp>XW{2my#NSOtSyHV+SEf>_vl<+{8e_O21cUSrdB1##{^ z(C~tIiTjEmUUUV8AYQmH>B$69pOtcg$U03C#su+yx2qj!j2H#lXiS4+jjIo z`m?eijXiEw$gQYoyxklDd70*Lx^RZ)%APmgo(!k6`L6@~n#zAYz^|758Ub<-zgFJT zd-^4Vk6c~*2^lygBHw;ETG92uVU5+|0(R%rzcTP$c10*ZR#`8|LV!xa?6?Q09 z7NyaY9Q^w5a&ML;+3N#Lu5Gd;l)3I6eZ3*U6p3JE`^AU%)^z zmR40HzUH_}q2`)=_<*~Vk5^}5v9sR@K}v#HPJDzFSb`_8#;BfYnxRPcn5NFM0?Y#J zS!$Y5OZm?ODLZbI4Dnh@M*xO1g_a` z-_Qp2NFFL#n`6DgQIZ9NH8azo@@q&aGcr8O$xV?Xcg{LZI%co3l>qyc<>j<>q=-N) z6k=i8mA9!YOpGL47db$Iq%BqCEl{+kg_Apr7I>BKzV76uQ*0F_SH`paRf^oJ)mac{ zDE?d~4yan`qddvVT)#-Gxf-Rx-P8kKorQmmVL!6ECwZGhs+>kG#;a)H8cQ+mRzKX_ zQjAL;fL>=QH0#5JkJ+?jSOJ2@U7G67C;8l5i<`k8He|`5GWoKHbu;dqo8(>r-;=u8 z`DB-j_^!lldV&gm0tAQbvh`D95!w1luF|o|oeVvNAk)SCZP6*rzMl(ZI%GK}@Y(vJ z4ma4N?_Mt7+t?Q~z|^obG-WiPWSIR;yzkxV-jX{lXz0#0$FKTx%?WcOv$lJ0>Q^~V z!=S4No7+bY8+)blV8QpO_KdPS6XaOQFbts#X*k!N>|>0KX~sslSs!xm&0$SGF<1ZU zLxCof5+<68vGRFGu1lK2PWbdOSCMOZ2WwM>%gPRsYX$rZa>eP7-#tpIG=LJym`-Za z8?~6=s^8=O_n7~EO_fs-^ZwLg<8pM{sxYM-+o{^@_IQ4)k}Il+@N3nsgp#^`iS+i0 zZoc+44ALd;w7g_lCHf?`YbjSrikwOcf1gbUrnO^~**MZ@Oj$E)FORsqeUy(r@a4}f z{FvV%+2iCC=J7OJKT?|Y{kv0UL1#6yyqoxmt4MZwyM4aK>g35RTapTrZE_vl!Ud}B zl~uZ&nW??rOkK$ejF=axRxe#pGZ1&t|6bUR-wo2gB3HQE)jHxXd#K0Xxl62tGOmv~ zJu){KAEA=#c&iQ0^vXTVzGHM42g%Bm->-2*Z3s2;X!$L6idp)r&KZxXEd;6M+TwaBK1|W!ys60J%7Ccp_VMbg zQ95C`QIkqW>7ULT+B!Caj0^`GYDM+y`UF~})Av2fswb)akcM3!wj;S~Gj;~HhApkv z8|3UF`+iAW|0z+_)$;P8m?d!ONM4II3?5(m+OcDQ4I>|=e@~=67`@0Xn%=Y zPAK5C7~eXpvHUyKoc_t*vv;257L1>A?>u!V-bMj4x;MaB2SIy`u{2S-q)k6%jGxqT z&XLx07kq$COIJ$Wak6(I?J!@XPe!jQU9mgDfp_2tr z{%ee_o?Og~x}5jz2E1X~nGbklKj5t~E)LzGx5Hg*LujZ$FQ4rAWstK$FCP$2&*Z;2 z9XXxKf5rT|mJfP4d@o(jf0-z(Fv#MVHd}9&bTHbbQ%THdS6A%RMO_g$4zP{#5wh+V zh*fx(E&1L*nh-5_GrQdFW1T2H*(IZbGNb%(`=Q`>*a-8UA8gIEroYtcI20}LQ(Dd0 zVUdMq?iH{7RwC<5KXrHa5gC=_N9eS9QgAs>(ab@GH zXiyB!kE{4Hp1}1Z?>j~7`W_$gL#kSN>N(5?Ra#jX!cMMkP(_uFO{I;gcGL$k(>2bA z*XSyw;WhhFqf|TBuZYczqgN#Y7>HGP%YIaYPQo>#E4R(NItOhBP_%S@qvoJ%aw7R0 zbWNimsH7t&p_(0rrO(idK!FhBJ?l<32h9Qz!(s_6_ySv`Z>8~t_*YbCp#)&Q(_J8Vi2)e3>iujJw};etT6G12=e?s}%Ecmkn;61@+zt zh)awWyUL#K5^#LzHcBU;SpoNx&L1!PS}*!qF9JPoK}rSs0=0IQYrOy*BNez=f%_>} z>!Ppqysz~<&@A1I(yLJ!hjY~0QLgnIa11UmU=_HZakb9-TF?4g&jL;OA1UxJ_3R9_ z*2=Y>0d84v%N4lRxJ4JUs+ExBw6FCv&`W||Dxh;|Y>|*EOb8hm`3?DsA0PuWp`}oh zawMnCunRaBPl}v)-ps1_w)$Lj%+#HRp%^|alts?WQII=V3>~mJ&jlqw^va;>)9&64 zMF7N$GH_sdm8(qem%(yL3sqMAgUf3kM3-DaX+DwToz=lHUbPimCp)UsI5O}q{|gq~ z6?2c{I~ZN10@?Q~s;F>)m-*?tmC@+t^sy7*wYpQshF*8ok<@28H!`O>%*e!;|t z28pjk$!7qQ2`Z0GqV&gHot$XE76=r_*LfP?>X?M*r>L@GI8Fgo9dQ7);A)&!je~p> z-q&~%*b$0G%IZByjTNIY2~+}9F^b^FPq`W=RO1k1HDBX#V5_4Co{v#u#bAs9mAO|J zYXIfVMN2heF0O@+lGhlC$&RCa-ne2QHk7I7rPX+JSpFsGyDPv45z=*Qf1Y2Kp;W*} z`ucwOvje>hCiE%Z@C$tX<%?XuxLGB|NOpcTcp>}j3s&GixW%zEFLO^y_7qncic^f! zrr(*@PY{SLTh-7goqnebTb61H-B|%bNDFrPsj!Uf69ZFa<-qXt%MD_?2CD52=#Gxi z0hV)UIX+uFsTGm{|DXT1Sy>fk{c5rikWlpG%f*hs37Ut3Bq%UWf>kIwDf9_NCp`KS zpg-|W)&9;kJK|jG$$hHHQcvv3iu;5Rp?;!c@*(zCZN=gg`_U$&CD)tm+`G_7&5%6D zQM=#(dc9$BHHV0H`)IGnUpbXr2UBgeRdH;p6=#suay^=O*>(nkYJPMaF4$?&%)fD3)P4&fo7oYjGoLPfn8wkx zy07;1r@;^{n&B!VF!O2R8zH|0O)H1byQ9czqAgf*d}KVz3Vm>{jYLl*ozf!vK)5AG zP$M%6>Wo(-^^OBK0qalt$Q{{dC^&0O3%x`K?ZQ3m_O3hn0Ao7qz_T5oeKe`6^oAW4 zu$q3Q*;k6D`)2GERUb`Tij5Srj)35Uanjp8>^!i`fd=stVr;9(V(;#Q^tauPn5CDX z0?y$AS5fA|OGHef%*B6iY+bCd)i(WK)hn2$iO;$nXyaTJV2yEAyAL+mk>1h|uGb9M zH~*HNTv1D0SM`Je=%ij(YcA=`K05*sr2RioB35O&R@!7LNWiqctSfE)zOMi6Yu|sE zJdJ-eCP4+X#Z^HY|4Fy6+T&amR`m1KAxW;a?V}qjTNmA=$MAEUM4QBKy~(E?`Dh*A zB4t0m9RlM8lpSs;!9#AF*(QH~p6r>9hf+EF%ybUR(z_hUR(~&$+x$KG?c3>dysB8= z4rd-ar_SeIZirNXEoaoRjJdO?FV)0xaKo|Xar{08>GGD z-_VK8_5&cD+HCjWnQ(trdPjMK`;~v|Uub4Oc(9B6$$#g7hPhw(f4CQ__wZxpPyHMB zWB&=p3eMz{K7)3z#}BV6yljPhPGG9QH}{*-?q` zDS7GM<8Ki&;r2{?=SRtv2#Xe2#2ZguHg$TKM!RIoZ!p@;h1D!lrU`2nLwj3L@+e5v z+2@_CUi&_T_uYr0GyImi&+2-CopavG<(#MNmK11@vjTg$$l5q#%AAW2kL#m^=gzE| znT4Nu;GFXnd?ubVZHULY3coS;JG%DWj=&litbBK}3%NgUF0|>|ZRX~vnVYC)ZnlE- zOQb$mRp-nBwQM-#eWk38l;^}YACVE;u)3l^3+yiW>(Zw!j^RVhc4Se-6gSG2S^<}~ z8meqOGu8&t^1l$I^co*d@UAJxk+L>80yZ__45?6I&+jx>Go-|RtM^kT$IWHcwq*Ih z)psp%v`g|FllP6rHgotTwwc$gs38QHI_lUp!Bqq~?tVvOT(byt^;tXT%0)c+ZsW{* z?9ADKkckzo78|t(`TP)bm}_yOe0>qqj_Ui zKyS}{I$KY{mIF@F&HH%#U$5=sx$gowOu!6R9q4+>U#C@md5?N%FXcU?%=IwFdW$A) zcV8Q>5##P`qr^Z=EKdQa|1f??k4vD_llrS1-sf~&bXRIZpIV%vGo$yXV+J;9U^-Ab zHAP4*v=M~G`sekSw-@ZXKRsvH`_p;5YFI!To^inax^U37E_ReXXWr$MSzazvMk{`2 zo`xbipJbZzNd`f@_BdEVA(d+%hsyiG;&3#rqCQ_ldla3dNYt6q75a{IEr(Q5%L80{ z3V`|DBDCR<6PmJ(657(Bd_Bn>WPU?OajU+>V&=@ev8O*DJaCp)TVHbVQ&nGbf!`v; zqOOx8>ZjG2_mi@l_frlq8#aH;`jCC%q0yQ1&|>`}Lbjhpgls>vn9YtL$Rp(Jgn}YM z#`eYIpLCed>x!*8%T+exvtdZ*B@HAI7bV|QhSOMmTF*(U7TW4iB;cf?KndIXJ#&irsK!dkz zFvBRxY5L|6A{RtKt-9y83M} zt8wjg^^K1My(s9#0y=BF`(}-|)-~Rux&>9YP*lgSA952T*FMgDFSB!8MfR&7XS;-; z=L_hpagOf1anDzOH&{dVRjQj)b#p~^{PJ@sm(@60x8fUL0eV)@vjy}O%b?Iwtu1O@YwOPZPNnDn!AZdEw*%f_5|pcYar)a? z>9B(`fpfXaf?|xkpBi9%%JEL_Vd3H^TSqXX)LV{HGin1$o$_s*qK*0Ol+9CFL8+5! zkwa^@mF?e2VCMuoSAqSKt9eQ_V}d4q&67a0Vi-lNKp*!t-&L;pIIuHk3y<{0h($f}W^A zU-mWcEZ2M)SdR5VY$~wcEUl6XJUs%GXd&ik6r1HB^Xm7?a{`b__eiuj)8 zxG$KY!d!7FYcGf1RiFGeUcpsQaTVpKz71(n8h)0_a_o{jk&92K%Wk=I+Nlq(nJ2-x zx`P=54*N|1v47st;5$kr(omsKb0vbD`LxTMQ42Mx{+V+9neU$T*i3kACctJ|(9>mT z9bY~7OomN?i93zbF!_%T6OYB&XQ%>`KKG2rV(uBFQT0xh>&;x*abbbXjC(A`!D2$t z69x1}WTqJ_&P$b1yk4%)fka2lTQ$iv=BE+t$6D|^N%q@G1Q1#an6oH&TaTT9q#}R`E zy^~88W$Pphm%x?<=Molv*xc#Thj|kZeu1k5?81j(UMFSx;9cRtXWXtpxwkA!=-u0l zfO(8G{;bbJ|AE{8y{M`YuJgX?^He=8=;=z;e#4<=hV!bOw_%4NOtq?i?iM^}e<%CM z*3fhMx7N~g>07BBdS2jKqUU)PFIiU9-pT1n**bcf$M^;3*iPz2Y|a!{)6{Rp^>EZkoGkW#5w%YRP4 z{00T5#XQ26sJ59(+dt~)by*d#@My)iy#n;Kpr?zr`L(QiX}&THTn2VZuv3+q$2pe} zdRTCwG|5{4d@n*2*?>8@mMtBePWh!awi6vCSM;{o@sEW}Sjv z5H|SEMUTxQ*t7)QDr1wbvaXhbHVVcfRLE<~Hci1cV%jil{T=JI;1si>ypBv;nqtNc zKc_!P1G|WDxk?I7eh|qWq)gyk7Ww95IiA88UDPWm&l1;?@+_+O6kD&|yM-~LtiAI5 zn45i^(u$Pqy^vj0?-SBUMQfm#@CHq*ET-CuJL)Qn^$%7MRol0 zaoSlmj?bO*jn4ti>HpZ30(ygjski=#o2NXZTCr@izSdc4wXamoQtMi_+uDRocv(;= zXAuRQWa!l<8+IwBHvN8tfLwHq>@c_K7{_Js_czN9k}}8a_z0NuQrqnM&0_@Vn!fw6 z#^WsglZup5|HKpEfYKc2T2h)Z6<^cW$y0kL_c)Zbm&OxcF*|qReX0-3!c`K#_&y?6 z=`G)-?*IoaFvf7f3H9$_YL>;J@n+w9$(?(1xoBKK3}Kd@E%wDqAbAOXn)+T;Sk9daA;_J<8g* z=Y#(X@8uPO|3$9G;P;~On<-nMvNh&rU7l{O#xKxx)!Zyl-Mp%sFRJ60&(odrjnDhW z=YgIR^jra*nVXy1y18|Y&r#j1s+%pU-8+UPqtN3^2J?NLM z+oG~H{JW{ez6?H9{#~Xz&L2bpi|Y90-NlL;M_n)Z#xDWABK2RY_~rSxq{iXj1>g7upce$aP(a@T|60ynEUH%A#d%-rd1{?kt@G6C`Nyww zLN>a;8Zw>(c22N!1qS^3iVKA2RWp)t*4KO%=vhI}mTQ)Yue<5q-4XlXX9O`*)VIMN z**O<$yaoGM%8}XkxybBzN&~}0{#+$M<0%HmM!JCWsC8#GroqW9=oM__mm%bhsMiN`cbS>75&?OXF{ zx5an!1}^P9SG9Kj-2`#BQ#L_eg-1H~ZW|L+MmpyJ9T(_$1@u3=S%-O5j4Gb>6`uvV zCFoWK`i!f1b9o4L2GFZoGI^D=cnchU-=)T8RWUMo+E;uU=v6_lR-jM0iYud-Q-H1r zbfp6NpIpV$su=w}=_@`7^s=CrE6|g!;@is@PXf9m(4`8f*Ubr4jBXzH6(0wBQP7J8 z^adqaw)NNCFlSt~GKV$hYaOH31=YGht%YvRxigsC40GlL%wtG=E5jV(0FL?|ZSF5p zH0+ijtK$!DVo$=2Gdx;8A&tyaFaOAmPcOU+e8@5{a+N49z6<&4q>L4{{2jMlX<3q4 z%V>*Lp!yuF3W_;yg_je5h1ak#$GK|Cc}%~V7jEfyX>L2Zs+M`-3ReMMepkW?$?kZJ ztt#N-CA5&;Wv3NyEiK#8GM#1Bf3YTHwFo%ZL5kYwpkF8$MFhjy5v6gq<$x_6?6u&$ zr?v|PDRqnDxp80JU9gRF8(1i~Py;)lD_>|;Lcx8oaqU7u8elJwTPPTb!udkMh^4Y@ zsnxbQx3fYLmbmqT_7blas|2Hh+o$a45r|_W;(x^_Ajlw0KLT0_y2n+#KluobMyLYK z-+9~AobeuIdMNlky`cfIt~Twzs5{tuo~y9>5vKj^AgXhEFd3^NHJJR)F zS?^&RC%Fo#Nst;Rph?sHA5u?7!?feCZ+Tp~K5uRrm5km`BykN^<_TDu?3e ztP*5!OKG(l{hWB%`q|1BHjeXKQaq+|Ubsfp&|&(k+2YsJ?gbUJPU&FkQxEGSneG6S zO}Q{{%GafB%7xw^nu2p-)2AU>kdY!s#`vbgx`-VQ`fdYX=)z{CL4%c3NnK?L%Y14a zFxw_6$$~FZLM_OYp0N#Fne6`Fo7r>aaXYri={IDe_qdEuhz!??j)RfqN;DWO`4n`d6lc3roeSLo?q&9y}$aL+6 z(jGpoI_Fb~&K4Xy7`+A-w7IHNJ`P5r55KOsU;QO~njtttWh5tP(pJCjc|pCHB1!r( zSJKDRhMnF1Eq6N-z1)y&OxJu*IX9#gj`rQ5+VIgdsfuKJKp^PbVi?TnYcrB9l;%L+ zuhx6mm8czxwp+1}YrgSzzBp|sI+ByG=?pvb9#p!_o+GQP$r6^~h;@Yai7CkreTviJ z(MAVH6(r+7{SR3$$-`4&gOADct6RTLhs_=x%hd}*r#RV&`2~7y+vxjs3e|v(F<8Z? zIkrb4X~C0ySSVy{yV zz!khiH~;w}`MMr`@KWrxW{YQO*w}>f_HrN_honId_XwhHPBt|H`GPnUw`p!>=W^}e1A+E;dRVhpzBkUPK( z4*3JjI0wKHV$e_BT%SYFK?s1W=a;!J;B7IFKN7tG{v#Y&wgvtqd`UX{2>2k&kn~~Y z`kT$IN%yCuYZUQix)VwFQ~p;?09ysnX#iUV(tjf96adxH-;w4f10IR?K|!|ngF41= zFio;08?Fq#4&r{Y9wqdxeklG3Z_K;SYS*UY7y{_FksfjNIT${7w`r4Y%`h?SV=tFA z5{SuwNKa6LO|F@MH6oPKOh7YJp|J;+EXU2wV)?~biWu3sVZ61uEn{vo)j1m`-1M`- zOUFw|KsRT-FwHp=@&L`5Vi{OWwgO2#?dQ&=L@P=xZSSPX*2Cpw%3H?f{N=7FPkN>Z_ z_kphKxbHjfdyfD~{2@USq-069E}rR_k|m0=B#S0xn~#4aaaVsBO0CkI#4<=el8`_E z20%%)8|&498>EYN5sGe^HJgL8Wqpt=+XLHdmfLb0)L}M=i*&JGHj8d~ve+$mmuC-8 z4z^`lw&k|_`Tl0^-1~qB5TGUJl!thC?%cUEbAR)j-+X_+nfVO|BG&p4h_A*lB(Z|7 z(e##~8Ydaxy@!gMoCLH^v`*|87uTqx*{QPf4a_l!xwiGz4L5Nj{6-xlw2`u4E+u3` zolC_TJN{JJjqxTOBqZ*ZFUB>rYt*(*{#F)>yOC!o_uJb|VXore>ExQK{g&yqqo~c;ox< z;~SF!;#^tyJl#_oY{lcz{p`!tkW}%hHM|%a~k42|Q^ zpx_V}S*>scSXHbmed(*55Po)r9GF3p6*O+lN(c3y`nZn0{i+EsgaK1P0VK6eK&l{z zd7_Ay6!j&8Q*r%+M1Umf@kLlNOy#4ff6IC^k2i-9XZD!<#S;NSv50Rn&ad*&VjC%`W&tI;A>y>O(k&!C z`dNW5paR(79p^X26cK9br$+*;L=aSWjOU<*7~M;~dN4Y6Jf^v@p3-F|j}g z+7Z2^6l}hCxbNn>_QOQ3F_hzD#il(^J=OQ6Gwf4A zxBY4{dN6MOFZTT5qTUd;(RaSPD;%Zw>{tXz^Ot$MQR%hu6iVL$5XWkXy#qj$G+F!Of3*BG9P zv;5PidHS@T$`f(CTHFn@#;fURmKRuiGfFDXu+U^)CiB&gv{}4noK5KK#Dd!)) z09YKJB_VxN=VtRRKOdYfI&O_U)57C=(5j!N4~B{x;-%s?~I1l~yrWIB0+mQwIX19$lihl9IBIHQgkXkjfudeyaNQLe6Sl1>z ze!BKsu6?s_JuN|<+G##mu|lJaY!Mz)3>SidB^C8KH+*93;EP^zm)1BZ`^nG2z@N+i zoV=PGkP9RPN1OFH=THR4s%p}@V1xVrehuM`l|Ba#Z(!nxtA>n8G@Eh7ISV0(hv7W6 zx_v7z(Fs+|G+D`$5Odody^L$t+x~h>84y3Kdz?xC-~)d14;Jy-defpfyF^Kb&6Sxu zftP6_%R5ira;fKV2sX+PRLqP@v=s={FST7J>kps^9yX}&w=^_8U;+u+=;UwFXjbQc zlR*WuEd4f@YJ_}aV!Q`5F`N#WpCGq=AK@hAlRA4E0RCt+t#B35Dg}EsZ`Xbf(4|)4 z7-~v4r-GaZUCg;}%Q5~Yp)evrl;CIUyMWNd-X{0Yxy_~)hpMvd)eaQS@6!5|15TRc zHP)?a`8y8lslTs+v0ai@mn5gQ`D<{Eya5bxRV@Z|b&~-77E)Qx+d`+^bM(x!`6Ima zzy1~DoUf!ofJ|wJF`sfe5cAzIo4U`J&TJQ->fVmU`O+C;JAaq%_9C%4`JYZsY|piv zSDg__E#Fl@A{AyZ56mxrS68cn7^O=@KLSgUy* zEgP%f_0SG(P2aV_395R_vrv-+3HI&NoEOxE!SqbOHuXojBL{m-4y#41IF$0UwypXXr!rfdCpbJq<_}1v(g{P=A?22ROL8+diZZP_NC2 zVG=sz%!q@abaa66JRM-n1?WJnpab5UQ##Z=Prj%lB0;@Kph-=`5dIS!334e3@{NC5 zO@h25fm%1MId7+4wvZDk0dj!=sJG(cc?5tj69UX(1hIS|fHMHKl7lgV*|3ZeaDAL5 zfKvdB5vUakfDs@Mu8>zPz8u9>=09mM`t+QbBjZ&I##&K&8i^+sgZfR+qFh?2_1V0@ zg;+`$icu|+#L~14dUDr5rV2!>}kUenL`ODI>ql6l761>UgOV2 zlqFL7iHuxn@E;&jgu^m9IJGw9uvY9#k?JVc{q+^1qADo)k42y*3Ivalvj-a2q!EbV z>Ujn`AmV4|zH>194pnUY9O5g#E9C3uMEHEDxE3&}fNA~;mU8_JCz?p9&IK+dmrNe1 zaUl1gW!2b|D`XN-ZPqUq$dT)1e;xDJ^99I9J0+SnK{RbTo7}!Z4pof{N;(}#e2{mk z6B%GCcH^(CD#)>X7{V&`Zx`!a2kT zzzx>R(35WrMe1Q_Z%0I( z_Yr3mp>{+hF{uV^3sTQYMH$LgCOH#Is-%O8T!mM7lqG!b;wAE~#9JZRX%M}?pElIe-CXdaxD|v&&o6QXr&OSU3nm6XwxGBcp%zD{H zcjj8SP-eoVP1bI52<39%H(lz1A%aEDN$ujM<*k#T&XxKECw*^2q3-?sHv(3g0i{Ko zY0*k@Y7W!)ZV|u;HV&yH=eP>3oLkG{EzKXF=X~3!G*boRqSF7up}x*JoZ4@km(<#q zbp3v1g3dOj{9w&VyCU&)#W~zRxBJf&2LD?su{YAc%Fm9E{PyE z_=wr{G{}-jAFGS4dz3?O_kLJpK-B!+j1s~TuFpw=qVBN8f*?}Vf~YXX0u3d@@FRth z?^8wLLgtSwDA;kK5u37{@QF6cN$;qOAqdpxGJ+r~{m30WezTdhtTem9RkXd)%t}ll zMvCWm)STBRLe{7@iZQ1&Vp8%v!QBMql&$62{5d^=XBHF8Lh6hq%Ks)7zXLi ziQ&vSBEBli79vDzjP>nP;Jh)dgCKR43snh`=2-J*CPc^{A+p8`5o@U?T=31%iM-gb zMoeXfdx767nPFvKfZn4jbCfc@F$t6;T=)EX;B1qKlzVXPSO@a>#OiD!UBfd&2O)#$owW_)rHIA6@GRQ06LzC^k9 zE$kwnMaBnS{9A6d>@9uNqu@0R=a=|Q8Pw7-<0o%%4h2|Ri<_N9M+jt{<}TLa5-*n| zUeraKb`MmBL&NLQcz6`Xj78dimbT?Z3`z;tSfkz18}#UZrz?jQ-uCx1y8d62zy5FN;nNDA2ZvccDF+Z$ zyN6?YpdBDge&z?F83TA!I_)+~T(W`?KDz!NZVS+u!uYnkpet`pySIiB{wAOJia{T~ zK)8Z(Rfu9QFF z-s*A1pQp&Db2~BY z3m@`@Uvh69a3!9h#1~y~h~TbL!3w7ka=<*q?|7#0ZAsZ<{Qz= zbp0P(!5m3s6u+q}Z=H2-d7*rZ(s-b@ze$j_5mqqsai(xau2iHBvjm1pk!iG4S`vOCqKE?#UAjL%+Xy-x-WT*yH$=nGI zj@;kWb)+)L&~`(QOc67PF{39yw`+E#liIZwWV@;-lvoYfrkfLRR+>tK6CtQtaOiRZ zI`n=J{k1>`DJ7B;$hI1-R{%^Z^HhVZbAT`4y}%a+ydcIjq|5^-HuwQhvV)%i6gT+Q z04TO+l(nuGGozdbB~^pg-9U+rPy!`kh+3K7l@3v>5>UdqV}O#?F;{m`7u;b-S%We& zpoGV?9LSPDlYvnWN|<2E7|gGW&VZ5`uHus!pl1LjtLA7nt3a?Gl#nZ+WVL}3Rvmf- ztRZS8*ks&>D1Roc!^!q23{mcNep86Tc}7+P4N(E2taQpvXfqE{Y_I{MWCt6AC~mN+ zhA4T5Bnn(2N)SZ3iSVg{DAy&8V0w)`O3t{GLKL%4U|)0j=*%%6a+d_6hzA3o-UCFj z;R%RxF*zLKLvDW$QSRRU0irCY{R2c<2}F@Kr3IzmM&cBr$R6PQ952%T7ZLpdqWJb- zioBJi419v$f=u7`5M@9TABa-%0v_eYK@@p8s0mTV^#%~-ALQQ`Lh zOE_1|h&-XIhb32h+_*2h8kS5@;1*Z*I6=V@mAzb8!qH;}OD^f^VaY{bFb9d*M_0p= zOOyuBNkWei6f9A}_X0~+nc+-_Y%PRbJm$do;7mb{KVDy0gPCY$GG#Qrc0TSHFqazi z1nhoM>A(Ij4fs`Ld;o>q@uSNfMi*mgQu9O}LipIQbA+BXqBorLALST&R!!eO_yDH& z>Es64Y83Xi8U+opGEtT?{r6cjyb`a`DBKXQ z)dj*Mb2R*8f4s$2ubL%_Lj;M{M+Wi}RYTwMs`Q5Zt`w)VCOD%W@W^Gp#h1i(STvR{8vtiHy8x25)3jl$XI+yIGP^A?Fi>%j49b0?g;s zV5M9Vrw-AQ*kc55JfCv&*Kj)seatP{1OcIW$*2JmtI7DP4Evq4#6tR|ACXuXTZ!)o zJQ4IMm%@5Q`TEvuKWnrWGWFa&iN{pqYv1yiYIq$7isrx3l3=Q-rumr4BZOfM3t|c1 zk%t&<3?ZDc(WV+9fTEH6Tf6{eEND!E>H&$7LL-juWvds{PwJ`{ZSQz8w>Am{NYG6Y zl}-!|F)urOk<(<3GBI0I0)2}4XY(UU;829}46I)ZMUZj^h$EDxfkt6amc~*A!C`d- zFVKOMLWph9BR0j6QY}2rjGP3`jKg(|G8W`zeU@T{!!$v{D%U3Aur-BU9=xp0?@GZ- zO9Eb4PK=QS(3XOiafktU$?Wrr^q6rD1V^CBRxW$+lI-ttGe1{E55UVfS8?Gu5HEn2 zmO0?1#kSrUcp+E7%Q_ni*2NH3ySozbqP^p>HHvnYJGI)qz;6m(*3JVjHXH(8uyI&z zY+Nvc+aO;JUi`d_PP|X#ChT&DSJm>jM0M`ZisVja+Mu7>3Wpk4j*!SqfmOa?jk}~E z)}z`4xTwJb&nykNm{Uf8ixhKF_&h?vfD2qg)vAHZYAR&F1$nOetO}I$z-5|TWF88@ zMaJr?2n@@DKeo!GK8ytQ0k{YYxv%tABl?2@7jbR)wz~nB5ivKwyo)tZpkJ>x>=mt#`~?1zf6mwhFi`%DQaIv&K9}V+P=| z?p}e5!3BUz7B1Y-cL}(xoeNxS7zVfud4|%EG^5l4EwwBi9Z))~?|=j|#`+<4wucU=gT@?NYO!n*N?6rn zBoA67egmi81+-jMH5j3$Sc7P@s~<9>I?!@=KJ}nwIb0e*%X}^kpk+y1Iz=mb(BgR% znt0GMDf$SsOb}3$Pmoxh8|jo`JqKE@D6v4xxKBJzV%|zpE`{xiEgrP63v>a{;t>gI zzDFegs}XhaE!{ppGJ~7 zh?+;V%(vY!54EH=qu>W_8r*D72n*Sq)E91H6cnqMNX_p!a);6b^HA@LG72)qHl{1) zc&%+p)HYk+bjB=JDlOEEs2Vlnz3;gB@L5Wi$hz6=MOH(8R|*8#3E66!%h)#w5Ny(B z!o-R-yxxFdQ`RWJV}Rhf^~qLGs>f0$n5?PFC~!tQsR4q+T=nV0>#^O7XGmSO;ZqAj zv}M{G1;`#C*kofX%gEGF4NS95*)&Uo%CR+Od3S)L}muUcQyqAf8!srju2jK+92GYo(lVnL|Q4m*pKat{p@fL#H) zi(4030x90XOcs1KVuC2&Vt`Z72nYN!* zNu=hNeS#_{NO7e0Z_!qg-e%4~ILPunsJJUYYI`pu9BQub3S#Q_-PDPu{{^Hqb8do3 z=4uVp4AA^u%31&=+vhHzZ!G)uOP{eNCJ;IW(;i^! zmr0d~OXmkFQ$JF~h-k_o2Iu60%CDtgqP@{1vhYcevrT>+ zEbJny1;lJo`($O~!okb}aPh-Q;z1|gi9P82BQuYIRX}3`O=kV`_BD4hBdlOz{k*6PtkNC@amPq@a>M&xuEztB}(Sj6NMZ$HIrkAk($z0Pk6vg-VJr19Ax65uHDup6Y;05;Ki zAgdxt2*|plzRx$@L7v_a$RahrH>#!-jiYT@H8MmXOG~Ruml;`(LtlHMkCFB=3? z&S7XGs)hm`gqVk5Hp2!4%TBP3Y3Onmma)4*u=*5&;RN}o1;J!kuYzDQ4p%|2>$3ae zfosOi`4&a&B|4a~bA5w$Te~IG2^-}~qph%2W^814 z1im-e&M(Y!TX_jrX?y>;*{ROz(T^(=->ld|@?kw8#gJXm2J9Nv5|7wzEg&|aCsc`X zN__oA*E)k6JrJX!Y4CPy601th>dmY43HQElB8!^G?Xmp$jQyiC{JyyRw160);UDV0 zVb5uq{|Fti`*!XbthtXOJ%6A3I`@7__cNu_f-i)Ick6zD{4nkjI%4-*NDs%!Va^xN z;2-DLzj(S$3^xo^(8Q;fBP-1JwlxsGf+a=qY8r(V&wkQmlOofcxzdF-a-8bonE6~w z@Z1_LM`LaLx-bjVhJ$Lq$fRvUz?C^2VghBIl*yI8>r8hS){_ZyC>&g3>@kY{ilrTv zn%@bNOeuT73^()!xbnKLD1Vc>0$QZ}T~SzzHC$<-Er^=e7GTU=>2JAxJm>WuOgggO zgMik2X2{)`U`)Iaf-yJAeWWwpK|=G@j~~piP~N;t%5=9eaWjcW0{SksO4dj?9~Ead zQm9OKT-7s%H!|R@B2J5k=X#pND`o;nC>@OH*7LN+8-yTRgXvCA@8k6r7f_{p!748l zQ#$fiTPw}1GDl=CRGAfCYppWfRkqapR$G;= z_hO2-1`?{o9G^3*ugg6&P_X(gCeTb2QK&3gv_>GQYXPCRxVbzVXJ}4(1r;TSY{hu*Hnqh9>bdM+mO3| z;mE|qO0F~wP`cK#2v6SwT}GBlml4&C)HQheL#4+i&(oSZI;%3zQsyQ<4Vx?diL+!f z6Ok+Z5%jp4@Xd$a*BxD!(AQN*j>xD%m&N<~J@Uy_=u%Ocm6T8D-^+oDjL+!QsSy7I zx5yI}D<^mUXv;P2Ev$p-<*^q!8Ro3H} zFs%3$s%za+5;ruN>5TbJcV~0a+-Z$#L?o92#vgNxg<(dHutt7kpi;Sx&xryy9+O$@ zZD;MZpU-LzGPT)>TOfvQYv*d)+H*{4B`!bM+YYy*vbfU2R}fWW2nuNFH-}89v7W~$ ziMhonc^R!A%eM{5{K{Gm5j^O|vB&oO5T6p)Z_f|vx^jDdK-X2<^A&v}xb9%FS!hp)QJVRG3^0qc%GhQx^wriRNzY-1#HHK;a#$dkG3LXIBwJ)}AG6>>nIlNKa=ruffR9`^D z`%sd2Ct-fWZCW_D&IIH#yCZd9l z`K7nv04>16KZg1g%5&#cK9<8dmG91yRlcRsrKT!ei!L=);g5hGiOP2;s{+qc`B)a{ zRK8owR{56L*K4VKwdk^lD!c&h{K@#_R#p|hSI{|8OXV}g4V4c+Y$g-NQTc|ABTeNS zh9X&+fU5T&q!`i7uj_i<)I8-JhDxGp2<)IBeeZjwAen-O_JxAxWYHQ{I^*zK!xg{N zRg;>2TfkaIXlZ`(({Oo?#+PR$pjB&34;aar%4Y+v*ZjjeLm0#4yEJ20oN4@5E-fMm% zUh_NWHNUgEI?eA4K?jhW|1~|KDWo&%n@v}wiKHt^^JB_h+kDLk?hi85K}Jfd6I&9s z&un+c2L9v|6BDa(hwQp8ed1TiWweJR3A>`}2Iu@BB zm|+nqjA9WfjB0mN6uFn8sQdBdt9_eQNukZaB%6PFJYp`L=2!-5v51BWZ4#Wb#A8A8 z`-j3HUe{a(d;GLDzww~?eKyMP(!m3(>UmTWgBVCXKzwO%*9TeZ;fqqByvyF{^ zT$fvsD2Y1iAm?ThgJ>7yCRRG@pUFh(KbA>Og8Q~uTT{8>J>z*@XVsnMdq-Ct4$K6@ z4Ta(CLAeFzl>x39wq{om#|GqC1C`&E-_`Q>;e9*FM;?8x$9`Xi8VbtmZq(lix%d>R z>mj9ZUOGvy-f}%3l*5~85Vt*P)$`X>9SZ$b433;J&UvnLBhIPf7i@A}d%@-}GAtJG zMx`#OO8zB0EwBrKUC2!=33l#vp**%eWn(=~)Ll}KD`cfIhYYmZa&>&HGv~EJzSfgD zuZk@o$@-|LNLyDm6i!l5FOpEMcFR7X0gWlI3Rh_oI!wX$xU6$_qqiLiWy_q&n+Y!* zqp$*}AgYHA?1kM4fG)TOOgFG=W0Kp#=w9bHT~x*4VL7d7fQfwHE4Xzl#>jqCB_-XjhyzplRX%0{7`D%g?H$2A+bgCP82M%O{y5k2 zcXjp9WJR_UaFCqq1bDu;#f4m5C!j4{C&(-=qykANAfQ9Oy%Ya9Sw!Sq^V12;H$R<# z+9sVqX=|MD9hMN0C7r;nEab2Vb^jHC`?b2*Io@?^inU?Gy})nE_A6+@!1fYo@rq@# zeLlnX|6x;MMRpNLWyAd4UH{rm8jr7w&BeoIuByOg^w%3&Ep!D70&9t?%siZYR<*lp zhLj|Y*FSNapZt0pygVQ0XVyCpj z<}$Q$?|YuIsCi69nqlM~+qMudrE}}#H;~n}CbXPKA9haqQKPLcOk&|A%PoN)(xxbu zYz}f2od%`XvWi2w@;g>#Y2nMkV|ru6rgyFo%o^_X1jKep(R_!wtmgiLzdtX*n zV~yD48sGiv^Sd_WouQsb^t$x*8T6SPtRw$E zH}JU^_)R51y@4f$N0kGq`5mpA zT<8gwcM5KAp2Zg%jrnMUHhE}PPx~lOKhH{OlC3uEqT$`{k5iAoLF#$2l zY{X%jU`A!nP_}PG?!I}xqAf~H3?oSi3^wN%X6k#O%hXcoGNrnax{59z0Xvc4ah_fj=`mHSy{@)u1! z6oT;nE4t$Ta?synpa{Yo;{>t-laebnl@&EjN~HQH&LKOdiKw)RMS#g69v^Z8lmH2lk+(ocUN70aL zW(1wtRQj%4I6S0$aVj&&)vyq?5~OK)tL1-UR8h*m?otjYB~DE$K4pcJ0!>ga*Yabf z74bvHay6rjZ*x_~w^`U86BYBBE;%KYA}66vdGa14=#)=efNk5-z@>MT5~*t_jr_dIZs4uvPPkioK|8j* z-5CrR_Pdp4)8LH|RE1_#kvmL+AuF=LkEj~JFG#a$gySKpAsoIai*RNINgcwOoexQ; zHKYJZuj&d}4Dnns7^)INUm&VRZFtASP=hqU(12)idFvAnhR!j?n29Cv98fVUOR(N4=zwaK1IBkRTXmPQgX4PPYu&jL>K< zY;n`l89g$c#~uYx>R#tJ1*PhoCU+7@37AAJ$KPKiJv8Wg)d1u{DMo7prPq88*N}Z9 zb;OaHUw3d4^#pGE{#e7E@r9pky8irqcObj(zvKI4t2Z* zk~`|I>3s=8c!C3aR; z{Vc<27is^yzY2!KU5?&E-i@sF2&5sO8Sj5`*I0gG+TFe7urLkV3;M!Rz2%4v!*pY{ zhb%n`YSNM%Wyy;KJGE#-YB1MPmb`eR%{Sosjd>|SdCPh!8C4F>OUdYbon%;gln1yh zl0rLLA%R!rBZR0W1KevP)`B`nvh+oE+a=bsrT9I%2Y*oVN`WZ9yPqucWI^hxmQ1)y z2u=%BYWc~U)1nDDX`tBUx9D}5VC7R|hMJ^av;Lhk!RiPk`6|EGoL`vT?}12DOC{2j zsz&N6B7NktNUTweUty@kzuE8{Kfx4z3spx6Er_7>*BY3d5> z%9E?)5q~p(E8cIwT}A$vK8dWTFhD-~cCp|fY|C#e#%qd&(yyJi@oszzYpQhkC|4QI zE^ooIw2`i0YpN`sH2gGbS(VbP4Sf+`pA&uy-fFSEKQ{-(db?(b*( z{j}~A#Gyqol}Cu6$n1`!Lg~gMUVIfwGih)-1Xa|O-n_LzmDT%RmRZz1TO?^N-{*Gw z)cY{Vb0xu9v^Z@7TIIvqD74y#Nz&khkH~L?OZ{=}7%G&`Kj2<$_F=ua#)o-vtq<~I zix2YRI)c*=x);~`uwLBY!@St)gS@ELP-L~!Wi?#26jSTEl1!@T%0ALPXce2^C( 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 QwIpBXcYUjZmEZaQ0TvUtL;wH) literal 111977 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 0) { + element.style.borderTopLeftRadius = cornerRadius.topLeft.value + 'px'; + } + if (cornerRadius.topRight.value > 0) { + element.style.borderTopRightRadius = cornerRadius.topRight.value + 'px'; + } + if (cornerRadius.bottomLeft.value > 0) { + element.style.borderBottomLeftRadius = cornerRadius.bottomLeft.value + 'px'; + } + if (cornerRadius.bottomRight.value > 0) { + element.style.borderBottomRightRadius = cornerRadius.bottomRight.value + 'px'; + } + } + function renderLoopHTML() { let capacity = memoryDataView.getInt32(scratchSpaceAddress, true); let length = memoryDataView.getInt32(scratchSpaceAddress + 4, true); @@ -375,7 +416,7 @@ let scissorStack = [{ nextAllocation: { x: 0, y: 0 }, element: htmlRoot, nextElementIndex: 0 }]; let previousId = 0; for (let i = 0; i < length; i++, arrayOffset += renderCommandSize) { - let entireRenderCommandMemory = new Uint32Array(memoryDataView.buffer.slice(arrayOffset, arrayOffset + renderCommandSize)); + let entireRenderCommandMemory = new Uint8Array(memoryDataView.buffer.slice(arrayOffset, arrayOffset + renderCommandSize)); let renderCommand = readStructAtAddress(arrayOffset, renderCommandDefinition); let parentElement = scissorStack[scissorStack.length - 1]; let element = null; @@ -384,13 +425,12 @@ let elementType = 'div'; switch (renderCommand.commandType.value & 0xff) { case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: { - if (readStructAtAddress(renderCommand.config.value, rectangleConfigDefinition).link.length.value > 0) { - elementType = 'a'; - } + // if (readStructAtAddress(renderCommand.renderData.rectangle.value, rectangleRenderDataDefinition).link.length.value > 0) { TODO reimplement links + // elementType = 'a'; + // } break; } case CLAY_RENDER_COMMAND_TYPE_IMAGE: { - console.log('test5'); elementType = 'img'; break; } default: break; @@ -443,93 +483,82 @@ break; } case (CLAY_RENDER_COMMAND_TYPE_RECTANGLE): { - let config = readStructAtAddress(renderCommand.config.value, rectangleConfigDefinition); - let sharedConfig = readStructAtAddress( renderCommand.textOrSharedConfig.sharedConfig.value, sharedConfigDefinition); - let configMemory = new Uint8Array(memoryDataView.buffer.slice(renderCommand.config.value, renderCommand.config.value + config.__size)); - let linkContents = config.link.length.value > 0 ? textDecoder.decode(new Uint8Array(memoryDataView.buffer.slice(config.link.chars.value, config.link.chars.value + config.link.length.value))) : 0; - memoryDataView.setUint32(0, renderCommand.id.value, true); - if (linkContents.length > 0 && (window.mouseDownThisFrame || window.touchDown) && instance.exports.Clay_PointerOver(0)) { - window.location.href = linkContents; - } - if (!dirty && !MemoryIsDifferent(configMemory, elementData.previousMemoryConfig, config.__size)) { + let config = renderCommand.renderData.rectangle; + let configMemory = JSON.stringify(config); + if (configMemory === elementData.previousMemoryConfig) { break; } - if (linkContents.length > 0) { - element.href = linkContents; + + SetElementBackgroundColorAndRadius(element, config.cornerRadius, config.backgroundColor); + if (renderCommand.userData.value !== 0) { + let customData = readStructAtAddress(renderCommand.userData.value, customHTMLDataDefinition); + + let linkContents = customData.link.length.value > 0 ? textDecoder.decode(new Uint8Array(memoryDataView.buffer.slice(customData.link.chars.value, customData.link.chars.value + customData.link.length.value))) : 0; + memoryDataView.setUint32(0, renderCommand.id.value, true); + if (linkContents.length > 0 && (window.mouseDownThisFrame || window.touchDown) && instance.exports.Clay_PointerOver(0)) { + window.location.href = linkContents; + } + if (linkContents.length > 0) { + element.href = linkContents; + } + + if (linkContents.length > 0 || customData.cursorPointer.value) { + element.style.pointerEvents = 'all'; + element.style.cursor = 'pointer'; + } } - if (linkContents.length > 0 || config.cursorPointer.value) { - element.style.pointerEvents = 'all'; - element.style.cursor = 'pointer'; - } elementData.previousMemoryConfig = configMemory; - let color = config.color; - element.style.backgroundColor = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; - if (sharedConfig.cornerRadius.topLeft.value > 0) { - element.style.borderTopLeftRadius = sharedConfig.cornerRadius.topLeft.value + 'px'; - } - if (sharedConfig.cornerRadius.topRight.value > 0) { - element.style.borderTopRightRadius = sharedConfig.cornerRadius.topRight.value + 'px'; - } - if (sharedConfig.cornerRadius.bottomLeft.value > 0) { - element.style.borderBottomLeftRadius = sharedConfig.cornerRadius.bottomLeft.value + 'px'; - } - if (sharedConfig.cornerRadius.bottomRight.value > 0) { - element.style.borderBottomRightRadius = sharedConfig.cornerRadius.bottomRight.value + 'px'; - } + break; } case (CLAY_RENDER_COMMAND_TYPE_BORDER): { - let config = readStructAtAddress(renderCommand.config.value, borderConfigDefinition); - let sharedConfig = readStructAtAddress( renderCommand.textOrSharedConfig.sharedConfig.value, sharedConfigDefinition); - let configMemory = new Uint8Array(memoryDataView.buffer.slice(renderCommand.config.value, renderCommand.config.value + config.__size)); - if (!dirty && !MemoryIsDifferent(configMemory, elementData.previousMemoryConfig, config.__size)) { + let config = renderCommand.renderData.border; + let configMemory = JSON.stringify(config); + if (configMemory === elementData.previousMemoryConfig) { break; } + let color = config.color; elementData.previousMemoryConfig = configMemory; - if (config.left.width.value > 0) { - let color = config.left.color; - element.style.borderLeft = `${config.left.width.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` + if (config.width.left.value > 0) { + element.style.borderLeft = `${config.width.left.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` } - if (config.right.width.value > 0) { - let color = config.right.color; - element.style.borderRight = `${config.right.width.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` + if (config.width.right.value > 0) { + element.style.borderRight = `${config.width.right.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` } - if (config.top.width.value > 0) { - let color = config.top.color; - element.style.borderTop = `${config.top.width.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` + if (config.width.top.value > 0) { + element.style.borderTop = `${config.width.top.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` } - if (config.bottom.width.value > 0) { - let color = config.bottom.color; - element.style.borderBottom = `${config.bottom.width.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` + if (config.width.bottom.value > 0) { + element.style.borderBottom = `${config.width.bottom.value}px solid rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})` } - if (sharedConfig.cornerRadius.topLeft.value > 0) { - element.style.borderTopLeftRadius = sharedConfig.cornerRadius.topLeft.value + 'px'; + if (config.cornerRadius.topLeft.value > 0) { + element.style.borderTopLeftRadius = config.cornerRadius.topLeft.value + 'px'; } - if (sharedConfig.cornerRadius.topRight.value > 0) { - element.style.borderTopRightRadius = sharedConfig.cornerRadius.topRight.value + 'px'; + if (config.cornerRadius.topRight.value > 0) { + element.style.borderTopRightRadius = config.cornerRadius.topRight.value + 'px'; } - if (sharedConfig.cornerRadius.bottomLeft.value > 0) { - element.style.borderBottomLeftRadius = sharedConfig.cornerRadius.bottomLeft.value + 'px'; + if (config.cornerRadius.bottomLeft.value > 0) { + element.style.borderBottomLeftRadius = config.cornerRadius.bottomLeft.value + 'px'; } - if (sharedConfig.cornerRadius.bottomRight.value > 0) { - element.style.borderBottomRightRadius = sharedConfig.cornerRadius.bottomRight.value + 'px'; + if (config.cornerRadius.bottomRight.value > 0) { + element.style.borderBottomRightRadius = config.cornerRadius.bottomRight.value + 'px'; } break; } case (CLAY_RENDER_COMMAND_TYPE_TEXT): { - let config = readStructAtAddress(renderCommand.config.value, textConfigDefinition); - let configMemory = new Uint8Array(memoryDataView.buffer.slice(renderCommand.config.value, renderCommand.config.value + config.__size)); - let textContents = renderCommand.textOrSharedConfig.text; - let stringContents = new Uint8Array(memoryDataView.buffer.slice(textContents.chars.value, textContents.chars.value + textContents.length.value)); - if (MemoryIsDifferent(configMemory, elementData.previousMemoryConfig, config.__size)) { + let config = renderCommand.renderData.text; + let customData = readStructAtAddress(renderCommand.userData.value, customHTMLDataDefinition); + let configMemory = JSON.stringify(config); + let stringContents = new Uint8Array(memoryDataView.buffer.slice(config.stringContents.chars.value, config.stringContents.chars.value + config.stringContents.length.value)); + if (configMemory !== elementData.previousMemoryConfig) { element.className = 'text'; let textColor = config.textColor; let fontSize = Math.round(config.fontSize.value * GLOBAL_FONT_SCALING_FACTOR); element.style.color = `rgba(${textColor.r.value}, ${textColor.g.value}, ${textColor.b.value}, ${textColor.a.value})`; element.style.fontFamily = fontsById[config.fontId.value]; element.style.fontSize = fontSize + 'px'; - element.style.pointerEvents = config.disablePointerEvents.value ? 'none' : 'all'; + element.style.pointerEvents = customData.disablePointerEvents.value ? 'none' : 'all'; elementData.previousMemoryConfig = configMemory; } if (stringContents.length !== elementData.previousMemoryText.length || MemoryIsDifferent(stringContents, elementData.previousMemoryText, stringContents.length)) { @@ -540,7 +569,11 @@ } case (CLAY_RENDER_COMMAND_TYPE_SCISSOR_START): { scissorStack.push({ nextAllocation: { x: renderCommand.boundingBox.x.value, y: renderCommand.boundingBox.y.value }, element, nextElementIndex: 0 }); - let config = readStructAtAddress(renderCommand.config.value, scrollConfigDefinition); + let config = renderCommand.renderData.scroll; + let configMemory = JSON.stringify(config); + if (configMemory === elementData.previousMemoryConfig) { + break; + } if (config.horizontal.value) { element.style.overflowX = 'scroll'; element.style.pointerEvents = 'auto'; @@ -549,6 +582,7 @@ element.style.overflowY = 'scroll'; element.style.pointerEvents = 'auto'; } + elementData.previousMemoryConfig = configMemory; break; } case (CLAY_RENDER_COMMAND_TYPE_SCISSOR_END): { @@ -556,9 +590,9 @@ break; } case (CLAY_RENDER_COMMAND_TYPE_IMAGE): { - console.log('test1'); - let config = readStructAtAddress(renderCommand.config.value, imageConfigDefinition); - let srcContents = new Uint8Array(memoryDataView.buffer.slice(config.sourceURL.chars.value, config.sourceURL.chars.value + config.sourceURL.length.value)); + let config = renderCommand.renderData.image; + let imageURL = readStructAtAddress(config.imageData.value, stringDefinition); + let srcContents = new Uint8Array(memoryDataView.buffer.slice(imageURL.chars.value, imageURL.chars.value + imageURL.length.value)); if (srcContents.length !== elementData.previousMemoryText.length || MemoryIsDifferent(srcContents, elementData.previousMemoryText, srcContents.length)) { element.src = textDecoder.decode(srcContents); } @@ -566,6 +600,9 @@ break; } case (CLAY_RENDER_COMMAND_TYPE_CUSTOM): break; + default: { + console.log("Error: unhandled render command"); + } } } @@ -602,8 +639,8 @@ break; } case (CLAY_RENDER_COMMAND_TYPE_RECTANGLE): { - let config = readStructAtAddress(renderCommand.config.value, rectangleConfigDefinition); - let color = config.color; + let config = renderCommand.renderData.rectangle; + let color = config.backgroundColor; ctx.beginPath(); window.canvasContext.fillStyle = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; window.canvasContext.roundRect( @@ -615,33 +652,35 @@ ctx.fill(); ctx.closePath(); // Handle link clicks - let linkContents = config.link.length.value > 0 ? textDecoder.decode(new Uint8Array(memoryDataView.buffer.slice(config.link.chars.value, config.link.chars.value + config.link.length.value))) : 0; - memoryDataView.setUint32(0, renderCommand.id.value, true); - if (linkContents.length > 0 && (window.mouseDownThisFrame || window.touchDown) && instance.exports.Clay_PointerOver(0)) { - window.location.href = linkContents; + if (renderCommand.userData.value !== 0) { + let customData = readStructAtAddress(renderCommand.userData.value, customHTMLDataDefinition); + let linkContents = customData.link.length.value > 0 ? textDecoder.decode(new Uint8Array(memoryDataView.buffer.slice(customData.link.chars.value, customData.link.chars.value + customData.link.length.value))) : 0; + memoryDataView.setUint32(0, renderCommand.id.value, true); + if (linkContents.length > 0 && (window.mouseDownThisFrame || window.touchDown) && instance.exports.Clay_PointerOver(0)) { + window.location.href = linkContents; + } } break; } case (CLAY_RENDER_COMMAND_TYPE_BORDER): { - let config = readStructAtAddress(renderCommand.config.value, borderConfigDefinition); + let config = renderCommand.renderData.border; + let color = config.color; ctx.beginPath(); ctx.moveTo(boundingBox.x.value * scale, boundingBox.y.value * scale); // Top Left Corner if (config.cornerRadius.topLeft.value > 0) { - let lineWidth = config.top.width.value; + let lineWidth = config.width.top.value; let halfLineWidth = lineWidth / 2; ctx.moveTo((boundingBox.x.value + halfLineWidth) * scale, (boundingBox.y.value + config.cornerRadius.topLeft.value + halfLineWidth) * scale); - let color = config.top.color; ctx.lineWidth = lineWidth * scale; ctx.strokeStyle = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; ctx.arcTo((boundingBox.x.value + halfLineWidth) * scale, (boundingBox.y.value + halfLineWidth) * scale, (boundingBox.x.value + config.cornerRadius.topLeft.value + halfLineWidth) * scale, (boundingBox.y.value + halfLineWidth) * scale, config.cornerRadius.topLeft.value * scale); ctx.stroke(); } // Top border - if (config.top.width.value > 0) { - let lineWidth = config.top.width.value; + if (config.width.top.value > 0) { + let lineWidth = config.width.top.value; let halfLineWidth = lineWidth / 2; - let color = config.top.color; ctx.lineWidth = lineWidth * scale; ctx.strokeStyle = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; ctx.moveTo((boundingBox.x.value + config.cornerRadius.topLeft.value + halfLineWidth) * scale, (boundingBox.y.value + halfLineWidth) * scale); @@ -650,19 +689,17 @@ } // Top Right Corner if (config.cornerRadius.topRight.value > 0) { - let lineWidth = config.top.width.value; + let lineWidth = config.width.top.value; let halfLineWidth = lineWidth / 2; ctx.moveTo((boundingBox.x.value + boundingBox.width.value - config.cornerRadius.topRight.value - halfLineWidth) * scale, (boundingBox.y.value + halfLineWidth) * scale); - let color = config.top.color; ctx.lineWidth = lineWidth * scale; ctx.strokeStyle = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; ctx.arcTo((boundingBox.x.value + boundingBox.width.value - halfLineWidth) * scale, (boundingBox.y.value + halfLineWidth) * scale, (boundingBox.x.value + boundingBox.width.value - halfLineWidth) * scale, (boundingBox.y.value + config.cornerRadius.topRight.value + halfLineWidth) * scale, config.cornerRadius.topRight.value * scale); ctx.stroke(); } // Right border - if (config.right.width.value > 0) { - let color = config.right.color; - let lineWidth = config.right.width.value; + if (config.width.right.value > 0) { + let lineWidth = config.width.right.value; let halfLineWidth = lineWidth / 2; ctx.lineWidth = lineWidth * scale; ctx.strokeStyle = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; @@ -672,8 +709,7 @@ } // Bottom Right Corner if (config.cornerRadius.bottomRight.value > 0) { - let color = config.top.color; - let lineWidth = config.top.width.value; + let lineWidth = config.width.top.value; let halfLineWidth = lineWidth / 2; ctx.moveTo((boundingBox.x.value + boundingBox.width.value - halfLineWidth) * scale, (boundingBox.y.value + boundingBox.height.value - config.cornerRadius.bottomRight.value - halfLineWidth) * scale); ctx.lineWidth = lineWidth * scale; @@ -682,9 +718,8 @@ ctx.stroke(); } // Bottom Border - if (config.bottom.width.value > 0) { - let color = config.bottom.color; - let lineWidth = config.bottom.width.value; + if (config.width.bottom.value > 0) { + let lineWidth = config.width.bottom.value; let halfLineWidth = lineWidth / 2; ctx.lineWidth = lineWidth * scale; ctx.strokeStyle = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; @@ -694,8 +729,7 @@ } // Bottom Left Corner if (config.cornerRadius.bottomLeft.value > 0) { - let color = config.bottom.color; - let lineWidth = config.bottom.width.value; + let lineWidth = config.width.bottom.value; let halfLineWidth = lineWidth / 2; ctx.moveTo((boundingBox.x.value + config.cornerRadius.bottomLeft.value + halfLineWidth) * scale, (boundingBox.y.value + boundingBox.height.value - halfLineWidth) * scale); ctx.lineWidth = lineWidth * scale; @@ -704,9 +738,8 @@ ctx.stroke(); } // Left Border - if (config.left.width.value > 0) { - let color = config.left.color; - let lineWidth = config.left.width.value; + if (config.width.left.value > 0) { + let lineWidth = config.width.left.value; let halfLineWidth = lineWidth / 2; ctx.lineWidth = lineWidth * scale; ctx.strokeStyle = `rgba(${color.r.value}, ${color.g.value}, ${color.b.value}, ${color.a.value / 255})`; @@ -718,8 +751,8 @@ break; } case (CLAY_RENDER_COMMAND_TYPE_TEXT): { - let config = readStructAtAddress(renderCommand.config.value, textConfigDefinition); - let textContents = renderCommand.text; + let config = renderCommand.renderData.text; + let textContents = config.stringContents; let stringContents = new Uint8Array(memoryDataView.buffer.slice(textContents.chars.value, textContents.chars.value + textContents.length.value)); let fontSize = config.fontSize.value * GLOBAL_FONT_SCALING_FACTOR * scale; ctx.font = `${fontSize}px ${fontsById[config.fontId.value]}`; @@ -742,8 +775,9 @@ break; } case (CLAY_RENDER_COMMAND_TYPE_IMAGE): { - let config = readStructAtAddress(renderCommand.config.value, imageConfigDefinition); - let src = textDecoder.decode(new Uint8Array(memoryDataView.buffer.slice(config.sourceURL.chars.value, config.sourceURL.chars.value + config.sourceURL.length.value))); + let config = renderCommand.renderData.image; + let imageURL = readStructAtAddress(config.imageData.value, stringDefinition); + let src = textDecoder.decode(new Uint8Array(memoryDataView.buffer.slice(imageURL.chars.value, imageURL.chars.value + imageURL.length.value))); if (!imageCache[src]) { imageCache[src] = { image: new Image(), diff --git a/examples/clay-official-website/main.c b/examples/clay-official-website/main.c index 19d9635..7847132 100644 --- a/examples/clay-official-website/main.c +++ b/examples/clay-official-website/main.c @@ -3,7 +3,7 @@ double windowWidth = 1024, windowHeight = 768; float modelPageOneZRotation = 0; -uint32_t ACTIVE_RENDERER_INDEX = 0; +uint32_t ACTIVE_RENDERER_INDEX = 1; const uint32_t FONT_ID_BODY_16 = 0; const uint32_t FONT_ID_TITLE_56 = 1; @@ -52,13 +52,21 @@ typedef struct { CustomHTMLData* FrameAllocateCustomData(CustomHTMLData data) { CustomHTMLData *customData = (CustomHTMLData *)(frameArena.memory + frameArena.offset); + *customData = data; frameArena.offset += sizeof(CustomHTMLData); return customData; } -void LandingPageBlob(int index, int fontSize, Clay_Color color, Clay_String text, char* imageURL) { +Clay_String* FrameAllocateString(Clay_String string) { + Clay_String *allocated = (Clay_String *)(frameArena.memory + frameArena.offset); + *allocated = string; + frameArena.offset += sizeof(Clay_String); + return allocated; +} + +void LandingPageBlob(int index, int fontSize, Clay_Color color, Clay_String text, Clay_String imageURL) { CLAY({ .id = CLAY_IDI("HeroBlob", index), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 480) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }, .border = { .color = color, .width = { 2, 2, 2, 2 }}, .cornerRadius = CLAY_CORNER_RADIUS(10) }) { - CLAY({ .id = CLAY_IDI("CheckImage", index), .layout = { .sizing = { CLAY_SIZING_FIXED(32) } }, .image = { .sourceDimensions = { 128, 128 }, .imageData = imageURL } }) {} + CLAY({ .id = CLAY_IDI("CheckImage", index), .layout = { .sizing = { CLAY_SIZING_FIXED(32) } }, .image = { .sourceDimensions = { 128, 128 }, .imageData = FrameAllocateString(imageURL) } }) {} CLAY_TEXT(text, CLAY_TEXT_CONFIG({ .fontSize = fontSize, .fontId = FONT_ID_BODY_24, .textColor = color })); } } @@ -72,11 +80,11 @@ void LandingPageDesktop() { CLAY_TEXT(CLAY_STRING("Clay is laying out this webpage right now!"), CLAY_TEXT_CONFIG({ .fontSize = 36, .fontId = FONT_ID_TITLE_36, .textColor = COLOR_ORANGE })); } CLAY({ .id = CLAY_ID("HeroImageOuter"), .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_PERCENT(0.45f) }, .childAlignment = { CLAY_ALIGN_X_CENTER }, .childGap = 16 } }) { - LandingPageBlob(1, 32, COLOR_BLOB_BORDER_5, CLAY_STRING("High performance"), "/clay/images/check_5.png"); - LandingPageBlob(2, 32, COLOR_BLOB_BORDER_4, CLAY_STRING("Flexbox-style responsive layout"), "/clay/images/check_4.png"); - LandingPageBlob(3, 32, COLOR_BLOB_BORDER_3, CLAY_STRING("Declarative syntax"), "/clay/images/check_3.png"); - LandingPageBlob(4, 32, COLOR_BLOB_BORDER_2, CLAY_STRING("Single .h file for C/C++"), "/clay/images/check_2.png"); - LandingPageBlob(5, 32, COLOR_BLOB_BORDER_1, CLAY_STRING("Compile to 15kb .wasm"), "/clay/images/check_1.png"); + LandingPageBlob(1, 32, COLOR_BLOB_BORDER_5, CLAY_STRING("High performance"), CLAY_STRING("/clay/images/check_5.png")); + LandingPageBlob(2, 32, COLOR_BLOB_BORDER_4, CLAY_STRING("Flexbox-style responsive layout"), CLAY_STRING("/clay/images/check_4.png")); + LandingPageBlob(3, 32, COLOR_BLOB_BORDER_3, CLAY_STRING("Declarative syntax"), CLAY_STRING("/clay/images/check_3.png")); + LandingPageBlob(4, 32, COLOR_BLOB_BORDER_2, CLAY_STRING("Single .h file for C/C++"), CLAY_STRING("/clay/images/check_2.png")); + LandingPageBlob(5, 32, COLOR_BLOB_BORDER_1, CLAY_STRING("Compile to 15kb .wasm"), CLAY_STRING("/clay/images/check_1.png")); } } } @@ -90,11 +98,11 @@ void LandingPageMobile() { CLAY_TEXT(CLAY_STRING("Clay is laying out this webpage right now!"), CLAY_TEXT_CONFIG({ .fontSize = 32, .fontId = FONT_ID_TITLE_36, .textColor = COLOR_ORANGE })); } CLAY({ .id = CLAY_ID("HeroImageOuter"), .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .childAlignment = { CLAY_ALIGN_X_CENTER }, .childGap = 16 } }) { - LandingPageBlob(1, 28, COLOR_BLOB_BORDER_5, CLAY_STRING("High performance"), "/clay/images/check_5.png"); - LandingPageBlob(2, 28, COLOR_BLOB_BORDER_4, CLAY_STRING("Flexbox-style responsive layout"), "/clay/images/check_4.png"); - LandingPageBlob(3, 28, COLOR_BLOB_BORDER_3, CLAY_STRING("Declarative syntax"), "/clay/images/check_3.png"); - LandingPageBlob(4, 28, COLOR_BLOB_BORDER_2, CLAY_STRING("Single .h file for C/C++"), "/clay/images/check_2.png"); - LandingPageBlob(5, 28, COLOR_BLOB_BORDER_1, CLAY_STRING("Compile to 15kb .wasm"), "/clay/images/check_1.png"); + LandingPageBlob(1, 28, COLOR_BLOB_BORDER_5, CLAY_STRING("High performance"), CLAY_STRING("/clay/images/check_5.png")); + LandingPageBlob(2, 28, COLOR_BLOB_BORDER_4, CLAY_STRING("Flexbox-style responsive layout"), CLAY_STRING("/clay/images/check_4.png")); + LandingPageBlob(3, 28, COLOR_BLOB_BORDER_3, CLAY_STRING("Declarative syntax"), CLAY_STRING("/clay/images/check_3.png")); + LandingPageBlob(4, 28, COLOR_BLOB_BORDER_2, CLAY_STRING("Single .h file for C/C++"), CLAY_STRING("/clay/images/check_2.png")); + LandingPageBlob(5, 28, COLOR_BLOB_BORDER_1, CLAY_STRING("Compile to 15kb .wasm"), CLAY_STRING("/clay/images/check_1.png")); } } } @@ -148,7 +156,7 @@ void DeclarativeSyntaxPageDesktop() { CLAY_TEXT(CLAY_STRING("Create your own library of re-usable components from UI primitives like text, images and rectangles."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED })); } CLAY({ .id = CLAY_ID("SyntaxPageRightImage"), .layout = { .sizing = { CLAY_SIZING_PERCENT(0.50) }, .childAlignment = {.x = CLAY_ALIGN_X_CENTER} } }) { - CLAY({ .id = CLAY_ID("SyntaxPageRightImageInner"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 568) } }, .image = { .sourceDimensions = {1136, 1194}, .imageData = "/clay/images/declarative.png" } }) {} + CLAY({ .id = CLAY_ID("SyntaxPageRightImageInner"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 568) } }, .image = { .sourceDimensions = {1136, 1194}, .imageData = FrameAllocateString(CLAY_STRING("/clay/images/declarative.png")) } }) {} } } } @@ -164,7 +172,7 @@ void DeclarativeSyntaxPageMobile() { CLAY_TEXT(CLAY_STRING("Create your own library of re-usable components from UI primitives like text, images and rectangles."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED })); } CLAY({ .id = CLAY_ID("SyntaxPageRightImage"), .layout = { .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {.x = CLAY_ALIGN_X_CENTER} } }) { - CLAY({ .id = CLAY_ID("SyntaxPageRightImageInner"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 568) } }, .image = { .sourceDimensions = {1136, 1194}, .imageData = "/clay/images/declarative.png" } }) {} + CLAY({ .id = CLAY_ID("SyntaxPageRightImageInner"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 568) } }, .image = { .sourceDimensions = {1136, 1194}, .imageData = FrameAllocateString(CLAY_STRING("/clay/images/declarative.png")) } }) {} } } } @@ -237,7 +245,7 @@ void RendererButtonActive(Clay_String text) { .layout = { .sizing = {CLAY_SIZING_FIXED(300) }, .padding = CLAY_PADDING_ALL(16) }, .backgroundColor = Clay_Hovered() ? COLOR_RED_HOVER : COLOR_RED, .cornerRadius = CLAY_CORNER_RADIUS(10), - .custom = { .customData = FrameAllocateCustomData((CustomHTMLData) { .disablePointerEvents = true, .cursorPointer = true })} + .userData = FrameAllocateCustomData((CustomHTMLData) { .disablePointerEvents = true, .cursorPointer = true }) }) { CLAY_TEXT(text, CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT })); } @@ -249,7 +257,7 @@ void RendererButtonInactive(Clay_String text, size_t rendererIndex) { .border = { .width = {2, 2, 2, 2}, .color = COLOR_RED }, .backgroundColor = Clay_Hovered() ? COLOR_LIGHT_HOVER : COLOR_LIGHT, .cornerRadius = CLAY_CORNER_RADIUS(10), - .custom = { .customData = FrameAllocateCustomData((CustomHTMLData) { .disablePointerEvents = true, .cursorPointer = true })} + .userData = FrameAllocateCustomData((CustomHTMLData) { .disablePointerEvents = true, .cursorPointer = true }) }) { Clay_OnHover(HandleRendererButtonInteraction, rendererIndex); CLAY_TEXT(text, CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED })); @@ -315,7 +323,7 @@ void DebuggerPageDesktop() { CLAY_TEXT(CLAY_STRING("Press the \"d\" key to try it out now!"), CLAY_TEXT_CONFIG({ .fontSize = 32, .fontId = FONT_ID_TITLE_36, .textColor = COLOR_ORANGE })); } CLAY({ .id = CLAY_ID("DebuggerRightImageOuter"), .layout = { .sizing = { CLAY_SIZING_PERCENT(0.50) }, .childAlignment = {CLAY_ALIGN_X_CENTER} } }) { - CLAY({ .id = CLAY_ID("DebuggerPageRightImageInner"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 558) } }, .image = { .sourceDimensions = {1620, 1474}, .imageData = "/clay/images/debugger.png" } }) {} + CLAY({ .id = CLAY_ID("DebuggerPageRightImageInner"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 558) } }, .image = { .sourceDimensions = {1620, 1474}, .imageData = FrameAllocateString(CLAY_STRING("/clay/images/debugger.png")) } }) {} } } } @@ -337,10 +345,10 @@ Clay_RenderCommandArray CreateLayout(bool mobileScreen, float lerpValue) { CLAY_TEXT(CLAY_STRING("Clay"), &headerTextConfig); CLAY({ .id = CLAY_ID("Spacer"), .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) } } }) {} if (!mobileScreen) { - CLAY({ .id = CLAY_ID("LinkExamplesOuter"), .layout = { .padding = {8, 8} }, .custom = { .customData = FrameAllocateCustomData((CustomHTMLData) { .link = CLAY_STRING("https://github.com/nicbarker/clay/tree/main/examples") }) } }) { + CLAY({ .id = CLAY_ID("LinkExamplesOuter"), .layout = { .padding = {8, 8} }, .userData = FrameAllocateCustomData((CustomHTMLData) { .link = CLAY_STRING("https://github.com/nicbarker/clay/tree/main/examples") }) }) { CLAY_TEXT(CLAY_STRING("Examples"), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} })); } - CLAY({ .id = CLAY_ID("LinkDocsOuter"), .layout = { .padding = {8, 8} }, .custom = { .customData = FrameAllocateCustomData((CustomHTMLData) { .link = CLAY_STRING("https://github.com/nicbarker/clay/blob/main/README.md") }) } }) { + CLAY({ .id = CLAY_ID("LinkDocsOuter"), .layout = { .padding = {8, 8} }, .userData = FrameAllocateCustomData((CustomHTMLData) { .link = CLAY_STRING("https://github.com/nicbarker/clay/blob/main/README.md") }) }) { CLAY_TEXT(CLAY_STRING("Docs"), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} })); } } @@ -349,7 +357,7 @@ Clay_RenderCommandArray CreateLayout(bool mobileScreen, float lerpValue) { .backgroundColor = Clay_Hovered() ? COLOR_LIGHT_HOVER : COLOR_LIGHT, .border = { .width = {2, 2, 2, 2}, .color = COLOR_RED }, .cornerRadius = CLAY_CORNER_RADIUS(10), - .custom = { .customData = FrameAllocateCustomData((CustomHTMLData) { .link = CLAY_STRING("https://github.com/nicbarker/clay/tree/main/examples") }) }, + .userData = FrameAllocateCustomData((CustomHTMLData) { .link = CLAY_STRING("https://github.com/nicbarker/clay/tree/main/examples") }), }) { CLAY_TEXT(CLAY_STRING("Discord"), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} })); } @@ -358,7 +366,7 @@ Clay_RenderCommandArray CreateLayout(bool mobileScreen, float lerpValue) { .backgroundColor = Clay_Hovered() ? COLOR_LIGHT_HOVER : COLOR_LIGHT, .border = { .width = {2, 2, 2, 2}, .color = COLOR_RED }, .cornerRadius = CLAY_CORNER_RADIUS(10), - .custom = { .customData = FrameAllocateCustomData((CustomHTMLData) { .link = CLAY_STRING("https://github.com/nicbarker/clay") }) }, + .userData = FrameAllocateCustomData((CustomHTMLData) { .link = CLAY_STRING("https://github.com/nicbarker/clay") }), }) { CLAY_TEXT(CLAY_STRING("Github"), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} })); } @@ -413,7 +421,12 @@ Clay_RenderCommandArray CreateLayout(bool mobileScreen, float lerpValue) { bool debugModeEnabled = false; +CLAY_WASM_EXPORT("SetScratchMemory") void SetScratchMemory(void * memory) { + frameArena.memory = memory; +} + CLAY_WASM_EXPORT("UpdateDrawFrame") Clay_RenderCommandArray UpdateDrawFrame(float width, float height, float mouseWheelX, float mouseWheelY, float mousePositionX, float mousePositionY, bool isTouchDown, bool isMouseDown, bool arrowKeyDownPressedThisFrame, bool arrowKeyUpPressedThisFrame, bool dKeyPressedThisFrame, float deltaTime) { + frameArena.offset = 0; windowWidth = width; windowHeight = height; Clay_SetLayoutDimensions((Clay_Dimensions) { width, height });