[{"data":1,"prerenderedAt":1911},["ShallowReactive",2],{"post-learning-tea":3,"i-mdi:close":1897,"i-bx:menu":1900,"i-ph:translate":1902,"i-flag:br-4x3":1905,"i-flag:us-4x3":1909},{"id":4,"title":5,"body":6,"description":53,"description_en":1879,"description_pt":1880,"draft":1881,"extension":1882,"meta":1883,"navigation":271,"path":1884,"publishDate":1885,"seo":1886,"slug":1887,"stem":1888,"tags":1889,"title_en":1894,"title_pt":1895,"__hash__":1896},"blog/blog/learning-tea.md","Learning Tea",{"type":7,"value":8,"toc":1867},"minimark",[9,29,47,134,162,185,207,216,229,240,355,367,378,509,514,519,679,705,731,923,953,979,1037,1045,1052,1555,1596,1634,1821,1842,1863],[10,11,13,17,20,23,26],"lang-block",{"lang":12},"en",[14,15,16],"p",{},"This is the first part of a series of articles about writing a TEA-based framework in TypeScript.",[14,18,19],{},"The Elm Architecture is used in many places: Lustre in Gleam, Bubble Tea in Go, and Iced in Rust.",[14,21,22],{},"So let’s learn by creating a small project using The Elm Architecture, which we can later migrate to our own TypeScript framework. After all, there are not enough JavaScript frameworks for the web.",[14,24,25],{},"You don’t need prior Elm knowledge, but you should have a basic understanding of TypeScript and DOM events.",[14,27,28],{},"We can start with a simple Vite project, using the Vanilla template and TypeScript:",[10,30,32,35,38,41,44],{"lang":31},"pt",[14,33,34],{},"Esta é a primeira parte de uma série de artigos sobre como escrever um framework baseado em TEA (The Elm Architecture) em TypeScript.",[14,36,37],{},"A Elm Architecture é utilizada em muitos lugares: Lustre em Gleam, Bubble Tea em Go e Iced em Rust.",[14,39,40],{},"Então vamos aprender criando um pequeno projeto usando a Elm Architecture, que poderemos migrar posteriormente para o nosso próprio framework TypeScript. Afinal, nunca existem frameworks JavaScript suficientes para a web.",[14,42,43],{},"Você não precisa de conhecimento prévio de Elm, mas deve ter um entendimento básico de TypeScript e eventos do DOM.",[14,45,46],{},"Podemos começar com um projeto Vite simples, usando o template Vanilla e TypeScript:",[48,49,54],"pre",{"className":50,"code":51,"language":52,"meta":53,"style":53},"language-sh shiki shiki-themes github-dark github-dark github-light","❯ pnpm create vite\n│\n◇  Project name:\n│  tea\n│\n◇  Select a framework:\n│  Vanilla\n│\n◇  Select a variant:\n│  TypeScript\n│\n◇  Install with pnpm and start now?\n│  Yes\n","sh","",[55,56,57,65,71,77,83,88,94,100,105,111,117,122,128],"code",{"__ignoreMap":53},[58,59,62],"span",{"class":60,"line":61},"line",1,[58,63,64],{},"❯ pnpm create vite\n",[58,66,68],{"class":60,"line":67},2,[58,69,70],{},"│\n",[58,72,74],{"class":60,"line":73},3,[58,75,76],{},"◇  Project name:\n",[58,78,80],{"class":60,"line":79},4,[58,81,82],{},"│  tea\n",[58,84,86],{"class":60,"line":85},5,[58,87,70],{},[58,89,91],{"class":60,"line":90},6,[58,92,93],{},"◇  Select a framework:\n",[58,95,97],{"class":60,"line":96},7,[58,98,99],{},"│  Vanilla\n",[58,101,103],{"class":60,"line":102},8,[58,104,70],{},[58,106,108],{"class":60,"line":107},9,[58,109,110],{},"◇  Select a variant:\n",[58,112,114],{"class":60,"line":113},10,[58,115,116],{},"│  TypeScript\n",[58,118,120],{"class":60,"line":119},11,[58,121,70],{},[58,123,125],{"class":60,"line":124},12,[58,126,127],{},"◇  Install with pnpm and start now?\n",[58,129,131],{"class":60,"line":130},13,[58,132,133],{},"│  Yes\n",[10,135,136,143],{"lang":12},[14,137,138,139,142],{},"For this article we are going to use ",[55,140,141],{},"lit-html"," so we don’t have to implement two key features ourselves: HTML generation and efficient rendering.",[14,144,145,146,149,150,153,154,157,158,161],{},"We can create templates with JavaScript interpolation by using the ",[55,147,148],{},"html"," tag (for example, ",[55,151,152],{},"${...}"," inside the template), and we can bind DOM events with ",[55,155,156],{},"@event"," syntax, similar to Vue, and conceptually similar to ",[55,159,160],{},"onEvent"," props in React.",[10,163,164,170],{"lang":31},[14,165,166,167,169],{},"Para este artigo, vamos usar ",[55,168,141],{}," para não termos que implementar duas funcionalidades principais nós mesmos: geração de HTML e renderização eficiente.",[14,171,172,173,175,176,178,179,181,182,184],{},"Podemos criar templates com interpolação JavaScript usando a tag ",[55,174,148],{}," (por exemplo, ",[55,177,152],{}," dentro do template), e podemos vincular eventos do DOM com a sintaxe ",[55,180,156],{},", semelhante ao Vue, e conceitualmente parecida com as props ",[55,183,160],{}," no React.",[186,187,190,199],"more-info",{"title-en":188,"title-pt":189},"Tip","Dica",[191,192,193],"template",{"v-slot:en":53},[14,194,195,196,198],{},"If you want syntax highlighting inside ",[55,197,148],{}," template literals, install the VS Code plugin for Lit.",[191,200,201],{"v-slot:pt":53},[14,202,203,204,206],{},"Se você quiser realce de sintaxe dentro de literais de template ",[55,205,148],{},", instale o plugin do VS Code para Lit.",[48,208,210],{"className":50,"code":209,"language":52,"meta":53,"style":53},"pnpm add lit-html\n",[55,211,212],{"__ignoreMap":53},[58,213,214],{"class":60,"line":61},[58,215,209],{},[10,217,218],{"lang":12},[14,219,220,221,224,225,228],{},"We remove everything in ",[55,222,223],{},"main.ts"," and write a basic ",[55,226,227],{},"view"," for our app:",[10,230,231],{"lang":31},[14,232,233,234,236,237,239],{},"Removemos tudo no ",[55,235,223],{}," e escrevemos uma ",[55,238,227],{}," básica para o nosso app:",[48,241,245],{"className":242,"code":243,"language":244,"meta":53,"style":53},"language-ts shiki shiki-themes github-dark github-dark github-light","import { html, render } from \"lit-html\";\n\nconst view = html`\n  \u003Ch1>Hello, World\u003C/h1>\n  \u003Cp>Counter is at 0\u003C/p>\n  \u003Cbutton>Click me\u003C/button>\n`;\n\nconst root = document.getElementById(\"app\")!;\nrender(view, root);\n","ts",[55,246,247,267,273,292,297,302,307,314,318,347],{"__ignoreMap":53},[58,248,249,253,257,260,264],{"class":60,"line":61},[58,250,252],{"class":251},"s6ubI","import",[58,254,256],{"class":255},"sAvwS"," { html, render } ",[58,258,259],{"class":251},"from",[58,261,263],{"class":262},"s4Y1p"," \"lit-html\"",[58,265,266],{"class":255},";\n",[58,268,269],{"class":60,"line":67},[58,270,272],{"emptyLinePlaceholder":271},true,"\n",[58,274,275,278,282,285,289],{"class":60,"line":73},[58,276,277],{"class":251},"const",[58,279,281],{"class":280},"sXWYR"," view",[58,283,284],{"class":251}," =",[58,286,288],{"class":287},"s5n6i"," html",[58,290,291],{"class":262},"`\n",[58,293,294],{"class":60,"line":79},[58,295,296],{"class":262},"  \u003Ch1>Hello, World\u003C/h1>\n",[58,298,299],{"class":60,"line":85},[58,300,301],{"class":262},"  \u003Cp>Counter is at 0\u003C/p>\n",[58,303,304],{"class":60,"line":90},[58,305,306],{"class":262},"  \u003Cbutton>Click me\u003C/button>\n",[58,308,309,312],{"class":60,"line":96},[58,310,311],{"class":262},"`",[58,313,266],{"class":255},[58,315,316],{"class":60,"line":102},[58,317,272],{"emptyLinePlaceholder":271},[58,319,320,322,325,327,330,333,336,339,342,345],{"class":60,"line":107},[58,321,277],{"class":251},[58,323,324],{"class":280}," root",[58,326,284],{"class":251},[58,328,329],{"class":255}," document.",[58,331,332],{"class":287},"getElementById",[58,334,335],{"class":255},"(",[58,337,338],{"class":262},"\"app\"",[58,340,341],{"class":255},")",[58,343,344],{"class":251},"!",[58,346,266],{"class":255},[58,348,349,352],{"class":60,"line":113},[58,350,351],{"class":287},"render",[58,353,354],{"class":255},"(view, root);\n",[10,356,357],{"lang":12},[14,358,359,360,363,364,366],{},"We render into ",[55,361,362],{},"#app"," using ",[55,365,141],{},". Next, let’s make this dynamic using interpolation:",[10,368,369],{"lang":31},[14,370,371,372,374,375,377],{},"Renderizamos no ",[55,373,362],{}," usando ",[55,376,141],{},". Em seguida, vamos tornar isso dinâmico usando interpolação:",[48,379,381],{"className":242,"code":380,"language":244,"meta":53,"style":53},"import { html, render } from \"lit-html\";\n\nlet counter = 0;\nconst title = \"Hello, World\";\n\nconst view = html`\n  \u003Ch1>${title}\u003C/h1>\n  \u003Cp>Counter is at ${counter}\u003C/p>\n  \u003Cbutton>Click me\u003C/button>\n`;\n\nconst root = document.getElementById(\"app\")!;\nrender(view, root);\n",[55,382,383,395,399,415,429,433,445,456,467,471,477,481,503],{"__ignoreMap":53},[58,384,385,387,389,391,393],{"class":60,"line":61},[58,386,252],{"class":251},[58,388,256],{"class":255},[58,390,259],{"class":251},[58,392,263],{"class":262},[58,394,266],{"class":255},[58,396,397],{"class":60,"line":67},[58,398,272],{"emptyLinePlaceholder":271},[58,400,401,404,407,410,413],{"class":60,"line":73},[58,402,403],{"class":251},"let",[58,405,406],{"class":255}," counter ",[58,408,409],{"class":251},"=",[58,411,412],{"class":280}," 0",[58,414,266],{"class":255},[58,416,417,419,422,424,427],{"class":60,"line":79},[58,418,277],{"class":251},[58,420,421],{"class":280}," title",[58,423,284],{"class":251},[58,425,426],{"class":262}," \"Hello, World\"",[58,428,266],{"class":255},[58,430,431],{"class":60,"line":85},[58,432,272],{"emptyLinePlaceholder":271},[58,434,435,437,439,441,443],{"class":60,"line":90},[58,436,277],{"class":251},[58,438,281],{"class":280},[58,440,284],{"class":251},[58,442,288],{"class":287},[58,444,291],{"class":262},[58,446,447,450,453],{"class":60,"line":96},[58,448,449],{"class":262},"  \u003Ch1>${",[58,451,452],{"class":255},"title",[58,454,455],{"class":262},"}\u003C/h1>\n",[58,457,458,461,464],{"class":60,"line":102},[58,459,460],{"class":262},"  \u003Cp>Counter is at ${",[58,462,463],{"class":255},"counter",[58,465,466],{"class":262},"}\u003C/p>\n",[58,468,469],{"class":60,"line":107},[58,470,306],{"class":262},[58,472,473,475],{"class":60,"line":113},[58,474,311],{"class":262},[58,476,266],{"class":255},[58,478,479],{"class":60,"line":119},[58,480,272],{"emptyLinePlaceholder":271},[58,482,483,485,487,489,491,493,495,497,499,501],{"class":60,"line":124},[58,484,277],{"class":251},[58,486,324],{"class":280},[58,488,284],{"class":251},[58,490,329],{"class":255},[58,492,332],{"class":287},[58,494,335],{"class":255},[58,496,338],{"class":262},[58,498,341],{"class":255},[58,500,344],{"class":251},[58,502,266],{"class":255},[58,504,505,507],{"class":60,"line":130},[58,506,351],{"class":287},[58,508,354],{"class":255},[10,510,511],{"lang":12},[14,512,513],{},"Now, let’s make a function that increases the counter and bind it to the button:",[10,515,516],{"lang":31},[14,517,518],{},"Agora, vamos criar uma função que aumenta o contador e vinculá-la ao botão:",[48,520,522],{"className":242,"code":521,"language":244,"meta":53,"style":53},"import { html, render } from \"lit-html\";\n\nlet counter = 0;\nconst title = \"Hello, World\";\n\nconst view = html`\n  \u003Ch1>${title}\u003C/h1>\n  \u003Cp>Counter is at ${counter}\u003C/p>\n  \u003Cbutton @click=${increaseCounter}>Click me\u003C/button>\n`;\n\nconst root = document.getElementById(\"app\")!;\nrender(view, root);\n\nfunction increaseCounter() {\n  counter++;\n}\n",[55,523,524,536,540,552,564,568,580,588,596,607,613,617,639,645,650,662,673],{"__ignoreMap":53},[58,525,526,528,530,532,534],{"class":60,"line":61},[58,527,252],{"class":251},[58,529,256],{"class":255},[58,531,259],{"class":251},[58,533,263],{"class":262},[58,535,266],{"class":255},[58,537,538],{"class":60,"line":67},[58,539,272],{"emptyLinePlaceholder":271},[58,541,542,544,546,548,550],{"class":60,"line":73},[58,543,403],{"class":251},[58,545,406],{"class":255},[58,547,409],{"class":251},[58,549,412],{"class":280},[58,551,266],{"class":255},[58,553,554,556,558,560,562],{"class":60,"line":79},[58,555,277],{"class":251},[58,557,421],{"class":280},[58,559,284],{"class":251},[58,561,426],{"class":262},[58,563,266],{"class":255},[58,565,566],{"class":60,"line":85},[58,567,272],{"emptyLinePlaceholder":271},[58,569,570,572,574,576,578],{"class":60,"line":90},[58,571,277],{"class":251},[58,573,281],{"class":280},[58,575,284],{"class":251},[58,577,288],{"class":287},[58,579,291],{"class":262},[58,581,582,584,586],{"class":60,"line":96},[58,583,449],{"class":262},[58,585,452],{"class":255},[58,587,455],{"class":262},[58,589,590,592,594],{"class":60,"line":102},[58,591,460],{"class":262},[58,593,463],{"class":255},[58,595,466],{"class":262},[58,597,598,601,604],{"class":60,"line":107},[58,599,600],{"class":262},"  \u003Cbutton @click=${",[58,602,603],{"class":255},"increaseCounter",[58,605,606],{"class":262},"}>Click me\u003C/button>\n",[58,608,609,611],{"class":60,"line":113},[58,610,311],{"class":262},[58,612,266],{"class":255},[58,614,615],{"class":60,"line":119},[58,616,272],{"emptyLinePlaceholder":271},[58,618,619,621,623,625,627,629,631,633,635,637],{"class":60,"line":124},[58,620,277],{"class":251},[58,622,324],{"class":280},[58,624,284],{"class":251},[58,626,329],{"class":255},[58,628,332],{"class":287},[58,630,335],{"class":255},[58,632,338],{"class":262},[58,634,341],{"class":255},[58,636,344],{"class":251},[58,638,266],{"class":255},[58,640,641,643],{"class":60,"line":130},[58,642,351],{"class":287},[58,644,354],{"class":255},[58,646,648],{"class":60,"line":647},14,[58,649,272],{"emptyLinePlaceholder":271},[58,651,653,656,659],{"class":60,"line":652},15,[58,654,655],{"class":251},"function",[58,657,658],{"class":287}," increaseCounter",[58,660,661],{"class":255},"() {\n",[58,663,665,668,671],{"class":60,"line":664},16,[58,666,667],{"class":255},"  counter",[58,669,670],{"class":251},"++",[58,672,266],{"class":255},[58,674,676],{"class":60,"line":675},17,[58,677,678],{"class":255},"}\n",[10,680,681,684,699],{"lang":12},[14,682,683],{},"But this won’t work. Why?",[14,685,686,687,689,690,692,693,695,696,698],{},"When ",[55,688,603],{}," runs, the ",[55,691,227],{}," was already created and rendered. We update ",[55,694,463],{},", but we don’t create a new ",[55,697,227],{}," or render again.",[14,700,701,702,704],{},"Let’s fix that by making ",[55,703,227],{}," a function that receives state, and re-rendering after each update:",[10,706,707,710,725],{"lang":31},[14,708,709],{},"Mas isso não vai funcionar. Por quê?",[14,711,712,713,715,716,718,719,721,722,724],{},"Quando o ",[55,714,603],{}," é executado, a ",[55,717,227],{}," já foi criada e renderizada. Atualizamos o ",[55,720,463],{},", mas não criamos uma nova ",[55,723,227],{}," nem renderizamos novamente.",[14,726,727,728,730],{},"Vamos corrigir isso tornando a ",[55,729,227],{}," uma função que recebe o estado e renderizando novamente após cada atualização:",[48,732,734],{"className":242,"code":733,"language":244,"meta":53,"style":53},"import { html, render } from \"lit-html\";\n\nlet counter = 0;\nconst title = \"Hello, World\";\n\nfunction view(counterAmount: number) {\n  return html`\n    \u003Ch1>${title}\u003C/h1>\n    \u003Cp>Counter is at ${counterAmount}\u003C/p>\n    \u003Cbutton @click=${increaseCounter}>Click me\u003C/button>\n  `;\n}\n\nconst root = document.getElementById(\"app\")!;\nrender(view(counter), root);\n\nfunction increaseCounter() {\n  counter++;\n  render(view(counter), root);\n}\n",[55,735,736,748,752,764,776,780,801,810,819,828,837,844,848,852,874,885,889,897,906,918],{"__ignoreMap":53},[58,737,738,740,742,744,746],{"class":60,"line":61},[58,739,252],{"class":251},[58,741,256],{"class":255},[58,743,259],{"class":251},[58,745,263],{"class":262},[58,747,266],{"class":255},[58,749,750],{"class":60,"line":67},[58,751,272],{"emptyLinePlaceholder":271},[58,753,754,756,758,760,762],{"class":60,"line":73},[58,755,403],{"class":251},[58,757,406],{"class":255},[58,759,409],{"class":251},[58,761,412],{"class":280},[58,763,266],{"class":255},[58,765,766,768,770,772,774],{"class":60,"line":79},[58,767,277],{"class":251},[58,769,421],{"class":280},[58,771,284],{"class":251},[58,773,426],{"class":262},[58,775,266],{"class":255},[58,777,778],{"class":60,"line":85},[58,779,272],{"emptyLinePlaceholder":271},[58,781,782,784,786,788,792,795,798],{"class":60,"line":90},[58,783,655],{"class":251},[58,785,281],{"class":287},[58,787,335],{"class":255},[58,789,791],{"class":790},"sAzo5","counterAmount",[58,793,794],{"class":251},":",[58,796,797],{"class":280}," number",[58,799,800],{"class":255},") {\n",[58,802,803,806,808],{"class":60,"line":96},[58,804,805],{"class":251},"  return",[58,807,288],{"class":287},[58,809,291],{"class":262},[58,811,812,815,817],{"class":60,"line":102},[58,813,814],{"class":262},"    \u003Ch1>${",[58,816,452],{"class":255},[58,818,455],{"class":262},[58,820,821,824,826],{"class":60,"line":107},[58,822,823],{"class":262},"    \u003Cp>Counter is at ${",[58,825,791],{"class":255},[58,827,466],{"class":262},[58,829,830,833,835],{"class":60,"line":113},[58,831,832],{"class":262},"    \u003Cbutton @click=${",[58,834,603],{"class":255},[58,836,606],{"class":262},[58,838,839,842],{"class":60,"line":119},[58,840,841],{"class":262},"  `",[58,843,266],{"class":255},[58,845,846],{"class":60,"line":124},[58,847,678],{"class":255},[58,849,850],{"class":60,"line":130},[58,851,272],{"emptyLinePlaceholder":271},[58,853,854,856,858,860,862,864,866,868,870,872],{"class":60,"line":647},[58,855,277],{"class":251},[58,857,324],{"class":280},[58,859,284],{"class":251},[58,861,329],{"class":255},[58,863,332],{"class":287},[58,865,335],{"class":255},[58,867,338],{"class":262},[58,869,341],{"class":255},[58,871,344],{"class":251},[58,873,266],{"class":255},[58,875,876,878,880,882],{"class":60,"line":652},[58,877,351],{"class":287},[58,879,335],{"class":255},[58,881,227],{"class":287},[58,883,884],{"class":255},"(counter), root);\n",[58,886,887],{"class":60,"line":664},[58,888,272],{"emptyLinePlaceholder":271},[58,890,891,893,895],{"class":60,"line":675},[58,892,655],{"class":251},[58,894,658],{"class":287},[58,896,661],{"class":255},[58,898,900,902,904],{"class":60,"line":899},18,[58,901,667],{"class":255},[58,903,670],{"class":251},[58,905,266],{"class":255},[58,907,909,912,914,916],{"class":60,"line":908},19,[58,910,911],{"class":287},"  render",[58,913,335],{"class":255},[58,915,227],{"class":287},[58,917,884],{"class":255},[58,919,921],{"class":60,"line":920},20,[58,922,678],{"class":255},[10,924,925,928,931,938,947,950],{"lang":12},[14,926,927],{},"Now clicking the button updates the UI again.",[14,929,930],{},"At a high level, this idea appears in many frameworks: UI as a function of state. The details differ (Virtual DOM, fine-grained reactivity, compile-time optimizations), but the core loop is familiar.",[14,932,933,934,937],{},"Now we’ll apply the core ideas from The Elm Architecture but encapsulated in a class, similar to how the ",[55,935,936],{},"iced"," library works in Rust.",[939,940,942,943,946],"h2",{"id":941},"the-counter-application","The ",[55,944,945],{},"Counter"," Application",[14,948,949],{},"Instead of loose functions and variables, we’ll encapsulate our application logic in a class. This class will hold our application state and define how to update and view it.",[14,951,952],{},"First, let's define our state and messages:",[10,954,955,958,961,967,973,976],{"lang":31},[14,956,957],{},"Agora, clicar no botão atualiza a UI novamente.",[14,959,960],{},"Em um nível macro, essa ideia aparece em muitos frameworks: a UI como uma função do estado. Os detalhes diferem (Virtual DOM, reatividade granular, otimizações em tempo de compilação), mas o loop principal é familiar.",[14,962,963,964,966],{},"Agora vamos aplicar as ideias centrais da Elm Architecture, mas encapsuladas em uma classe, semelhante a como a biblioteca ",[55,965,936],{}," funciona em Rust.",[939,968,970,971],{"id":969},"a-aplicação-counter","A Aplicação ",[55,972,945],{},[14,974,975],{},"Em vez de funções e variáveis soltas, vamos encapsular a lógica da nossa aplicação em uma classe. Essa classe manterá o estado da nossa aplicação e definirá como atualizá-lo e visualizá-lo.",[14,977,978],{},"Primeiro, vamos definir nosso estado e mensagens:",[48,980,982],{"className":242,"code":981,"language":244,"meta":53,"style":53},"type State = {\n  value: number;\n};\n\ntype Message = \"Increment\" | \"Decrement\";\n",[55,983,984,997,1008,1013,1017],{"__ignoreMap":53},[58,985,986,989,992,994],{"class":60,"line":61},[58,987,988],{"class":251},"type",[58,990,991],{"class":287}," State",[58,993,284],{"class":251},[58,995,996],{"class":255}," {\n",[58,998,999,1002,1004,1006],{"class":60,"line":67},[58,1000,1001],{"class":790},"  value",[58,1003,794],{"class":251},[58,1005,797],{"class":280},[58,1007,266],{"class":255},[58,1009,1010],{"class":60,"line":73},[58,1011,1012],{"class":255},"};\n",[58,1014,1015],{"class":60,"line":79},[58,1016,272],{"emptyLinePlaceholder":271},[58,1018,1019,1021,1024,1026,1029,1032,1035],{"class":60,"line":85},[58,1020,988],{"class":251},[58,1022,1023],{"class":287}," Message",[58,1025,284],{"class":251},[58,1027,1028],{"class":262}," \"Increment\"",[58,1030,1031],{"class":251}," |",[58,1033,1034],{"class":262}," \"Decrement\"",[58,1036,266],{"class":255},[10,1038,1039],{"lang":12},[14,1040,1041,1042,1044],{},"Now, let's create the ",[55,1043,945],{}," class:",[10,1046,1047],{"lang":31},[14,1048,1049,1050,794],{},"Agora, vamos criar a classe ",[55,1051,945],{},[48,1053,1055],{"className":242,"code":1054,"language":244,"meta":53,"style":53},"import { html, render } from \"lit-html\";\n\nclass Counter {\n  // We use an internal state object\n  state: State = {\n    value: 0,\n  };\n\n  // The update method describes how state changes in response to messages\n  update(message: Message) {\n    // We capture a snapshot of the current state before the update logic starts.\n    let state = this.state;\n\n    switch (message) {\n      case \"Increment\":\n        this.state = { ...state, value: state.value + 1 };\n        break;\n      case \"Decrement\":\n        this.state = { ...state, value: state.value - 1 };\n        break;\n    }\n  }\n\n  // The view method describes how the UI should look based on the current state\n  view() {\n    return html`\n      \u003Ch1>Counter App\u003C/h1>\n      \u003Cp>Count: ${this.state.value}\u003C/p>\n      \u003Cbutton @click=${() => this.dispatch(\"Increment\")}>+\u003C/button>\n      \u003Cbutton @click=${() => this.dispatch(\"Decrement\")}>-\u003C/button>\n    `;\n  }\n\n  // The runtime logic\n  private root = document.getElementById(\"app\")!;\n\n  dispatch(message: Message) {\n    this.update(message);\n    this.render();\n  }\n\n  render() {\n    render(this.view(), this.root);\n  }\n}\n\nconst app = new Counter();\napp.render();\n",[55,1056,1057,1069,1073,1083,1089,1102,1113,1118,1122,1127,1143,1148,1164,1168,1176,1186,1214,1221,1229,1250,1256,1262,1268,1273,1279,1287,1297,1303,1325,1354,1379,1387,1392,1397,1403,1427,1432,1448,1462,1474,1479,1484,1491,1513,1518,1523,1528,1545],{"__ignoreMap":53},[58,1058,1059,1061,1063,1065,1067],{"class":60,"line":61},[58,1060,252],{"class":251},[58,1062,256],{"class":255},[58,1064,259],{"class":251},[58,1066,263],{"class":262},[58,1068,266],{"class":255},[58,1070,1071],{"class":60,"line":67},[58,1072,272],{"emptyLinePlaceholder":271},[58,1074,1075,1078,1081],{"class":60,"line":73},[58,1076,1077],{"class":251},"class",[58,1079,1080],{"class":287}," Counter",[58,1082,996],{"class":255},[58,1084,1085],{"class":60,"line":79},[58,1086,1088],{"class":1087},"sxXm1","  // We use an internal state object\n",[58,1090,1091,1094,1096,1098,1100],{"class":60,"line":85},[58,1092,1093],{"class":790},"  state",[58,1095,794],{"class":251},[58,1097,991],{"class":287},[58,1099,284],{"class":251},[58,1101,996],{"class":255},[58,1103,1104,1107,1110],{"class":60,"line":90},[58,1105,1106],{"class":255},"    value: ",[58,1108,1109],{"class":280},"0",[58,1111,1112],{"class":255},",\n",[58,1114,1115],{"class":60,"line":96},[58,1116,1117],{"class":255},"  };\n",[58,1119,1120],{"class":60,"line":102},[58,1121,272],{"emptyLinePlaceholder":271},[58,1123,1124],{"class":60,"line":107},[58,1125,1126],{"class":1087},"  // The update method describes how state changes in response to messages\n",[58,1128,1129,1132,1134,1137,1139,1141],{"class":60,"line":113},[58,1130,1131],{"class":287},"  update",[58,1133,335],{"class":255},[58,1135,1136],{"class":790},"message",[58,1138,794],{"class":251},[58,1140,1023],{"class":287},[58,1142,800],{"class":255},[58,1144,1145],{"class":60,"line":119},[58,1146,1147],{"class":1087},"    // We capture a snapshot of the current state before the update logic starts.\n",[58,1149,1150,1153,1156,1158,1161],{"class":60,"line":124},[58,1151,1152],{"class":251},"    let",[58,1154,1155],{"class":255}," state ",[58,1157,409],{"class":251},[58,1159,1160],{"class":280}," this",[58,1162,1163],{"class":255},".state;\n",[58,1165,1166],{"class":60,"line":130},[58,1167,272],{"emptyLinePlaceholder":271},[58,1169,1170,1173],{"class":60,"line":647},[58,1171,1172],{"class":251},"    switch",[58,1174,1175],{"class":255}," (message) {\n",[58,1177,1178,1181,1183],{"class":60,"line":652},[58,1179,1180],{"class":251},"      case",[58,1182,1028],{"class":262},[58,1184,1185],{"class":255},":\n",[58,1187,1188,1191,1194,1196,1199,1202,1205,1208,1211],{"class":60,"line":664},[58,1189,1190],{"class":280},"        this",[58,1192,1193],{"class":255},".state ",[58,1195,409],{"class":251},[58,1197,1198],{"class":255}," { ",[58,1200,1201],{"class":251},"...",[58,1203,1204],{"class":255},"state, value: state.value ",[58,1206,1207],{"class":251},"+",[58,1209,1210],{"class":280}," 1",[58,1212,1213],{"class":255}," };\n",[58,1215,1216,1219],{"class":60,"line":675},[58,1217,1218],{"class":251},"        break",[58,1220,266],{"class":255},[58,1222,1223,1225,1227],{"class":60,"line":899},[58,1224,1180],{"class":251},[58,1226,1034],{"class":262},[58,1228,1185],{"class":255},[58,1230,1231,1233,1235,1237,1239,1241,1243,1246,1248],{"class":60,"line":908},[58,1232,1190],{"class":280},[58,1234,1193],{"class":255},[58,1236,409],{"class":251},[58,1238,1198],{"class":255},[58,1240,1201],{"class":251},[58,1242,1204],{"class":255},[58,1244,1245],{"class":251},"-",[58,1247,1210],{"class":280},[58,1249,1213],{"class":255},[58,1251,1252,1254],{"class":60,"line":920},[58,1253,1218],{"class":251},[58,1255,266],{"class":255},[58,1257,1259],{"class":60,"line":1258},21,[58,1260,1261],{"class":255},"    }\n",[58,1263,1265],{"class":60,"line":1264},22,[58,1266,1267],{"class":255},"  }\n",[58,1269,1271],{"class":60,"line":1270},23,[58,1272,272],{"emptyLinePlaceholder":271},[58,1274,1276],{"class":60,"line":1275},24,[58,1277,1278],{"class":1087},"  // The view method describes how the UI should look based on the current state\n",[58,1280,1282,1285],{"class":60,"line":1281},25,[58,1283,1284],{"class":287},"  view",[58,1286,661],{"class":255},[58,1288,1290,1293,1295],{"class":60,"line":1289},26,[58,1291,1292],{"class":251},"    return",[58,1294,288],{"class":287},[58,1296,291],{"class":262},[58,1298,1300],{"class":60,"line":1299},27,[58,1301,1302],{"class":262},"      \u003Ch1>Counter App\u003C/h1>\n",[58,1304,1306,1309,1312,1315,1318,1320,1323],{"class":60,"line":1305},28,[58,1307,1308],{"class":262},"      \u003Cp>Count: ${",[58,1310,1311],{"class":280},"this",[58,1313,1314],{"class":262},".",[58,1316,1317],{"class":255},"state",[58,1319,1314],{"class":262},[58,1321,1322],{"class":255},"value",[58,1324,466],{"class":262},[58,1326,1328,1331,1334,1337,1339,1341,1344,1346,1349,1351],{"class":60,"line":1327},29,[58,1329,1330],{"class":262},"      \u003Cbutton @click=${",[58,1332,1333],{"class":262},"() ",[58,1335,1336],{"class":251},"=>",[58,1338,1160],{"class":280},[58,1340,1314],{"class":262},[58,1342,1343],{"class":287},"dispatch",[58,1345,335],{"class":262},[58,1347,1348],{"class":262},"\"Increment\"",[58,1350,341],{"class":262},[58,1352,1353],{"class":262},"}>+\u003C/button>\n",[58,1355,1357,1359,1361,1363,1365,1367,1369,1371,1374,1376],{"class":60,"line":1356},30,[58,1358,1330],{"class":262},[58,1360,1333],{"class":262},[58,1362,1336],{"class":251},[58,1364,1160],{"class":280},[58,1366,1314],{"class":262},[58,1368,1343],{"class":287},[58,1370,335],{"class":262},[58,1372,1373],{"class":262},"\"Decrement\"",[58,1375,341],{"class":262},[58,1377,1378],{"class":262},"}>-\u003C/button>\n",[58,1380,1382,1385],{"class":60,"line":1381},31,[58,1383,1384],{"class":262},"    `",[58,1386,266],{"class":255},[58,1388,1390],{"class":60,"line":1389},32,[58,1391,1267],{"class":255},[58,1393,1395],{"class":60,"line":1394},33,[58,1396,272],{"emptyLinePlaceholder":271},[58,1398,1400],{"class":60,"line":1399},34,[58,1401,1402],{"class":1087},"  // The runtime logic\n",[58,1404,1406,1409,1411,1413,1415,1417,1419,1421,1423,1425],{"class":60,"line":1405},35,[58,1407,1408],{"class":251},"  private",[58,1410,324],{"class":790},[58,1412,284],{"class":251},[58,1414,329],{"class":255},[58,1416,332],{"class":287},[58,1418,335],{"class":255},[58,1420,338],{"class":262},[58,1422,341],{"class":255},[58,1424,344],{"class":251},[58,1426,266],{"class":255},[58,1428,1430],{"class":60,"line":1429},36,[58,1431,272],{"emptyLinePlaceholder":271},[58,1433,1435,1438,1440,1442,1444,1446],{"class":60,"line":1434},37,[58,1436,1437],{"class":287},"  dispatch",[58,1439,335],{"class":255},[58,1441,1136],{"class":790},[58,1443,794],{"class":251},[58,1445,1023],{"class":287},[58,1447,800],{"class":255},[58,1449,1451,1454,1456,1459],{"class":60,"line":1450},38,[58,1452,1453],{"class":280},"    this",[58,1455,1314],{"class":255},[58,1457,1458],{"class":287},"update",[58,1460,1461],{"class":255},"(message);\n",[58,1463,1465,1467,1469,1471],{"class":60,"line":1464},39,[58,1466,1453],{"class":280},[58,1468,1314],{"class":255},[58,1470,351],{"class":287},[58,1472,1473],{"class":255},"();\n",[58,1475,1477],{"class":60,"line":1476},40,[58,1478,1267],{"class":255},[58,1480,1482],{"class":60,"line":1481},41,[58,1483,272],{"emptyLinePlaceholder":271},[58,1485,1487,1489],{"class":60,"line":1486},42,[58,1488,911],{"class":287},[58,1490,661],{"class":255},[58,1492,1494,1497,1499,1501,1503,1505,1508,1510],{"class":60,"line":1493},43,[58,1495,1496],{"class":287},"    render",[58,1498,335],{"class":255},[58,1500,1311],{"class":280},[58,1502,1314],{"class":255},[58,1504,227],{"class":287},[58,1506,1507],{"class":255},"(), ",[58,1509,1311],{"class":280},[58,1511,1512],{"class":255},".root);\n",[58,1514,1516],{"class":60,"line":1515},44,[58,1517,1267],{"class":255},[58,1519,1521],{"class":60,"line":1520},45,[58,1522,678],{"class":255},[58,1524,1526],{"class":60,"line":1525},46,[58,1527,272],{"emptyLinePlaceholder":271},[58,1529,1531,1533,1536,1538,1541,1543],{"class":60,"line":1530},47,[58,1532,277],{"class":251},[58,1534,1535],{"class":280}," app",[58,1537,284],{"class":251},[58,1539,1540],{"class":251}," new",[58,1542,1080],{"class":287},[58,1544,1473],{"class":255},[58,1546,1548,1551,1553],{"class":60,"line":1547},48,[58,1549,1550],{"class":255},"app.",[58,1552,351],{"class":287},[58,1554,1473],{"class":255},[10,1556,1557,1561,1574,1584,1587,1593],{"lang":12},[939,1558,1560],{"id":1559},"why-avoid-mutation","Why avoid mutation?",[14,1562,1563,1564,1566,1567,1570,1571,1314],{},"In the ",[55,1565,1458],{}," method, notice we didn't do ",[55,1568,1569],{},"this.state.value++",". Instead, we created a whole new object: ",[55,1572,1573],{},"this.state = { ...state, value: state.value + 1 }",[14,1575,1576,1577,1579,1580,1314],{},"By reassigning the ",[55,1578,1317],{}," instead of mutating its properties, we preserve the previous state in memory (as long as something holds a reference to it). This is the foundation for features like ",[1581,1582,1583],"strong",{},"Time Traveling",[939,1585,1583],{"id":1586},"time-traveling",[14,1588,1589,1590,1592],{},"Because our ",[55,1591,1458],{}," logic is based on transition from one immutable state to another, we can easily keep track of every state our application has ever been in.",[14,1594,1595],{},"Imagine adding a history array to our class:",[10,1597,1598,1602,1613,1622,1625,1631],{"lang":31},[939,1599,1601],{"id":1600},"por-que-evitar-mutação","Por que evitar mutação?",[14,1603,1604,1605,1607,1608,1610,1611,1314],{},"No método ",[55,1606,1458],{},", observe que não fizemos ",[55,1609,1569],{},". Em vez disso, criamos um objeto totalmente novo: ",[55,1612,1573],{},[14,1614,1615,1616,1618,1619,1621],{},"Ao reatribuir o ",[55,1617,1317],{}," em vez de mutar suas propriedades, preservamos o estado anterior na memória (desde que algo mantenha uma referência a ele). Esta é a base para funcionalidades como ",[1581,1620,1583],{}," (Viagem no Tempo).",[939,1623,1583],{"id":1624},"time-traveling-1",[14,1626,1627,1628,1630],{},"Como nossa lógica de ",[55,1629,1458],{}," é baseada na transição de um estado imutável para outro, podemos facilmente rastrear todos os estados em que nossa aplicação já esteve.",[14,1632,1633],{},"Imagine adicionar um array de histórico à nossa classe:",[48,1635,1637],{"className":242,"code":1636,"language":244,"meta":53,"style":53},"class Counter {\n  state: State = { value: 0 };\n  history: State[] = [];\n\n  dispatch(message: Message) {\n    // Save current state to history before updating\n    this.history.push(this.state);\n\n    this.update(message);\n    this.render();\n  }\n\n  undo() {\n    const previousState = this.history.pop();\n    if (previousState) {\n      this.state = previousState;\n      this.render();\n    }\n  }\n}\n",[55,1638,1639,1647,1664,1681,1685,1699,1704,1721,1725,1735,1745,1749,1753,1760,1779,1787,1799,1809,1813,1817],{"__ignoreMap":53},[58,1640,1641,1643,1645],{"class":60,"line":61},[58,1642,1077],{"class":251},[58,1644,1080],{"class":287},[58,1646,996],{"class":255},[58,1648,1649,1651,1653,1655,1657,1660,1662],{"class":60,"line":67},[58,1650,1093],{"class":790},[58,1652,794],{"class":251},[58,1654,991],{"class":287},[58,1656,284],{"class":251},[58,1658,1659],{"class":255}," { value: ",[58,1661,1109],{"class":280},[58,1663,1213],{"class":255},[58,1665,1666,1669,1671,1673,1676,1678],{"class":60,"line":73},[58,1667,1668],{"class":790},"  history",[58,1670,794],{"class":251},[58,1672,991],{"class":287},[58,1674,1675],{"class":255},"[] ",[58,1677,409],{"class":251},[58,1679,1680],{"class":255}," [];\n",[58,1682,1683],{"class":60,"line":79},[58,1684,272],{"emptyLinePlaceholder":271},[58,1686,1687,1689,1691,1693,1695,1697],{"class":60,"line":85},[58,1688,1437],{"class":287},[58,1690,335],{"class":255},[58,1692,1136],{"class":790},[58,1694,794],{"class":251},[58,1696,1023],{"class":287},[58,1698,800],{"class":255},[58,1700,1701],{"class":60,"line":90},[58,1702,1703],{"class":1087},"    // Save current state to history before updating\n",[58,1705,1706,1708,1711,1714,1716,1718],{"class":60,"line":96},[58,1707,1453],{"class":280},[58,1709,1710],{"class":255},".history.",[58,1712,1713],{"class":287},"push",[58,1715,335],{"class":255},[58,1717,1311],{"class":280},[58,1719,1720],{"class":255},".state);\n",[58,1722,1723],{"class":60,"line":102},[58,1724,272],{"emptyLinePlaceholder":271},[58,1726,1727,1729,1731,1733],{"class":60,"line":107},[58,1728,1453],{"class":280},[58,1730,1314],{"class":255},[58,1732,1458],{"class":287},[58,1734,1461],{"class":255},[58,1736,1737,1739,1741,1743],{"class":60,"line":113},[58,1738,1453],{"class":280},[58,1740,1314],{"class":255},[58,1742,351],{"class":287},[58,1744,1473],{"class":255},[58,1746,1747],{"class":60,"line":119},[58,1748,1267],{"class":255},[58,1750,1751],{"class":60,"line":124},[58,1752,272],{"emptyLinePlaceholder":271},[58,1754,1755,1758],{"class":60,"line":130},[58,1756,1757],{"class":287},"  undo",[58,1759,661],{"class":255},[58,1761,1762,1765,1768,1770,1772,1774,1777],{"class":60,"line":647},[58,1763,1764],{"class":251},"    const",[58,1766,1767],{"class":280}," previousState",[58,1769,284],{"class":251},[58,1771,1160],{"class":280},[58,1773,1710],{"class":255},[58,1775,1776],{"class":287},"pop",[58,1778,1473],{"class":255},[58,1780,1781,1784],{"class":60,"line":652},[58,1782,1783],{"class":251},"    if",[58,1785,1786],{"class":255}," (previousState) {\n",[58,1788,1789,1792,1794,1796],{"class":60,"line":664},[58,1790,1791],{"class":280},"      this",[58,1793,1193],{"class":255},[58,1795,409],{"class":251},[58,1797,1798],{"class":255}," previousState;\n",[58,1800,1801,1803,1805,1807],{"class":60,"line":675},[58,1802,1791],{"class":280},[58,1804,1314],{"class":255},[58,1806,351],{"class":287},[58,1808,1473],{"class":255},[58,1810,1811],{"class":60,"line":899},[58,1812,1261],{"class":255},[58,1814,1815],{"class":60,"line":908},[58,1816,1267],{"class":255},[58,1818,1819],{"class":60,"line":920},[58,1820,678],{"class":255},[10,1822,1823,1826,1830,1836,1839],{"lang":12},[14,1824,1825],{},"With this pattern, implementing \"Undo\" or a full \"Time Travel Debugger\" becomes trivial. You can just store an array of states and jump between them.",[939,1827,1829],{"id":1828},"recap","Recap",[14,1831,1832,1833,1835],{},"At this point, we have a single class as the source of truth for app state and logic. We apply changes by reassigning an immutable state object, and ",[55,1834,1343],{}," acts as the central loop.",[14,1837,1838],{},"This should give you a practical overview of how The Elm Architecture works in a more structured, object-oriented way.",[14,1840,1841],{},"In the next article, we’ll build on this with more realistic examples (form input, async data, and composition patterns).",[10,1843,1844,1847,1851,1857,1860],{"lang":31},[14,1845,1846],{},"Com esse padrão, implementar \"Desfazer\" (Undo) ou um \"Depurador de Viagem no Tempo\" completo torna-se trivial. Você pode apenas armazenar um array de estados e saltar entre eles.",[939,1848,1850],{"id":1849},"recapitulação","Recapitulação",[14,1852,1853,1854,1856],{},"Neste ponto, temos uma única classe como fonte da verdade para o estado e a lógica do app. Aplicamos mudanças reatribuindo um objeto de estado imutável, e o ",[55,1855,1343],{}," atua como o loop central.",[14,1858,1859],{},"Isso deve te dar uma visão prática de como a Elm Architecture funciona de uma maneira mais estruturada e orientada a objetos.",[14,1861,1862],{},"No próximo artigo, construiremos sobre isso com exemplos mais realistas (input de formulário, dados assíncronos e padrões de composição).",[1864,1865,1866],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html pre.shiki code .s6ubI, html code.shiki .s6ubI{--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-light:#D73A49}html pre.shiki code .sAvwS, html code.shiki .sAvwS{--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-light:#24292E}html pre.shiki code .s4Y1p, html code.shiki .s4Y1p{--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-light:#032F62}html pre.shiki code .sXWYR, html code.shiki .sXWYR{--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-light:#005CC5}html pre.shiki code .s5n6i, html code.shiki .s5n6i{--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-light:#6F42C1}html pre.shiki code .sAzo5, html code.shiki .sAzo5{--shiki-default:#FFAB70;--shiki-dark:#FFAB70;--shiki-light:#E36209}html pre.shiki code .sxXm1, html code.shiki .sxXm1{--shiki-default:#6A737D;--shiki-dark:#6A737D;--shiki-light:#6A737D}",{"title":53,"searchDepth":67,"depth":67,"links":1868},[1869,1871,1873,1874,1875,1876,1877,1878],{"id":941,"depth":67,"text":1870},"The Counter Application",{"id":969,"depth":67,"text":1872},"A Aplicação Counter",{"id":1559,"depth":67,"text":1560},{"id":1586,"depth":67,"text":1583},{"id":1600,"depth":67,"text":1601},{"id":1624,"depth":67,"text":1583},{"id":1828,"depth":67,"text":1829},{"id":1849,"depth":67,"text":1850},"Learn the core ideas of The Elm Architecture in TypeScript with lit-html: model, view, update, messages, and commands.","Aprenda as ideias centrais da Elm Architecture em TypeScript com lit-html: model, view, update, messages e commands.",false,"md",{},"/blog/learning-tea","2026-05-01",{"title":5,"description":53},"learning-tea","blog/learning-tea",[1890,1891,1892,1893],"javascript","typescript","elm","functional programming","Learning and understanding The Elm Architecture","Aprendendo e entendendo a Elm Architecture","z7xFqAbJnwXUXYOZoZEZ20T1RrH5EFDm_Qma2BE_QTg",{"left":1898,"top":1898,"width":1275,"height":1275,"rotate":1898,"vFlip":1881,"hFlip":1881,"body":1899},0,"\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12z\"/>",{"left":1898,"top":1898,"width":1275,"height":1275,"rotate":1898,"vFlip":1881,"hFlip":1881,"body":1901},"\u003Cpath fill=\"currentColor\" d=\"M4 6h16v2H4zm0 5h16v2H4zm0 5h16v2H4z\"/>",{"left":1898,"top":1898,"width":1903,"height":1903,"rotate":1898,"vFlip":1881,"hFlip":1881,"body":1904},256,"\u003Cpath fill=\"currentColor\" d=\"m247.15 212.42l-56-112a8 8 0 0 0-14.31 0l-21.71 43.43A88 88 0 0 1 108 126.93A103.65 103.65 0 0 0 135.69 64H160a8 8 0 0 0 0-16h-56V32a8 8 0 0 0-16 0v16H32a8 8 0 0 0 0 16h87.63A87.76 87.76 0 0 1 96 116.35a87.7 87.7 0 0 1-19-31a8 8 0 1 0-15.08 5.34A103.6 103.6 0 0 0 84 127a87.55 87.55 0 0 1-52 17a8 8 0 0 0 0 16a103.46 103.46 0 0 0 64-22.08a104.2 104.2 0 0 0 51.44 21.31l-26.6 53.19a8 8 0 0 0 14.31 7.16L148.94 192h70.11l13.79 27.58A8 8 0 0 0 240 224a8 8 0 0 0 7.15-11.58M156.94 176L184 121.89L211.05 176Z\"/>",{"left":1898,"top":1898,"width":1906,"height":1907,"rotate":1898,"vFlip":1881,"hFlip":1881,"body":1908},640,480,"\u003Cg stroke-width=\"1pt\">\u003Cpath fill=\"#229e45\" fill-rule=\"evenodd\" d=\"M0 0h640v480H0z\"/>\u003Cpath fill=\"#f8e509\" fill-rule=\"evenodd\" d=\"m321.4 436l301.5-195.7L319.6 44L17.1 240.7z\"/>\u003Cpath fill=\"#2b49a3\" fill-rule=\"evenodd\" d=\"M452.8 240c0 70.3-57.1 127.3-127.6 127.3A127.4 127.4 0 1 1 452.8 240\"/>\u003Cpath fill=\"#ffffef\" fill-rule=\"evenodd\" d=\"m283.3 316.3l-4-2.3l-4 2l.9-4.5l-3.2-3.4l4.5-.5l2.2-4l1.9 4.2l4.4.8l-3.3 3m86 26.3l-3.9-2.3l-4 2l.8-4.5l-3.1-3.3l4.5-.5l2.1-4.1l2 4.2l4.4.8l-3.4 3.1m-36.2-30l-3.4-2l-3.5 1.8l.8-3.9l-2.8-2.9l4-.4l1.8-3.6l1.6 3.7l3.9.7l-3 2.7m87-8.5l-3.4-2l-3.5 1.8l.8-3.9l-2.7-2.8l3.9-.4l1.8-3.5l1.6 3.6l3.8.7l-2.9 2.6m-87.3-22l-4-2.2l-4 2l.8-4.6l-3.1-3.3l4.5-.5l2.1-4.1l2 4.2l4.4.8l-3.4 3.2m-104.6-35l-4-2.2l-4 2l1-4.6l-3.3-3.3l4.6-.5l2-4.1l2 4.2l4.4.8l-3.3 3.1m13.3 57.2l-4-2.3l-4 2l.9-4.5l-3.2-3.3l4.5-.6l2.1-4l2 4.2l4.4.8l-3.3 3.1m132-67.3l-3.6-2l-3.6 1.8l.8-4l-2.8-3l4-.5l1.9-3.6l1.7 3.8l4 .7l-3 2.7m-6.7 38.3l-2.7-1.6l-2.9 1.4l.6-3.2l-2.2-2.3l3.2-.4l1.5-2.8l1.3 3l3 .5l-2.2 2.2m-142.2 50.4l-2.7-1.5l-2.7 1.3l.6-3l-2.1-2.2l3-.4l1.4-2.7l1.3 2.8l3 .6l-2.3 2M419 299.8l-2.2-1.1l-2.2 1l.5-2.3l-1.7-1.6l2.4-.3l1.2-2l1 2l2.5.5l-1.9 1.5\"/>\u003Cpath fill=\"#ffffef\" fill-rule=\"evenodd\" d=\"m219.3 287.6l-2.7-1.5l-2.7 1.3l.6-3l-2.1-2.2l3-.4l1.4-2.7l1.3 2.8l3 .6l-2.3 2\"/>\u003Cpath fill=\"#ffffef\" fill-rule=\"evenodd\" d=\"m219.3 287.6l-2.7-1.5l-2.7 1.3l.6-3l-2.1-2.2l3-.4l1.4-2.7l1.3 2.8l3 .6l-2.3 2m42.3 3l-2.6-1.4l-2.7 1.3l.6-3l-2.1-2.2l3-.4l1.4-2.7l1.3 2.8l3 .5l-2.3 2.1m-4.8 17l-2.6-1.5l-2.7 1.4l.6-3l-2.1-2.3l3-.4l1.4-2.7l1.3 2.8l3 .6l-2.3 2m87.4-22.2l-2.6-1.6l-2.8 1.4l.6-3l-2-2.3l3-.3l1.4-2.7l1.2 2.8l3 .5l-2.2 2.1m-25.1 3l-2.7-1.5l-2.7 1.4l.6-3l-2-2.3l3-.3l1.4-2.8l1.2 2.9l3 .5l-2.2 2.1m-68.8-5.8l-1.7-1l-1.7.8l.4-1.9l-1.3-1.4l1.9-.2l.8-1.7l.8 1.8l1.9.3l-1.4 1.3m167.8 45.4l-2.6-1.5l-2.7 1.4l.6-3l-2.1-2.3l3-.4l1.4-2.7l1.3 2.8l3 .6l-2.3 2m-20.8 6l-2.2-1.4l-2.3 1.2l.5-2.6l-1.7-1.8l2.5-.3l1.2-2.3l1 2.4l2.5.4l-1.9 1.8m10.4 2.3l-2-1.2l-2.1 1l.4-2.3l-1.6-1.7l2.3-.3l1.1-2l1 2l2.3.5l-1.7 1.6m29.1-22.8l-2-1l-2 1l.5-2.3l-1.6-1.7l2.3-.3l1-2l1 2.1l2.1.4l-1.6 1.6m-38.8 41.8l-2.5-1.4l-2.7 1.2l.6-2.8l-2-2l3-.3l1.3-2.5l1.2 2.6l3 .5l-2.3 1.9m.6 14.2l-2.4-1.4l-2.4 1.3l.6-2.8l-1.9-2l2.7-.4l1.2-2.5l1.1 2.6l2.7.5l-2 2m-19-23.1l-1.9-1.2l-2 1l.4-2.2l-1.5-1.7l2.2-.2l1-2l1 2l2.2.4l-1.6 1.6m-17.8 2.3l-2-1.2l-2 1l.5-2.2l-1.6-1.7l2.3-.2l1-2l1 2l2.1.4l-1.6 1.6m-30.4-24.6l-2-1.1l-2 1l.5-2.3l-1.6-1.6l2.2-.3l1-2l1 2l2.2.5l-1.6 1.5m3.7 57l-1.6-.9l-1.8.9l.4-2l-1.3-1.4l1.9-.2l.9-1.7l.8 1.8l1.9.3l-1.4 1.3m-46.2-86.6l-4-2.3l-4 2l.9-4.5l-3.2-3.3l4.5-.6l2.2-4l1.9 4.2l4.4.8l-3.3 3.1\"/>\u003Cpath fill=\"#fff\" fill-rule=\"evenodd\" d=\"M444.4 285.8a125 125 0 0 0 5.8-19.8c-67.8-59.5-143.3-90-238.7-83.7a125 125 0 0 0-8.5 20.9c113-10.8 196 39.2 241.4 82.6\"/>\u003Cpath fill=\"#309e3a\" d=\"m414 252.4l2.3 1.3a3 3 0 0 0-.3 2.2a3 3 0 0 0 1.4 1.7q1 .8 2 .7q.9 0 1.3-.7l.2-.9l-.5-1l-1.5-1.8a8 8 0 0 1-1.8-3a4 4 0 0 1 2-4.4a4 4 0 0 1 2.3-.2a7 7 0 0 1 2.6 1.2q2.1 1.5 2.6 3.2a4 4 0 0 1-.6 3.3l-2.4-1.5q.5-1 .2-1.7q-.2-.8-1.2-1.4a3 3 0 0 0-1.8-.7a1 1 0 0 0-.9.5q-.3.4-.1 1q.2.8 1.6 2.2t2 2.5a4 4 0 0 1-.3 4.2a4 4 0 0 1-1.9 1.5a4 4 0 0 1-2.4.3q-1.3-.3-2.8-1.3q-2.2-1.5-2.7-3.3a5 5 0 0 1 .6-4zm-11.6-7.6l2.5 1.3a3 3 0 0 0-.2 2.2a3 3 0 0 0 1.4 1.6q1.1.8 2 .6q.9 0 1.3-.8l.2-.8q0-.5-.5-1l-1.6-1.8q-1.7-1.6-2-2.8a4 4 0 0 1 .4-3.1a4 4 0 0 1 1.6-1.4a4 4 0 0 1 2.2-.3a7 7 0 0 1 2.6 1q2.3 1.5 2.7 3.1a4 4 0 0 1-.4 3.4l-2.5-1.4q.5-1 .2-1.7q-.4-1-1.3-1.4a3 3 0 0 0-1.9-.6a1 1 0 0 0-.8.5q-.3.4-.1 1q.3.8 1.7 2.2q1.5 1.5 2 2.4a4 4 0 0 1 0 4.2a4 4 0 0 1-1.8 1.6a4 4 0 0 1-2.4.3a8 8 0 0 1-2.9-1.1a6 6 0 0 1-2.8-3.2a5 5 0 0 1 .4-4m-14.2-3.8l7.3-12l8.8 5.5l-1.2 2l-6.4-4l-1.6 2.7l6 3.7l-1.3 2l-6-3.7l-2 3.3l6.7 4l-1.2 2zm-20.7-17l1.1-2l5.4 2.7l-2.5 5q-1.2.3-3 .2a9 9 0 0 1-3.3-1a8 8 0 0 1-3-2.6a6 6 0 0 1-1-3.5a9 9 0 0 1 1-3.7a8 8 0 0 1 2.6-3a6 6 0 0 1 3.6-1.1q1.4 0 3.2 1q2.4 1.1 3.1 2.8a5 5 0 0 1 .3 3.5l-2.7-.8a3 3 0 0 0-.2-2q-.4-.9-1.6-1.4a4 4 0 0 0-3.1-.3q-1.5.5-2.6 2.6t-.7 3.8a4 4 0 0 0 2 2.4q.8.5 1.7.5h1.8l.8-1.6zm-90.2-22.3l2-14l4.2.7l1.1 9.8l3.9-9l4.2.6l-2 13.8l-2.7-.4l1.7-10.9l-4.4 10.5l-2.7-.4l-1.1-11.3l-1.6 11zm-14.1-1.7l1.3-14l10.3 1l-.2 2.4l-7.5-.7l-.3 3l7 .7l-.3 2.4l-7-.7l-.3 3.8l7.8.7l-.2 2.4z\"/>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"M216.5 191.3q0-2.2.7-3.6a7 7 0 0 1 1.4-1.9a5 5 0 0 1 1.8-1.2q1.5-.5 3-.5q3.1.1 5 2a7 7 0 0 1 1.6 5.5q0 3.3-2 5.3a7 7 0 0 1-5 1.7a7 7 0 0 1-4.8-2a7 7 0 0 1-1.7-5.3\"/>\u003Cpath fill=\"#f7ffff\" d=\"M219.4 191.3q0 2.3 1 3.6t2.8 1.3a4 4 0 0 0 2.8-1.1q1-1.2 1.1-3.7q.1-2.4-1-3.6a4 4 0 0 0-2.7-1.3a4 4 0 0 0-2.8 1.2q-1.1 1.2-1.2 3.6\"/>\u003C/g>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"m233 198.5l.2-14h6q2.2 0 3.2.5q1 .3 1.6 1.3c.6 1 .6 1.4.6 2.3a4 4 0 0 1-1 2.6a5 5 0 0 1-2.7 1.2l1.5 1.2q.6.6 1.5 2.3l1.7 2.8h-3.4l-2-3.2l-1.4-2l-.9-.6l-1.4-.2h-.6v5.8z\"/>\u003Cpath fill=\"#fff\" d=\"M236 190.5h2q2.1 0 2.6-.2q.5-.1.8-.5q.4-.6.3-1q0-.9-.4-1.2q-.3-.4-1-.6h-2l-2.3-.1z\"/>\u003C/g>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"m249 185.2l5.2.3q1.7 0 2.6.3a5 5 0 0 1 2 1.4a6 6 0 0 1 1.2 2.4q.4 1.4.3 3.3a9 9 0 0 1-.5 3q-.6 1.5-1.7 2.4a5 5 0 0 1-2 1q-1 .3-2.5.2l-5.3-.3z\"/>\u003Cpath fill=\"#fff\" d=\"m251.7 187.7l-.5 9.3h3.8q.8 0 1.2-.5q.5-.4.8-1.3t.4-2.6l-.1-2.5a3 3 0 0 0-.8-1.4l-1.2-.7l-2.3-.3z\"/>\u003C/g>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"m317.6 210.2l3.3-13.6l4.4 1l3.2 1q1.1.6 1.6 1.9t.2 2.8q-.3 1.2-1 2a4 4 0 0 1-3 1.4q-1 0-3-.5l-1.7-.5l-1.2 5.2z\"/>\u003Cpath fill=\"#fff\" d=\"m323 199.6l-.8 3.8l1.5.4q1.6.4 2.2.3a2 2 0 0 0 1.6-1.5q0-.7-.2-1.3a2 2 0 0 0-1-.9l-1.9-.5l-1.3-.3z\"/>\u003C/g>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"m330.6 214.1l4.7-13.2l5.5 2q2.2.8 3 1.4q.8.7 1 1.8c.2 1.1.2 1.5 0 2.3q-.6 1.5-1.8 2.2q-1.2.6-3 .3q.6.7 1 1.6l.8 2.7l.6 3.1l-3.1-1.1l-1-3.6l-.7-2.4l-.6-.8q-.3-.4-1.3-.7l-.5-.2l-2 5.6z\"/>\u003Cpath fill=\"#fff\" d=\"m336 207.4l1.9.7q2 .7 2.5.7t.9-.3q.5-.3.6-.9q.3-.6 0-1.2l-.8-.9l-2-.7l-2-.7l-1.2 3.3z\"/>\u003C/g>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"M347 213.6a9 9 0 0 1 1.7-3.2l1.8-1.5l2-.7q1.5-.1 3.1.4a7 7 0 0 1 4.2 3.3q1.2 2.4.2 5.7a7 7 0 0 1-3.4 4.5q-2.3 1.3-5.2.4a7 7 0 0 1-4.2-3.3a7 7 0 0 1-.2-5.6\"/>\u003Cpath fill=\"#fff\" d=\"M349.8 214.4q-.7 2.3 0 3.8c.7 1.5 1.2 1.6 2.3 2q1.5.5 3-.4q1.4-.8 2.1-3.2q.8-2.2 0-3.7a4 4 0 0 0-2.2-2a4 4 0 0 0-3 .3q-1.5.8-2.2 3.2\"/>\u003C/g>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"m374.3 233.1l6.4-12.4l5.3 2.7a10 10 0 0 1 2.7 1.9q.8.7.8 1.9c0 1.2 0 1.5-.4 2.2a4 4 0 0 1-2 2q-1.5.4-3.1-.2q.6 1 .8 1.7q.3.9.4 2.8l.2 3.2l-3-1.5l-.4-3.7l-.3-2.5l-.5-1l-1.2-.7l-.5-.3l-2.7 5.2z\"/>\u003Cpath fill=\"#fff\" d=\"m380.5 227.2l1.9 1q1.8 1 2.3 1t1-.2q.4-.2.7-.8t.2-1.2l-.7-1l-1.8-1l-2-1z\"/>\u003C/g>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"M426.1 258.7a9 9 0 0 1 2.5-2.6a7 7 0 0 1 2.2-.9a6 6 0 0 1 2.2 0q1.5.3 2.8 1.2a7 7 0 0 1 3 4.4q.4 2.6-1.4 5.5a7 7 0 0 1-4.5 3.3a7 7 0 0 1-5.2-1.1a7 7 0 0 1-3-4.4q-.4-2.7 1.4-5.4\"/>\u003Cpath fill=\"#fff\" d=\"M428.6 260.3q-1.4 2-1.1 3.6a4 4 0 0 0 1.6 2.5q1.5 1 3 .6t2.9-2.4q1.4-2.1 1.1-3.6t-1.6-2.6c-1.4-1.1-2-.8-3-.5q-1.5.3-3 2.4z\"/>\u003C/g>\u003Cpath fill=\"#309e3a\" d=\"m301.8 204.5l2.3-9.8l7.2 1.7l-.3 1.6l-5.3-1.2l-.5 2.2l4.9 1.1l-.4 1.7l-4.9-1.2l-.6 2.7l5.5 1.3l-.4 1.6z\"/>\u003C/g>",{"left":1898,"top":1898,"width":1906,"height":1907,"rotate":1898,"vFlip":1881,"hFlip":1881,"body":1910},"\u003Cpath fill=\"#bd3d44\" d=\"M0 0h640v480H0\"/>\u003Cpath stroke=\"#fff\" stroke-width=\"37\" d=\"M0 55.3h640M0 129h640M0 203h640M0 277h640M0 351h640M0 425h640\"/>\u003Cpath fill=\"#192f5d\" d=\"M0 0h364.8v258.5H0\"/>\u003Cmarker id=\"SVGEq3dreKJ\" markerHeight=\"30\" markerWidth=\"30\">\u003Cpath fill=\"#fff\" d=\"m14 0l9 27L0 10h28L5 27z\"/>\u003C/marker>\u003Cpath fill=\"none\" marker-mid=\"url(#SVGEq3dreKJ)\" d=\"m0 0l16 11h61h61h61h61h60L47 37h61h61h60h61L16 63h61h61h61h61h60L47 89h61h61h60h61L16 115h61h61h61h61h60L47 141h61h61h60h61L16 166h61h61h61h61h60L47 192h61h61h60h61L16 218h61h61h61h61h60z\"/>",1777685536820]