Compare commits

..

6 Commits

Author SHA1 Message Date
Andrey Antukh
e2f355ce07 Make constrast plugin be able to run on subpath 2026-02-10 18:58:17 +01:00
Andrey Antukh
483ead59fe Make penpot depend on local plugins runtime
This removes the need to publish versions to pnpn
2026-02-10 18:53:52 +01:00
Andrey Antukh
d8d532ed4f Make the colors-to-tokens plugin work on subpath 2026-02-10 18:53:52 +01:00
Andrey Antukh
a7cec4573d Make the table-plugin work correctly in subpath 2026-02-10 18:53:52 +01:00
Andrey Antukh
6049fa1c96 Add better approach for handling plugin iframe url
Ensure params are passed correctly to plugins declared to be version
2 and are prepared to run in a subpath.
2026-02-10 18:53:52 +01:00
Andrey Antukh
a0fef67c16 Update devenv nginx to serve locally builded plugins 2026-02-10 18:38:51 +01:00
400 changed files with 22289 additions and 58019 deletions

View File

@@ -1,7 +1,6 @@
name: _DEVELOP name: _DEVELOP
on: on:
workflow_dispatch:
schedule: schedule:
- cron: '16 5-20 * * 1-5' - cron: '16 5-20 * * 1-5'

View File

@@ -1,7 +1,6 @@
name: _STAGING RENDER name: _STAGING RENDER
on: on:
workflow_dispatch:
schedule: schedule:
- cron: '36 5-20 * * 1-5' - cron: '36 5-20 * * 1-5'

View File

@@ -1,7 +1,6 @@
name: _STAGING name: _STAGING
on: on:
workflow_dispatch:
schedule: schedule:
- cron: '36 5-20 * * 1-5' - cron: '36 5-20 * * 1-5'

View File

@@ -1,7 +1,6 @@
name: _TAG name: _TAG
on: on:
workflow_dispatch:
push: push:
tags: tags:
- '*' - '*'

View File

@@ -80,7 +80,7 @@ jobs:
- name: "Build package for ${{ inputs.plugin_name }}-plugin" - name: "Build package for ${{ inputs.plugin_name }}-plugin"
working-directory: plugins working-directory: plugins
shell: bash shell: bash
run: pnpm --filter ${{ inputs.plugin_name }}-plugin build run: npx nx build ${{ inputs.plugin_name }}-plugin
- name: Select Worker name - name: Select Worker name
run: | run: |

View File

@@ -78,7 +78,7 @@ jobs:
- name: Build styles - name: Build styles
working-directory: plugins working-directory: plugins
shell: bash shell: bash
run: pnpm run build:styles-example run: npx nx run example-styles:build
- name: Select Worker name - name: Select Worker name
run: | run: |

View File

@@ -1,6 +1,6 @@
# CHANGELOG # CHANGELOG
## 2.15.0 (Unreleased) ## 2.14.0 (Unreleased)
### :boom: Breaking changes & Deprecations ### :boom: Breaking changes & Deprecations
@@ -10,20 +10,6 @@
### :sparkles: New features & Enhancements ### :sparkles: New features & Enhancements
- Add MCP server integration [Taiga #13112](https://tree.taiga.io/project/penpot/us/13112), [Taiga #13114](https://tree.taiga.io/project/penpot/us/13114)
- Add woff2 support on user uploaded fonts (by @Nivl) [Github #8248](https://github.com/penpot/penpot/pull/8248)
- Option to download custom fonts (by @dfelinto) [Github #8320](https://github.com/penpot/penpot/issues/8320)
- Add copy as image to clipboard option to workspace context menu (by @dfelinto) [Github #8313](https://github.com/penpot/penpot/pull/8313)
### :bug: Bugs fixed
- Fix Alt/Option to draw shapes from center point (by @offreal) [Github #8361](https://github.com/penpot/penpot/pull/8361)
## 2.14.0 (Unreleased)
### :sparkles: New features & Enhancements
- Access to design tokens in Penpot Plugins [Taiga #8990](https://tree.taiga.io/project/penpot/us/8990) - Access to design tokens in Penpot Plugins [Taiga #8990](https://tree.taiga.io/project/penpot/us/8990)
- Remap references when renaming tokens [Taiga #10202](https://tree.taiga.io/project/penpot/us/10202) - Remap references when renaming tokens [Taiga #10202](https://tree.taiga.io/project/penpot/us/10202)
- Tokens panel nested path view [Taiga #9966](https://tree.taiga.io/project/penpot/us/9966) - Tokens panel nested path view [Taiga #9966](https://tree.taiga.io/project/penpot/us/9966)
@@ -48,20 +34,12 @@
- Fix boolean operators in menu for boards [Taiga #13174](https://tree.taiga.io/project/penpot/issue/13174) - Fix boolean operators in menu for boards [Taiga #13174](https://tree.taiga.io/project/penpot/issue/13174)
- Fix viewer can update library [Taiga #13186](https://tree.taiga.io/project/penpot/issue/13186) - Fix viewer can update library [Taiga #13186](https://tree.taiga.io/project/penpot/issue/13186)
- Fix remove fill affects different element than selected [Taiga #13128](https://tree.taiga.io/project/penpot/issue/13128) - Fix remove fill affects different element than selected [Taiga #13128](https://tree.taiga.io/project/penpot/issue/13128)
- Fix unable to finish the create account form using keyboard [Taiga #11333](https://tree.taiga.io/project/penpot/issue/11333)
## 2.13.3
### :bug: Bugs fixed
- Revert yetti (http server) update, because that caused a regression on multipart uploads
## 2.13.2 ## 2.13.2
### :bug: Bugs fixed ### :bug: Bugs fixed
- Fix modifying shapes by apply negative tokens to border radius [Taiga #13317](https://tree.taiga.io/project/penpot/issue/13317) - Fix security issue (Path Traversal Vulnerability) on fonts related RPC method
- Fix arbitrary file read security issue on create-font-variant rpc method (https://github.com/penpot/penpot/security/advisories/GHSA-xp3f-g8rq-9px2)
## 2.13.1 ## 2.13.1

View File

@@ -2,30 +2,4 @@
## Reporting a Vulnerability ## Reporting a Vulnerability
We take the security of this project seriously. If you have discovered Please report security issues to `support@penpot.app`
a security vulnerability, please do **not** open a public issue.
Please report vulnerabilities via email to: **[support@penpot.app]**
### What to include:
* A brief description of the vulnerability.
* Steps to reproduce the issue.
* Potential impact if exploited.
We appreciate your patience and your commitment to **responsible disclosure**.
---
## Security Contributors
We are incredibly grateful to the following individuals and
organizations for their help in keeping this project safe.
* **Ali Maharramli** for identifying critical path traversal vulnerability
> **Note:** This list is a work in progress. If you have contributed
> to the security of this project and would like to be recognized (or
> prefer to remain anonymous), please let us know.

View File

@@ -28,8 +28,8 @@
com.google.guava/guava {:mvn/version "33.4.8-jre"} com.google.guava/guava {:mvn/version "33.4.8-jre"}
funcool/yetti funcool/yetti
{:git/tag "v11.8" {:git/tag "v11.9"
:git/sha "1d1b33f" :git/sha "5fad7a9"
:git/url "https://github.com/funcool/yetti.git" :git/url "https://github.com/funcool/yetti.git"
:exclusions [org.slf4j/slf4j-api]} :exclusions [org.slf4j/slf4j-api]}

View File

@@ -12,7 +12,6 @@ penpot - error list
<a class="{% if version = 3 %}strong{% endif %}" href="?version=3">[BACKEND ERRORS]</a> <a class="{% if version = 3 %}strong{% endif %}" href="?version=3">[BACKEND ERRORS]</a>
<a class="{% if version = 4 %}strong{% endif %}" href="?version=4">[FRONTEND ERRORS]</a> <a class="{% if version = 4 %}strong{% endif %}" href="?version=4">[FRONTEND ERRORS]</a>
<a class="{% if version = 5 %}strong{% endif %}" href="?version=5">[RLIMIT REPORTS]</a>
</div> </div>
</nav> </nav>
<main class="horizontal-list"> <main class="horizontal-list">

View File

@@ -1,40 +0,0 @@
{% extends "app/templates/base.tmpl" %}
{% block title %}
Report: {{hint|abbreviate:150}} - {{id}} - Penpot Rate Limit Report
{% endblock %}
{% block content %}
<nav>
<div>[<a href="/dbg/error?version={{version}}">⮜</a>]</div>
<div>[<a href="#head">head</a>]</div>
<div>[<a href="#context">context</a>]</div>
<div>[<a href="#result">result</a>]</div>
</nav>
<main>
<div class="table">
<div class="table-row multiline">
<div id="head" class="table-key">HEAD:</div>
<div class="table-val">
<h1><span class="not-important">Hint:</span> <br/> {{hint}}</h1>
<h2><span class="not-important">Reported at:</span> <br/> {{created-at}}</h2>
<h2><span class="not-important">Report ID:</span> <br/> {{id}}</h2>
</div>
</div>
<div class="table-row multiline">
<div id="context" class="table-key">CONTEXT: </div>
<div class="table-val">
<pre>{{context}}</pre>
</div>
</div>
<div class="table-row multiline">
<div id="result" class="table-key">RESULT: </div>
<div class="table-val">
<pre>{{result}}</pre>
</div>
</div>
</div>
</main>
{% endblock %}

View File

@@ -3,9 +3,9 @@
{:default {:default
[[:default :window "200000/h"]] [[:default :window "200000/h"]]
;; #{:main/get-teams} ;; #{:command/get-teams}
;; [[:burst :bucket "5/5/5s"]] ;; [[:burst :bucket "5/5/5s"]]
;; #{:main/get-profile} ;; #{:command/get-profile}
;; [[:burst :bucket "60/60/1m"]] ;; [[:burst :bucket "60/60/1m"]]
} }

View File

@@ -240,13 +240,6 @@
(tmpl/render (-> content (tmpl/render (-> content
(assoc :id id) (assoc :id id)
(assoc :version 4) (assoc :version 4)
(assoc :created-at (ct/format-inst created-at :rfc1123))))))
(render-template-v5 [{:keys [content id created-at]}]
(-> (io/resource "app/templates/error-report.v5.tmpl")
(tmpl/render (-> content
(assoc :id id)
(assoc :version 5)
(assoc :created-at (ct/format-inst created-at :rfc1123))))))] (assoc :created-at (ct/format-inst created-at :rfc1123))))))]
(if-let [report (get-report request)] (if-let [report (get-report request)]
@@ -254,8 +247,7 @@
1 (render-template-v1 report) 1 (render-template-v1 report)
2 (render-template-v2 report) 2 (render-template-v2 report)
3 (render-template-v3 report) 3 (render-template-v3 report)
4 (render-template-v4 report) 4 (render-template-v4 report))]
5 (render-template-v5 report))]
{::yres/status 200 {::yres/status 200
::yres/body result ::yres/body result
::yres/headers {"content-type" "text/html; charset=utf-8" ::yres/headers {"content-type" "text/html; charset=utf-8"

View File

@@ -213,14 +213,14 @@
(assoc "access-control-allow-origin" origin) (assoc "access-control-allow-origin" origin)
(assoc "access-control-allow-methods" "GET,POST,DELETE,OPTIONS,PUT,HEAD,PATCH") (assoc "access-control-allow-methods" "GET,POST,DELETE,OPTIONS,PUT,HEAD,PATCH")
(assoc "access-control-allow-credentials" "true") (assoc "access-control-allow-credentials" "true")
(assoc "access-control-expose-headers" "content-type, set-cookie") (assoc "access-control-expose-headers" "x-requested-with, content-type, cookie")
(assoc "access-control-allow-headers" "x-frontend-version, x-client, x-requested-width, content-type, accept, cookie"))) (assoc "access-control-allow-headers" "x-frontend-version, content-type, accept, x-requested-width")))
(defn wrap-cors (defn wrap-cors
[handler] [handler]
(fn [request] (fn [request]
(let [response (if (= (yreq/method request) :options) (let [response (if (= (yreq/method request) :options)
{::yres/status 204} {::yres/status 200}
(handler request)) (handler request))
origin (yreq/get-header request "origin")] origin (yreq/get-header request "origin")]
(update response ::yres/headers with-cors-headers origin)))) (update response ::yres/headers with-cors-headers origin))))

View File

@@ -53,7 +53,6 @@
::yres/status 200 ::yres/status 200
::yres/body (yres/stream-body ::yres/body (yres/stream-body
(fn [_ output] (fn [_ output]
(let [channel (sp/chan :buf buf :xf (keep encode)) (let [channel (sp/chan :buf buf :xf (keep encode))
listener (events/spawn-listener listener (events/spawn-listener
channel channel

View File

@@ -151,22 +151,20 @@
uuid/zero) uuid/zero)
props (-> (or (::replace-props resultm) props (-> (or (::replace-props resultm)
(merge params (::props resultm))) (-> params
(merge (::props resultm))
(dissoc :profile-id)
(dissoc :type)))
(clean-props)) (clean-props))
context (merge (::context resultm) context (merge (::context resultm)
(prepare-context-from-request request)) (prepare-context-from-request request))
ip-addr (inet/parse-request request) ip-addr (inet/parse-request request)]
module (get cfg ::rpc/module)]
{::type (or (::type resultm) {::type (or (::type resultm)
(::rpc/type cfg)) (::rpc/type cfg))
::name (or (::name resultm) ::name (or (::name resultm)
(let [sname (::sv/name mdata)] (::sv/name mdata))
(if (not= module "main")
(str module "-" sname)
sname)))
::profile-id profile-id ::profile-id profile-id
::ip-addr ip-addr ::ip-addr ip-addr
::props props ::props props

View File

@@ -15,7 +15,6 @@
[app.config :as cf] [app.config :as cf]
[app.db :as db] [app.db :as db]
[app.loggers.audit :as audit] [app.loggers.audit :as audit]
[app.rpc.rlimit :as-alias rlimit]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[integrant.core :as ig] [integrant.core :as ig]
[promesa.exec :as px] [promesa.exec :as px]
@@ -42,7 +41,7 @@
(or (instance? java.util.concurrent.CompletionException cause) (or (instance? java.util.concurrent.CompletionException cause)
(instance? java.util.concurrent.ExecutionException cause))) (instance? java.util.concurrent.ExecutionException cause)))
(defn- log-record->report (defn record->report
[{:keys [::l/context ::l/message ::l/props ::l/logger ::l/level ::l/cause] :as record}] [{:keys [::l/context ::l/message ::l/props ::l/logger ::l/level ::l/cause] :as record}]
(assert (l/valid-record? record) "expectd valid log record") (assert (l/valid-record? record) "expectd valid log record")
(let [data (if (concurrent-exception? cause) (let [data (if (concurrent-exception? cause)
@@ -87,16 +86,16 @@
[{:keys [::db/pool]} {:keys [::l/id] :as record}] [{:keys [::db/pool]} {:keys [::l/id] :as record}]
(try (try
(let [uri (cf/get :public-uri) (let [uri (cf/get :public-uri)
report (-> record log-record->report d/without-nils)] report (-> record record->report d/without-nils)]
(l/dbg :hint "registering error on database" (l/dbg :hint "registering error on database"
:id (str id) :id id
:src "logging" :src "logging"
:uri (str uri "/dbg/error/" id)) :uri (str uri "/dbg/error/" id))
(persist-on-database! pool id 3 report)) (persist-on-database! pool id 3 report))
(catch Throwable cause (catch Throwable cause
(l/warn :hint "unexpected exception on database error logger" :cause cause)))) (l/warn :hint "unexpected exception on database error logger" :cause cause))))
(defn- audit-event->report (defn- event->report
[{:keys [::audit/context ::audit/props ::audit/ip-addr] :as record}] [{:keys [::audit/context ::audit/props ::audit/ip-addr] :as record}]
(let [context (let [context
(reduce-kv (fn [context k v] (reduce-kv (fn [context k v]
@@ -126,51 +125,15 @@
[{:keys [::db/pool]} {:keys [::audit/id] :as event}] [{:keys [::db/pool]} {:keys [::audit/id] :as event}]
(try (try
(let [uri (cf/get :public-uri) (let [uri (cf/get :public-uri)
report (-> event audit-event->report d/without-nils)] report (-> event event->report d/without-nils)]
(l/dbg :hint "registering error on database" (l/dbg :hint "registering error on database"
:id (str id) :id id
:src "audit-log" :src "audit-log"
:uri (str uri "/dbg/error/" id)) :uri (str uri "/dbg/error/" id))
(persist-on-database! pool id 4 report)) (persist-on-database! pool id 4 report))
(catch Throwable cause (catch Throwable cause
(l/warn :hint "unexpected exception on database error logger" :cause cause)))) (l/warn :hint "unexpected exception on database error logger" :cause cause))))
(defn- rlimit-event->report
[event]
(let [context
(-> {}
(assoc :rlimit/uid (::rlimit/uid event))
(assoc :rlimit/method (::rlimit/method event))
(assoc :backend/tenant (cf/get :tenant))
(assoc :backend/host (cf/get :host))
(assoc :backend/public-uri (str (cf/get :public-uri)))
(assoc :backend/version (:full cf/version)))
result
(->> (::rlimit/results event)
(mapv (fn [result]
(-> (into (sorted-map) result)
(dissoc ::rlimit/method)))))]
{:hint (str "Rate Limit Rejection: " (::rlimit/method event) " for " (::rlimit/uid event))
:context (-> (into (sorted-map) context)
(pp/pprint-str :length 50))
:result (pp/pprint-str result :length 50)}))
(defn- handle-rlimit-event
"Convert the log record into a report object and persist it on the database"
[{:keys [::db/pool]} {:keys [::rlimit/id] :as event}]
(try
(let [uri (cf/get :public-uri)
report (-> event rlimit-event->report d/without-nils)]
(l/dbg :hint "registering rate limit rejection"
:id (str id)
:src "rlimit"
:uri (str uri "/dbg/error/" id))
(persist-on-database! pool id 5 report))
(catch Throwable cause
(l/warn :hint "unexpected exception on database error logger" :cause cause))))
(defmethod ig/assert-key ::reporter (defmethod ig/assert-key ::reporter
[_ params] [_ params]
(assert (db/pool? (::db/pool params)) "expect valid database pool")) (assert (db/pool? (::db/pool params)) "expect valid database pool"))
@@ -191,9 +154,6 @@
(::audit/id item) (::audit/id item)
(handle-audit-event cfg item) (handle-audit-event cfg item)
(::rlimit/id item)
(handle-rlimit-event cfg item)
:else :else
(l/warn :hint "received unexpected item" :item item)) (l/warn :hint "received unexpected item" :item item))

View File

@@ -9,12 +9,10 @@
(:require (:require
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l] [app.common.logging :as l]
[app.common.pprint :as pp]
[app.common.uri :as u] [app.common.uri :as u]
[app.config :as cf] [app.config :as cf]
[app.http.client :as http] [app.http.client :as http]
[app.loggers.audit :as audit] [app.loggers.audit :as audit]
[app.rpc.rlimit :as-alias rlimit]
[app.util.json :as json] [app.util.json :as json]
[integrant.core :as ig] [integrant.core :as ig]
[promesa.exec :as px] [promesa.exec :as px]
@@ -24,28 +22,21 @@
(defn- send-mattermost-notification! (defn- send-mattermost-notification!
[cfg {:keys [id] :as report}] [cfg {:keys [id] :as report}]
(let [type (get report :type)
text (str "#" type " | " (get report :hint) "\n"
(when id
(str (u/join (cf/get :public-uri) "/dbg/error/" id) " "))
(let [url (u/join (cf/get :public-uri) "/dbg/error/" id)
text (str "Exception: " url " "
(when-let [pid (:profile-id report)] (when-let [pid (:profile-id report)]
(if (uuid? pid) (str "(pid: #uuid-" pid ")"))
(str "(pid: #uuid-" pid ")")
(str "(pid: #ip-" pid ")")))
"\n" "\n"
"- host: #" (:host report) "\n" "- host: #" (:host report) "\n"
"- tenant: #" (:tenant report) "\n" "- tenant: #" (:tenant report) "\n"
"- origin: #" (:origin report) "\n" "- origin: #" (:origin report) "\n"
(when-let [href (get report :href)] "- href: `" (:href report) "`\n"
(str "- href: `" href "`\n")) "- frontend-version: `" (:frontend-version report) "`\n"
(when-let [version (get report :frontend-version)] "- backend-version: `" (:backend-version report) "`\n"
(str "- frontend-version: `" version "`\n"))
(when-let [version (get report :backend-version)]
(str "- backend-version: `" version "`\n"))
"\n" "\n"
(when-let [info (:info report)]
(str "```\n" info "```"))
(when-let [trace (:trace report)] (when-let [trace (:trace report)]
(str "```\n" (str "```\n"
"Trace:\n" "Trace:\n"
@@ -63,15 +54,13 @@
(l/warn :hint "error on sending data" (l/warn :hint "error on sending data"
:response (pr-str resp))))) :response (pr-str resp)))))
(defn- log-record->report (defn- record->report
[{:keys [::l/context ::l/id ::l/cause ::l/message] :as record}] [{:keys [::l/context ::l/id ::l/cause] :as record}]
(assert (l/valid-record? record) "expectd valid log record") (assert (l/valid-record? record) "expectd valid log record")
(let [public-uri (cf/get :public-uri)] (let [public-uri (cf/get :public-uri)]
{:id id {:id id
:type "exception"
:origin "logging" :origin "logging"
:hint (or (some-> cause ex-message) @message)
:tenant (cf/get :tenant) :tenant (cf/get :tenant)
:host (cf/get :host) :host (cf/get :host)
:backend-version (:full cf/version) :backend-version (:full cf/version)
@@ -85,9 +74,7 @@
(defn- audit-event->report (defn- audit-event->report
[{:keys [::audit/context ::audit/props ::audit/id] :as event}] [{:keys [::audit/context ::audit/props ::audit/id] :as event}]
{:id id {:id id
:type "exception"
:origin "audit-log" :origin "audit-log"
:hint (get props :hint)
:tenant (cf/get :tenant) :tenant (cf/get :tenant)
:host (cf/get :host) :host (cf/get :host)
:backend-version (:full cf/version) :backend-version (:full cf/version)
@@ -95,35 +82,18 @@
:profile-id (:audit/profile-id event) :profile-id (:audit/profile-id event)
:href (get props :href)}) :href (get props :href)})
(defn- rlimit-event->report (defn- handle-log-record
[event] [cfg record]
{:id (::rlimit/id event)
:type "notification"
:origin "rlimit"
:hint (str "rlimit reject of "
(::rlimit/method event)
" for "
(::rlimit/uid event))
:tenant (cf/get :tenant)
:host (cf/get :host)
:backend-version (:full cf/version)
:profile-id (::rlimit/profile-id event)
:info (with-out-str
(println "Rejected by:")
(println "------------")
(println "Method: " (::rlimit/method event))
(println "Limit Name: " (::rlimit/name event))
(println "Limit Strategy:" (::rlimit/strategy event))
(println)
(println "Results & Config:")
(println "-----------------")
(doseq [result (::rlimit/results event)]
(pp/pprint (into (sorted-map) result))))})
(defn- handle-event
[cfg event event->report]
(try (try
(let [report (event->report event)] (let [report (record->report record)]
(send-mattermost-notification! cfg report))
(catch Throwable cause
(l/warn :hint "unhandled error" :cause cause))))
(defn- handle-audit-event
[cfg record]
(try
(let [report (audit-event->report record)]
(send-mattermost-notification! cfg report)) (send-mattermost-notification! cfg report))
(catch Throwable cause (catch Throwable cause
(l/warn :hint "unhandled error" :cause cause)))) (l/warn :hint "unhandled error" :cause cause))))
@@ -146,13 +116,10 @@
(when @enabled (when @enabled
(cond (cond
(::l/id item) (::l/id item)
(handle-event cfg item log-record->report) (handle-log-record cfg item)
(::audit/id item) (::audit/id item)
(handle-event cfg item audit-event->report) (handle-audit-event cfg item)
(::rlimit/id item)
(handle-event cfg item rlimit-event->report)
:else :else
(l/warn :hint "received unexpected item" :item item))) (l/warn :hint "received unexpected item" :item item)))

View File

@@ -317,13 +317,7 @@
::climit/enabled (contains? cf/flags :rpc-climit)} ::climit/enabled (contains? cf/flags :rpc-climit)}
:app.rpc/rlimit :app.rpc/rlimit
{::wrk/executor (ig/ref ::wrk/netty-executor) {::wrk/executor (ig/ref ::wrk/netty-executor)}
:app.loggers.mattermost/reporter
(ig/ref :app.loggers.mattermost/reporter)
:app.loggers.database/reporter
(ig/ref :app.loggers.database/reporter)}
:app.rpc/methods :app.rpc/methods
{::http.client/client (ig/ref ::http.client/client) {::http.client/client (ig/ref ::http.client/client)

View File

@@ -54,7 +54,7 @@
[:path ::fs/path] [:path ::fs/path]
[:mtype {:optional true} ::sm/text]]) [:mtype {:optional true} ::sm/text]])
(def check-input (def ^:private check-input
(sm/check-fn schema:input)) (sm/check-fn schema:input))
(defn validate-media-type! (defn validate-media-type!
@@ -381,22 +381,6 @@
(when (zero? (:exit res)) (when (zero? (:exit res))
(:out res)))) (:out res))))
(woff2->sfnt [data]
;; woff2_decompress outputs to same directory with .ttf extension
(let [finput (tmp/tempfile :prefix "penpot.font." :suffix ".woff2")
foutput (fs/path (str/replace (str finput) #"\.woff2$" ".ttf"))]
(try
(io/write* finput data)
(let [res (sh/sh "woff2_decompress" (str finput))]
(if (zero? (:exit res))
foutput
(do
(when (fs/exists? foutput)
(fs/delete foutput))
nil)))
(finally
(fs/delete finput)))))
;; Documented here: ;; Documented here:
;; https://docs.microsoft.com/en-us/typography/opentype/spec/otff#table-directory ;; https://docs.microsoft.com/en-us/typography/opentype/spec/otff#table-directory
(get-sfnt-type [data] (get-sfnt-type [data]
@@ -446,27 +430,4 @@
(= stype :ttf) (= stype :ttf)
(-> (assoc "font/otf" (ttf->otf sfnt)) (-> (assoc "font/otf" (ttf->otf sfnt))
(assoc "font/ttf" sfnt))))) (assoc "font/ttf" sfnt)))))))))
(contains? current "font/woff2")
(let [data (get input "font/woff2")
foutput (woff2->sfnt data)]
(when-not foutput
(ex/raise :type :validation
:code :invalid-woff2-file
:hint "invalid woff2 file"))
(try
(let [sfnt (io/read* foutput)
type (get-sfnt-type sfnt)]
(cond-> input
(= type :otf)
(-> (assoc "font/otf" sfnt)
(assoc "font/ttf" (otf->ttf sfnt))
(update "font/woff" gen-if-nil #(ttf-or-otf->woff sfnt)))
(= type :ttf)
(-> (assoc "font/ttf" sfnt)
(assoc "font/otf" (ttf->otf sfnt))
(update "font/woff" gen-if-nil #(ttf-or-otf->woff sfnt)))))
(finally
(fs/delete foutput))))))))

View File

@@ -463,10 +463,8 @@
:fn (mg/resource "app/migrations/sql/0144-mod-server-error-report-table.sql")} :fn (mg/resource "app/migrations/sql/0144-mod-server-error-report-table.sql")}
{:name "0145-fix-plugins-uri-on-profile" {:name "0145-fix-plugins-uri-on-profile"
:fn mg0145/migrate} :fn mg0145/migrate}])
{:name "0146-mod-access-token-table"
:fn (mg/resource "app/migrations/sql/0146-mod-access-token-table.sql")}])
(defn apply-migrations! (defn apply-migrations!
[pool name migrations] [pool name migrations]

View File

@@ -1,2 +0,0 @@
ALTER TABLE access_token
ADD COLUMN type text NULL;

View File

@@ -73,13 +73,9 @@
(if (nil? result) (if (nil? result)
204 204
200)) 200))
headers (cond-> (::http/headers mdata {})
headers (::http/headers mdata {}) (yres/stream-body? result)
headers (cond-> headers
(and (yres/stream-body? result)
(not (contains? headers "content-type")))
(assoc "content-type" "application/octet-stream"))] (assoc "content-type" "application/octet-stream"))]
{::yres/status status {::yres/status status
::yres/headers headers ::yres/headers headers
::yres/body result}))] ::yres/body result}))]
@@ -94,7 +90,7 @@
[methods] [methods]
(let [methods (update-vals methods peek)] (let [methods (update-vals methods peek)]
(fn [{:keys [params path-params method] :as request}] (fn [{:keys [params path-params method] :as request}]
(let [handler-name (:method-name path-params) (let [handler-name (:type path-params)
etag (yreq/get-header request "if-none-match") etag (yreq/get-header request "if-none-match")
key-id (get request ::http/auth-key-id) key-id (get request ::http/auth-key-id)
@@ -231,8 +227,8 @@
(wrap-authentication cfg $ mdata))) (wrap-authentication cfg $ mdata)))
(defn- process-method (defn- process-method
[cfg wrap-fn [f mdata]] [cfg module wrap-fn [f mdata]]
(l/trc :hint "add method" :module (::module cfg) :type (::type cfg) :name (::sv/name mdata)) (l/trc :hint "add method" :module module :name (::sv/name mdata))
(let [f (wrap-fn cfg f mdata) (let [f (wrap-fn cfg f mdata)
k (keyword (::sv/name mdata))] k (keyword (::sv/name mdata))]
[k [mdata (partial f cfg)]])) [k [mdata (partial f cfg)]]))
@@ -243,7 +239,7 @@
(defn- resolve-methods (defn- resolve-methods
[cfg] [cfg]
(let [cfg (assoc cfg ::module "main" ::type "command" ::metrics-id :rpc-main-timing)] (let [cfg (assoc cfg ::type "command" ::metrics-id :rpc-command-timing)]
(->> (sv/scan-ns (->> (sv/scan-ns
'app.rpc.commands.access-token 'app.rpc.commands.access-token
'app.rpc.commands.audit 'app.rpc.commands.audit
@@ -270,7 +266,7 @@
'app.rpc.commands.verify-token 'app.rpc.commands.verify-token
'app.rpc.commands.viewer 'app.rpc.commands.viewer
'app.rpc.commands.webhooks) 'app.rpc.commands.webhooks)
(map (partial process-method cfg wrap)) (map (partial process-method cfg "rpc" wrap))
(into {})))) (into {}))))
(def ^:private schema:methods-params (def ^:private schema:methods-params
@@ -302,13 +298,13 @@
(defn- resolve-management-methods (defn- resolve-management-methods
[cfg] [cfg]
(let [cfg (assoc cfg ::module "management" ::type "command" ::metrics-id :rpc-management-timing) (let [cfg (assoc cfg ::type "management" ::metrics-id :rpc-management-timing)
mods (cond->> (list 'app.rpc.management.exporter) mods (cond->> (list 'app.rpc.management.exporter)
(contains? cf/flags :nitrate) (contains? cf/flags :nitrate)
(cons 'app.rpc.management.nitrate))] (cons 'app.rpc.management.nitrate))]
(->> (apply sv/scan-ns mods) (->> (apply sv/scan-ns mods)
(map (partial process-method cfg wrap-management)) (map (partial process-method cfg "management" wrap-management))
(into {})))) (into {}))))
(def ^:private schema:management-methods-params (def ^:private schema:management-methods-params
@@ -363,7 +359,7 @@
(let [public-uri (cf/get :public-uri)] (let [public-uri (cf/get :public-uri)]
["/api" ["/api"
["/management" ["/management"
["/methods/:method-name" ["/methods/:type"
{:middleware [[mw/shared-key-auth shared-keys] {:middleware [[mw/shared-key-auth shared-keys]
[session/authz cfg]] [session/authz cfg]]
:handler (make-rpc-handler management-methods)}] :handler (make-rpc-handler management-methods)}]
@@ -374,7 +370,7 @@
:description "MANAGEMENT API")] :description "MANAGEMENT API")]
["/main" ["/main"
["/methods/:method-name" ["/methods/:type"
{:middleware [[mw/cors] {:middleware [[mw/cors]
[sec/client-header-check] [sec/client-header-check]
[session/authz cfg] [session/authz cfg]
@@ -392,7 +388,7 @@
["/openapi" {:handler (redirect (u/join public-uri "/api/main/doc/openapi"))}] ["/openapi" {:handler (redirect (u/join public-uri "/api/main/doc/openapi"))}]
["/openapi.join" {:handler (redirect (u/join public-uri "/api/main/doc/openapi.json"))}] ["/openapi.join" {:handler (redirect (u/join public-uri "/api/main/doc/openapi.json"))}]
["/rpc/command/:method-name" ["/rpc/command/:type"
{:middleware [[mw/cors] {:middleware [[mw/cors]
[sec/client-header-check] [sec/client-header-check]
[session/authz cfg] [session/authz cfg]

View File

@@ -23,7 +23,7 @@
(dissoc row :perms)) (dissoc row :perms))
(defn create-access-token (defn create-access-token
[{:keys [::db/conn] :as cfg} profile-id name expiration type] [{:keys [::db/conn] :as cfg} profile-id name expiration]
(let [token-id (uuid/next) (let [token-id (uuid/next)
expires-at (some-> expiration (ct/in-future)) expires-at (some-> expiration (ct/in-future))
created-at (ct/now) created-at (ct/now)
@@ -36,7 +36,6 @@
{:id token-id {:id token-id
:name name :name name
:token token :token token
:type type
:profile-id profile-id :profile-id profile-id
:created-at created-at :created-at created-at
:updated-at created-at :updated-at created-at
@@ -51,18 +50,17 @@
(def ^:private schema:create-access-token (def ^:private schema:create-access-token
[:map {:title "create-access-token"} [:map {:title "create-access-token"}
[:name [:string {:max 250 :min 1}]] [:name [:string {:max 250 :min 1}]]
[:expiration {:optional true} ::ct/duration] [:expiration {:optional true} ::ct/duration]])
[:type {:optional true} :string]])
(sv/defmethod ::create-access-token (sv/defmethod ::create-access-token
{::doc/added "1.18" {::doc/added "1.18"
::sm/params schema:create-access-token} ::sm/params schema:create-access-token}
[cfg {:keys [::rpc/profile-id name expiration type]}] [cfg {:keys [::rpc/profile-id name expiration]}]
(quotes/check! cfg {::quotes/id ::quotes/access-tokens-per-profile (quotes/check! cfg {::quotes/id ::quotes/access-tokens-per-profile
::quotes/profile-id profile-id}) ::quotes/profile-id profile-id})
(db/tx-run! cfg create-access-token profile-id name expiration type)) (db/tx-run! cfg create-access-token profile-id name expiration))
(def ^:private schema:delete-access-token (def ^:private schema:delete-access-token
[:map {:title "delete-access-token"} [:map {:title "delete-access-token"}
@@ -85,22 +83,5 @@
(->> (db/query pool :access-token (->> (db/query pool :access-token
{:profile-id profile-id} {:profile-id profile-id}
{:order-by [[:expires-at :asc] [:created-at :asc]] {:order-by [[:expires-at :asc] [:created-at :asc]]
:columns [:id :name :perms :type :created-at :updated-at :expires-at]}) :columns [:id :name :perms :created-at :updated-at :expires-at]})
(mapv decode-row))) (mapv decode-row)))
(def ^:private schema:get-current-mcp-token
[:map {:title "get-current-mcp-token"}])
(sv/defmethod ::get-current-mcp-token
{::doc/added "2.15"
::sm/params schema:get-current-mcp-token}
[{:keys [::db/pool]} {:keys [::rpc/profile-id ::rpc/request-at]}]
(->> (db/query pool :access-token
{:profile-id profile-id
:type "mcp"}
{:order-by [[:expires-at :asc] [:created-at :asc]]
:columns [:token :expires-at]})
(remove #(ct/is-after? (:expires-at %) request-at))
(map decode-row)
(first)))

View File

@@ -9,14 +9,12 @@
[app.binfile.common :as bfc] [app.binfile.common :as bfc]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.media :as cmedia]
[app.common.schema :as sm] [app.common.schema :as sm]
[app.common.time :as ct] [app.common.time :as ct]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.db :as db] [app.db :as db]
[app.db.sql :as-alias sql] [app.db.sql :as-alias sql]
[app.features.logical-deletion :as ldel] [app.features.logical-deletion :as ldel]
[app.http :as-alias http]
[app.loggers.audit :as-alias audit] [app.loggers.audit :as-alias audit]
[app.loggers.webhooks :as-alias webhooks] [app.loggers.webhooks :as-alias webhooks]
[app.media :as media] [app.media :as media]
@@ -36,9 +34,7 @@
java.io.InputStream java.io.InputStream
java.io.OutputStream java.io.OutputStream
java.io.SequenceInputStream java.io.SequenceInputStream
java.util.Collections java.util.Collections))
java.util.zip.ZipEntry
java.util.zip.ZipOutputStream))
(set! *warn-on-reflection* true) (set! *warn-on-reflection* true)
@@ -300,98 +296,3 @@
(rph/with-meta (rph/wrap) (rph/with-meta (rph/wrap)
{::audit/props {:font-family (:font-family variant) {::audit/props {:font-family (:font-family variant)
:font-id (:font-id variant)}}))) :font-id (:font-id variant)}})))
;; --- DOWNLOAD FONT
(defn- make-temporal-storage-object
[cfg profile-id content]
(let [storage (sto/resolve cfg)
content (media/check-input content)
hash (sto/calculate-hash (:path content))
data (-> (sto/content (:path content))
(sto/wrap-with-hash hash))
mtype (:mtype content "application/octet-stream")
content {::sto/content data
::sto/deduplicate? true
::sto/touched-at (ct/in-future {:minutes 30})
:profile-id profile-id
:content-type mtype
:bucket "tempfile"}]
(sto/put-object! storage content)))
(defn- make-variant-filename
[v mtype]
(str (:font-family v) "-" (:font-weight v)
(when-not (= "normal" (:font-style v)) (str "-" (:font-style v)))
(cmedia/mtype->extension mtype)))
(def ^:private schema:download-font
[:map {:title "download-font"}
[:id ::sm/uuid]])
(sv/defmethod ::download-font
"Download the font file. Returns a http redirect to the asset resource uri."
{::doc/added "2.15"
::sm/params schema:download-font}
[{:keys [::sto/storage ::db/pool] :as cfg} {:keys [::rpc/profile-id id]}]
(let [variant (db/get pool :team-font-variant {:id id})]
(teams/check-read-permissions! pool profile-id (:team-id variant))
;; Try to get the best available font format (prefer TTF for broader compatibility).
(let [media-id (or (:ttf-file-id variant)
(:otf-file-id variant)
(:woff2-file-id variant)
(:woff1-file-id variant))
sobj (sto/get-object storage media-id)
mtype (-> sobj meta :content-type)]
{:id (:id sobj)
:uri (files/resolve-public-uri (:id sobj))
:name (make-variant-filename variant mtype)})))
(def ^:private schema:download-font-family
[:map {:title "download-font-family"}
[:font-id ::sm/uuid]])
(sv/defmethod ::download-font-family
"Download the entire font family as a zip file. Returns the zip
bytes on the body, without encoding it on transit or json."
{::doc/added "2.15"
::sm/params schema:download-font-family}
[{:keys [::sto/storage ::db/pool] :as cfg} {:keys [::rpc/profile-id font-id]}]
(let [variants (db/query pool :team-font-variant
{:font-id font-id
:deleted-at nil})]
(when-not (seq variants)
(ex/raise :type :not-found
:code :object-not-found))
(teams/check-read-permissions! pool profile-id (:team-id (first variants)))
(let [tempfile (tmp/tempfile :suffix ".zip")
ffamily (-> variants first :font-family)]
(with-open [^OutputStream output (io/output-stream tempfile)
^OutputStream output (ZipOutputStream. output)]
(doseq [v variants]
(let [media-id (or (:ttf-file-id v)
(:otf-file-id v)
(:woff2-file-id v)
(:woff1-file-id v))
sobj (sto/get-object storage media-id)
mtype (-> sobj meta :content-type)
name (make-variant-filename v mtype)]
(with-open [input (sto/get-object-data storage sobj)]
(.putNextEntry ^ZipOutputStream output (ZipEntry. ^String name))
(io/copy input output :size (:size sobj))
(.closeEntry ^ZipOutputStream output)))))
(let [{:keys [id] :as sobj} (make-temporal-storage-object cfg profile-id
{:mtype "application/zip"
:path tempfile})]
{:id id
:uri (files/resolve-public-uri id)
:name (str ffamily ".zip")}))))

View File

@@ -48,7 +48,6 @@
(def schema:props (def schema:props
[:map {:title "ProfileProps"} [:map {:title "ProfileProps"}
[:plugins {:optional true} schema:plugin-registry] [:plugins {:optional true} schema:plugin-registry]
[:mcp-status {:optional true} ::sm/boolean]
[:newsletter-updates {:optional true} ::sm/boolean] [:newsletter-updates {:optional true} ::sm/boolean]
[:newsletter-news {:optional true} ::sm/boolean] [:newsletter-news {:optional true} ::sm/boolean]
[:onboarding-team-id {:optional true} ::sm/uuid] [:onboarding-team-id {:optional true} ::sm/uuid]

View File

@@ -52,8 +52,6 @@
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.config :as cf] [app.config :as cf]
[app.http :as-alias http] [app.http :as-alias http]
[app.loggers.database :as loggers.db]
[app.loggers.mattermost :as loggers.mm]
[app.redis :as rds] [app.redis :as rds]
[app.redis.script :as-alias rscript] [app.redis.script :as-alias rscript]
[app.rpc :as-alias rpc] [app.rpc :as-alias rpc]
@@ -173,9 +171,9 @@
:hint (str/ffmt "looks like '%' does not have a valid format" opts)))) :hint (str/ffmt "looks like '%' does not have a valid format" opts))))
(defmethod process-limit :bucket (defmethod process-limit :bucket
[rconn profile-id now {:keys [::key ::params ::method ::capacity ::interval ::rate] :as limit}] [rconn profile-id now {:keys [::key ::params ::service ::capacity ::interval ::rate] :as limit}]
(let [script (-> bucket-rate-limit-script (let [script (-> bucket-rate-limit-script
(assoc ::rscript/keys [(str key "." method "." profile-id)]) (assoc ::rscript/keys [(str key "." service "." profile-id)])
(assoc ::rscript/vals (conj params (->seconds now)))) (assoc ::rscript/vals (conj params (->seconds now))))
result (rds/eval rconn script) result (rds/eval rconn script)
allowed? (boolean (nth result 0)) allowed? (boolean (nth result 0))
@@ -183,7 +181,7 @@
reset (* (/ (inst-ms interval) rate) reset (* (/ (inst-ms interval) rate)
(- capacity remaining))] (- capacity remaining))]
(l/trace :hint "limit processed" (l/trace :hint "limit processed"
:method method :service service
:limit (name (::name limit)) :limit (name (::name limit))
:strategy (name (::strategy limit)) :strategy (name (::strategy limit))
:opts (::opts limit) :opts (::opts limit)
@@ -195,17 +193,17 @@
(assoc ::lresult/remaining remaining)))) (assoc ::lresult/remaining remaining))))
(defmethod process-limit :window (defmethod process-limit :window
[rconn uid now {:keys [::permits ::unit ::key ::method] :as limit}] [rconn profile-id now {:keys [::permits ::unit ::key ::service] :as limit}]
(let [ts (ct/truncate now unit) (let [ts (ct/truncate now unit)
ttl (ct/diff now (ct/plus ts {unit 1})) ttl (ct/diff now (ct/plus ts {unit 1}))
script (-> window-rate-limit-script script (-> window-rate-limit-script
(assoc ::rscript/keys [(str key "." method "." uid "." (ct/format-inst ts))]) (assoc ::rscript/keys [(str key "." service "." profile-id "." (ct/format-inst ts))])
(assoc ::rscript/vals [permits (->seconds ttl)])) (assoc ::rscript/vals [permits (->seconds ttl)]))
result (rds/eval rconn script) result (rds/eval rconn script)
allowed? (boolean (nth result 0)) allowed? (boolean (nth result 0))
remaining (nth result 1)] remaining (nth result 1)]
(l/trace :hint "limit processed" (l/trace :hint "limit processed"
:method method :service service
:name (name (::name limit)) :name (name (::name limit))
:strategy (name (::strategy limit)) :strategy (name (::strategy limit))
:opts (::opts limit) :opts (::opts limit)
@@ -213,13 +211,12 @@
:remaining remaining) :remaining remaining)
(-> limit (-> limit
(assoc ::lresult/allowed allowed?) (assoc ::lresult/allowed allowed?)
(assoc ::lresult/timestamp ts)
(assoc ::lresult/remaining remaining) (assoc ::lresult/remaining remaining)
(assoc ::lresult/reset (ct/plus ts {unit 1}))))) (assoc ::lresult/reset (ct/plus ts {unit 1})))))
(defn- process-limits (defn- process-limits
[{:keys [::rds/conn] :as cfg} uid limits now] [rconn profile-id limits now]
(let [results (into [] (map (partial process-limit conn uid now)) limits) (let [results (into [] (map (partial process-limit rconn profile-id now)) limits)
remaining (->> results remaining (->> results
(d/index-by ::name ::lresult/remaining) (d/index-by ::name ::lresult/remaining)
(uri/map->query-string)) (uri/map->query-string))
@@ -230,22 +227,11 @@
rejected (d/seek (complement ::lresult/allowed) results)] rejected (d/seek (complement ::lresult/allowed) results)]
(when rejected (when rejected
(let [event {::id (uuid/next)
::uid uid
::method (-> rejected ::method name)
::name (-> rejected ::name name)
::strategy (-> rejected ::strategy name)
::results results}]
(l/warn :hint "rejected rate limit" (l/warn :hint "rejected rate limit"
:method (-> rejected ::method name) :profile-id (str profile-id)
:name (-> rejected ::name name) :limit-service (-> rejected ::service name)
:strategy (-> rejected ::strategy name) :limit-name (-> rejected ::name name)
:uid (str uid) :limit-strategy (-> rejected ::strategy name)))
:report-id (:id event))
(loggers.mm/emit cfg event)
(loggers.db/emit cfg event)))
{::enabled true {::enabled true
::allowed (not (some? rejected)) ::allowed (not (some? rejected))
@@ -258,7 +244,7 @@
[state skey sname] [state skey sname]
(when-let [limits (or (get-in @state [::limits skey]) (when-let [limits (or (get-in @state [::limits skey])
(get-in @state [::limits :default]))] (get-in @state [::limits :default]))]
(into [] (map #(assoc % ::method sname)) limits))) (into [] (map #(assoc % ::service sname)) limits)))
(defn- get-uid (defn- get-uid
[{:keys [::rpc/profile-id] :as params}] [{:keys [::rpc/profile-id] :as params}]
@@ -268,10 +254,10 @@
uuid/zero))) uuid/zero)))
(defn- process-request' (defn- process-request'
[cfg limits params] [{:keys [::rds/conn] :as cfg} limits params]
(try (try
(let [uid (get-uid params) (let [uid (get-uid params)
result (process-limits cfg uid limits (ct/now))] result (process-limits conn uid limits (ct/now))]
(if (contains? cf/flags :soft-rpc-rlimit) (if (contains? cf/flags :soft-rpc-rlimit)
{::enabled false} {::enabled false}
result)) result))
@@ -289,8 +275,8 @@
(assert (or (nil? rlimit) (valid-rlimit-instance? rlimit)) "expected a valid rlimit instance") (assert (or (nil? rlimit) (valid-rlimit-instance? rlimit)) "expected a valid rlimit instance")
(if rlimit (if rlimit
(let [skey (keyword (::rpc/module cfg) (->> mdata ::sv/spec name)) (let [skey (keyword (::rpc/type cfg) (->> mdata ::sv/spec name))
sname (str (::rpc/module cfg) "." (->> mdata ::sv/spec name)) sname (str (::rpc/type cfg) "." (->> mdata ::sv/spec name))
cfg (-> cfg cfg (-> cfg
(assoc ::skey skey) (assoc ::skey skey)
(assoc ::sname sname))] (assoc ::sname sname))]

View File

@@ -33,7 +33,6 @@
java.util.Optional java.util.Optional
java.util.concurrent.atomic.AtomicLong java.util.concurrent.atomic.AtomicLong
org.reactivestreams.Subscriber org.reactivestreams.Subscriber
software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider
software.amazon.awssdk.core.ResponseBytes software.amazon.awssdk.core.ResponseBytes
software.amazon.awssdk.core.async.AsyncRequestBody software.amazon.awssdk.core.async.AsyncRequestBody
software.amazon.awssdk.core.async.AsyncResponseTransformer software.amazon.awssdk.core.async.AsyncResponseTransformer
@@ -200,8 +199,7 @@
(defn- build-s3-client (defn- build-s3-client
[{:keys [::region ::endpoint ::wrk/netty-io-executor]}] [{:keys [::region ::endpoint ::wrk/netty-io-executor]}]
(let [creds-provider (DefaultCredentialsProvider/create) (let [aconfig (-> (ClientAsyncConfiguration/builder)
aconfig (-> (ClientAsyncConfiguration/builder)
(.build)) (.build))
sconfig (-> (S3Configuration/builder) sconfig (-> (S3Configuration/builder)
@@ -223,7 +221,6 @@
builder (.asyncConfiguration ^S3AsyncClientBuilder builder ^ClientAsyncConfiguration aconfig) builder (.asyncConfiguration ^S3AsyncClientBuilder builder ^ClientAsyncConfiguration aconfig)
builder (.httpClient ^S3AsyncClientBuilder builder ^NettyNioAsyncHttpClient hclient) builder (.httpClient ^S3AsyncClientBuilder builder ^NettyNioAsyncHttpClient hclient)
builder (.region ^S3AsyncClientBuilder builder (lookup-region region)) builder (.region ^S3AsyncClientBuilder builder (lookup-region region))
builder (.credentialsProvider ^S3AsyncClientBuilder builder creds-provider)
builder (cond-> ^S3AsyncClientBuilder builder builder (cond-> ^S3AsyncClientBuilder builder
(some? endpoint) (some? endpoint)
(.endpointOverride (URI. (str endpoint))))] (.endpointOverride (URI. (str endpoint))))]
@@ -240,8 +237,7 @@
(defn- build-s3-presigner (defn- build-s3-presigner
[{:keys [::region ::endpoint]}] [{:keys [::region ::endpoint]}]
(let [creds-provider (DefaultCredentialsProvider/create) (let [config (-> (S3Configuration/builder)
config (-> (S3Configuration/builder)
(cond-> (some? endpoint) (.pathStyleAccessEnabled true)) (cond-> (some? endpoint) (.pathStyleAccessEnabled true))
(.build))] (.build))]
@@ -249,7 +245,6 @@
(cond-> (some? endpoint) (.endpointOverride (URI. (str endpoint)))) (cond-> (some? endpoint) (.endpointOverride (URI. (str endpoint))))
(.region (lookup-region region)) (.region (lookup-region region))
(.serviceConfiguration ^S3Configuration config) (.serviceConfiguration ^S3Configuration config)
(.credentialsProvider creds-provider)
(.build)))) (.build))))
(defn- write-input-stream (defn- write-input-stream

View File

@@ -104,13 +104,13 @@
(assoc-in [::db/pool ::db/password] (:database-password config)) (assoc-in [::db/pool ::db/password] (:database-password config))
(assoc-in [:app.rpc/methods :app.setup/templates] templates) (assoc-in [:app.rpc/methods :app.setup/templates] templates)
(assoc-in [:app.rpc/methods :app.setup/templates] templates) (assoc-in [:app.rpc/methods :app.setup/templates] templates)
(update :app.rpc/rlimit assoc (update :app.rpc/methods
:app.loggers.mattermost/reporter nil (fn [state]
:app.loggers.database/reporter nil) (-> state
(update :app.rpc/methods assoc (assoc :app.setup/templates templates)
:app.setup/templates templates (assoc :app.loggers.mattermost/reporter nil)
:app.loggers.mattermost/reporter nil (assoc :app.loggers.database/reporter nil))))
:app.loggers.database/reporter nil)
(dissoc :app.srepl/server (dissoc :app.srepl/server
:app.http/server :app.http/server
:app.http/route :app.http/route

View File

@@ -102,7 +102,7 @@
(t/deftest access-token-authz (t/deftest access-token-authz
(let [profile (th/create-profile* 1) (let [profile (th/create-profile* 1)
token (db/tx-run! th/*system* app.rpc.commands.access-token/create-access-token (:id profile) "test" nil nil) token (db/tx-run! th/*system* app.rpc.commands.access-token/create-access-token (:id profile) "test" nil)
handler (#'app.http.access-token/wrap-authz identity th/*system*)] handler (#'app.http.access-token/wrap-authz identity th/*system*)]
(let [response (handler nil)] (let [response (handler nil)]

View File

@@ -107,18 +107,4 @@
;; (th/print-result! out) ;; (th/print-result! out)
(t/is (nil? (:error out))) (t/is (nil? (:error out)))
(let [results (:result out)] (let [results (:result out)]
(t/is (= 2 (count results)))))) (t/is (= 2 (count results))))))))
(t/testing "get mcp token"
(let [_ (th/command! {::th/type :create-access-token
::rpc/profile-id (:id prof)
:type "mcp"
:name "token 1"
:perms ["get-profile"]})
{:keys [error result]}
(th/command! {::th/type :get-current-mcp-token
::rpc/profile-id (:id prof)})]
;; (th/print-result! result)
(t/is (nil? error))
(t/is (string? (:token result)))))))

View File

@@ -93,41 +93,6 @@
:font-weight :font-weight
:font-style)))) :font-style))))
(t/deftest woff2-font-upload-1
(let [prof (th/create-profile* 1 {:is-active true})
team-id (:default-team-id prof)
proj-id (:default-project-id prof)
font-id (uuid/custom 10 1)
data (-> (io/resource "backend_tests/test_files/font-1.woff2")
(io/read*))
params {::th/type :create-font-variant
::rpc/profile-id (:id prof)
:team-id team-id
:font-id font-id
:font-family "somefont"
:font-weight 400
:font-style "normal"
:data {"font/woff2" data}}
out (th/command! params)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(let [result (:result out)]
(t/is (uuid? (:id result)))
(t/is (uuid? (:ttf-file-id result)))
(t/is (uuid? (:otf-file-id result)))
(t/is (uuid? (:woff1-file-id result)))
(t/is (uuid? (:woff2-file-id result)))
(t/are [k] (= (get params k)
(get result k))
:team-id
:font-id
:font-family
:font-weight
:font-style))))
(t/deftest font-deletion-1 (t/deftest font-deletion-1
(let [prof (th/create-profile* 1 {:is-active true}) (let [prof (th/create-profile* 1 {:is-active true})
team-id (:default-team-id prof) team-id (:default-team-id prof)

View File

Binary file not shown.

View File

@@ -55,7 +55,6 @@
"design-tokens/v1" "design-tokens/v1"
"text-editor/v2-html-paste" "text-editor/v2-html-paste"
"text-editor/v2" "text-editor/v2"
"text-editor-wasm/v1"
"render-wasm/v1" "render-wasm/v1"
"variants/v1"}) "variants/v1"})
@@ -79,7 +78,6 @@
"plugins/runtime" "plugins/runtime"
"text-editor/v2-html-paste" "text-editor/v2-html-paste"
"text-editor/v2" "text-editor/v2"
"text-editor-wasm/v1"
"tokens/numeric-input" "tokens/numeric-input"
"render-wasm/v1"}) "render-wasm/v1"})
@@ -129,7 +127,6 @@
:feature-design-tokens "design-tokens/v1" :feature-design-tokens "design-tokens/v1"
:feature-text-editor-v2 "text-editor/v2" :feature-text-editor-v2 "text-editor/v2"
:feature-text-editor-v2-html-paste "text-editor/v2-html-paste" :feature-text-editor-v2-html-paste "text-editor/v2-html-paste"
:feature-text-editor-wasm "text-editor-wasm/v1"
:feature-render-wasm "render-wasm/v1" :feature-render-wasm "render-wasm/v1"
:feature-variants "variants/v1" :feature-variants "variants/v1"
:feature-token-input "tokens/numeric-input" :feature-token-input "tokens/numeric-input"

View File

@@ -35,7 +35,7 @@
[::sm/text {:error/fn token-value-empty-fn}]) [::sm/text {:error/fn token-value-empty-fn}])
(def schema:token-value-font-family (def schema:token-value-font-family
[:vector ::sm/text]) [:vector :string])
(def schema:token-value-typography-map (def schema:token-value-typography-map
[:map [:map

View File

@@ -152,9 +152,7 @@
:redis-cache :redis-cache
;; Activates the nitrate module ;; Activates the nitrate module
:nitrate :nitrate})
:mcp})
(def all-flags (def all-flags
(set/union email login varia)) (set/union email login varia))

View File

@@ -12,7 +12,6 @@
(def font-types (def font-types
#{"font/ttf" #{"font/ttf"
"font/woff" "font/woff"
"font/woff2"
"font/otf" "font/otf"
"font/opentype"}) "font/opentype"})
@@ -82,22 +81,21 @@
(defn parse-font-weight (defn parse-font-weight
[variant] [variant]
(cond (cond
(re-seq #"(?i)(?:^|[-_\s])(hairline|thin)(?=(?:[-_\s]|$|italic\b))" variant) 100 (re-seq #"(?i)(?:hairline|thin)" variant) 100
(re-seq #"(?i)(?:^|[-_\s])(extra\s*light|ultra\s*light)(?=(?:[-_\s]|$|italic\b))" variant) 200 (re-seq #"(?i)(?:extra\s*light|ultra\s*light)" variant) 200
(re-seq #"(?i)(?:^|[-_\s])(light)(?=(?:[-_\s]|$|italic\b))" variant) 300 (re-seq #"(?i)(?:light)" variant) 300
(re-seq #"(?i)(?:^|[-_\s])(normal|regular)(?=(?:[-_\s]|$|italic\b))" variant) 400 (re-seq #"(?i)(?:normal|regular)" variant) 400
(re-seq #"(?i)(?:^|[-_\s])(medium)(?=(?:[-_\s]|$|italic\b))" variant) 500 (re-seq #"(?i)(?:medium)" variant) 500
(re-seq #"(?i)(?:^|[-_\s])(semi\s*bold|demi\s*bold)(?=(?:[-_\s]|$|italic\b))" variant) 600 (re-seq #"(?i)(?:semi\s*bold|demi\s*bold)" variant) 600
(re-seq #"(?i)(?:^|[-_\s])(extra\s*bold|ultra\s*bold)(?=(?:[-_\s]|$|italic\b))" variant) 800 (re-seq #"(?i)(?:extra\s*bold|ultra\s*bold)" variant) 800
(re-seq #"(?i)(?:^|[-_\s])(bold)(?=(?:[-_\s]|$|italic\b))" variant) 700 (re-seq #"(?i)(?:bold)" variant) 700
(re-seq #"(?i)(?:^|[-_\s])(extra\s*black|ultra\s*black)(?=(?:[-_\s]|$|italic\b))" variant) 950 (re-seq #"(?i)(?:extra\s*black|ultra\s*black)" variant) 950
(re-seq #"(?i)(?:^|[-_\s])(black|heavy|solid)(?=(?:[-_\s]|$|italic\b))" variant) 900 (re-seq #"(?i)(?:black|heavy|solid)" variant) 900
:else 400)) :else 400))
(defn parse-font-style (defn parse-font-style
[variant] [variant]
(if (or (re-seq #"(?i)(?:^|[-_\s])(italic)(?:[-_\s]|$)" variant) (if (re-seq #"(?i)(?:italic)" variant)
(re-seq #"(?i)italic$" variant))
"italic" "italic"
"normal")) "normal"))

View File

@@ -9,39 +9,6 @@
[app.common.media :as media] [app.common.media :as media]
[clojure.test :as t])) [clojure.test :as t]))
(t/deftest test-parse-font-weight
(t/testing "matches weight tokens with proper boundaries"
(t/is (= 700 (media/parse-font-weight "Roboto-Bold")))
(t/is (= 700 (media/parse-font-weight "Roboto_Bold")))
(t/is (= 700 (media/parse-font-weight "Roboto Bold")))
(t/is (= 700 (media/parse-font-weight "Bold")))
(t/is (= 800 (media/parse-font-weight "Roboto-ExtraBold")))
(t/is (= 600 (media/parse-font-weight "OpenSans-SemiBold")))
(t/is (= 300 (media/parse-font-weight "Lato-Light")))
(t/is (= 100 (media/parse-font-weight "Roboto-Thin")))
(t/is (= 200 (media/parse-font-weight "Roboto-ExtraLight")))
(t/is (= 500 (media/parse-font-weight "Roboto-Medium")))
(t/is (= 900 (media/parse-font-weight "Roboto-Black"))))
(t/testing "does not match weight tokens embedded in words"
(t/is (= 400 (media/parse-font-weight "Boldini")))
(t/is (= 400 (media/parse-font-weight "Lighthaus")))
(t/is (= 400 (media/parse-font-weight "Blackwood")))
(t/is (= 400 (media/parse-font-weight "Thinker")))
(t/is (= 400 (media/parse-font-weight "Mediaeval")))))
(t/deftest test-parse-font-style
(t/testing "matches italic with proper boundaries"
(t/is (= "italic" (media/parse-font-style "Roboto-Italic")))
(t/is (= "italic" (media/parse-font-style "Roboto_Italic")))
(t/is (= "italic" (media/parse-font-style "Roboto Italic")))
(t/is (= "italic" (media/parse-font-style "Italic")))
(t/is (= "italic" (media/parse-font-style "Roboto-BoldItalic"))))
(t/testing "does not match italic embedded in words"
(t/is (= "normal" (media/parse-font-style "Italica")))
(t/is (= "normal" (media/parse-font-style "Roboto-Regular")))))
(t/deftest test-strip-image-extension (t/deftest test-strip-image-extension
(t/testing "removes extension from supported image files" (t/testing "removes extension from supported image files"
(t/is (= (media/strip-image-extension "foo.png") "foo")) (t/is (= (media/strip-image-extension "foo.png") "foo"))

View File

@@ -50,7 +50,6 @@ services:
- 4400:4400 - 4400:4400
- 4401:4401 - 4401:4401
- 4402:4402 - 4402:4402
- 4403:4403
# Plugins # Plugins
- 4200:4200 - 4200:4200

View File

@@ -126,6 +126,12 @@ http {
proxy_http_version 1.1; proxy_http_version 1.1;
} }
location /plugins {
autoindex on;
alias /home/penpot/penpot/plugins/dist/apps;
proxy_http_version 1.1;
}
location /mcp/ws { location /mcp/ws {
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade'; proxy_set_header Connection 'upgrade';

View File

@@ -5,8 +5,7 @@ ENV LANG=en_US.UTF-8 \
LC_ALL=en_US.UTF-8 \ LC_ALL=en_US.UTF-8 \
NODE_VERSION=v22.22.0 \ NODE_VERSION=v22.22.0 \
DEBIAN_FRONTEND=noninteractive \ DEBIAN_FRONTEND=noninteractive \
PATH=/opt/node/bin:/opt/imagick/bin:$PATH \ PATH=/opt/node/bin:/opt/imagick/bin:$PATH
PLAYWRIGHT_BROWSERS_PATH=/opt/penpot/browsers
RUN set -ex; \ RUN set -ex; \
useradd -U -M -u 1001 -s /bin/false -d /opt/penpot penpot; \ useradd -U -M -u 1001 -s /bin/false -d /opt/penpot penpot; \

View File

@@ -198,6 +198,13 @@ services:
## Valkey (or previously Redis) is used for the websockets notifications. ## Valkey (or previously Redis) is used for the websockets notifications.
PENPOT_REDIS_URI: redis://penpot-valkey/0 PENPOT_REDIS_URI: redis://penpot-valkey/0
penpot-mcp:
image: penpotapp/mcp:${PENPOT_VERSION:-latest}
restart: always
networks:
- penpot
penpot-postgres: penpot-postgres:
image: "postgres:15" image: "postgres:15"
restart: always restart: always

View File

@@ -8,7 +8,9 @@ desc: Customize your Penpot instance today. Learn how to install with Elestio, D
This guide explains how to get your own Penpot instance, running on a machine you control, This guide explains how to get your own Penpot instance, running on a machine you control,
to test it, use it by you or your team, or even customize and extend it any way you like. to test it, use it by you or your team, or even customize and extend it any way you like.
For additional context, see the post <a href="https://penpot.app/blog/how-to-self-host-penpot/" target="_blank">How to self-host Penpot: A technical implementation guide</a> on the Penpot blog. If you need more context you can look at the <a
href="https://community.penpot.app/t/self-hosting-penpot-i/2336" target="_blank">post
about self-hosting</a> in Penpot community.
<strong>The experience stays the same, whether you use <strong>The experience stays the same, whether you use
Penpot <a href="https://design.penpot.app" target="_blank">in the cloud</a> Penpot <a href="https://design.penpot.app" target="_blank">in the cloud</a>

View File

@@ -14,7 +14,7 @@ Keep in mind that database size doesn't grow strictly proportionally with user c
# About Valkey / Redis requirements # About Valkey / Redis requirements
Valkey is mainly used for coordinating websocket notifications and, since Penpot 2.11, as a cache. Therefore, disk storage will not be necessary as it will use the instance's RAM. "Valkey is mainly used for coordinating websocket notifications and, since Penpot 2.11, as a cache. Therefore, disk storage will not be necessary as it will use the instance's RAM.
To prevent the cache from hogging all the system's RAM usage, it is recommended to use two configuration parameters which, both in the docker-compose.yaml provided by Penpot and in the official Helm Chart, come with default parameters that should be sufficient for most deployments: To prevent the cache from hogging all the system's RAM usage, it is recommended to use two configuration parameters which, both in the docker-compose.yaml provided by Penpot and in the official Helm Chart, come with default parameters that should be sufficient for most deployments:

View File

@@ -15,7 +15,6 @@ pnpm run build;
cp pnpm-lock.yaml target/; cp pnpm-lock.yaml target/;
cp package.json target/; cp package.json target/;
touch target/pnpm-workspace.yaml;
cat <<EOF | tee target/setup cat <<EOF | tee target/setup
#/usr/bin/env bash #/usr/bin/env bash
@@ -23,7 +22,7 @@ set -e;
corepack enable; corepack enable;
corepack install; corepack install;
pnpm install pnpm install
pnpm exec playwright install chromium; pnpx playwright install chromium;
EOF EOF
chmod +x target/setup; chmod +x target/setup;

View File

@@ -4,7 +4,7 @@
"license": "MPL-2.0", "license": "MPL-2.0",
"author": "Kaleidos INC", "author": "Kaleidos INC",
"private": true, "private": true,
"packageManager": "pnpm@10.29.2+sha512.bef43fa759d91fd2da4b319a5a0d13ef7a45bb985a3d7342058470f9d2051a3ba8674e629672654686ef9443ad13a82da2beb9eeb3e0221c87b8154fff9d74b8", "packageManager": "pnpm@10.28.2+sha512.41872f037ad22f7348e3b1debbaf7e867cfd448f2726d9cf74c08f19507c31d2c8e7a11525b983febc2df640b5438dee6023ebb1f84ed43cc2d654d2bc326264",
"browserslist": [ "browserslist": [
"defaults" "defaults"
], ],
@@ -40,16 +40,15 @@
"watch:app:libs": "node ./scripts/build-libs.js --watch", "watch:app:libs": "node ./scripts/build-libs.js --watch",
"watch:app:main": "clojure -M:dev:shadow-cljs watch main worker storybook", "watch:app:main": "clojure -M:dev:shadow-cljs watch main worker storybook",
"clear:shadow-cache": "rm -rf .shadow-cljs", "clear:shadow-cache": "rm -rf .shadow-cljs",
"clear:wasm": "cargo clean --manifest-path ../render-wasm/Cargo.toml",
"watch": "exit 0", "watch": "exit 0",
"watch:app": "pnpm run clear:shadow-cache && pnpm run clear:wasm && pnpm run build:wasm && concurrently --kill-others-on-fail \"pnpm run watch:app:assets\" \"pnpm run watch:app:main\" \"pnpm run watch:app:libs\"", "watch:app": "pnpm run clear:shadow-cache && pnpm run build:wasm && concurrently --kill-others-on-fail \"pnpm run watch:app:assets\" \"pnpm run watch:app:main\" \"pnpm run watch:app:libs\"",
"watch:storybook": "pnpm run build:storybook:assets && concurrently --kill-others-on-fail \"storybook dev -p 6006 --no-open\" \"node ./scripts/watch-storybook.js\"", "watch:storybook": "pnpm run build:storybook:assets && concurrently --kill-others-on-fail \"storybook dev -p 6006 --no-open\" \"node ./scripts/watch-storybook.js\"",
"postinstall": "(cd ../plugins/libs/plugins-runtime; pnpm install; pnpm run build)" "postinstall": "(cd ../plugins/libs/plugins-runtime; pnpm run build)"
}, },
"devDependencies": { "devDependencies": {
"@penpot/draft-js": "workspace:./packages/draft-js", "@penpot/draft-js": "workspace:./packages/draft-js",
"@penpot/mousetrap": "workspace:./packages/mousetrap", "@penpot/mousetrap": "workspace:./packages/mousetrap",
"@penpot/plugins-runtime": "link:../plugins/dist/plugins-runtime", "@penpot/plugins-runtime": "link:../plugins/libs/plugins-runtime",
"@penpot/svgo": "penpot/svgo#v3.2", "@penpot/svgo": "penpot/svgo#v3.2",
"@penpot/text-editor": "workspace:./text-editor", "@penpot/text-editor": "workspace:./text-editor",
"@penpot/tokenscript": "workspace:./packages/tokenscript", "@penpot/tokenscript": "workspace:./packages/tokenscript",

View File

@@ -8,6 +8,6 @@
"author": "Andrey Antukh", "author": "Andrey Antukh",
"license": "MPL-2.0", "license": "MPL-2.0",
"dependencies": { "dependencies": {
"@tokens-studio/tokenscript-interpreter": "^0.26.0" "@tokens-studio/tokenscript-interpreter": "^0.23.1"
} }
} }

View File

@@ -1,12 +1,12 @@
// Auto-generated by @tokens-studio/tokenscript-schemas // Auto-generated by @tokens-studio/tokenscript-schemas
// Version: @tokens-studio/tokenscript-schemas@v0.4.0 // Version: @tokens-studio/tokenscript-schemas@v0.1.2
// GitHub: https://github.com/tokens-studio/tokenscript-schemas // GitHub: https://github.com/tokens-studio/tokenscript-schemas
// Command: npx @tokens-studio/tokenscript-schemas bundle preset:css preset:cssColors --output ./schemas.js // Command: npx @tokens-studio/tokenscript-schemas bundle preset:css --output ./tokenscript-schemas.js
// Generated: 2026-02-11T08:46:40.467Z // Generated: 2026-01-07T09:21:11.478Z
import { Config } from "@tokens-studio/tokenscript-interpreter"; import { Config } from "@tokens-studio/tokenscript-interpreter";
export const SCHEMAS = [ const SCHEMAS = [
{ {
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/hex-color/0/", uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/hex-color/0/",
schema: { schema: {
@@ -31,127 +31,7 @@ export const SCHEMAS = [
} }
} }
], ],
"conversions": [ "conversions": []
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/",
"target": "$self",
"description": "Converts sRGB (0-1) to Hex format",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// sRGB to Hex Conversion\n// Converts sRGB (0-1) to hexadecimal string format\n//\n// Examples:\n// sRGB(1, 0, 0) → #ff0000\n// sRGB(0, 1, 0.5) → #00ff80\n\nvariable hex: String = \"#\";\nvariable value: Number = 0;\n\n// Red channel\nvalue = round({input}.r * 255);\nif (value < 0) [ value = 0; ];\nif (value > 255) [ value = 255; ];\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Green channel\nvalue = round({input}.g * 255);\nif (value < 0) [ value = 0; ];\nif (value > 255) [ value = 255; ];\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Blue channel\nvalue = round({input}.b * 255);\nif (value < 0) [ value = 0; ];\nif (value > 255) [ value = 255; ];\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\nreturn hex;"
}
},
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/p3-color/0/",
"target": "$self",
"description": "Converts Display P3 to Hex format (clamps to sRGB gamut)",
"lossless": false,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// Display P3 to Hex Conversion\n// Converts P3 (0-1) to hexadecimal string format\n// Note: P3 colors may be out of sRGB gamut, values are clamped to 0-1\n//\n// Examples:\n// P3(1, 0, 0) → #ff0000\n// P3(0, 1, 0.5) → #00ff80\n\nvariable hex: String = \"#\";\nvariable value: Number = 0;\n\n// Red channel (clamp P3 to sRGB range)\nvalue = {input}.r;\nif (value < 0) [ value = 0; ];\nif (value > 1) [ value = 1; ];\nvalue = round(value * 255);\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Green channel\nvalue = {input}.g;\nif (value < 0) [ value = 0; ];\nif (value > 1) [ value = 1; ];\nvalue = round(value * 255);\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Blue channel\nvalue = {input}.b;\nif (value < 0) [ value = 0; ];\nif (value > 1) [ value = 1; ];\nvalue = round(value * 255);\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\nreturn hex;"
}
},
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/hsl-color/0/",
"target": "$self",
"description": "Converts HSL to Hex format",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// HSL to Hex Conversion\n// Converts HSL to hexadecimal string format\n// Reference: Standard HSL to RGB algorithm\n//\n// Input: Color.HSL with h (0-360), s (0-1), l (0-1)\n// Output: Hex string #rrggbb\n\n// Get input HSL values\nvariable h: Number = {input}.h;\nvariable s: Number = {input}.s;\nvariable l: Number = {input}.l;\n\n// Normalize hue to 0-1 range\nvariable hue: Number = h / 360;\n\n// RGB values (default to achromatic)\nvariable r: Number = l;\nvariable g: Number = l;\nvariable b: Number = l;\n\n// Only calculate if there's saturation\nif (s > 0) [\n variable q: Number = 0;\n if (l < 0.5) [\n q = l * (1 + s);\n ] else [\n q = l + s - l * s;\n ];\n\n variable p: Number = 2 * l - q;\n\n // Red (hue + 1/3)\n variable tr: Number = hue + 0.333333333333333;\n if (tr < 0) [ tr = tr + 1; ];\n if (tr > 1) [ tr = tr - 1; ];\n\n if (tr < 0.166666666666667) [\n r = p + (q - p) * 6 * tr;\n ] else [\n if (tr < 0.5) [\n r = q;\n ] else [\n if (tr < 0.666666666666667) [\n r = p + (q - p) * (0.666666666666667 - tr) * 6;\n ] else [\n r = p;\n ];\n ];\n ];\n\n // Green (hue)\n variable tg: Number = hue;\n if (tg < 0) [ tg = tg + 1; ];\n if (tg > 1) [ tg = tg - 1; ];\n\n if (tg < 0.166666666666667) [\n g = p + (q - p) * 6 * tg;\n ] else [\n if (tg < 0.5) [\n g = q;\n ] else [\n if (tg < 0.666666666666667) [\n g = p + (q - p) * (0.666666666666667 - tg) * 6;\n ] else [\n g = p;\n ];\n ];\n ];\n\n // Blue (hue - 1/3)\n variable tb: Number = hue - 0.333333333333333;\n if (tb < 0) [ tb = tb + 1; ];\n if (tb > 1) [ tb = tb - 1; ];\n\n if (tb < 0.166666666666667) [\n b = p + (q - p) * 6 * tb;\n ] else [\n if (tb < 0.5) [\n b = q;\n ] else [\n if (tb < 0.666666666666667) [\n b = p + (q - p) * (0.666666666666667 - tb) * 6;\n ] else [\n b = p;\n ];\n ];\n ];\n];\n\n// Convert RGB to hex\nvariable hex: String = \"#\";\nvariable value: Number = 0;\n\n// Red\nvalue = round(r * 255);\nif (value < 0) [ value = 0; ];\nif (value > 255) [ value = 255; ];\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Green\nvalue = round(g * 255);\nif (value < 0) [ value = 0; ];\nif (value > 255) [ value = 255; ];\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Blue\nvalue = round(b * 255);\nif (value < 0) [ value = 0; ];\nif (value > 255) [ value = 255; ];\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\nreturn hex;"
}
},
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/oklch-color/0/",
"target": "$self",
"description": "Converts OKLCH to Hex format (clamps to sRGB gamut)",
"lossless": false,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// OKLCH to Hex Conversion\n// Converts OKLCH perceptual color to hexadecimal string format\n// Path: OKLCH → OKLab → XYZ-D65 → Linear sRGB → sRGB → Hex\n//\n// Input: Color.OKLCH with l (0-1), c, h (0-360)\n// Output: Hex string #rrggbb\n\n// Get input OKLCH values\nvariable ok_l: Number = {input}.l;\nvariable ok_c: Number = {input}.c;\nvariable ok_h: Number = {input}.h;\n\n// === Step 1: OKLCH to OKLab (polar to cartesian) ===\nvariable pi: Number = pi();\nvariable deg_to_rad: Number = pi / 180;\nvariable h_rad: Number = ok_h * deg_to_rad;\n\nvariable lab_a: Number = ok_c * cos(h_rad);\nvariable lab_b: Number = ok_c * sin(h_rad);\n\n// === Step 2: OKLab to XYZ-D65 ===\n// Inverse Lab-to-LMS matrix\nvariable lms_l: Number = 1.0 * ok_l + 0.3963377773761749 * lab_a + 0.2158037573099136 * lab_b;\nvariable lms_m: Number = 1.0 * ok_l + -0.1055613458156586 * lab_a + -0.0638541728258133 * lab_b;\nvariable lms_s: Number = 1.0 * ok_l + -0.0894841775298119 * lab_a + -1.2914855480194092 * lab_b;\n\n// Cube the values (inverse of cube root)\nvariable lms_l_cubed: Number = lms_l * lms_l * lms_l;\nvariable lms_m_cubed: Number = lms_m * lms_m * lms_m;\nvariable lms_s_cubed: Number = lms_s * lms_s * lms_s;\n\n// Inverse LMS-to-XYZ matrix\nvariable xyz_x: Number = 1.2268798758459243 * lms_l_cubed + -0.5578149944602171 * lms_m_cubed + 0.2813910456659647 * lms_s_cubed;\nvariable xyz_y: Number = -0.0405757452148008 * lms_l_cubed + 1.1122868032803170 * lms_m_cubed + -0.0717110580655164 * lms_s_cubed;\nvariable xyz_z: Number = -0.0763729366746601 * lms_l_cubed + -0.4214933324022432 * lms_m_cubed + 1.5869240198367816 * lms_s_cubed;\n\n// === Step 3: XYZ-D65 to Linear sRGB ===\nvariable linear_r: Number = 3.2409699419045226 * xyz_x + -1.537383177570094 * xyz_y + -0.4986107602930034 * xyz_z;\nvariable linear_g: Number = -0.9692436362808796 * xyz_x + 1.8759675015077202 * xyz_y + 0.04155505740717559 * xyz_z;\nvariable linear_b: Number = 0.05563007969699366 * xyz_x + -0.20397695888897652 * xyz_y + 1.0569715142428786 * xyz_z;\n\n// === Step 4: Linear sRGB to sRGB (gamma correction) ===\nvariable threshold: Number = 0.0031308;\nvariable linear_scale: Number = 12.92;\nvariable gamma_offset: Number = 0.055;\nvariable gamma_scale: Number = 1.055;\nvariable gamma_exp: Number = 0.416666666666667;\n\nvariable srgb_r: Number = 0;\nif (linear_r <= threshold) [\n srgb_r = linear_r * linear_scale;\n] else [\n if (linear_r > 0) [\n srgb_r = gamma_scale * pow(linear_r, gamma_exp) - gamma_offset;\n ] else [\n srgb_r = 0;\n ];\n];\n\nvariable srgb_g: Number = 0;\nif (linear_g <= threshold) [\n srgb_g = linear_g * linear_scale;\n] else [\n if (linear_g > 0) [\n srgb_g = gamma_scale * pow(linear_g, gamma_exp) - gamma_offset;\n ] else [\n srgb_g = 0;\n ];\n];\n\nvariable srgb_b: Number = 0;\nif (linear_b <= threshold) [\n srgb_b = linear_b * linear_scale;\n] else [\n if (linear_b > 0) [\n srgb_b = gamma_scale * pow(linear_b, gamma_exp) - gamma_offset;\n ] else [\n srgb_b = 0;\n ];\n];\n\n// === Step 5: sRGB to Hex ===\nvariable hex: String = \"#\";\nvariable value: Number = 0;\n\n// Red (clamp to 0-1)\nvalue = srgb_r;\nif (value < 0) [ value = 0; ];\nif (value > 1) [ value = 1; ];\nvalue = round(value * 255);\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Green\nvalue = srgb_g;\nif (value < 0) [ value = 0; ];\nif (value > 1) [ value = 1; ];\nvalue = round(value * 255);\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Blue\nvalue = srgb_b;\nif (value < 0) [ value = 0; ];\nif (value > 1) [ value = 1; ];\nvalue = round(value * 255);\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\nreturn hex;"
}
}
]
}
},
{
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/",
schema: {
"name": "SRGB",
"type": "color",
"description": "sRGB color space with normalized 0-1 range. The standard color space for web and displays.",
"schema": {
"type": "object",
"properties": {
"r": {
"type": "number",
"description": "Red channel (0-1)"
},
"g": {
"type": "number",
"description": "Green channel (0-1)"
},
"b": {
"type": "number",
"description": "Blue channel (0-1)"
}
},
"required": [
"r",
"g",
"b"
],
"order": [
"r",
"g",
"b"
],
"additionalProperties": false
},
"initializers": [
{
"title": "sRGB Color Initializer",
"keyword": "srgb",
"description": "Creates an sRGB color from normalized 0-1 values",
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// sRGB Color Initializer\n// Creates an sRGB color from normalized 0-1 values\n// Input: List of [r, g, b] or [r, g, b, alpha] values in 0-1 range\n\nvariable color_values: List = {input};\nvariable output: Color.SRGB;\n\noutput.r = color_values.get(0);\noutput.g = color_values.get(1);\noutput.b = color_values.get(2);\n\n// Set alpha if provided as 4th parameter\nif (color_values.length() > 3) [\n output.alpha = color_values.get(3);\n];\n\nreturn output;"
}
}
],
"conversions": [
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/rgb-color/0/",
"target": "$self",
"description": "Converts RGB (0-255) to sRGB (0-1) by normalizing",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// RGB to sRGB Conversion\n// Converts RGB (0-255) to sRGB (0-1) by normalizing\n// Input: Color.Rgb with r, g, b in 0-255 range\n// Output: Color.SRGB with r, g, b in 0-1 range\n// Lossless: Yes (simple division)\n\nvariable r_normalized: Number = {input}.r / 255;\nvariable g_normalized: Number = {input}.g / 255;\nvariable b_normalized: Number = {input}.b / 255;\n\nvariable output: Color.SRGB;\noutput.r = r_normalized;\noutput.g = g_normalized;\noutput.b = b_normalized;\n\nreturn output;"
}
},
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/hsl-color/0/",
"target": "$self",
"description": "Converts HSL to sRGB",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// HSL to sRGB Conversion\n// Reference: https://github.com/color-js/color.js/blob/main/src/spaces/hsl.js\n//\n// Algorithm:\n// 1. If saturation is 0, it's achromatic: R=G=B=L\n// 2. Otherwise use the HSL to RGB formula:\n// - Calculate intermediate values based on L\n// - Use hue to determine RGB components\n//\n// Input: Color.HSL with h (0-360), s (0-1), l (0-1)\n// Output: Color.SRGB with r, g, b in 0-1 range\n\n// Get input HSL values\nvariable h: Number = {input}.h;\nvariable s: Number = {input}.s;\nvariable l: Number = {input}.l;\n\n// Normalize hue to 0-1 range\nvariable hue: Number = h / 360;\n\n// Output values\nvariable r: Number = l;\nvariable g: Number = l;\nvariable b: Number = l;\n\n// Only calculate if there's saturation (not achromatic)\nif (s > 0) [\n // Calculate intermediate value\n variable q: Number = 0;\n if (l < 0.5) [\n q = l * (1 + s);\n ] else [\n q = l + s - l * s;\n ];\n \n variable p: Number = 2 * l - q;\n \n // Helper function logic inlined for R (hue + 1/3)\n variable tr: Number = hue + 0.333333333333333;\n if (tr < 0) [ tr = tr + 1; ];\n if (tr > 1) [ tr = tr - 1; ];\n \n if (tr < 0.166666666666667) [\n r = p + (q - p) * 6 * tr;\n ] else [\n if (tr < 0.5) [\n r = q;\n ] else [\n if (tr < 0.666666666666667) [\n r = p + (q - p) * (0.666666666666667 - tr) * 6;\n ] else [\n r = p;\n ];\n ];\n ];\n \n // Helper function logic inlined for G (hue)\n variable tg: Number = hue;\n if (tg < 0) [ tg = tg + 1; ];\n if (tg > 1) [ tg = tg - 1; ];\n \n if (tg < 0.166666666666667) [\n g = p + (q - p) * 6 * tg;\n ] else [\n if (tg < 0.5) [\n g = q;\n ] else [\n if (tg < 0.666666666666667) [\n g = p + (q - p) * (0.666666666666667 - tg) * 6;\n ] else [\n g = p;\n ];\n ];\n ];\n \n // Helper function logic inlined for B (hue - 1/3)\n variable tb: Number = hue - 0.333333333333333;\n if (tb < 0) [ tb = tb + 1; ];\n if (tb > 1) [ tb = tb - 1; ];\n \n if (tb < 0.166666666666667) [\n b = p + (q - p) * 6 * tb;\n ] else [\n if (tb < 0.5) [\n b = q;\n ] else [\n if (tb < 0.666666666666667) [\n b = p + (q - p) * (0.666666666666667 - tb) * 6;\n ] else [\n b = p;\n ];\n ];\n ];\n];\n\n// Create output\nvariable output: Color.SRGB;\noutput.r = r;\noutput.g = g;\noutput.b = b;\n\nreturn output;"
}
},
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-linear-color/0/",
"target": "$self",
"description": "Converts Linear sRGB to sRGB by applying gamma correction",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// Linear sRGB to sRGB Conversion\n// Applies gamma correction (transfer function)\n// Reference: IEC 61966-2-1:1999 (sRGB specification)\n//\n// Algorithm:\n// if linear ≤ 0.0031308: srgb = linear * 12.92\n// else: srgb = 1.055 * linear^(1/2.4) - 0.055\n//\n// Input: Color.LinearSRGB with r, g, b in linear 0-1 range\n// Output: Color.SRGB with r, g, b in gamma-corrected 0-1 range\n\n// Gamma correction constants (IEC 61966-2-1)\nvariable threshold: Number = 0.0031308;\nvariable linear_scale: Number = 12.92;\nvariable gamma_offset: Number = 0.055;\nvariable gamma_scale: Number = 1.055;\nvariable gamma_exponent: Number = 0.416666666666667;\n\n// Get input linear values\nvariable linear_r: Number = {input}.r;\nvariable linear_g: Number = {input}.g;\nvariable linear_b: Number = {input}.b;\n\n// Convert red channel\nvariable srgb_r: Number = 0;\nif (linear_r <= threshold) [\n srgb_r = linear_r * linear_scale;\n] else [\n srgb_r = gamma_scale * pow(linear_r, gamma_exponent) - gamma_offset;\n];\n\n// Convert green channel\nvariable srgb_g: Number = 0;\nif (linear_g <= threshold) [\n srgb_g = linear_g * linear_scale;\n] else [\n srgb_g = gamma_scale * pow(linear_g, gamma_exponent) - gamma_offset;\n];\n\n// Convert blue channel\nvariable srgb_b: Number = 0;\nif (linear_b <= threshold) [\n srgb_b = linear_b * linear_scale;\n] else [\n srgb_b = gamma_scale * pow(linear_b, gamma_exponent) - gamma_offset;\n];\n\n// Create output\nvariable output: Color.SRGB;\noutput.r = srgb_r;\noutput.g = srgb_g;\noutput.b = srgb_b;\n\nreturn output;"
}
}
]
} }
}, },
{ {
@@ -297,6 +177,85 @@ export const SCHEMAS = [
] ]
} }
}, },
{
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/",
schema: {
"name": "SRGB",
"type": "color",
"description": "sRGB color space with normalized 0-1 range. The standard color space for web and displays.",
"schema": {
"type": "object",
"properties": {
"r": {
"type": "number",
"description": "Red channel (0-1)"
},
"g": {
"type": "number",
"description": "Green channel (0-1)"
},
"b": {
"type": "number",
"description": "Blue channel (0-1)"
}
},
"required": [
"r",
"g",
"b"
],
"order": [
"r",
"g",
"b"
],
"additionalProperties": false
},
"initializers": [
{
"title": "sRGB Color Initializer",
"keyword": "srgb",
"description": "Creates an sRGB color from normalized 0-1 values",
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// sRGB Color Initializer\n// Creates an sRGB color from normalized 0-1 values\n// Input: List of [r, g, b] or [r, g, b, alpha] values in 0-1 range\n\nvariable color_values: List = {input};\nvariable output: Color.SRGB;\n\noutput.r = color_values.get(0);\noutput.g = color_values.get(1);\noutput.b = color_values.get(2);\n\n// Set alpha if provided as 4th parameter\nif (color_values.length() > 3) [\n output.alpha = color_values.get(3);\n];\n\nreturn output;"
}
}
],
"conversions": [
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/rgb-color/0/",
"target": "$self",
"description": "Converts RGB (0-255) to sRGB (0-1) by normalizing",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// RGB to sRGB Conversion\n// Converts RGB (0-255) to sRGB (0-1) by normalizing\n// Input: Color.Rgb with r, g, b in 0-255 range\n// Output: Color.SRGB with r, g, b in 0-1 range\n// Lossless: Yes (simple division)\n\nvariable r_normalized: Number = {input}.r / 255;\nvariable g_normalized: Number = {input}.g / 255;\nvariable b_normalized: Number = {input}.b / 255;\n\nvariable output: Color.SRGB;\noutput.r = r_normalized;\noutput.g = g_normalized;\noutput.b = b_normalized;\n\nreturn output;"
}
},
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/hsl-color/0/",
"target": "$self",
"description": "Converts HSL to sRGB",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// HSL to sRGB Conversion\n// Reference: https://github.com/color-js/color.js/blob/main/src/spaces/hsl.js\n//\n// Algorithm:\n// 1. If saturation is 0, it's achromatic: R=G=B=L\n// 2. Otherwise use the HSL to RGB formula:\n// - Calculate intermediate values based on L\n// - Use hue to determine RGB components\n//\n// Input: Color.HSL with h (0-360), s (0-1), l (0-1)\n// Output: Color.SRGB with r, g, b in 0-1 range\n\n// Get input HSL values\nvariable h: Number = {input}.h;\nvariable s: Number = {input}.s;\nvariable l: Number = {input}.l;\n\n// Normalize hue to 0-1 range\nvariable hue: Number = h / 360;\n\n// Output values\nvariable r: Number = l;\nvariable g: Number = l;\nvariable b: Number = l;\n\n// Only calculate if there's saturation (not achromatic)\nif (s > 0) [\n // Calculate intermediate value\n variable q: Number = 0;\n if (l < 0.5) [\n q = l * (1 + s);\n ] else [\n q = l + s - l * s;\n ];\n \n variable p: Number = 2 * l - q;\n \n // Helper function logic inlined for R (hue + 1/3)\n variable tr: Number = hue + 0.333333333333333;\n if (tr < 0) [ tr = tr + 1; ];\n if (tr > 1) [ tr = tr - 1; ];\n \n if (tr < 0.166666666666667) [\n r = p + (q - p) * 6 * tr;\n ] else [\n if (tr < 0.5) [\n r = q;\n ] else [\n if (tr < 0.666666666666667) [\n r = p + (q - p) * (0.666666666666667 - tr) * 6;\n ] else [\n r = p;\n ];\n ];\n ];\n \n // Helper function logic inlined for G (hue)\n variable tg: Number = hue;\n if (tg < 0) [ tg = tg + 1; ];\n if (tg > 1) [ tg = tg - 1; ];\n \n if (tg < 0.166666666666667) [\n g = p + (q - p) * 6 * tg;\n ] else [\n if (tg < 0.5) [\n g = q;\n ] else [\n if (tg < 0.666666666666667) [\n g = p + (q - p) * (0.666666666666667 - tg) * 6;\n ] else [\n g = p;\n ];\n ];\n ];\n \n // Helper function logic inlined for B (hue - 1/3)\n variable tb: Number = hue - 0.333333333333333;\n if (tb < 0) [ tb = tb + 1; ];\n if (tb > 1) [ tb = tb - 1; ];\n \n if (tb < 0.166666666666667) [\n b = p + (q - p) * 6 * tb;\n ] else [\n if (tb < 0.5) [\n b = q;\n ] else [\n if (tb < 0.666666666666667) [\n b = p + (q - p) * (0.666666666666667 - tb) * 6;\n ] else [\n b = p;\n ];\n ];\n ];\n];\n\n// Create output\nvariable output: Color.SRGB;\noutput.r = r;\noutput.g = g;\noutput.b = b;\n\nreturn output;"
}
},
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-linear-color/0/",
"target": "$self",
"description": "Converts Linear sRGB to sRGB by applying gamma correction",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// Linear sRGB to sRGB Conversion\n// Applies gamma correction (transfer function)\n// Reference: IEC 61966-2-1:1999 (sRGB specification)\n//\n// Algorithm:\n// if linear ≤ 0.0031308: srgb = linear * 12.92\n// else: srgb = 1.055 * linear^(1/2.4) - 0.055\n//\n// Input: Color.LinearSRGB with r, g, b in linear 0-1 range\n// Output: Color.SRGB with r, g, b in gamma-corrected 0-1 range\n\n// Gamma correction constants (IEC 61966-2-1)\nvariable threshold: Number = 0.0031308;\nvariable linear_scale: Number = 12.92;\nvariable gamma_offset: Number = 0.055;\nvariable gamma_scale: Number = 1.055;\nvariable gamma_exponent: Number = 0.416666666666667;\n\n// Get input linear values\nvariable linear_r: Number = {input}.r;\nvariable linear_g: Number = {input}.g;\nvariable linear_b: Number = {input}.b;\n\n// Convert red channel\nvariable srgb_r: Number = 0;\nif (linear_r <= threshold) [\n srgb_r = linear_r * linear_scale;\n] else [\n srgb_r = gamma_scale * pow(linear_r, gamma_exponent) - gamma_offset;\n];\n\n// Convert green channel\nvariable srgb_g: Number = 0;\nif (linear_g <= threshold) [\n srgb_g = linear_g * linear_scale;\n] else [\n srgb_g = gamma_scale * pow(linear_g, gamma_exponent) - gamma_offset;\n];\n\n// Convert blue channel\nvariable srgb_b: Number = 0;\nif (linear_b <= threshold) [\n srgb_b = linear_b * linear_scale;\n] else [\n srgb_b = gamma_scale * pow(linear_b, gamma_exponent) - gamma_offset;\n];\n\n// Create output\nvariable output: Color.SRGB;\noutput.r = srgb_r;\noutput.g = srgb_g;\noutput.b = srgb_b;\n\nreturn output;"
}
}
]
}
},
{ {
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-linear-color/0/", uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-linear-color/0/",
schema: { schema: {
@@ -770,65 +729,6 @@ export const SCHEMAS = [
] ]
} }
}, },
{
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/p3-color/0/",
schema: {
"name": "P3",
"type": "color",
"description": "Display-P3 color space with sRGB transfer function. Wider gamut than sRGB, common on modern Apple displays.",
"schema": {
"type": "object",
"properties": {
"r": {
"type": "number",
"description": "Red channel (0-1, can exceed for out-of-gamut)"
},
"g": {
"type": "number",
"description": "Green channel (0-1, can exceed for out-of-gamut)"
},
"b": {
"type": "number",
"description": "Blue channel (0-1, can exceed for out-of-gamut)"
}
},
"required": [
"r",
"g",
"b"
],
"order": [
"r",
"g",
"b"
],
"additionalProperties": false
},
"initializers": [
{
"title": "Display-P3 Color Initializer",
"keyword": "p3",
"description": "Creates a Display-P3 color from 0-1 values",
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// Display-P3 Color Initializer\n// Creates a Display-P3 color from 0-1 values\n// Input: List of [r, g, b] or [r, g, b, alpha] values\n\nvariable color_values: List = {input};\nvariable output: Color.P3;\n\noutput.r = color_values.get(0);\noutput.g = color_values.get(1);\noutput.b = color_values.get(2);\n\n// Set alpha if provided as 4th parameter\nif (color_values.length() > 3) [\n output.alpha = color_values.get(3);\n];\n\nreturn output;"
}
}
],
"conversions": [
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/p3-linear-color/0/",
"target": "$self",
"description": "Converts Linear P3 to P3 by applying sRGB transfer function",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// Linear P3 to P3 Conversion\n// Applies sRGB transfer function (gamma encoding)\n// P3 uses the same transfer function as sRGB\n// Reference: CSS Color Level 4\n//\n// Algorithm (same as sRGB):\n// if linear ≤ 0.0031308: encoded = 12.92 × linear\n// else: encoded = 1.055 × linear^(1/2.4) - 0.055\n//\n// Input: Color.LinearP3 with linear r, g, b values\n// Output: Color.P3 with gamma-encoded r, g, b values\n\n// Transfer function constants (same as sRGB)\nvariable threshold: Number = 0.0031308;\nvariable linear_scale: Number = 12.92;\nvariable gamma_scale: Number = 1.055;\nvariable gamma_offset: Number = 0.055;\nvariable gamma_exponent: Number = 0.4166666666666667;\n\n// Get linear values\nvariable linear_r: Number = {input}.r;\nvariable linear_g: Number = {input}.g;\nvariable linear_b: Number = {input}.b;\n\n// Convert red channel\nvariable encoded_r: Number = 0;\nif (linear_r <= threshold) [\n encoded_r = linear_scale * linear_r;\n] else [\n encoded_r = gamma_scale * pow(linear_r, gamma_exponent) - gamma_offset;\n];\n\n// Convert green channel\nvariable encoded_g: Number = 0;\nif (linear_g <= threshold) [\n encoded_g = linear_scale * linear_g;\n] else [\n encoded_g = gamma_scale * pow(linear_g, gamma_exponent) - gamma_offset;\n];\n\n// Convert blue channel\nvariable encoded_b: Number = 0;\nif (linear_b <= threshold) [\n encoded_b = linear_scale * linear_b;\n] else [\n encoded_b = gamma_scale * pow(linear_b, gamma_exponent) - gamma_offset;\n];\n\n// Create output\nvariable output: Color.P3;\noutput.r = encoded_r;\noutput.g = encoded_g;\noutput.b = encoded_b;\n\nreturn output;"
}
}
]
}
},
{ {
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/css-color/0/", uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/css-color/0/",
schema: { schema: {
@@ -1286,6 +1186,65 @@ export const SCHEMAS = [
] ]
} }
}, },
{
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/p3-color/0/",
schema: {
"name": "P3",
"type": "color",
"description": "Display-P3 color space with sRGB transfer function. Wider gamut than sRGB, common on modern Apple displays.",
"schema": {
"type": "object",
"properties": {
"r": {
"type": "number",
"description": "Red channel (0-1, can exceed for out-of-gamut)"
},
"g": {
"type": "number",
"description": "Green channel (0-1, can exceed for out-of-gamut)"
},
"b": {
"type": "number",
"description": "Blue channel (0-1, can exceed for out-of-gamut)"
}
},
"required": [
"r",
"g",
"b"
],
"order": [
"r",
"g",
"b"
],
"additionalProperties": false
},
"initializers": [
{
"title": "Display-P3 Color Initializer",
"keyword": "p3",
"description": "Creates a Display-P3 color from 0-1 values",
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// Display-P3 Color Initializer\n// Creates a Display-P3 color from 0-1 values\n// Input: List of [r, g, b] or [r, g, b, alpha] values\n\nvariable color_values: List = {input};\nvariable output: Color.P3;\n\noutput.r = color_values.get(0);\noutput.g = color_values.get(1);\noutput.b = color_values.get(2);\n\n// Set alpha if provided as 4th parameter\nif (color_values.length() > 3) [\n output.alpha = color_values.get(3);\n];\n\nreturn output;"
}
}
],
"conversions": [
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/p3-linear-color/0/",
"target": "$self",
"description": "Converts Linear P3 to P3 by applying sRGB transfer function",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// Linear P3 to P3 Conversion\n// Applies sRGB transfer function (gamma encoding)\n// P3 uses the same transfer function as sRGB\n// Reference: CSS Color Level 4\n//\n// Algorithm (same as sRGB):\n// if linear ≤ 0.0031308: encoded = 12.92 × linear\n// else: encoded = 1.055 × linear^(1/2.4) - 0.055\n//\n// Input: Color.LinearP3 with linear r, g, b values\n// Output: Color.P3 with gamma-encoded r, g, b values\n\n// Transfer function constants (same as sRGB)\nvariable threshold: Number = 0.0031308;\nvariable linear_scale: Number = 12.92;\nvariable gamma_scale: Number = 1.055;\nvariable gamma_offset: Number = 0.055;\nvariable gamma_exponent: Number = 0.4166666666666667;\n\n// Get linear values\nvariable linear_r: Number = {input}.r;\nvariable linear_g: Number = {input}.g;\nvariable linear_b: Number = {input}.b;\n\n// Convert red channel\nvariable encoded_r: Number = 0;\nif (linear_r <= threshold) [\n encoded_r = linear_scale * linear_r;\n] else [\n encoded_r = gamma_scale * pow(linear_r, gamma_exponent) - gamma_offset;\n];\n\n// Convert green channel\nvariable encoded_g: Number = 0;\nif (linear_g <= threshold) [\n encoded_g = linear_scale * linear_g;\n] else [\n encoded_g = gamma_scale * pow(linear_g, gamma_exponent) - gamma_offset;\n];\n\n// Convert blue channel\nvariable encoded_b: Number = 0;\nif (linear_b <= threshold) [\n encoded_b = linear_scale * linear_b;\n] else [\n encoded_b = gamma_scale * pow(linear_b, gamma_exponent) - gamma_offset;\n];\n\n// Create output\nvariable output: Color.P3;\noutput.r = encoded_r;\noutput.g = encoded_g;\noutput.b = encoded_b;\n\nreturn output;"
}
}
]
}
},
{ {
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/function/lighten/0/", uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/function/lighten/0/",
schema: { schema: {
@@ -1465,165 +1424,6 @@ export const SCHEMAS = [
] ]
} }
}, },
{
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/constants/css-hex-colors/0/",
schema: {
"name": "CSS Hex Colors",
"type": "constants",
"description": "CSS named colors mapped to their hex values (CSS Color Level 4)",
"inline": true,
"values": {
"aliceblue": "#F0F8FF",
"antiquewhite": "#FAEBD7",
"aqua": "#00FFFF",
"aquamarine": "#7FFFD4",
"azure": "#F0FFFF",
"beige": "#F5F5DC",
"bisque": "#FFE4C4",
"black": "#000000",
"blanchedalmond": "#FFEBCD",
"blue": "#0000FF",
"blueviolet": "#8A2BE2",
"brown": "#A52A2A",
"burlywood": "#DEB887",
"cadetblue": "#5F9EA0",
"chartreuse": "#7FFF00",
"chocolate": "#D2691E",
"coral": "#FF7F50",
"cornflowerblue": "#6495ED",
"cornsilk": "#FFF8DC",
"crimson": "#DC143C",
"cyan": "#00FFFF",
"darkblue": "#00008B",
"darkcyan": "#008B8B",
"darkgoldenrod": "#B8860B",
"darkgray": "#A9A9A9",
"darkgreen": "#006400",
"darkgrey": "#A9A9A9",
"darkkhaki": "#BDB76B",
"darkmagenta": "#8B008B",
"darkolivegreen": "#556B2F",
"darkorange": "#FF8C00",
"darkorchid": "#9932CC",
"darkred": "#8B0000",
"darksalmon": "#E9967A",
"darkseagreen": "#8FBC8F",
"darkslateblue": "#483D8B",
"darkslategray": "#2F4F4F",
"darkslategrey": "#2F4F4F",
"darkturquoise": "#00CED1",
"darkviolet": "#9400D3",
"deeppink": "#FF1493",
"deepskyblue": "#00BFFF",
"dimgray": "#696969",
"dimgrey": "#696969",
"dodgerblue": "#1E90FF",
"firebrick": "#B22222",
"floralwhite": "#FFFAF0",
"forestgreen": "#228B22",
"fuchsia": "#FF00FF",
"gainsboro": "#DCDCDC",
"ghostwhite": "#F8F8FF",
"gold": "#FFD700",
"goldenrod": "#DAA520",
"gray": "#808080",
"green": "#008000",
"greenyellow": "#ADFF2F",
"grey": "#808080",
"honeydew": "#F0FFF0",
"hotpink": "#FF69B4",
"indianred": "#CD5C5C",
"indigo": "#4B0082",
"ivory": "#FFFFF0",
"khaki": "#F0E68C",
"lavender": "#E6E6FA",
"lavenderblush": "#FFF0F5",
"lawngreen": "#7CFC00",
"lemonchiffon": "#FFFACD",
"lightblue": "#ADD8E6",
"lightcoral": "#F08080",
"lightcyan": "#E0FFFF",
"lightgoldenrodyellow": "#FAFAD2",
"lightgray": "#D3D3D3",
"lightgreen": "#90EE90",
"lightgrey": "#D3D3D3",
"lightpink": "#FFB6C1",
"lightsalmon": "#FFA07A",
"lightseagreen": "#20B2AA",
"lightskyblue": "#87CEFA",
"lightslategray": "#778899",
"lightslategrey": "#778899",
"lightsteelblue": "#B0C4DE",
"lightyellow": "#FFFFE0",
"lime": "#00FF00",
"limegreen": "#32CD32",
"linen": "#FAF0E6",
"magenta": "#FF00FF",
"maroon": "#800000",
"mediumaquamarine": "#66CDAA",
"mediumblue": "#0000CD",
"mediumorchid": "#BA55D3",
"mediumpurple": "#9370DB",
"mediumseagreen": "#3CB371",
"mediumslateblue": "#7B68EE",
"mediumspringgreen": "#00FA9A",
"mediumturquoise": "#48D1CC",
"mediumvioletred": "#C71585",
"midnightblue": "#191970",
"mintcream": "#F5FFFA",
"mistyrose": "#FFE4E1",
"moccasin": "#FFE4B5",
"navajowhite": "#FFDEAD",
"navy": "#000080",
"oldlace": "#FDF5E6",
"olive": "#808000",
"olivedrab": "#6B8E23",
"orange": "#FFA500",
"orangered": "#FF4500",
"orchid": "#DA70D6",
"palegoldenrod": "#EEE8AA",
"palegreen": "#98FB98",
"paleturquoise": "#AFEEEE",
"palevioletred": "#DB7093",
"papayawhip": "#FFEFD5",
"peachpuff": "#FFDAB9",
"peru": "#CD853F",
"pink": "#FFC0CB",
"plum": "#DDA0DD",
"powderblue": "#B0E0E6",
"purple": "#800080",
"rebeccapurple": "#663399",
"red": "#FF0000",
"rosybrown": "#BC8F8F",
"royalblue": "#4169E1",
"saddlebrown": "#8B4513",
"salmon": "#FA8072",
"sandybrown": "#F4A460",
"seagreen": "#2E8B57",
"seashell": "#FFF5EE",
"sienna": "#A0522D",
"silver": "#C0C0C0",
"skyblue": "#87CEEB",
"slateblue": "#6A5ACD",
"slategray": "#708090",
"slategrey": "#708090",
"snow": "#FFFAFA",
"springgreen": "#00FF7F",
"steelblue": "#4682B4",
"tan": "#D2B48C",
"teal": "#008080",
"thistle": "#D8BFD8",
"tomato": "#FF6347",
"turquoise": "#40E0D0",
"violet": "#EE82EE",
"wheat": "#F5DEB3",
"white": "#FFFFFF",
"whitesmoke": "#F5F5F5",
"yellow": "#FFFF00",
"yellowgreen": "#9ACD32"
}
}
},
]; ];
export function makeConfig() { export function makeConfig() {

View File

@@ -1,147 +0,0 @@
{
"~:features": {
"~#set": [
"fdata/path-data",
"plugins/runtime",
"design-tokens/v1",
"variants/v1",
"layout/grid",
"styles/v2",
"fdata/objects-map",
"text-editor/v2",
"render-wasm/v1",
"components/v2",
"fdata/shape-data-type"
]
},
"~:team-id": "~ud7430f09-4f59-8049-8007-6277bb7586f6",
"~:permissions": {
"~:type": "~:membership",
"~:is-owner": true,
"~:is-admin": true,
"~:can-edit": true,
"~:can-read": true,
"~:is-logged": true
},
"~:has-media-trimmed": false,
"~:comment-thread-seqn": 0,
"~:name": "test_color_blending",
"~:revn": 78,
"~:modified-at": "~m1770820738388",
"~:vern": 0,
"~:id": "~ub15901d7-d46d-8056-8007-8d5e34fc1f0c",
"~:is-shared": false,
"~:migrations": {
"~#ordered-set": [
"legacy-2",
"legacy-3",
"legacy-5",
"legacy-6",
"legacy-7",
"legacy-8",
"legacy-9",
"legacy-10",
"legacy-11",
"legacy-12",
"legacy-13",
"legacy-14",
"legacy-16",
"legacy-17",
"legacy-18",
"legacy-19",
"legacy-25",
"legacy-26",
"legacy-27",
"legacy-28",
"legacy-29",
"legacy-31",
"legacy-32",
"legacy-33",
"legacy-34",
"legacy-36",
"legacy-37",
"legacy-38",
"legacy-39",
"legacy-40",
"legacy-41",
"legacy-42",
"legacy-43",
"legacy-44",
"legacy-45",
"legacy-46",
"legacy-47",
"legacy-48",
"legacy-49",
"legacy-50",
"legacy-51",
"legacy-52",
"legacy-53",
"legacy-54",
"legacy-55",
"legacy-56",
"legacy-57",
"legacy-59",
"legacy-62",
"legacy-65",
"legacy-66",
"legacy-67",
"0001-remove-tokens-from-groups",
"0002-normalize-bool-content-v2",
"0002-clean-shape-interactions",
"0003-fix-root-shape",
"0003-convert-path-content-v2",
"0005-deprecate-image-type",
"0006-fix-old-texts-fills",
"0008-fix-library-colors-v4",
"0009-clean-library-colors",
"0009-add-partial-text-touched-flags",
"0010-fix-swap-slots-pointing-non-existent-shapes",
"0011-fix-invalid-text-touched-flags",
"0012-fix-position-data",
"0013-fix-component-path",
"0013-clear-invalid-strokes-and-fills",
"0014-fix-tokens-lib-duplicate-ids",
"0014-clear-components-nil-objects",
"0015-fix-text-attrs-blank-strings",
"0015-clean-shadow-color",
"0016-copy-fills-from-position-data-to-text-node"
]
},
"~:version": 67,
"~:project-id": "~ud7430f09-4f59-8049-8007-6277bb765abd",
"~:created-at": "~m1770741329904",
"~:backend": "legacy-db",
"~:data": {
"~:pages": [
"~ub15901d7-d46d-8056-8007-8d5e34fc1f0d"
],
"~:pages-index": {
"~ub15901d7-d46d-8056-8007-8d5e34fc1f0d": {
"~:objects": {
"~#penpot/objects-map/v2": {
"~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^H\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~u3b7d4c1f-3b79-80e5-8007-8d5e38c5a297\",\"~udb80df91-a3a3-803b-8007-8e379b5fd50f\",\"~udb80df91-a3a3-803b-8007-8e38034ff7c8\",\"~udb80df91-a3a3-803b-8007-8e37a71c9d28\",\"~udb80df91-a3a3-803b-8007-8e384d8c53b9\",\"~udb80df91-a3a3-803b-8007-8e37c09b4084\",\"~u18522c44-655d-8050-8007-8e89f4bdc0c4\",\"~u097859f1-ca3b-80ba-8007-8e8beb99a3f5\",\"~u18522c44-655d-8050-8007-8e89f4bdc0c5\",\"~u097859f1-ca3b-80ba-8007-8e8bfca43303\",\"~ufb1f50bf-1bff-8030-8007-8e8c3bd8fcd7\",\"~u18522c44-655d-8050-8007-8e89f4bdc0c6\"]]]",
"~u097859f1-ca3b-80ba-8007-8e8bfca43303": "[\"~#shape\",[\"^ \",\"~:y\",-637.0000057220459,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",300.0000100135803,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",336.9999895095825,\"~:y\",-637.000005722046]],[\"^<\",[\"^ \",\"~:x\",636.9999995231628,\"~:y\",-637.000005722046]],[\"^<\",[\"^ \",\"~:x\",636.9999995231628,\"~:y\",-337.00000858306885]],[\"^<\",[\"^ \",\"~:x\",336.9999895095825,\"~:y\",-337.00000858306885]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:blur\",[\"^ \",\"~:id\",\"~udb80df91-a3a3-803b-8007-8e380b12ac2a\",\"^9\",\"~:layer-blur\",\"~:value\",7,\"~:hidden\",false],\"~:r1\",0,\"^B\",\"~u097859f1-ca3b-80ba-8007-8e8bfca43303\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:center\",\"~:stroke-width\",10,\"~:stroke-color\",\"#4bff00\",\"~:stroke-opacity\",1],[\"^ \",\"^J\",\"^K\",\"^L\",\"~:outer\",\"^N\",10,\"^O\",\"#333fbd\",\"^P\",1],[\"^ \",\"^J\",\"^K\",\"^L\",\"~:inner\",\"^N\",10,\"^O\",\"#ff0000\",\"^P\",1]],\"~:x\",336.9999895095825,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",336.9999895095825,\"~:y\",-637.0000057220459,\"^8\",300.0000100135803,\"~:height\",299.99999713897705,\"~:x1\",336.9999895095825,\"~:y1\",-637.0000057220459,\"~:x2\",636.9999995231628,\"~:y2\",-337.00000858306885]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1],[\"^ \",\"^11\",\"#ff0000\",\"^12\",1]],\"~:flip-x\",null,\"^W\",299.99999713897705,\"~:flip-y\",null]]",
"~udb80df91-a3a3-803b-8007-8e384d8c53b9": "[\"~#shape\",[\"^ \",\"~:y\",450.99999806284904,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Ellipse\",\"~:width\",300.0000065565109,\"~:type\",\"~:circle\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1021.0000203847885,\"~:y\",450.99999806284904]],[\"^<\",[\"^ \",\"~:x\",1321.0000269412994,\"~:y\",450.99999806284904]],[\"^<\",[\"^ \",\"~:x\",1321.0000269412994,\"~:y\",751.0000142753124]],[\"^<\",[\"^ \",\"~:x\",1021.0000203847885,\"~:y\",751.0000142753124]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:blur\",[\"^ \",\"~:id\",\"~udb80df91-a3a3-803b-8007-8e37b7ddd15c\",\"^9\",\"~:layer-blur\",\"~:value\",7,\"~:hidden\",false],\"^@\",\"~udb80df91-a3a3-803b-8007-8e384d8c53b9\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",20,\"~:stroke-color\",\"#333fbd\",\"~:stroke-opacity\",1]],\"~:x\",1021.0000203847885,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1021.0000203847885,\"~:y\",450.99999806284904,\"^8\",300.0000065565109,\"~:height\",300.0000162124634,\"~:x1\",1021.0000203847885,\"~:y1\",450.99999806284904,\"~:x2\",1321.0000269412994,\"~:y2\",751.0000142753124]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1],[\"^ \",\"^W\",\"#ff0000\",\"^X\",1]],\"~:flip-x\",null,\"^Q\",300.0000162124634,\"~:flip-y\",null]]",
"~udb80df91-a3a3-803b-8007-8e379b5fd50f": "[\"~#shape\",[\"^ \",\"~:y\",82.00000368146124,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",300.0000100135803,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",686.7500124588994,\"~:y\",82.00000368146122]],[\"^<\",[\"^ \",\"~:x\",986.7500224724797,\"~:y\",82.00000368146122]],[\"^<\",[\"^ \",\"~:x\",986.7500224724797,\"~:y\",382.0000008204383]],[\"^<\",[\"^ \",\"~:x\",686.7500124588994,\"~:y\",382.0000008204383]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~udb80df91-a3a3-803b-8007-8e379b5fd50f\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",686.7500124588994,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",686.7500124588994,\"~:y\",82.00000368146124,\"^8\",300.0000100135803,\"~:height\",299.99999713897705,\"~:x1\",686.7500124588994,\"~:y1\",82.00000368146124,\"~:x2\",986.7500224724797,\"~:y2\",382.0000008204383]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1],[\"^ \",\"^P\",\"#ff0000\",\"^Q\",1]],\"~:flip-x\",null,\"^J\",299.99999713897705,\"~:flip-y\",null]]",
"~u3b7d4c1f-3b79-80e5-8007-8d5e38c5a297": "[\"~#shape\",[\"^ \",\"~:y\",81.9999960520667,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",300.0000100135803,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",337.0000200882939,\"~:y\",81.99999605206669]],[\"^<\",[\"^ \",\"~:x\",637.0000301018742,\"~:y\",81.99999605206669]],[\"^<\",[\"^ \",\"~:x\",637.0000301018742,\"~:y\",381.99999319104376]],[\"^<\",[\"^ \",\"~:x\",337.0000200882939,\"~:y\",381.99999319104376]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:blur\",[\"^ \",\"~:id\",\"~u432cbb09-2ee7-80bf-8007-8d660b2f52ad\",\"^9\",\"~:layer-blur\",\"~:value\",7,\"~:hidden\",false],\"~:r1\",0,\"^B\",\"~u3b7d4c1f-3b79-80e5-8007-8d5e38c5a297\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",337.0000200882939,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",337.0000200882939,\"~:y\",81.9999960520667,\"^8\",300.0000100135803,\"~:height\",299.99999713897705,\"~:x1\",337.0000200882939,\"~:y1\",81.9999960520667,\"~:x2\",637.0000301018742,\"~:y2\",381.99999319104376]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1],[\"^ \",\"^T\",\"#ff0000\",\"^U\",1]],\"~:flip-x\",null,\"^N\",299.99999713897705,\"~:flip-y\",null]]",
"~ufb1f50bf-1bff-8030-8007-8e8c3bd8fcd7": "[\"~#shape\",[\"^ \",\"~:y\",-629.9999999999998,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",300.0000100135803,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1037,\"~:y\",-630]],[\"^<\",[\"^ \",\"~:x\",1337.0000100135803,\"~:y\",-630]],[\"^<\",[\"^ \",\"~:x\",1337.0000100135803,\"~:y\",-330.0000028610228]],[\"^<\",[\"^ \",\"~:x\",1037,\"~:y\",-330.0000028610228]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:blur\",[\"^ \",\"~:id\",\"~udb80df91-a3a3-803b-8007-8e380b12ac2a\",\"^9\",\"~:layer-blur\",\"~:value\",7,\"~:hidden\",false],\"~:r1\",0,\"^B\",\"~ufb1f50bf-1bff-8030-8007-8e8c3bd8fcd7\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:outer\",\"~:stroke-width\",10,\"~:stroke-color\",\"#333fbd\",\"~:stroke-opacity\",1],[\"^ \",\"^J\",\"^K\",\"^L\",\"~:inner\",\"^N\",10,\"^O\",\"#ff0000\",\"^P\",1],[\"^ \",\"^J\",\"^K\",\"^L\",\"~:center\",\"^N\",10,\"^O\",\"#4bff00\",\"^P\",1]],\"~:x\",1037,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1037,\"~:y\",-629.9999999999998,\"^8\",300.0000100135803,\"~:height\",299.999997138977,\"~:x1\",1037,\"~:y1\",-629.9999999999998,\"~:x2\",1337.0000100135803,\"~:y2\",-330.0000028610228]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1],[\"^ \",\"^11\",\"#ff0000\",\"^12\",1]],\"~:flip-x\",null,\"^W\",299.999997138977,\"~:flip-y\",null]]",
"~u097859f1-ca3b-80ba-8007-8e8beb99a3f5": "[\"~#shape\",[\"^ \",\"~:y\",-626.0000057220459,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",300.0000100135803,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",687.0000123977661,\"~:y\",-626.000005722046]],[\"^<\",[\"^ \",\"~:x\",987.0000224113464,\"~:y\",-626.000005722046]],[\"^<\",[\"^ \",\"~:x\",987.0000224113464,\"~:y\",-326.00000858306885]],[\"^<\",[\"^ \",\"~:x\",687.0000123977661,\"~:y\",-326.00000858306885]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:blur\",[\"^ \",\"~:id\",\"~udb80df91-a3a3-803b-8007-8e380b12ac2a\",\"^9\",\"~:layer-blur\",\"~:value\",7,\"~:hidden\",false],\"~:r1\",0,\"^B\",\"~u097859f1-ca3b-80ba-8007-8e8beb99a3f5\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",10,\"~:stroke-color\",\"#333fbd\",\"~:stroke-opacity\",1],[\"^ \",\"^J\",\"^K\",\"^L\",\"^M\",\"^N\",10,\"^O\",\"#ff0000\",\"^P\",1]],\"~:x\",687.0000123977661,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",687.0000123977661,\"~:y\",-626.0000057220459,\"^8\",300.0000100135803,\"~:height\",299.99999713897705,\"~:x1\",687.0000123977661,\"~:y1\",-626.0000057220459,\"~:x2\",987.0000224113464,\"~:y2\",-326.00000858306885]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1],[\"^ \",\"^[\",\"#ff0000\",\"^10\",1]],\"~:flip-x\",null,\"^U\",299.99999713897705,\"~:flip-y\",null]]",
"~udb80df91-a3a3-803b-8007-8e37a71c9d28": "[\"~#shape\",[\"^ \",\"~:y\",450.99999806284904,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Ellipse\",\"~:width\",300.0000065565109,\"~:type\",\"~:circle\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",337.0000203847885,\"~:y\",450.99999806284904]],[\"^<\",[\"^ \",\"~:x\",637.0000269412994,\"~:y\",450.99999806284904]],[\"^<\",[\"^ \",\"~:x\",637.0000269412994,\"~:y\",751.0000142753124]],[\"^<\",[\"^ \",\"~:x\",337.0000203847885,\"~:y\",751.0000142753124]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:blur\",[\"^ \",\"~:id\",\"~udb80df91-a3a3-803b-8007-8e37b7ddd15c\",\"^9\",\"~:layer-blur\",\"~:value\",7,\"~:hidden\",false],\"^@\",\"~udb80df91-a3a3-803b-8007-8e37a71c9d28\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",337.0000203847885,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",337.0000203847885,\"~:y\",450.99999806284904,\"^8\",300.0000065565109,\"~:height\",300.0000162124634,\"~:x1\",337.0000203847885,\"~:y1\",450.99999806284904,\"~:x2\",637.0000269412994,\"~:y2\",751.0000142753124]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1],[\"^ \",\"^P\",\"#ff0000\",\"^Q\",1]],\"~:flip-x\",null,\"^J\",300.0000162124634,\"~:flip-y\",null]]",
"~u18522c44-655d-8050-8007-8e89f4bdc0c5": "[\"~#shape\",[\"^ \",\"~:y\",-287.0000057220459,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",300.0000100135803,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",337.00002002716064,\"~:y\",-287.000005722046]],[\"^<\",[\"^ \",\"~:x\",637.000030040741,\"~:y\",-287.000005722046]],[\"^<\",[\"^ \",\"~:x\",637.000030040741,\"~:y\",12.999991416931152]],[\"^<\",[\"^ \",\"~:x\",337.00002002716064,\"~:y\",12.999991416931152]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:blur\",[\"^ \",\"~:id\",\"~udb80df91-a3a3-803b-8007-8e380b12ac2a\",\"^9\",\"~:layer-blur\",\"~:value\",7,\"~:hidden\",false],\"~:r1\",0,\"^B\",\"~u18522c44-655d-8050-8007-8e89f4bdc0c5\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:outer\",\"~:stroke-width\",10,\"~:stroke-color\",\"#333fbd\",\"~:stroke-opacity\",1],[\"^ \",\"^J\",\"^K\",\"^L\",\"~:inner\",\"^N\",10,\"^O\",\"#ff0000\",\"^P\",1]],\"~:x\",337.00002002716064,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",337.00002002716064,\"~:y\",-287.0000057220459,\"^8\",300.0000100135803,\"~:height\",299.99999713897705,\"~:x1\",337.00002002716064,\"~:y1\",-287.0000057220459,\"~:x2\",637.000030040741,\"~:y2\",12.999991416931152]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1],[\"^ \",\"^10\",\"#ff0000\",\"^11\",1]],\"~:flip-x\",null,\"^V\",299.99999713897705,\"~:flip-y\",null]]",
"~udb80df91-a3a3-803b-8007-8e37c09b4084": "[\"~#shape\",[\"^ \",\"~:y\",450.99999806284904,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Ellipse\",\"~:width\",300.0000065565109,\"~:type\",\"~:circle\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",679.0000203847885,\"~:y\",450.99999806284904]],[\"^<\",[\"^ \",\"~:x\",979.0000269412994,\"~:y\",450.99999806284904]],[\"^<\",[\"^ \",\"~:x\",979.0000269412994,\"~:y\",751.0000142753124]],[\"^<\",[\"^ \",\"~:x\",679.0000203847885,\"~:y\",751.0000142753124]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~udb80df91-a3a3-803b-8007-8e37c09b4084\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",679.0000203847885,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",679.0000203847885,\"~:y\",450.99999806284904,\"^8\",300.0000065565109,\"~:height\",300.0000162124634,\"~:x1\",679.0000203847885,\"~:y1\",450.99999806284904,\"~:x2\",979.0000269412994,\"~:y2\",751.0000142753124]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1],[\"^ \",\"^L\",\"#ff0000\",\"^M\",1]],\"~:flip-x\",null,\"^F\",300.0000162124634,\"~:flip-y\",null]]",
"~u18522c44-655d-8050-8007-8e89f4bdc0c4": "[\"~#shape\",[\"^ \",\"~:y\",-287.0000057220459,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",300.0000100135803,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",686.7500123977661,\"~:y\",-287.000005722046]],[\"^<\",[\"^ \",\"~:x\",986.7500224113464,\"~:y\",-287.000005722046]],[\"^<\",[\"^ \",\"~:x\",986.7500224113464,\"~:y\",12.999991416931152]],[\"^<\",[\"^ \",\"~:x\",686.7500123977661,\"~:y\",12.999991416931152]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:blur\",[\"^ \",\"~:id\",\"~udb80df91-a3a3-803b-8007-8e380b12ac2a\",\"^9\",\"~:layer-blur\",\"~:value\",7,\"~:hidden\",false],\"~:r1\",0,\"^B\",\"~u18522c44-655d-8050-8007-8e89f4bdc0c4\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",10,\"~:stroke-color\",\"#333fbd\",\"~:stroke-opacity\",0.5],[\"^ \",\"^J\",\"^K\",\"^L\",\"^M\",\"^N\",10,\"^O\",\"#ff0000\",\"^P\",1]],\"~:x\",686.7500123977661,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",686.7500123977661,\"~:y\",-287.0000057220459,\"^8\",300.0000100135803,\"~:height\",299.99999713897705,\"~:x1\",686.7500123977661,\"~:y1\",-287.0000057220459,\"~:x2\",986.7500224113464,\"~:y2\",12.999991416931152]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1],[\"^ \",\"^[\",\"#ff0000\",\"^10\",1]],\"~:flip-x\",null,\"^U\",299.99999713897705,\"~:flip-y\",null]]",
"~udb80df91-a3a3-803b-8007-8e38034ff7c8": "[\"~#shape\",[\"^ \",\"~:y\",82.00000368146124,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",300.0000100135803,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1036.5000048295049,\"~:y\",82.00000368146122]],[\"^<\",[\"^ \",\"~:x\",1336.5000148430852,\"~:y\",82.00000368146122]],[\"^<\",[\"^ \",\"~:x\",1336.5000148430852,\"~:y\",382.0000008204383]],[\"^<\",[\"^ \",\"~:x\",1036.5000048295049,\"~:y\",382.0000008204383]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:blur\",[\"^ \",\"~:id\",\"~udb80df91-a3a3-803b-8007-8e380b12ac2a\",\"^9\",\"~:layer-blur\",\"~:value\",7,\"~:hidden\",false],\"~:r1\",0,\"^B\",\"~udb80df91-a3a3-803b-8007-8e38034ff7c8\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",10,\"~:stroke-color\",\"#333fbd\",\"~:stroke-opacity\",1]],\"~:x\",1036.5000048295049,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1036.5000048295049,\"~:y\",82.00000368146124,\"^8\",300.0000100135803,\"~:height\",299.99999713897705,\"~:x1\",1036.5000048295049,\"~:y1\",82.00000368146124,\"~:x2\",1336.5000148430852,\"~:y2\",382.0000008204383]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1],[\"^ \",\"^[\",\"#ff0000\",\"^10\",1]],\"~:flip-x\",null,\"^U\",299.99999713897705,\"~:flip-y\",null]]",
"~u18522c44-655d-8050-8007-8e89f4bdc0c6": "[\"~#shape\",[\"^ \",\"~:y\",-287.0000057220459,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",300.0000100135803,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1036.5000047683716,\"~:y\",-287.000005722046]],[\"^<\",[\"^ \",\"~:x\",1336.500014781952,\"~:y\",-287.000005722046]],[\"^<\",[\"^ \",\"~:x\",1336.500014781952,\"~:y\",12.999991416931152]],[\"^<\",[\"^ \",\"~:x\",1036.5000047683716,\"~:y\",12.999991416931152]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:blur\",[\"^ \",\"~:id\",\"~udb80df91-a3a3-803b-8007-8e380b12ac2a\",\"^9\",\"~:layer-blur\",\"~:value\",7,\"~:hidden\",false],\"~:r1\",0,\"^B\",\"~u18522c44-655d-8050-8007-8e89f4bdc0c6\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",10,\"~:stroke-color\",\"#333fbd\",\"~:stroke-opacity\",1],[\"^ \",\"^J\",\"^K\",\"^L\",\"~:outer\",\"^N\",10,\"^O\",\"#ff0000\",\"^P\",1]],\"~:x\",1036.5000047683716,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1036.5000047683716,\"~:y\",-287.0000057220459,\"^8\",300.0000100135803,\"~:height\",299.99999713897705,\"~:x1\",1036.5000047683716,\"~:y1\",-287.0000057220459,\"~:x2\",1336.500014781952,\"~:y2\",12.999991416931152]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1],[\"^ \",\"^10\",\"#ff0000\",\"^11\",1]],\"~:flip-x\",null,\"^V\",299.99999713897705,\"~:flip-y\",null]]"
}
},
"~:id": "~ub15901d7-d46d-8056-8007-8d5e34fc1f0d",
"~:name": "Page 1"
}
},
"~:id": "~ub15901d7-d46d-8056-8007-8d5e34fc1f0c",
"~:options": {
"~:components-v2": true,
"~:base-font-size": "16px"
}
}
}

View File

@@ -22,8 +22,8 @@
"~:has-media-trimmed": false, "~:has-media-trimmed": false,
"~:comment-thread-seqn": 0, "~:comment-thread-seqn": 0,
"~:name": "flex_index_position", "~:name": "flex_index_position",
"~:revn": 126, "~:revn": 114,
"~:modified-at": "~m1770978609930", "~:modified-at": "~m1769430362161",
"~:vern": 0, "~:vern": 0,
"~:id": "~u31fe2e21-73e7-80f3-8007-73894fb58240", "~:id": "~u31fe2e21-73e7-80f3-8007-73894fb58240",
"~:is-shared": false, "~:is-shared": false,
@@ -117,63 +117,31 @@
"~:name": "Page 1", "~:name": "Page 1",
"~:objects": { "~:objects": {
"~#penpot/objects-map/v2": { "~#penpot/objects-map/v2": {
"~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^I\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~u77c71dba-32ee-804c-8007-736561cf857f\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~u9299427e-8172-80bb-8007-90e71cbb9fea\",\"~u9299427e-8172-80bb-8007-90e71fba0f7d\",\"~u9299427e-8172-80bb-8007-90e72469bf8c\"]]]", "~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^I\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~u77c71dba-32ee-804c-8007-736561cf857f\"]]]",
"~u9299427e-8172-80bb-8007-90e71fba0f82": "[\"~#shape\",[\"^ \",\"~:y\",210.0000271241638,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:name\",\"base-background\",\"~:width\",24,\"~:type\",\"~:rect\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linejoin\",\"round\",\"~:stroke-linecap\",\"round\",\"~:id\",\"base-background\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1140,\"~:y\",210.0000271241638]],[\"^?\",[\"^ \",\"~:x\",1164,\"~:y\",210.0000271241638]],[\"^?\",[\"^ \",\"~:x\",1164,\"~:y\",234.0000271241638]],[\"^?\",[\"^ \",\"~:x\",1140,\"~:y\",234.0000271241638]]],\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c5\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:hidden\",true,\"^=\",\"~u9299427e-8172-80bb-8007-90e71fba0f82\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f81\",\"~:svg-viewbox\",[\"^ \",\"~:y\",0,\"~:y1\",0,\"^6\",24,\"~:x\",0,\"~:x1\",0,\"~:y2\",24,\"~:x2\",24,\"~:height\",24],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f81\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-color\",\"#ffffff\",\"~:stroke-opacity\",1,\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2]],\"~:x\",1140,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1140,\"~:y\",210.0000271241638,\"^6\",24,\"^K\",24,\"^H\",1140,\"^G\",210.0000271241638,\"^J\",1164,\"^I\",234.0000271241638]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",24,\"~:flip-y\",null]]", "~u77c71dba-32ee-804c-8007-736561cff457": "[\"~#shape\",[\"^ \",\"~:y\",396.00000357564704,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",396.00000357564704]],[\"^>\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",396.00000357564704]],[\"^>\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",476.00000357564704]],[\"^>\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",476.00000357564704]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff457\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:strokes\",[],\"~:x\",688.9999775886536,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",396.00000357564704,\"^9\",80,\"~:height\",80,\"~:x1\",688.9999775886536,\"~:y1\",396.00000357564704,\"~:x2\",768.9999775886536,\"~:y2\",476.00000357564704]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e7059421c2": "[\"~#shape\",[\"^ \",\"~:y\",198.00002998518676,\"~:hide-fill-on-export\",false,\"~:layout-item-absolute\",true,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"add-favorites\",\"~:layout-align-items\",\"~:center\",\"~:width\",48,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:touched\",[\"~#set\",[\"^2\",\"~:layout-item-z-index\"]],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",792,\"~:y\",198.00002998518676]],[\"^P\",[\"^ \",\"~:x\",840,\"~:y\",198.00002998518676]],[\"^P\",[\"^ \",\"~:x\",840,\"~:y\",246.00002426314086]],[\"^P\",[\"^ \",\"~:x\",792,\"~:y\",246.00002426314086]]],\"~:r2\",50,\"~:shape-ref\",\"~uc8b014fe-f285-8021-8007-8ea400bd9406\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",50,\"~:layout-justify-content\",\"^F\",\"~:r1\",50,\"~:id\",\"~u9299427e-8172-80bb-8007-90e7059421c2\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:layout-flex-dir\",\"~:row\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"color.bg.default\"],\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea447a0bc30\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:strokes\",[],\"~:x\",792,\"~:proportion\",1,\"~:r4\",50,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",792,\"~:y\",198.00002998518676,\"^G\",48,\"~:height\",47.9999942779541,\"~:x1\",792,\"~:y1\",198.00002998518676,\"~:x2\",840,\"~:y2\",246.00002426314086]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.3]],\"~:flip-x\",null,\"^1?\",47.9999942779541,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e7059421c4\"]]]", "~u94eaebe4-addd-80d1-8007-79d508aa2885": "[\"~#shape\",[\"^ \",\"~:y\",612.0000188344361,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",604.9999165534973,\"~:y\",612.0000188344361]],[\"^>\",[\"^ \",\"~:x\",684.9999165534973,\"~:y\",612.0000188344361]],[\"^>\",[\"^ \",\"~:x\",684.9999165534973,\"~:y\",692.0000188344361]],[\"^>\",[\"^ \",\"~:x\",604.9999165534973,\"~:y\",692.0000188344361]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2885\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:strokes\",[],\"~:x\",604.9999165534973,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",604.9999165534973,\"~:y\",612.0000188344361,\"^9\",80,\"~:height\",80,\"~:x1\",604.9999165534973,\"~:y1\",612.0000188344361,\"~:x2\",684.9999165534973,\"~:y2\",692.0000188344361]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71fba0f83": "[\"~#shape\",[\"^ \",\"~:y\",212.99997181105346,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"svg-path\",\"~:width\",20,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1142,\"~:y\",212.99997181105346]],[\"^;\",[\"^ \",\"~:x\",1162,\"~:y\",212.99997181105346]],[\"^;\",[\"^ \",\"~:x\",1162,\"~:y\",230.99997181105346]],[\"^;\",[\"^ \",\"~:x\",1142,\"~:y\",230.99997181105346]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c6\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71fba0f83\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f81\",\"~:applied-tokens\",[\"^ \"],\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea4f64a1c9b\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f81\",\"~:strokes\",[],\"~:x\",1142,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1142,\"~:y\",212.99997181105346,\"^7\",20,\"~:height\",18,\"~:x1\",1142,\"~:y1\",212.99997181105346,\"~:x2\",1162,\"~:y2\",230.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^N\",18,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71fba0f84\"]]]", "~u94eaebe4-addd-80d1-8007-79d508aa2886": "[\"~#shape\",[\"^ \",\"~:y\",636.0000188344361,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",611.9999165534973,\"~:y\",636.0000188344361]],[\"^K\",[\"^ \",\"~:x\",677.9999165534973,\"~:y\",636.0000188344361]],[\"^K\",[\"^ \",\"~:x\",677.9999165534973,\"~:y\",668.0000188344361]],[\"^K\",[\"^ \",\"~:x\",611.9999165534973,\"~:y\",668.0000188344361]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:strokes\",[],\"~:x\",611.9999165534973,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",611.9999165534973,\"~:y\",636.0000188344361,\"^E\",66,\"~:height\",32,\"~:x1\",611.9999165534973,\"~:y1\",636.0000188344361,\"~:x2\",677.9999165534973,\"~:y2\",668.0000188344361]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508aa2887\"]]]",
"~u9299427e-8172-80bb-8007-90e7059421c3": "[\"~#shape\",[\"^ \",\"~:y\",192.00001259178498,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"patinegro\",\"~:width\",264.80230943863717,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",579.9999793759137,\"~:y\",192.00001259178498]],[\"^9\",[\"^ \",\"~:x\",844.8022888145506,\"~:y\",192.00001259178498]],[\"^9\",[\"^ \",\"~:x\",844.8022888145506,\"~:y\",388.1131514739925]],[\"^9\",[\"^ \",\"~:x\",579.9999793759137,\"~:y\",388.1131514739925]]],\"~:r2\",0,\"~:proportion-lock\",true,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e7059421c3\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e7059421c1\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e7059421c1\",\"~:strokes\",[],\"~:x\",579.9999793759134,\"~:proportion\",1.3487940630797774,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",579.9999793759134,\"~:y\",192.00001259178498,\"^5\",264.80230943863717,\"~:height\",196.11313888220752,\"~:x1\",579.9999793759134,\"~:y1\",192.00001259178498,\"~:x2\",844.8022888145506,\"~:y2\",388.1131514739925]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#b73d3d\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^H\",196.11313888220752,\"~:flip-y\",null]]", "~u94eaebe4-addd-80d1-8007-79d508aa2887": "[\"~#shape\",[\"^ \",\"~:y\",644.0000188344361,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",623.9999165534973,\"~:y\",644.0000188344361]],[\"^K\",[\"^ \",\"~:x\",665.9999165534973,\"~:y\",644.0000188344361]],[\"^K\",[\"^ \",\"~:x\",665.9999165534973,\"~:y\",660.0000188344361]],[\"^K\",[\"^ \",\"~:x\",623.9999165534973,\"~:y\",660.0000188344361]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2887\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\",\"~:strokes\",[],\"~:x\",623.9999165534973,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",623.9999165534973,\"~:y\",644.0000188344361,\"^D\",42,\"~:height\",16,\"~:x1\",623.9999165534973,\"~:y1\",644.0000188344361,\"~:x2\",665.9999165534973,\"~:y2\",660.0000188344361]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508aa2888\"]]]",
"~u9299427e-8172-80bb-8007-90e71fba0f80": "[\"~#shape\",[\"^ \",\"~:y\",192.00001259178498,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"patinegro\",\"~:width\",264.80230943863717,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",915.9999793759137,\"~:y\",192.00001259178498]],[\"^9\",[\"^ \",\"~:x\",1180.8022888145506,\"~:y\",192.00001259178498]],[\"^9\",[\"^ \",\"~:x\",1180.8022888145506,\"~:y\",388.1131514739925]],[\"^9\",[\"^ \",\"~:x\",915.9999793759137,\"~:y\",388.1131514739925]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c3\",\"~:proportion-lock\",true,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71fba0f80\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7e\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7e\",\"~:strokes\",[],\"~:x\",915.9999793759134,\"~:proportion\",1.3487940630797774,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",915.9999793759134,\"~:y\",192.00001259178498,\"^5\",264.80230943863717,\"~:height\",196.11313888220752,\"~:x1\",915.9999793759134,\"~:y1\",192.00001259178498,\"~:x2\",1180.8022888145506,\"~:y2\",388.1131514739925]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#b73d3d\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^I\",196.11313888220752,\"~:flip-y\",null]]", "~u94eaebe4-addd-80d1-8007-79d508aa2888": "[\"~#shape\",[\"^ \",\"~:y\",645.0000188344363,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",625.9999165534973,\"~:y\",645.0000188344363]],[\"^S\",[\"^ \",\"~:x\",663.9999165534973,\"~:y\",645.0000188344363]],[\"^S\",[\"^ \",\"~:x\",663.9999165534973,\"~:y\",660.0000188344359]],[\"^S\",[\"^ \",\"~:x\",625.9999165534973,\"~:y\",660.0000188344363]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2888\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2887\",\"~:position-data\",[[\"^ \",\"~:y\",659.3400268554688,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.94000244140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",626.0299682617188,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.08001708984375,\"^L\",\"Label\"]],\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2887\",\"~:strokes\",[],\"~:x\",625.9999165534973,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",625.9999165534973,\"~:y\",645.0000188344363,\"^Q\",38,\"^11\",15,\"~:x1\",625.9999165534973,\"~:y1\",645.0000188344363,\"~:x2\",663.9999165534973,\"~:y2\",660.0000188344363]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e7059421c0": "[\"~#shape\",[\"^ \",\"~:y\",191.99998474121094,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"card-img / patinegro\",\"~:layout-align-items\",\"~:start\",\"~:variant-name\",\"patinegro\",\"~:width\",265,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",580,\"~:y\",191.99998474121094]],[\"^M\",[\"^ \",\"~:x\",845,\"~:y\",191.99998474121094]],[\"^M\",[\"^ \",\"~:x\",845,\"~:y\",369.99997875688996]],[\"^M\",[\"^ \",\"~:x\",580,\"~:y\",369.99997875688996]]],\"~:r2\",20,\"~:component-root\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:r3\",20,\"~:layout-justify-content\",\"^E\",\"~:r1\",20,\"~:id\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~u9299427e-8172-80bb-8007-90e7059a83e2\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",580,\"~:main-instance\",true,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",580,\"~:y\",191.99998474121094,\"^G\",265,\"~:height\",177.99999401567902,\"~:x1\",580,\"~:y1\",191.99998474121094,\"~:x2\",845,\"~:y2\",369.99997875688996]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^1=\",177.99999401567902,\"~:component-file\",\"~u31fe2e21-73e7-80f3-8007-73894fb58240\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e7059421c1\",\"~u9299427e-8172-80bb-8007-90e7059421c2\"]]]", "~u77c71dba-32ee-804c-8007-736561cff45a": "[\"~#shape\",[\"^ \",\"~:y\",429.00000357564727,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",709.9999775886536,\"~:y\",429.00000357564727]],[\"^S\",[\"^ \",\"~:x\",747.9999775886536,\"~:y\",429.00000357564727]],[\"^S\",[\"^ \",\"~:x\",747.9999775886536,\"~:y\",444.0000035756468]],[\"^S\",[\"^ \",\"~:x\",709.9999775886536,\"~:y\",444.00000357564727]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff45a\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cff459\",\"~:position-data\",[[\"^ \",\"~:y\",443.3399963378906,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.93994140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",710.030029296875,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.079986572265625,\"^L\",\"Label\"]],\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cff459\",\"~:strokes\",[],\"~:x\",709.9999775886536,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",709.9999775886536,\"~:y\",429.00000357564727,\"^Q\",38,\"^11\",15,\"~:x1\",709.9999775886536,\"~:y1\",429.00000357564727,\"~:x2\",747.9999775886536,\"~:y2\",444.00000357564727]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71fba0f81": "[\"~#shape\",[\"^ \",\"~:y\",209.99999660658568,\"~:rx\",0,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:hide-in-viewer\",true,\"~:name\",\"heart\",\"~:width\",24,\"~:type\",\"~:frame\",\"~:svg-attrs\",[\"^ \",\"^8\",\"24\",\"~:height\",\"24\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1140,\"~:y\",209.99999660658568]],[\"^>\",[\"^ \",\"~:x\",1164,\"~:y\",209.99999660658568]],[\"^>\",[\"^ \",\"~:x\",1164,\"~:y\",233.99999660658568]],[\"^>\",[\"^ \",\"~:x\",1140,\"~:y\",233.99999660658568]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71fba0f81\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7f\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7f\",\"~:strokes\",[],\"~:x\",1140,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1140,\"~:y\",209.99999660658568,\"^8\",24,\"^<\",24,\"~:x1\",1140,\"~:y1\",209.99999660658568,\"~:x2\",1164,\"~:y2\",233.99999660658568]],\"~:fills\",[],\"~:flip-x\",null,\"~:ry\",0,\"^<\",24,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71fba0f82\",\"~u9299427e-8172-80bb-8007-90e71fba0f83\"]]]", "~u77c71dba-32ee-804c-8007-736561cff459": "[\"~#shape\",[\"^ \",\"~:y\",428.00000357564704,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",707.9999775886536,\"~:y\",428.00000357564704]],[\"^K\",[\"^ \",\"~:x\",749.9999775886536,\"~:y\",428.00000357564704]],[\"^K\",[\"^ \",\"~:x\",749.9999775886536,\"~:y\",444.00000357564704]],[\"^K\",[\"^ \",\"~:x\",707.9999775886536,\"~:y\",444.00000357564704]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff459\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cff458\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cff458\",\"~:strokes\",[],\"~:x\",707.9999775886536,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",707.9999775886536,\"~:y\",428.00000357564704,\"^D\",42,\"~:height\",16,\"~:x1\",707.9999775886536,\"~:y1\",428.00000357564704,\"~:x2\",749.9999775886536,\"~:y2\",444.00000357564704]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cff45a\"]]]",
"~u9299427e-8172-80bb-8007-90e7059421c1": "[\"~#shape\",[\"^ \",\"~:y\",191.99999475401955,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"img-city\",\"~:width\",265,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",580,\"~:y\",191.99999475401978]],[\"^;\",[\"^ \",\"~:x\",845,\"~:y\",191.99999475401978]],[\"^;\",[\"^ \",\"~:x\",845,\"~:y\",369.9899634401968]],[\"^;\",[\"^ \",\"~:x\",580,\"~:y\",369.9899634401968]]],\"~:r2\",0,\"~:layout-item-h-sizing\",\"~:fill\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:layout-item-v-sizing\",\"^>\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e7059421c1\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:strokes\",[],\"~:x\",580,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",580,\"~:y\",191.99999475401955,\"^7\",265,\"~:height\",177.989968686177,\"~:x1\",580,\"~:y1\",191.99999475401955,\"~:x2\",845,\"~:y2\",369.98996344019656]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^M\",177.989968686177,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e7059421c3\"]]]", "~u77c71dba-32ee-804c-8007-736561cff458": "[\"~#shape\",[\"^ \",\"~:y\",420.00000357564704,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",695.9999775886536,\"~:y\",420.00000357564704]],[\"^K\",[\"^ \",\"~:x\",761.9999775886536,\"~:y\",420.00000357564704]],[\"^K\",[\"^ \",\"~:x\",761.9999775886536,\"~:y\",452.00000357564704]],[\"^K\",[\"^ \",\"~:x\",695.9999775886536,\"~:y\",452.00000357564704]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff458\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:strokes\",[],\"~:x\",695.9999775886536,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",695.9999775886536,\"~:y\",420.00000357564704,\"^E\",66,\"~:height\",32,\"~:x1\",695.9999775886536,\"~:y1\",420.00000357564704,\"~:x2\",761.9999775886536,\"~:y2\",452.00000357564704]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cff459\"]]]",
"~u77c71dba-32ee-804c-8007-736561cff457": "[\"~#shape\",[\"^ \",\"~:y\",222.00000357564704,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",222.00000357564704]],[\"^>\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",222.00000357564704]],[\"^>\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",302.00000357564704]],[\"^>\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",302.00000357564704]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff457\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:strokes\",[],\"~:x\",379.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",222.00000357564704,\"^9\",80,\"~:height\",80,\"~:x1\",379.0000081062317,\"~:y1\",222.00000357564704,\"~:x2\",459.0000081062317,\"~:y2\",302.00000357564704]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]", "~u77c71dba-32ee-804c-8007-736561cf857f": "[\"~#shape\",[\"^ \",\"~:y\",395.99997913999186,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 1\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",593.0000386238098,\"~:y\",395.99997913999186]],[\"^J\",[\"^ \",\"~:x\",865.0000386238098,\"~:y\",395.99997913999186]],[\"^J\",[\"^ \",\"~:x\",865.0000386238098,\"~:y\",475.9999669761459]],[\"^J\",[\"^ \",\"~:x\",593.0000386238098,\"~:y\",475.9999669761459]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cf857f\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",593.0000386238098,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",593.0000386238098,\"~:y\",395.99997913999186,\"^D\",272,\"~:height\",79.99998783615405,\"~:x1\",593.0000386238098,\"~:y1\",395.99997913999186,\"~:x2\",865.0000386238098,\"~:y2\",475.9999669761459]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.99998783615405,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cf8584\"]]]",
"~u9299427e-8172-80bb-8007-90e7059421c6": "[\"~#shape\",[\"^ \",\"~:y\",212.99997181105346,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"svg-path\",\"~:width\",20,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",806,\"~:y\",212.99997181105346]],[\"^;\",[\"^ \",\"~:x\",826,\"~:y\",212.99997181105346]],[\"^;\",[\"^ \",\"~:x\",826,\"~:y\",230.99997181105346]],[\"^;\",[\"^ \",\"~:x\",806,\"~:y\",230.99997181105346]]],\"~:r2\",0,\"~:shape-ref\",\"~uc8b014fe-f285-8021-8007-8ea51856a422\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e7059421c6\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:applied-tokens\",[\"^ \"],\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea4f64a1c9b\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:strokes\",[],\"~:x\",806,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",806,\"~:y\",212.99997181105346,\"^7\",20,\"~:height\",18,\"~:x1\",806,\"~:y1\",212.99997181105346,\"~:x2\",826,\"~:y2\",230.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^N\",18,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e705944588\"]]]", "~u94eaebe4-addd-80d1-8007-79d50980078e": "[\"~#shape\",[\"^ \",\"~:y\",720.0000478045426,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 4\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",592.9998555183411,\"~:y\",720.0000478045426]],[\"^J\",[\"^ \",\"~:x\",864.9998555183411,\"~:y\",720.0000478045426]],[\"^J\",[\"^ \",\"~:x\",864.9998555183411,\"~:y\",800.0000356406968]],[\"^J\",[\"^ \",\"~:x\",592.9998555183411,\"~:y\",800.0000356406968]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column-reverse\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",592.9998555183411,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",592.9998555183411,\"~:y\",720.0000478045426,\"^D\",272,\"~:height\",79.9999878361541,\"~:x1\",592.9998555183411,\"~:y1\",720.0000478045426,\"~:x2\",864.9998555183411,\"~:y2\",800.0000356406968]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.9999878361541,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d50980078f\"]]]",
"~u94eaebe4-addd-80d1-8007-79d508aa2885": "[\"~#shape\",[\"^ \",\"~:y\",437.999988316858,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",437.999988316858]],[\"^>\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",437.999988316858]],[\"^>\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",517.999988316858]],[\"^>\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",517.999988316858]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2885\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:strokes\",[],\"~:x\",295.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",437.999988316858,\"^9\",80,\"~:height\",80,\"~:x1\",295.0000081062317,\"~:y1\",437.999988316858,\"~:x2\",375.0000081062317,\"~:y2\",517.999988316858]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]", "~u94eaebe4-addd-80d1-8007-79d50980078f": "[\"~#shape\",[\"^ \",\"~:y\",719.9999806874634,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",604.9999775886536,\"~:y\",719.9999806874634]],[\"^;\",[\"^ \",\"~:x\",684.9999775886536,\"~:y\",719.9999806874634]],[\"^;\",[\"^ \",\"~:x\",684.9999775886536,\"~:y\",799.9999806874634]],[\"^;\",[\"^ \",\"~:x\",604.9999775886536,\"~:y\",799.9999806874634]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~:strokes\",[],\"~:x\",604.9999775886536,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",604.9999775886536,\"~:y\",719.9999806874634,\"^7\",80,\"~:height\",80,\"~:x1\",604.9999775886536,\"~:y1\",719.9999806874634,\"~:x2\",684.9999775886536,\"~:y2\",799.9999806874634]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d509800790\",\"~u94eaebe4-addd-80d1-8007-79d509800791\"]]]",
"~u9299427e-8172-80bb-8007-90e71fba0f84": "[\"~#shape\",[\"^ \",\"~:y\",null,\"~:stroke-cap-start\",\"round\",\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:content\",[\"~#penpot/path-data\",\"~bAQAAAAAAAAAAAAAAAAAAAAAAAAAA4JBE/P9fQwMAAACuD5FE/IleQwBAkUT8yVxDAECRRPx/WkMDAAAAAECRRHx2V0M08ZBE/P9UQwCQkET8/1RDAwAAAK5XkET8/1RDADCQRPx/VUMAAJBE/P9WQwMAAAAA0I9E/H9VQ1Koj0T8/1RDAHCPRPz/VEMDAAAAzA6PRPz/VEMAwI5EfHZXQwDAjkT8f1pDAwAAAADAjkT8zFxDAPCORPyMXkMAII9E/P9fQwIAAAAAAAAAAAAAAAAAAAAAAAAAAACQRPz/ZkMCAAAAAAAAAAAAAAAAAAAAAAAAAADgkET8/19D\"],\"~:name\",\"svg-path\",\"~:width\",null,\"~:type\",\"~:path\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linecap\",\"round\",\"~:stroke-linejoin\",\"round\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1142,\"~:y\",212.99997181105346]],[\"^A\",[\"^ \",\"~:x\",1162,\"~:y\",212.99997181105346]],[\"^A\",[\"^ \",\"~:x\",1162,\"~:y\",230.99997181105346]],[\"^A\",[\"^ \",\"~:x\",1142,\"~:y\",230.99997181105346]]],\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e705944588\",\"~:proportion-lock\",false,\"~:stroke-cap-end\",\"round\",\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:constraints-v\",\"~:scale\",\"~:svg-transform\",[\"^ \",\"~:a\",1,\"~:b\",0,\"~:c\",0,\"~:d\",1,\"~:e\",0,\"~:f\",0],\"~:constraints-h\",\"^H\",\"~:id\",\"~u9299427e-8172-80bb-8007-90e71fba0f84\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f83\",\"~:svg-viewbox\",[\"^ \",\"~:y\",3,\"~:y1\",3,\"^9\",20,\"~:x\",2,\"~:x1\",2,\"~:y2\",21,\"~:x2\",22,\"~:height\",18],\"~:applied-tokens\",[\"^ \",\"~:stroke-color\",\"color.icon.default\"],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f83\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2,\"^T\",\"#ffffff\",\"~:stroke-opacity\",1]],\"~:x\",null,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1142,\"~:y\",212.99997181105346,\"^9\",20,\"^R\",18,\"^O\",1142,\"^N\",212.99997181105346,\"^Q\",1162,\"^P\",230.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^R\",null,\"~:flip-y\",null]]", "~u94eaebe4-addd-80d1-8007-79d508a9dc2f": "[\"~#shape\",[\"^ \",\"~:y\",612.000024916359,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 3\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",592.9999165534973,\"~:y\",612.000024916359]],[\"^J\",[\"^ \",\"~:x\",864.9999165534973,\"~:y\",612.000024916359]],[\"^J\",[\"^ \",\"~:x\",864.9999165534973,\"~:y\",692.0000127525132]],[\"^J\",[\"^ \",\"~:x\",592.9999165534973,\"~:y\",692.0000127525132]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",592.9999165534973,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",592.9999165534973,\"~:y\",612.000024916359,\"^D\",272,\"~:height\",79.9999878361541,\"~:x1\",592.9999165534973,\"~:y1\",612.000024916359,\"~:x2\",864.9999165534973,\"~:y2\",692.0000127525132]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.9999878361541,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\"]]]",
"~u94eaebe4-addd-80d1-8007-79d508aa2886": "[\"~#shape\",[\"^ \",\"~:y\",461.999988316858,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",302.0000081062317,\"~:y\",461.999988316858]],[\"^K\",[\"^ \",\"~:x\",368.0000081062317,\"~:y\",461.999988316858]],[\"^K\",[\"^ \",\"~:x\",368.0000081062317,\"~:y\",493.999988316858]],[\"^K\",[\"^ \",\"~:x\",302.0000081062317,\"~:y\",493.999988316858]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:strokes\",[],\"~:x\",302.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",302.0000081062317,\"~:y\",461.999988316858,\"^E\",66,\"~:height\",32,\"~:x1\",302.0000081062317,\"~:y1\",461.999988316858,\"~:x2\",368.0000081062317,\"~:y2\",493.999988316858]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508aa2887\"]]]", "~u94eaebe4-addd-80d1-8007-79d509800790": "[\"~#shape\",[\"^ \",\"~:y\",720.0000417226197,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",604.9998555183411,\"~:y\",720.0000417226197]],[\"^>\",[\"^ \",\"~:x\",684.9998555183411,\"~:y\",720.0000417226197]],[\"^>\",[\"^ \",\"~:x\",684.9998555183411,\"~:y\",800.0000417226197]],[\"^>\",[\"^ \",\"~:x\",604.9998555183411,\"~:y\",800.0000417226197]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800790\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:strokes\",[],\"~:x\",604.9998555183411,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",604.9998555183411,\"~:y\",720.0000417226197,\"^9\",80,\"~:height\",80,\"~:x1\",604.9998555183411,\"~:y1\",720.0000417226197,\"~:x2\",684.9998555183411,\"~:y2\",800.0000417226197]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e7059421c4": "[\"~#shape\",[\"^ \",\"~:y\",209.99999660658568,\"~:rx\",0,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:hide-in-viewer\",true,\"~:name\",\"heart\",\"~:width\",24,\"~:type\",\"~:frame\",\"~:svg-attrs\",[\"^ \",\"^8\",\"24\",\"~:height\",\"24\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",804,\"~:y\",209.99999660658568]],[\"^>\",[\"^ \",\"~:x\",828,\"~:y\",209.99999660658568]],[\"^>\",[\"^ \",\"~:x\",828,\"~:y\",233.99999660658568]],[\"^>\",[\"^ \",\"~:x\",804,\"~:y\",233.99999660658568]]],\"~:r2\",0,\"~:shape-ref\",\"~uc8b014fe-f285-8021-8007-8ea400bd9407\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e7059421c2\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e7059421c2\",\"~:strokes\",[],\"~:x\",804,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",804,\"~:y\",209.99999660658568,\"^8\",24,\"^<\",24,\"~:x1\",804,\"~:y1\",209.99999660658568,\"~:x2\",828,\"~:y2\",233.99999660658568]],\"~:fills\",[],\"~:flip-x\",null,\"~:ry\",0,\"^<\",24,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e7059421c5\",\"~u9299427e-8172-80bb-8007-90e7059421c6\"]]]", "~u94eaebe4-addd-80d1-8007-79d508a9dc30": "[\"~#shape\",[\"^ \",\"~:y\",612.0000188344361,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",604.9999775886536,\"~:y\",612.0000188344361]],[\"^;\",[\"^ \",\"~:x\",684.9999775886536,\"~:y\",612.0000188344361]],[\"^;\",[\"^ \",\"~:x\",684.9999775886536,\"~:y\",692.0000188344361]],[\"^;\",[\"^ \",\"~:x\",604.9999775886536,\"~:y\",692.0000188344361]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~:strokes\",[],\"~:x\",604.9999775886536,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",604.9999775886536,\"~:y\",612.0000188344361,\"^7\",80,\"~:height\",80,\"~:x1\",604.9999775886536,\"~:y1\",612.0000188344361,\"~:x2\",684.9999775886536,\"~:y2\",692.0000188344361]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508aa2885\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\"]]]",
"~u94eaebe4-addd-80d1-8007-79d508aa2887": "[\"~#shape\",[\"^ \",\"~:y\",469.999988316858,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",314.0000081062317,\"~:y\",469.999988316858]],[\"^K\",[\"^ \",\"~:x\",356.0000081062317,\"~:y\",469.999988316858]],[\"^K\",[\"^ \",\"~:x\",356.0000081062317,\"~:y\",485.999988316858]],[\"^K\",[\"^ \",\"~:x\",314.0000081062317,\"~:y\",485.999988316858]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2887\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\",\"~:strokes\",[],\"~:x\",314.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",314.0000081062317,\"~:y\",469.999988316858,\"^D\",42,\"~:height\",16,\"~:x1\",314.0000081062317,\"~:y1\",469.999988316858,\"~:x2\",356.0000081062317,\"~:y2\",485.999988316858]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508aa2888\"]]]", "~u94eaebe4-addd-80d1-8007-79d509800791": "[\"~#shape\",[\"^ \",\"~:y\",744.0000417226197,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",611.9998555183411,\"~:y\",744.0000417226197]],[\"^K\",[\"^ \",\"~:x\",677.9998555183411,\"~:y\",744.0000417226197]],[\"^K\",[\"^ \",\"~:x\",677.9998555183411,\"~:y\",776.0000417226197]],[\"^K\",[\"^ \",\"~:x\",611.9998555183411,\"~:y\",776.0000417226197]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800791\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:strokes\",[],\"~:x\",611.9998555183411,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",611.9998555183411,\"~:y\",744.0000417226197,\"^E\",66,\"~:height\",32,\"~:x1\",611.9998555183411,\"~:y1\",744.0000417226197,\"~:x2\",677.9998555183411,\"~:y2\",776.0000417226197]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d509800792\"]]]",
"~u9299427e-8172-80bb-8007-90e7059421c5": "[\"~#shape\",[\"^ \",\"~:y\",210.0000271241638,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:name\",\"base-background\",\"~:width\",24,\"~:type\",\"~:rect\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linejoin\",\"round\",\"~:stroke-linecap\",\"round\",\"~:id\",\"base-background\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",804,\"~:y\",210.0000271241638]],[\"^?\",[\"^ \",\"~:x\",828,\"~:y\",210.0000271241638]],[\"^?\",[\"^ \",\"~:x\",828,\"~:y\",234.0000271241638]],[\"^?\",[\"^ \",\"~:x\",804,\"~:y\",234.0000271241638]]],\"~:shape-ref\",\"~uc8b014fe-f285-8021-8007-8ea400bd9408\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:hidden\",true,\"^=\",\"~u9299427e-8172-80bb-8007-90e7059421c5\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:svg-viewbox\",[\"^ \",\"~:y\",0,\"~:y1\",0,\"^6\",24,\"~:x\",0,\"~:x1\",0,\"~:y2\",24,\"~:x2\",24,\"~:height\",24],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-color\",\"#ffffff\",\"~:stroke-opacity\",1,\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2]],\"~:x\",804,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",804,\"~:y\",210.0000271241638,\"^6\",24,\"^K\",24,\"^H\",804,\"^G\",210.0000271241638,\"^J\",828,\"^I\",234.0000271241638]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",24,\"~:flip-y\",null]]", "~u94eaebe4-addd-80d1-8007-79d509800792": "[\"~#shape\",[\"^ \",\"~:y\",752.0000417226197,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",623.9998555183411,\"~:y\",752.0000417226197]],[\"^K\",[\"^ \",\"~:x\",665.9998555183411,\"~:y\",752.0000417226197]],[\"^K\",[\"^ \",\"~:x\",665.9998555183411,\"~:y\",768.0000417226197]],[\"^K\",[\"^ \",\"~:x\",623.9998555183411,\"~:y\",768.0000417226197]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800792\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d509800791\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d509800791\",\"~:strokes\",[],\"~:x\",623.9998555183411,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",623.9998555183411,\"~:y\",752.0000417226197,\"^D\",42,\"~:height\",16,\"~:x1\",623.9998555183411,\"~:y1\",752.0000417226197,\"~:x2\",665.9998555183411,\"~:y2\",768.0000417226197]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d509800793\"]]]",
"~u9299427e-8172-80bb-8007-90e71cbb9fea": "[\"~#shape\",[\"^ \",\"~:y\",428.99998474121094,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"card-img / patinegro\",\"~:layout-align-items\",\"~:start\",\"~:width\",265,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",580,\"~:y\",428.99998474121094]],[\"^L\",[\"^ \",\"~:x\",845,\"~:y\",428.99998474121094]],[\"^L\",[\"^ \",\"~:x\",845,\"~:y\",606.99997875689]],[\"^L\",[\"^ \",\"~:x\",580,\"~:y\",606.99997875689]]],\"~:r2\",20,\"~:component-root\",true,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",20,\"~:layout-justify-content\",\"^E\",\"~:r1\",20,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71cbb9fea\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~u9299427e-8172-80bb-8007-90e7059a83e2\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",580,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",580,\"~:y\",428.99998474121094,\"^F\",265,\"~:height\",177.99999401567902,\"~:x1\",580,\"~:y1\",428.99998474121094,\"~:x2\",845,\"~:y2\",606.99997875689]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^1:\",177.99999401567902,\"~:component-file\",\"~u31fe2e21-73e7-80f3-8007-73894fb58240\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71cbc342d\",\"~u9299427e-8172-80bb-8007-90e71cbc342f\"]]]", "~u94eaebe4-addd-80d1-8007-79d509800793": "[\"~#shape\",[\"^ \",\"~:y\",753.0000417226199,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",625.9998555183411,\"~:y\",753.0000417226199]],[\"^S\",[\"^ \",\"~:x\",663.9998555183411,\"~:y\",753.0000417226199]],[\"^S\",[\"^ \",\"~:x\",663.9998555183411,\"~:y\",768.0000417226195]],[\"^S\",[\"^ \",\"~:x\",625.9998555183411,\"~:y\",768.0000417226199]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800793\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d509800792\",\"~:position-data\",[[\"^ \",\"~:y\",767.340087890625,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.93994140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",626.0299072265625,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.08001708984375,\"^L\",\"Label\"]],\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d509800792\",\"~:strokes\",[],\"~:x\",625.9998555183411,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",625.9998555183411,\"~:y\",753.0000417226199,\"^Q\",38,\"^11\",15,\"~:x1\",625.9998555183411,\"~:y1\",753.0000417226199,\"~:x2\",663.9998555183411,\"~:y2\",768.0000417226199]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]",
"~u94eaebe4-addd-80d1-8007-79d508aa2888": "[\"~#shape\",[\"^ \",\"~:y\",470.9999883168582,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",316.0000081062317,\"~:y\",470.9999883168582]],[\"^S\",[\"^ \",\"~:x\",354.0000081062317,\"~:y\",470.9999883168582]],[\"^S\",[\"^ \",\"~:x\",354.0000081062317,\"~:y\",485.99998831685775]],[\"^S\",[\"^ \",\"~:x\",316.0000081062317,\"~:y\",485.9999883168582]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2888\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2887\",\"~:position-data\",[[\"^ \",\"~:y\",485.3399963378906,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.94000244140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",316.0299987792969,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.079986572265625,\"^L\",\"Label\"]],\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2887\",\"~:strokes\",[],\"~:x\",316.0000081062317,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",316.0000081062317,\"~:y\",470.9999883168582,\"^Q\",38,\"^11\",15,\"~:x1\",316.0000081062317,\"~:y1\",470.9999883168582,\"~:x2\",354.0000081062317,\"~:y2\",485.9999883168582]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]", "~u77c71dba-32ee-804c-8007-736561cf8584": "[\"~#shape\",[\"^ \",\"~:y\",396.00000357564704,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",396.00000357564704]],[\"^;\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",396.00000357564704]],[\"^;\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",476.00000357564704]],[\"^;\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",476.00000357564704]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cf857f\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cf857f\",\"~:strokes\",[],\"~:x\",688.9999775886536,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",396.00000357564704,\"^7\",80,\"~:height\",80,\"~:x1\",688.9999775886536,\"~:y1\",396.00000357564704,\"~:x2\",768.9999775886536,\"~:y2\",476.00000357564704]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cff457\",\"~u77c71dba-32ee-804c-8007-736561cff458\"]]]",
"~u77c71dba-32ee-804c-8007-736561cff45a": "[\"~#shape\",[\"^ \",\"~:y\",255.00000357564727,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",400.0000081062317,\"~:y\",255.00000357564727]],[\"^S\",[\"^ \",\"~:x\",438.0000081062317,\"~:y\",255.00000357564727]],[\"^S\",[\"^ \",\"~:x\",438.0000081062317,\"~:y\",270.0000035756468]],[\"^S\",[\"^ \",\"~:x\",400.0000081062317,\"~:y\",270.00000357564727]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff45a\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cff459\",\"~:position-data\",[[\"^ \",\"~:y\",269.3399963378906,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.94000244140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",400.0299987792969,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.080001831054688,\"^L\",\"Label\"]],\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cff459\",\"~:strokes\",[],\"~:x\",400.0000081062317,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",400.0000081062317,\"~:y\",255.00000357564727,\"^Q\",38,\"^11\",15,\"~:x1\",400.0000081062317,\"~:y1\",255.00000357564727,\"~:x2\",438.0000081062317,\"~:y2\",270.00000357564727]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]", "~u94eaebe4-addd-80d1-8007-79d5055d6859": "[\"~#shape\",[\"^ \",\"~:y\",504.00000202817546,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 2\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",592.9999775886536,\"~:y\",504.00000202817546]],[\"^J\",[\"^ \",\"~:x\",864.9999775886536,\"~:y\",504.00000202817546]],[\"^J\",[\"^ \",\"~:x\",864.9999775886536,\"~:y\",583.9999898643296]],[\"^J\",[\"^ \",\"~:x\",592.9999775886536,\"~:y\",583.9999898643296]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:row-reverse\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",592.9999775886536,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",592.9999775886536,\"~:y\",504.00000202817546,\"^D\",272,\"~:height\",79.9999878361541,\"~:x1\",592.9999775886536,\"~:y1\",504.00000202817546,\"~:x2\",864.9999775886536,\"~:y2\",583.9999898643296]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.9999878361541,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685a\"]]]",
"~u77c71dba-32ee-804c-8007-736561cff459": "[\"~#shape\",[\"^ \",\"~:y\",254.00000357564704,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",398.0000081062317,\"~:y\",254.00000357564704]],[\"^K\",[\"^ \",\"~:x\",440.0000081062317,\"~:y\",254.00000357564704]],[\"^K\",[\"^ \",\"~:x\",440.0000081062317,\"~:y\",270.00000357564704]],[\"^K\",[\"^ \",\"~:x\",398.0000081062317,\"~:y\",270.00000357564704]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff459\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cff458\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cff458\",\"~:strokes\",[],\"~:x\",398.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",398.0000081062317,\"~:y\",254.00000357564704,\"^D\",42,\"~:height\",16,\"~:x1\",398.0000081062317,\"~:y1\",254.00000357564704,\"~:x2\",440.0000081062317,\"~:y2\",270.00000357564704]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cff45a\"]]]", "~u94eaebe4-addd-80d1-8007-79d5055d685a": "[\"~#shape\",[\"^ \",\"~:y\",503.9999959462525,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",503.9999959462525]],[\"^;\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",503.9999959462525]],[\"^;\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",583.9999959462525]],[\"^;\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",583.9999959462525]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~:strokes\",[],\"~:x\",688.9999775886536,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",503.9999959462525,\"^7\",80,\"~:height\",80,\"~:x1\",688.9999775886536,\"~:y1\",503.9999959462525,\"~:x2\",768.9999775886536,\"~:y2\",583.9999959462525]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685b\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\"]]]",
"~u9299427e-8172-80bb-8007-90e705944588": "[\"~#shape\",[\"^ \",\"~:y\",null,\"~:stroke-cap-start\",\"round\",\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:content\",[\"~#penpot/path-data\",\"~bAQAAAAAAAAAAAAAAAAAAAAAAAAAAwE1E/P9fQwMAAABcH05E/IleQwCATkT8yVxDAIBORPx/WkMDAAAAAIBORHx2V0No4k1E/P9UQwAgTUT8/1RDAwAAAFyvTET8/1RDAGBMRPx/VUMAAExE/P9WQwMAAAAAoEtE/H9VQ6RQS0T8/1RDAOBKRPz/VEMDAAAAmB1KRPz/VEMAgElEfHZXQwCASUT8f1pDAwAAAACASUT8zFxDAOBJRPyMXkMAQEpE/P9fQwIAAAAAAAAAAAAAAAAAAAAAAAAAAABMRPz/ZkMCAAAAAAAAAAAAAAAAAAAAAAAAAADATUT8/19D\"],\"~:name\",\"svg-path\",\"~:width\",null,\"~:type\",\"~:path\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linecap\",\"round\",\"~:stroke-linejoin\",\"round\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",806,\"~:y\",212.99997181105346]],[\"^A\",[\"^ \",\"~:x\",826,\"~:y\",212.99997181105346]],[\"^A\",[\"^ \",\"~:x\",826,\"~:y\",230.99997181105346]],[\"^A\",[\"^ \",\"~:x\",806,\"~:y\",230.99997181105346]]],\"~:shape-ref\",\"~uc8b014fe-f285-8021-8007-8ea518570b0f\",\"~:proportion-lock\",false,\"~:stroke-cap-end\",\"round\",\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:constraints-v\",\"~:scale\",\"~:svg-transform\",[\"^ \",\"~:a\",1,\"~:b\",0,\"~:c\",0,\"~:d\",1,\"~:e\",0,\"~:f\",0],\"~:constraints-h\",\"^H\",\"~:id\",\"~u9299427e-8172-80bb-8007-90e705944588\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e7059421c6\",\"~:svg-viewbox\",[\"^ \",\"~:y\",3,\"~:y1\",3,\"^9\",20,\"~:x\",2,\"~:x1\",2,\"~:y2\",21,\"~:x2\",22,\"~:height\",18],\"~:applied-tokens\",[\"^ \",\"~:stroke-color\",\"color.icon.default\"],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e7059421c6\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2,\"^T\",\"#ffffff\",\"~:stroke-opacity\",1]],\"~:x\",null,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",806,\"~:y\",212.99997181105346,\"^9\",20,\"^R\",18,\"^O\",806,\"^N\",212.99997181105346,\"^Q\",826,\"^P\",230.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^R\",null,\"~:flip-y\",null]]", "~u94eaebe4-addd-80d1-8007-79d5055d685b": "[\"~#shape\",[\"^ \",\"~:y\",503.9999959462525,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",503.9999959462525]],[\"^>\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",503.9999959462525]],[\"^>\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",583.9999959462525]],[\"^>\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",583.9999959462525]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685b\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:strokes\",[],\"~:x\",688.9999775886536,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",503.9999959462525,\"^9\",80,\"~:height\",80,\"~:x1\",688.9999775886536,\"~:y1\",503.9999959462525,\"~:x2\",768.9999775886536,\"~:y2\",583.9999959462525]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]",
"~u77c71dba-32ee-804c-8007-736561cff458": "[\"~#shape\",[\"^ \",\"~:y\",246.00000357564704,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",386.0000081062317,\"~:y\",246.00000357564704]],[\"^K\",[\"^ \",\"~:x\",452.0000081062317,\"~:y\",246.00000357564704]],[\"^K\",[\"^ \",\"~:x\",452.0000081062317,\"~:y\",278.00000357564704]],[\"^K\",[\"^ \",\"~:x\",386.0000081062317,\"~:y\",278.00000357564704]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff458\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:strokes\",[],\"~:x\",386.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",386.0000081062317,\"~:y\",246.00000357564704,\"^E\",66,\"~:height\",32,\"~:x1\",386.0000081062317,\"~:y1\",246.00000357564704,\"~:x2\",452.0000081062317,\"~:y2\",278.00000357564704]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cff459\"]]]", "~u94eaebe4-addd-80d1-8007-79d5055d685c": "[\"~#shape\",[\"^ \",\"~:y\",527.9999959462525,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",695.9999775886536,\"~:y\",527.9999959462525]],[\"^K\",[\"^ \",\"~:x\",761.9999775886536,\"~:y\",527.9999959462525]],[\"^K\",[\"^ \",\"~:x\",761.9999775886536,\"~:y\",559.9999959462525]],[\"^K\",[\"^ \",\"~:x\",695.9999775886536,\"~:y\",559.9999959462525]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:strokes\",[],\"~:x\",695.9999775886536,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",695.9999775886536,\"~:y\",527.9999959462525,\"^E\",66,\"~:height\",32,\"~:x1\",695.9999775886536,\"~:y1\",527.9999959462525,\"~:x2\",761.9999775886536,\"~:y2\",559.9999959462525]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685d\"]]]",
"~u9299427e-8172-80bb-8007-90e72469bf8e": "[\"~#shape\",[\"^ \",\"~:y\",444.00002998518676,\"~:hide-fill-on-export\",false,\"~:layout-item-absolute\",true,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"add-favorites\",\"~:layout-align-items\",\"~:center\",\"~:width\",48,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1128,\"~:y\",444.00002998518676]],[\"^M\",[\"^ \",\"~:x\",1176,\"~:y\",444.00002998518676]],[\"^M\",[\"^ \",\"~:x\",1176,\"~:y\",492.00002426314086]],[\"^M\",[\"^ \",\"~:x\",1128,\"~:y\",492.00002426314086]]],\"~:r2\",50,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c2\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",50,\"~:layout-justify-content\",\"^F\",\"~:r1\",50,\"~:id\",\"~u9299427e-8172-80bb-8007-90e72469bf8e\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8c\",\"~:layout-flex-dir\",\"~:row\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"color.bg.default\"],\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea447a0bc30\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8c\",\"~:strokes\",[],\"~:x\",1128,\"~:proportion\",1,\"~:r4\",50,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1128,\"~:y\",444.00002998518676,\"^G\",48,\"~:height\",47.9999942779541,\"~:x1\",1128,\"~:y1\",444.00002998518676,\"~:x2\",1176,\"~:y2\",492.00002426314086]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.3]],\"~:flip-x\",null,\"^1<\",47.9999942779541,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e72469bf90\"]]]", "~u94eaebe4-addd-80d1-8007-79d5055d685d": "[\"~#shape\",[\"^ \",\"~:y\",535.9999959462525,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",707.9999775886536,\"~:y\",535.9999959462525]],[\"^K\",[\"^ \",\"~:x\",749.9999775886536,\"~:y\",535.9999959462525]],[\"^K\",[\"^ \",\"~:x\",749.9999775886536,\"~:y\",551.9999959462525]],[\"^K\",[\"^ \",\"~:x\",707.9999775886536,\"~:y\",551.9999959462525]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685d\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\",\"~:strokes\",[],\"~:x\",707.9999775886536,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",707.9999775886536,\"~:y\",535.9999959462525,\"^D\",42,\"~:height\",16,\"~:x1\",707.9999775886536,\"~:y1\",535.9999959462525,\"~:x2\",749.9999775886536,\"~:y2\",551.9999959462525]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685e\"]]]",
"~u9299427e-8172-80bb-8007-90e71cbc342e": "[\"~#shape\",[\"^ \",\"~:y\",429.000012591785,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"patinegro\",\"~:width\",264.80230943863717,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",579.9999793759137,\"~:y\",429.000012591785]],[\"^9\",[\"^ \",\"~:x\",844.8022888145506,\"~:y\",429.000012591785]],[\"^9\",[\"^ \",\"~:x\",844.8022888145506,\"~:y\",625.1131514739925]],[\"^9\",[\"^ \",\"~:x\",579.9999793759137,\"~:y\",625.1131514739925]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c3\",\"~:proportion-lock\",true,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71cbc342e\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71cbc342d\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71cbc342d\",\"~:strokes\",[],\"~:x\",579.9999793759134,\"~:proportion\",1.3487940630797774,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",579.9999793759134,\"~:y\",429.000012591785,\"^5\",264.80230943863717,\"~:height\",196.11313888220752,\"~:x1\",579.9999793759134,\"~:y1\",429.000012591785,\"~:x2\",844.8022888145506,\"~:y2\",625.1131514739925]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#b73d3d\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^I\",196.11313888220752,\"~:flip-y\",null]]", "~u94eaebe4-addd-80d1-8007-79d5055d685e": "[\"~#shape\",[\"^ \",\"~:y\",536.9999959462527,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",709.9999775886536,\"~:y\",536.9999959462527]],[\"^S\",[\"^ \",\"~:x\",747.9999775886536,\"~:y\",536.9999959462527]],[\"^S\",[\"^ \",\"~:x\",747.9999775886536,\"~:y\",551.9999959462523]],[\"^S\",[\"^ \",\"~:x\",709.9999775886536,\"~:y\",551.9999959462527]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685e\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685d\",\"~:position-data\",[[\"^ \",\"~:y\",551.3400268554688,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.93994140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",710.030029296875,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.08001708984375,\"^L\",\"Label\"]],\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685d\",\"~:strokes\",[],\"~:x\",709.9999775886536,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",709.9999775886536,\"~:y\",536.9999959462527,\"^Q\",38,\"^11\",15,\"~:x1\",709.9999775886536,\"~:y1\",536.9999959462527,\"~:x2\",747.9999775886536,\"~:y2\",551.9999959462527]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]"
"~u77c71dba-32ee-804c-8007-736561cf857f": "[\"~#shape\",[\"^ \",\"~:y\",221.99999439878093,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 1\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",221.99999439878093]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",221.99999439878093]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",301.999982234935]],[\"^J\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",301.999982234935]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cf857f\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",283.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",221.99999439878093,\"^D\",272,\"~:height\",79.99998783615405,\"~:x1\",283.0000081062317,\"~:y1\",221.99999439878093,\"~:x2\",555.0000081062317,\"~:y2\",301.999982234935]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.99998783615405,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cf8584\"]]]",
"~u9299427e-8172-80bb-8007-90e72469bf8f": "[\"~#shape\",[\"^ \",\"~:y\",438.000012591785,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"patinegro\",\"~:width\",264.80230943863717,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",915.9999793759137,\"~:y\",438.000012591785]],[\"^9\",[\"^ \",\"~:x\",1180.8022888145506,\"~:y\",438.000012591785]],[\"^9\",[\"^ \",\"~:x\",1180.8022888145506,\"~:y\",634.1131514739925]],[\"^9\",[\"^ \",\"~:x\",915.9999793759137,\"~:y\",634.1131514739925]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c3\",\"~:proportion-lock\",true,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e72469bf8f\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8d\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8d\",\"~:strokes\",[],\"~:x\",915.9999793759134,\"~:proportion\",1.3487940630797774,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",915.9999793759134,\"~:y\",438.000012591785,\"^5\",264.80230943863717,\"~:height\",196.11313888220752,\"~:x1\",915.9999793759134,\"~:y1\",438.000012591785,\"~:x2\",1180.8022888145506,\"~:y2\",634.1131514739925]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#b73d3d\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^I\",196.11313888220752,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71cbc342f": "[\"~#shape\",[\"^ \",\"~:y\",435.00002998518676,\"~:hide-fill-on-export\",false,\"~:layout-item-absolute\",true,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"add-favorites\",\"~:layout-align-items\",\"~:center\",\"~:width\",48,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:touched\",[\"~#set\",[\"~:layout-item-z-index\"]],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",792,\"~:y\",435.00002998518676]],[\"^P\",[\"^ \",\"~:x\",840,\"~:y\",435.00002998518676]],[\"^P\",[\"^ \",\"~:x\",840,\"~:y\",483.00002426314086]],[\"^P\",[\"^ \",\"~:x\",792,\"~:y\",483.00002426314086]]],\"~:r2\",50,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c2\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",50,\"~:layout-justify-content\",\"^F\",\"~:r1\",50,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71cbc342f\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71cbb9fea\",\"~:layout-flex-dir\",\"~:row\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"color.bg.default\"],\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea447a0bc30\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71cbb9fea\",\"~:strokes\",[],\"~:x\",792,\"~:proportion\",1,\"~:r4\",50,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",792,\"~:y\",435.00002998518676,\"^G\",48,\"~:height\",47.9999942779541,\"~:x1\",792,\"~:y1\",435.00002998518676,\"~:x2\",840,\"~:y2\",483.00002426314086]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.3]],\"~:flip-x\",null,\"^1?\",47.9999942779541,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"^N\",1,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71cbc3430\"]]]",
"~u94eaebe4-addd-80d1-8007-79d50980078e": "[\"~#shape\",[\"^ \",\"~:y\",546.0000478045426,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 4\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",546.0000478045426]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",546.0000478045426]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",626.0000356406968]],[\"^J\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",626.0000356406968]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column-reverse\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",283.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",546.0000478045426,\"^D\",272,\"~:height\",79.9999878361541,\"~:x1\",283.0000081062317,\"~:y1\",546.0000478045426,\"~:x2\",555.0000081062317,\"~:y2\",626.0000356406968]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.9999878361541,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d50980078f\"]]]",
"~u9299427e-8172-80bb-8007-90e72469bf8c": "[\"~#shape\",[\"^ \",\"~:y\",437.99998474121094,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"card-img / patinegro\",\"~:layout-align-items\",\"~:start\",\"~:width\",265,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",916,\"~:y\",437.99998474121094]],[\"^L\",[\"^ \",\"~:x\",1181,\"~:y\",437.99998474121094]],[\"^L\",[\"^ \",\"~:x\",1181,\"~:y\",615.99997875689]],[\"^L\",[\"^ \",\"~:x\",916,\"~:y\",615.99997875689]]],\"~:r2\",20,\"~:component-root\",true,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",20,\"~:layout-justify-content\",\"^E\",\"~:r1\",20,\"~:id\",\"~u9299427e-8172-80bb-8007-90e72469bf8c\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~u9299427e-8172-80bb-8007-90e7059a83e2\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",916,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",916,\"~:y\",437.99998474121094,\"^F\",265,\"~:height\",177.99999401567902,\"~:x1\",916,\"~:y1\",437.99998474121094,\"~:x2\",1181,\"~:y2\",615.99997875689]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^1:\",177.99999401567902,\"~:component-file\",\"~u31fe2e21-73e7-80f3-8007-73894fb58240\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e72469bf8d\",\"~u9299427e-8172-80bb-8007-90e72469bf8e\"]]]",
"~u94eaebe4-addd-80d1-8007-79d50980078f": "[\"~#shape\",[\"^ \",\"~:y\",545.9999806874634,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",545.9999806874634]],[\"^;\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",545.9999806874634]],[\"^;\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",625.9999806874634]],[\"^;\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",625.9999806874634]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~:strokes\",[],\"~:x\",295.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",545.9999806874634,\"^7\",80,\"~:height\",80,\"~:x1\",295.0000081062317,\"~:y1\",545.9999806874634,\"~:x2\",375.0000081062317,\"~:y2\",625.9999806874634]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d509800790\",\"~u94eaebe4-addd-80d1-8007-79d509800791\"]]]",
"~u9299427e-8172-80bb-8007-90e72469bf8d": "[\"~#shape\",[\"^ \",\"~:y\",437.99999475401955,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"img-city\",\"~:width\",265,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",916,\"~:y\",437.9999947540198]],[\"^;\",[\"^ \",\"~:x\",1181,\"~:y\",437.9999947540198]],[\"^;\",[\"^ \",\"~:x\",1181,\"~:y\",615.9899634401968]],[\"^;\",[\"^ \",\"~:x\",916,\"~:y\",615.9899634401968]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c1\",\"~:layout-item-h-sizing\",\"~:fill\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:layout-item-v-sizing\",\"^?\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e72469bf8d\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8c\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8c\",\"~:strokes\",[],\"~:x\",916,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",916,\"~:y\",437.99999475401955,\"^7\",265,\"~:height\",177.989968686177,\"~:x1\",916,\"~:y1\",437.99999475401955,\"~:x2\",1181,\"~:y2\",615.9899634401966]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^N\",177.989968686177,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e72469bf8f\"]]]",
"~u9299427e-8172-80bb-8007-90e71cbc342d": "[\"~#shape\",[\"^ \",\"~:y\",428.99999475401955,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"img-city\",\"~:width\",265,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",580,\"~:y\",428.9999947540198]],[\"^;\",[\"^ \",\"~:x\",845,\"~:y\",428.9999947540198]],[\"^;\",[\"^ \",\"~:x\",845,\"~:y\",606.9899634401968]],[\"^;\",[\"^ \",\"~:x\",580,\"~:y\",606.9899634401968]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c1\",\"~:layout-item-h-sizing\",\"~:fill\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:layout-item-v-sizing\",\"^?\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71cbc342d\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71cbb9fea\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71cbb9fea\",\"~:strokes\",[],\"~:x\",580,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",580,\"~:y\",428.99999475401955,\"^7\",265,\"~:height\",177.989968686177,\"~:x1\",580,\"~:y1\",428.99999475401955,\"~:x2\",845,\"~:y2\",606.9899634401966]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^N\",177.989968686177,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71cbc342e\"]]]",
"~u94eaebe4-addd-80d1-8007-79d508a9dc2f": "[\"~#shape\",[\"^ \",\"~:y\",437.9999943987809,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 3\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",437.9999943987809]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",437.9999943987809]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",517.999982234935]],[\"^J\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",517.999982234935]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",283.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",437.9999943987809,\"^D\",272,\"~:height\",79.9999878361541,\"~:x1\",283.0000081062317,\"~:y1\",437.9999943987809,\"~:x2\",555.0000081062317,\"~:y2\",517.999982234935]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.9999878361541,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\"]]]",
"~u94eaebe4-addd-80d1-8007-79d509800790": "[\"~#shape\",[\"^ \",\"~:y\",546.0000417226197,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",546.0000417226197]],[\"^>\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",546.0000417226197]],[\"^>\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",626.0000417226197]],[\"^>\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",626.0000417226197]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800790\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:strokes\",[],\"~:x\",295.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",546.0000417226197,\"^9\",80,\"~:height\",80,\"~:x1\",295.0000081062317,\"~:y1\",546.0000417226197,\"~:x2\",375.0000081062317,\"~:y2\",626.0000417226197]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e72469bf92": "[\"~#shape\",[\"^ \",\"~:y\",458.99997181105346,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"svg-path\",\"~:width\",20,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1142,\"~:y\",458.99997181105346]],[\"^;\",[\"^ \",\"~:x\",1162,\"~:y\",458.99997181105346]],[\"^;\",[\"^ \",\"~:x\",1162,\"~:y\",476.99997181105346]],[\"^;\",[\"^ \",\"~:x\",1142,\"~:y\",476.99997181105346]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c6\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e72469bf92\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e72469bf90\",\"~:applied-tokens\",[\"^ \"],\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea4f64a1c9b\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e72469bf90\",\"~:strokes\",[],\"~:x\",1142,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1142,\"~:y\",458.99997181105346,\"^7\",20,\"~:height\",18,\"~:x1\",1142,\"~:y1\",458.99997181105346,\"~:x2\",1162,\"~:y2\",476.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^N\",18,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e72469bf93\"]]]",
"~u9299427e-8172-80bb-8007-90e71cbc3432": "[\"~#shape\",[\"^ \",\"~:y\",449.99997181105346,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"svg-path\",\"~:width\",20,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",806,\"~:y\",449.99997181105346]],[\"^;\",[\"^ \",\"~:x\",826,\"~:y\",449.99997181105346]],[\"^;\",[\"^ \",\"~:x\",826,\"~:y\",467.99997181105346]],[\"^;\",[\"^ \",\"~:x\",806,\"~:y\",467.99997181105346]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c6\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71cbc3432\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71cbc3430\",\"~:applied-tokens\",[\"^ \"],\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea4f64a1c9b\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71cbc3430\",\"~:strokes\",[],\"~:x\",806,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",806,\"~:y\",449.99997181105346,\"^7\",20,\"~:height\",18,\"~:x1\",806,\"~:y1\",449.99997181105346,\"~:x2\",826,\"~:y2\",467.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^N\",18,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71cbc3433\"]]]",
"~u94eaebe4-addd-80d1-8007-79d508a9dc30": "[\"~#shape\",[\"^ \",\"~:y\",437.999988316858,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",437.999988316858]],[\"^;\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",437.999988316858]],[\"^;\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",517.999988316858]],[\"^;\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",517.999988316858]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~:strokes\",[],\"~:x\",295.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",437.999988316858,\"^7\",80,\"~:height\",80,\"~:x1\",295.0000081062317,\"~:y1\",437.999988316858,\"~:x2\",375.0000081062317,\"~:y2\",517.999988316858]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508aa2885\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\"]]]",
"~u94eaebe4-addd-80d1-8007-79d509800791": "[\"~#shape\",[\"^ \",\"~:y\",570.0000417226197,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",302.0000081062317,\"~:y\",570.0000417226197]],[\"^K\",[\"^ \",\"~:x\",368.0000081062317,\"~:y\",570.0000417226197]],[\"^K\",[\"^ \",\"~:x\",368.0000081062317,\"~:y\",602.0000417226197]],[\"^K\",[\"^ \",\"~:x\",302.0000081062317,\"~:y\",602.0000417226197]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800791\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:strokes\",[],\"~:x\",302.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",302.0000081062317,\"~:y\",570.0000417226197,\"^E\",66,\"~:height\",32,\"~:x1\",302.0000081062317,\"~:y1\",570.0000417226197,\"~:x2\",368.0000081062317,\"~:y2\",602.0000417226197]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d509800792\"]]]",
"~u9299427e-8172-80bb-8007-90e72469bf93": "[\"~#shape\",[\"^ \",\"~:y\",null,\"~:stroke-cap-start\",\"round\",\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:content\",[\"~#penpot/path-data\",\"~bAQAAAAAAAAAAAAAAAAAAAAAAAAAA4JBE/v/qQwMAAACuD5FE/kTqQwBAkUT+ZOlDAECRRP4/6EMDAAAAAECRRD675kM08ZBE/n/lQwCQkET+f+VDAwAAAK5XkET+f+VDADCQRP6/5UMAAJBE/n/mQwMAAAAA0I9E/r/lQ1Koj0T+f+VDAHCPRP5/5UMDAAAAzA6PRP5/5UMAwI5EPrvmQwDAjkT+P+hDAwAAAADAjkR+ZulDAPCORH5G6kMAII9E/v/qQwIAAAAAAAAAAAAAAAAAAAAAAAAAAACQRP5/7kMCAAAAAAAAAAAAAAAAAAAAAAAAAADgkET+/+pD\"],\"~:name\",\"svg-path\",\"~:width\",null,\"~:type\",\"~:path\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linecap\",\"round\",\"~:stroke-linejoin\",\"round\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1142,\"~:y\",458.99997181105346]],[\"^A\",[\"^ \",\"~:x\",1162,\"~:y\",458.99997181105346]],[\"^A\",[\"^ \",\"~:x\",1162,\"~:y\",476.99997181105346]],[\"^A\",[\"^ \",\"~:x\",1142,\"~:y\",476.99997181105346]]],\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e705944588\",\"~:proportion-lock\",false,\"~:stroke-cap-end\",\"round\",\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:constraints-v\",\"~:scale\",\"~:svg-transform\",[\"^ \",\"~:a\",1,\"~:b\",0,\"~:c\",0,\"~:d\",1,\"~:e\",0,\"~:f\",0],\"~:constraints-h\",\"^H\",\"~:id\",\"~u9299427e-8172-80bb-8007-90e72469bf93\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e72469bf92\",\"~:svg-viewbox\",[\"^ \",\"~:y\",3,\"~:y1\",3,\"^9\",20,\"~:x\",2,\"~:x1\",2,\"~:y2\",21,\"~:x2\",22,\"~:height\",18],\"~:applied-tokens\",[\"^ \",\"~:stroke-color\",\"color.icon.default\"],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e72469bf92\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2,\"^T\",\"#ffffff\",\"~:stroke-opacity\",1]],\"~:x\",null,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1142,\"~:y\",458.99997181105346,\"^9\",20,\"^R\",18,\"^O\",1142,\"^N\",458.99997181105346,\"^Q\",1162,\"^P\",476.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^R\",null,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71cbc3433": "[\"~#shape\",[\"^ \",\"~:y\",null,\"~:stroke-cap-start\",\"round\",\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:content\",[\"~#penpot/path-data\",\"~bAQAAAAAAAAAAAAAAAAAAAAAAAAAAwE1E/n/mQwMAAABcH05E/sTlQwCATkT+5ORDAIBORP6/40MDAAAAAIBORD474kNo4k1E/v/gQwAgTUT+/+BDAwAAAFyvTET+/+BDAGBMRP4/4UMAAExE/v/hQwMAAAAAoEtE/j/hQ6RQS0T+/+BDAOBKRP7/4EMDAAAAmB1KRP7/4EMAgElEPjviQwCASUT+v+NDAwAAAACASUR+5uRDAOBJRH7G5UMAQEpE/n/mQwIAAAAAAAAAAAAAAAAAAAAAAAAAAABMRP7/6UMCAAAAAAAAAAAAAAAAAAAAAAAAAADATUT+f+ZD\"],\"~:name\",\"svg-path\",\"~:width\",null,\"~:type\",\"~:path\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linecap\",\"round\",\"~:stroke-linejoin\",\"round\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",806,\"~:y\",449.99997181105346]],[\"^A\",[\"^ \",\"~:x\",826,\"~:y\",449.99997181105346]],[\"^A\",[\"^ \",\"~:x\",826,\"~:y\",467.99997181105346]],[\"^A\",[\"^ \",\"~:x\",806,\"~:y\",467.99997181105346]]],\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e705944588\",\"~:proportion-lock\",false,\"~:stroke-cap-end\",\"round\",\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:constraints-v\",\"~:scale\",\"~:svg-transform\",[\"^ \",\"~:a\",1,\"~:b\",0,\"~:c\",0,\"~:d\",1,\"~:e\",0,\"~:f\",0],\"~:constraints-h\",\"^H\",\"~:id\",\"~u9299427e-8172-80bb-8007-90e71cbc3433\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71cbc3432\",\"~:svg-viewbox\",[\"^ \",\"~:y\",3,\"~:y1\",3,\"^9\",20,\"~:x\",2,\"~:x1\",2,\"~:y2\",21,\"~:x2\",22,\"~:height\",18],\"~:applied-tokens\",[\"^ \",\"~:stroke-color\",\"color.icon.default\"],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71cbc3432\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2,\"^T\",\"#ffffff\",\"~:stroke-opacity\",1]],\"~:x\",null,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",806,\"~:y\",449.99997181105346,\"^9\",20,\"^R\",18,\"^O\",806,\"^N\",449.99997181105346,\"^Q\",826,\"^P\",467.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^R\",null,\"~:flip-y\",null]]",
"~u94eaebe4-addd-80d1-8007-79d509800792": "[\"~#shape\",[\"^ \",\"~:y\",578.0000417226197,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",314.0000081062317,\"~:y\",578.0000417226197]],[\"^K\",[\"^ \",\"~:x\",356.0000081062317,\"~:y\",578.0000417226197]],[\"^K\",[\"^ \",\"~:x\",356.0000081062317,\"~:y\",594.0000417226197]],[\"^K\",[\"^ \",\"~:x\",314.0000081062317,\"~:y\",594.0000417226197]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800792\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d509800791\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d509800791\",\"~:strokes\",[],\"~:x\",314.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",314.0000081062317,\"~:y\",578.0000417226197,\"^D\",42,\"~:height\",16,\"~:x1\",314.0000081062317,\"~:y1\",578.0000417226197,\"~:x2\",356.0000081062317,\"~:y2\",594.0000417226197]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d509800793\"]]]",
"~u9299427e-8172-80bb-8007-90e72469bf90": "[\"~#shape\",[\"^ \",\"~:y\",455.9999966065857,\"~:rx\",0,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:hide-in-viewer\",true,\"~:name\",\"heart\",\"~:width\",24,\"~:type\",\"~:frame\",\"~:svg-attrs\",[\"^ \",\"^8\",\"24\",\"~:height\",\"24\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1140,\"~:y\",455.9999966065857]],[\"^>\",[\"^ \",\"~:x\",1164,\"~:y\",455.9999966065857]],[\"^>\",[\"^ \",\"~:x\",1164,\"~:y\",479.9999966065857]],[\"^>\",[\"^ \",\"~:x\",1140,\"~:y\",479.9999966065857]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e72469bf90\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8e\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8e\",\"~:strokes\",[],\"~:x\",1140,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1140,\"~:y\",455.9999966065857,\"^8\",24,\"^<\",24,\"~:x1\",1140,\"~:y1\",455.9999966065857,\"~:x2\",1164,\"~:y2\",479.9999966065857]],\"~:fills\",[],\"~:flip-x\",null,\"~:ry\",0,\"^<\",24,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e72469bf91\",\"~u9299427e-8172-80bb-8007-90e72469bf92\"]]]",
"~u9299427e-8172-80bb-8007-90e71cbc3430": "[\"~#shape\",[\"^ \",\"~:y\",446.9999966065857,\"~:rx\",0,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:hide-in-viewer\",true,\"~:name\",\"heart\",\"~:width\",24,\"~:type\",\"~:frame\",\"~:svg-attrs\",[\"^ \",\"^8\",\"24\",\"~:height\",\"24\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",804,\"~:y\",446.9999966065857]],[\"^>\",[\"^ \",\"~:x\",828,\"~:y\",446.9999966065857]],[\"^>\",[\"^ \",\"~:x\",828,\"~:y\",470.9999966065857]],[\"^>\",[\"^ \",\"~:x\",804,\"~:y\",470.9999966065857]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71cbc3430\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71cbc342f\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71cbc342f\",\"~:strokes\",[],\"~:x\",804,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",804,\"~:y\",446.9999966065857,\"^8\",24,\"^<\",24,\"~:x1\",804,\"~:y1\",446.9999966065857,\"~:x2\",828,\"~:y2\",470.9999966065857]],\"~:fills\",[],\"~:flip-x\",null,\"~:ry\",0,\"^<\",24,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71cbc3431\",\"~u9299427e-8172-80bb-8007-90e71cbc3432\"]]]",
"~u94eaebe4-addd-80d1-8007-79d509800793": "[\"~#shape\",[\"^ \",\"~:y\",579.0000417226199,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",316.0000081062317,\"~:y\",579.0000417226199]],[\"^S\",[\"^ \",\"~:x\",354.0000081062317,\"~:y\",579.0000417226199]],[\"^S\",[\"^ \",\"~:x\",354.0000081062317,\"~:y\",594.0000417226195]],[\"^S\",[\"^ \",\"~:x\",316.0000081062317,\"~:y\",594.0000417226199]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800793\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d509800792\",\"~:position-data\",[[\"^ \",\"~:y\",593.340087890625,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.94000244140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",316.0299987792969,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.08001708984375,\"^L\",\"Label\"]],\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d509800792\",\"~:strokes\",[],\"~:x\",316.0000081062317,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",316.0000081062317,\"~:y\",579.0000417226199,\"^Q\",38,\"^11\",15,\"~:x1\",316.0000081062317,\"~:y1\",579.0000417226199,\"~:x2\",354.0000081062317,\"~:y2\",594.0000417226199]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e72469bf91": "[\"~#shape\",[\"^ \",\"~:y\",456.0000271241638,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:name\",\"base-background\",\"~:width\",24,\"~:type\",\"~:rect\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linejoin\",\"round\",\"~:stroke-linecap\",\"round\",\"~:id\",\"base-background\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1140,\"~:y\",456.0000271241638]],[\"^?\",[\"^ \",\"~:x\",1164,\"~:y\",456.0000271241638]],[\"^?\",[\"^ \",\"~:x\",1164,\"~:y\",480.0000271241638]],[\"^?\",[\"^ \",\"~:x\",1140,\"~:y\",480.0000271241638]]],\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c5\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:hidden\",true,\"^=\",\"~u9299427e-8172-80bb-8007-90e72469bf91\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e72469bf90\",\"~:svg-viewbox\",[\"^ \",\"~:y\",0,\"~:y1\",0,\"^6\",24,\"~:x\",0,\"~:x1\",0,\"~:y2\",24,\"~:x2\",24,\"~:height\",24],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e72469bf90\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-color\",\"#ffffff\",\"~:stroke-opacity\",1,\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2]],\"~:x\",1140,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1140,\"~:y\",456.0000271241638,\"^6\",24,\"^K\",24,\"^H\",1140,\"^G\",456.0000271241638,\"^J\",1164,\"^I\",480.0000271241638]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",24,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71cbc3431": "[\"~#shape\",[\"^ \",\"~:y\",447.0000271241638,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:name\",\"base-background\",\"~:width\",24,\"~:type\",\"~:rect\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linejoin\",\"round\",\"~:stroke-linecap\",\"round\",\"~:id\",\"base-background\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",804,\"~:y\",447.0000271241638]],[\"^?\",[\"^ \",\"~:x\",828,\"~:y\",447.0000271241638]],[\"^?\",[\"^ \",\"~:x\",828,\"~:y\",471.0000271241638]],[\"^?\",[\"^ \",\"~:x\",804,\"~:y\",471.0000271241638]]],\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c5\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:hidden\",true,\"^=\",\"~u9299427e-8172-80bb-8007-90e71cbc3431\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71cbc3430\",\"~:svg-viewbox\",[\"^ \",\"~:y\",0,\"~:y1\",0,\"^6\",24,\"~:x\",0,\"~:x1\",0,\"~:y2\",24,\"~:x2\",24,\"~:height\",24],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71cbc3430\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-color\",\"#ffffff\",\"~:stroke-opacity\",1,\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2]],\"~:x\",804,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",804,\"~:y\",447.0000271241638,\"^6\",24,\"^K\",24,\"^H\",804,\"^G\",447.0000271241638,\"^J\",828,\"^I\",471.0000271241638]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",24,\"~:flip-y\",null]]",
"~u77c71dba-32ee-804c-8007-736561cf8584": "[\"~#shape\",[\"^ \",\"~:y\",222.00000357564704,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",222.00000357564704]],[\"^;\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",222.00000357564704]],[\"^;\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",302.00000357564704]],[\"^;\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",302.00000357564704]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cf857f\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cf857f\",\"~:strokes\",[],\"~:x\",379.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",222.00000357564704,\"^7\",80,\"~:height\",80,\"~:x1\",379.0000081062317,\"~:y1\",222.00000357564704,\"~:x2\",459.0000081062317,\"~:y2\",302.00000357564704]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cff457\",\"~u77c71dba-32ee-804c-8007-736561cff458\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d6859": "[\"~#shape\",[\"^ \",\"~:y\",330.00000202817546,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 2\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",330.00000202817546]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",330.00000202817546]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",409.99998986432956]],[\"^J\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",409.99998986432956]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:row-reverse\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",283.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",330.00000202817546,\"^D\",272,\"~:height\",79.9999878361541,\"~:x1\",283.0000081062317,\"~:y1\",330.00000202817546,\"~:x2\",555.0000081062317,\"~:y2\",409.99998986432956]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.9999878361541,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685a\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685a": "[\"~#shape\",[\"^ \",\"~:y\",329.9999959462525,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",329.9999959462525]],[\"^;\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",329.9999959462525]],[\"^;\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",409.9999959462525]],[\"^;\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",409.9999959462525]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~:strokes\",[],\"~:x\",379.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",329.9999959462525,\"^7\",80,\"~:height\",80,\"~:x1\",379.0000081062317,\"~:y1\",329.9999959462525,\"~:x2\",459.0000081062317,\"~:y2\",409.9999959462525]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685b\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685b": "[\"~#shape\",[\"^ \",\"~:y\",329.9999959462525,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",329.9999959462525]],[\"^>\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",329.9999959462525]],[\"^>\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",409.9999959462525]],[\"^>\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",409.9999959462525]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685b\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:strokes\",[],\"~:x\",379.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",329.9999959462525,\"^9\",80,\"~:height\",80,\"~:x1\",379.0000081062317,\"~:y1\",329.9999959462525,\"~:x2\",459.0000081062317,\"~:y2\",409.9999959462525]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71fba0f7e": "[\"~#shape\",[\"^ \",\"~:y\",191.99999475401955,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"img-city\",\"~:width\",265,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",916,\"~:y\",191.99999475401978]],[\"^;\",[\"^ \",\"~:x\",1181,\"~:y\",191.99999475401978]],[\"^;\",[\"^ \",\"~:x\",1181,\"~:y\",369.9899634401968]],[\"^;\",[\"^ \",\"~:x\",916,\"~:y\",369.9899634401968]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c1\",\"~:layout-item-h-sizing\",\"~:fill\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:layout-item-v-sizing\",\"^?\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7e\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7d\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7d\",\"~:strokes\",[],\"~:x\",916,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",916,\"~:y\",191.99999475401955,\"^7\",265,\"~:height\",177.989968686177,\"~:x1\",916,\"~:y1\",191.99999475401955,\"~:x2\",1181,\"~:y2\",369.98996344019656]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^N\",177.989968686177,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71fba0f80\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685c": "[\"~#shape\",[\"^ \",\"~:y\",353.9999959462525,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",386.0000081062317,\"~:y\",353.9999959462525]],[\"^K\",[\"^ \",\"~:x\",452.0000081062317,\"~:y\",353.9999959462525]],[\"^K\",[\"^ \",\"~:x\",452.0000081062317,\"~:y\",385.9999959462525]],[\"^K\",[\"^ \",\"~:x\",386.0000081062317,\"~:y\",385.9999959462525]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:strokes\",[],\"~:x\",386.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",386.0000081062317,\"~:y\",353.9999959462525,\"^E\",66,\"~:height\",32,\"~:x1\",386.0000081062317,\"~:y1\",353.9999959462525,\"~:x2\",452.0000081062317,\"~:y2\",385.9999959462525]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685d\"]]]",
"~u9299427e-8172-80bb-8007-90e71fba0f7f": "[\"~#shape\",[\"^ \",\"~:y\",198.00002998518676,\"~:hide-fill-on-export\",false,\"~:layout-item-absolute\",true,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"add-favorites\",\"~:layout-align-items\",\"~:center\",\"~:width\",48,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:touched\",[\"~#set\",[\"~:layout-item-z-index\"]],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1128,\"~:y\",198.00002998518676]],[\"^P\",[\"^ \",\"~:x\",1176,\"~:y\",198.00002998518676]],[\"^P\",[\"^ \",\"~:x\",1176,\"~:y\",246.00002426314086]],[\"^P\",[\"^ \",\"~:x\",1128,\"~:y\",246.00002426314086]]],\"~:r2\",50,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c2\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",50,\"~:layout-justify-content\",\"^F\",\"~:r1\",50,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7f\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7d\",\"~:layout-flex-dir\",\"~:row\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"color.bg.default\"],\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea447a0bc30\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7d\",\"~:strokes\",[],\"~:x\",1128,\"~:proportion\",1,\"~:r4\",50,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1128,\"~:y\",198.00002998518676,\"^G\",48,\"~:height\",47.9999942779541,\"~:x1\",1128,\"~:y1\",198.00002998518676,\"~:x2\",1176,\"~:y2\",246.00002426314086]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.3]],\"~:flip-x\",null,\"^1?\",47.9999942779541,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"^N\",0,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71fba0f81\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685d": "[\"~#shape\",[\"^ \",\"~:y\",361.9999959462525,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",398.0000081062317,\"~:y\",361.9999959462525]],[\"^K\",[\"^ \",\"~:x\",440.0000081062317,\"~:y\",361.9999959462525]],[\"^K\",[\"^ \",\"~:x\",440.0000081062317,\"~:y\",377.9999959462525]],[\"^K\",[\"^ \",\"~:x\",398.0000081062317,\"~:y\",377.9999959462525]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685d\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\",\"~:strokes\",[],\"~:x\",398.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",398.0000081062317,\"~:y\",361.9999959462525,\"^D\",42,\"~:height\",16,\"~:x1\",398.0000081062317,\"~:y1\",361.9999959462525,\"~:x2\",440.0000081062317,\"~:y2\",377.9999959462525]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685e\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685e": "[\"~#shape\",[\"^ \",\"~:y\",362.99999594625274,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",400.0000081062317,\"~:y\",362.99999594625274]],[\"^S\",[\"^ \",\"~:x\",438.0000081062317,\"~:y\",362.99999594625274]],[\"^S\",[\"^ \",\"~:x\",438.0000081062317,\"~:y\",377.9999959462523]],[\"^S\",[\"^ \",\"~:x\",400.0000081062317,\"~:y\",377.99999594625274]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685e\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685d\",\"~:position-data\",[[\"^ \",\"~:y\",377.3399963378906,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.94000244140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",400.0299987792969,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.079986572265625,\"^L\",\"Label\"]],\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685d\",\"~:strokes\",[],\"~:x\",400.0000081062317,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",400.0000081062317,\"~:y\",362.99999594625274,\"^Q\",38,\"^11\",15,\"~:x1\",400.0000081062317,\"~:y1\",362.99999594625274,\"~:x2\",438.0000081062317,\"~:y2\",377.99999594625274]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71fba0f7d": "[\"~#shape\",[\"^ \",\"~:y\",191.99998474121094,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"card-img / patinegro\",\"~:layout-align-items\",\"~:start\",\"~:width\",265,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",916,\"~:y\",191.99998474121094]],[\"^L\",[\"^ \",\"~:x\",1181,\"~:y\",191.99998474121094]],[\"^L\",[\"^ \",\"~:x\",1181,\"~:y\",369.99997875688996]],[\"^L\",[\"^ \",\"~:x\",916,\"~:y\",369.99997875688996]]],\"~:r2\",20,\"~:component-root\",true,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",20,\"~:layout-justify-content\",\"^E\",\"~:r1\",20,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7d\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~u9299427e-8172-80bb-8007-90e7059a83e2\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",916,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",916,\"~:y\",191.99998474121094,\"^F\",265,\"~:height\",177.99999401567902,\"~:x1\",916,\"~:y1\",191.99998474121094,\"~:x2\",1181,\"~:y2\",369.99997875688996]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^1:\",177.99999401567902,\"~:component-file\",\"~u31fe2e21-73e7-80f3-8007-73894fb58240\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71fba0f7e\",\"~u9299427e-8172-80bb-8007-90e71fba0f7f\"]]]"
} }
} }
} }
@@ -182,16 +150,6 @@
"~:options": { "~:options": {
"~:components-v2": true, "~:components-v2": true,
"~:base-font-size": "16px" "~:base-font-size": "16px"
},
"~:components": {
"~u9299427e-8172-80bb-8007-90e7059a83e2": {
"~:id": "~u9299427e-8172-80bb-8007-90e7059a83e2",
"~:name": "patinegro",
"~:path": "card-img",
"~:modified-at": "~m1770978606872",
"~:main-instance-id": "~u9299427e-8172-80bb-8007-90e7059421c0",
"~:main-instance-page": "~u02e9633d-4ce7-80da-8007-736558496fa8"
}
} }
} }
} }

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,137 +0,0 @@
{
"~:features": {
"~#set": [
"fdata/path-data",
"plugins/runtime",
"design-tokens/v1",
"variants/v1",
"layout/grid",
"styles/v2",
"fdata/objects-map",
"render-wasm/v1",
"components/v2",
"fdata/shape-data-type"
]
},
"~:team-id": "~u99e49e93-362f-80ef-8007-3450ea52c9a4",
"~:permissions": {
"~:type": "~:membership",
"~:is-owner": true,
"~:is-admin": true,
"~:can-edit": true,
"~:can-read": true,
"~:is-logged": true
},
"~:has-media-trimmed": false,
"~:comment-thread-seqn": 0,
"~:name": "BUG 13305",
"~:revn": 11,
"~:modified-at": "~m1770911234124",
"~:vern": 0,
"~:id": "~u9666e946-78e8-8111-8007-8fe5f0f454bf",
"~:is-shared": false,
"~:migrations": {
"~#ordered-set": [
"legacy-2",
"legacy-3",
"legacy-5",
"legacy-6",
"legacy-7",
"legacy-8",
"legacy-9",
"legacy-10",
"legacy-11",
"legacy-12",
"legacy-13",
"legacy-14",
"legacy-16",
"legacy-17",
"legacy-18",
"legacy-19",
"legacy-25",
"legacy-26",
"legacy-27",
"legacy-28",
"legacy-29",
"legacy-31",
"legacy-32",
"legacy-33",
"legacy-34",
"legacy-36",
"legacy-37",
"legacy-38",
"legacy-39",
"legacy-40",
"legacy-41",
"legacy-42",
"legacy-43",
"legacy-44",
"legacy-45",
"legacy-46",
"legacy-47",
"legacy-48",
"legacy-49",
"legacy-50",
"legacy-51",
"legacy-52",
"legacy-53",
"legacy-54",
"legacy-55",
"legacy-56",
"legacy-57",
"legacy-59",
"legacy-62",
"legacy-65",
"legacy-66",
"legacy-67",
"0001-remove-tokens-from-groups",
"0002-normalize-bool-content-v2",
"0002-clean-shape-interactions",
"0003-fix-root-shape",
"0003-convert-path-content-v2",
"0005-deprecate-image-type",
"0006-fix-old-texts-fills",
"0008-fix-library-colors-v4",
"0009-clean-library-colors",
"0009-add-partial-text-touched-flags",
"0010-fix-swap-slots-pointing-non-existent-shapes",
"0011-fix-invalid-text-touched-flags",
"0012-fix-position-data",
"0013-fix-component-path",
"0013-clear-invalid-strokes-and-fills",
"0014-fix-tokens-lib-duplicate-ids",
"0014-clear-components-nil-objects",
"0015-fix-text-attrs-blank-strings",
"0015-clean-shadow-color",
"0016-copy-fills-from-position-data-to-text-node"
]
},
"~:version": 67,
"~:project-id": "~ucd8f7672-e5d1-810f-8007-87e124eda82a",
"~:created-at": "~m1770911129553",
"~:backend": "legacy-db",
"~:data": {
"~:pages": [
"~u9666e946-78e8-8111-8007-8fe5f0f49ac6"
],
"~:pages-index": {
"~u9666e946-78e8-8111-8007-8fe5f0f49ac6": {
"~:objects": {
"~#penpot/objects-map/v2": {
"~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^H\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a\"]]]",
"~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a": "[\"~#shape\",[\"^ \",\"~:y\",99.99999499320984,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Board\",\"~:width\",511.99998180389287,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",99.9999820137034,\"~:y\",99.99999499320984]],[\"^=\",[\"^ \",\"~:x\",611.9999638175963,\"~:y\",99.99999499320984]],[\"^=\",[\"^ \",\"~:x\",611.9999638175963,\"~:y\",611.9999695949548]],[\"^=\",[\"^ \",\"~:x\",99.9999820137034,\"~:y\",611.9999695949548]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",99.9999820137034,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",99.9999820137034,\"~:y\",99.99999499320984,\"^9\",511.99998180389287,\"~:height\",511.99997460174495,\"~:x1\",99.9999820137034,\"~:y1\",99.99999499320984,\"~:x2\",611.9999638175963,\"~:y2\",611.9999695949548]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^K\",511.99997460174495,\"~:flip-y\",null,\"~:shapes\",[\"~u3edd6127-ced7-80c6-8007-8fe60306baa7\",\"~u3edd6127-ced7-80c6-8007-8fe61479065a\"]]]",
"~u3edd6127-ced7-80c6-8007-8fe60306baa7": "[\"~#shape\",[\"^ \",\"~:y\",109.99999433755875,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",100.00000357627869,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",109.99998164176941,\"~:y\",109.99999433755875]],[\"^<\",[\"^ \",\"~:x\",209.9999852180481,\"~:y\",109.99999433755875]],[\"^<\",[\"^ \",\"~:x\",209.9999852180481,\"~:y\",209.9999930858612]],[\"^<\",[\"^ \",\"~:x\",109.99998164176941,\"~:y\",209.9999930858612]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:r1\",0,\"~:id\",\"~u3edd6127-ced7-80c6-8007-8fe60306baa7\",\"~:parent-id\",\"~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a\",\"~:frame-id\",\"~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a\",\"~:strokes\",[],\"~:x\",109.99998164176941,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",109.99998164176941,\"~:y\",109.99999433755875,\"^8\",100.00000357627869,\"~:height\",99.99999874830246,\"~:x1\",109.99998164176941,\"~:y1\",109.99999433755875,\"~:x2\",209.9999852180481,\"~:y2\",209.9999930858612]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^N\",99.99999874830246,\"~:flip-y\",null]]",
"~u3edd6127-ced7-80c6-8007-8fe61479065a": "[\"~#shape\",[\"^ \",\"~:y\",483.9999952316284,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Ellipse\",\"~:width\",256.000000834465,\"~:type\",\"~:circle\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",483.99998211860657,\"~:y\",483.9999952316284]],[\"^<\",[\"^ \",\"~:x\",739.9999829530716,\"~:y\",483.9999952316284]],[\"^<\",[\"^ \",\"~:x\",739.9999829530716,\"~:y\",739.9999876022339]],[\"^<\",[\"^ \",\"~:x\",483.99998211860657,\"~:y\",739.9999876022339]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u3edd6127-ced7-80c6-8007-8fe61479065a\",\"~:parent-id\",\"~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a\",\"~:frame-id\",\"~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a\",\"~:strokes\",[],\"~:x\",483.99998211860657,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",483.99998211860657,\"~:y\",483.9999952316284,\"^8\",256.000000834465,\"~:height\",255.99999237060547,\"~:x1\",483.99998211860657,\"~:y1\",483.9999952316284,\"~:x2\",739.9999829530716,\"~:y2\",739.9999876022339]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^J\",255.99999237060547,\"~:flip-y\",null]]"
}
},
"~:id": "~u9666e946-78e8-8111-8007-8fe5f0f49ac6",
"~:name": "Page 1"
}
},
"~:id": "~u9666e946-78e8-8111-8007-8fe5f0f454bf",
"~:options": {
"~:components-v2": true,
"~:base-font-size": "16px"
}
}
}

View File

@@ -1,22 +0,0 @@
{
"~:file-id": "~u52c4e771-3853-8190-8007-9506c70e8100",
"~:id": "~u4173a29d-4020-80b4-8007-96527ba9d8af",
"~:created-at": "~m1771342236330",
"~:modified-at": "~m1771342236330",
"~:type": "fragment",
"~:backend": "db",
"~:data": {
"~:id": "~uecb0cfd0-0f0b-81f7-8007-950628f9665b",
"~:name": "Page 1",
"~:objects": {
"~#penpot/objects-map/v2": {
"~ude9c6736-45ce-80a1-8007-950643da554d": "[\"~#shape\",[\"^ \",\"~:y\",383.99998939037323,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"R1\",\"~:width\",74,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",831.999992787838,\"~:y\",383.99998939037323]],[\"^<\",[\"^ \",\"~:x\",905.999992787838,\"~:y\",383.99998939037323]],[\"^<\",[\"^ \",\"~:x\",905.999992787838,\"~:y\",429.99998664855957]],[\"^<\",[\"^ \",\"~:x\",831.999992787838,\"~:y\",429.99998664855957]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~uecb0cfd0-0f0b-81f7-8007-950628f9665b\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~ude9c6736-45ce-80a1-8007-950643da554d\",\"~:parent-id\",\"~ude9c6736-45ce-80a1-8007-95063a202e52\",\"~:frame-id\",\"~ude9c6736-45ce-80a1-8007-95063a202e52\",\"~:strokes\",[],\"~:x\",831.999992787838,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",831.999992787838,\"~:y\",383.99998939037323,\"^8\",74,\"~:height\",45.99999725818634,\"~:x1\",831.999992787838,\"~:y1\",383.99998939037323,\"~:x2\",905.999992787838,\"~:y2\",429.99998664855957]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^K\",45.99999725818634,\"~:flip-y\",null]]",
"~ude9c6736-45ce-80a1-8007-95065b4599ea": "[\"~#shape\",[\"^ \",\"~:y\",439.999969256975,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"R2\",\"~:width\",300.00007388362076,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",832.0000015918991,\"~:y\",439.99996925697496]],[\"^<\",[\"^ \",\"~:x\",1132.00007547552,\"~:y\",439.99996925697496]],[\"^<\",[\"^ \",\"~:x\",1132.00007547552,\"~:y\",589.9999658711585]],[\"^<\",[\"^ \",\"~:x\",832.0000015918991,\"~:y\",589.9999658711585]]],\"~:r2\",0,\"~:layout-item-h-sizing\",\"~:fix\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~uecb0cfd0-0f0b-81f7-8007-950628f9665b\",\"~:layout-item-v-sizing\",\"^?\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~ude9c6736-45ce-80a1-8007-95065b4599ea\",\"~:parent-id\",\"~ude9c6736-45ce-80a1-8007-95063a202e52\",\"~:frame-id\",\"~ude9c6736-45ce-80a1-8007-95063a202e52\",\"~:strokes\",[],\"~:x\",832.0000015918993,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",832.0000015918993,\"~:y\",439.999969256975,\"^8\",300.00007388362076,\"~:height\",149.9999966141835,\"~:x1\",832.0000015918993,\"~:y1\",439.999969256975,\"~:x2\",1132.0000754755201,\"~:y2\",589.9999658711586]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^N\",149.9999966141835,\"~:flip-y\",null]]",
"~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~uecb0cfd0-0f0b-81f7-8007-950628f9665b\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^I\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~ude9c6736-45ce-80a1-8007-95062aa41d6b\"]]]",
"~ude9c6736-45ce-80a1-8007-95062aa41d6b": "[\"~#shape\",[\"^ \",\"~:y\",342.0000208153068,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",false,\"~:name\",\"A\",\"~:layout-align-items\",\"~:start\",\"~:width\",392.9999889135361,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",787.9999763965607,\"~:y\",342.0000208153068]],[\"^L\",[\"^ \",\"~:x\",1180.9999653100967,\"~:y\",342.0000208153068]],[\"^L\",[\"^ \",\"~:x\",1180.9999653100967,\"~:y\",704.000018450968]],[\"^L\",[\"^ \",\"~:x\",787.9999763965607,\"~:y\",704.000018450968]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~uecb0cfd0-0f0b-81f7-8007-950628f9665b\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:r3\",0,\"~:layout-justify-content\",\"^E\",\"~:r1\",0,\"~:id\",\"~ude9c6736-45ce-80a1-8007-95062aa41d6b\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",787.9999763965607,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",787.9999763965607,\"~:y\",342.0000208153068,\"^F\",392.9999889135361,\"~:height\",361.9999976356612,\"~:x1\",787.9999763965607,\"~:y1\",342.0000208153068,\"~:x2\",1180.9999653100967,\"~:y2\",704.000018450968]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^19\",361.9999976356612,\"~:flip-y\",null,\"~:shapes\",[\"~ude9c6736-45ce-80a1-8007-95062fafbb88\"]]]",
"~ude9c6736-45ce-80a1-8007-95063a202e52": "[\"~#shape\",[\"^ \",\"~:y\",374.00001145409465,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",10,\"~:p2\",10,\"~:p3\",10,\"~:p4\",10],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"C\",\"~:layout-align-items\",\"~:start\",\"~:width\",320.00009969013945,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",821.9999915631233,\"~:y\",374.0000114540946]],[\"^L\",[\"^ \",\"~:x\",1142.0000912532628,\"~:y\",374.0000114540946]],[\"^L\",[\"^ \",\"~:x\",1142.0000912532628,\"~:y\",600.0000518384436]],[\"^L\",[\"^ \",\"~:x\",821.9999915631233,\"~:y\",600.0000518384436]]],\"~:r2\",0,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",10,\"~:column-gap\",0],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~uecb0cfd0-0f0b-81f7-8007-950628f9665b\",\"~:layout-item-v-sizing\",\"^O\",\"~:r3\",0,\"~:layout-justify-content\",\"^E\",\"~:r1\",0,\"~:id\",\"~ude9c6736-45ce-80a1-8007-95063a202e52\",\"~:parent-id\",\"~ude9c6736-45ce-80a1-8007-95062fafbb88\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~ude9c6736-45ce-80a1-8007-95062fafbb88\",\"~:strokes\",[[\"^ \",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-style\",\"~:solid\",\"~:stroke-color\",\"#000000\",\"~:stroke-opacity\",1,\"~:stroke-width\",1]],\"~:x\",821.9999915631233,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",821.9999915631233,\"~:y\",374.00001145409465,\"^F\",320.00009969013945,\"~:height\",226.000040384349,\"~:x1\",821.9999915631233,\"~:y1\",374.00001145409465,\"~:x2\",1142.0000912532628,\"~:y2\",600.0000518384436]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^1A\",226.000040384349,\"~:flip-y\",null,\"~:shapes\",[\"~ude9c6736-45ce-80a1-8007-95065b4599ea\",\"~ude9c6736-45ce-80a1-8007-950643da554d\"]]]",
"~ude9c6736-45ce-80a1-8007-95062fafbb88": "[\"~#shape\",[\"^ \",\"~:y\",342.0000083402533,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",31.999953508377075,\"~:p2\",34.000026052944804,\"~:p3\",31.999953508377075,\"~:p4\",34.000026052944804],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"B\",\"~:layout-align-items\",\"~:start\",\"~:width\",392.9999979687366,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",788.0000295450811,\"~:y\",342.00000834025326]],[\"^L\",[\"^ \",\"~:x\",1181.0000275138177,\"~:y\",342.00000834025326]],[\"^L\",[\"^ \",\"~:x\",1181.0000275138177,\"~:y\",631.9999659712]],[\"^L\",[\"^ \",\"~:x\",788.0000295450811,\"~:y\",631.9999659712]]],\"~:r2\",0,\"~:layout-item-h-sizing\",\"~:fill\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~uecb0cfd0-0f0b-81f7-8007-950628f9665b\",\"~:layout-item-v-sizing\",\"~:auto\",\"~:r3\",0,\"~:layout-justify-content\",\"^E\",\"~:r1\",0,\"~:id\",\"~ude9c6736-45ce-80a1-8007-95062fafbb88\",\"~:parent-id\",\"~ude9c6736-45ce-80a1-8007-95062aa41d6b\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~ude9c6736-45ce-80a1-8007-95062aa41d6b\",\"~:strokes\",[[\"^ \",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-style\",\"~:solid\",\"~:stroke-color\",\"#000000\",\"~:stroke-opacity\",1,\"~:stroke-width\",1]],\"~:x\",788.0000295450811,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",788.0000295450811,\"~:y\",342.0000083402533,\"^F\",392.9999979687366,\"~:height\",289.99995763094677,\"~:x1\",788.0000295450811,\"~:y1\",342.0000083402533,\"~:x2\",1181.0000275138177,\"~:y2\",631.9999659712]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^1B\",289.99995763094677,\"~:flip-y\",null,\"~:shapes\",[\"~ude9c6736-45ce-80a1-8007-95063a202e52\"]]]"
}
}
}
}

View File

@@ -1,131 +0,0 @@
{
"~:features": {
"~#set": [
"fdata/path-data",
"design-tokens/v1",
"variants/v1",
"layout/grid",
"fdata/pointer-map",
"fdata/objects-map",
"components/v2",
"fdata/shape-data-type"
]
},
"~:team-id": "~ud715d0a5-a44e-8056-8005-a79999e18b64",
"~:permissions": {
"~:type": "~:membership",
"~:is-owner": true,
"~:is-admin": true,
"~:can-edit": true,
"~:can-read": true,
"~:is-logged": true
},
"~:has-media-trimmed": false,
"~:comment-thread-seqn": 0,
"~:name": "bug flex",
"~:revn": 33,
"~:modified-at": "~m1771342236324",
"~:vern": 0,
"~:id": "~u52c4e771-3853-8190-8007-9506c70e8100",
"~:is-shared": false,
"~:migrations": {
"~#ordered-set": [
"legacy-2",
"legacy-3",
"legacy-5",
"legacy-6",
"legacy-7",
"legacy-8",
"legacy-9",
"legacy-10",
"legacy-11",
"legacy-12",
"legacy-13",
"legacy-14",
"legacy-16",
"legacy-17",
"legacy-18",
"legacy-19",
"legacy-25",
"legacy-26",
"legacy-27",
"legacy-28",
"legacy-29",
"legacy-31",
"legacy-32",
"legacy-33",
"legacy-34",
"legacy-36",
"legacy-37",
"legacy-38",
"legacy-39",
"legacy-40",
"legacy-41",
"legacy-42",
"legacy-43",
"legacy-44",
"legacy-45",
"legacy-46",
"legacy-47",
"legacy-48",
"legacy-49",
"legacy-50",
"legacy-51",
"legacy-52",
"legacy-53",
"legacy-54",
"legacy-55",
"legacy-56",
"legacy-57",
"legacy-59",
"legacy-62",
"legacy-65",
"legacy-66",
"legacy-67",
"0001-remove-tokens-from-groups",
"0002-normalize-bool-content-v2",
"0002-clean-shape-interactions",
"0003-fix-root-shape",
"0003-convert-path-content-v2",
"0005-deprecate-image-type",
"0006-fix-old-texts-fills",
"0008-fix-library-colors-v4",
"0009-clean-library-colors",
"0009-add-partial-text-touched-flags",
"0010-fix-swap-slots-pointing-non-existent-shapes",
"0011-fix-invalid-text-touched-flags",
"0012-fix-position-data",
"0013-fix-component-path",
"0013-clear-invalid-strokes-and-fills",
"0014-fix-tokens-lib-duplicate-ids",
"0014-clear-components-nil-objects",
"0015-fix-text-attrs-blank-strings",
"0015-clean-shadow-color",
"0016-copy-fills-from-position-data-to-text-node"
]
},
"~:version": 67,
"~:project-id": "~u76eab896-accf-81a5-8007-2b264ebe7817",
"~:created-at": "~m1771255281717",
"~:backend": "legacy-db",
"~:data": {
"~:pages": [
"~uecb0cfd0-0f0b-81f7-8007-950628f9665b"
],
"~:pages-index": {
"~uecb0cfd0-0f0b-81f7-8007-950628f9665b": {
"~#penpot/pointer": [
"~u4173a29d-4020-80b4-8007-96527ba9d8af",
{
"~:created-at": "~m1771342236327"
}
]
}
},
"~:id": "~u52c4e771-3853-8190-8007-9506c70e8100",
"~:options": {
"~:components-v2": true,
"~:base-font-size": "16px"
}
}
}

View File

@@ -1,136 +0,0 @@
{
"~:features": {
"~#set": [
"fdata/path-data",
"plugins/runtime",
"design-tokens/v1",
"variants/v1",
"layout/grid",
"styles/v2",
"fdata/objects-map",
"render-wasm/v1",
"components/v2",
"fdata/shape-data-type"
]
},
"~:team-id": "~u99e49e93-362f-80ef-8007-3450ea52c9a4",
"~:permissions": {
"~:type": "~:membership",
"~:is-owner": true,
"~:is-admin": true,
"~:can-edit": true,
"~:can-read": true,
"~:is-logged": true
},
"~:has-media-trimmed": false,
"~:comment-thread-seqn": 0,
"~:name": "BUG 13385",
"~:revn": 3,
"~:modified-at": "~m1771254407745",
"~:vern": 1173241426,
"~:id": "~u3ea49ce0-9d99-8197-8007-950361d24e43",
"~:is-shared": false,
"~:migrations": {
"~#ordered-set": [
"legacy-2",
"legacy-3",
"legacy-5",
"legacy-6",
"legacy-7",
"legacy-8",
"legacy-9",
"legacy-10",
"legacy-11",
"legacy-12",
"legacy-13",
"legacy-14",
"legacy-16",
"legacy-17",
"legacy-18",
"legacy-19",
"legacy-25",
"legacy-26",
"legacy-27",
"legacy-28",
"legacy-29",
"legacy-31",
"legacy-32",
"legacy-33",
"legacy-34",
"legacy-36",
"legacy-37",
"legacy-38",
"legacy-39",
"legacy-40",
"legacy-41",
"legacy-42",
"legacy-43",
"legacy-44",
"legacy-45",
"legacy-46",
"legacy-47",
"legacy-48",
"legacy-49",
"legacy-50",
"legacy-51",
"legacy-52",
"legacy-53",
"legacy-54",
"legacy-55",
"legacy-56",
"legacy-57",
"legacy-59",
"legacy-62",
"legacy-65",
"legacy-66",
"legacy-67",
"0001-remove-tokens-from-groups",
"0002-normalize-bool-content-v2",
"0002-clean-shape-interactions",
"0003-fix-root-shape",
"0003-convert-path-content-v2",
"0005-deprecate-image-type",
"0006-fix-old-texts-fills",
"0008-fix-library-colors-v4",
"0009-clean-library-colors",
"0009-add-partial-text-touched-flags",
"0010-fix-swap-slots-pointing-non-existent-shapes",
"0011-fix-invalid-text-touched-flags",
"0012-fix-position-data",
"0013-fix-component-path",
"0013-clear-invalid-strokes-and-fills",
"0014-fix-tokens-lib-duplicate-ids",
"0014-clear-components-nil-objects",
"0015-fix-text-attrs-blank-strings",
"0015-clean-shadow-color",
"0016-copy-fills-from-position-data-to-text-node"
]
},
"~:version": 67,
"~:project-id": "~ucd8f7672-e5d1-810f-8007-87e124eda82a",
"~:created-at": "~m1771254391625",
"~:backend": "legacy-db",
"~:data": {
"~:pages": [
"~u3ea49ce0-9d99-8197-8007-950361d24e44"
],
"~:pages-index": {
"~u3ea49ce0-9d99-8197-8007-950361d24e44": {
"~:objects": {
"~#penpot/objects-map/v2": {
"~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^H\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~ue0e81bed-4dc2-805c-8007-95036a4a3131\",\"~ue0e81bed-4dc2-805c-8007-95036c27428b\"]]]",
"~ue0e81bed-4dc2-805c-8007-95036a4a3131": "[\"~#shape\",[\"^ \",\"~:y\",252,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",177,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",156,\"~:y\",252]],[\"^<\",[\"^ \",\"~:x\",333,\"~:y\",252]],[\"^<\",[\"^ \",\"~:x\",333,\"~:y\",389]],[\"^<\",[\"^ \",\"~:x\",156,\"~:y\",389]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~ue0e81bed-4dc2-805c-8007-95036a4a3131\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",156,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",156,\"~:y\",252,\"^8\",177,\"~:height\",137,\"~:x1\",156,\"~:y1\",252,\"~:x2\",333,\"~:y2\",389]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^J\",137,\"~:flip-y\",null]]",
"~ue0e81bed-4dc2-805c-8007-95036c27428b": "[\"~#shape\",[\"^ \",\"~:y\",250,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Ellipse\",\"~:width\",148,\"~:type\",\"~:circle\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",362,\"~:y\",250]],[\"^<\",[\"^ \",\"~:x\",510,\"~:y\",250]],[\"^<\",[\"^ \",\"~:x\",510,\"~:y\",389]],[\"^<\",[\"^ \",\"~:x\",362,\"~:y\",389]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~ue0e81bed-4dc2-805c-8007-95036c27428b\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",362,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",362,\"~:y\",250,\"^8\",148,\"~:height\",139,\"~:x1\",362,\"~:y1\",250,\"~:x2\",510,\"~:y2\",389]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^F\",139,\"~:flip-y\",null]]"
}
},
"~:id": "~u3ea49ce0-9d99-8197-8007-950361d24e44",
"~:name": "Page 1"
}
},
"~:id": "~u3ea49ce0-9d99-8197-8007-950361d24e43",
"~:options": {
"~:components-v2": true,
"~:base-font-size": "16px"
}
}
}

View File

@@ -1,135 +0,0 @@
{
"~:features": {
"~#set": [
"fdata/path-data",
"plugins/runtime",
"design-tokens/v1",
"variants/v1",
"layout/grid",
"styles/v2",
"fdata/objects-map",
"render-wasm/v1",
"components/v2",
"fdata/shape-data-type"
]
},
"~:team-id": "~u99e49e93-362f-80ef-8007-3450ea52c9a4",
"~:permissions": {
"~:type": "~:membership",
"~:is-owner": true,
"~:is-admin": true,
"~:can-edit": true,
"~:can-read": true,
"~:is-logged": true
},
"~:has-media-trimmed": false,
"~:comment-thread-seqn": 0,
"~:name": "BUG 13385",
"~:revn": 2,
"~:modified-at": "~m1771254464312",
"~:vern": 0,
"~:id": "~u3ea49ce0-9d99-8197-8007-950361d24e43",
"~:is-shared": false,
"~:migrations": {
"~#ordered-set": [
"legacy-2",
"legacy-3",
"legacy-5",
"legacy-6",
"legacy-7",
"legacy-8",
"legacy-9",
"legacy-10",
"legacy-11",
"legacy-12",
"legacy-13",
"legacy-14",
"legacy-16",
"legacy-17",
"legacy-18",
"legacy-19",
"legacy-25",
"legacy-26",
"legacy-27",
"legacy-28",
"legacy-29",
"legacy-31",
"legacy-32",
"legacy-33",
"legacy-34",
"legacy-36",
"legacy-37",
"legacy-38",
"legacy-39",
"legacy-40",
"legacy-41",
"legacy-42",
"legacy-43",
"legacy-44",
"legacy-45",
"legacy-46",
"legacy-47",
"legacy-48",
"legacy-49",
"legacy-50",
"legacy-51",
"legacy-52",
"legacy-53",
"legacy-54",
"legacy-55",
"legacy-56",
"legacy-57",
"legacy-59",
"legacy-62",
"legacy-65",
"legacy-66",
"legacy-67",
"0001-remove-tokens-from-groups",
"0002-normalize-bool-content-v2",
"0002-clean-shape-interactions",
"0003-fix-root-shape",
"0003-convert-path-content-v2",
"0005-deprecate-image-type",
"0006-fix-old-texts-fills",
"0008-fix-library-colors-v4",
"0009-clean-library-colors",
"0009-add-partial-text-touched-flags",
"0010-fix-swap-slots-pointing-non-existent-shapes",
"0011-fix-invalid-text-touched-flags",
"0012-fix-position-data",
"0013-fix-component-path",
"0013-clear-invalid-strokes-and-fills",
"0014-fix-tokens-lib-duplicate-ids",
"0014-clear-components-nil-objects",
"0015-fix-text-attrs-blank-strings",
"0015-clean-shadow-color",
"0016-copy-fills-from-position-data-to-text-node"
]
},
"~:version": 67,
"~:project-id": "~ucd8f7672-e5d1-810f-8007-87e124eda82a",
"~:created-at": "~m1771254391625",
"~:backend": "legacy-db",
"~:data": {
"~:pages": [
"~u3ea49ce0-9d99-8197-8007-950361d24e44"
],
"~:pages-index": {
"~u3ea49ce0-9d99-8197-8007-950361d24e44": {
"~:objects": {
"~#penpot/objects-map/v2": {
"~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^H\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~ue0e81bed-4dc2-805c-8007-95036a4a3131\"]]]",
"~ue0e81bed-4dc2-805c-8007-95036a4a3131": "[\"~#shape\",[\"^ \",\"~:y\",252,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",177,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",156,\"~:y\",252]],[\"^<\",[\"^ \",\"~:x\",333,\"~:y\",252]],[\"^<\",[\"^ \",\"~:x\",333,\"~:y\",389]],[\"^<\",[\"^ \",\"~:x\",156,\"~:y\",389]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~ue0e81bed-4dc2-805c-8007-95036a4a3131\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",156,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",156,\"~:y\",252,\"^8\",177,\"~:height\",137,\"~:x1\",156,\"~:y1\",252,\"~:x2\",333,\"~:y2\",389]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^J\",137,\"~:flip-y\",null]]"
}
},
"~:id": "~u3ea49ce0-9d99-8197-8007-950361d24e44",
"~:name": "Page 1"
}
},
"~:id": "~u3ea49ce0-9d99-8197-8007-950361d24e43",
"~:options": {
"~:components-v2": true,
"~:base-font-size": "16px"
}
}
}

View File

@@ -1,135 +0,0 @@
{
"~:features": {
"~#set": [
"fdata/path-data",
"plugins/runtime",
"design-tokens/v1",
"variants/v1",
"layout/grid",
"styles/v2",
"fdata/objects-map",
"render-wasm/v1",
"components/v2",
"fdata/shape-data-type"
]
},
"~:team-id": "~u99e49e93-362f-80ef-8007-3450ea52c9a4",
"~:permissions": {
"~:type": "~:membership",
"~:is-owner": true,
"~:is-admin": true,
"~:can-edit": true,
"~:can-read": true,
"~:is-logged": true
},
"~:has-media-trimmed": false,
"~:comment-thread-seqn": 0,
"~:name": "BUG 13415",
"~:revn": 14,
"~:modified-at": "~m1771334256704",
"~:vern": 0,
"~:id": "~u0472abff-2573-8186-8007-961793e53f45",
"~:is-shared": false,
"~:migrations": {
"~#ordered-set": [
"legacy-2",
"legacy-3",
"legacy-5",
"legacy-6",
"legacy-7",
"legacy-8",
"legacy-9",
"legacy-10",
"legacy-11",
"legacy-12",
"legacy-13",
"legacy-14",
"legacy-16",
"legacy-17",
"legacy-18",
"legacy-19",
"legacy-25",
"legacy-26",
"legacy-27",
"legacy-28",
"legacy-29",
"legacy-31",
"legacy-32",
"legacy-33",
"legacy-34",
"legacy-36",
"legacy-37",
"legacy-38",
"legacy-39",
"legacy-40",
"legacy-41",
"legacy-42",
"legacy-43",
"legacy-44",
"legacy-45",
"legacy-46",
"legacy-47",
"legacy-48",
"legacy-49",
"legacy-50",
"legacy-51",
"legacy-52",
"legacy-53",
"legacy-54",
"legacy-55",
"legacy-56",
"legacy-57",
"legacy-59",
"legacy-62",
"legacy-65",
"legacy-66",
"legacy-67",
"0001-remove-tokens-from-groups",
"0002-normalize-bool-content-v2",
"0002-clean-shape-interactions",
"0003-fix-root-shape",
"0003-convert-path-content-v2",
"0005-deprecate-image-type",
"0006-fix-old-texts-fills",
"0008-fix-library-colors-v4",
"0009-clean-library-colors",
"0009-add-partial-text-touched-flags",
"0010-fix-swap-slots-pointing-non-existent-shapes",
"0011-fix-invalid-text-touched-flags",
"0012-fix-position-data",
"0013-fix-component-path",
"0013-clear-invalid-strokes-and-fills",
"0014-fix-tokens-lib-duplicate-ids",
"0014-clear-components-nil-objects",
"0015-fix-text-attrs-blank-strings",
"0015-clean-shadow-color",
"0016-copy-fills-from-position-data-to-text-node"
]
},
"~:version": 67,
"~:project-id": "~ucd8f7672-e5d1-810f-8007-87e124eda82a",
"~:created-at": "~m1771326794644",
"~:backend": "legacy-db",
"~:data": {
"~:pages": [
"~u0472abff-2573-8186-8007-961793e53f46"
],
"~:pages-index": {
"~u0472abff-2573-8186-8007-961793e53f46": {
"~:objects": {
"~#penpot/objects-map/v2": {
"~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^H\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~uaef184da-e9c1-80f8-8007-961cf253d534\"]]]",
"~uaef184da-e9c1-80f8-8007-961cf253d534": "[\"~#shape\",[\"^ \",\"~:y\",286,\"~:layout-grid-columns\",[[\"^ \",\"~:type\",\"~:flex\",\"~:value\",1],[\"^ \",\"^2\",\"^3\",\"^4\",1]],\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:grid\",\"~:hide-in-viewer\",false,\"~:name\",\"Board\",\"~:layout-align-items\",\"~:start\",\"~:width\",298,\"~:layout-grid-cells\",[\"^ \",\"~uaef184da-e9c1-80f8-8007-961cf50d67b4\",[\"^ \",\"~:justify-self\",\"~:auto\",\"~:column\",1,\"~:id\",\"~uaef184da-e9c1-80f8-8007-961cf50d67b4\",\"~:position\",\"^L\",\"~:column-span\",1,\"~:align-self\",\"^L\",\"~:row\",1,\"~:row-span\",1,\"~:shapes\",[]],\"~uaef184da-e9c1-80f8-8007-961cf50d67b5\",[\"^ \",\"^K\",\"^L\",\"^M\",2,\"^N\",\"~uaef184da-e9c1-80f8-8007-961cf50d67b5\",\"^O\",\"^L\",\"^P\",1,\"^Q\",\"^L\",\"^R\",1,\"^S\",1,\"^T\",[]],\"~uaef184da-e9c1-80f8-8007-961cf50d67b6\",[\"^ \",\"^K\",\"^L\",\"^M\",1,\"^N\",\"~uaef184da-e9c1-80f8-8007-961cf50d67b6\",\"^O\",\"^L\",\"^P\",1,\"^Q\",\"^L\",\"^R\",2,\"^S\",1,\"^T\",[]],\"~uaef184da-e9c1-80f8-8007-961cf50d67b7\",[\"^ \",\"^K\",\"^L\",\"^M\",2,\"^N\",\"~uaef184da-e9c1-80f8-8007-961cf50d67b7\",\"^O\",\"^L\",\"^P\",1,\"^Q\",\"^L\",\"^R\",2,\"^S\",1,\"^T\",[]]],\"~:layout-padding-type\",\"~:simple\",\"^2\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",322,\"~:y\",286]],[\"^10\",[\"^ \",\"~:x\",620,\"~:y\",286]],[\"^10\",[\"^ \",\"~:x\",620,\"~:y\",552]],[\"^10\",[\"^ \",\"~:x\",322,\"~:y\",552]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^>\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:layout-justify-content\",\"~:stretch\",\"~:r1\",0,\"^N\",\"~uaef184da-e9c1-80f8-8007-961cf253d534\",\"~:layout-justify-items\",\"^G\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-align-content\",\"^19\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",322,\"~:proportion\",1,\"~:r4\",0,\"~:layout-grid-rows\",[[\"^ \",\"^2\",\"^3\",\"^4\",1],[\"^ \",\"^2\",\"^3\",\"^4\",1]],\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",322,\"~:y\",286,\"^H\",298,\"~:height\",266,\"~:x1\",322,\"~:y1\",286,\"~:x2\",620,\"~:y2\",552]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:layout-grid-dir\",\"^R\",\"~:flip-x\",null,\"^1E\",266,\"~:flip-y\",null,\"^T\",[]]]"
}
},
"~:id": "~u0472abff-2573-8186-8007-961793e53f46",
"~:name": "Page 1"
}
},
"~:id": "~u0472abff-2573-8186-8007-961793e53f45",
"~:options": {
"~:components-v2": true,
"~:base-font-size": "16px"
}
}
}

View File

@@ -1,23 +0,0 @@
[
{
"~:id": "~u3ea49ce0-9d99-8197-8007-95037190405b",
"~:label": "Version 000",
"~:revn": 1,
"~:version": 67,
"~:created-at": "~m1771254407745",
"~:modified-at": "~m1771254407745",
"~:created-by": "user",
"~:profile-id": "~u99e49e93-362f-80ef-8007-3450ea5204aa"
},
{
"~:revn": 0,
"~:modified-at": "~m1771254406526",
"~:deleted-at": "~m1771340806524",
"~:created-by": "system",
"~:label": "internal/snapshot/0",
"~:id": "~u3ea49ce0-9d99-8197-8007-9503705f8b9b",
"~:profile-id": "~u99e49e93-362f-80ef-8007-3450ea5204aa",
"~:version": 67,
"~:created-at": "~m1771254406526"
}
]

View File

@@ -1,9 +0,0 @@
[
{
"~:id": "~u99e49e93-362f-80ef-8007-3450ea5204aa",
"~:email": "belen@example.com",
"~:name": "Belén Albeza",
"~:fullname": "Belén Albeza",
"~:is-active": true
}
]

View File

@@ -1,98 +0,0 @@
{
"~:revn": 11,
"~:lagged": [
{
"~:id": "~u9666e946-78e8-8111-8007-8fe7be6223c2",
"~:revn": 12,
"~:file-id": "~u9666e946-78e8-8111-8007-8fe5f0f454bf",
"~:session-id": "~u3966be0d-5f49-807f-8007-8fe68b13fee6",
"~:changes": [
{
"~:type": "~:mod-obj",
"~:id": "~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a",
"~:page-id": "~u9666e946-78e8-8111-8007-8fe5f0f49ac6",
"~:operations": [
{
"~:type": "~:set",
"~:attr": "~:y",
"~:val": 110.00000528339297,
"~:ignore-geometry": false,
"~:ignore-touched": false
},
{
"~:type": "~:set",
"~:attr": "~:width",
"~:val": 629.9999776102587,
"~:ignore-geometry": false,
"~:ignore-touched": false
},
{
"~:type": "~:set",
"~:attr": "~:points",
"~:val": [
{
"~#point": {
"~:x": 109.99999217353886,
"~:y": 110.00000528339297
}
},
{
"~#point": {
"~:x": 739.9999697837976,
"~:y": 110.00000528339297
}
},
{
"~#point": {
"~:x": 739.9999697837976,
"~:y": 739.9999740316338
}
},
{
"~#point": {
"~:x": 109.99999217353886,
"~:y": 739.9999740316338
}
}
],
"~:ignore-geometry": false,
"~:ignore-touched": false
},
{
"~:type": "~:set",
"~:attr": "~:x",
"~:val": 109.99999217353889,
"~:ignore-geometry": false,
"~:ignore-touched": false
},
{
"~:type": "~:set",
"~:attr": "~:selrect",
"~:val": {
"~#rect": {
"~:x": 109.99999217353889,
"~:y": 110.00000528339297,
"~:width": 629.9999776102587,
"~:height": 629.9999687482408,
"~:x1": 109.99999217353889,
"~:y1": 110.00000528339297,
"~:x2": 739.9999697837976,
"~:y2": 739.9999740316338
}
},
"~:ignore-geometry": false,
"~:ignore-touched": false
},
{
"~:type": "~:set",
"~:attr": "~:height",
"~:val": 629.9999687482408,
"~:ignore-geometry": false,
"~:ignore-touched": false
}
]
}
]
}
]
}

View File

@@ -1,18 +0,0 @@
{
"~:revn": 14,
"~:lagged": [
{
"~:id": "~u0472abff-2573-8186-8007-96347d525f65",
"~:revn": 15,
"~:file-id": "~u0472abff-2573-8186-8007-961793e53f45",
"~:session-id": "~uf25e6d2f-d10c-8021-8007-96344433f08d",
"~:changes": [
{
"~:type": "~:del-obj",
"~:page-id": "~u0472abff-2573-8186-8007-961793e53f46",
"~:id": "~uaef184da-e9c1-80f8-8007-961cf253d534"
}
]
}
]
}

View File

@@ -22,7 +22,7 @@ export class BasePage {
* @param {*} options * @param {*} options
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
static async mockRPC(page, path, jsonFilename = "", options = {}) { static async mockRPC(page, path, jsonFilename, options) {
if (!page) { if (!page) {
throw new TypeError("Invalid page argument. Must be a Playwright page."); throw new TypeError("Invalid page argument. Must be a Playwright page.");
} }
@@ -41,7 +41,7 @@ export class BasePage {
return page.route(url, (route) => return page.route(url, (route) =>
route.fulfill({ route.fulfill({
...interceptConfig, ...interceptConfig,
path: jsonFilename ? `playwright/data/${jsonFilename}` : undefined, path: `playwright/data/${jsonFilename}`,
}), }),
); );
} }

View File

@@ -10,7 +10,7 @@ export const WASM_FLAGS = [
export class WasmWorkspacePage extends WorkspacePage { export class WasmWorkspacePage extends WorkspacePage {
static async init(page) { static async init(page) {
await super.init(page); await super.init(page);
await WasmWorkspacePage.mockConfigFlags(page, WASM_FLAGS); await WorkspacePage.mockConfigFlags(page, WASM_FLAGS);
await page.addInitScript(() => { await page.addInitScript(() => {
document.addEventListener("penpot:wasm:loaded", () => { document.addEventListener("penpot:wasm:loaded", () => {
@@ -27,16 +27,8 @@ export class WasmWorkspacePage extends WorkspacePage {
}); });
} }
static async mockConfigFlags(page, flags) { constructor(page) {
await super.mockConfigFlags(page, [...WASM_FLAGS, ...flags]); super(page);
}
async mockConfigFlags(flags) {
return WasmWorkspacePage.mockConfigFlags(this.page, flags);
}
constructor(page, options) {
super(page, options);
this.canvas = page.getByTestId("canvas-wasm-shapes"); this.canvas = page.getByTestId("canvas-wasm-shapes");
} }
@@ -54,19 +46,6 @@ export class WasmWorkspacePage extends WorkspacePage {
await this.hideUI(); await this.hideUI();
} }
async getRenderCount() {
return this.page.evaluate(() => window.wasmRenderCount || 0);
}
async waitForNextRender(previousCount = null) {
const baseCount =
previousCount === null ? await this.getRenderCount() : previousCount;
await this.page.waitForFunction(
(count) => (window.wasmRenderCount || 0) > count,
baseCount,
);
}
async hideUI() { async hideUI() {
await this.page.keyboard.press("\\"); await this.page.keyboard.press("\\");
await expect(this.pageName).not.toBeVisible(); await expect(this.pageName).not.toBeVisible();

View File

@@ -35,9 +35,45 @@ export class WorkspacePage extends BaseWebSocketPage {
} }
async waitForEditor() { async waitForEditor() {
const typographyInput = return this.page.waitForSelector('[data-itype="editor"]');
this.workspacePage.rightSidebar.getByLabel("Font Size"); }
await expect(typographyInput).toBeVisible();
async waitForRoot() {
return this.page.waitForSelector('[data-itype="root"]');
}
async waitForParagraph(nth) {
if (!nth) {
return this.page.waitForSelector('[data-itype="paragraph"]');
}
return this.page.waitForSelector(
`[data-itype="paragraph"]:nth-child(${nth})`,
);
}
async waitForParagraphStyle(nth, styleName) {
const paragraph = await this.waitForParagraph(nth);
return this.waitForStyle(paragraph, styleName);
}
async waitForTextSpan(nth = 0) {
if (!nth) {
return this.page.waitForSelector('[data-itype="span"]');
}
return this.page.waitForSelector(
`[data-itype="span"]:nth-child(${nth})`,
);
}
async waitForTextSpanContent(nth = 0) {
const textSpan = await this.waitForTextSpan(nth);
const textContent = await textSpan.textContent();
return textContent;
}
async waitForTextSpanStyle(nth, styleName) {
const textSpan = await this.waitForTextSpan(nth);
return this.waitForStyle(textSpan, styleName);
} }
async startEditing() { async startEditing() {
@@ -62,7 +98,7 @@ export class WorkspacePage extends BaseWebSocketPage {
} }
async moveFromStart(offset = 0) { async moveFromStart(offset = 0) {
await this.page.keyboard.press("Home"); await this.page.keyboard.press("ArrowLeft");
await this.moveToRight(offset); await this.moveToRight(offset);
} }
@@ -89,7 +125,7 @@ export class WorkspacePage extends BaseWebSocketPage {
await expect(locator).toBeVisible(); await expect(locator).toBeVisible();
await locator.focus(); await locator.focus();
await locator.fill(`${newValue}`); await locator.fill(`${newValue}`);
await this.page.keyboard.press("Enter"); await locator.blur();
} }
changeFontSize(newValue) { changeFontSize(newValue) {
@@ -162,10 +198,10 @@ export class WorkspacePage extends BaseWebSocketPage {
`[id="shape-00000000-0000-0000-0000-000000000000"]`, `[id="shape-00000000-0000-0000-0000-000000000000"]`,
); );
this.toolbarOptions = page.getByTestId("toolbar-options"); this.toolbarOptions = page.getByTestId("toolbar-options");
this.rectShapeButton = page.getByRole("button", { name: "Rectangle (R)" }); this.rectShapeButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Rectangle" });
this.ellipseShapeButton = page.getByRole("button", { name: "Ellipse (E)" }); this.ellipseShapeButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Ellipse" });
this.moveButton = page.getByRole("button", { name: "Move (V)" }); this.moveButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Move" });
this.boardButton = page.getByRole("button", { name: "Board (B)" }); this.boardButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Board" });
this.toggleToolbarButton = page.getByRole("button", { this.toggleToolbarButton = page.getByRole("button", {
name: "Toggle toolbar", name: "Toggle toolbar",
}); });
@@ -281,6 +317,7 @@ export class WorkspacePage extends BaseWebSocketPage {
body, body,
}), }),
); );
// await this.mockRPC(/get\-file\?/, jsonFile);
} }
async mockGetAsset(regex, asset) { async mockGetAsset(regex, asset) {
@@ -301,18 +338,9 @@ export class WorkspacePage extends BaseWebSocketPage {
async clickWithDragViewportAt(x, y, width, height) { async clickWithDragViewportAt(x, y, width, height) {
await this.page.waitForTimeout(100); await this.page.waitForTimeout(100);
const box = await this.viewport.boundingBox(); await this.viewport.hover({ position: { x, y } });
if (!box) throw new Error('Viewport not visible');
const startX = box.x + x;
const startY = box.y + y;
const endX = startX + width;
const endY = startY + height;
await this.page.mouse.move(startX, startY);
await this.page.mouse.down(); await this.page.mouse.down();
// Use steps so mouseup is properly processed (see Playwright issue #20254) await this.viewport.hover({ position: { x: x + width, y: y + height } });
await this.page.mouse.move(endX, endY, { steps: 10 });
await this.page.mouse.up(); await this.page.mouse.up();
} }
@@ -354,12 +382,10 @@ export class WorkspacePage extends BaseWebSocketPage {
const timeToWait = options?.timeToWait ?? 100; const timeToWait = options?.timeToWait ?? 100;
await this.page.keyboard.press("T"); await this.page.keyboard.press("T");
await this.page.waitForTimeout(timeToWait); await this.page.waitForTimeout(timeToWait);
const layersCountBefore = await this.layers.getByTestId("layer-row").count();
await this.clickAndMove(x1, y1, x2, y2); await this.clickAndMove(x1, y1, x2, y2);
await expect(this.page.getByTestId("text-editor")).toBeVisible();
if (initialText) { if (initialText) {
await this.waitForSelectedShapeName("Text");
await this.page.keyboard.type(initialText); await this.page.keyboard.type(initialText);
} }
} }
@@ -459,23 +485,10 @@ export class WorkspacePage extends BaseWebSocketPage {
async expectSelectedLayer(name) { async expectSelectedLayer(name) {
await expect( await expect(
this.layers.getByRole("checkbox", { name, checked: true }), this.layers
).toBeVisible(); .getByTestId("layer-row")
} .filter({ has: this.page.getByText(name) }),
).toHaveClass(/selected/);
async getSelectedShapeName() {
const selectedLayer = this.layers
.getByRole("checkbox", { checked: true })
.first();
await selectedLayer.waitFor({ state: "visible" });
return (await selectedLayer.innerText()).trim();
}
async waitForSelectedShapeName(expectedName) {
const selectedLayer = this.layers
.getByRole("checkbox", { checked: true })
.first();
await expect(selectedLayer).toHaveText(expectedName);
} }
async expectHiddenToolbarOptions() { async expectHiddenToolbarOptions() {

View File

@@ -165,7 +165,6 @@ test("Updates canvas background", async ({ page }) => {
}); });
await canvasBackgroundInput.fill("FABADA"); await canvasBackgroundInput.fill("FABADA");
await workspace.page.keyboard.press("Enter"); await workspace.page.keyboard.press("Enter");
await workspace.waitForFirstRenderWithoutUI();
await expect(workspace.canvas).toHaveScreenshot(); await expect(workspace.canvas).toHaveScreenshot();
}); });
@@ -291,24 +290,6 @@ test("Renders a file with nested clipping frames", async ({ page }) => {
await expect(workspace.canvas).toHaveScreenshot(); await expect(workspace.canvas).toHaveScreenshot();
}); });
test("Renders clipped frames with strokes correctly (no double painting)", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
await workspace.setupEmptyFile();
await workspace.mockGetFile(
"render-wasm/get-file-frame-strokes-opacity.json",
);
await workspace.goToWorkspace({
id: "3144ac7c-a5cc-80e8-8007-8bbb29a4e56e",
pageId: "3144ac7c-a5cc-80e8-8007-8bbb29a510ac",
});
await workspace.waitForFirstRenderWithoutUI();
await expect(workspace.canvas).toHaveScreenshot();
});
test("Renders a clipped frame with a large blur drop shadow", async ({ test("Renders a clipped frame with a large blur drop shadow", async ({
page, page,
}) => { }) => {
@@ -324,71 +305,3 @@ test("Renders a clipped frame with a large blur drop shadow", async ({
await expect(workspace.canvas).toHaveScreenshot(); await expect(workspace.canvas).toHaveScreenshot();
}); });
test("Renders a file with solid, dotted, dashed and mixed stroke styles", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
await workspace.setupEmptyFile();
await workspace.mockGetFile("render-wasm/get-file-stroke-styles.json");
await workspace.goToWorkspace({
id: "b888b894-3697-80d3-8006-51cc8a55c200",
pageId: "b888b894-3697-80d3-8006-51cc8a55c210",
});
await workspace.waitForFirstRenderWithoutUI();
await expect(workspace.canvas).toHaveScreenshot();
});
test("Renders shapes with multiple fills and blur", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
await workspace.setupEmptyFile();
await workspace.mockGetFile("render-wasm/get-file-fill-blend-blurs.json");
await workspace.goToWorkspace({
id: "b15901d7-d46d-8056-8007-8d5e34fc1f0c",
pageId: "b15901d7-d46d-8056-8007-8d5e34fc1f0d",
});
await workspace.waitForFirstRenderWithoutUI();
await expect(workspace.canvas).toHaveScreenshot();
});
test("Keeps component visible when focusing after creating it", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "workspace/get-file-not-empty.json");
await workspace.mockRPC(
"update-file?id=*",
"workspace/update-file-create-rect.json",
);
await workspace.goToWorkspace({
fileId: "6191cd35-bb1f-81f7-8004-7cc63d087374",
pageId: "6191cd35-bb1f-81f7-8004-7cc63d087375",
});
await workspace.waitForFirstRender();
await workspace.clickLayers();
await workspace.clickLeafLayer("Rectangle");
await page.keyboard.press("ControlOrMeta+k");
const componentLayer = workspace.layers
.getByTestId("layer-row")
.filter({ has: page.getByTestId("icon-component") })
.first();
await expect(componentLayer).toBeVisible();
await componentLayer.click();
const previousRenderCount = await workspace.getRenderCount();
await page.keyboard.press("f");
await workspace.waitForNextRender(previousRenderCount);
await workspace.hideUI();
await expect(workspace.canvas).toHaveScreenshot();
});

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 KiB

After

Width:  |  Height:  |  Size: 360 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

After

Width:  |  Height:  |  Size: 216 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 124 KiB

View File

@@ -1,14 +1,14 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; import { WorkspacePage } from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page); await WorkspacePage.init(page);
}); });
test("User adds a library and its automatically selected in the color palette", async ({ test("User adds a library and its automatically selected in the color palette", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.mockRPC( await workspacePage.mockRPC(
"link-file-to-library", "link-file-to-library",
@@ -53,7 +53,7 @@ test("User adds a library and its automatically selected in the color palette",
test("BUG 10090 - Local library should be expanded by default", async ({ test("BUG 10090 - Local library should be expanded by default", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page); await workspacePage.setupEmptyFile(page);
await workspacePage.goToWorkspace(); await workspacePage.goToWorkspace();

View File

@@ -1,15 +1,15 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; import { WorkspacePage } from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page); await WorkspacePage.init(page);
}); });
// Fix for https://tree.taiga.io/project/penpot/issue/7549 // Fix for https://tree.taiga.io/project/penpot/issue/7549
test("Bug 7549 - User clicks on color swatch to display the color picker next to it", async ({ test("Bug 7549 - User clicks on color swatch to display the color picker next to it", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page); await workspacePage.setupEmptyFile(page);
await workspacePage.goToWorkspace(); await workspacePage.goToWorkspace();
@@ -25,7 +25,7 @@ test("Bug 7549 - User clicks on color swatch to display the color picker next to
}); });
test("Create a LINEAR gradient", async ({ page }) => { test("Create a LINEAR gradient", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.mockRPC( await workspacePage.mockRPC(
/get\-file\?/, /get\-file\?/,
@@ -99,7 +99,7 @@ test("Create a LINEAR gradient", async ({ page }) => {
}); });
test("Create a RADIAL gradient", async ({ page }) => { test("Create a RADIAL gradient", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.mockRPC( await workspacePage.mockRPC(
/get\-file\?/, /get\-file\?/,
@@ -183,7 +183,7 @@ test("Create a RADIAL gradient", async ({ page }) => {
}); });
test("Gradient stops limit", async ({ page }) => { test("Gradient stops limit", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.mockConfigFlags(["enable-feature-render-wasm"]); await workspacePage.mockConfigFlags(["enable-feature-render-wasm"]);
await workspacePage.setupEmptyFile(page); await workspacePage.setupEmptyFile(page);
@@ -215,7 +215,7 @@ test("Gradient stops limit", async ({ page }) => {
test("Bug 9900 - Color picker has no inputs for HSV values", async ({ test("Bug 9900 - Color picker has no inputs for HSV values", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page); await workspacePage.setupEmptyFile(page);
await workspacePage.goToWorkspace(); await workspacePage.goToWorkspace();
@@ -232,7 +232,7 @@ test("Bug 9900 - Color picker has no inputs for HSV values", async ({
}); });
test("Bug 10089 - Cannot change alpha", async ({ page }) => { test("Bug 10089 - Cannot change alpha", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.mockRPC( await workspacePage.mockRPC(
/get\-file\?/, /get\-file\?/,

View File

@@ -1,8 +1,8 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; import { WorkspacePage } from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page); await WorkspacePage.init(page);
}); });
const multipleConstraintsFileId = `03bff843-920f-81a1-8004-756365e1eb6a`; const multipleConstraintsFileId = `03bff843-920f-81a1-8004-756365e1eb6a`;
@@ -42,7 +42,7 @@ test.describe("Constraints", () => {
test("Constraint dropdown shows 'Mixed' when multiple layers are selected with different constraints", async ({ test("Constraint dropdown shows 'Mixed' when multiple layers are selected with different constraints", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page); const workspace = new WorkspacePage(page);
await setupFileWithMultipeConstraints(workspace); await setupFileWithMultipeConstraints(workspace);
await workspace.goToWorkspace({ await workspace.goToWorkspace({
fileId: multipleConstraintsFileId, fileId: multipleConstraintsFileId,
@@ -70,7 +70,7 @@ test.describe("Shape attributes", () => {
test("Cannot add a new fill when the limit has been reached", async ({ test("Cannot add a new fill when the limit has been reached", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page); const workspace = new WorkspacePage(page);
await workspace.mockConfigFlags(["enable-feature-render-wasm"]); await workspace.mockConfigFlags(["enable-feature-render-wasm"]);
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "design/get-file-fills-limit.json"); await workspace.mockRPC(/get\-file\?/, "design/get-file-fills-limit.json");
@@ -94,7 +94,7 @@ test.describe("Shape attributes", () => {
test.skip("Cannot add a new text fill when the limit has been reached", async ({ test.skip("Cannot add a new text fill when the limit has been reached", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page); const workspace = new WorkspacePage(page);
await workspace.mockConfigFlags(["enable-feature-render-wasm"]); await workspace.mockConfigFlags(["enable-feature-render-wasm"]);
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
await workspace.mockRPC( await workspace.mockRPC(
@@ -128,7 +128,7 @@ test.describe("Multiple shapes attributes", () => {
test("User selects multiple shapes with sames fills, strokes, shadows and blur", async ({ test("User selects multiple shapes with sames fills, strokes, shadows and blur", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page); const workspace = new WorkspacePage(page);
await setupFileWithMultipeConstraints(workspace); await setupFileWithMultipeConstraints(workspace);
await workspace.goToWorkspace({ await workspace.goToWorkspace({
fileId: multipleConstraintsFileId, fileId: multipleConstraintsFileId,
@@ -148,7 +148,7 @@ test.describe("Multiple shapes attributes", () => {
test("User selects multiple shapes with different fills, strokes, shadows and blur", async ({ test("User selects multiple shapes with different fills, strokes, shadows and blur", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page); const workspace = new WorkspacePage(page);
await setupFileWithMultipeAttributes(workspace); await setupFileWithMultipeAttributes(workspace);
await workspace.goToWorkspace({ await workspace.goToWorkspace({
fileId: multipleAttributesFileId, fileId: multipleAttributesFileId,
@@ -168,7 +168,7 @@ test.describe("Multiple shapes attributes", () => {
test("BUG 7760 - Layout losing properties when changing parents", async ({ test("BUG 7760 - Layout losing properties when changing parents", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-7760.json"); await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-7760.json");
await workspacePage.mockRPC( await workspacePage.mockRPC(
@@ -189,8 +189,8 @@ test("BUG 7760 - Layout losing properties when changing parents", async ({
await workspacePage.clickLeafLayer("Flex Board"); await workspacePage.clickLeafLayer("Flex Board");
// Move the first board into the second // Move the first board into the second
const hAuto = await workspacePage.page.getByTitle("Fit content (Horizontal)"); const hAuto = await workspacePage.page.getByTestId("behaviour-h-auto");
const vAuto = await workspacePage.page.getByTitle("Fit content (Vertical)"); const vAuto = await workspacePage.page.getByTestId("behaviour-v-auto");
await expect(vAuto.locator("input")).toBeChecked(); await expect(vAuto.locator("input")).toBeChecked();
await expect(hAuto.locator("input")).toBeChecked(); await expect(hAuto.locator("input")).toBeChecked();
@@ -205,7 +205,7 @@ test("BUG 7760 - Layout losing properties when changing parents", async ({
test("BUG 9061 - Group blur visibility toggle icon not updating", async ({ test("BUG 9061 - Group blur visibility toggle icon not updating", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page); const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "design/get-file-9061.json"); await workspace.mockRPC(/get\-file\?/, "design/get-file-9061.json");
await workspace.mockRPC( await workspace.mockRPC(
@@ -234,7 +234,7 @@ test("BUG 9061 - Group blur visibility toggle icon not updating", async ({
test("BUG 9543 - Layout padding inputs not showing 'mixed' when needed", async ({ test("BUG 9543 - Layout padding inputs not showing 'mixed' when needed", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page); const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "design/get-file-9543.json"); await workspace.mockRPC(/get\-file\?/, "design/get-file-9543.json");
await workspace.mockRPC( await workspace.mockRPC(
@@ -267,7 +267,7 @@ test("BUG 9543 - Layout padding inputs not showing 'mixed' when needed", async (
test("BUG 11177 - Font size input not showing 'mixed' when needed", async ({ test("BUG 11177 - Font size input not showing 'mixed' when needed", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page); const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "design/get-file-11177.json"); await workspace.mockRPC(/get\-file\?/, "design/get-file-11177.json");
@@ -288,7 +288,7 @@ test("BUG 11177 - Font size input not showing 'mixed' when needed", async ({
test("BUG 12287 Fix identical text fills not being added/removed", async ({ test("BUG 12287 Fix identical text fills not being added/removed", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page); const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "design/get-file-12287.json"); await workspace.mockRPC(/get\-file\?/, "design/get-file-12287.json");
@@ -323,7 +323,7 @@ test("BUG 12287 Fix identical text fills not being added/removed", async ({
}); });
test("BUG 12384 - Export crashing when exporting a board", async ({ page }) => { test("BUG 12384 - Export crashing when exporting a board", async ({ page }) => {
const workspace = new WasmWorkspacePage(page); const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "design/get-file-12384.json"); await workspace.mockRPC(/get\-file\?/, "design/get-file-12384.json");

View File

@@ -1,8 +1,8 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; import { WorkspacePage } from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page); await WorkspacePage.init(page);
}); });
/** /**
@@ -32,7 +32,7 @@ test.describe("Export frames to PDF", () => {
test("Export frames menu option is NOT visible when page has no frames", async ({ test("Export frames menu option is NOT visible when page has no frames", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.goToWorkspace(); await workspacePage.goToWorkspace();
@@ -48,7 +48,7 @@ test.describe("Export frames to PDF", () => {
test("Export frames menu option is visible when there are frames (even if not selected)", async ({ test("Export frames menu option is visible when there are frames (even if not selected)", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupWorkspaceWithFrames(workspacePage); await setupWorkspaceWithFrames(workspacePage);
// Open main menu // Open main menu
@@ -62,7 +62,7 @@ test.describe("Export frames to PDF", () => {
test("Export frames modal shows all frames when none are selected", async ({ test("Export frames modal shows all frames when none are selected", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupWorkspaceWithFrames(workspacePage); await setupWorkspaceWithFrames(workspacePage);
// Don't select any frame // Don't select any frame
@@ -88,7 +88,7 @@ test.describe("Export frames to PDF", () => {
test("Export frames modal shows only the selected frames", async ({ test("Export frames modal shows only the selected frames", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupWorkspaceWithFrames(workspacePage); await setupWorkspaceWithFrames(workspacePage);
// Select Frame 1 // Select Frame 1
@@ -116,7 +116,7 @@ test.describe("Export frames to PDF", () => {
}); });
test("User can deselect frames in the export modal", async ({ page }) => { test("User can deselect frames in the export modal", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupWorkspaceWithFrames(workspacePage); await setupWorkspaceWithFrames(workspacePage);
// Select Frame 1 // Select Frame 1
@@ -149,7 +149,7 @@ test.describe("Export frames to PDF", () => {
test("Export button is disabled when all frames are deselected", async ({ test("Export button is disabled when all frames are deselected", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupWorkspaceWithFrames(workspacePage); await setupWorkspaceWithFrames(workspacePage);
// Select Frame 1 // Select Frame 1
@@ -173,7 +173,7 @@ test.describe("Export frames to PDF", () => {
}); });
test("User can cancel the export modal", async ({ page }) => { test("User can cancel the export modal", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupWorkspaceWithFrames(workspacePage); await setupWorkspaceWithFrames(workspacePage);
// Select Frame 1 // Select Frame 1

View File

@@ -1,15 +1,15 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; import { WorkspacePage } from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page); await WorkspacePage.init(page);
}); });
// Fix for https://tree.taiga.io/project/penpot/issue/9042 // Fix for https://tree.taiga.io/project/penpot/issue/9042
test("Bug 9042 - Measurement unit dropdowns for columns are cut off in grid layout edit mode", async ({ test("Bug 9042 - Measurement unit dropdowns for columns are cut off in grid layout edit mode", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page); await workspacePage.setupEmptyFile(page);
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-9042.json"); await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-9042.json");
await workspacePage.mockRPC( await workspacePage.mockRPC(
@@ -37,7 +37,7 @@ test("[Taiga #9116] Copy CSS background color in the selected format in the INSP
page, page,
context, context,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page); await workspacePage.setupEmptyFile(page);
await workspacePage.goToWorkspace(); await workspacePage.goToWorkspace();
@@ -87,7 +87,7 @@ test("[Taiga #10630] [INSPECT] Style assets not being displayed on info tab", as
page, page,
context, context,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page); await workspacePage.setupEmptyFile(page);
await workspacePage.goToWorkspace(); await workspacePage.goToWorkspace();
await workspacePage.mockRPC( await workspacePage.mockRPC(

View File

@@ -1,10 +1,10 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; import { WorkspacePage } from "../pages/WorkspacePage";
const flags = ["enable-inspect-styles"]; const flags = ["enable-inspect-styles"];
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page); await WorkspacePage.init(page);
}); });
const setupFile = async (workspacePage) => { const setupFile = async (workspacePage) => {
@@ -90,7 +90,7 @@ const copyPropertyFromPropertyRow = async (panel, property) => {
/** /**
* Returns the style panel by its title * Returns the style panel by its title
* @param {WasmWorkspacePage} workspacePage - The workspace page instance * @param {WorkspacePage} workspacePage - The workspace page instance
* @param {string} title - The title of the panel to retrieve * @param {string} title - The title of the panel to retrieve
*/ */
const getPanelByTitle = async (workspacePage, title) => { const getPanelByTitle = async (workspacePage, title) => {
@@ -103,7 +103,7 @@ const getPanelByTitle = async (workspacePage, title) => {
/** /**
* Selects a layer in the layers panel * Selects a layer in the layers panel
* @param {WasmWorkspacePage} workspacePage - The workspace page instance * @param {WorkspacePage} workspacePage - The workspace page instance
* @param {string} layerName - The name of the layer to select * @param {string} layerName - The name of the layer to select
* @param {string} parentLayerName - The name of the parent layer to expand (optional) * @param {string} parentLayerName - The name of the parent layer to expand (optional)
*/ */
@@ -118,7 +118,7 @@ const selectLayer = async (workspacePage, layerName, parentLayerName) => {
/** /**
* Opens the Inspect tab * Opens the Inspect tab
* @param {WasmWorkspacePage} workspacePage - The workspace page instance * @param {WorkspacePage} workspacePage - The workspace page instance
*/ */
const openInspectTab = async (workspacePage) => { const openInspectTab = async (workspacePage) => {
@@ -133,7 +133,7 @@ const openInspectTab = async (workspacePage) => {
/** /**
* @typedef {'hex' | 'rgba' | 'hsla'} ColorSpace * @typedef {'hex' | 'rgba' | 'hsla'} ColorSpace
* *
* @param {WasmWorkspacePage} workspacePage - The workspace page instance * @param {WorkspacePage} workspacePage - The workspace page instance
* @param {ColorSpace} colorSpace - The color space to select * @param {ColorSpace} colorSpace - The color space to select
*/ */
const selectColorSpace = async (workspacePage, colorSpace) => { const selectColorSpace = async (workspacePage, colorSpace) => {
@@ -148,7 +148,7 @@ const selectColorSpace = async (workspacePage, colorSpace) => {
test.describe("Inspect tab - Styles", () => { test.describe("Inspect tab - Styles", () => {
test.skip("Open Inspect tab", async ({ page }) => { test.skip("Open Inspect tab", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.flex); await selectLayer(workspacePage, shapeToLayerName.flex);
@@ -162,7 +162,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test.describe("Inspect tab - Flex", () => { test.describe("Inspect tab - Flex", () => {
test("Shape Layout Flex ", async ({ page }) => { test("Shape Layout Flex ", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.flex); await selectLayer(workspacePage, shapeToLayerName.flex);
@@ -178,7 +178,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Shape Layout Flex Element", async ({ page }) => { test("Shape Layout Flex Element", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer( await selectLayer(
@@ -199,7 +199,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Shape Layout Grid", async ({ page }) => { test("Shape Layout Grid", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.grid); await selectLayer(workspacePage, shapeToLayerName.grid);
@@ -216,7 +216,7 @@ test.describe("Inspect tab - Styles", () => {
test.describe("Inspect tab - Shadow", () => { test.describe("Inspect tab - Shadow", () => {
test("Shape Shadow - Single shadow", async ({ page }) => { test("Shape Shadow - Single shadow", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.shadow); await selectLayer(workspacePage, shapeToLayerName.shadow);
@@ -232,7 +232,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Shape Shadow - Multiple shadow", async ({ page }) => { test("Shape Shadow - Multiple shadow", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.shadowMultiple); await selectLayer(workspacePage, shapeToLayerName.shadowMultiple);
@@ -249,7 +249,7 @@ test.describe("Inspect tab - Styles", () => {
// FIXME: flaky/random (depends on trace ?) // FIXME: flaky/random (depends on trace ?)
test.skip("Shape Shadow - Composite shadow", async ({ page }) => { test.skip("Shape Shadow - Composite shadow", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.shadowComposite); await selectLayer(workspacePage, shapeToLayerName.shadowComposite);
@@ -278,7 +278,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Shape - Blur", async ({ page }) => { test("Shape - Blur", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.blur); await selectLayer(workspacePage, shapeToLayerName.blur);
@@ -295,7 +295,7 @@ test.describe("Inspect tab - Styles", () => {
test.describe("Inspect tab - Border radius", () => { test.describe("Inspect tab - Border radius", () => {
test("Shape - Border radius - individual", async ({ page }) => { test("Shape - Border radius - individual", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer( await selectLayer(
@@ -325,7 +325,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Shape - Border radius - multiple", async ({ page }) => { test("Shape - Border radius - multiple", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer( await selectLayer(
@@ -365,7 +365,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Shape - Border radius - token", async ({ page }) => { test("Shape - Border radius - token", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer( await selectLayer(
@@ -399,7 +399,7 @@ test.describe("Inspect tab - Styles", () => {
test.describe("Inspect tab - Fill", () => { test.describe("Inspect tab - Fill", () => {
test("Shape - Fill - Solid", async ({ page }) => { test("Shape - Fill - Solid", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.fill.solid); await selectLayer(workspacePage, shapeToLayerName.fill.solid);
@@ -416,7 +416,7 @@ test.describe("Inspect tab - Styles", () => {
test("Change color space and ensure fill and shorthand changes", async ({ test("Change color space and ensure fill and shorthand changes", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.fill.solid); await selectLayer(workspacePage, shapeToLayerName.fill.solid);
@@ -454,7 +454,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Shape - Fill - Gradient", async ({ page }) => { test("Shape - Fill - Gradient", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.fill.gradient); await selectLayer(workspacePage, shapeToLayerName.fill.gradient);
@@ -469,7 +469,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Shape - Fill - Image", async ({ page }) => { test("Shape - Fill - Image", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.fill.image); await selectLayer(workspacePage, shapeToLayerName.fill.image);
@@ -489,7 +489,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Shape - Fill - Multiple", async ({ page }) => { test("Shape - Fill - Multiple", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.fill.multiple); await selectLayer(workspacePage, shapeToLayerName.fill.multiple);
@@ -509,7 +509,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Shape - Fill - Token", async ({ page }) => { test("Shape - Fill - Token", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.fill.token); await selectLayer(workspacePage, shapeToLayerName.fill.token);
@@ -532,7 +532,7 @@ test.describe("Inspect tab - Styles", () => {
test.describe("Inspect tab - Stroke", () => { test.describe("Inspect tab - Stroke", () => {
test("Shape - Stroke - Solid", async ({ page }) => { test("Shape - Stroke - Solid", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.stroke.solid); await selectLayer(workspacePage, shapeToLayerName.stroke.solid);
@@ -547,7 +547,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Shape - Stroke - Gradient", async ({ page }) => { test("Shape - Stroke - Gradient", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.stroke.gradient); await selectLayer(workspacePage, shapeToLayerName.stroke.gradient);
@@ -562,7 +562,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Shape - Stroke - Image", async ({ page }) => { test("Shape - Stroke - Image", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.stroke.image); await selectLayer(workspacePage, shapeToLayerName.stroke.image);
@@ -582,7 +582,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Shape - Stroke - Multiple", async ({ page }) => { test("Shape - Stroke - Multiple", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.stroke.multiple); await selectLayer(workspacePage, shapeToLayerName.stroke.multiple);
@@ -602,7 +602,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Shape - Stroke - Token", async ({ page }) => { test("Shape - Stroke - Token", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.stroke.token); await selectLayer(workspacePage, shapeToLayerName.stroke.token);
@@ -625,7 +625,7 @@ test.describe("Inspect tab - Styles", () => {
test.describe("Inspect tab - Typography", () => { test.describe("Inspect tab - Typography", () => {
test("Text - simple", async ({ page }) => { test("Text - simple", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.text.simple); await selectLayer(workspacePage, shapeToLayerName.text.simple);
@@ -643,7 +643,7 @@ test.describe("Inspect tab - Styles", () => {
}); });
test("Text - token", async ({ page }) => { test("Text - token", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.text.token); await selectLayer(workspacePage, shapeToLayerName.text.token);
@@ -679,7 +679,7 @@ test.describe("Inspect tab - Styles", () => {
await expect(textPreview).toBeVisible(); await expect(textPreview).toBeVisible();
}); });
test("Text - composite token", async ({ page }) => { test("Text - composite token", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.text.compositeToken); await selectLayer(workspacePage, shapeToLayerName.text.compositeToken);
@@ -705,7 +705,7 @@ test.describe("Inspect tab - Styles", () => {
test.describe("Copy properties", () => { test.describe("Copy properties", () => {
test("Copy single property", async ({ page }) => { test("Copy single property", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.flex); await selectLayer(workspacePage, shapeToLayerName.flex);
@@ -722,7 +722,7 @@ test.describe("Inspect tab - Styles", () => {
expect(shorthand).toBe("display: flex;"); expect(shorthand).toBe("display: flex;");
}); });
test("Copy shorthand - multiple properties", async ({ page }) => { test("Copy shorthand - multiple properties", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage); await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.shadow); await selectLayer(workspacePage, shapeToLayerName.shadow);

View File

@@ -1,14 +1,14 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; import { WorkspacePage } from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page); await WorkspacePage.init(page);
}); });
test("BUG 7466 - Layers tab height extends to the bottom when 'Pages' is collapsed", async ({ test("BUG 7466 - Layers tab height extends to the bottom when 'Pages' is collapsed", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page); const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
await workspace.goToWorkspace(); await workspace.goToWorkspace();

View File

@@ -1,9 +1,9 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; import WorkspacePage from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page); await WorkspacePage.init(page);
await WasmWorkspacePage.mockConfigFlags(page, [ await WorkspacePage.mockConfigFlags(page, [
"enable-subscriptions", "enable-subscriptions",
"disable-onboarding", "disable-onboarding",
]); ]);
@@ -13,16 +13,16 @@ test.describe("Subscriptions: workspace", () => {
test("Unlimited team should have 'Power up your plan' link in main menu", async ({ test("Unlimited team should have 'Power up your plan' link in main menu", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await WasmWorkspacePage.mockRPC( await WorkspacePage.mockRPC(
page, page,
"get-profile", "get-profile",
"subscription/get-profile-unlimited-subscription.json", "subscription/get-profile-unlimited-subscription.json",
); );
await WasmWorkspacePage.mockRPC( await WorkspacePage.mockRPC(
page, page,
"get-subscription-usage", "get-subscription-usage",
"subscription/get-subscription-usage.json", "subscription/get-subscription-usage.json",
@@ -41,16 +41,16 @@ test.describe("Subscriptions: workspace", () => {
test("Enterprise team should not have 'Power up your plan' link in main menu", async ({ test("Enterprise team should not have 'Power up your plan' link in main menu", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await WasmWorkspacePage.mockRPC( await WorkspacePage.mockRPC(
page, page,
"get-profile", "get-profile",
"subscription/get-profile-enterprise-subscription.json", "subscription/get-profile-enterprise-subscription.json",
); );
await WasmWorkspacePage.mockRPC( await WorkspacePage.mockRPC(
page, page,
"get-subscription-usage", "get-subscription-usage",
"subscription/get-subscription-usage.json", "subscription/get-subscription-usage.json",
@@ -69,16 +69,16 @@ test.describe("Subscriptions: workspace", () => {
test("Professional team should have 7 days autosaved versions", async ({ test("Professional team should have 7 days autosaved versions", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await WasmWorkspacePage.mockRPC( await WorkspacePage.mockRPC(
page, page,
"get-profile", "get-profile",
"subscription/get-profile-enterprise-subscription.json", "subscription/get-profile-enterprise-subscription.json",
); );
await WasmWorkspacePage.mockRPC( await WorkspacePage.mockRPC(
page, page,
"get-subscription-usage", "get-subscription-usage",
"subscription/get-subscription-usage.json", "subscription/get-subscription-usage.json",
@@ -105,22 +105,22 @@ test.describe("Subscriptions: workspace", () => {
test("Unlimited team should have 30 days autosaved versions", async ({ test("Unlimited team should have 30 days autosaved versions", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await WasmWorkspacePage.mockRPC( await WorkspacePage.mockRPC(
page, page,
"get-profile", "get-profile",
"subscription/get-profile-unlimited-subscription.json", "subscription/get-profile-unlimited-subscription.json",
); );
await WasmWorkspacePage.mockRPC( await WorkspacePage.mockRPC(
page, page,
"get-subscription-usage", "get-subscription-usage",
"subscription/get-subscription-usage.json", "subscription/get-subscription-usage.json",
); );
await WasmWorkspacePage.mockRPC( await WorkspacePage.mockRPC(
page, page,
"get-teams", "get-teams",
"subscription/get-teams-unlimited-one-team.json", "subscription/get-teams-unlimited-one-team.json",
@@ -147,22 +147,22 @@ test.describe("Subscriptions: workspace", () => {
test("Unlimited team should have 90 days autosaved versions", async ({ test("Unlimited team should have 90 days autosaved versions", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await WasmWorkspacePage.mockRPC( await WorkspacePage.mockRPC(
page, page,
"get-profile", "get-profile",
"subscription/get-profile-enterprise-subscription.json", "subscription/get-profile-enterprise-subscription.json",
); );
await WasmWorkspacePage.mockRPC( await WorkspacePage.mockRPC(
page, page,
"get-subscription-usage", "get-subscription-usage",
"subscription/get-subscription-usage.json", "subscription/get-subscription-usage.json",
); );
await WasmWorkspacePage.mockRPC( await WorkspacePage.mockRPC(
page, page,
"get-teams", "get-teams",
"subscription/get-teams-enterprise-one-team.json", "subscription/get-teams-enterprise-one-team.json",

View File

@@ -1,14 +1,14 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import { Clipboard } from "../../helpers/Clipboard"; import { Clipboard } from "../../helpers/Clipboard";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; import { WorkspacePage } from "../pages/WorkspacePage";
const timeToWait = 100; const timeToWait = 100;
test.beforeEach(async ({ page, context }) => { test.beforeEach(async ({ page, context }) => {
await Clipboard.enable(context, Clipboard.Permission.ALL); await Clipboard.enable(context, Clipboard.Permission.ALL);
await WasmWorkspacePage.init(page); await WorkspacePage.init(page);
await WasmWorkspacePage.mockConfigFlags(page, ["enable-feature-text-editor-v2"]); await WorkspacePage.mockConfigFlags(page, ["enable-feature-text-editor-v2"]);
}); });
test.afterEach(async ({ context }) => { test.afterEach(async ({ context }) => {
@@ -17,21 +17,22 @@ test.afterEach(async ({ context }) => {
test("Create a new text shape", async ({ page }) => { test("Create a new text shape", async ({ page }) => {
const initialText = "Lorem ipsum"; const initialText = "Lorem ipsum";
const workspace = new WasmWorkspacePage(page, { const workspace = new WorkspacePage(page, {
textEditor: true, textEditor: true,
}); });
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
await workspace.goToWorkspace(); await workspace.goToWorkspace();
await workspace.createTextShape(190, 150, 300, 200, initialText); await workspace.createTextShape(190, 150, 300, 200, initialText);
await workspace.textEditor.stopEditing(); const textContent = await workspace.textEditor.waitForTextSpanContent();
expect(textContent).toBe(initialText);
await workspace.waitForSelectedShapeName(initialText); await workspace.textEditor.stopEditing();
}); });
test("Create a new text shape from pasting text", async ({ page, context }) => { test("Create a new text shape from pasting text", async ({ page, context }) => {
const textToPaste = "Lorem ipsum"; const textToPaste = "Lorem ipsum";
const workspace = new WasmWorkspacePage(page, { const workspace = new WorkspacePage(page, {
textEditor: true, textEditor: true,
}); });
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
@@ -42,9 +43,13 @@ test("Create a new text shape from pasting text", async ({ page, context }) => {
await workspace.clickAt(190, 150); await workspace.clickAt(190, 150);
await workspace.paste("keyboard"); await workspace.paste("keyboard");
await workspace.textEditor.stopEditing();
await expect(workspace.layers.getByText(textToPaste)).toBeVisible(); await page.waitForTimeout(timeToWait);
const textContent = await workspace.textEditor.waitForTextSpanContent();
expect(textContent).toBe(textToPaste);
await workspace.textEditor.stopEditing();
}); });
test("Create a new text shape from pasting text using context menu", async ({ test("Create a new text shape from pasting text using context menu", async ({
@@ -52,7 +57,7 @@ test("Create a new text shape from pasting text using context menu", async ({
context, context,
}) => { }) => {
const textToPaste = "Lorem ipsum"; const textToPaste = "Lorem ipsum";
const workspace = new WasmWorkspacePage(page, { const workspace = new WorkspacePage(page, {
textEditor: true, textEditor: true,
}); });
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
@@ -62,15 +67,17 @@ test("Create a new text shape from pasting text using context menu", async ({
await workspace.clickAt(190, 150); await workspace.clickAt(190, 150);
await workspace.paste("context-menu"); await workspace.paste("context-menu");
await workspace.textEditor.stopEditing();
await expect(workspace.layers.getByText(textToPaste)).toBeVisible(); const textContent = await workspace.textEditor.waitForTextSpanContent();
expect(textContent).toBe(textToPaste);
await workspace.textEditor.stopEditing();
}); });
test("Update an already created text shape by appending text", async ({ test("Update an already created text shape by appending text", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page, { const workspace = new WorkspacePage(page, {
textEditor: true, textEditor: true,
}); });
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
@@ -80,14 +87,15 @@ test("Update an already created text shape by appending text", async ({
await workspace.textEditor.startEditing(); await workspace.textEditor.startEditing();
await workspace.textEditor.moveFromEnd(0); await workspace.textEditor.moveFromEnd(0);
await page.keyboard.type(" dolor sit amet"); await page.keyboard.type(" dolor sit amet");
const textContent = await workspace.textEditor.waitForTextSpanContent();
expect(textContent).toBe("Lorem ipsum dolor sit amet");
await workspace.textEditor.stopEditing(); await workspace.textEditor.stopEditing();
await workspace.waitForSelectedShapeName("Lorem ipsum dolor sit amet");
}); });
test("Update an already created text shape by prepending text", async ({ test("Update an already created text shape by prepending text", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page, { const workspace = new WorkspacePage(page, {
textEditor: true, textEditor: true,
}); });
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
@@ -97,14 +105,15 @@ test("Update an already created text shape by prepending text", async ({
await workspace.textEditor.startEditing(); await workspace.textEditor.startEditing();
await workspace.textEditor.moveFromStart(0); await workspace.textEditor.moveFromStart(0);
await page.keyboard.type("Dolor sit amet "); await page.keyboard.type("Dolor sit amet ");
const textContent = await workspace.textEditor.waitForTextSpanContent();
expect(textContent).toBe("Dolor sit amet Lorem ipsum");
await workspace.textEditor.stopEditing(); await workspace.textEditor.stopEditing();
await workspace.waitForSelectedShapeName("Dolor sit amet Lorem ipsum");
}); });
test.skip("Update an already created text shape by inserting text in between", async ({ test.skip("Update an already created text shape by inserting text in between", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page, { const workspace = new WorkspacePage(page, {
textEditor: true, textEditor: true,
}); });
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
@@ -114,8 +123,9 @@ test.skip("Update an already created text shape by inserting text in between", a
await workspace.textEditor.startEditing(); await workspace.textEditor.startEditing();
await workspace.textEditor.moveFromStart(5); await workspace.textEditor.moveFromStart(5);
await page.keyboard.type(" dolor sit amet"); await page.keyboard.type(" dolor sit amet");
const textContent = await workspace.textEditor.waitForTextSpanContent();
expect(textContent).toBe("Lorem dolor sit amet ipsum");
await workspace.textEditor.stopEditing(); await workspace.textEditor.stopEditing();
await workspace.waitForSelectedShapeName("Lorem dolor sit amet ipsum");
}); });
test("Update a new text shape appending text by pasting text", async ({ test("Update a new text shape appending text by pasting text", async ({
@@ -123,7 +133,7 @@ test("Update a new text shape appending text by pasting text", async ({
context, context,
}) => { }) => {
const textToPaste = " dolor sit amet"; const textToPaste = " dolor sit amet";
const workspace = new WasmWorkspacePage(page, { const workspace = new WorkspacePage(page, {
textEditor: true, textEditor: true,
}); });
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
@@ -136,8 +146,9 @@ test("Update a new text shape appending text by pasting text", async ({
await workspace.textEditor.startEditing(); await workspace.textEditor.startEditing();
await workspace.textEditor.moveFromEnd(); await workspace.textEditor.moveFromEnd();
await workspace.paste("keyboard"); await workspace.paste("keyboard");
const textContent = await workspace.textEditor.waitForTextSpanContent();
expect(textContent).toBe("Lorem ipsum dolor sit amet");
await workspace.textEditor.stopEditing(); await workspace.textEditor.stopEditing();
await workspace.waitForSelectedShapeName("Lorem ipsum dolor sit amet");
}); });
test.skip("Update a new text shape prepending text by pasting text", async ({ test.skip("Update a new text shape prepending text by pasting text", async ({
@@ -145,7 +156,7 @@ test.skip("Update a new text shape prepending text by pasting text", async ({
context, context,
}) => { }) => {
const textToPaste = "Dolor sit amet "; const textToPaste = "Dolor sit amet ";
const workspace = new WasmWorkspacePage(page, { const workspace = new WorkspacePage(page, {
textEditor: true, textEditor: true,
}); });
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
@@ -158,17 +169,16 @@ test.skip("Update a new text shape prepending text by pasting text", async ({
await workspace.textEditor.startEditing(); await workspace.textEditor.startEditing();
await workspace.textEditor.moveFromStart(); await workspace.textEditor.moveFromStart();
await workspace.paste("keyboard"); await workspace.paste("keyboard");
const textContent = await workspace.textEditor.waitForTextSpanContent();
expect(textContent).toBe("Dolor sit amet Lorem ipsum");
await workspace.textEditor.stopEditing(); await workspace.textEditor.stopEditing();
await workspace.hideUI();
await expect(workspace.canvas).toHaveScreenshot();
}); });
test("Update a new text shape replacing (starting) text with pasted text", async ({ test("Update a new text shape replacing (starting) text with pasted text", async ({
page, page,
}) => { }) => {
const textToPaste = "Dolor sit amet"; const textToPaste = "Dolor sit amet";
const workspace = new WasmWorkspacePage(page, { const workspace = new WorkspacePage(page, {
textEditor: true, textEditor: true,
}); });
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
@@ -182,15 +192,17 @@ test("Update a new text shape replacing (starting) text with pasted text", async
await workspace.paste("keyboard"); await workspace.paste("keyboard");
const textContent = await workspace.textEditor.waitForTextSpanContent();
expect(textContent).toBe("Dolor sit amet ipsum");
await workspace.textEditor.stopEditing(); await workspace.textEditor.stopEditing();
await workspace.waitForSelectedShapeName("Dolor sit amet ipsum");
}); });
test("Update a new text shape replacing (ending) text with pasted text", async ({ test("Update a new text shape replacing (ending) text with pasted text", async ({
page, page,
}) => { }) => {
const textToPaste = "dolor sit amet"; const textToPaste = "dolor sit amet";
const workspace = new WasmWorkspacePage(page, { const workspace = new WorkspacePage(page, {
textEditor: true, textEditor: true,
}); });
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
@@ -204,15 +216,17 @@ test("Update a new text shape replacing (ending) text with pasted text", async (
await workspace.paste("keyboard"); await workspace.paste("keyboard");
const textContent = await workspace.textEditor.waitForTextSpanContent();
expect(textContent).toBe("Lorem dolor sit amet");
await workspace.textEditor.stopEditing(); await workspace.textEditor.stopEditing();
await workspace.waitForSelectedShapeName("Lorem dolor sit amet");
}); });
test("Update a new text shape replacing (in between) text with pasted text", async ({ test("Update a new text shape replacing (in between) text with pasted text", async ({
page, page,
}) => { }) => {
const textToPaste = "dolor sit amet"; const textToPaste = "dolor sit amet";
const workspace = new WasmWorkspacePage(page, { const workspace = new WorkspacePage(page, {
textEditor: true, textEditor: true,
}); });
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
@@ -226,14 +240,16 @@ test("Update a new text shape replacing (in between) text with pasted text", asy
await workspace.paste("keyboard"); await workspace.paste("keyboard");
const textContent = await workspace.textEditor.waitForTextSpanContent();
expect(textContent).toBe("Lordolor sit ametsum");
await workspace.textEditor.stopEditing(); await workspace.textEditor.stopEditing();
await workspace.waitForSelectedShapeName("Lordolor sit ametsum");
}); });
test("Update text font size selecting a part of it (starting)", async ({ test("Update text font size selecting a part of it (starting)", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page, { const workspace = new WorkspacePage(page, {
textEditor: true, textEditor: true,
}); });
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
@@ -244,16 +260,18 @@ test("Update text font size selecting a part of it (starting)", async ({
await workspace.textEditor.startEditing(); await workspace.textEditor.startEditing();
await workspace.textEditor.selectFromStart(5); await workspace.textEditor.selectFromStart(5);
await workspace.textEditor.changeFontSize(36); await workspace.textEditor.changeFontSize(36);
await workspace.textEditor.stopEditing();
await workspace.hideUI(); const textContent1 = await workspace.textEditor.waitForTextSpanContent(1);
await expect(workspace.canvas).toHaveScreenshot(); expect(textContent1).toBe("Lorem");
const textContent2 = await workspace.textEditor.waitForTextSpanContent(2);
expect(textContent2).toBe(" ipsum");
await workspace.textEditor.stopEditing();
}); });
test("Update text line height selecting a part of it (starting)", async ({ test.skip("Update text line height selecting a part of it (starting)", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page, { const workspace = new WorkspacePage(page, {
textEditor: true, textEditor: true,
}); });
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
@@ -263,17 +281,24 @@ test("Update text line height selecting a part of it (starting)", async ({
await workspace.clickLeafLayer("Lorem ipsum"); await workspace.clickLeafLayer("Lorem ipsum");
await workspace.textEditor.startEditing(); await workspace.textEditor.startEditing();
await workspace.textEditor.selectFromStart(5); await workspace.textEditor.selectFromStart(5);
await workspace.textEditor.changeLineHeight(4.4); await workspace.textEditor.changeLineHeight(1.4);
await workspace.textEditor.stopEditing();
await workspace.hideUI(); const lineHeight = await workspace.textEditor.waitForParagraphStyle(
await expect(workspace.canvas).toHaveScreenshot(); 1,
"line-height",
);
expect(lineHeight).toBe("1.4");
const textContent = await workspace.textEditor.waitForTextSpanContent();
expect(textContent).toBe("Lorem ipsum");
await workspace.textEditor.stopEditing();
}); });
test.skip("Update text letter spacing selecting a part of it (starting)", async ({ test.skip("Update text letter spacing selecting a part of it (starting)", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page, { const workspace = new WorkspacePage(page, {
textEditor: true, textEditor: true,
}); });
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
@@ -284,14 +309,16 @@ test.skip("Update text letter spacing selecting a part of it (starting)", async
await workspace.textEditor.startEditing(); await workspace.textEditor.startEditing();
await workspace.textEditor.selectFromStart(5); await workspace.textEditor.selectFromStart(5);
await workspace.textEditor.changeLetterSpacing(10); await workspace.textEditor.changeLetterSpacing(10);
await workspace.textEditor.stopEditing();
await workspace.hideUI(); const textContent1 = await workspace.textEditor.waitForTextSpanContent(1);
await expect(workspace.canvas).toHaveScreenshot(); expect(textContent1).toBe("Lorem");
const textContent2 = await workspace.textEditor.waitForTextSpanContent(2);
expect(textContent2).toBe(" ipsum");
await workspace.textEditor.stopEditing();
}); });
test("BUG 11552 - Apply styles to the current caret", async ({ page }) => { test("BUG 11552 - Apply styles to the current caret", async ({ page }) => {
const workspace = new WasmWorkspacePage(page); const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
await workspace.mockGetFile("text-editor/get-file-11552.json"); await workspace.mockGetFile("text-editor/get-file-11552.json");
await workspace.mockRPC( await workspace.mockRPC(

View File

@@ -1493,8 +1493,10 @@ test.describe("Tokens - creation", () => {
const nameField = tokensUpdateCreateModal.getByLabel("Name"); const nameField = tokensUpdateCreateModal.getByLabel("Name");
await nameField.fill(newTokenTitle); await nameField.fill(newTokenTitle);
const referenceTabButton = tokensUpdateCreateModal.getByTestId("reference-opt"); const referenceTabButton = tokensUpdateCreateModal.getByRole("button", {
await referenceTabButton.click(); name: "Use a reference",
});
referenceTabButton.click();
const referenceField = tokensUpdateCreateModal.getByRole("textbox", { const referenceField = tokensUpdateCreateModal.getByRole("textbox", {
name: "Reference", name: "Reference",

View File

@@ -1,12 +1,12 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; import { WorkspacePage } from "../pages/WorkspacePage";
import { BaseWebSocketPage } from "../pages/BaseWebSocketPage"; import { BaseWebSocketPage } from "../pages/BaseWebSocketPage";
import { Clipboard } from "../../helpers/Clipboard"; import { Clipboard } from "../../helpers/Clipboard";
test.beforeEach(async ({ page, context }) => { test.beforeEach(async ({ page, context }) => {
await Clipboard.enable(context, Clipboard.Permission.ALL); await Clipboard.enable(context, Clipboard.Permission.ALL);
await WasmWorkspacePage.init(page); await WorkspacePage.init(page);
await BaseWebSocketPage.mockRPC(page, "get-teams", "get-teams-variants.json"); await BaseWebSocketPage.mockRPC(page, "get-teams", "get-teams-variants.json");
}); });
@@ -127,7 +127,7 @@ const validateVariant = async (variant) => {
}; };
test("User creates a variant", async ({ page }) => { test("User creates a variant", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage); await setupVariantsFileWithVariant(workspacePage);
await workspacePage.clickLeafLayer("Rectangle"); await workspacePage.clickLeafLayer("Rectangle");
@@ -154,7 +154,7 @@ test("User creates a variant", async ({ page }) => {
}); });
test("User duplicates a variant container", async ({ page }) => { test("User duplicates a variant container", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage); await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0); const variant = await findVariant(workspacePage, 0);
@@ -177,7 +177,7 @@ test("User duplicates a variant container", async ({ page }) => {
}); });
test("User copy paste a variant container", async ({ page, context }) => { test("User copy paste a variant container", async ({ page, context }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
// Access to the read/write clipboard necesary for this functionality // Access to the read/write clipboard necesary for this functionality
await setupVariantsFileWithVariant(workspacePage); await setupVariantsFileWithVariant(workspacePage);
await workspacePage.mockRPC( await workspacePage.mockRPC(
@@ -212,7 +212,7 @@ test("User copy paste a variant container", async ({ page, context }) => {
}); });
test("User cut paste a variant container", async ({ page }) => { test("User cut paste a variant container", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage); await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0); const variant = await findVariant(workspacePage, 0);
@@ -240,7 +240,7 @@ test("User cut paste a variant container", async ({ page }) => {
test("User cut paste a variant container into a board, and undo twice", async ({ test("User cut paste a variant container into a board, and undo twice", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage); await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0); const variant = await findVariant(workspacePage, 0);
@@ -283,7 +283,7 @@ test("User cut paste a variant container into a board, and undo twice", async ({
}); });
test("User copy paste a variant", async ({ page }) => { test("User copy paste a variant", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage); await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0); const variant = await findVariant(workspacePage, 0);
@@ -308,7 +308,7 @@ test("User copy paste a variant", async ({ page }) => {
}); });
test("User cut paste a variant outside the container", async ({ page }) => { test("User cut paste a variant outside the container", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage); await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0); const variant = await findVariant(workspacePage, 0);
@@ -333,7 +333,7 @@ test("User cut paste a variant outside the container", async ({ page }) => {
}); });
test("User drag and drop a variant outside the container", async ({ page }) => { test("User drag and drop a variant outside the container", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage); await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0); const variant = await findVariant(workspacePage, 0);
@@ -347,7 +347,7 @@ test("User drag and drop a variant outside the container", async ({ page }) => {
}); });
test("User cut paste a component inside a variant", async ({ page }) => { test("User cut paste a component inside a variant", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage); await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0); const variant = await findVariant(workspacePage, 0);
@@ -378,7 +378,7 @@ test("User cut paste a component inside a variant", async ({ page }) => {
test("User cut paste a component with path inside a variant", async ({ test("User cut paste a component with path inside a variant", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage); await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0); const variant = await findVariant(workspacePage, 0);
@@ -417,7 +417,7 @@ test("User cut paste a component with path inside a variant", async ({
test("User drag and drop a component with path inside a variant", async ({ test("User drag and drop a component with path inside a variant", async ({
page, page,
}) => { }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage); await setupVariantsFileWithVariant(workspacePage);
const variant = findVariantNoWait(workspacePage, 0); const variant = findVariantNoWait(workspacePage, 0);
@@ -450,7 +450,7 @@ test("User drag and drop a component with path inside a variant", async ({
}); });
test("User cut paste a variant into another container", async ({ page }) => { test("User cut paste a variant into another container", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage); await setupVariantsFileWithVariant(workspacePage);
// Create anothe variant // Create anothe variant

View File

@@ -1,15 +1,15 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; import { WorkspacePage } from "../pages/WorkspacePage";
import { presenceFixture } from "../../data/workspace/ws-notifications"; import { presenceFixture } from "../../data/workspace/ws-notifications";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page); await WorkspacePage.init(page);
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page); await workspacePage.setupEmptyFile(page);
}); });
test("Save and restore version", async ({ page }) => { test("Save and restore version", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.mockRPC(/get\-file\?/, "workspace/versions-init.json"); await workspacePage.mockRPC(/get\-file\?/, "workspace/versions-init.json");
await workspacePage.mockRPC( await workspacePage.mockRPC(
@@ -97,7 +97,7 @@ test("Save and restore version", async ({ page }) => {
}); });
test("BUG 11006 - Fix history panel shortcut", async ({ page }) => { test("BUG 11006 - Fix history panel shortcut", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.mockRPC(/get\-file\?/, "workspace/versions-init.json"); await workspacePage.mockRPC(/get\-file\?/, "workspace/versions-init.json");
await workspacePage.mockRPC( await workspacePage.mockRPC(
"get-file-snapshots?file-id=*", "get-file-snapshots?file-id=*",
@@ -112,31 +112,3 @@ test("BUG 11006 - Fix history panel shortcut", async ({ page }) => {
workspacePage.rightSidebar.getByText("There are no versions yet"), workspacePage.rightSidebar.getByText("There are no versions yet"),
).toBeVisible(); ).toBeVisible();
}); });
test("BUG 13385 - Fix viewport not updating when restoring version", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
await workspacePage.setupEmptyFile();
await workspacePage.mockGetFile("workspace/get-file-13385.json");
await workspacePage.mockRPC("get-profiles-for-file-comments?file-id=*", "workspace/get-profiles-for-file-comments-13385.json");
// navigate to workspace and check that the circle shape is not there
await workspacePage.goToWorkspace();
await expect(workspacePage.layers.getByText("Ellipse")).not.toBeVisible();
// mock network requests to restore the version
await workspacePage.mockGetFile("workspace/get-file-13385-2.json");
await workspacePage.mockRPC("get-file-snapshots?file-id=*", "workspace/get-file-snapshots-13385.json");
await workspacePage.mockRPC("restore-file-snapshot", "", {
status: 204,
});
// request to restore the version
await workspacePage.rightSidebar.getByRole("button", { name: "History" }).click();
await workspacePage.rightSidebar.getByRole("button", { name: "Open version menu" }).click();
await workspacePage.rightSidebar.getByRole("button", { name: "Restore" }).click();
// confirm modal
await workspacePage.page.getByRole("button", { name: /Restore/i }).click();
// assert that the circle shape exists
await expect(workspacePage.layers.getByText("Ellipse")).toBeVisible();
});

View File

@@ -1,12 +1,12 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; import { WorkspacePage } from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page); await WorkspacePage.init(page);
}); });
test("Group bubbles when zooming out if they overlap", async ({ page }) => { test("Group bubbles when zooming out if they overlap", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.setupFileWithComments(); await workspacePage.setupFileWithComments();

View File

@@ -1,57 +0,0 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page);
});
test("BUG 13305 - Fix resize board to fit content", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
await workspacePage.setupEmptyFile();
await workspacePage.mockGetFile("workspace/get-file-13305.json");
await workspacePage.mockRPC("update-file?id=*", "workspace/update-file-13305.json");
await workspacePage.goToWorkspace({
fileId: "9666e946-78e8-8111-8007-8fe5f0f454bf",
pageId: "9666e946-78e8-8111-8007-8fe5f0f49ac6",
});
await workspacePage.clickLeafLayer("Board");
await workspacePage.rightSidebar.getByRole("button", { name: "Resize board to fit content" }).click();
await expect(workspacePage.rightSidebar.getByTitle("Width").getByRole("textbox")).toHaveValue("630");
await expect(workspacePage.rightSidebar.getByTitle("Height").getByRole("textbox")).toHaveValue("630");
await expect(workspacePage.rightSidebar.getByTitle("X axis").getByRole("textbox")).toHaveValue("110");
await expect(workspacePage.rightSidebar.getByTitle("Y axis").getByRole("textbox")).toHaveValue("110");
});
test("BUG 13382 - Fix problem with flex layout", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
await workspacePage.setupEmptyFile();
await workspacePage.mockGetFile("workspace/get-file-13382.json");
await workspacePage.mockRPC(
"get-file-fragment?file-id=*&fragment-id=*",
"workspace/get-file-13382-fragment.json",
);
await workspacePage.mockRPC("update-file?id=*", "workspace/update-file-empty.json");
await workspacePage.goToWorkspace({
fileId: "52c4e771-3853-8190-8007-9506c70e8100",
pageId: "ecb0cfd0-0f0b-81f7-8007-950628f9665b",
});
await workspacePage.clickToggableLayer("A");
await workspacePage.clickToggableLayer("B");
await workspacePage.clickToggableLayer("C");
await workspacePage.clickLeafLayer("R2");
const heightText = workspacePage.rightSidebar.getByTitle("Height").getByPlaceholder('--');
await heightText.fill("200");
await heightText.press("Enter");
await workspacePage.clickLeafLayer("B");
await expect(workspacePage.rightSidebar.getByTitle("Height").getByRole("textbox")).toHaveValue("340");
});

View File

@@ -1,5 +1,5 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; import { WorkspacePage } from "../pages/WorkspacePage";
const mainFileId = "3622460c-3408-81e2-8005-2fd0e55888b7"; const mainFileId = "3622460c-3408-81e2-8005-2fd0e55888b7";
const sharedFileId = "3622460c-3408-81e2-8005-2fc938010233"; const sharedFileId = "3622460c-3408-81e2-8005-2fc938010233";
@@ -13,12 +13,12 @@ const sharedFileFragmentId1 = "3622460c-3408-81e2-8005-31859c15ff91";
const sharedFileFragmentId2 = "3622460c-3408-81e2-8005-31859c15ff90"; const sharedFileFragmentId2 = "3622460c-3408-81e2-8005-31859c15ff90";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page); await WorkspacePage.init(page);
}); });
// Fix for https://tree.taiga.io/project/penpot/issue/9042 // Fix for https://tree.taiga.io/project/penpot/issue/9042
test("Bug 9056 - 'More info' doesn't open the update tab", async ({ page }) => { test("Bug 9056 - 'More info' doesn't open the update tab", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page); await workspacePage.setupEmptyFile(page);
await workspacePage.mockRPC( await workspacePage.mockRPC(
@@ -76,7 +76,7 @@ test("Bug 9056 - 'More info' doesn't open the update tab", async ({ page }) => {
test("Bug 10113 - Empty library modal for non-empty library", async ({ test("Bug 10113 - Empty library modal for non-empty library", async ({
page, page,
}) => { }) => {
const workspace = new WasmWorkspacePage(page); const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile(page); await workspace.setupEmptyFile(page);
await workspace.mockRPC(/get\-file\?/, "workspace/get-file-10113.json"); await workspace.mockRPC(/get\-file\?/, "workspace/get-file-10113.json");

View File

@@ -1,13 +1,13 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage"; import { WorkspacePage } from "../pages/WorkspacePage";
import { presenceFixture } from "../../data/workspace/ws-notifications"; import { presenceFixture } from "../../data/workspace/ws-notifications";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page); await WorkspacePage.init(page);
const workspacePage = new WasmWorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page); await workspacePage.setupEmptyFile(page);
await WasmWorkspacePage.mockRPC(page, "get-teams", "get-teams-role-viewer.json"); await WorkspacePage.mockRPC(page, "get-teams", "get-teams-role-viewer.json");
await workspacePage.goToWorkspace(); await workspacePage.goToWorkspace();
}); });

View File

@@ -353,24 +353,33 @@ test("Copy/paste properties", async ({ page, context }) => {
await page.getByText("Copy/Paste as").hover(); await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click(); await page.getByText("Paste properties").click();
await page.getByText("Rectangle").first().click({ button: "right" }); await page
await page.getByText("Copy/Paste as").hover(); .getByTestId("layer-item")
await page.getByText("Paste properties").click(); .getByText("Rectangle")
.first()
await page.getByText("Board").nth(2).click({ button: "right" }); .click({ button: "right" });
await page.getByText("Copy/Paste as").hover(); await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click(); await page.getByText("Paste properties").click();
await page await page
.getByTestId("layer-item") .getByTestId("layer-item")
.locator("div") .getByText("Board")
.filter({ hasText: "Path" })
.nth(1) .nth(1)
.click({ button: "right" }); .click({ button: "right" });
await page.getByText("Copy/Paste as").hover(); await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click(); await page.getByText("Paste properties").click();
await page.getByText("Ellipse").click({ button: "right" }); await page
.getByTestId("layer-item")
.getByText("Path")
.click({ button: "right" });
await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click();
await page
.getByTestId("layer-item")
.getByText("Ellipse")
.click({ button: "right" });
await page.getByText("Copy/Paste as").hover(); await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click(); await page.getByText("Paste properties").click();
}); });
@@ -483,25 +492,3 @@ test("Bug 8371 - Flatten option is not visible in context menu", async ({
.filter({ visible: true }), .filter({ visible: true }),
).toBeVisible(); ).toBeVisible();
}); });
test("BUG 13415 - Grid layout overlay is not removed when deleting a board", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
await workspacePage.setupEmptyFile(page);
await workspacePage.mockGetFile("workspace/get-file-13415.json");
await workspacePage.mockRPC(
"update-file?id=*",
"workspace/update-file-13415.json",
);
await workspacePage.goToWorkspace();
await workspacePage.clickLeafLayer("Board");
const currentRenderCount = await workspacePage.getRenderCount();
await workspacePage.page.keyboard.press("Delete");
await workspacePage.waitForNextRender(currentRenderCount);
await workspacePage.hideUI();
await expect(workspacePage.canvas).toHaveScreenshot();
});

View File

@@ -20,8 +20,8 @@ importers:
specifier: workspace:./packages/mousetrap specifier: workspace:./packages/mousetrap
version: link:packages/mousetrap version: link:packages/mousetrap
'@penpot/plugins-runtime': '@penpot/plugins-runtime':
specifier: link:../plugins/dist/plugins-runtime specifier: link:../plugins/libs/plugins-runtime
version: link:../plugins/dist/plugins-runtime version: link:../plugins/libs/plugins-runtime
'@penpot/svgo': '@penpot/svgo':
specifier: penpot/svgo#v3.2 specifier: penpot/svgo#v3.2
version: svgo@https://codeload.github.com/penpot/svgo/tar.gz/8c9b0e32e9cb5f106085260bd9375f3c91a5010b version: svgo@https://codeload.github.com/penpot/svgo/tar.gz/8c9b0e32e9cb5f106085260bd9375f3c91a5010b
@@ -260,8 +260,8 @@ importers:
packages/tokenscript: packages/tokenscript:
dependencies: dependencies:
'@tokens-studio/tokenscript-interpreter': '@tokens-studio/tokenscript-interpreter':
specifier: ^0.26.0 specifier: ^0.23.1
version: 0.26.0 version: 0.23.1
packages/ui: packages/ui:
dependencies: dependencies:
@@ -1705,8 +1705,8 @@ packages:
peerDependencies: peerDependencies:
style-dictionary: '>=4.3.0 < 6' style-dictionary: '>=4.3.0 < 6'
'@tokens-studio/tokenscript-interpreter@0.26.0': '@tokens-studio/tokenscript-interpreter@0.23.1':
resolution: {integrity: sha512-dGjvUJnXRspWYp98FZw43l4cN+0ey/cF5sEJjL3coKc5C7DY7MsKgkmOONizmaZqf13GUIzklTEas3gt3jvrOQ==} resolution: {integrity: sha512-aIcJprCkHIyckl0Knn78Sn7ef3U3IXLjNv9MOePdNR0Mz3Z4PleerldtfLmr1DdXUXiroVSyJROyJrO3TfB2Gg==}
engines: {node: '>=16.0.0'} engines: {node: '>=16.0.0'}
hasBin: true hasBin: true
@@ -6680,7 +6680,7 @@ snapshots:
is-mergeable-object: 1.1.1 is-mergeable-object: 1.1.1
style-dictionary: 5.0.0-rc.1(tslib@2.8.1) style-dictionary: 5.0.0-rc.1(tslib@2.8.1)
'@tokens-studio/tokenscript-interpreter@0.26.0': '@tokens-studio/tokenscript-interpreter@0.23.1':
dependencies: dependencies:
arktype: 2.1.29 arktype: 2.1.29
commander: 14.0.3 commander: 14.0.3

View File

@@ -244,13 +244,6 @@
--assets-component-second-border-selected: var(--color-background-primary); --assets-component-second-border-selected: var(--color-background-primary);
--assets-component-hightlight: var(--color-accent-secondary); --assets-component-hightlight: var(--color-accent-secondary);
--radio-btns-background-color: var(--color-background-tertiary);
--radio-btn-background-color-selected: var(--color-background-quaternary);
--radio-btn-foreground-color: var(--color-foreground-secondary);
--radio-btn-foreground-color-selected: var(--color-accent-primary);
--radio-btn-border-color: var(--color-background-tertiary);
--radio-btn-border-color-selected: var(--color-background-quaternary);
--library-name-foreground-color: var(--color-foreground-primary); --library-name-foreground-color: var(--color-foreground-primary);
--library-content-foreground-color: var(--color-foreground-secondary); --library-content-foreground-color: var(--color-foreground-secondary);
@@ -423,13 +416,6 @@
--tab-border-color: var(--color-background-tertiary); --tab-border-color: var(--color-background-tertiary);
--tab-border-color-selected: var(--color-background-secondary); --tab-border-color-selected: var(--color-background-secondary);
--radio-btns-background-color: var(--color-background-tertiary);
--radio-btn-background-color-selected: var(--color-background-primary);
--radio-btn-foreground-color: var(--color-foreground-secondary);
--radio-btn-foreground-color-selected: var(--color-accent-primary);
--radio-btn-border-color: var(--color-background-tertiary);
--radio-btn-border-color-selected: var(--color-background-secondary);
--button-icon-background-color-selected: var(--color-background-primary); --button-icon-background-color-selected: var(--color-background-primary);
--button-icon-border-color-selected: var(--color-background-secondary); --button-icon-border-color-selected: var(--color-background-secondary);

View File

@@ -119,10 +119,6 @@
(normalize-uri (or (obj/get global "penpotPublicURI") (normalize-uri (or (obj/get global "penpotPublicURI")
(obj/get location "origin")))) (obj/get location "origin"))))
(def mcp-ws-uri
(or (some-> (obj/get global "penpotMcpServerURI") u/uri)
(u/join public-uri "mcp/ws")))
(def rasterizer-uri (def rasterizer-uri
(or (some-> (obj/get global "penpotRasterizerURI") normalize-uri) (or (some-> (obj/get global "penpotRasterizerURI") normalize-uri)
public-uri)) public-uri))
@@ -151,9 +147,6 @@
(let [f (obj/get global "initializeExternalConfigInfo")] (let [f (obj/get global "initializeExternalConfigInfo")]
(when (fn? f) (f)))) (when (fn? f) (f))))
(def mcp-server-url (-> public-uri u/ensure-path-slash (u/join "mcp") str))
(def mcp-help-center-uri "https://help.penpot.app/technical-guide/")
;; --- Helper Functions ;; --- Helper Functions
(defn ^boolean check-browser? [candidate] (defn ^boolean check-browser? [candidate]

Some files were not shown because too many files have changed in this diff Show More