From 4548f69de868586742e05e216754cc873ccb56d7 Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Fri, 24 Apr 2026 13:19:04 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A7(addons)=20introduce=20initial=20Mi?= =?UTF-8?q?crosoft=20Outlook=20add-in=20support=20(alpha)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provide the minimal components required to support an Outlook add-in: user authentication, JWT retrieval, and API calls to generate meeting links. This implementation is an early alpha: developer experience is limited, documentation is incomplete, and the solution is not white-labeled. It's too early to consider these parts ready to ship into production. As a result, it is currently only available within the DINUM frontend image. --- CHANGELOG.md | 1 + bin/Tiltfile | 3 +- docker/dinum-frontend/Dockerfile | 21 +- docker/dinum-frontend/nginx/dinum.conf | 76 + src/addons/outlook/.eslintrc.json | 8 + src/addons/outlook/assets/add-16.png | Bin 0 -> 396 bytes src/addons/outlook/assets/add-32.png | Bin 0 -> 678 bytes src/addons/outlook/assets/add-80.png | Bin 0 -> 1472 bytes src/addons/outlook/assets/icon-128.png | Bin 0 -> 1711 bytes src/addons/outlook/assets/icon-16.png | Bin 0 -> 307 bytes src/addons/outlook/assets/icon-32.png | Bin 0 -> 544 bytes src/addons/outlook/assets/icon-64.png | Bin 0 -> 927 bytes src/addons/outlook/assets/icon-80.png | Bin 0 -> 1115 bytes src/addons/outlook/assets/logo-filled.png | Bin 0 -> 4022 bytes src/addons/outlook/assets/settings-16.png | Bin 0 -> 353 bytes src/addons/outlook/assets/settings-32.png | Bin 0 -> 756 bytes src/addons/outlook/assets/settings-80.png | Bin 0 -> 1784 bytes src/addons/outlook/babel.config.json | 12 + src/addons/outlook/manifest.xml | 190 + src/addons/outlook/package-lock.json | 16211 ++++++++++++++++ src/addons/outlook/package.json | 63 + src/addons/outlook/src/commands/commands.html | 11 + src/addons/outlook/src/commands/commands.js | 117 + src/addons/outlook/src/common/api.js | 82 + src/addons/outlook/src/common/helpers.js | 16 + src/addons/outlook/src/common/index.js | 7 + .../outlook/src/common/messageBuilder.js | 52 + src/addons/outlook/src/common/polling.js | 47 + src/addons/outlook/src/common/session.js | 104 + .../outlook/src/common/transitDialog.js | 43 + src/addons/outlook/src/common/transitToken.js | 18 + src/addons/outlook/src/common/urls.js | 15 + src/addons/outlook/src/styles/spinner.css | 81 + src/addons/outlook/src/success/success.html | 44 + src/addons/outlook/src/success/success.js | 20 + src/addons/outlook/src/taskpane/taskpane.css | 147 + src/addons/outlook/src/taskpane/taskpane.html | 56 + src/addons/outlook/src/taskpane/taskpane.js | 128 + src/addons/outlook/src/transit/transit.html | 48 + src/addons/outlook/src/transit/transit.js | 53 + src/addons/outlook/webpack.config.js | 128 + src/frontend/default.conf | 6 - .../env.d/dev-dinum/values.meet.yaml.gotmpl | 24 + .../dev-keycloak/values.meet.yaml.gotmpl | 1 + src/helm/meet/files/outlook-manifest.xml.tpl | 190 + .../meet/templates/frontend_addons_cm.yml | 13 + .../templates/frontend_addons_manifest_cm.yml | 15 + src/helm/meet/values.yaml | 9 + 48 files changed, 18052 insertions(+), 8 deletions(-) create mode 100644 docker/dinum-frontend/nginx/dinum.conf create mode 100644 src/addons/outlook/.eslintrc.json create mode 100644 src/addons/outlook/assets/add-16.png create mode 100644 src/addons/outlook/assets/add-32.png create mode 100644 src/addons/outlook/assets/add-80.png create mode 100644 src/addons/outlook/assets/icon-128.png create mode 100644 src/addons/outlook/assets/icon-16.png create mode 100644 src/addons/outlook/assets/icon-32.png create mode 100644 src/addons/outlook/assets/icon-64.png create mode 100644 src/addons/outlook/assets/icon-80.png create mode 100644 src/addons/outlook/assets/logo-filled.png create mode 100644 src/addons/outlook/assets/settings-16.png create mode 100644 src/addons/outlook/assets/settings-32.png create mode 100644 src/addons/outlook/assets/settings-80.png create mode 100644 src/addons/outlook/babel.config.json create mode 100644 src/addons/outlook/manifest.xml create mode 100644 src/addons/outlook/package-lock.json create mode 100644 src/addons/outlook/package.json create mode 100644 src/addons/outlook/src/commands/commands.html create mode 100644 src/addons/outlook/src/commands/commands.js create mode 100644 src/addons/outlook/src/common/api.js create mode 100644 src/addons/outlook/src/common/helpers.js create mode 100644 src/addons/outlook/src/common/index.js create mode 100644 src/addons/outlook/src/common/messageBuilder.js create mode 100644 src/addons/outlook/src/common/polling.js create mode 100644 src/addons/outlook/src/common/session.js create mode 100644 src/addons/outlook/src/common/transitDialog.js create mode 100644 src/addons/outlook/src/common/transitToken.js create mode 100644 src/addons/outlook/src/common/urls.js create mode 100644 src/addons/outlook/src/styles/spinner.css create mode 100644 src/addons/outlook/src/success/success.html create mode 100644 src/addons/outlook/src/success/success.js create mode 100644 src/addons/outlook/src/taskpane/taskpane.css create mode 100644 src/addons/outlook/src/taskpane/taskpane.html create mode 100644 src/addons/outlook/src/taskpane/taskpane.js create mode 100644 src/addons/outlook/src/transit/transit.html create mode 100644 src/addons/outlook/src/transit/transit.js create mode 100644 src/addons/outlook/webpack.config.js create mode 100644 src/helm/meet/files/outlook-manifest.xml.tpl create mode 100644 src/helm/meet/templates/frontend_addons_cm.yml create mode 100644 src/helm/meet/templates/frontend_addons_manifest_cm.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 992e2bfd..bbcb78f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to - ✨(backend) add metadata collection of VAD, connection and chat events - ✨(backend) introduce add-ons authentication backend - 💬(backend) clarify french transcription audio download link text #1299 +- 🚧(addons) introduce initial Microsoft Outlook add-in support (alpha) ### Fixed diff --git a/bin/Tiltfile b/bin/Tiltfile index 693edef9..2ee909aa 100644 --- a/bin/Tiltfile +++ b/bin/Tiltfile @@ -34,10 +34,11 @@ docker_build( 'localhost:5001/meet-frontend-dinum:latest', context='..', dockerfile='../docker/dinum-frontend/Dockerfile', - only=['./src/frontend', './docker', './.dockerignore'], + only=['./src/frontend', './src/addons', './docker', './.dockerignore'], target = 'frontend-production', live_update=[ sync('../src/frontend', '/home/frontend'), + sync('../src/addons', '/home/addons'), ] ) clean_old_images('localhost:5001/meet-frontend-dinum') diff --git a/docker/dinum-frontend/Dockerfile b/docker/dinum-frontend/Dockerfile index 7e7a63c0..20e2b28e 100644 --- a/docker/dinum-frontend/Dockerfile +++ b/docker/dinum-frontend/Dockerfile @@ -38,6 +38,21 @@ COPY ./docker/dinum-frontend/assets/ \ COPY ./docker/dinum-frontend/fonts/ \ ./dist/assets/fonts/ +# ---- Addons builder image ---- +FROM node:20-alpine AS addons-builder + +WORKDIR /home/addons/outlook + +COPY ./src/addons/outlook/package.json ./package.json +COPY ./src/addons/outlook/package-lock.json ./package-lock.json + +RUN npm ci + +COPY ./src/addons/outlook/ . + +RUN npx webpack --mode production + + # ---- Front-end image ---- FROM nginxinc/nginx-unprivileged:alpine3.23 AS frontend-production @@ -60,7 +75,11 @@ COPY --from=meet-builder \ /home/frontend/dist \ /usr/share/nginx/html -COPY ./src/frontend/default.conf /etc/nginx/conf.d +COPY --from=addons-builder \ + /home/addons/outlook/dist \ + /usr/share/nginx/html/addons/outlook + +COPY ./docker/dinum-frontend/nginx/dinum.conf /etc/nginx/conf.d COPY ./docker/files/usr/local/bin/entrypoint /usr/local/bin/entrypoint ENTRYPOINT [ "/usr/local/bin/entrypoint" ] diff --git a/docker/dinum-frontend/nginx/dinum.conf b/docker/dinum-frontend/nginx/dinum.conf new file mode 100644 index 00000000..6ef89f00 --- /dev/null +++ b/docker/dinum-frontend/nginx/dinum.conf @@ -0,0 +1,76 @@ +server { + listen 8080; + server_name localhost; + server_tokens off; + + root /usr/share/nginx/html; + + include /etc/nginx/extra/*.conf; + + location = /.well-known/windows-app-web-link { + default_type application/json; + alias /usr/share/nginx/html/.well-known/windows-app-web-link; + add_header Content-Disposition "attachment; filename=windows-app-web-link"; + } + + # Manifest — fetched, never iframed + location = /addons/outlook/manifest.xml { + alias /usr/share/nginx/html/addons/outlook/manifest.xml; + + add_header Access-Control-Allow-Origin "*"; + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header X-Frame-Options "DENY"; + add_header Content-Security-Policy "frame-ancestors 'none'"; + } + + location ~* ^/addons/outlook/assets/.+\.(css|js|json|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + alias /usr/share/nginx/html/addons/outlook/assets/; + expires 30d; + add_header Cache-Control "public, max-age=2592000, immutable" always; + add_header Access-Control-Allow-Origin "*"; + add_header Vary "Origin" always; + } + + location ~ ^/addons/outlook(/.*)?$ { + alias /usr/share/nginx/html/addons/outlook$1; + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Pragma "no-cache" always; + add_header Expires 0 always; + + set $ms_domains "https://*.live.com https://*.office.com https://*.microsoft.com https://*.office365.com https://*.sharepoint.com"; + + set $nonce $request_id; + + set $csp "upgrade-insecure-requests; "; + set $csp "${csp}frame-ancestors ${ms_domains}; "; + set $csp "${csp}script-src 'nonce-${nonce}' 'strict-dynamic'; "; + set $csp "${csp}connect-src 'self' ${ms_domains}; "; + set $csp "${csp}frame-src 'none'; "; + set $csp "${csp}object-src 'none'; "; + set $csp "${csp}base-uri 'none'; "; + + add_header Content-Security-Policy $csp; + + sub_filter 'NONCE_PLACEHOLDER' $nonce; + sub_filter_once off; + sub_filter_types text/html; + } + + # Serve static files with caching + location ~* ^/assets/.*\.(css|js|json|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 30d; + add_header Cache-Control "public, max-age=2592000"; + } + + # Serve static files + location / { + try_files $uri $uri/ /index.html; + # Add no-cache headers + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Pragma "no-cache"; # HTTP 1.0 header for backward compatibility + add_header Expires 0; + } + + # Optionally, handle 404 errors by redirecting to index.html + error_page 404 =200 /index.html; +} diff --git a/src/addons/outlook/.eslintrc.json b/src/addons/outlook/.eslintrc.json new file mode 100644 index 00000000..e406c09e --- /dev/null +++ b/src/addons/outlook/.eslintrc.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + "office-addins" + ], + "extends": [ + "plugin:office-addins/recommended" + ] +} diff --git a/src/addons/outlook/assets/add-16.png b/src/addons/outlook/assets/add-16.png new file mode 100644 index 0000000000000000000000000000000000000000..e4e42729948040540b4ffd08dcfc3cb29da39fd9 GIT binary patch literal 396 zcmV;70dxL|P)j~0igoy3P>t2seq&dICH?MAbaFycK{{uCVFFymUWbj^tAHs%$qkKCoW=-^REXS z6QJZ(3;6T#=^FYbk-!FcadGULz2D$ZXPX*v)@R@rl`L$`q?n|Z&=hD029zjR&t qwPM-#e`7$jpc==ldmE^B6JP+r3wT9dbkg!2>PG2V8v0czJTzQL1(x#m!-Sdb zr!Ajm#y5q{<1|DNsRNK2xnk;~FwKgPK$bM{&UD*~{_d;|pG&VYpRlaGXhn)Vt%U{}n?Js$$R zk>N)OR_^#Xa4<4e<6g86iWAcM~cE^O5motTCraosh?? zG1(a~uZ~(i*$i^Qq=@-F0!yuf=rsVIb>J%I`mD%EWe`0@wLL1XLjd=^<>G{h4i>gR z^c28Tv3V(k2`O_xVE$VLwH6@WQXGp%{1%T258v8$ie~Vg>Lv%yHp!T#C68FP}k(q^`mcupWtauM^rVs!U(o%F^Mz%fC6v!S2|rYfhf zPy!ed?849li#G05RQNDJ0I@ayBb^WNA6hsVAb{AK1IfUEU=y+{fafB}cVn7;P|u5O zt%~3OkB(iV))PfI!=Hs+7Wjn4=4`lvlE-IP(IU?kKs|}B0BXt=KusHY1yIvQ`U4G; z$u+EITBY)R_(WjB z0je*y=B((2F*`UOAb@u!0gMI+Ahza15kR!|MJ#*uLSRcUw%()&U_!WWJRtT_HW;M; z0R%^q8MtX*1S3l#H(VAoksU#eqXDRIOiX8^($FU%Xy`s_?V z!!Rw|6=UbqVghCF%WIF>N7|0Q>kJJ4@{z-0^6Iu9N+~U;( z@Pt_+?aV#>MOi&?O<-ZrGgYP>>B!2CbND3{2I@}D7--*h_I)R&s->7zomBc@v@>#( zuI^e@IIVQ?eR5SvpLzyl3%O$#Ll&wTx`@R^0D)E1qfq-Ufmk>{Op(eX9X>(tQw0#C zj;Jm55M_d$xUU2d9Lk*0-X%y7XO24zs@jrHFj0^E#|o5}0r}jOMu`x!ZW+BWOzxXN zdM^yox5~jn0r=4cl?ILYU}{zMrO~DnHQfFuI|6LXTJW+frv5rY>HKq(jd#SPtT#l| z08SaaS^#Q-$iSrnOg>q z181}?m5nB};#+-W?zIEWA->y~ys4F)PN3EcM}U-7_O*@7$m&)x&4!33RQ1JnQ=leW z!G{p1#TLQLAP;|Qs`Xwg|BL{@6i(+3J_8Mwr81Um<49U-|IOh7s3RoKlW}71N^{4* a0t^5ZrZ5)Yhs8Sp0000<59!+iq?cA?Cm0G9x!e{96-01E)bob4!Nx0rE$ zk!AFZt$bQq&QBfEVnN)d*P2HWDv|yk&pRZ#YC1L~ZqgaoL@UctX7&Gx3e+sD88K&| z)>YfT4vgXKUGm&?C*o+wRTvsieA-F|edL|xss9_~2MgQMySsv54Wl3vp-Cdwn3LPR zmDZwRa$+x$G&$G{0nAX)*DGp%E>nG@ChaJs-uSo+VC*Oa#(D;8JmEI@yIn+q{F{^F zylkkxqNfo5FzOsP;#))87>v-4+7*c8cBL?`kp8a|Uxp_KR6yt#( zMzPB+`h*=Uz*!jC%FUScSx)(b&A|ZE*bCVuO;apeU}X>Z1wR`Y{Y*8gW`z#QK43b4 zZbcF~iga-;{1G+xi8`3?DtW%;3_a@+BQ(|$J1DKMPE*o^cIKrm1HaQFtP^k~bjxRVT9*g+$+{e0|aElOQ;_2$|_#mt($>UU!1wSr<OS)rcN;z1(qgQb5Pwk?lTTx`Njz8oOVz7o?SNz%&c~%@z z^{piI)a(}2iywH)!+bD1w)ZDgNS6YkSNk>f>ti6rN)boZ_w&_jwBE9l9wJjQ0-Xb7 zWb&^y3TeWBnG}0h&XjwzYvW({e>r;dLT_bR4ojSV;IFmfvh*xSes0f+AdWvt1IH|M2APIJgO$4D?^P zlc2ZUcgFm1bcEOW+!L$KpNl@gzRd18_;i)3Bl)+`H zkxY1ySTH+kKlqEz7_V)t!bCdW4@N43EZ~G-s{?r$(*1!9sJ|0N%aj2-*7$=%MKZui z3e^(ogJp*;Y*JmD0PJ$LPr5T>Q{$HArG~K#t5odNafQXD)j~~RyObxVU?P`WI_fYR z4R+SPvFwpGA?N1FBTvM9&(oO&b+DLgdEV|q%Lw82JsM~qJo-!+cm9AW%Tu`>P6%dn z`u5+wZ8E(lf;?M=ZmvDV{*?aFGk0VXdnDUC61gV=-Gg{urH}FrRZW*Ak`vHm+EtqP zI5EgsUL|=XPPgr!LbEPa;osZ$?qnF7l~^od@@v(he2MvQjU0jBxwH~B#EmRf%LF7K zcwphAo|a*?8W}hzrNa{~YxPuXwh^^{6{B(3!YgPy{@X>uAZ&GDJ#lo|^}jEP7BnJ@ z@Va7qZ0^w0foX<;WPqcya;1u?j}{M89r;n4B{|){@;%>{Ue{kN|L!_ezZ_lUSA?Y_xrfoRcf?&IX|AK;3!`Hk6nbAsMqS0&l;@3lMM+H`6x zW-bu*=MgAKIyGciT>UE^ zJYmAb_GNK4n>53b=Z$SQ(*NIlz>#A9$dKcilSsbNK^EWtcNrv)$bb0Wp?KxK3!|Dz z9piKoAXi9w0}6&Qd!% zlET8uc!O{P;RGQkAe;bh08|zhKxb)bXO55?=pX&~*0`I1o7F=8d!M}QZkWF_vpeH? zC;WGGniia2?E*X!@PjGdr#$yV08@?~a8(cyu0vo#$^>2gm4IJMLKi5S1e6Yps{eUgCqe|Q9SHc$ z6*ew%pJ*ExzrVX*m?kZDpQ!^ZOp)$V+vh;k(nTX1iFDY~pVuuQ2zzNI*o~IRZ%eIo`V4!vF6;M5;Xjr1*$Fe3Hopo?}B2 z+#){MlIHH$@N-qL6>KgQ9}ur*aM@j!ne2*-)(!kz6)}j2TU34xw><~DUSOBx@~|a8 zS4D(}JT_3g%6f-(!9_kIybfUHJr!$!@_Uj|$!SX`cTuR3@)lfgkIYj?`H_V3r~5m( zAThA?gpcQIQ~47<3E*5z;?dz0fymO#5<MZJd=)4kDk%Tg1>T=tMkH&Jfq)23M?+L=w=t1O5jtj!)(FUODl#N9M$|_FtQr|(aibu4aRQ_> zMpxXyX?VRbW1x@U_ML!y#+c>4-`xuV8D4W%klY&qy{rQa0evSR?YIufJrPh;S1j+z z1(KqM3`LhR0ZE4lNK1MUPo?s7z8tDXG{`kpg6zranpebo&m7_U$e}HwNl~M82bB_Rc|CFCK9LTUpzh^ek&9^7nvl( z+{3A!$mR|zM`W<#!+V5-D-dw?S)s~G5E&xd8oLxYVh?%u>Dq%*4>BjASmM>-2-Yxb zv9ep-a$fME&dJCW9^ylj86qZhg81Jap*S{jVQ`BLgf3hOi!CJi!>|yaWNJFg5^l z%K$IIO<+8qSzMV8Fs3eo^bNxs!@~?lSMd;NkqZEs-V{IpHzaUFL!T=li#)a(Ab{%< zxN!xa4dJ~2#ChugD#kfgSsfpJ1$dZQml|Yetnp)!HnYRtj zJOa;u5CTXCSXLD0bmAjk#HwO==xytqFooxj&>Q@c157AMbUZt?C$~;3fHx+1pT=f5 zZ_h8tu4@b2wGp?5>t73cT)tH3x*}_gbRbf=TGJF%L{ZQZc&O87CkU$W-X!3i z6yyX)XD9XqajgIk-}g@M*DqrnjDgo0i5A{84SiMgx+utd7Hb?B5x#&5Sl2X@$h2A^ z%a=HjPM4(#g+;R#xTYl)$U4fmz#NNAu;#&7$U#BOGd8OV&PxD*h@)Qu@klME(EHc7b4|}C4;EZm9{!BhxQ5X!0f~twCX2K& z(R5^8TgL*gg(m(RAkJZQ1VGxDvHNwLq%4WdGLQoCF(r^OwR~9^WpdP4=X@G|t1GqAI&B2%5_ropu zFRh&!d4^hSK^1Yq6735h;@^5juaO0qwh-V>z!I^=wlx9pTifEF$l4fc_@X-}S^yyq zZd>NY3(2^MEw)(40zI!ieLCF8C~Z;no>(@yd;kP1Oew{?tfP)05X49Z;zc115T~BI z&CZXN^O|K2zCRSq(EI;pA^> zw(-Se!A*A(^X_XSylLTF7$ELpAVgbN7$jtMmBwwluiYby#L>&(p@deb((Ovs-AXBZ z5z+ON_Yb>2ir0j0WzC-AJCPRwfKzq@kS|_y`{goswJOO;wX?{rBbtoYS$HqVb*!rp zl=^`*a|ylb7Y=O++}zgP>&gvPbnCNhZQ3%jZCfML*|m`vSOW4u@ew<{y8kz!mTjz7 zSYQswEZeHAP(7Z-Ij5$Rccu>r5Ye3zT9Ht;V+cWSvZ~%=<<^khyyt0yAB)9eu~;k? hi^XEGr1e*T0RY$z#@i#70;~W4002ovPDHLkV1jv#@PYsU literal 0 HcmV?d00001 diff --git a/src/addons/outlook/assets/logo-filled.png b/src/addons/outlook/assets/logo-filled.png new file mode 100644 index 0000000000000000000000000000000000000000..756353cd14a6f887e62e463af93f2245db4f3047 GIT binary patch literal 4022 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 F?teT7m3aUF literal 0 HcmV?d00001 diff --git a/src/addons/outlook/assets/settings-16.png b/src/addons/outlook/assets/settings-16.png new file mode 100644 index 0000000000000000000000000000000000000000..58c5a7f8c2cf5c8e05f5a96acd0763deb641d87a GIT binary patch literal 353 zcmV-n0iOPeP) z2g#~Y9>ri4VvI{j58aB0{QS$$WY_-AZvh4Xs$_j4N@$0B00000NkvXXu0mjfQJ;^} literal 0 HcmV?d00001 diff --git a/src/addons/outlook/assets/settings-32.png b/src/addons/outlook/assets/settings-32.png new file mode 100644 index 0000000000000000000000000000000000000000..08159045eaf7f029c5fb4576cfc09d723df8f64c GIT binary patch literal 756 zcmVHhqh>{H}rXBhAnVfh9|^h4$4iONR<*rq8m^TYsb#q$## z?(y}f7y#biz{i{`hfrVQf$uGk0Pr?v*8p9{Fy51Q_$sVb-XY)ed*jz(-+(MtithpBO*|c8FZ=NqK9e35|Gw6Dw9s-IJ_=P~I@q zYdB*|IfWPbFvK;5-lFCx0%ZAb#?XSWh5JCFBHqX}=0@w>x{s$j@%&e3K@W5B=T8c| z3*`Em58l1D@xm2Q{L2;-}8{pBP zcrKi)Pr87N;1ymef|f!M^6$0W3Yu|%;+<3o##dGknkN(9n!Z!OYj2!0fT$GnW6&(< zBfpi#_ZS`V79kIn%g-!ABk=q{Mpa@4Nb0O{or_IpDwLhzxQN0?DDMpn;j&5srT+%d z5NZ@<5^8(u7Ark#;OUfmdl7|=H^SqAI zNgP-k#l_+D5fp3#%9n)s%Lq2CPuh_3S`UcqN?ST3L+VI5A99%?XhsWV&jyoB&%$H6 zvCg%M49EAuq&FkQLmVn&qkih4uV`6fRm-*Ng*=>|yUwM)8A-1yWoq7k>B}j2pCq$5 m17F4j+f!wA?^1=m3ormT{0-dOG6 zwDn<(0B{e)dSelm>=eI!1DwyD_-)oo1_}VyNT93&kK_@!&9+Wej%x-FQQd{+yN&pq zfbeKfj_UFN6cd}8?69JQ@cb2T)(FT;ql7Nk9T?ysbL)EoT0Mc%*6u)UJP8c$Yarg zhau(We?tL8(ykpD@Lq*&Iz$&F1ZYyB83_<+C|TICWM3tvKdOMFIb)&93qOE#ZVh<3 zqX0blLpfJg0m$vbvC1QTWC05m-EvqLE7Bt_Y*|F@6@(b~ItC&KGY?IiJ=7#f(l97y zCpQ)Y^r-YR3t-5*WJ3CMpQ6`1P*@ZsB%*@J+5qU)PYfhfkKh1P3Rt}XM}hlalue8j zA;*9M`xjZD^?Cn7&TlMn!H7!mWJw9l6qX)${>3osk>KsA!0TfUX@nijzhhK%q8-hE z$c{{0QZoW?@0f4Hg;>ozkP5f5aujPS9L65WA~SFW?>+2tVIq+w0hp&OyTzKgXcnE9 z>a`xp!sht$=5vQrI3)5IS0xTyK^5_|Bg2MxL1O6T?X-pvRLF|CKsV$ACGp(FP8{jG~iDxdCp%G0@cZAlDCzT}Z4K?pET zjJ=YZ_9m{ADdpcZ2gE@l6LvK&okmzi0tWn)9z`jS@ z6;n}ikQ(3cODmS8$0f%A5_PU?I|W1aw;C0RH0)g57IlSf70 z&?zwx?S3DIY#t&rqCD0N*-|3z`(j!xx>4*dcRDr;-FZc7S!+974ovj#(JB{t9IBiM z;*mZ_?G=Q5n@T4_wt!<-TGwM#4G8iMhes|Bd;$hpwhcLIsONIuLpkz@74~O?lzHfe zZ2_+flH$x$yL2Yx&&%~RIdVq3c4`ou0Ws?~s&4T;>-(!<-w*=OFr-2A&EG?J=qvL0 zQRJ`8uMFKf%+C3K#OoLZeAI!G0py`>Q&F-{3m{Es8-;mNN$%vt=ZT;1HzAcw)m_zG zIRHaFt@NXcVp9%N%n{AsZDgkF3FlfnTuVhd$pxKP2;VugivC9YPAoYav**47(CMN$OBRMSL+bhfVQN*QZY z;S!6cK;=Uk{8tlpk{G`}<--9Opisdk{H;*ol7x8Tvys;!HwEA>z?e@>ETj + + a025f0f6-757a-4790-97f3-99c66c4a5795 + 0.0.1.0 + __APP_NAME__ + fr-FR + + + + + + + https://localhost:3000/ + + + + + + + + + + +
+ + + 250 + +
+
+ + + +
+
+ ReadWriteItem + + + + + + false + + + + + + + + + + + + + + + +