From ca06eda6322e19c0a981da027a73df5b3a7a805b Mon Sep 17 00:00:00 2001 From: LiuShen <3162475700@qq.com> Date: Sun, 13 Jul 2025 13:41:59 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=98=8E=E5=88=86=E5=BC=80=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=EF=BC=8Cdind=E4=BB=A5=E5=8F=8A=E5=AE=BF=E4=B8=BB?= =?UTF-8?q?=E6=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- forgejo-runner-dind/7.0.0/data.yml | 67 +++++++++++++++++ forgejo-runner-dind/7.0.0/docker-compose.yml | 45 ++++++++++++ forgejo-runner-dind/7.0.0/scripts/init.sh | 62 ++++++++++++++++ forgejo-runner-dind/7.0.0/scripts/register.sh | 24 +++++++ forgejo-runner-dind/README.md | 68 ++++++++++++++++++ forgejo-runner-dind/data.yml | 31 ++++++++ forgejo-runner-dind/logo.png | Bin 0 -> 9200 bytes 7 files changed, 297 insertions(+) create mode 100644 forgejo-runner-dind/7.0.0/data.yml create mode 100644 forgejo-runner-dind/7.0.0/docker-compose.yml create mode 100644 forgejo-runner-dind/7.0.0/scripts/init.sh create mode 100644 forgejo-runner-dind/7.0.0/scripts/register.sh create mode 100644 forgejo-runner-dind/README.md create mode 100644 forgejo-runner-dind/data.yml create mode 100644 forgejo-runner-dind/logo.png diff --git a/forgejo-runner-dind/7.0.0/data.yml b/forgejo-runner-dind/7.0.0/data.yml new file mode 100644 index 000000000..690e9483f --- /dev/null +++ b/forgejo-runner-dind/7.0.0/data.yml @@ -0,0 +1,67 @@ +additionalProperties: + formFields: + - default: http://1.2.3.4:3000 + edit: true + envKey: FORGEJO_INSTANCE_URL + labelEn: Forgejo Instance + labelZh: Forgejo 实例 + required: true + rule: paramExtUrl + type: text + label: + en: Forgejo Instance + ja: Forgejo インスタンス + ms: Instans Forgejo + pt-br: Instância Forgejo + ru: Экземпляр Forgejo + ko: Forgejo 인스턴스 + zh-Hant: Forgejo 實例 + zh: Forgejo 实例 + - default: '' + edit: true + envKey: RUNNER_REGISTRATION_TOKEN + labelEn: Registration Token + labelZh: Registration Token + required: true + type: text + label: + en: Registration Token + ja: 登録トークン + ms: Token Pendaftaran + pt-br: Token de Registro + ru: Токен регистрации + ko: 등록 토큰 + zh-Hant: 註冊令牌 + zh: 注册令牌 + - default: '' + edit: true + envKey: RUNNER_NAME + labelEn: Runner Name + labelZh: Runner Name + required: true + type: text + label: + en: Runner Name + ja: ランナー名 + ms: Nama Pelari + pt-br: Nome do Runner + ru: Имя бегуна + ko: 러너 이름 + zh-Hant: 執行器名稱 + zh: 运行器名称 + - default: '' + edit: true + envKey: RUNNER_LABELS + labelEn: Runner Labels + labelZh: Runner Labels + required: true + type: text + label: + en: Runner Labels + ja: ランナータグ + ms: Label Pelari + pt-br: Rótulos do Runner + ru: Метки бегуна + ko: 러너 레이블 + zh-Hant: 執行器標籤 + zh: 运行器标签 diff --git a/forgejo-runner-dind/7.0.0/docker-compose.yml b/forgejo-runner-dind/7.0.0/docker-compose.yml new file mode 100644 index 000000000..8dac2d5b0 --- /dev/null +++ b/forgejo-runner-dind/7.0.0/docker-compose.yml @@ -0,0 +1,45 @@ +version: "3.9" +services: + dind: + image: docker:dind + container_name: forgejo-dind + privileged: true + restart: 'unless-stopped' + command: ['dockerd', '-H', 'tcp://0.0.0.0:2375', '--tls=false'] + environment: + DOCKER_TLS_CERTDIR: "" + volumes: + - ./data/dind-data:/var/lib/docker + - ./data/daemon.json:/etc/docker/daemon.json:ro + networks: + - 1panel-network + labels: + createdBy: "Apps" + forgejo_runner: + image: code.forgejo.org/forgejo/runner:7.0.0 + container_name: ${CONTAINER_NAME:-forgejo-runner} + depends_on: + dind: + condition: service_started + links: + - dind + restart: always + user: "1000:1000" # 非 root 用户运行容器 + command: "/data/scripts/register.sh" + volumes: + - ./data/runner-data:/data + - ./scripts/register.sh:/data/scripts/register.sh:ro + environment: + - DOCKER_HOST=tcp://dind:2375 + - FORGEJO_INSTANCE_URL=${FORGEJO_INSTANCE_URL} + - RUNNER_REGISTRATION_TOKEN=${RUNNER_REGISTRATION_TOKEN} + - RUNNER_NAME=${RUNNER_NAME} + - RUNNER_LABELS=${RUNNER_LABELS} + networks: + - 1panel-network + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true \ No newline at end of file diff --git a/forgejo-runner-dind/7.0.0/scripts/init.sh b/forgejo-runner-dind/7.0.0/scripts/init.sh new file mode 100644 index 000000000..4135dc574 --- /dev/null +++ b/forgejo-runner-dind/7.0.0/scripts/init.sh @@ -0,0 +1,62 @@ +#!/bin/bash +set -e + +echo "🚀 正在初始化 Forgejo Runner 所需目录..." + +# 进入项目目录 +mkdir -p data +cd data + +## ---------------------------- +## Runner 数据目录及权限设置 +## ---------------------------- + +mkdir -p runner-data +touch runner-data/.runner +touch runner-data/config.yml +mkdir -p runner-data/.cache + +# 设置权限为 forgejo-runner 镜像中默认用户(UID 1000) +chown -R 1000:1000 runner-data +chmod 775 runner-data/.runner +chmod 775 runner-data/.cache +chmod g+s runner-data/.runner +chmod g+s runner-data/.cache + +## ---------------------------- +## Docker-in-Docker 数据目录 +## ---------------------------- + +mkdir -p dind-data +echo "📦 已创建 ./data/dind-data 目录(用于持久化 dind 镜像和元数据)" + +## ---------------------------- +## daemon.json 镜像加速配置 +## ---------------------------- + +if [ -f /etc/docker/daemon.json ]; then + echo "📥 检测到宿主机的 /etc/docker/daemon.json,正在复制..." + cp /etc/docker/daemon.json ./daemon.json +else + echo "📄 未检测到宿主机 daemon.json,正在生成默认镜像加速配置..." + cat > ./daemon.json <>> Registering runner..." + forgejo-runner register --no-interactive \ + --instance "$FORGEJO_INSTANCE_URL" \ + --token "$RUNNER_REGISTRATION_TOKEN" \ + --name "$RUNNER_NAME" \ + --labels "$RUNNER_LABELS" + forgejo-runner generate-config > config.yml +fi + +echo ">>> Starting daemon..." +exec forgejo-runner --config config.yml daemon diff --git a/forgejo-runner-dind/README.md b/forgejo-runner-dind/README.md new file mode 100644 index 000000000..e57248e1c --- /dev/null +++ b/forgejo-runner-dind/README.md @@ -0,0 +1,68 @@ +# Forgejo Actions Runner + +**Forgejo Actions Runner** 是 Forgejo 的官方运行器组件,用于执行 CI/CD 工作流中的各类任务。它与 Forgejo Actions 系统集成,支持本地或远程运行任务,帮助用户构建自动化 DevOps 流程。 + +> 该容器基于Dind,安全性更强,与宿主机完全独立,基本没有越权,适合组织使用 + +适合希望**完全自托管** CI/CD 流水线的个人或组织部署使用。 + +## ✨ 特性 + +- 与 Forgejo Actions 完全集成 +- 支持自定义容器或直接在主机运行 +- 多 Runner 支持并行执行 +- 支持 amd64 / arm64 等架构 +- 简单易用,部署轻量 + +## ⚙️ 快速开始(Docker 部署) + +### 1. 启动 Forgejo 主服务(略) + +确保 Forgejo 主程序已部署并启用了 Actions 功能。 + +### 2. 运行 Action Runner 容器 + +```bash +docker run -d --name forgejo-runner \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /opt/runner:/data \ + codeberg.org/forgejo/runner:latest +``` + +### 3. 初始化注册 + +首次运行后,进入容器进行注册: + +```bash +docker exec -it forgejo-runner forgejo-runner register +``` + +你需要提供: + +- **Forgejo 实例 URL**(例如 `https://git.example.com`) +- **Runner Token**(从仓库或组织设置中获取) +- **运行模式**(Docker / shell 等) +- **标签**(可选,便于任务调度) + +## 🔄 自动启动示例(Docker Compose) + +```yaml +version: '3' +services: + forgejo-runner: + image: codeberg.org/forgejo/runner:latest + container_name: forgejo-runner + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./runner-data:/data + restart: unless-stopped +``` + +## 📘 文档与资源 + +- 项目主页:https://forgejo.org/docs/latest/admin/actions/ +- 源码仓库:https://code.forgejo.org/forgejo/runner + +## 🧑‍🤝‍🧑 关于 Forgejo Runner + +Forgejo Runner 是社区主导的 CI 执行器,致力于提供安全、可控、可扩展的构建环境。它是 Forgejo 构建完整 DevOps 生态的重要组成部分。 diff --git a/forgejo-runner-dind/data.yml b/forgejo-runner-dind/data.yml new file mode 100644 index 000000000..dc193293a --- /dev/null +++ b/forgejo-runner-dind/data.yml @@ -0,0 +1,31 @@ +name: Forgejo Runner Docker in Docker +tags: + - DevOps +title: Forgejo Actions 的 Runner 基于 Dind +description: Forgejo Actions 的 Runner +additionalProperties: + key: forgejo-runner-dind + name: Forgejo Runner Docker in Docker + tags: + - DevOps + shortDescZh: Forgejo Actions 的 Runner + shortDescEn: A runner for Forgejo based on Forgejo fork of act + description: + en: A runner for Forgejo based on Forgejo fork of act + ja: act の Forgejo フォークに基づいた Forgejo 用ランナー + ms: Penjalank untuk Forgejo berdasarkan fork Forgejo dari act + pt-br: Um runner para Forgejo baseado no fork do Forgejo do act + ru: Раннер для Forgejo на основе форка Forgejo от act + ko: act의 Forgejo 포크를 기반으로 한 Forgejo용 러너 + zh-Hant: 基於 Forgejo fork 的 act 的 Forgejo 執行器 + zh: 基于 Forgejo fork 的 act 的 Forgejo 运行器 + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://forgejo.org/docs/latest/admin/actions/ + github: https://code.forgejo.org/forgejo/runner + document: https://forgejo.org/docs/latest/admin/actions/ + architectures: + - amd64 + - arm64 diff --git a/forgejo-runner-dind/logo.png b/forgejo-runner-dind/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4e5f549489427adf7c4cc57d92480a5762a71886 GIT binary patch literal 9200 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGqB>(^xB>_oNB=7(LBZWysK~#8N?VSmj z6vf%c7mz~{Q3M4=j2e{$6@w2RJP|d41P_QoG(`OrR3d^0Dk6e>C`!N(6%h#@AreVE z@cO(lF@P5;0zsBNU{B6v+50|b=Kbp5U9~hz&20Bf%}jSq|DNY{Ww*P!s_XsNTUU3d zkx$$Sg+d4Yj1|@C`Gm(8h(h47!mI>?LF0FUK!E=yHkzB8jr5SNm2lVhi5_1dQ6h6h z{9A}28Q|Ko>&x=$V-H^-4zM~JeyWNH@do*{=3D%~Puutci2xkQ+KowObWnwkWr`=h zKw1H35s{&_GwFy`Al69ZW8w>hBOE0aL=g`E9vn)_3q&}Aa15V=??tNLmy{F;L}Bel z`Gm(RkW`E+DJ2j;TEs>w3Po#yq;kub2&@f`u4pL`5g~kG#2?&an7HSvrF@5r{7gcc5FhOACRB5bt-X+=DLl;c0=0R>~KKJJBJUcvc{|`Mxl`ftTyb za{@tYWHlf6BkBqw@migEN+7toVg=ks4S{;*u-m>QTJsm8&tEic?ej$IR}vL`Pr>?n zQq}egp?C?;2t|W}Hft`I&jK7;&peSSj5FZj%3Gn*thZ zDX`{cqH(N>Z($~L^jHj02+`=C?nJ8>GY^j~(z~@$WF>SDxIu0Xx1Is_@724AZerDo z!M4o7RT;)7lR6Q7JTGRExDi%5_uz{ocF+cg-kW1ajd+Vg7(_C$1JQ=J%uFc2Eq=gC z=A#R6so(i93x&yJOm}ppO5>Kj$qa{WLSS5eG z+*pk^oN0{dOvd6HoDmKV2eTTS(}}fq*l>olAx4N}9*aDymr!tD4h71}iSoZATC!XsMmF!tpZX0nuvd7}g{=nwf5kiXx&%2G}3`Lx4Co=WCvTS`sM|Rtg^# z7{aJw!r1fyg_d4VH1ROA>*RD?5Klusm{3D(Fdr)2X=dCmg`0@(Vq&)w`EVT^_x_{& zWcBz0@en~)SE2NOQSkX2*g(6BDGV`wkU3DY3{HFZkrev=tpnpC2LwM|WOfl{XGbWt!T@+j~iRi(;iP_o_i?Oj!XyFwUs@Tsn?+l}Zd`HK& z%g7^0Xlftx91p`v5~A}r=}ENlRz39A^r)go3x8r!0plsz zHLM1K+;cRAN_O!Ry$LHxe9&1OR9{V@zu!i5d;8d*uSk@k%QuO&{@8gN3oGt0yO6SL zSPfBz3553L@Dt-lJpGK7B0eN~Ixb-pZX|m295Z6Lahws(kk>m8CtACd7bHqvzt5RK zigWpi@k2Dm@qm>gKIkS6V@+V~OQw^dOXVeTz>rtiC-cn$Ma$a{ITJ|HHhyCKiN`Vm zD}{QJvEms|g3YXjdVQKX2zUEfBa$)44!%4g>VdP-z>l=D?o1NG)Th357cS=v@Z1A=Q| zW-q~rZ^)~Hl|mibt(4c56TN(kIron)mCPBuWN=(2^3ci$DTKuvr#wB}oRpBIZ8af~ zXGZW76N}10J1d16v>S6YvGV-wW^?16SG!a)gX7+F6w$iB^OD*G@6ob5V;bvR1G*|OOfAFl!kL(Q zmZcTWkUkoMDLsh(G?YTmT}`2-*HGx`UlTocF45iHoTrO?|1OOJ8R56lCz7NJM2JHh zf#j_xn%>WJNV~12Duc6P8W~UWVS7Bfci26PY1OH{&Be+2Lx|>Gbg1F?cz-T-5F_uh z^uw7DB18tUz=YuNd#CpS=P$YSbdE%c0}hBqH%y&Q zIfiK2c%oHLvDSATQB{%olIa@OkHt7aQ3C&d?H&s5J$O4tv{f3Y zYoOqw-y~M#!f-vj6#JcrT@yV7nD&j>xR2oC~bi;>v#3#d+`~b371lk)T}cI-#e2Ng;FtT}(9N5mq{9L~{{W^RI>Gw)J>)t>Bz+ zQbebf513<#M3J?cXvS%#@Z%*CL_^s83n^6igX_9ht%+uZot4fRx`+d%2<3ijE|_6V zAaj6NjCZN%fBO@C|E77-M8hIUaQ>xccMEw@B^0D1rhoAYqcZP26y*!VCZRwxh2EZN zemO~X3k%0#P8nP@ib4t8?k&R@xUZO~?vY>!jinQsb`k~uZ;m5>(W~Lwt{C?)?#+0=2_IA7w&%-!r=vm3_p;PprhAP$)9;-HbKxoX7 zLNETFf^{{n9k3cgsjp$UE{f;i9}nR+~hSgWj~GwF(*D8gzswFs2$ zCmPM2J63}@FesngnLTLGieLPE~D8gzuJX#IR8Nuo*qH8P;9;;!XkFP`d zcoz70q$t8_I6S%u#Q2UMoLc7WP7P}wh#($c6G(NU7KnD@0NAyQ87G;;J2hi__pLl( zAFmV6-&rloiDu`cn+f85c6MIfZ^tk=#|JMxv`Nn=Jn-{yV{KN;a&VGP0tpotn&Lp$ zNaplT3^P}=`ty{1yiO!vXEl8&Itil%d~O*6LF+GbdMAc)%zqZ~gne{|)%2kt+-SG{ z@$O7D0>SyePoqG=7M`$=&am1}5tfX0w#7S~A&m$7k@4PMAMIhaeK5L>Jz9ADJT(yn ztMJRl5j8dNguO?wzMcYQWmNUiN3?h9RN66iEahHs0cG~?O<5F14v7~qCKzko}faA&{{wf@H1bDZ87dJ$oqcvdfeR!)ih#__=G`IBMFp zgJ046Km!p4V*R5w;8Vo-pk%B9!2lm?Ao<_%gxyQc+O?E3c(5_fP$>?piF9)>x{&JA zf8bZv3s&1H0G_8-B@pbv%3seDb|-b4H&ZqnREt)=wPUL^5lwQ>A8gEw=|IE?q9rN? zf>|sV3#752fVQ7|ZbHN%Oo*iL$}8bSJSX18x=7Ay+XTPVar|MBLIT-!!`Ot1Ll~}y zu};xL5AmFMm#`5;TT(y>R`!cpy*%xS|Jjz{{Ly^f=tK?5m&_;AV}HjMHvxrDY4_^GjWBCanx zKb&FZy(xP$FSR!jdSJC};tRxvMJbS`UAw62{r73l-FMUWL4zp0efxvN;M4(C7_JKe z6kIXF*pt^E1!B`|2qe_pOqDBF8are&k3Zfuq7a6BAaa!d^PfD&_SpZ#e4{LO%7J50=8{F; zf2fSrb_$RnfmASI6pk82na3Q{A_}(%119nl?NqFYgtD})CazO>)kuD(cVV@i0>oJ$ z_zpAbA=HM0;Wp2*kmx>esBoJDdG@nM1hU;IN2zMN_Bpn-U!b zS6yYKBfEyxgg}~i@8oBC6IS~vK(qp}h$H(*?}|eh9DB!auA*Q?^qUFob}MmQ)(L(1 zS>Aqy zojX&`dFN5-bI(!jS6@*>Ru)x%_#qWPI)}EOb9T!vUc2IeVVtt>(MS2s_cqKUQUJRG znaT#_-Ar*fafnz=IG`|GABKqm7#z-yInB5AdgA}Xne2R-;aH@n3;L8K5_SZ_2IUpQ zSS7c2<`B`E)%mQ3zisc|-*~!j_nmjr{sjxDbm>y6eB%wOVl8{s2Ok`2?Dv)LzH2<( zWKGAeS+C#PWXFdy91o#Z{No?|#(N*;87V+p0=YAdDu=V~1``KbKUw9gvewR*(d|ge zzw9z&3r9mn2G4MG)NR^C+s-`GaU@Y;xE`Wi&Uu4)ZuEe8M+y*0AQRIlFwWdU63?{` zAqqI})=r%$cko~;n*IM33LXG(9EIDr_V@6v^;KKX>_Kp&Wg zqyXUr!p0p{Bho0dQ~aC>=|X&%5h{85$%MTPeeVNPjffaekqF@x5q=k?c9eR^WQX&7p1rqZXMFv?~`FU2Orfv-}Pz4#)9G~E%N zx&oP$Mm1OvjMJ=@;XFNiQt8qq6s)b`8A&`9uPmp`<9i!XOjS9N4uqFG=v=D(Y7K>g z`o459H3h<=NAQ+3+H+QXqK6@lqmP!pZz>toZ%H@a$(7!&T}<6BAq@Q7H+wcU?V!OtV zqo%z(wT>EA41uKF6NMAhM-SmhcvmhyUgKsO^YV;!mz_2!xG48poP_Zke+?HHZV2)vq5l7kl?b%|3EcPat=uQO>bui!XC{rzWCD z#qwqRLO!~YS^~LWZTAY|$h&wbzle{Hw2VQt|NOyyM^oKMb=@l%ra>DsHu8)3=tSy$ zA7tv$RB?$pzb|ukr-taU?X=VQ1$=Zv%aZo=&+XzyTOU0L}69}xict20vM>h~Cqyo{Fn%tJJ zLCKuni6M=G;lqv3Jp1U0HBcN9LA0FBs?DRUp2x%-JzyAr?4EcB1sfZA;yyZ)8UiW( zfwGS6u0$Z1-Yr|akTmU#rabWfun`1U|ELYc-%(bNZps8wv+4t$u#axEDG(iL`u0Q0 z>~@4Yfqbgp`=5MFS_gGk#NQo|1!#HTI71%Z|ne#~)K+VIlu(@^CB=fKj~;Lh%J+AG|E>*=L`nv(7q;(pXtr zTbC|f=*lavq_qxTuexK$4!ZyT`{|TZPB|paBaS$Nh7B7=Z@>LEKRR*1zay>t`2ulh zItwH(FOP-{8FGjNhqH$tewd#bnO9zUg?jbsB~7EXU48Y{RFa^N41t&gqJubqFOas$ z&(EhH{pd$hr;TL4_{A^i=9_P(n{K*EYQO#MZ>8r&vUAQkhxYB;$8#2cBKdhlfdCzz zGV}!!nWm;DI{*ChrOuixyX>;dBDU-*K>BU@cbftMUXLWcKq7-Nhs;TnZ7;m=0?%Rc zuq6<$M-g8j;c0Aaq|;A7UFx7t4Be?Ozx2H-$#rb^() z$|DHynm~eebyV`y0?It@I71vN1cEfO`t+eacTS>a<_KPA-n@BI$8>5~Kol$DMMXu_ zy?b}*aZc^Q2Ol)jREd)@wIhK*bzTt(K4`Oh!UW^f$Ex0_C=BVraxb`m8e-gfk!)Un z{dK8hI<>xi`x@Iw00#c2o_ebEIH$IF@nR!QRXB+rz_CD_B%Unlw```|Aw!f!4VfWb zh$Q=zQ>f0vgLbs~ojZ4yI;RuE3b>UqW5!62b86pz|2j`w z4;e3(PLw!=36T^GyOiak!OV=um_2*8)Jfa2u3fv*mMvR&DhC7M9d_7Z((~G~>#n+$565!n~x2Ll~~R_3$I8>@Q1sj=aY&fB8$Pvxc*7-MSgib422` z*IuLc?b}Pw4`lA)A!!U-)xk)1CyA*zyRp5Zz37T8Y(2StlN zZrnJ!^wLYIXV0F-A|M`WI{D<2=~_0%!_$CH>%F?V+E^98;DQT`ZkbgO*k(U``0$qQ z*r-vX_*tVvDFL|X2PmI{E&9ta2;hF zd8DJXacn-T?53SNd1~H42n4oy^Je3B*gk^CY%v{NS665JE>`e#A@*2(_St7f6vFyR zc6K(kYu7F=0*M7B0zn8%mQb2@6tplkG6yMCZe$iLj&6pj?%Qu^TmSyHx>`6UXW&53&1T(t>#Z%V zcw2@+bw)-8KQl7eS;Cgke_4EQ8Hf(5_VvWXr{_~$p>)UBWYHfJ7-7dI(JjTIsiy-I+##7Z zQnZ!kqTQ6)qlYbl7&A*(UB%Cgj(sy{*qRW)-?y?zQ_rVL-3%7(R6Gwddh}?XqRII2 zpY2{$ zJhuVEOB(R927uNaQ^K<2oZ3q-y=0^rj(GP{JTH)(!GpQ;%bnF~7&w2}n9(aICK;l)H+ONNMBoH|H_Os8n-MR-#_tTEwTy0w%I0libZ25AYg1cF= zWQo)F(um2bVtQ;<{p z^*YLR(1n8`ZLGN0@!ha)=WEu$$Q;wDU3~GyJVlesFTY%RoKySclTUbxCW#aWNcb2e z9@BAqrc5!qH8O{lnQ(a6_JISbbm2m(UH?5%Lj^S!7Et-$|4!S_JFg{b*cAs1(PPIA zH&TGLqFw;6=sE4Q)1=Pn#BRCe7Gvu=)>Jla+C)=Woyd-JVpwFXtgPfYJs^%ml9WMu zJhr1iAWj@vI6g#xbK%%{WEY12k479uWa`(CYU1=h*?95flTS(=)QO3WhT;AljbVIb zCDGylNf8LZ#zvK4vUKTE!?B$>v`Q0V+dJh>o+Iyo>DgG{K%(04W_OHb0Q@8w8(~4x z1Oim|CAXh>rlYQwDih+^e%4u@SR9mr{Zzes_m(a;Su z_uhN?nUTS_3}xrb49|+-=|TX%NJh8HO40>_n;=XDm2bU8TOB?}9*c?SQT)fpc@De{ zo;%0XYPf+r#uj)z(5h9d_!;)VS8=bn;tJ~6v7!*z zaDy-et`vx>&|34w7nIGq3Mxf{bd2;^SEJ@LXWa~+wn@bH5hu7xAOeU()!+KnN4@yBV~fB}?#nEBnpa0YQ;WxQzCENUt$;%ED) zKtu|+b*Wn834y5WavemV$#^Wb@|}06Hfkc7K!O%@{%k-z{ zGKnZ5^4mJkK5gR*L=iFv6s>kVqYbVhgdh<4@C6YoME?(g_Em~hTAP3X0000