From 92ad0296e6f6048e1227a20ea133eae2865e9df0 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Tue, 9 Mar 2021 23:24:45 +0800 Subject: [PATCH] feat: switch to use Excalidraw api --- resources/css/common.css | 9 + resources/css/excalidraw.min.css | 42 +- resources/css/fonts.css | 13 + resources/css/style.css | 1 + resources/css/style.dev.css | 3 +- resources/{css => fonts}/Cascadia.woff2 | Bin resources/{css => fonts}/FG_Virgil.woff2 | Bin resources/fonts/Virgil.woff2 | Bin 0 -> 65704 bytes shadow-cljs.edn | 3 + src/main/frontend/commands.cljs | 15 +- src/main/frontend/components/block.cljs | 53 +- src/main/frontend/components/draw.cljs | 497 ------------------- src/main/frontend/components/draw.css | 23 - src/main/frontend/components/sidebar.cljs | 4 +- src/main/frontend/encrypt.cljs | 7 +- src/main/frontend/extensions/excalidraw.cljs | 136 +++++ src/main/frontend/fs/nfs.cljs | 6 +- src/main/frontend/handler/draw.cljs | 80 +-- src/main/frontend/handler/editor.cljs | 17 - src/main/frontend/handler/ui.cljs | 9 + src/main/frontend/keyboards.cljs | 2 + src/main/frontend/routes.cljs | 5 - src/main/frontend/state.cljs | 20 +- src/main/frontend/ui.cljs | 7 +- 24 files changed, 258 insertions(+), 694 deletions(-) create mode 100644 resources/css/fonts.css rename resources/{css => fonts}/Cascadia.woff2 (100%) rename resources/{css => fonts}/FG_Virgil.woff2 (100%) create mode 100644 resources/fonts/Virgil.woff2 delete mode 100644 src/main/frontend/components/draw.cljs delete mode 100644 src/main/frontend/components/draw.css create mode 100644 src/main/frontend/extensions/excalidraw.cljs diff --git a/resources/css/common.css b/resources/css/common.css index 02375ad95..9193de449 100644 --- a/resources/css/common.css +++ b/resources/css/common.css @@ -789,3 +789,12 @@ a { font-weight: 600; font-size: 13px; } + +/* excalidraw */ +.Island > div > div > div { + width: 44px; +} + +.excalidraw hr { + margin: 0; +} diff --git a/resources/css/excalidraw.min.css b/resources/css/excalidraw.min.css index 190340b0d..b957d0fc3 100644 --- a/resources/css/excalidraw.min.css +++ b/resources/css/excalidraw.min.css @@ -1,40 +1,2 @@ -.popover{position:absolute;z-index:10}.popover .cover{position:fixed;top:0;left:0;right:0;bottom:0} - -.context-menu{position:relative;border-radius:4px;box-shadow:0px 3px 10px rgba(0,0,0,0.2);padding:0;list-style:none;user-select:none;margin:-0.25rem 0 0 0.125rem;padding:0.25rem 0;background-color:#f1f3f5;border:1px solid #adb5bd}.context-menu-option{position:relative;width:100%;min-width:9.5rem;margin:0;padding:0.25rem 1rem 0.25rem 1.25rem;text-align:start;border-radius:0;background-color:transparent;border:none;white-space:nowrap}.context-menu-option:hover{color:#fff;background-color:#339af0}.context-menu-option:focus{z-index:1} - -:root{--button-gray-1: #e9ecef;--button-gray-2: #ced4da;--button-gray-3: #adb5bd;--button-blue: #a5d8ff}.ToolIcon{display:inline-flex;align-items:center;position:relative;font-family:Cascadia;cursor:pointer;background-color:var(--button-gray-1);-webkit-tap-highlight-color:transparent;border-radius:var(--space-factor)}.ToolIcon__icon{width:2.5rem;height:2.5rem;display:flex;justify-content:center;align-items:center;border-radius:var(--space-factor)}.ToolIcon__icon svg{position:relative;height:1em}.ToolIcon__icon+.ToolIcon__label{margin-inline-start:0}.ToolIcon__label{font-family:var(--ui-font);margin:0 0.8em;text-overflow:ellipsis}.ToolIcon_size_s .ToolIcon__icon{width:1.4rem;height:1.4rem;font-size:0.8em}.excalidraw .ToolIcon_type_button,.Modal .ToolIcon_type_button,.ToolIcon_type_button{padding:0;border:none;margin:0;font-size:inherit}.excalidraw .ToolIcon_type_button:hover,.Modal .ToolIcon_type_button:hover,.ToolIcon_type_button:hover{background-color:var(--button-gray-1)}.excalidraw .ToolIcon_type_button:active,.Modal .ToolIcon_type_button:active,.ToolIcon_type_button:active{background-color:var(--button-gray-2)}.excalidraw .ToolIcon_type_button:focus,.Modal .ToolIcon_type_button:focus,.ToolIcon_type_button:focus{box-shadow:0 0 0 2px var(--button-blue)}.excalidraw .ToolIcon_type_button.ToolIcon--selected,.Modal .ToolIcon_type_button.ToolIcon--selected,.ToolIcon_type_button.ToolIcon--selected{background-color:var(--button-gray-2)}.excalidraw .ToolIcon_type_button.ToolIcon--selected:active,.Modal .ToolIcon_type_button.ToolIcon--selected:active,.ToolIcon_type_button.ToolIcon--selected:active{background-color:var(--button-gray-3)}.excalidraw .ToolIcon_type_button--show,.Modal .ToolIcon_type_button--show,.ToolIcon_type_button--show{visibility:visible}.excalidraw .ToolIcon_type_button--hide,.Modal .ToolIcon_type_button--hide,.ToolIcon_type_button--hide{visibility:hidden}.ToolIcon_type_radio,.ToolIcon_type_checkbox{position:absolute;opacity:0;pointer-events:none}.ToolIcon_type_radio:checked+.ToolIcon__icon,.ToolIcon_type_checkbox:checked+.ToolIcon__icon{background-color:var(--button-gray-2)}.ToolIcon_type_radio:focus+.ToolIcon__icon,.ToolIcon_type_checkbox:focus+.ToolIcon__icon{box-shadow:0 0 0 2px var(--button-blue)}.ToolIcon_type_radio:active+.ToolIcon__icon,.ToolIcon_type_checkbox:active+.ToolIcon__icon{background-color:var(--button-gray-3)}.ToolIcon_type_floating{background-color:transparent}.ToolIcon_type_floating:hover{background-color:transparent}.ToolIcon_type_floating:active{background-color:transparent}.ToolIcon_type_floating:focus{box-shadow:none}.ToolIcon_type_floating .ToolIcon__icon{width:2rem;height:2em}.ToolIcon.ToolIcon__lock.ToolIcon_type_floating{margin-left:0.1rem}.ToolIcon__keybinding{position:absolute;bottom:2px;right:3px;font-size:0.5em;color:var(--button-gray-3);font-family:var(--ui-font);user-select:none}@media (max-width: 360px){.ToolIcon.ToolIcon__lock{display:inline-block;position:absolute;top:60px;right:-8px;margin-left:0;border-radius:20px 0 0 20px;background-color:var(--button-gray-1)}.ToolIcon.ToolIcon__lock:hover{background-color:var(--button-gray-1)}.ToolIcon.ToolIcon__lock:active{background-color:var(--button-gray-2)}.ToolIcon.ToolIcon__lock .ToolIcon__icon{width:2.5rem;height:2.5rem;border-radius:inherit}.ToolIcon.ToolIcon__lock svg{position:static}}:root[dir="ltr"] .unlocked-icon{left:2px}:root[dir="rtl"] .unlocked-icon{right:2px} - -.color-picker{background:#fff;border:0px solid rgba(255,255,255,0.25);box-shadow:rgba(0,0,0,0.25) 0px 1px 4px;border-radius:4px;position:absolute}:root[dir="ltr"] .color-picker{left:-5.5px}:root[dir="rtl"] .color-picker{right:-5.5px}.color-picker-control-container{display:grid;grid-template-columns:auto 1fr;align-items:center}.color-picker-triangle{width:0px;height:0px;border-style:solid;border-width:0px 9px 10px;border-color:transparent transparent #fff;position:absolute;top:-10px}:root[dir="ltr"] .color-picker-triangle{left:12px}:root[dir="rtl"] .color-picker-triangle{right:12px}.color-picker-triangle-shadow{border-color:transparent transparent rgba(0,0,0,0.1);top:-11px}.color-picker-content{padding:0.5rem;display:grid;grid-template-columns:repeat(5, auto);grid-gap:0.5rem}.color-picker-content .color-input-container{grid-column:1 / span 5}.excalidraw .color-picker-swatch{position:relative;height:1.875rem;width:1.875rem;cursor:pointer;border-radius:4px;margin:0;box-sizing:border-box;border:1px solid #ddd;background-color:currentColor !important}.excalidraw .color-picker-swatch:focus{box-shadow:0 0 4px 1px currentColor;border-color:#339af0}.color-picker-transparent{border-radius:4px;box-shadow:rgba(0,0,0,0.1) 0px 0px 0px 1px inset;position:absolute;top:0px;right:0px;bottom:0px;left:0px}.color-picker-transparent,.color-picker-label-swatch{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMUlEQVQ4T2NkYGAQYcAP3uCTZhw1gGGYhAGBZIA/nYDCgBDAm9BGDWAAJyRCgLaBCAAgXwixzAS0pgAAAABJRU5ErkJggg==") left center}.color-picker-hash{background:#dee2e6;height:1.875rem;width:1.875rem;color:#495057;display:flex;align-items:center;justify-content:center;position:relative}:root[dir="ltr"] .color-picker-hash{border-radius:4px 0px 0px 4px}:root[dir="rtl"] .color-picker-hash{border-radius:0px 4px 4px 0px}.color-input-container:focus-within .color-picker-hash{box-shadow:0 0 0 2px #a5d8ff}.color-input-container:focus-within .color-picker-hash::before,.color-input-container:focus-within .color-picker-hash::after{content:"";width:1px;height:100%;position:absolute;top:0}.color-input-container:focus-within .color-picker-hash::before{background:#dee2e6}:root[dir="ltr"] .color-input-container:focus-within .color-picker-hash::before{right:-1px}:root[dir="rtl"] .color-input-container:focus-within .color-picker-hash::before{left:-1px}.color-input-container:focus-within .color-picker-hash::after{background:#fff}:root[dir="ltr"] .color-input-container:focus-within .color-picker-hash::after{right:-2px}:root[dir="rtl"] .color-input-container:focus-within .color-picker-hash::after{left:-2px}.color-input-container{display:flex}.color-picker-input{width:12ch;margin:0;font-size:1rem;color:#343a40;border:0px;outline:none;height:1.75em;box-shadow:#dee2e6 0px 0px 0px 1px inset;float:left;padding:1px;padding-inline-start:0.5em;appearance:none}:root[dir="ltr"] .color-picker-input{border-radius:0px 4px 4px 0px}:root[dir="rtl"] .color-picker-input{border-radius:4px 0px 0px 4px}.excalidraw .color-picker-label-swatch{height:1.875rem;width:1.875rem;margin-inline-end:0.25rem;border:1px solid #dee2e6;position:relative;overflow:hidden;background-color:transparent !important}.excalidraw .color-picker-label-swatch:after{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background:var(--swatch-color)}.color-picker-keybinding{position:absolute;bottom:2px;font-size:0.7em;color:#ccc}:root[dir="ltr"] .color-picker-keybinding{right:2px}:root[dir="rtl"] .color-picker-keybinding{left:2px} - -.TextInput{display:inline-block;border:1.5px solid #e9ecef;line-height:1;padding:0.75rem;white-space:nowrap;border-radius:var(--space-factor);background-color:#fff}.TextInput:not(:focus):hover{background-color:#f1f3f5}.TextInput:focus{outline:none;box-shadow:0 0 0 2px #339af0} - -.Avatar{width:2.5rem;height:2.5rem;border-radius:1.25rem;display:flex;justify-content:center;align-items:center;color:#fff;cursor:pointer;font-size:0.8rem;font-weight:500} - -.Island{--padding: 0;background-color:var(--bg-color-island);backdrop-filter:saturate(100%) blur(10px);box-shadow:var(--shadow-island);border-radius:var(--border-radius-m);padding:calc(var(--padding) * var(--space-factor));position:relative;transition:box-shadow 0.5s ease-in-out}.Island.zen-mode{box-shadow:none} - -.Stack{--gap: 0;display:grid;gap:calc(var(--space-factor) * var(--gap))}.Stack_vertical{grid-template-columns:auto;grid-auto-flow:row;grid-auto-rows:min-content}.Stack_horizontal{grid-template-rows:auto;grid-auto-flow:column;grid-auto-columns:min-content} - -.FixedSideContainer{--margin: 0.25rem;position:absolute;pointer-events:none}.FixedSideContainer>*{pointer-events:all}.FixedSideContainer_side_top{left:var(--margin);top:var(--margin);right:var(--margin);z-index:2}.FixedSideContainer_side_top.zen-mode{right:42px} - -.UserList{pointer-events:none;padding:var(--space-factor) 40px var(--space-factor) var(--space-factor);display:flex;flex-wrap:wrap;justify-content:flex-end}.UserList>*{pointer-events:all;margin:0 0 var(--space-factor) var(--space-factor)}.UserList_mobile{padding:0;justify-content:normal}.UserList_mobile>*{margin:0 var(--space-factor) var(--space-factor) 0} - -.ExportDialog__preview{--preview-padding: calc(var(--space-factor) * 4);background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMUlEQVQ4T2NkYGAQYcAP3uCTZhw1gGGYhAGBZIA/nYDCgBDAm9BGDWAAJyRCgLaBCAAgXwixzAS0pgAAAABJRU5ErkJggg==") left center;text-align:center;padding:var(--preview-padding);margin-bottom:calc(var(--space-factor) * 3)}.ExportDialog__preview canvas{max-width:calc(100% - var(--preview-padding) * 2);max-height:25rem}.ExportDialog__actions{width:100%;display:flex;grid-gap:calc(var(--space-factor) * 2);align-items:top;justify-content:space-between}.ExportDialog__name{grid-column:project-name;margin:auto}@media (max-width: 550px){.ExportDialog{display:flex;flex-direction:column}.ExportDialog__actions{flex-direction:column;align-items:center}.ExportDialog__actions>*{margin-bottom:calc(var(--space-factor) * 3)}}@media (max-width: 600px), (max-height: 500px) and (max-width: 1000px){.ExportDialog__preview canvas{max-height:30vh}.ExportDialog__dialog,.ExportDialog__dialog .Island{height:100%;box-sizing:border-box}.ExportDialog__dialog .Island{overflow-y:auto}} - -.Modal{position:fixed;top:0;left:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center;overflow:auto;padding:calc(var(--space-factor) * 10)}.Modal__background{position:fixed;top:0;left:0;right:0;bottom:0;z-index:1;background-color:rgba(0,0,0,0.3);backdrop-filter:blur(2px)}.Modal__content{position:relative;z-index:2;width:100%;max-width:var(--max-width);opacity:0;transform:translateY(10px);animation:Modal__content_fade-in 0.1s ease-out 0.05s forwards;position:relative;background:#fff;backdrop-filter:none}@media (max-width: 600px), (max-height: 500px) and (max-width: 1000px){.Modal__content{max-width:100%}}@keyframes Modal__content_fade-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.Modal__close{width:calc(var(--space-factor) * 7);height:calc(var(--space-factor) * 7);display:flex;align-items:center;justify-content:center}.Modal__close svg{height:calc(var(--space-factor) * 5)}.Modal__close--floating{position:absolute;right:calc(var(--space-factor) * 5);top:calc(var(--space-factor) * 5)}@media (max-width: 600px), (max-height: 500px) and (max-width: 1000px){.Modal{padding:0}.Modal__content{position:fixed;top:0;left:0;right:0;bottom:0}} - -.Dialog__title{display:grid;align-items:center;margin-top:0;grid-template-columns:1fr calc(var(--space-factor) * 7);grid-gap:var(--metric)}.Dialog__titleContent{flex:1}.Dialog .Modal__close{margin:0}@media (max-width: 600px), (max-height: 500px) and (max-width: 1000px){.Dialog{--metric: calc(var(--space-factor) * 4);--inset-left: max(var(--metric), var(--sal));--inset-right: max(var(--metric), var(--sar))}.Dialog__title{grid-template-columns:calc(var(--space-factor) * 7) 1fr calc( var(--space-factor) * 7);position:sticky;top:calc(-1 * var(--metric));margin:calc(-1 * var(--inset-right));margin-top:calc(-1 * var(--metric));margin-bottom:var(--metric);padding:calc(var(--space-factor) * 2);padding-left:var(--inset-left);padding-right:var(--inset-right);background:white;font-size:1.25em;box-sizing:border-box;border-bottom:1px solid #ced4da;z-index:1}.Dialog__titleContent{text-align:center}.Dialog .Island{width:100vw;height:100%;box-sizing:border-box;overflow-y:auto;padding-left:max(calc(var(--padding) * var(--space-factor)), var(--sal));padding-right:max(calc(var(--padding) * var(--space-factor)), var(--sar));padding-bottom:max(calc(var(--padding) * var(--space-factor)), var(--sab))}.Dialog .Modal__close{order:-1}} - -.HintViewer{color:#868e96;font-size:0.8rem;left:50%;pointer-events:none;position:absolute;top:54px;transform:translateX(calc(-50% - 16px));white-space:pre;text-align:center}@media (max-width: 600px), (max-height: 500px) and (max-width: 1000px){.HintViewer{position:static;transform:none;margin-top:0.5rem}}.HintViewer>span{background-color:rgba(255,255,255,0.88);padding:0.2rem 0.4rem;border-radius:3px} - -.RoomDialog-modalButton.is-collaborating{background-color:#ebfbee;color:#2b8a3e}.RoomDialog-modalButton-collaborators{min-width:1em;position:absolute;bottom:-5px;right:-5px;padding:3px;border-radius:50%;background-color:#40c057;color:#fff;font-size:0.7em;font-family:var(--ui-font)}.RoomDialog-linkContainer{display:flex;margin:1.5em 0}.RoomDialog-link{min-width:0;flex:1 1 auto;margin-left:1em;display:inline-block;cursor:pointer;border:none;height:2.5rem;line-height:2.5rem;padding:0 0.5rem;white-space:nowrap;border-radius:var(--space-factor);background-color:var(--button-gray-1)}.RoomDialog-usernameContainer{display:flex;margin:1.5em 0;display:flex;align-items:center;justify-content:center}.RoomDialog-username{appearance:none;min-width:0;flex:1 1 auto;margin-left:1em;height:2.5rem;font-size:1em;line-height:1.5;padding:0 0.5rem}.RoomDialog-sessionStartButtonContainer{display:flex;justify-content:center}.Modal .RoomDialog-stopSession{background-color:#ffe3e3;color:#c92a2a} - -.Tooltip{position:relative}.Tooltip__label{--arrow-size: 4px;visibility:hidden;width:10ch;background:#000;color:#fff;text-align:center;border-radius:4px;padding:4px;position:absolute;z-index:10;font-size:0.7rem;line-height:1.5;top:calc(100% + var(--arrow-size) + 3px);left:calc(-50% + var(--arrow-size) / 2 - 1px);word-wrap:break-word}.Tooltip__label::after{content:"";border:var(--arrow-size) solid transparent;border-bottom-color:#000;position:absolute;bottom:100%;left:calc(50% - var(--arrow-size))}body:active .Tooltip:not(:hover){pointer-events:none}body:not(:active) .Tooltip:hover .Tooltip__label{visibility:visible}.Tooltip__label:hover{visibility:visible} - -.layer-ui__wrapper .encrypted-icon{position:relative;margin-inline-start:15px;display:flex;justify-content:center;align-items:center;border-radius:var(--space-factor);color:#2b8a3e}.layer-ui__wrapper .encrypted-icon svg{width:1.2rem;height:1.2rem}.layer-ui__wrapper .encrypted-icon.tooltip .tooltip-text{visibility:hidden;width:20rem;bottom:calc(50% + 0.8rem + 6px);background-color:#000;color:#fff;text-align:center;border-radius:6px;padding:5px;position:absolute;z-index:10;font-size:13px;line-height:1.5;white-space:pre-wrap}:root[dir="ltr"] .layer-ui__wrapper .encrypted-icon.tooltip .tooltip-text{left:-5px}:root[dir="rtl"] .layer-ui__wrapper .encrypted-icon.tooltip .tooltip-text{right:-5px}.layer-ui__wrapper .encrypted-icon.tooltip .tooltip-text::after{--size: 6px;content:"";border:var(--size) solid transparent;border-top-color:#000;position:absolute;bottom:calc(-2 * var(--size))}:root[dir="ltr"] .layer-ui__wrapper .encrypted-icon.tooltip .tooltip-text::after{left:calc(5px + var(--size) / 2)}:root[dir="rtl"] .layer-ui__wrapper .encrypted-icon.tooltip .tooltip-text::after{right:calc(5px + var(--size) / 2)}body:active .layer-ui__wrapper .encrypted-icon.tooltip:not(:hover){pointer-events:none}body:not(:active) .layer-ui__wrapper .encrypted-icon.tooltip:hover .tooltip-text{visibility:visible}.layer-ui__wrapper .encrypted-icon .tooltip-text:hover{visibility:visible}.layer-ui__wrapper__github-corner{top:0;position:absolute;width:40px}:root[dir="ltr"] .layer-ui__wrapper__github-corner{right:0}:root[dir="rtl"] .layer-ui__wrapper__github-corner{left:0}.layer-ui__wrapper__footer{position:absolute;bottom:0px;width:190px}:root[dir="ltr"] .layer-ui__wrapper__footer{right:0}:root[dir="rtl"] .layer-ui__wrapper__footer{left:0}.layer-ui__wrapper .zen-mode-transition{transition:transform 0.5s ease-in-out}:root[dir="ltr"] .layer-ui__wrapper .zen-mode-transition.transition-left{transform:translate(-999px, 0)}:root[dir="ltr"] .layer-ui__wrapper .zen-mode-transition.transition-right{transform:translate(999px, 0px)}:root[dir="rtl"] .layer-ui__wrapper .zen-mode-transition.transition-left{transform:translate(999px, 0)}:root[dir="rtl"] .layer-ui__wrapper .zen-mode-transition.transition-right{transform:translate(-999px, 0)}.layer-ui__wrapper .zen-mode-transition.App-menu_bottom--transition-left{transform:translate(-92px, 0)}.layer-ui__wrapper .disable-zen-mode{height:30px;position:absolute;bottom:10px;right:15px;font-size:10px;padding:10px;font-weight:500;opacity:0;visibility:hidden;transition:visibility 0s linear 0s, opacity 0.5s}.layer-ui__wrapper .disable-zen-mode--visible{opacity:1;visibility:visible;transition:visibility 0s linear 300ms, opacity 0.5s;transition-delay:0.8s} - -@font-face{font-family:"Virgil";src:url(FG_Virgil.woff2);font-display:swap}@font-face{font-family:"Cascadia";src:url(Cascadia.woff2);font-display:swap} - -.visually-hidden{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px);white-space:nowrap}.LoadingMessage{position:absolute;top:0;right:0;bottom:0;left:0;z-index:999;display:flex;align-items:center;justify-content:center;pointer-events:none}.LoadingMessage span{background-color:rgba(255,255,255,0.8);border-radius:5px;padding:0.8em 1.2em;font-size:1.3em} - -:root{--text-color-primary: #343a40;--bg-color-main: #fff;--shadow-island: 0 1px 5px rgba(0, 0, 0, 0.15);--bg-color-island: rgba(255, 255, 255, 0.9);--border-radius-m: 4px;--space-factor: 0.25rem}:root{--sat: env(safe-area-inset-top);--sab: env(safe-area-inset-bottom);--sal: env(safe-area-inset-left);--sar: env(safe-area-inset-right);--text-color-primary: #343a40;--bg-color-main: #fff;--shadow-island: 0 1px 5px rgba(0,0,0,0.15);--border-radius-m: 4px;--space-factor: 0.25rem}.excalidraw{display:flex;position:fixed;top:0;bottom:0;left:0;right:0}.excalidraw [contenteditable]{user-select:auto;cursor:text}.excalidraw canvas{touch-action:none;user-select:none;image-rendering:pixelated;image-rendering:-moz-crisp-edges}.excalidraw .FixedSideContainer{padding-top:var(--sat, 0px);padding-right:var(--sar, 0px);padding-bottom:var(--sab, 0px);padding-left:var(--sal, 0px)}.excalidraw .panelRow{display:flex;justify-content:space-between}.excalidraw .panelColumn{display:flex;flex-direction:column}.excalidraw .panelColumn h3,.excalidraw .panelColumn legend,.excalidraw .panelColumn .control-label{margin-top:0.333rem;margin-bottom:0.333rem;font-size:0.75rem;color:var(--text-color-primary);font-weight:bold;display:block}.excalidraw .panelColumn .control-label input{display:block;width:100%}.excalidraw .panelColumn h3:first-child,.excalidraw .panelColumn legend:first-child,.excalidraw .panelColumn .control-label:first-child{margin-top:0}.excalidraw .panelColumn legend{padding:0}.excalidraw .panelColumn .buttonList{flex-wrap:wrap}.excalidraw .panelColumn .buttonList label{margin-right:0.25rem;font-size:0.75rem;display:inline-block}.excalidraw .panelColumn .buttonList input[type="radio"]{opacity:0;position:absolute;pointer-events:none}.excalidraw .panelColumn .buttonList .ToolIcon{margin:0 5px}.excalidraw .panelColumn .buttonList .ToolIcon__icon{width:28px;height:28px}.excalidraw .panelColumn fieldset{margin:0;margin-top:0.333rem;padding:0;border:none}.excalidraw .divider{width:1px;background-color:#e9ecef;margin:1px}.excalidraw .buttonList label:focus-within,.excalidraw input:focus{outline:transparent;box-shadow:0 0 0 2px #a5d8ff}.excalidraw .active,.excalidraw .buttonList label.active{background-color:#ced4da}.excalidraw .active:hover,.excalidraw .buttonList label.active:hover{background-color:#ced4da}.excalidraw .active:active,.excalidraw .buttonList label.active:active{background-color:#adb5bd}.excalidraw .App-bottom-bar{position:absolute;top:0;bottom:0;left:0;right:0;--bar-padding: calc(4 * var(--space-factor));padding-top:max(var(--bar-padding), var(--sat, 0px));padding-right:var(--sar, 0px);padding-bottom:var(--sab, 0px);padding-left:var(--sal, 0px);z-index:4;display:flex;align-items:flex-end;pointer-events:none}.excalidraw .App-bottom-bar>.Island{width:100%;max-width:100%;min-width:100%;box-sizing:border-box;max-height:100%;display:flex;flex-direction:column;pointer-events:initial}.excalidraw .App-toolbar{width:100%;box-sizing:border-box}.excalidraw .App-toolbar-content{display:flex;align-items:center;justify-content:space-between}.excalidraw .App-mobile-menu{width:100%;overflow-x:visible;overflow-y:auto;box-sizing:border-box;margin-bottom:var(--bar-padding)}.excalidraw .App-menu{display:grid}.excalidraw .App-menu_top{grid-template-columns:1fr auto 1fr;grid-gap:4px;align-items:flex-start;cursor:default;pointer-events:none !important}.excalidraw .App-menu_top>*{pointer-events:all}.excalidraw .App-menu_top>*:first-child{justify-self:flex-start}.excalidraw .App-menu_top>*:last-child{justify-self:flex-end}.excalidraw .App-menu_bottom{position:absolute;bottom:0;grid-template-columns:1fr auto 1fr;grid-gap:4px;align-items:flex-start;cursor:default;pointer-events:none !important}.excalidraw .App-menu_bottom--transition-left section{width:185px}.excalidraw .App-menu_bottom section{display:flex}.excalidraw .App-menu_bottom>*{pointer-events:all}.excalidraw .App-menu_bottom>*:first-child{justify-self:flex-start}.excalidraw .App-menu_bottom>*:last-child{justify-self:flex-end}.excalidraw .App-menu_left{grid-template-rows:1fr auto 1fr;height:100%}.excalidraw .App-menu_right{grid-template-rows:1fr;height:100%}.excalidraw .App-menu__left{overflow-y:auto;max-height:calc(100vh - 236px)}.excalidraw .ErrorSplash{min-height:100vh;padding:20px 0;overflow:auto;display:flex;align-items:center;justify-content:center;user-select:text}.excalidraw .ErrorSplash .ErrorSplash-messageContainer{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px;background-color:#ffe3e3;border:3px solid #c92a2a}.excalidraw .ErrorSplash .ErrorSplash-paragraph{margin:15px 0;max-width:600px}.excalidraw .ErrorSplash .ErrorSplash-paragraph.align-center{text-align:center}.excalidraw .ErrorSplash .bigger,.excalidraw .ErrorSplash .bigger button{font-size:1.1em}.excalidraw .ErrorSplash .smaller,.excalidraw .ErrorSplash .smaller button{font-size:0.9em}.excalidraw .ErrorSplash .ErrorSplash-details{display:flex;flex-direction:column;align-items:flex-start}.excalidraw .ErrorSplash .ErrorSplash-details textarea{width:100%;margin:10px 0;font-family:"Cascadia";font-size:0.8em}.excalidraw .dropdown-select{height:1.5rem;padding:0;padding-inline-start:0.5rem;padding-inline-end:1.5rem;background-color:#e9ecef;border-radius:var(--space-factor);border:1px solid #ced4da;font-size:0.8rem;outline:none;appearance:none;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-position:right 0.7rem top 50%, 0 0;background-size:0.65em auto, 100%}:root[dir="rtl"] .excalidraw .dropdown-select{background-position:left 0.7rem top 50%, 0 0}.excalidraw .dropdown-select:focus{box-shadow:0 0 0 2px #a5d8ff}.excalidraw .dropdown-select:hover{background-color:#ced4da}.excalidraw .dropdown-select:active{background-color:#ced4da}.excalidraw .dropdown-select.dropdown-select--floating{position:absolute;margin-right:0.5em}.excalidraw .dropdown-select__language.dropdown-select--floating{position:fixed;bottom:10px}:root[dir="ltr"] .excalidraw .dropdown-select__language.dropdown-select--floating{right:44px}:root[dir="rtl"] .excalidraw .dropdown-select__language.dropdown-select--floating{left:44px}.excalidraw .zIndexButton{margin:0 5px;padding:5px;display:inline-flex;align-items:center;justify-content:center}.excalidraw .zIndexButton svg{width:18px;height:18px}.excalidraw .scroll-back-to-content{position:fixed;left:50%;bottom:30px;transform:translateX(-50%);padding:10px 20px}.excalidraw .help-icon{position:absolute;cursor:pointer;fill:#868e96;bottom:14px}:root[dir="ltr"] .excalidraw .help-icon{right:14px}:root[dir="rtl"] .excalidraw .help-icon{left:14px}@media (max-width: 600px), (max-height: 500px) and (max-width: 1000px){.excalidraw aside{display:none}.excalidraw .scroll-back-to-content{bottom:calc(80px + var(--sab, 0px));z-index:-1}}:root[dir="rtl"] .excalidraw .rtl-mirror{transform:scaleX(-1)}.excalidraw .github-corner{position:absolute;top:0;z-index:2}:root[dir="ltr"] .excalidraw .github-corner{right:0}:root[dir="rtl"] .excalidraw .github-corner{left:0}.excalidraw .zen-mode-visibility{visibility:visible;opacity:1;height:auto;width:auto;transition:opacity 0.5s}.excalidraw .zen-mode-visibility.zen-mode-visibility--hidden{visibility:hidden;opacity:0;height:0;width:0;transition:opacity 0.5s}.excalidraw .disable-pointerEvents{pointer-events:none !important}.excalidraw a,.Modal a{font-weight:500;text-decoration:none;color:#1c7ed6}.excalidraw a:hover,.Modal a:hover{text-decoration:underline}.excalidraw button,.excalidraw .buttonList label,.Modal button,.Modal .buttonList label{user-select:none;background-color:#e9ecef;border:0;border-radius:4px;margin:0.125rem 0;padding:0.25rem;white-space:nowrap;cursor:pointer}.excalidraw button:focus,.excalidraw .buttonList label:focus,.Modal button:focus,.Modal .buttonList label:focus{outline:transparent;box-shadow:0 0 0 2px #a5d8ff}.excalidraw button:hover,.excalidraw .buttonList label:hover,.Modal button:hover,.Modal .buttonList label:hover{background-color:#ced4da}.excalidraw button:active,.excalidraw .buttonList label:active,.Modal button:active,.Modal .buttonList label:active{background-color:#adb5bd}.excalidraw button:disabled,.excalidraw .buttonList label:disabled,.Modal button:disabled,.Modal .buttonList label:disabled{cursor:not-allowed}@media print{.App-bottom-bar,.FixedSideContainer,.layer-ui__wrapper{display:none}} - +.excalidraw .Dialog{-webkit-user-select:text;user-select:text;cursor:auto}.excalidraw .Dialog__title{display:grid;align-items:center;margin-top:0;grid-template-columns:1fr calc(var(--space-factor)*7);grid-gap:var(--metric);padding:calc(var(--space-factor)*2);text-align:center;font-feature-settings:"smcp";font-variant:small-caps;font-size:1.2em}.excalidraw .Dialog__titleContent{flex:1 1}.excalidraw .Dialog .Modal__close{color:var(--icon-fill-color);margin:0}.excalidraw .Dialog__content{padding:0 16px 16px}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw .Dialog{--metric:calc(var(--space-factor)*4);--inset-left:max(var(--metric),var(--sal));--inset-right:max(var(--metric),var(--sar))}.excalidraw .Dialog__title{grid-template-columns:calc(var(--space-factor)*7) 1fr calc(var(--space-factor)*7);position:-webkit-sticky;position:sticky;top:0;padding:calc(var(--space-factor)*2);background:var(--island-bg-color);font-size:1.25em;box-sizing:border-box;border-bottom:1px solid var(--button-gray-2);z-index:1}.excalidraw .Dialog__titleContent{text-align:center}.excalidraw .Dialog .Island{width:100vw;height:100%;box-sizing:border-box;overflow-y:auto;padding-left:max(calc(var(--padding)*var(--space-factor)),var(--sal));padding-right:max(calc(var(--padding)*var(--space-factor)),var(--sar));padding-bottom:max(calc(var(--padding)*var(--space-factor)),var(--sab))}.excalidraw .Dialog .Modal__close{order:-1}}.excalidraw .Island{--padding:0;background-color:var(--island-bg-color);-webkit-backdrop-filter:saturate(100%) blur(10px);backdrop-filter:saturate(100%) blur(10px);box-shadow:var(--shadow-island);border-radius:4px;padding:calc(var(--padding)*var(--space-factor));position:relative;transition:box-shadow .5s ease-in-out}.excalidraw .Island.zen-mode{box-shadow:none}.excalidraw.excalidraw-modal-container{position:absolute;z-index:10}.excalidraw .Modal{position:absolute;top:0;left:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center;overflow:auto;padding:calc(var(--space-factor)*10)}.excalidraw .Modal__background{position:absolute;top:0;left:0;right:0;bottom:0;z-index:1;background-color:rgba(0,0,0,.3);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.excalidraw .Modal__content{z-index:2;width:100%;max-width:var(--max-width);max-height:100%;opacity:0;transform:translateY(10px);animation:Modal__content_fade-in .1s ease-out .05s forwards;position:relative;overflow-y:auto;background:var(--island-bg-color);-webkit-backdrop-filter:none;backdrop-filter:none;border:1px solid var(--dialog-border-color);box-shadow:0 2px 10px rgba(0,0,0,.25);border-radius:6px}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw .Modal__content{max-width:100%;border:0;border-radius:0}}@keyframes Modal__content_fade-in{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.excalidraw .Modal__close{width:calc(var(--space-factor)*7);height:calc(var(--space-factor)*7);display:flex;align-items:center;justify-content:center}.excalidraw .Modal__close svg{height:calc(var(--space-factor)*5)}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw .Modal{padding:0}.excalidraw .Modal__content{position:absolute;top:0;left:0;right:0;bottom:0}}.excalidraw .ToolIcon{display:inline-flex;position:relative;font-family:Cascadia;cursor:pointer;background-color:var(--button-gray-1);-webkit-tap-highlight-color:transparent}.excalidraw .ToolIcon,.excalidraw .ToolIcon__icon{align-items:center;border-radius:var(--space-factor)}.excalidraw .ToolIcon__icon{width:2.5rem;height:2.5rem;color:var(--icon-fill-color);display:flex;justify-content:center}.excalidraw .ToolIcon__icon svg{position:relative;height:1em;fill:var(--icon-fill-color);color:var(--icon-fill-color)}.excalidraw .ToolIcon__icon+.ToolIcon__label{margin-inline-start:0}.excalidraw .ToolIcon__label{color:var(--icon-fill-color);font-family:var(--ui-font);margin:0 .8em;text-overflow:ellipsis}.excalidraw .ToolIcon_size_s .ToolIcon__icon{width:1.4rem;height:1.4rem;font-size:.8em}.excalidraw .excalidraw .ToolIcon_type_button,.excalidraw .Modal .ToolIcon_type_button,.excalidraw .ToolIcon_type_button{padding:0;border:none;margin:0;font-size:inherit}.excalidraw .excalidraw .ToolIcon_type_button:hover,.excalidraw .Modal .ToolIcon_type_button:hover,.excalidraw .ToolIcon_type_button:hover{background-color:var(--button-gray-1)}.excalidraw .excalidraw .ToolIcon_type_button:active,.excalidraw .Modal .ToolIcon_type_button:active,.excalidraw .ToolIcon_type_button:active{background-color:var(--button-gray-2)}.excalidraw .excalidraw .ToolIcon_type_button:focus,.excalidraw .Modal .ToolIcon_type_button:focus,.excalidraw .ToolIcon_type_button:focus{box-shadow:0 0 0 2px var(--focus-highlight-color)}.excalidraw .excalidraw .ToolIcon_type_button.ToolIcon--selected,.excalidraw .Modal .ToolIcon_type_button.ToolIcon--selected,.excalidraw .ToolIcon_type_button.ToolIcon--selected{background-color:var(--button-gray-2)}.excalidraw .excalidraw .ToolIcon_type_button.ToolIcon--selected:active,.excalidraw .Modal .ToolIcon_type_button.ToolIcon--selected:active,.excalidraw .ToolIcon_type_button.ToolIcon--selected:active{background-color:var(--button-gray-3)}.excalidraw .excalidraw .ToolIcon_type_button--show,.excalidraw .Modal .ToolIcon_type_button--show,.excalidraw .ToolIcon_type_button--show{visibility:visible}.excalidraw .excalidraw .ToolIcon_type_button--hide,.excalidraw .Modal .ToolIcon_type_button--hide,.excalidraw .ToolIcon_type_button--hide{visibility:hidden}.excalidraw .ToolIcon_type_checkbox,.excalidraw .ToolIcon_type_radio{position:absolute;opacity:0;pointer-events:none}.excalidraw .ToolIcon_type_checkbox:not(.ToolIcon_toggle_opaque):checked+.ToolIcon__icon,.excalidraw .ToolIcon_type_radio:not(.ToolIcon_toggle_opaque):checked+.ToolIcon__icon{background-color:var(--button-gray-2)}.excalidraw .ToolIcon_type_checkbox:focus+.ToolIcon__icon,.excalidraw .ToolIcon_type_radio:focus+.ToolIcon__icon{box-shadow:0 0 0 2px var(--focus-highlight-color)}.excalidraw .ToolIcon_type_checkbox:active+.ToolIcon__icon,.excalidraw .ToolIcon_type_radio:active+.ToolIcon__icon{background-color:var(--button-gray-3)}.excalidraw .ToolIcon_type_floating,.excalidraw .ToolIcon_type_floating:active,.excalidraw .ToolIcon_type_floating:hover{background-color:initial}.excalidraw .ToolIcon_type_floating:focus{box-shadow:none}.excalidraw .ToolIcon_type_floating .ToolIcon__icon{width:2rem;height:2em}.excalidraw .ToolIcon.ToolIcon__lock.ToolIcon_type_floating{margin-left:.1rem}.excalidraw .ToolIcon__keybinding{position:absolute;bottom:2px;right:3px;font-size:.5em;color:var(--keybinding-color);font-family:var(--ui-font);-webkit-user-select:none;user-select:none}@media(max-width:425px){.excalidraw .Shape .ToolIcon__icon{width:2rem;height:2rem}.excalidraw .Shape .ToolIcon__icon svg{height:.8em}}@media(max-width:760px){.excalidraw .ToolIcon.ToolIcon__lock{display:inline-block;position:absolute;top:60px;right:-8px;margin-left:0;border-radius:20px 0 0 20px;z-index:1}.excalidraw .ToolIcon.ToolIcon__lock,.excalidraw .ToolIcon.ToolIcon__lock:hover{background-color:var(--button-gray-1)}.excalidraw .ToolIcon.ToolIcon__lock:active{background-color:var(--button-gray-2)}.excalidraw .ToolIcon.ToolIcon__lock .ToolIcon__icon{border-radius:inherit}.excalidraw .ToolIcon.ToolIcon__lock svg{position:static}}.excalidraw .TooltipIcon{width:.9em;height:.9em;margin-left:5px;margin-top:1px}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw .TooltipIcon{display:none}}:root[dir=ltr] .excalidraw .unlocked-icon{left:2px}:root[dir=rtl] .excalidraw .unlocked-icon{right:2px}.excalidraw .popover{position:fixed;z-index:10}.excalidraw .color-picker{background:var(--popup-bg-color);border:0 solid hsla(0,0%,100%,.25);box-shadow:0 1px 4px rgba(0,0,0,.25);border-radius:4px;position:absolute}:root[dir=ltr] .excalidraw .color-picker{left:-5.5px}:root[dir=rtl] .excalidraw .color-picker{right:-5.5px}.excalidraw .color-picker-control-container{display:grid;grid-template-columns:auto 1fr;align-items:center}.excalidraw .color-picker-triangle{width:0;height:0;border-left:9px solid transparent;border-bottom:10px solid var(--popup-bg-color);border-right:9px solid transparent;border-top:0 solid transparent;position:absolute;top:-10px}:root[dir=ltr] .excalidraw .color-picker-triangle{left:12px}:root[dir=rtl] .excalidraw .color-picker-triangle{right:12px}.excalidraw .color-picker-triangle-shadow{border-color:transparent transparent rgba(0,0,0,.1);top:-11px}.excalidraw .color-picker-content{padding:.5rem;display:grid;grid-template-columns:repeat(5,auto);grid-gap:.5rem;border-radius:4px}.excalidraw .color-picker-content:focus{outline:none;box-shadow:0 0 0 2px var(--focus-highlight-color)}.excalidraw .color-picker-content .color-input-container{grid-column:1/span 5}.excalidraw .color-picker-swatch{position:relative;height:1.875rem;width:1.875rem;cursor:pointer;border-radius:4px;margin:0;box-sizing:border-box;border:1px solid #ddd;background-color:currentColor!important;filter:var(--appearance-filter)}.excalidraw .color-picker-swatch:focus{box-shadow:0 0 4px 1px currentColor;border-color:var(--select-highlight-color)}.excalidraw .color-picker-transparent{border-radius:4px;box-shadow:inset 0 0 0 1px rgba(0,0,0,.1);position:absolute;top:0;right:0;bottom:0;left:0}.excalidraw .color-picker-label-swatch,.excalidraw .color-picker-transparent{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMUlEQVQ4T2NkYGAQYcAP3uCTZhw1gGGYhAGBZIA/nYDCgBDAm9BGDWAAJyRCgLaBCAAgXwixzAS0pgAAAABJRU5ErkJggg==") 0}.excalidraw .color-picker-hash{background:var(--input-border-color);height:1.875rem;width:1.875rem;color:var(--input-label-color);display:flex;align-items:center;justify-content:center;position:relative}:root[dir=ltr] .excalidraw .color-picker-hash{border-radius:4px 0 0 4px}:root[dir=rtl] .excalidraw .color-picker-hash{border-radius:0 4px 4px 0}.excalidraw .color-input-container:focus-within .color-picker-hash{box-shadow:0 0 0 2px var(--focus-highlight-color)}.excalidraw .color-input-container:focus-within .color-picker-hash:after,.excalidraw .color-input-container:focus-within .color-picker-hash:before{content:"";width:1px;height:100%;position:absolute;top:0}.excalidraw .color-input-container:focus-within .color-picker-hash:before{background:var(--input-border-color)}:root[dir=ltr] .excalidraw .color-input-container:focus-within .color-picker-hash:before{right:-1px}:root[dir=rtl] .excalidraw .color-input-container:focus-within .color-picker-hash:before{left:-1px}.excalidraw .color-input-container:focus-within .color-picker-hash:after{background:var(--input-bg-color)}:root[dir=ltr] .excalidraw .color-input-container:focus-within .color-picker-hash:after{right:-2px}:root[dir=rtl] .excalidraw .color-input-container:focus-within .color-picker-hash:after{left:-2px}.excalidraw .color-input-container{display:flex}.excalidraw .color-picker-input{width:12ch;margin:0;font-size:1rem;background-color:var(--input-bg-color);color:var(--text-primary-color);border:0;outline:none;height:1.75em;box-shadow:var(--input-border-color) 0 0 0 1px inset;float:left;padding:1px;padding-inline-start:.5em;-webkit-appearance:none;-moz-appearance:none;appearance:none}:root[dir=ltr] .excalidraw .color-picker-input{border-radius:0 4px 4px 0}:root[dir=rtl] .excalidraw .color-picker-input{border-radius:4px 0 0 4px}.excalidraw .color-picker-label-swatch{height:1.875rem;width:1.875rem;margin-inline-end:.25rem;border:1px solid #dee2e6;position:relative;overflow:hidden;background-color:initial!important;filter:var(--appearance-filter)}.excalidraw .color-picker-label-swatch:after{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background:var(--swatch-color)}.excalidraw .color-picker-keybinding{position:absolute;bottom:2px;font-size:.7em}:root[dir=ltr] .excalidraw .color-picker-keybinding{right:2px}:root[dir=rtl] .excalidraw .color-picker-keybinding{left:2px}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw .color-picker-keybinding{display:none}}.excalidraw .color-picker-type-canvasBackground .color-picker-keybinding{color:#aaa}.excalidraw .color-picker-type-elementBackground .color-picker-keybinding{color:#fff}.excalidraw .color-picker-swatch[aria-label=transparent] .color-picker-keybinding{color:#aaa}.excalidraw .color-picker-type-elementStroke .color-picker-keybinding{color:#d4d4d4}.excalidraw.Appearance_dark .color-picker-swatch[aria-label=transparent] .color-picker-keybinding,.excalidraw.Appearance_dark .color-picker-type-elementBackground .color-picker-keybinding{color:#000}.excalidraw .picker-container{display:inline-block;box-sizing:border-box;margin-right:.25rem}.excalidraw .picker{background:var(--popup-bg-color);border:0 solid hsla(0,0%,100%,.25);box-shadow:0 1px 4px rgba(0,0,0,.25);border-radius:4px;position:absolute}.excalidraw .picker-container button,.excalidraw .picker button{position:relative;display:flex;align-items:center;justify-content:center}.excalidraw .picker-container button:focus,.excalidraw .picker button:focus{outline:transparent;background-color:var(--button-gray-2)}.excalidraw .picker-container button:focus svg,.excalidraw .picker button:focus svg{opacity:1}.excalidraw .picker-container button:hover,.excalidraw .picker button:hover{background-color:var(--button-gray-2)}.excalidraw .picker-container button:active,.excalidraw .picker button:active{background-color:var(--button-gray-3)}.excalidraw .picker-container button:disabled,.excalidraw .picker button:disabled{cursor:not-allowed}.excalidraw .picker-container button svg,.excalidraw .picker button svg{margin:0;width:36px;height:18px;opacity:.6;pointer-events:none}.excalidraw .picker button{padding:.25rem .28rem .35rem .25rem}.excalidraw .picker-triangle{width:0;height:0;position:relative;top:-10px;z-index:10}:root[dir=ltr] .excalidraw .picker-triangle{left:12px}:root[dir=rtl] .excalidraw .picker-triangle{right:12px}.excalidraw .picker-triangle:before{content:"";position:absolute;border-color:transparent transparent rgba(0,0,0,.1);border-style:solid;border-width:0 9px 10px;top:-1px}.excalidraw .picker-triangle:after{content:"";position:absolute;border-left:9px solid transparent;border-bottom:10px solid var(--popup-bg-color);border-right:9px solid transparent;border-top:0 solid transparent}.excalidraw .picker-content{padding:.5rem;display:grid;grid-auto-flow:column;grid-gap:.5rem;border-radius:4px}:root[dir=rtl] .excalidraw .picker-content{padding:.4rem}.excalidraw .picker-keybinding{position:absolute;bottom:2px;font-size:.7em;color:var(--keybinding-color)}:root[dir=ltr] .excalidraw .picker-keybinding{right:2px}:root[dir=rtl] .excalidraw .picker-keybinding{left:2px}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw .picker-keybinding{display:none}}.excalidraw .picker-type-canvasBackground .picker-keybinding{color:#aaa}.excalidraw .picker-type-elementBackground .picker-keybinding{color:#fff}.excalidraw .picker-swatch[aria-label=transparent] .picker-keybinding{color:#aaa}.excalidraw .picker-type-elementStroke .picker-keybinding{color:#d4d4d4}.excalidraw.Appearance_dark .picker-swatch[aria-label=transparent] .picker-keybinding,.excalidraw.Appearance_dark .picker-type-elementBackground .picker-keybinding{color:#000}.excalidraw .TextInput{color:var(--text-primary-color);display:inline-block;border:1.5px solid var(--button-gray-1);line-height:1;padding:.75rem;white-space:nowrap;border-radius:var(--space-factor);background-color:var(--input-bg-color)}.excalidraw .TextInput:not(:focus):hover{background-color:var(--input-hover-bg-color)}.excalidraw .TextInput:focus{outline:none;box-shadow:0 0 0 2px var(--focus-highlight-color)}.excalidraw .Tooltip{position:relative}.excalidraw .Tooltip__label{--arrow-size:4px;visibility:hidden;background:#000;color:#fff;text-align:center;border-radius:6px;padding:8px;position:absolute;z-index:10;font-size:13px;line-height:1.5;font-weight:500;left:calc(50% + var(--arrow-size)/2 - 1px);transform:translateX(-50%);word-wrap:break-word}.excalidraw .Tooltip__label:after{content:"";border:var(--arrow-size) solid transparent;position:absolute;left:calc(50% - var(--arrow-size))}.excalidraw .Tooltip__label--above{bottom:calc(100% + var(--arrow-size) + 3px)}.excalidraw .Tooltip__label--above:after{border-top-color:#000;top:100%}.excalidraw .Tooltip__label--below{top:calc(100% + var(--arrow-size) + 3px)}.excalidraw .Tooltip__label--below:after{border-bottom-color:#000;bottom:100%}.excalidraw .Tooltip:hover .Tooltip__label,.excalidraw .Tooltip__label:hover{visibility:visible}.excalidraw .Avatar{width:2.5rem;height:2.5rem;border-radius:1.25rem;display:flex;justify-content:center;align-items:center;color:#fff;cursor:pointer;font-size:.8rem;font-weight:500}.excalidraw .context-menu{position:relative;border-radius:4px;box-shadow:0 3px 10px rgba(0,0,0,.2);list-style:none;-webkit-user-select:none;user-select:none;margin:-.25rem 0 0 .125rem;padding:.5rem 0;background-color:var(--popup-secondary-bg-color);border:1px solid var(--button-gray-3);cursor:default}.excalidraw .context-menu button{color:var(--popup-text-color)}.excalidraw .context-menu-option{position:relative;width:100%;min-width:9.5rem;margin:0;padding:.25rem 1rem .25rem 1.25rem;text-align:start;border-radius:0;background-color:initial;border:none;white-space:nowrap;display:grid;grid-template-columns:1fr .2fr;align-items:center}.excalidraw .context-menu-option.checkmark:before{position:absolute;left:6px;margin-bottom:1px;content:"✓"}.excalidraw .context-menu-option.dangerous .context-menu-option__label{color:#f03e3e}.excalidraw .context-menu-option .context-menu-option__label{justify-self:start;margin-inline-end:20px}.excalidraw .context-menu-option .context-menu-option__shortcut{justify-self:end;opacity:.6;font-family:inherit;font-size:.7rem}.excalidraw .context-menu-option:hover{color:var(--popup-bg-color);background-color:var(--select-highlight-color)}.excalidraw .context-menu-option:hover.dangerous{background-color:#fa5252}.excalidraw .context-menu-option:hover.dangerous .context-menu-option__label{color:var(--popup-bg-color)}.excalidraw .context-menu-option:focus{z-index:1}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw .context-menu-option{display:block}.excalidraw .context-menu-option .context-menu-option__label{margin-inline-end:0}.excalidraw .context-menu-option .context-menu-option__shortcut{display:none}}.excalidraw .context-menu-option-separator{border:none;border-top:1px solid #adb5bd}.excalidraw .Stack{--gap:0;display:grid;grid-gap:calc(var(--space-factor)*var(--gap));gap:calc(var(--space-factor)*var(--gap))}.excalidraw .Stack_vertical{grid-template-columns:auto;grid-auto-flow:row;grid-auto-rows:-webkit-min-content;grid-auto-rows:min-content}.excalidraw .Stack_horizontal{grid-template-rows:auto;grid-auto-flow:column;grid-auto-columns:-webkit-min-content;grid-auto-columns:min-content}.excalidraw .CollabButton.is-collaborating{background-color:var(--button-special-active-bg-color)}.excalidraw .CollabButton.is-collaborating .ToolIcon__icon svg,.excalidraw .CollabButton.is-collaborating .ToolIcon__label{color:var(--icon-green-fill-color)}.excalidraw .CollabButton-collaborators{min-width:1em;position:absolute;bottom:-5px;padding:3px;border-radius:50%;background-color:#40c057;color:#fff;font-size:.7em;font-family:var(--ui-font)}:root[dir=ltr] .excalidraw .CollabButton-collaborators{right:-5px}:root[dir=rtl] .excalidraw .CollabButton-collaborators{left:-5px}.excalidraw .ExportDialog__preview{--preview-padding:calc(var(--space-factor)*4);background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMUlEQVQ4T2NkYGAQYcAP3uCTZhw1gGGYhAGBZIA/nYDCgBDAm9BGDWAAJyRCgLaBCAAgXwixzAS0pgAAAABJRU5ErkJggg==") 0;text-align:center;padding:var(--preview-padding);margin-bottom:calc(var(--space-factor)*3)}.excalidraw .ExportDialog__preview canvas{max-width:calc(100% - var(--preview-padding)*2);max-height:25rem}.excalidraw.Appearance_dark .ExportDialog__preview canvas{filter:none}.excalidraw .ExportDialog__actions{width:100%;display:flex;grid-gap:calc(var(--space-factor)*2);align-items:top;justify-content:space-between}.excalidraw .ExportDialog__name{grid-column:project-name;margin:auto}.excalidraw .ExportDialog__name .TextInput{height:calc(1rem - 3px)}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw .ExportDialog{display:flex;flex-direction:column}.excalidraw .ExportDialog__actions{flex-direction:column;align-items:center}.excalidraw .ExportDialog__actions>*{margin-bottom:calc(var(--space-factor)*3)}.excalidraw .ExportDialog__preview canvas{max-height:30vh}.excalidraw .ExportDialog__dialog,.excalidraw .ExportDialog__dialog .Island{height:100%;box-sizing:border-box}.excalidraw .ExportDialog__dialog .Island{overflow-y:auto}}.excalidraw .FixedSideContainer{--margin:0.25rem;position:absolute;pointer-events:none}.excalidraw .FixedSideContainer>*{pointer-events:all}.excalidraw .FixedSideContainer_side_top{left:var(--margin);top:var(--margin);right:var(--margin);z-index:2}.excalidraw .FixedSideContainer_side_top.zen-mode{right:42px}.excalidraw .HintViewer{pointer-events:none;box-sizing:border-box;position:absolute;display:flex;justify-content:center;left:0;top:100%;max-width:100%;width:100%;margin-top:6px;text-align:center;color:#868e96;font-size:.8rem}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw .HintViewer{position:static;padding-right:2em}}.excalidraw .HintViewer>span{padding:.2rem .4rem;background-color:var(--overlay-bg-color);border-radius:4px}.excalidraw .layer-ui__library{margin:auto;display:flex;align-items:center;justify-content:center}.excalidraw .layer-ui__library .layer-ui__library-header{display:flex;align-items:center;width:100%;margin:2px 0}.excalidraw .layer-ui__library .layer-ui__library-header button{margin:0 2px}.excalidraw .layer-ui__library .layer-ui__library-header a{margin-inline-start:auto;padding-inline-end:18px;white-space:nowrap}.excalidraw .layer-ui__library-message{padding:10px 20px;max-width:200px}.excalidraw .layer-ui__library-items{max-height:50vh;overflow:auto}.excalidraw .layer-ui__wrapper{z-index:var(--zIndex-layerUI)}.excalidraw .layer-ui__wrapper .encrypted-icon{position:relative;margin-inline-start:15px;display:flex;justify-content:center;align-items:center;border-radius:var(--space-factor);color:#2b8a3e}.excalidraw .layer-ui__wrapper .encrypted-icon svg{width:1.2rem;height:1.2rem}.excalidraw .layer-ui__wrapper__github-corner{top:0;position:absolute;width:40px}:root[dir=ltr] .excalidraw .layer-ui__wrapper__github-corner{right:0}:root[dir=rtl] .excalidraw .layer-ui__wrapper__github-corner{left:0}.excalidraw .layer-ui__wrapper__footer{position:absolute;z-index:100;bottom:0;width:190px}:root[dir=ltr] .excalidraw .layer-ui__wrapper__footer{right:0}:root[dir=rtl] .excalidraw .layer-ui__wrapper__footer{left:0}.excalidraw .layer-ui__wrapper .zen-mode-transition{transition:transform .5s ease-in-out}:root[dir=ltr] .excalidraw .layer-ui__wrapper .zen-mode-transition.transition-left{transform:translate(-999px)}:root[dir=ltr] .excalidraw .layer-ui__wrapper .zen-mode-transition.transition-right,:root[dir=rtl] .excalidraw .layer-ui__wrapper .zen-mode-transition.transition-left{transform:translate(999px)}:root[dir=rtl] .excalidraw .layer-ui__wrapper .zen-mode-transition.transition-right{transform:translate(-999px)}:root[dir=ltr] .excalidraw .layer-ui__wrapper .zen-mode-transition.App-menu_bottom--transition-left{transform:translate(-92px)}:root[dir=rtl] .excalidraw .layer-ui__wrapper .zen-mode-transition.App-menu_bottom--transition-left{transform:translate(92px)}.excalidraw .layer-ui__wrapper .disable-zen-mode{height:30px;position:absolute;bottom:10px;font-size:10px;padding:10px;font-weight:500;opacity:0;visibility:hidden;transition:visibility 0s linear 0s,opacity .5s}[dir=ltr] .excalidraw .layer-ui__wrapper .disable-zen-mode{right:15px}[dir=rtl] .excalidraw .layer-ui__wrapper .disable-zen-mode{left:15px}.excalidraw .layer-ui__wrapper .disable-zen-mode--visible{opacity:1;visibility:visible;transition:visibility 0s linear .3s,opacity .5s;transition-delay:.8s}.excalidraw .library-unit{align-items:center;border:1px solid var(--button-gray-2);display:flex;justify-content:center;position:relative;width:63px;height:63px}.excalidraw .library-unit__dragger{display:flex;height:100%;width:100%}.excalidraw .library-unit__dragger>svg{filter:var(--appearance-filter);flex-grow:1;max-height:100%;max-width:100%}.excalidraw .library-unit__removeFromLibrary,.excalidraw .library-unit__removeFromLibrary:active,.excalidraw .library-unit__removeFromLibrary:hover{align-items:center;background:none;border:none;color:var(--icon-fill-color);display:flex;justify-content:center;margin:0;padding:0;position:absolute;right:5px;top:5px}.excalidraw .library-unit__removeFromLibrary>svg{height:16px;width:16px}.excalidraw .library-unit__pulse{transform:scale(1);animation:library-unit__pulse-animation 1s ease-in infinite}.excalidraw .library-unit__adder{position:absolute;left:50%;top:50%;width:20px;height:20px;margin-left:-10px;margin-top:-10px;pointer-events:none}.excalidraw .library-unit__active{cursor:pointer}@keyframes library-unit__pulse-animation{0%{transform:scale(.95)}50%{transform:scale(1)}to{transform:scale(.95)}}.excalidraw .UserList{pointer-events:none;padding:var(--space-factor) 40px var(--space-factor) var(--space-factor);display:flex;flex-wrap:wrap;justify-content:flex-end}.excalidraw .UserList>*{pointer-events:all;margin:0 0 var(--space-factor) var(--space-factor)}.excalidraw .UserList_mobile{padding:0;justify-content:normal}.excalidraw .UserList_mobile>*{margin:0 var(--space-factor) var(--space-factor) 0}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw .PasteChartDialog .Island{display:flex;flex-direction:column}}.excalidraw .PasteChartDialog .container{display:flex;align-items:center;justify-content:space-around;flex-wrap:wrap}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw .PasteChartDialog .container{flex-direction:column;justify-content:center}}.excalidraw .PasteChartDialog .ChartPreview{margin:8px;text-align:center;width:192px;height:128px;border-radius:2px;padding:1px;border:1px solid #ced4da;display:flex;align-items:center;justify-content:center;background:transparent}.excalidraw .PasteChartDialog .ChartPreview div{display:inline-block}.excalidraw .PasteChartDialog .ChartPreview svg{max-height:120px;max-width:186px}.excalidraw .PasteChartDialog .ChartPreview:hover{padding:0;border:2px solid #339af0}.excalidraw .HelpDialog h3{border-bottom:1px solid var(--button-gray-2);padding-bottom:4px}.excalidraw .HelpDialog--island{border:1px solid var(--button-gray-2);margin-bottom:16px}.excalidraw .HelpDialog--island-title{margin:0;padding:4px;background-color:var(--button-gray-1);text-align:center}.excalidraw .HelpDialog--shortcut{border-top:1px solid var(--button-gray-2)}.excalidraw .HelpDialog--key{word-break:keep-all;border:1px solid var(--button-gray-2);padding:2px 8px;margin:auto 4px;background-color:var(--button-gray-1);border-radius:2px;font-size:.8em;min-height:26px;box-sizing:border-box;display:flex;align-items:center;font-family:inherit}.excalidraw .HelpDialog--header{display:flex;flex-direction:row;justify-content:space-evenly;margin-bottom:32px;padding-bottom:16px}.excalidraw .HelpDialog--btn{border:1px solid var(--link-color);padding:8px 32px;border-radius:4px}.excalidraw .HelpDialog--btn:hover{text-decoration:none}.excalidraw .Stats{position:absolute;top:64px;right:12px;font-size:12px;z-index:999}.excalidraw .Stats h3{margin:0 24px 8px 0;white-space:nowrap}.excalidraw .Stats .close{float:right;height:16px;width:16px;cursor:pointer}.excalidraw .Stats .close svg{width:100%;height:100%}.excalidraw .Stats table{width:100%}.excalidraw .Stats table th{border-bottom:1px solid var(--input-border-color);padding:4px}.excalidraw .Stats table tr td:nth-child(2){min-width:24px;text-align:right}:root[dir=rtl] .excalidraw .Stats{left:12px;right:auto}:root[dir=rtl] .excalidraw .Stats h3{margin:0 0 8px 24px}:root[dir=rtl] .excalidraw .Stats .close{float:left}.excalidraw .Toast{animation:fade-in .5s;background-color:var(--button-gray-1);border-radius:4px;bottom:10px;box-sizing:border-box;cursor:default;left:50%;margin-left:-150px;padding:4px 0;position:absolute;text-align:center;width:300px;z-index:999999}.excalidraw .Toast__message{color:var(--popup-text-color);white-space:pre-wrap}@keyframes fade-in{0%{opacity:0}to{opacity:1}}.visually-hidden{position:absolute!important;height:1px;width:1px;overflow:hidden;clip:rect(1px,1px,1px,1px);white-space:nowrap}.LoadingMessage{position:absolute;top:0;right:0;bottom:0;left:0;z-index:999;display:flex;align-items:center;justify-content:center;pointer-events:none}.LoadingMessage span{background-color:var(--button-gray-1);border-radius:5px;padding:.8em 1.2em;color:var(--popup-text-color);font-size:1.3em}.excalidraw{--appearance-filter:none;--button-destructive-bg-color:#ffe3e3;--button-destructive-color:#c92a2a;--button-gray-1:#e9ecef;--button-gray-2:#ced4da;--button-gray-3:#adb5bd;--button-special-active-bg-color:#ebfbee;--dialog-border-color:#868e96;--dropdown-icon:url('data:image/svg+xml;charset=utf-8,');--focus-highlight-color:#a5d8ff;--icon-fill-color:#000;--icon-green-fill-color:#2b8a3e;--input-bg-color:#fff;--input-border-color:#dee2e6;--input-hover-bg-color:#f1f3f5;--input-label-color:#495057;--island-bg-color:hsla(0,0%,100%,0.9);--keybinding-color:#adb5bd;--link-color:#1c7ed6;--overlay-bg-color:hsla(0,0%,100%,0.88);--popup-bg-color:#fff;--popup-secondary-bg-color:#f1f3f5;--popup-text-color:#000;--popup-text-inverted-color:#fff;--sab:env(safe-area-inset-bottom);--sal:env(safe-area-inset-left);--sar:env(safe-area-inset-right);--sat:env(safe-area-inset-top);--select-highlight-color:#339af0;--shadow-island:0 1px 5px rgba(0,0,0,0.15);--space-factor:0.25rem;--text-primary-color:#343a40}.excalidraw.Appearance_dark{background:#000}.excalidraw.Appearance_dark.Appearance_dark-background-none{background:none}.excalidraw.Appearance_dark{--appearance-filter:invert(93%) hue-rotate(180deg);--button-destructive-bg-color:#5a0000;--button-destructive-color:#ffa8a8;--button-gray-1:#363636;--button-gray-2:#272727;--button-gray-3:#222;--button-special-active-bg-color:#204624;--dialog-border-color:#212529;--dropdown-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='292.4' height='292.4' viewBox='0 0 292 292'%3E%3Cpath fill='%23ced4da' d='M287 197L159 69c-4-3-8-5-13-5s-9 2-13 5L5 197c-3 4-5 8-5 13s2 9 5 13c4 4 8 5 13 5h256c5 0 9-1 13-5s5-8 5-13-1-9-5-13z'/%3E%3C/svg%3E");--focus-highlight-color:#228be6;--icon-fill-color:#ced4da;--icon-green-fill-color:#69db7c;--input-bg-color:#121212;--input-border-color:#2e2e2e;--input-hover-bg-color:#181818;--input-label-color:#e9ecef;--island-bg-color:#1e1e1e;--keybinding-color:#868e96;--overlay-bg-color:rgba(52,58,64,0.12);--popup-bg-color:#2c2c2c;--popup-secondary-bg-color:#222;--popup-text-color:#ced4da;--popup-text-inverted-color:#2c2c2c;--select-highlight-color:#4dabf7;--shadow-island:0 1px 5px rgba(0,0,0,0.3);--text-primary-color:#ced4da}:root{--zIndex-canvas:1;--zIndex-wysiwyg:2;--zIndex-layerUI:3}.excalidraw{position:relative;overflow:hidden;color:var(--text-primary-color);display:flex;top:0;bottom:0;left:0;right:0}.excalidraw a{font-weight:500;text-decoration:none;color:var(--link-color)}.excalidraw a:hover{text-decoration:underline}.excalidraw canvas{touch-action:none;-webkit-user-select:none;user-select:none;image-rendering:pixelated;image-rendering:-moz-crisp-edges;z-index:var(--zIndex-canvas)}.excalidraw.Appearance_dark canvas{filter:var(--appearance-filter)}.excalidraw .FixedSideContainer{padding:var(--sat,0) var(--sar,0) var(--sab,0) var(--sal,0)}.excalidraw .panelRow{display:flex;justify-content:space-between}.excalidraw .panelColumn{display:flex;flex-direction:column}.excalidraw .panelColumn .control-label,.excalidraw .panelColumn h3,.excalidraw .panelColumn legend{margin-top:.333rem;margin-bottom:.333rem;font-size:.75rem;color:var(--text-primary-color);font-weight:700;display:block}.excalidraw .panelColumn .control-label input{display:block;width:100%}.excalidraw .panelColumn .control-label:first-child,.excalidraw .panelColumn h3:first-child,.excalidraw .panelColumn legend:first-child{margin-top:0}.excalidraw .panelColumn legend{padding:0}.excalidraw .panelColumn .iconSelectList{flex-wrap:wrap;position:relative}.excalidraw .panelColumn .buttonList{flex-wrap:wrap}.excalidraw .panelColumn .buttonList label{margin-right:.25rem;font-size:.75rem;display:inline-block}.excalidraw .panelColumn .buttonList input[type=button],.excalidraw .panelColumn .buttonList input[type=radio]{opacity:0;position:absolute;pointer-events:none}.excalidraw .panelColumn .buttonList .iconRow{margin-top:8px}.excalidraw .panelColumn .buttonList .ToolIcon{margin:0;margin-inline-end:8px}.excalidraw .panelColumn .buttonList .ToolIcon:focus{outline:transparent;box-shadow:0 0 0 2px var(--focus-highlight-color)}.excalidraw .panelColumn .buttonList .ToolIcon:hover{background-color:var(--button-gray-2)}.excalidraw .panelColumn .buttonList .ToolIcon:active{background-color:var(--button-gray-3)}.excalidraw .panelColumn .buttonList .ToolIcon:disabled{cursor:not-allowed}.excalidraw .panelColumn .buttonList .ToolIcon__icon{width:28px;height:28px}.excalidraw .panelColumn fieldset{margin:.333rem 0 0;padding:0;border:none}.excalidraw .divider{width:1px;background-color:#e9ecef;margin:1px}.excalidraw .buttonList label:focus-within,.excalidraw input:focus{outline:transparent;box-shadow:0 0 0 2px var(--focus-highlight-color)}.excalidraw .buttonList label,.excalidraw button{-webkit-user-select:none;user-select:none;background-color:var(--button-gray-1);border:0;border-radius:4px;margin:.125rem 0;padding:.25rem;white-space:nowrap;cursor:pointer}.excalidraw .buttonList label:focus,.excalidraw button:focus{outline:transparent;box-shadow:0 0 0 2px var(--focus-highlight-color)}.excalidraw .buttonList label:hover,.excalidraw button:hover{background-color:var(--button-gray-2)}.excalidraw .buttonList label:active,.excalidraw button:active{background-color:var(--button-gray-3)}.excalidraw .buttonList label:disabled,.excalidraw button:disabled{cursor:not-allowed}.excalidraw .active,.excalidraw .active:hover,.excalidraw .buttonList label.active,.excalidraw .buttonList label.active:hover{background-color:var(--button-gray-2)}.excalidraw .active:active,.excalidraw .buttonList label.active:active{background-color:var(--button-gray-3)}.excalidraw .buttonList.buttonListIcon label{display:inline-flex;justify-content:center;align-items:center}.excalidraw .buttonList.buttonListIcon label svg{width:36px;height:18px;opacity:.6}.excalidraw .buttonList.buttonListIcon label.active svg{opacity:1}.excalidraw .App-top-bar{z-index:var(--zIndex-layerUI);display:flex;flex-direction:column;align-items:center}.excalidraw .App-bottom-bar{position:absolute;top:0;bottom:0;left:0;right:0;--bar-padding:calc(var(--space-factor)*4);padding:max(var(--bar-padding),var(--sat,0)) var(--sar,0) var(--sab,0) var(--sal,0);z-index:4;display:flex;align-items:flex-end;pointer-events:none}.excalidraw .App-bottom-bar>.Island{width:100%;max-width:100%;min-width:100%;box-sizing:border-box;max-height:100%;display:flex;flex-direction:column;pointer-events:auto}.excalidraw .App-bottom-bar>.Island .panelColumn{padding:8px 8px 0}.excalidraw .App-toolbar{width:100%;box-sizing:border-box}.excalidraw .App-toolbar-content{display:flex;align-items:center;justify-content:space-between;padding:8px}.excalidraw .App-mobile-menu{width:100%;overflow-x:visible;overflow-y:auto;box-sizing:border-box;margin-bottom:var(--bar-padding)}.excalidraw .App-menu{display:grid;color:var(--icon-fill-color)}.excalidraw .App-menu_top{grid-template-columns:1fr auto 1fr;grid-gap:4px;align-items:flex-start;cursor:default;pointer-events:none!important}.excalidraw .layer-ui__wrapper:not(.disable-pointerEvents) .App-menu_top>*{pointer-events:all}.excalidraw .App-menu_top>:first-child{justify-self:flex-start}.excalidraw .App-menu_top>:last-child{justify-self:flex-end}.excalidraw .App-menu_bottom{position:absolute;bottom:0;grid-template-columns:1fr auto 1fr;grid-gap:4px;align-items:flex-start;cursor:default;pointer-events:none!important;z-index:100}:root[dir=ltr] .excalidraw .App-menu_bottom{left:.25rem}:root[dir=rtl] .excalidraw .App-menu_bottom{right:.25rem}.excalidraw .App-menu_bottom--transition-left section{width:185px}.excalidraw .App-menu_bottom section{display:flex}.excalidraw .layer-ui__wrapper:not(.disable-pointerEvents) .App-menu_bottom>*{pointer-events:all}.excalidraw .App-menu_bottom>:first-child{justify-self:flex-start}.excalidraw .App-menu_bottom>:last-child{justify-self:flex-end}.excalidraw .App-menu_left{grid-template-rows:1fr auto 1fr;height:100%}.excalidraw .App-menu_right{grid-template-rows:1fr;height:100%}.excalidraw .App-menu__left{overflow-y:auto}.excalidraw .dropdown-select{height:1.5rem;padding:0;padding-inline-start:.5rem;padding-inline-end:1.5rem;color:var(--icon-fill-color);background-color:var(--button-gray-1);border-radius:var(--space-factor);border:1px solid var(--button-gray-2);font-size:.8rem;outline:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:var(--dropdown-icon);background-repeat:no-repeat;background-position:right .7rem top 50%,0 0;background-size:.65em auto,100%}:root[dir=rtl] .excalidraw .dropdown-select{background-position:left .7rem top 50%,0 0}.excalidraw .dropdown-select:focus{box-shadow:0 0 0 2px var(--focus-highlight-color)}.excalidraw .dropdown-select:active,.excalidraw .dropdown-select:hover{background-color:var(--button-gray-2)}.excalidraw .dropdown-select.dropdown-select--floating{position:absolute;margin:.5em}.excalidraw .dropdown-select__language.dropdown-select--floating{position:absolute;bottom:10px}:root[dir=ltr] .excalidraw .dropdown-select__language.dropdown-select--floating{right:44px}:root[dir=rtl] .excalidraw .dropdown-select__language.dropdown-select--floating{left:44px}.excalidraw .zIndexButton{margin:0;margin-inline-end:8px;padding:5px;display:inline-flex;align-items:center;justify-content:center}.excalidraw .zIndexButton svg{width:18px;height:18px}.excalidraw .scroll-back-to-content{color:var(--popup-text-color);position:absolute;left:50%;bottom:30px;transform:translateX(-50%);padding:10px 20px}.excalidraw .help-icon{position:absolute;cursor:pointer;fill:#868e96;bottom:14px;width:1.5rem}:root[dir=ltr] .excalidraw .help-icon{right:14px}:root[dir=rtl] .excalidraw .help-icon{left:14px}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw aside{display:none}.excalidraw .scroll-back-to-content{bottom:calc(80px + var(--sab, 0));z-index:-1}}:root[dir=rtl] .excalidraw .rtl-mirror{transform:scaleX(-1)}.excalidraw .github-corner{position:absolute;top:0;z-index:2}:root[dir=ltr] .excalidraw .github-corner{right:0}:root[dir=rtl] .excalidraw .github-corner{left:0}.excalidraw .zen-mode-visibility{visibility:visible;opacity:1;height:auto;width:auto;transition:opacity .5s}.excalidraw .zen-mode-visibility.zen-mode-visibility--hidden{visibility:hidden;opacity:0;height:0;width:0;transition:opacity .5s}.excalidraw .disable-pointerEvents{pointer-events:none!important}.excalidraw.excalidraw--view-mode .App-menu{display:flex;justify-content:space-between}@media print{.excalidraw .App-bottom-bar,.excalidraw .FixedSideContainer,.excalidraw .layer-ui__wrapper{display:none}}.ErrorSplash.excalidraw{min-height:100vh;padding:20px 0;overflow:auto;display:flex;align-items:center;justify-content:center;-webkit-user-select:text;user-select:text}.ErrorSplash.excalidraw .ErrorSplash-messageContainer{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px;background-color:#ffe3e3;border:3px solid #c92a2a}.ErrorSplash.excalidraw .ErrorSplash-paragraph{margin:15px 0;max-width:600px}.ErrorSplash.excalidraw .ErrorSplash-paragraph.align-center{text-align:center}.ErrorSplash.excalidraw .bigger,.ErrorSplash.excalidraw .bigger button{font-size:1.1em}.ErrorSplash.excalidraw .smaller,.ErrorSplash.excalidraw .smaller button{font-size:.9em}.ErrorSplash.excalidraw .ErrorSplash-details{display:flex;flex-direction:column;align-items:flex-start}.ErrorSplash.excalidraw .ErrorSplash-details textarea{width:100%;margin:10px 0;font-family:"Cascadia";font-size:.8em}:export{isMobileQuery:(max-width:600px),(max-height:500px) and (max-width:1000px);appearanceFilter:invert(93%) hue-rotate(180deg)}.excalidraw .RoomDialog-linkContainer{display:flex;margin:1.5em 0}.excalidraw .RoomDialog-link{color:var(--text-primary-color);min-width:0;flex:1 1 auto;margin-inline-start:1em;display:inline-block;cursor:pointer;border:none;height:2.5rem;line-height:2.5rem;padding:0 .5rem;white-space:nowrap;border-radius:var(--space-factor);background-color:var(--button-gray-1)}.excalidraw .RoomDialog-emoji{font-family:sans-serif}.excalidraw .RoomDialog-usernameContainer{margin:1.5em 0;display:flex;align-items:center;justify-content:center}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw .RoomDialog-usernameContainer{flex-direction:column;align-items:stretch}}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw .RoomDialog-usernameLabel{font-weight:700}}.excalidraw .RoomDialog-username{background-color:var(--input-bg-color);border-color:var(--input-border-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;min-width:0;flex:1 1 auto;margin-inline-start:1em;height:2.5rem;font-size:1em;line-height:1.5;padding:0 .5rem}@media(max-height:500px)and (max-width:1000px),(max-width:600px){.excalidraw .RoomDialog-username{margin-top:.5em;margin-inline-start:0}}.excalidraw .RoomDialog-sessionStartButtonContainer{display:flex;justify-content:center}.excalidraw .Modal .RoomDialog-stopSession{background-color:var(--button-destructive-bg-color)}.excalidraw .Modal .RoomDialog-stopSession .ToolIcon__icon svg,.excalidraw .Modal .RoomDialog-stopSession .ToolIcon__label{color:var(--button-destructive-color)} +/*# sourceMappingURL=main.b0bde4ac.chunk.css.map */ \ No newline at end of file diff --git a/resources/css/fonts.css b/resources/css/fonts.css new file mode 100644 index 000000000..d78847d10 --- /dev/null +++ b/resources/css/fonts.css @@ -0,0 +1,13 @@ +/* http://www.eaglefonts.com/fg-virgil-ttf-131249.htm */ +@font-face { + font-family: "Virgil"; + src: url("../fonts/Virgil.woff2"); + font-display: swap; +} + +/* https://github.com/microsoft/cascadia-code */ +@font-face { + font-family: "Cascadia"; + src: url("../fonts/Cascadia.woff2"); + font-display: swap; +} diff --git a/resources/css/style.css b/resources/css/style.css index da0a45cfa..3a6e60b31 100644 --- a/resources/css/style.css +++ b/resources/css/style.css @@ -2,6 +2,7 @@ @import "./inter.css"; @import "./reveal.min.css"; @import "./reveal_black.min.css"; +@import "./fonts.css"; @import "./excalidraw.min.css"; @import "./katex.min.css"; @import "./codemirror.min.css"; diff --git a/resources/css/style.dev.css b/resources/css/style.dev.css index 7d9a95075..39523d6d0 100644 --- a/resources/css/style.dev.css +++ b/resources/css/style.dev.css @@ -2,6 +2,7 @@ @import "./inter.css"; @import "./reveal.min.css"; @import "./reveal_black.min.css"; +@import "./fonts.css"; @import "./excalidraw.min.css"; @import "./katex.min.css"; @import "./codemirror.min.css"; @@ -10,4 +11,4 @@ @import "./datepicker.css"; @import "./highlight.css"; @import "./tailwind.core.css"; /* Build by gulp. Check `_buildTailwind` for more detail */ -@import "./common.css"; \ No newline at end of file +@import "./common.css"; diff --git a/resources/css/Cascadia.woff2 b/resources/fonts/Cascadia.woff2 similarity index 100% rename from resources/css/Cascadia.woff2 rename to resources/fonts/Cascadia.woff2 diff --git a/resources/css/FG_Virgil.woff2 b/resources/fonts/FG_Virgil.woff2 similarity index 100% rename from resources/css/FG_Virgil.woff2 rename to resources/fonts/FG_Virgil.woff2 diff --git a/resources/fonts/Virgil.woff2 b/resources/fonts/Virgil.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..1d61d3fa254df7a99ad5c419088ce7f6caf38481 GIT binary patch literal 65704 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ʷ}W?EWg87&{17$^md>&PUS%zx#k23UiW z&m7lJu1c;y|00u~rd$=;+Kc4$QeE>z2^2`FS~pvx`U+3gN_#VfcSTPN`!UvxmM1vG z&P>{__!HWWx@KjNt(C;d=rHX9##pN*7@+-nyNLXmh1Hg^k`W6(hGQ#&SQae6Nuq)o z5+-3Llyx>VP!1MtAW;=kfj*Ke9le}zDHp{g8|ii`Ev?_HSGvGhrx6$2Yw?b2`;LEU(e(gDlTeaYfi};#6t+T!VG!uP zuMxZC*W)hPAVVt0>0w1NFmAd{I-o77r?xEciT7E3&R8Ebqo7}FBx_#ti(fx;^1kY_ z=9$uB2XJ9?z#)!Qv5Z)G!EX^Dk-ZViceI^uj8HCSDXwV*PTA(k7pwK`wtdO5)Vrhs zCfI{^vhx}>Q)>5A-EI^7ai_dz z)Wt?Sj`zm<{$8+`zawnt|L8N9=Fa()S+)a52TaY|QrQCl4i#u8A!7sJGm+sE6~Rae9O`S10Y z3;SBzUERsY{ThfnA+5neRS;_EO!6c+?{&N3I=D(h)rH=gm|4|M8l5@9z zg=~EnEkD*u)wbhf9J%`0jfsDT#ZKmlwsb1GT$@yxcs96EU#QKGmg5Eb!l1fU!`j1j zY6ni>IY6}4bWDMy_f=;4t#P%n7TC6bUiYcSXxA_>wM>jHr|K1*d>i9=*%Q|aArCCw zcExF2xlDg&=rKiX*B4d(W$(eN9{W?xU4=E3ZhL|7x{@=MQo)46u3V!t$})}ERNNsu z`|EtYS+8&G^bWW7v|A%Yk%{cCHd|yYIa)ikB?Vi0VAXxkJ-KuHyW5G4s2gb7##-T< zJFR2D^;%KZ0x>+V*wB@Xygaf+C#D2Zme^o;1_kB~&6S1f4tev`_`1y{V#{+gS+fmT zGN3ZTPY6NlzO2^jt4+(9ijjpSXbdb4wRg1eRV<)Cb-~pgMtrG^gTy~{WVJBV-puL& z*&qe2g^^ssbmm;hgZagxQYTSNY8E&_zHc@ffGqvViJjswXYzbq2`$$PeI?RNumUQ+_r`s9kKY$NslB8H;9r}qhDmW(dCgXdv1HTO zX}FH7w3AU&rLixkWmz6elmBepP7hyB5_=&sWm=+rAte2#-V_#%bz@Q8%;Z`drIOZM z!a*=yvLp+1!`R;4c*J*vZN5POU+d5mbsvDhcnIC*hp1@Yy}zvhqWzQQz-j@U!9aMB z)>zrm8(u%b*@7hzkd3YF8*nnFi#8f;ZO%6B!Gpp7erYRkQP{Vd&SJTc_g=xFyB1(o zMN(iY7dtA#wxseF0DrrGe5p$>o$-eokHL1VLMV0QvD7fZZseYD z?P)FbZbcDy+qJ+MlU6Y<#GnerQl&1|fbf0{+S!rP^ICv@gUCcLZ-H1W)tBMeJ}oFbMhCI1?yh=#3sT5L4;fO0a@U`75T%_1qXo5it;v-fe=D%VqEi(qL|eydRo zlZ+6^m$2S+Q(%>cqkAbq(jVmEqPgdC0CC zCxh46Sw(nbbG*07-R1dTd_8j>6k5;j<)F4SPR^qrk*Y?ma)RMx8UB(YxbcSHlNC7? zlqFXK^6E)*bXx3r4T*S&J zaIBcBIPgjzPYMFAve)qNiOyKv17gkk109x@pAd&VN^+(1u8P%)lNV)y%`YT)w%9HT z1rQQ5vdXfE8*pdqs>wlvi+05Pg5+dTe^sAq(6P)WJoN!=fOX7FZH`Um5Ms}_%&vod z@tc2*?0p9bcXjZ~RA)qy5=JftB!Ky{D8z_9d2h`RCv%uOs4RI+KEBb!ZNfU8T|~Z{ z$Mh-R2c%=RbmwSeKez7P{iIg4os-X7E(ocYNx(+prdc1h3uM!FQNBV{lk |lo^O3i=Arf}iDKBefD)C`*2d+xcQXOmXIzyBUx#H>2 zn}O}BgsOECZ(dacR!R1{0Rf_6C=@lHoJ4mL086Tb;kR*G$>&OyUihtg}_T8H^I&;K4$nl~OsC%u9Ap;k2A#lCmHQ;ln~lsR5ADab7s?!fnN= z4dks3X^gDC;jhC_!bT`X(z&lOh|)*w4~B1Eoab0IDn4|G>+6OVP^T2W^qSllR=^9^ zgAOKvV_RNXsoX0F`-gLH>80|@mx9%Y(}u+W2w1UKgnnESvS?FJ5fg5JW;go~f~2HI za_o*9`x{}`@N;$fFyAV!E`#wjW@4}-HrUUip!VWcWB{=0lVha->X*Q^&kuH|xQ57M ztt+qOX5@j_#X7bH#gu$K%)8r1Td(e~$Z49I1cRFHi%k$2S!@Y5kk@=+ZxcQ~-^$OU z-Qn%p?FF2PH%^4T?8?sxO<1fbBt~a*$CJYbP%EyU2@d&j+j`W@x3UTn3xcR4QRiif z4m91oaf$7$H0*F4fGNm-*!|aaVPGEe)yubbl(m%{@8QDJdmy;;^W#hL&RC5w<_a1|XGla893 zfu0Ey3lsVfI{`7qxb7)B8AE?;t@gW zCGLieQ1fYyTgyesZ$3M_a=BtjZkH|tgHCrHwwOMM24w(TGd2H}AiSj(5(@RgH_H8_ z4ygMvPAo2+lia+**6&;X7p3S&fl|oVV6Lp15lY#b$A>^{TV7Kzmw1)4%ht|V-ts%R z*Q^h29d<{D{n6;{iw?iOrdS4mudBzeHeyyNdRxM$W$U7Gpt%aI^#dPEpeh%sfcM53CFE;}s^tPXe!NGwly=t;Us32{9g^KxAL zfU#P<@wJqOGsr!GQsLnHXN*|HsT`O%K(>3Vl(Vn}rw2G?fLc~FsJA!T+)ZvHdB7Za zhf)pKJ?Aw&l)lvmDC<_7SnC@jRg~-4n@5(wEwUj7)~@b)`~xrvL|I7LQbt7bvm3#^I$YmgY_t;>83RGW5&qt22$20! zVu#UQE!!6pB)C|Nb;oEp2q&2m%3x2BNhR~2do zhlJ4enX*L73@5s%0II;I4&4HaWSz&b338L3LeZ(-k+*3opQelARyj;`Bg@*EP&uoD zdl9Xg9VQgWtl6bT^JfH+L*tBiE+T=Beep^kCIqJYQsn;;{KPaazk^!BMtLK@(Vj~K ztSFSC?0_PvJ-NFWDy~m5RZj-y>)n!ob}o!=eF@!5>Z(FZY=NY3Q@YE3iY2DXyo<#C zyb4#wUkz2ufvuts(o5wPuDu}*tappr(zu7#@uu3frm?Cu$ML?kAu)9yAn$ z<%Yos{X(?rTduZn|J*`kB8ym2-{3Bi}YoG#fj_CV+-GB^#pgA$N+8@(ElA262Z!$1t$p z{s2>0$1Qao;bWG*g+A5`NS2mFO&e%KfQL3n4K~2dlPc8*kzOZEhPKaJh)5PxfgMbG zcPndE0ewjm06dX<|0;$qpVccms$QOc^9gO8(T6L~LgG$N8 zs14`EiVW75#9cFptX3oj9C&fqI~ov^k`{FKwNU!>cEl;cX124ynN@_N@s%~g@Wec zqjx%GAdDpy8q*U0+E*VWG%UOF*cF$0VZWjkOs6w5M__EC*z?nj|8rmDj|M-egJ7NZ z*LGQoRrT*ryTKTR&$VgNn}uaZu^eHep%Mz8hvxA4bMdDzRv>%G;}Mp#~=?Q{z2!` zZ@o8KVF$|-7Q5*0F?EoQ$QUGHa@2`C9Uv;v28A=j{@5@;vZT8f6JhKUWo@7*DRaeQ zU?mKD3R^({f=i!c+U*Pv(cvto&UklN>sKPu`6o1+pZTikeQk2zrJ)@bFI@FeM8Vc$ zyxFT|E+Hvq?$tz z8AwNOz=g2ZwcxquSiV&upA|eB@U8zMp=rUH1QgD0cph8m8+Im)0!lrN^nbfcoY=D6 z%JyiDHJFA+H31QTNsJ}S3&Y?RGv-npu_Ryp5tiR16L|edveP;xgg{CFUCJ~jb4=|W zt^>;OD`48WO?yV6fy;X128NL|)5z_GCDY|i(nLxlZw)NyS4u_$Gxms}`4Pf(H z<~9c1z_&G7M*%YY8Ocs8PKUzIb?;Vwltr%Ui2Ah>Zj; z?GaGt4~;dS#Rj}Vd3PE^_evemcg_g!ZW!%%*v8WhN6V^R3^$a0Ft_Sf;Ij%Wj9^dh zf>_5}vj(K$|L{Q(TH}H&{y^yYXrXk0z(MF+D0$aePonK+7^6;plP4Cjc596Zw5AQj z#a*0AQqY(2Ud%wv8K4Wi2e%0GZjpF=n$l7nGpa7ZrOGsco%jscV(YvB!rtN_WE0q& zDoepJ_y(Vg`%QKN8&;*C4!MVts+H*#eZ*-eZ!U-4^S^MEnmZ={_@}l^a|)nVzF&FQ z>@`G)+6+xvXhMQh^EEB@$CrG#X5e>X#{L8IcttK+fU_a0vXhK;Zm0l&eE27fH67Cf zx$*ZxuOWTO$jbQg>7^g1ZCTcYe_>}Tii@6}6)Vh+ z-njudt11Mr(iUu5=qzxmhP@z`P0({VsNIMcz80_hhL>M9O4tnsMxakbz0~J`2S&U0 zgbLKEr79zIG2gsgg)mG7Nswn~X;n1YZjV(IuUt(+?vfM&^;ql~uX?ypgBL(rbu=Xq zZ}P$T*6UNGrR_I=4`qwyiNWBh$LyXtcfo9P=Cvxc$2=KT7X5H1Q8MBQBvnL4w|Yz> zt*y%dK+C@9Q}nJ6mZCByvmy?bqWP^eR!KZ?*gU8n{XtWSuwuHDw%ZA;SU$$LZzoda zLEmH|+0lV&?C;qrI|l z8H6D3Tof5+{*%$(R|TjCvI{>*(@2oKcs)tL&K}iSWN>_jEAa7?N6qND<=MM`cNVcl zDvlu(7>_W9f_E_4$Y1S)H6U~+~6 z$qHuL?D#1Y(E>-j>EnzWGWrcYU<(oASx*8lgi~DTSqfAsO;eOr4;@&to5n_e9z@Pm ztoo(th5aXQpE2ui7Ik>p92yVMnU}C=Jl@($6#653Oqeyom{%pTe?iPc53OvU3&N6wIbwG z4bg`SYHb}g;heL(Pc!+ z9H=utGmZ=7g8BtaRy8H4Y9vX@OHRy&v5eZVd?t2O_|XLi5crqWK2+EED`9L6`HeG+ zH4Az{Fk?oB$_?()-=31IFizyD0nHWR;3c##z1>Tr@3+qn)J#ofJ50Q{R9PR_WbK*# zWJBmY5=}i*@ZzpF0@(9-om%vH7?4T=hYa$XB{)%TiV>;~{@M(aZlTd- zKeg|IR@xcs&~);IZluWig5iY8R<}t&v3Q`NcX8IfwB?y!oa&?o^M6emiu@~ljJQZ$ zDW7?g6Lyf_;B~vjb!!v9Qq6J;i(g!~_*WaHaUviu7IF-Ei-$pI!6T^3~m$ zs~|{zzFKGQ%=#4x1N%kt6YzRx2AFrwN~MV}tTFXIS0uU;<#zs$JM}jU#+B5 zofewL1IIu99koS>y`C6=cw5+K`a$9bw>Z#|d+C%V!->5LZ=o!c%R@R%reLy`O?48<*qWt3GOYUzpZ@P#jo>wYf)5B~bp zjbfe=hMSWRS+k_i{H_20-*qBn(U<5+*7WCms0y~Ob}eA`zgTR;*MGVfbRc^LC5nlH zLuE5Xn?myLFlLqW78=ayUy244*N=VL8vu1=a|*1Md+>9XK7I9_2s|Prj&mOy z;MvsQW9DkN-^s(-;NY^Rb-u+j_M36r2ZBy5?eL)coDemOD|TzQ!0?#26d4V^{9Q$T z6R2gD6Nfq}*RV^6J)zkrQ^$%<=x03hlA-TDeKOTMrroc10CITRe9>GXDE?As{{JEp z*u;w!6U7OjHeOg2Fk=}gpqA4z+fX6+>XHRX`-R~pXlKK00i~fx=?gRhs7Mu)Hcm~v-D~zVGTdVb!e)L>VwBKLyoOIz zqL3BJt^!kM@7F9aTdJlV)Y;pUZI}j;qSscD0)y4+?wSTlq10dp_5ylWDug-aq7an6 zNL+};Yg1V+KZC;a?d()%j|urR`|dW3*|KCJ-q2+YX0?f4>VSOw&MNyu&2{$cOuj*Y zgen%1tFB^V*1bZjh3v5;y2j`&r?$!}w0GGfo0mQ#8gFz0Sots zkDb1#UnYOyK31}e60WHIjLQq|?;uxohcer}-h)d(7Ir0vFfj6d2`l zjRc0kkZVW^Ki=uTu>4V=N)43&pXkqoQJ#UtBTWgFBQT^i{Gy@6Ywnl6>|;3r>i*M+BYWx-`=iZ zDQLp(v=&+T*f%mLYJJ7_~FOu?;qnuG$5*k>HOVGl<`Qv4oO+@$d}1W!DlkY9jYA=@ zkJLzxIWQ2{%j`M!`$byFyi`mpC=G4%>@hgJM7tsi&ZW$l=%YUlK=z`+kCKo}|4q%< z<3nPqyFoPvMfF^WRDpPMQm>=uMq&pNg^<05MnGI?27@BLgm}Ix!bxGm73Boj8o>j8 z5ipn69Bauen`Bbv3`FKj?F1yiO@Rcd3u|n^&~5Oo2poH>As!>qsA3bnVCcc7UZt=- z(c*^AH-l_t@oj)r8`{fgBsJk!eV4`HC9VO}AVhE15V4R>W`9UTtfD_?#XBS(I89~N z?xP`{RBhN`oO{B&@!NIMm6nS^}i;PXZ-XN-sm zQ&cthfHu6y^gw6l9734v2SkFr}I0frP=c0LL{1pPt5{u%D#n6zgAhNEg9e ztpdI<2-<0o1gC00e|TXvih?urpM2NT1Hw67Ed{IPMj)p49?=$GyJF0xZ({QXuu2ju zjRx#)d_x1N;Dx;=+_XVq1$3Zli5V>eRjZ~0ypBru(e4`wEwT7p7R>fNM1o9J6{egY z%%T+}+Liv=JVNZaR|#RY+jYtT1SQ?(7(18S)Pz4$yb?Ujf!ib@sLaP_hIHk z19jm*qEjy{Pt+(KhEf7l*LvKCFraV%p9tV)gyGp;+}U6Z|`2L zk%ZD7%Ye{2BUh;lRPzqhY%qPQPlBFW$xi)=Rl=UwN08RTH--~8wZAAs%*2+s3D2HT zy}o*SN`kFupfOXc@Nl7DNYr~U+!9FulhxkRqbI)tbi`%C#%V#ILV#&wVh*M z7#5yb+Jq)9un)h)K9Ax~Ygw{C1gSEw` zo3#l&$I~yAO@ho~Q3Z_3FK0)>idBqJ)p9JW9yi2xjCCN}pJ_?vDkT@Gi~RIAkZeR{ z-BI91G2r|&y2OPgRR#%ARvS&12}6l7xF+iOsHrkF7ui;)%(U;BYf#wxOpB^UvyufQ3oZ4X?fg0;^~z8Lz) zgz9@#VyK=2L%Q8=UEV5w9pPt95EHdnM+$!EQB7?}UMfynmYU#%LtDRe$N-h)4+S1E zmm%WC86KW3dz0_q6OgVAY3CY%=tu{1-{o*wR#*8ZPcHiz*_AJ5=}S^J0Q>%rm9;xA zQ*A-{&%M@v!XV9oOF68?W_ z&~!3|y~x;vRNsFG%eni1?Poc@%|?iYi0;Mn>p?KzH16G!^zPQmaeEJx;cRf7F%el> zAVoMSwy6j``NjysqF=Y{UOTr|G3Mx+rZUUVJhT4ib0IJnXbBQxu!uX@PFFkdzm4EW)O$nc%>s$omlTA%`*PTR_8TTaz1 zZ-G2xt~HQ!Lwcw~SC-yH_pY_?W&V{W0W~%18V}`*v-wihR!brwZEMt(y5*naE=-bA zwHR1QId8ill=DhHRE(Hvs9^S8H5l(d@EVRl1ft4{N0ixu7+O^O^T|g;Ho=OQ2{DAo zDZA&U$-6kxwhI3*!Xk`mwaaT3hd1? zm?p|WmrAvM6xDD!O@9#o3YqMV98o^A}meq1msFJy%`)j4>*pJr?oL<;KfOgcP^ zaZ#2B7cAa0Vjoc%wT}MPlTTdqPWK<4eiMCw zq#I-N8E}RXH*YhaE4uH`s+zE7J@9W@vtqX9F^^k#x zHXsg`!lTKL+|N^CbSQ+LmhrcvS}fO}SCaVR2_88yEfo(=z@rNv)@7n9FUS`%`);rB z+9)4HsI{;SH(<7*`H^$?KRRLSl&XU|0Y;)gi_j)^g)*weIW311_S~Ksg`P@@k%4s<}6!NU=#Zgdev4T1C0! z#V1qJL%zH%rcdMCZoaJ4yi z_@JMox|Nx5K~@wts{Q1qSe;s=|1)>g8QF-Rdck)jfGw{VC~MQ0tm;JKli8^C^wQNb z9fDrq2-jO^Hw^XW6o;juwryo0@&TFLva?{{s=y*NJrhW*YKuUb3QN@(4Z7fx*NK_( z(fanG36d{mMvss=*b@a6fG?x}5&hTOJOOlOSBPOGt6Z6tWk#Xf>@??!#edad)Jg_? ze_LqyJF5%BmZsK03A%E&l~uN#nqJueSyo?*kyJcAFrd4|B+&iK?K?aFRRhnZJ7?GL zqjvEsoXC$tIXGTyyTDd{zSM+QziWEzNRVp*rr1{oYm^Z2Ym5f0-7G=;w-nvD%Q0TA zI0P4SM2+Cp=V?z6g8 z*cgn%B4Mc&`_|(d(HiAc#+?9czLswi`)l7SEjKE3rR_X-lqwAx``l)q>j)$ITc-(a z={*+ng^|zBjImtjWF_v(4t(=QHbFfqNt zK(p7AV?|5pNL@x|4ak$tKMy0zRT3&Yu>ta0--A}S5OjrKYyR$}`Fsm218&8V@1jiw zXMdWY1pT@45~@!3s~|P~^|AQ{Dd@g@^+uhsZyzN)sCs!y*hABnzE8TKl^9^`mX5 zi$0k*MpB>|^E9v!b>Ps*5jijqg&Qx(2G}xpgM1UlaOH)hOu&L?3l4?=8`!BYy8DNp zMTMmqsJD2wTkE0Q>1ho3W&}(z7ESn5L{#1ps|OujZO*}x;%u8X>}5-78CCB`+zkx_ zo!^+DW9Xjs_TBCGh{i zNKp9qeK3?2cibG2PmCW0C@xwy%}s_z<-o2vRR8j7kQ!yy(LugQ^IWjCZt)fpCefLl@2NPXsD>e3F@ z+n<5G;QQgNdhIJ36@7yfBv*)FP!xcJ%>fg z!g^?|45w`638yc14en!@wUs|vk8U!}OX*={<6<_*F&4|Q+1HdWSeXg@x@RZ&O8_9b zs_IM=7Ii<4*-}*+n(bueJ|hpP=3n0WNpYX$3YVz6oPI8s0Y#-_8PRdh-_Tu71iOKK z>nqQv5ZHi_WWGY%g*^O%dZc99l>OI1-)wYH;ox-Ek3tFqT zs5C@2-{x3VC@ai_4ct$%urnh=3yO0ySR{lg!Gz!#(kG9sBewExpeG_sMs?ssr_w;x z^;8Lxjcr)YRm&6+l?L>j^`*(|O12%t+v@fzKvI>maUfK^S`D3qu}o$o4;?a7;&OmV zz36ig2A5>cp!+yqkgNz0PL;9=6)ysHiN?-rIdwm9N{H;CYW#D7v(@7X1hy?XuT*S4G=ho9YSa|sVTL^k*ad%|4>!>;tcbx%QNW{`doVNy9O(13#? zo{V5WpefH25SfoGUVbQZ7WG2B`CqQz=79SUJ}%8Hb(N0EuJ41X{%y0y#jJ$qM{t6pHL;LJTZ`nA)-t_vHIhWh)p1d&xDfjS%1Yz&DHpHbCtBZg6nTYXz;> ztax>!DV+A^p1k;0Z5#}pKe8URIBkQu&{hpzgj#>|+&${3pzCWLXGHKR0O6ZN|~9xp?xl1JLe#_b@uFwTcCgVgT-Swmc_(E?ROu%w!^N5 zrrB7tXjcVbCH>$2^Vbov@1_liaJyYQo(Z~=+PTx9tudSK9R~zv3LVe)-QLPdX{I2r zx!S+((lR`n;$(v!q+qo&#!?lP_%;dZ_ z>;}Q;MV||8=XFzKp`dhrkB7&$E;BcN+q7G`jVzH4q?D~C=K!(xNH6%&WYSQSwRnG0N z{vXY5uc%4auKLZR3E!r5+KvQody}ppLelwGU~w+zcp&5ir4TB5+p)1^gm=|W*>e0z|%#Q;_oC)aQvUx>LH_ViEdr!&LZ#cPBU|M}UgR zuTnt~RpEVp`)PWfXnRh!u0qSv^iAmUy=*DYJO+EHP_>tnbQ3kCAGm{{>jRZ zW^Wz#wSn|y+`iPbEgKgcIZH;wqE5sm6b}@B!%iJXlM>B)%O4V>B-O{3kQa#u*||`0 zeDeQ90V@NH>bv_l6;1dsA|pQ#YX|*@7W)$BUo$P)^OjwjI7DJc!>%2-uQ%_mvADmS z+-6uHUB~4y3XPL?e<=1n4{6l-Xy^!w<@1bU*YZeI&AMCBuGiJ@uo5ZD2y`w{d=IK&V?g@<*H0j=DYdQo?nKK zz{3xJkqpd+lI*;=o?quT0KBB?kU9X*$Z`esN)rdot7Df4$rADdjufQ|GDQ8jz>CT) z0FhXgWtLxk`W_lGN{@4(OtmSap%dB+*3~M3)BgDf4XQkGrQj`-VZkt%^U^mB)i_7B z)tQ1`DCEoj;~zz$IhJwnKkih;b;@ zX-vhli6VUr6mT^HKR-o9g0Ji3>Ji;)@@+n(ZLjWybtUG)zkYy)sv>1`=y?ekuylWo3e_ zTSoP{MY)BXBZAR9H*V{>sUQD*CUza0uS}_t>>fyRzl^~h$(Mxf@Wa-f%ca4jmIsp> zN1GWwS)Jp;1!-SiOdNc2F!3gEmz6*~lG@!wq1(5b zch(jYq;wJG$@C`bKM;?Ql;nR&L0iQDi2Gy1X?q& z%(-G(j9Pd08Rx?*ou5%dwPmM9x|9U--paegzL&zh?4@|_hap=7)?x_^8#x?Q-cSnQ zt$VjGSdkOYiaTmismz_vd@S1f=+>J8HrO_;lN3S?no>6##Rj>s@??7t638BuT}`pU zQt{_^ZeC%?7>%Gi6Sa5*u~OY60V_)a?QeT?H61+8x7 zE`zx|)Y01fjk>yqe~^l6d>M}Zl!&f}AobIK!iy9QbmHSluXPiMeVh4FS=oa#5t|QO zM&YV%3ECxtm}y&8HZ_ASb{d!hR^G4YSikKE4vc3N%|epmc!V|*P)lp9nv%`yrGE~; zIQecU1dJz48Acq6>Y#+B;d_l?eXe}u`m^Ad+f#<4%i2Lti<&AsYsRX*+v?2d3U73tB!+i{Pdm|QqNF5{YNrL(%3F#o3WR^HPLX-&1uR|yQ6sTn zrdohZCTRu~`h9XAui!HNnA9n%GPL69Z4ROI-J^Aj>HQar9QdAtkm zMbx9}wz>&$ZBNl5SW{;{7TTZo@m7pGoo1#eeVk2$g_kvZ%wi|Yae9d>mCFmo_#89< z#x+nRzVqSJe2DOb16(Q_Cy?7HB&#R{cuEunWQ~S#iI*7c05`NyNb#WYqL}OmW?!lW|1{w-i+p&7A3Y zC63GU#_E(kqVO#ij7pC)9axlQN>R$PO+8A2)m|zraqsqdA*vY-dY)(aPoW zm3*9oy8+^>vWRR9yAY`E=mLn5D})Y0+`$N`>}ozqq9EX+qEnDL9K^+n)U>9s?9OSi zRbfYk9U7}VK75wg2$`lo6FgNyT%($uu)*Q zGWS3J7*!G;-}&aB*P&jxnIp*jllysi8SKp-%7;hf`=EaG;5o6?tEyU2M3L`7ZJSZttDI_NUQqv@K5 zQ=NF09tjZ%)rMlUHu7GbnyQ~Wf%|6rq3GQk@sYgWPGq(9kZ#b!PnFD{2jZp6oEJe< zFoHY-f@wy8M`psApH#9kZC$WRAkqiOc``?Jm;X^e|IGh?Y+p|$s~f_lZ&2o&ypPpN z{l4O)_-A7^jqNaN@YN7G?H7S;Urt}_+2`~mWl32w4?#q++A!jNF}g!Sl9V{A^fk=ydZ+BWxR~E04{(l~hz@7H%8nMax+D>`ej7oZOtRmMs{ zO#1(#YTRv*Xv!w*&e{SZk9|6o7MVyehP93^<5Djk6ZuWe(!7r{_OJG*PzAj+6vQKd z(H1e#Jr{M={lR*_z7t9|?tRJeXja(J8hf05xoKZEEx2;F%%o9etptSWN(D_? z*6dv-O0L;DQp&|nJ2ZhcJ(oqtjok>9unf#hzS%c!EQE~WSHHi%OM%2uYh|n0-f0lkqf0M|14BC7HjvPzBMkdv|CkQSX`_M+< z{*Qu$WA;$Ed=i~NFG@N8V-z;z{OeX+2TDEys+bG5M1fO;-x}RHh@Gx4_1yc_E=hs1 z(8$-2Fj=M*=)e@!LfvzQJIOULCGY}+qHD~)3cmHyhG9eu=sI^NcxqfXVdJ1BS7omc zE=#4PNw9h_#*o)hfG8Y7<3L_5;rBoh)E{(ZpXae4l zY7x7_j)DVp?E(rw&lWzll&|wn$HttoJGRxtyZt8}yF1ok4oi}YHAzb(GF4oHp>%b0 z6(LHJMHJ*JQlc00Q{SrOL{UoTlQuvgK4uQ|!T;*gGBTIGa3ilcZRs&>*Popi)iD|;~I=vYC7IWa>3=Jlk(OXgZgwjmO-MU%qyrI`#h(>1Xo!i$tt zDu&=>UsI>tpMnMH(JSM8Sx-1>d-zk0w#><*e1Vg%(Mqe8PbaOlyrjuG{af^}M41#{ z$6>rPi9}gq5Iw_}g?QDG$QGO=US*DElU0CRxs-^cW*oWOyaRIuk1FUdxA!f~zzq9Y zas87JIDu1`ku_E=wA8Gv|7*W6C>%bA07gK$zn6iDNHts=1Rb;FT7L&ubd+_PjuzcL zac{R;ASSJYOJSo#=2&tp&lmDh=Rz*{TBa7K;13mgA>QA9LamX$+=N4-RrSy&2_};& zr+0cceAu1jsq;%wf0Wz|p6T3Kz0)di^AO(i3famEsqy?2PIfGeQb@<5#g*loC*pN_ zvI&Qaa_?VY>;GswtXw(2@P+h-qWZhev?iYka;NJIx z%HI1(RN`2HSk%gE(=%DETNJ( zp4znQBlNRgEh~^^aX|6;mWWC=ssdPCniu&hL#H@JH{?M=pl3YRQPziLT@;a4D~!!1 z5MZVnx1)A%W4K%20$6f3sc0MJ#v-I?St=uQiorxGX$4#&0g(-vg#<~OS*(;ZoNh>S zA~WMNt%3(-gQ(j7skLD>{dy3Gjo#Myu)d)+5_P>8EiH?tnn8A4S(F7^pPGnmAzkKc zVAe&3<77SWF>QrYl&N#_^2J9-3gDe+L*#2pk@9ANkeKpza}&=3SoZBH%Fwy<@`Xo7 z{~Ym}ki(=j@#L7wHol3aqT5yxBiUhi<{dyFus>gff}?x(bo9si5_S1dZa8{^|ABvs zn|z63a#J5uTtQA6pAU2(zMQOL4xt0p4V9!%7ocRR7G|(2TA~SX9=n=!5r4inO9K3P5gSbu-2i_?Xr<@gMOY0fHJ;KuN`FWj0zRFKYkn2VdzYX~kc+>4G- zZ)Yz^#%kNzXAkU?{_9dc$U0WCW%ndrIEz|wS_Z*hUXja%)j~G2Fto2QJnn#R=qi0R3i2676oQx(wKKsTa*#rSpxMx$;iS-t@tV zZ@WEcZ85BJM2=xOK9>(WFG;G-r|wY>iKmm$;Zq?ngP|uqj!;M@H&*_y+CbTrgi<>_ zN{Z}Ki z5><3PLd~6RDoDPvYJ^@I%5Z2Z?6vjzF0?sS-A7JaCklF#?p(kBUy<|71sgv1zoh_8 z?--7By$z;u>oUE4&UC|(wr(8&1*N$ZKsBXd*HGGl(Nmp{3>6e~>9d)(ia)h43c|o9|Lg4qW+z0k(a!6cBPdy%0>CPZB>;|*tKf$`i%cVt%=X|y zNx+S7Mo$=bjC3XXJGW?RML$ccOF@P!!7i)ukyvo#R>p<`OJh1cbsw^68u+ z8RTox1fFZ@-->wu6XmuajjsUX(`qJ=T6I3m1o!8L4zTvWQtHF^?lwXZBr5fggvM$Z ztxbgZJBr3?XU*5)}p%rs#MWNp(inqId) zXqoZ3K%*~!)iu7}=wOqs@sP9v>19>NL8%+4Ix2`A7`z>>;J)5LkV^s3#O@26edAg) z<2iypw+=Tu?p>Njld6u3+p$oS2gzeCpWHxxXz{zMe5SPUXz8&@U^^Y2GSL?MTuJaW zH;+6*lF;^7BZ=q=P_0Nd@QW^;apM(|NBVTraZQnR}o7XV%0=x4-^ZHrOaC zxg1s(^hM5wrbIl0`J^y&7F$dzX9;sm^T@;XxN(StT+kTHD zQf2$~IunK;N!IWZl@&=6&fqhxX%*;`te-zWj^cTxeTMiq>!)qtAM(Q)E;Wjm6?bcB z_K+YWbw2F@*w66p`xM&M8Sf8TIFCV?&XZBuU{`y6(m&`AQ;H;ly1e!6dH=_i_NRZ3 z=-0b!f-_!b(@*qG4op{u>iF$lWykE%JW4$yL3goDG~t@^Hd`g;~iC*@u2FS`tl zGfG{n>i}RI_cx${FN;86?dm72-KiwD)&svaXgUP_i8jh6Q^|yPM>NxE06b!rHCdNlri49$pY}c;CDxLH zPUJ4O3mk<7`(=J{L8z3XCBiI+@vhm{u$e@$N8%RS>V3Q^n!Z*EPbcS=cGdwnV|y+Q z7t!I61Q(U0Hg@ogEGdE_T1U1!vH{tPQpm9ZET#l~lTLkolss0|I2qNMha-Nt{VeI^ z!4{bnB?|}{%l!Xz^KLv2jxsT-c>?wA+_M4mHVU12J1Vpy3(}JsCsn!x)JoN{mKrV@ ziih>jPiFm_wqj|@9yTO3o9%Rub0WM1HwynCH3raNUW!wddUWF$2DZ}c7{!?$5~y3} zG7cOC2RF$ne2@~0Fd#L|Yke?zJ?Bkk(xzrD;JB$=wiZvP{Od^S)IUb9ft{2(ySGj^ zntYrTscY6Cr>SjjgWmxV{jHr8JNvgzqk*)KmrAcdwT@@-t@sKJtNnLr(~L&ae@3=x z2r$RYC$9UnXO5(41L^qwBW`$frG%u+Mk$yo#WPcbi$hQ4&gETO(mrGgvEtTU&tg4_NHFy6~- zv4d)dgx2B^NNkbh;DI?tmqJ^ajqIj$^o!w|HnS7{t`@LBRFB&sGwmPZ?4&9$AMIUV z$qvQRVAuVb?fqG6zq!kcM2B}I5R+f`+zj*|FVp8(6_sDgU19W@n6W%+E#$5WcEAc4 zMt_kbD$G1r%fH%sb}0p8CD(%*4$ARh#?|P6=eZvSU-pUfh63QBISzA z6;)~=PlhnAXX6A^#^qQ?vBFMy-q-K-$YjhDCZd_FYC#VcIYs0PQi{@Q+S{>mfNb+G zel|~%lK#WHNoZ654NT?M)=<+`xja zRFLmo0zD?Climh7g*)I~s@pM7`nn8$Y>w=Rk$->BA0bVZIwfXxQe)(#6oiRk**z1| zv?TG!o`{JG&27k=QbskXRt|`B~1cy_fREupHv6Hum10Iq* z!CK4w>WcK{afNX7lPUf8J>{^WYx$aCM6a|2kesrouPU%9{TIR=dp=l&MG?rZ|JwH zuWtC&O>y{we?4rMi<_!?RtU+f=le(O8krN#R=_y5za6bLu}y86~-!ccdRMB`Drx%Bg0JyII- z-^Yey2ECvodsks2y?buuduw9W5Z;DPC&hpj-&S9>+zDkKK!ou_aK}ZIfFcrMc0TC3 zMemt^-1l`58sR5L-v47EfiT7y73%P9?Bt1VbASjv|2Gh$MFp_S##Mx10&*eq5ZF&DKqlt0H>Ar$z`G0OD11Oz+W6h)9WQcOo}P)w8ZltXS8-KD zw1?@(`Gd#g(&fKev(!ZNf;&L5RjB8q=9uH@K6d6V>3iU0P`R5P!Nt7M_YvPmLmUE8 zqzZ#8GtylhCJ4(@Wc@SG$5blpa)f6wQ?1GjrplOyE-Ds_=<7wAU$z~H2C*Cle(k%J zjYW81*B6~+ho@!K2esoaPnC59pzcz7D~pJYns^{-rPk=A#<5#q-_y@;elkN9bnDMp z`>5szw9_MO{KAEm_MGY4N9jopm;*oeJvV&*&^KMP!uae<0e8hi0~#?W!=CMb+&_qh zC-4*I)=S~vzT3cmHC^}3{v1^TU7po3^0hz(aH`-9KTeFY!I<6Z1OQ*=B(TY7H z8{p^Cxypxk*Xp`2+@dmp>pSQy-Vz(qI!hKwTt%AJ)`!0_x9-lewcWi^D+0Z7@7w`g z3D|uLNzZqq&Y53C(^_N)-ajeCWj@dp;ii7N@n+QQvw>i$5pOR|C96QO1+?TK6Fv2m zUB+C5mp=D?>N0-$6jyNVdJcQzgv#le^$JO)pkhHCkzO89m%Hrr`bSUJi7ZT8KJzv_q z(+5Y*-3SSXGn1oTFyrsh?0~Luz7l?wpQ~SFAmC*FO)OdJg8j`;d7_CP`GBVl-$gKH zu-w0}4^I!6d#$W#ndr5yAboR|Uos1A9w5-5I>Q#j4wFFbfo3wqE*XLtAsbp2`FRBh z2GK00CG;6~rz-r6S_Tf8Q@F}3VPpY_G+sJ_7)x@`TgeE6s~R2Fi{nZw zUC$&In7JcGEH(;z(z_2Ugy-Kw%v)bql?1J;9X@kksI^E!zPY$tW3$-tiPwxwOcTOX zaroETrDCT9BhQ<^HGW%mPKpaRUsIIEOB@74%@f=--LgNeAT;(3jSMdr(~QBmdgrIq zDI-l{qqy?sD9Kqu@UQyUR|=bDn=c1a6V|_HrS*S{S>$H)QYbuE$vGu?Y@39vJ&0FV zqfPWkqyKeM4xHxw><~_NH<~r%*OxWIswL8|DQ(K>yL33cTdbUe0Md2|-(AGs69yez z3Fq}m@8;HC>TpUX1S;_4QJSkAqKqO*Jfu1aA0@!+^k)lK-kcuzf0|)Z=}(>_9}B51 zhlTL0ZrRvov1Vq%bQslTe%>Ap5Vx;9Do;S*BmQa&V@9fzF>_SF3%A^dfwU(KntEy3Z3{3+@S*apH+n@h?3Qo|bWU=pc)P&6$q%`5h&p-g;^het( zq<|Y!IT^i+kc23qH;4p2Q-_uS-!$F#TpgwMLR}%d`1AFz-WC4^BccsQ9+jvbbM^t7 z#^Q7sloQG!bFooFaZRAs-9Xx*N)ZHXn`^=JX%Sn8bIxd^mmFirg}F^(*KnI^z2zIX zZY7Q#Jedk|BOjzg29f(OPI+hM!Mu2Et!HZW!q|IGJ4S|eeCr{4b!tqOEo<)7veMRH zzl+OOX-!LixsD)WdlhFpNW+nf-yCRd70ZZcp6&|=-h+Yt_&@f&Z&e7H%@9r0kr}EZ zI(5c_=sFLG7P1BR=vhN20Nh(C3~LRaVFZ`0ArACTb|U19o4vj!7^2Rm`yc*c6VPv~ zq;FzhUwLhzrpmf?c^jTL`gIhC-ZQ46QQLNdg7^7HXFe}l`T1OcJSu{m9T-EVq9hwE zb+XBo5?Vj6a%R&){AVi1}0cOSHvR->KoQ;DaB=C zst2_lpj&gxgI|zD|7^i-Q*4>qsqH{|HTRa&h}JFv$t9id1+Jx{n+^!tcHV_$Ln2Hz ziyJCY|E@2tPK1G2W-VknDW@iYW8Q2X2;N8Bwo?Q#7- zuxG)huuFkbGh3G2z_n7CwqXa^OGB=hCKSw)g_HQ#|D~&T@(!-M*kA6c5qUz^^tfln z;jtvvzK2~xg476F{tQ`lMhcmedhz?(Y8w1^X-8>~Dzc9=LTrG0+gH zJ#ky3!{}Ktl$gHwb@-h(Ye9eP6b5huVMeSUP{IC*^MUR6U3Iyy;1s9>uV za4$Y4$bmRZkf{|U4$xZ$LivDwp@l<3wN@RX&mo%>WE+PZ3<4RG+3V-EOO-_$j!#Jb zLisN2qd&!?yZ_+R9X{|-n)Q5z(H3oFx}6$-_iXCiMhD-Ct%U6{NUr?Ra(jHX5SBnd zZ*g^)b89sTRrZc(1drKz zH_;BklFMiZr`Gac{dqazts-p-_O$dzd9-C*dFV)>+Q4z=Cgl9h0EUX&h-M+tY)}<~ zP3nuf^O!4JNg}0F{}-xZ`Wq^lGUCaL)S>eufc5aMcdwk>`jb)6MXf7?{Atfc=VP0%Z)9SRf&J{J})4FyNE9JgyzB&+f@7{ z0HTokoer%y&AP*R;Ou4j7VL!hhOeViWO;^_UNi6j0)$n57=#BvX#{FE1d;twLSO5; zS>%;TyvnaH3s>khsYnaTR(MlNIJqP(l-bJOSr6}zS_E?$6XC!=)CTZrcDW93Fh8DR z$8#Aj>drc0h+gwq|3z%M#=H4~`9EY&5qpnCea(B|+Q8LO!6x4GLOtenDr#)^REt=$ zqkY%G_?oCbe0w=D_Tm25Rn#C+*WS!-N`C6VX&8rrX$uo8V!vknzxuq17<=3o1V@|? zjKjAqDCuQ^qGFoSYu$om!lUSxT!bV4AKIL*;fbA0?&x$&4yjA0uUql|&t#0h$>AAkN9fWf-m@}*c5 zH8{=D5bzl(WkQ~Jyl;LlvZih4=>E{HvnO%qIqha>5r724v5-fik3d>+GbE9GHzJW1 zOPr|gOd6Hm`5TUt;+PS+i8e+@l{7lrpN`v(val_|uvi~vGF%bQP@4-j5;Kk1S-WhcI*>LV*L9e*2;S(@TEvH)r zOx8MT5#>~6UKIcN>i1V9B4puhG0?hwPAGVuSn!E=S0uHfMz`F4Gw!q_Ht+Q7F$73V z;}pnKK6(VWnl6VDF)`@R>U|`U9tX9JTwz9k#I}Q1MNiGbnerEH95&VMJ)bK{8Pj~X zAzzW(v{z+gUU&p5*o{3N`ZAJKM3%OrM|U4gcr|oN!}?ZYj&3(twpYnsDJ7tH-SfAe zMevc}f<4p;4)B*4d%#PyMHpvrn8qycwkp$3=&5VZ}yy(08u= zV6eS^w6yBc__OR`S1gXp5Bl*`S<;c6iw6pI8XR59-`yx(<7$WN}7 zTnUWyxW^SBYk_M&vK+_44%+K_tmOae*1I2TR>YzlQ$WW(C`2&fj|+~3saocb_n&>< ziuy7KInfejy6YWe7exSxPNqA3kFK2UfN4*+fkM-l>g`?R>3NPH!!Le$^t|jncjrb| zVc#oj8A}uAI}sU+cwUbsHwIN5A#8pDjvaXF$?e?SCJJW?TVPVg^`5< zUhiR39wqk`=pj>tCgMPaS6Kf!8PN8>_VY|U(a)6l5(Z9Frx`QVw!Rs&r@J0KJQqq^ zHPM1Ij)N;N_oCHZ8&(fi{pHIFs;k9XOfa^>HhcvI$QR7tz})Qc zuVKmYMaWHyZc*!qY?!I`4V#-pRwz?w@&pOlY4ASuoFidX7i6Gn_Ciu3 z>)f}{ukBmPDF~y<9k5l}t%WwIu^Y@#yRtqdE*(_nINXBb^^4j(P0xW?67CdK-?neUoYQws zc$9+QWLw#(Mnn9`ajBfko+njG*vVz0%->*5%5}RWXf)3~v685j!K@FVr zKlLyR59V0{fvQG5Xk-?NG{-sXoBjLfgVDCRM$mYsxNgYGmM z;LrR6JYbZWe^05^WCc$8L6!VU!-)wW){?*>@7PJ*kVD1~s!tWGUe0T^9RuEl9kdA2 zM5`omxBVVO-RxrEqWcuj0(!vxQxv;cYB3a8L0O3 zW3S!0W%gK&N#z6lz(AKek>k_p8F966T<@QSmT796W7u{%*Zk zD}f)NnXCw=d^K$_epSM$lHLL|KV&(AMOuJc_Go zRKWIjCi!6zsEhslrQ|yLuOY4o?q7UX8khmgUe~$L)i>3x+793EFSBv4cK^AembY67 z-$1mYadi^1(_#gw@sdA4Y3+=tR4IhdyJ`^xgKb^4zi5N~(ra$K$T``I&-uWgZ3uOk zbrD531BD&w8(8}1PJ|_2F-6p>LrdoSMrYWtqQorfcZf%P1U)Mv{v=@Wu?d$%e&CrZ4CLFjL?v^Tfj3b2gV$gZ!9Qgjrw0Xf= z;nhP1`d7_25R@3FX!P^i@1*XyaJ0oJ_LkCu)gFO!QL}YZ-+J@3MadSWJaCjZeH@OI z?%%zJk~P7z}gny@!(fg4(g=2qd8Jkq%^Emu|p8Mz_YJ zehqimHnaV*$Vy6CFOS7N8xbSf(~uh)t;qh@U9nrm7Znv;hWZ+jIz)x)qsp-7V3&65 z#^ z6LJi;Q?8a{p;%0?5(&e=wpPl8r>@Un7^?C>Ew2=;vRAGZVxy*cmg0`aw(}g&HnVQGStO}0r=j&YFNj!XNB8>u3oo{f#Av_MWMw_SGDC-w$LkP4 z(v>%s|0%?Mg?)a=QmdMF<-Dwc{XkFZn`#??UKz#Q8`|cp0?Qgeyw9T?vlQ#_;iAfM zXk9yTNculKEW{iQfB);_pr>u?S{G&TC%eY^$T@nby|v3Gk$%EaL0Q^?{P?(crk1)Hr8$bO5(9YRlN0W4NAgY+|8pVVkEkv5NnY}L@xhD@ZP zZL?a8`Suz>>~~64qNOYyo`r6atokTsKJ?GJk$eGS{*kv)t_zQ>VSpz0`fA1Egf&{# zff&}MDs&i|KK}EZfr+qq&F{>_Ud(Z`49kvc`5a`&-Abd_%K!?LrJt0I)1CTB48W$k~fJ;8%rYcRm$d411MTt8#9(p!)He$QYR_Z|uT_SEt$n4|IlsN{#LH#OEkOM2jb z8C^OX%5r_+!lr(XeTKPqJ#EPcQ!Hkb3&|KYH%(X?MY{x95ABR?_I_N94g>^~l2>F% z9PfrNOwwOpz4pwZe<834kbB3V;Fvl2`nI9X7(bPJzK^;PllVl}mJ&m{#`sMJKGn_k z8iEU^<)V?%m_pgwC`jv>;n~58`1xKM6#qQoP8~hT4XZ80-0VqrD^{F zKc3P94gwsz}D1=-xXw4rT+N!_h<2Tps#<`DT%MSvNHf}Ct=aTYRrzJ11^ zR;kG%?1<5yvK@zjBB>f9j?5^MrZUy;^(otN~a0mhv| zyw9esq3u}f-Mzu95_EyDfAASd6_C6qA}0%<``IMR(zuHD(c$VM1a8(3e!QQZ`ok@_ zn?+rknfj#7YX=E?&ZS0ls0@vL2HZ1Xipr24yYd}`64d}9N$$~L=BM%HYh5DC{7rRZ zEsW4Y!#lMZWrauy1##`3;aDrA1@9~GGhZfw0iWpa=zh!b9X9Ws;T>0SValP^ErfmK z0P99@e5*VB>CW8z?*Sp(FN=Qkc;uj=P^z)PmZDySfY@D%--CsL6%aXpJh?V#8?o9@ z`=1I>;u8+y8+7UeN9uuMs>!f=Mz|)@rl>pQ6%aTht4*e+mE)ISUmJZL zwIUcE<>L}QA-G8LA^qYctIAQYN=95$V%nwi|1V86GfQWmAk>z z0vd9crAIE4E{ngz1%WeTT`@J-N=#s2~2E*iE@6M#Ea$(Gp6hIzKh*B~BT`HPy|(jEU4 z?x#~Pfg32Z`Rp@Luq}&y)@prN3}M|I#~5)QIS!b%aZ|g=ifsy3S*)MIVhGu|zV+lr zX*-#_pIN0eZ!{Dy|Tg1IC`X z2WG=IPmp1`dEI3J2L5QC4g4?s%bz0uDJ`#-drexn6-fln-3&|GYD>FUI1c>#b27RY zcUc^>%=Y5`&S5m zuyC-9*<>f@DB?70&$R<-vMj$Oe zXvej_7K%hwB6I+};!cPvG%eDw$_|l9-?vD^OfV``N!c+ZI6zzPdP&d8wjmB=Vz8YsONd zg&@W?Z#=5P5rzN5^JA5V5hCZ@`TX|Y;pMscVz=-NG^(iOaAZTxGpb|||NCX2EQsbn zoI!f`V?i$z+!U>0gQBg|8>Rc+HCwq z-3!43bPW7fvmGri8=ci}pLc^d1)urZ)615j{MlnhlhO4^J2gpKt>s zBFhKC3M+sR&+!<~*ygr#HvNHRy8?$lHxv)u7`-zBI2h#c+qr9NLsSlVZkq(Iq2sXd z+7rQfIyRZ(c~V5e*ih!=rVPHjpulW3a!SeZ%zu2+EqnQ-G_){RT)`GF57dV(Hm22G zLi*peTh=mFC6x2@2RKjK3F+W%OM};gEbbvH7wN{yW12pJb_r{xO%c2#)p{c3T+Aoi zhz+`UmS@>MzE~!JJ<<2&zd0Lbpbsnhhq94}MhEOV@`i3}u_hBeHi<-rOE<~i{fLbY zW{aQN;4j*)2N1})Go}lBy%*to4BEvY$jSn))^f%YnFTvf~Dxn~`PPyyAM<(>rZOAvo< z-%77=itoSt-9{@wQ2X60)5)bH0~+ge3KdHO$4k~5lN*g}JDu2{QCVWwfCKB1f7x9% zB6rXxUE3$&)?2!`k3>M{?Np|x5amZYU|IIgXLh+W>TOg86Apa$LA%{DSsd&Jq5m*O zlH$6e{ucLk888$4pw8gS(t@NYNQ$$QLD1x{`Vw>sB{@bt8Ropbq|SU>&F(ruc#ntM z*8h%=v@6PNTLO_F3C?t^s?}NesA!1z#2buqy*$m|1aPKqvasrQOfD~8m!h;FvY+<+ZV>WLkUj@M9*(iV2vQt;?Lq=sd8H+>1?qlJo_4Y#4 zs(Tq7<}+3k>Y6m&LNVS~8ooKhAC>QhFrw)OBkzxd2J+p4)*wdr=^ z?+e!iOWdG(cQT9MRfov7MobB>;wy#*_cniKj7HfdJmM+Kz1xN5YEC6q49W(6jCY}5 zskJmzR7Ir0qMM?QxHSm~%#6*t3bPk)J*S)sU{9jxWn+RNe{(nC+C^V~eH*|>Ilpg5 z7m@HtY}9@#FH+2DUXqvMOn%X(zSaLdIfx&|lTD`DI)$JHNu2OfU92C{N(r2fGwdPtNa6h^?9LW>8cfYd~e z=$yeRsor+F^$?Ut8yhuWSm~E1AhygvPiCpGtO8_JeT(6~8QZF2-{R~GQ#M;w=v#HWS7Q*X=L-|yq(}vQ# z-5G;E(lj!98j?QxFW=cksK}~sX`oRRI~^c>a>wd5q@LgM;ns0Kg>O z??QiJ7tDo_V`2Cb1KYvBA$4Vc8LZL${WUX82=qb&WR`6JT7#+#x{*a=K;Ql8Y=x(w z3XQ;wkn{v-wJ0mG00v4{npT;T*iY`8$NBmGeX7F z@kM73IQ@V0(=eR$8GZ{P1nUr*Fb{l;rhv=6f1-?(n{zLEa)3PMPxOD{si#zay^jcD z#g;L`AN>7u)2$fE=U|mF(RffD9MexO?86tu!|Pon^Xcldi+oi?H{ojhhH>hq@%ZpY zfw}am!lV2QB-{F|PGZr9<>OlI{gW?!tu9TqYf}Z(5LP`3nwurTLG`VCm4f#-{@sN! zX04|&9M-{&%OYUpMINl3rgpr$9@|{p7^fv}0{az2Zm#QF2`dd!vvbL0md1ooz4Pqu<8YHMn{nUDJ) z%hpEYg#*ZFL@rR1pYsqY*+bWF)uCT5OGQ*aP@C-c!7slg7TreOtkHb9^5Gd8opT67 zPZGrP9LDI_3_uc_u=Q8ZHL+9eIu25Vc|F)Z7VOdYKmHou>9SicQX0dND^GFjXHP1t z%deh0Tnd3il}HgDNXC|TQ5VQAKuiv(WNUW3x64cm%bhj&@D7B~QOjeQ3>Z~H;(|Sv z5~Cw(eB%maky0g#wb#;2tqpAH_nt=}vGmx4|11&+9qYvx_S1Wu%$*O9Au_jzh#k~! zD-V&a@3!Q?=Ar#InlUfO91O}ij+?maE&GGMR`pIA*+CKsB*~r;N@8Wm!UI`&#YDxb zfj&+^QuhNJ{_QYncDF?Hj4U%D97nOUR0carPVY&Eg3j|X634Dx42ANKxeE}z^Sl2V zR2O@Tut&SLf&ysNCI7EKJ8|_#Fe-p6In=9g2EAuK^6onPTt^TxTeJ zgsiN5eFzackFi2Kr81YRk9qo+ZUyJ)A^GhaHgHLP{RbJ0UGl-la7mO~PRNsFqJoHc zkG0vOFILdmkN`Hra~DFG{D=bovBEZfh=|}O*gp7%=s^CphSvVQF9*k%^|DCnS~kuu zT%8^3H4`L%Px^Uto&erQlONw?y`-@G{_%Tnb7v~{pZVqf@}EV4ul5?>h&0PcXeF=67&5QnVK;ffB7+bA*65j=GE{0hAX!V|LRGWeQwjk}5p zfrebt%1)LQE7v+IRMDA5W8D^!^rz96Zq@wa%>OM}oxAv(!qm9EsZQ$gVI+3JT+rZt z-M(~Z6#0vfV4LmXk68}-3cpp>>w|QiW9mzok(x3lx2~$VAXb3vU+n}CSeO62whNg> z5io>vg65YqP6(=n<+yJe(79KFaozbAiHw%udc^{EMUYyBN866=_D8pE^-ZQ#?XWp3 z35#sYvTTv?0eZ!OZJVI4P$_OeP_X#D4eh9VwEAAGg6v=dDb?F!Nl$*Ru`(GQ?Yx~1 zu5*#a@M=1Uz|4R|{r~zfK0EBsLt@EwgKUJnSq-S}o$+0#{nhmP`DamS(kn=KKz<1R zq3(45A>s2UyYO)hTRBLadcC$@dWu1uMJY3&KS#)}LF*3TTMGM7S@K287I1Sj{bMsg z;a$d1p`KZ(gvI~0v)~rc6(7Eez$XsjbW`?+pQ&f^gIKJmPTv9s(PPN#)_MD6=U&)% zze|+Lz0cpe{(}|zA_3@2Y+FKw?wKT!F)X-6arp^Un#(N~Kh#vp zsPj-(&JYG32Ht7k#4e~A&F%;mPUKfmZudviSBAij+JOyt+qel%IeRznF~+_b`2%`V zb?&}6zDPK_l|o>*OM2I!Ai_7}u$dHH$29U){hbtnF6VZs3?LWZV`Q zM9d$O zB0Xcm(a&M$#y2u^#4-PUot>#P#w2TGYL`X#TdR_jXFg5;+&_4!2f@;b`m0f_TYK}R z_hVy|St^9Bk~o>mu~Pxr<%`@v+w=$deeqFkJ#F|~zLfth#%gLb)02BOzs7!mw<`33 zoe@8MrdXv%A=@0M6?2d$yWwl>D|_iejVzP};A3?=b_WJQ0L`SWZ%;oI^ge)`zF?I; ztv*`^SxH;1$$&WJ03EHL349v^bpDEew}oA*^4<8&`GvJ6;t?LOA`h&#gR%j0&XE?N zqg~@Ww;`M|a8^popBani??mBr^Lg3s(m?AqhDcV=*(B~6@+Aucy^Cx%Mx}=r>3Tns zC_yY|Ix(Y|QWL2JHmlAK?-^u|>Il%On6^OLUu z>N`PHCzR_dZLxFZ%((H$gf4$^a>p3S+{-)Dq8w3g_68_$Cee`|^zU!~R=dg_D=ceXxducm-S^uw>M~LMBgcAYHP`sE9v8sVV2R58 z(eS74b20yP?yIJ3L_Txb`8$}aJa#gdRT%+Ut%YoPggtBZ|HpbF2CCycA9I=Ru{3rb-QeXE07N` zV(n?T*GxaJqkW0=(~lMshh)cS@YC-Ggf_xa?}wFnSF?DeoOH zy}p;9--SyYnt0E2_4-i~ir?b92A3$w z^IWv5HSWPk&L-y1Ps12y)j>xlwd#5Ue(m;}dqzaK$VR-C@(PcZ9FBHdDNpW$M3ixB zqC<78Afs4U$jz*X%bKg=A=fDJMXtft#&&lv`tyd~?{&3XEabXx3D_5g$RHkMB#5 zo;B@Hm{Z~!o8ox|u^Rl!=Y@?Ywg=~W^F+qLFH%AaDkB2V9SR|+?VjCU`>!cX(hVo` z3T~ZtwL6$9u(!4e$8A`#&_{#LA1NA$hz&(koHRr8<7A{eD;i!Ge~?Gw5s@lQYD8uM z+(*j4)8Zm@&{VmJJkPELbZt5_-9b{`SA6*L=+8bnUAQ?b<~k1%*rEHgQx_H%{ftVS zT|D0Y@~8wxuoEX8XBU;sl4xtDGB;x%ySq%bu^}xwM$Sc84PTL=C1Wcn=Ge-@>8p45 zo;^Ctl(4GAl?jqsv9->FRCX{5nd=)B=?ju!iik(%a5(`ymUw+kYY_R~_hqXB0vsqL z-#x+JL(0Cm=5VK>?8K8}9d7%Tu~nV7@YnU{SoWZ}zrzUlTb`D*Btvy&qE48a&{m$^ zw9Iv6R8}t$Jm9UWtueLMB2!EYSB=kRI~KK3KwFZFWKFuB5hH-*yd1${&1R*<=nhHo zk)czaMc88D9hCzEIMwq0I?_#DplMYHd~R?Eu^GYz>ec$#d?(|1JFObVv8)C+{*g;dKDT-xV}}G z54>F3Z(E8oRXEQJoBbE?Ho@ta;DCw4awfn-%}bU?D)4^I=iff*`&!ySK)>^!%zC$O z$jDUBoE6RZF&p>9q1*$F+yz5~19ke2mjR#xJyo9XWt9Bqpz8}KJIED`c`G~nyTD*R zyuJmuZ2cx;Zn7XW=0AXm^WdKej(OF~U_$$K>3( zD%a=<m9beSVp+(Cd~yn2a1QoZQMBmSBQjxI_CxN z;#rWqilTA3shZ7Qi>ObswGenTZv_aXwn~5X{i!hv%N5Ryo0P5B?W4BFCWbnr<_L`U z{?zBb!QT(&DB2e-dXgQ12O~8U$)ox@mSEt)o$r4SN%)b^bOn21t~}6H8;CD5SDxjN zKn=&0E^!x5Q(;qrm+6cEo$p46^J>vJO+=YFi+4S?Ds6v!%zaNqs$ zKIlw&-kDd~DfE!bbOq>JCj1?K6K{hmb;FlaT5QAZ^sh!{{qOPSkr+^#ZAS5~Y)s^y z?l`@#88t0ii-hAgfq+<8M1^ddW$zgW#u0*37H|CLA*`vbojV&`+(RR9T5={>mh+vv zcJyz)9`)FtTehsCl|4sqe1o4Qu3{8|F}<3^#T$`k5}-WwLR604vzA%%+@?r?9vjt#@1-l!#fw`rV&;C}-ee9H z;(dPAno@M-!ubqR&fn-?yI?au>~ zmFXd#+G^uP=-W7*61_At8030CwRz{H#RABreIFW7NU5dsKp69sHDVFRXVlU+^`B*2 zyX4*H6bd`>@e^k78^%jIgR#K4P^|EOPhZnLs(O&RYF$C&Bv*FXE0qGO0qxOAa@hXcUq|31tu0vYnt z*s1H8%rBN8K8yQeY^$7?Xg1%H5tWXmO_&Jo166%*^yVj-J8MM@jo@Ecv&t@E8H`(- z%wmIET?oy*i?E6r;|@Y7!Vb~kU{_7e1$T1Yr-DmTD1XI{q${Of6w&!=5>~e~(ixjK@`hLjcn^-uuC0RWaY?(X0TS z+<*JfJ^}Ee6tVS1i4=1=AKRURuYMMv>duM4=w2{>U?r@n*Wy@GFAqup=R^{Ice zCoQ8-$FW)oco!h}y!t!iG_;69D}!<;g<5eF%&~v*-CuU-1!M;4C)%CIh87vgX%4Wa zwZGtsTw2XB=vH6%e~r-DwAEs+RGEXGS!X{Re#Qke(scIJk(uxbT>bPXzOW}6yyLhD z+IhM5n{hplT6R~0vyH|!`$NyIcLEZ6=O;ij&;2U4@e|iKmkTJy5TBef&$xE!cL%(_ z7_YBc)*4*?d7BqZ1Y?hURE)H&NGd}#xxs)ZH&$YRGF8H%S<|a}3(Qz6=}+g^mQaxR z*>m;IEDG|UnWSGzx8OuOHFQMi$6YQWXI+M)G}VeS{v_>Qh-m@z)x;v?l~s(S!zGg0 zVPD&sUabIIvEfEsreCnT_d`=bFVU|58A}FR<)7E4LKFRAbktcV8!VUmTC?7x`*z5HNe2OIH^m=(qgp z+lc?M1H6wvnig4p1%0>%@P@W1RirO`EKXYgf}0Z>2PvWpHcN zoGW}Dhb9efkCkXk6*#(LoDu5)5{SIAWH1pj;=EO@LFjkt4#F`x4h@*f_B zwpGlIqg$mLuNY^+xv~G+AMKj!Lm1&PM1RRIkFybfM2@PkyaR!^U5(InpL8? z4j01GfHBxVTMp{T*%@prJphL#GoA|O?3LC4A=dK3%A zXSRzs#%2k8L++#J5v==Lb;E>gF>{ro^!%cbLC6oh1ACg+SKv<*$W=@qQ~`OUV=AKR zwzvyIDZwd1RfJ$!mBI(ykvlU-Wni0Ve{W@5l&$>Y0SQM1zI`3ViZZDfY15PoXtL>uDLUX(b+LGX zv304nfX$)IfX%q0r9%}UfK020#3lYMp4L~n{geR4wNW+=ZJVqmTbIxA+4ya~6emiI zyJavl+80R)juf>ISCCsj(0m4;pF64vkd$ApqHWzImPX(xej%(ub9G>^pg&A*{U-gU zMowMM5%;2|MRlb5k#Bx= z+Ve@>KKcVG!>)jBCx>?w_d2R2XK2XTl-QW06= zG7>4%jdawx`XtcJ8by+-9c}-rjxLVqdi+P2*Y+#!6nJwXsNJ6A!8cBZc1LGPJROg4 z60-T9c&~legTqJPt=dC(QYpx(t<`yU>?I8{e^n@^4CD7}#nCF4B=jd6Ka%-D!QYmj zx5}i0Xj|9LYx(ezXyi{+Y{VV%zWsF$=+$O!bWsl9<{x`i?b+kSbyis=T*g;`RZV3A zWCTkxoUsVuRK+=#ML`4ECtxsH;;=xJXQ$%Y<^{K_6DP(NBzn*XT)%QB>d_T2gFO)e zMc02va4w$+PMe+;mje-EoKQl-a_{V4j{okPeGyi@g+fxH06ol_Z-f z^ACka@tKrbCyct+G?qq4akmc~>@`k6tA7=hNFC&2(`)453YV0ikh4pwk@_H%^^kUu z`XPI?urD)0`9eS%n;N}xkJh<~qp4R0!+FbAF^Cc2r31q$x(*X1vaZrK1tV(~&rz5w4xUKmk! z0+A4t!W~x!SOKXsG|u2d2Zk8FR6^q&jyF{_KGRnTHd!Ln=&h>kpifmjyR%uPFw7lG zc46l{fR9*n?sUvO6n*-MIw}0Gf0XZb7TCybPjaKo%Y0NrqK>O5q6a>)fy9QQ!tOo2 zu@ik$@tb?YEz1|;tOX)uUUK2?osIQ)767v2LCOiD$)|uE(6C;+Nr%+vuHPJezZEs- zjaaCI6jf4-(35bz3_7sP+%4t76emam8%iuFG6Y~#OVTWmI0O-sklKx|U=x+&i-)^v zwbH{$t||lNp?_^@$aPeuI|M+A!DAQ$#k^NXQD}Tt+K5bGj$i-0i%juYerdH5BC4~N z$58eE9mADUeI;_8N}>e{`cToa$+;*nc-H#acD2)HM8Xs?s|6;~znb3yV0=ALIlgg{ zCJ%^&;|ID9?!AXwQpIzPWUU3}#7EA=)|BZxgv7c6lDWdgixx5n*jUceIp9rvI+0F1 zR^1SBWt;oG1 z79KmJ`tk5xDl@lIrpI0th<3EXLai*SzrtN^x7eu z_fo@0vmN~%cOyQ!dh8y8xxnRj3jex`)^aGQxp1YceQH^owh92q5l6wXN|@@VKS7cm zzfT+h?#5WW&?mB=!E`JYN!AZ>qUlLbVJ+sLSW@AFr{<}siRXZHGuEB?9G;BLbrM1Cs$h7b*$91p6J0BzHBTO8nShr)p z>chO%?)H-1C_s{Gm3q)A?L3V@sESw!YWkwd|8GarO_O&B<1Cf8v~`SIJap6gSCT{F zJA&QV-pE}Qi5cQ`{o@Zi0gGBtla;-p}3VfzL?0mN9-VDGZaz78asR57I#P1C%0PaJ%K9I z6iguEFn#HLQn6S@J?Y8Z6XkLxE;pBfS8Ro0mlo|wefNj3(_JMhrcjbW zcn8LF3NcXi{N_>Tq`ehwcD5V+TyHR1*}%rai0(;!=_#X{9x)vi(kp~9H3W6$DnIcH^TZEvvV&>DPA{FJ5 zTukvwS>(V^P`>2$4q8MkI7Hi(L@aX&o{({Y`PWa$j1?JmO}m!h#CTQA7h41VXu(@w zoFJC?%qJf?+aL`h1H5P;2P!ls=@~(iG0aqVoG@(#6b-huTh|cIYOd~pbAK;}VEp2% zA*?>wX)hyD-rU~~Za3$Wl_qV%Oi_}3)R-u@uQq@f&vtESj>hpK8p0-AV8xyX*KWM5 zMQTOiz@=JyiUn*IepPl!)4%L)IWj9uz_3C2-#DS2v{RkC{g62XI5_J9n7GmQI(o zf$jLrSrQ%I*_E#904cmqnbXAA1PNQf*EAJ+up};^U9m-RM4n$bHMx(&MG9ELwpD}F zt!NMQI6moqZ1?<9P)m}Mz zcI{>#OmS67W-X1AL0#O-ew10O^`*q($DX`6~g;PC*=N~pVll^{G0 z3Yw&GsHpHyo*5f050N>hTN_#+^HQ;@iqRF2_$Eq9>cxh-)6kAC)u*REBag!tAIHfH z?8T}Id!^I@+P74{&=fQI{^r*WvA+5QBP$C@hTOzU&>tUPDz1Fk9KUkWSsYBYZiNBc zW85J!mi99m4vKu2N8)s$qg6UEiBD!ja<1 z=q?48imt*?)JV3A8os+}3+NH*R6{amK28>@Q(2Sh^tJO=(W9@5c9eItxy$%r*uUNB z-1PcJSmm%R!*Kj=F6_McEKpr)O2M2w8EhX;XB%_mSJbQ7G~`2|cE9PW;7gIdQR^SZ zYM-dF9aTL(k|^(pq@>F~*9qyPJF-r_Zz8=XX=*Kef!u>YdL z^RblhGV{L`xw4!X-dDp*G_T_%=K!88h{a)c(Yt23-rEygv-agfbDyjyQbM`D2I*8e z7LX(EQk)=MTm6=I9@w7zHnW@^wWx8x7J5xLLh&5!lbYfs()p(5MT!z?3I^R_x1tWY zn0)u%9{u>=o2ds}oByt;{4Uow%{c?9P95*ZV9JpGTbIYM%v#)&d|{m2Y>kT#$%>Rz zMTv~v&>~83;zHp^&9F}B`_f?8+Iq#irsl<|jjMQn6>(|3DVFm-we~yVaB7|WG7#*tB`Uz1Tc9Imw&#oYH{d|4t6oG`m2DVn?`%>RwpVU( zAarOfj9_Dgnj?f2wMrq~EKXN8^V@gN@9$~$OxMot)953j2O>m?7NH~VIXOfM@h7b7 zYWf(oMf;;Q+kwt_5~k6^%DW$46sf=J)1-q$ zE(bJ5#WaDy`+Ey_gCw~B^sJt(8*6i2L7y7RRotVaT7N4VSwNHvLY$Rm4i8D`!&2!G zv}Hg4qv%h!j*;7eOOOvw)=g0XV{f%gSAI-~D!ZF8$ZtP)P=fAcyOl-jxLmS^59$dq z?M4nYapE8AI5Lg|i+hlOZz?60B?>E&w&)9(4Vi&jQ6 z#8vCsqmJizbRVpkn#Bo%EV2`OoB5rH(zDg!w%zE2O$!LcfQG@NSsXHn_mCvC@mW9p zTx`f^I43xHdE8@mdpujSiP_HrmXdgpVf=P!;MFRL6c-w`h^B+SD@;+*Kc6gqOrGq# zv(`tVcvey2!F5t8gK9$)I}l~?56>UQ{GI|crTV_A6xzcE09VTq2agr$dh<*CRMbJL`hMpA$lV&11lMm8;>*k3osl?K z^{-nSgR#2qcXpgXFs|%n|0eO$LP?OgqR2(xDMc6eN3{Psak0ClU-k2kd0$b*|_M!BG z`SY^RNYch3PJci=2 z>1e+xtVXik}2Tt&z=k>K+28Ly-wIT|Je(}^_J@@N}1iADap?ZJNyN3 zt3Q-d%WgR!m0C6`0PV!pv(T`H@(K221R=Jidka&+qVH+X~I+#Y`M&<2+5o3Otm-^%JWN)XN8QiD1QSrNhEy} ze_AXT#!Tg&-PG!pF+<`DCz}j-eO==yWmlG3!BejnsgS3=+2hGQgb4b4t&c(fU3a}_ zva+n&wlX$b)%yL^6B8eji zvVvHxGTNnav4k!sHSEj;R6^3;nkoif*JEj<(3h0Dgbm#>G<{SLsiYft1sa5XR$~e8 zum%VGP>0$xLPdbvBd>pO9dS9a!}~zuL?S?MLKb6`?a(pLZey)--vHjio23bCO&SqR zuF2Ytyd{t1zSNa&-Bj3IM27kaK~9F}%Rhek&{)W|hTODz3H(zBU@x{af<3nLcQ%$=dCK}Y$! zf2IE8Wm&=s#J~N!_Qb!iyCd75*fMQ9Zq{|rwZlh$@dHu+w04Dm9fOP(1~GGFo5ry) zdz107^*#|iXDaJ@7H-S_P(9pd&e0DmVHSHJqRxC*<}jOihu@Vp#K}U9z(Pgjgz}BG z@0$IaEmvN{-pYr_ixUg^r=FVsb^qcIOvwaCIp|1Rf_z{*F7kJj@de0bQN0heK}TVQ zKDFUBfp}~W??J)|PRdVt(WYz&n7+rv`A3an4oiln@G}5!zNx{|;0@g1-sV%jXEgr?Lpi9%XpQk$&YHz>nX+^*1Iw?BVM!k$bEvTq zra+wy_BjR^8(_N(*)+_-Fin{%7tv!9T-)FR&3z7X$^T1UCe?1w%r<&_fs? ztQLBNhlGQ|U(}zJJC#g{DJ|7T?WHbI4=5hK$|N*k0&<}dcA)_bxNrx=pav&|paA#a z6?{_wIXH-Mn1cCOg)_K}TUbOK1vD{29!hZ@4QNLXhA@FWxMXRKUz>OYzOzTBZ%;an9BezKsO;{6n;c&6% z0M^Y_Ri33^EH-X~5V2&}hWc3BB6p~LZEqBh<3VeeZYxL5pVSX}drtgLP`C@CQ3+Kq}u zZ&TyG{-t$1-$G@_$1k8K4-37@u=#3J8h<{X-YXK3{Z(49p`>D!qI6F7G^ZFwP|D`#u6i?$vY1YWp}VQI=bVwaZ_n#?9e}_ zT87v@3}ujzOkXw0NS>^8seW@aC(Sz3m-6YYJX3RL0Z2t)=G%Fy2)%WnbC7*Us&oRq z1w<_e_;MBO%wWj$KHGFmcTe(Rszpv%^!ONqs%6>%%JoJqzAbf1I@icFNr{uR0+X^# zUnQQr2q=hqNRelJ!DBf6iA1a`G)CaGON*s~gNw1a!kKj36^MYWZ2CD7rY_#scLx`n zx0-KqZcs|E-V>oK?rW*x#}+=+gl2M9({uVi;WVW>%W<42&*INh$gCt{6;auD4DeqR z$?)kPFC0LoSmAKYnL>pMrV^22f5LxYL)duV>5$6N5~WI_E}tTexlEBNI)lUwYCdV& z-XqopP;?{4r>d@|(IPK>sh-BtxlCcBxB={T!;k7u&o5P$(>qB|F6?UT4KvwB;?iH- zN9N_&qnz1X_efg*=vk?-gGsY}`0PowwNtZr7%?@!&Qhy=8 z_dO49*LGygI@TkDXz4PyBdsZDVpHafCt1b^x$?O88qW`elH8A&JPD_kQ*pS8esVRD z~k6=sc=U22-WYi+>*4Dd=)$>5(Jxo7Kb{X6I) zn-f{P&ar_h%OY!*@L*l31sXg3RoYQP$P0}%65@Y`B(r)?4K+8B%{6Hl08tAS1yWB^a0*nbf4=bk25{$-`Z#gMXW$wP=TfWsZ3n?y)TSv~@Nl`;L&2)ylLnYhcCiamwizJMc#GRZG}kc?aDToS^lUxs zWQVC?DMDGpZq}Gm%9VU%d8{5)|K6uSSyil zg1!6pCRSX=6Ykx82Tn_&O`0jh<&!%az(6kg>m}&BZ7j^H8uGkpQU)u(U0zWvsiu!ZA zMoxVuxahI#wkCbLr&F2K0h@DV2NL8F8eFna-c{Q3j3UIMDgqkr_1H_V*zPeZS~fn9 zHUib0CjfU&zI&|q3))KHgL6SMDltlZsi5c}h-JbtkWb;^^F>6BBXjkW`qQd;P2r%F z3&CgBzUu})e41_c7KE+!RA;9C_}{+6zjCgUG&A>){rJ^KFcFlD_gHmvBmL?ZBC{^A zcRRF#O6{$%Sq2DPiIyTFc*5MCRtN0tyx42+2`F?*IpW?N#2PS|Nfyz>ntYnc0_;E3g>w=^ zi?~pDO#ZWj>FG%fsMUzO`5$FT;dz;xAjawi%67tFmj{Bd=^=9&*E5+#te< zbWejln`OC*h9|9kaRh37(i5RMU@##nwH8WJK_X2zb+y||7~`$w4PSb;yi_Tt%kr65 zw0^~ZkT)NE&u-&7m>s{n?uRqVSFfW5FS42HlH!FLG3oNH@Q7%Im5Iv1{*VE@E1kc* z2t59CUrOh0ArV4V&}MRJzo{Stn5={-hOX|7xGaDmShwQ-&yusNES*r$9GJ#q+(oD!wS{YERQjGBh^dX^NvZpj%AtG=<|X{& zPcobmzB1xu$#vBs~&Bo8v$3bJ3d(AeeHNm%4hz z;efsN_M!*p`&;qOqQ+m5E=f%OmC5Y)gZ#Y1uek)K^qK2FKBu%)sD4oPLtue{(wbj(Z+^#pdmPYYbJb zz-uv$W=B(zgj^>+OEf&7U;HaU<5$lXvrRqn8%8CDGb7#gd%qGiP`64;mF;isiG6b0 zcRhg31{Sf-hLkaXP2=v#FHD2KaH)3Ai{Se6f1w8|s!FmL|!V@p9;?wyu3cw$P#f4{&w*X`2(-ltUa;g7p zCt_Ds*}CwcA1^m&1L0qku@mCt87^v;haor%+R}Jb52xIp-T`$N1hwyW0A^ORInH;A zaF9x7p{w%(xOZ|@tpZ#fV}Dw0VkmGb=SgN<uLyq?iDf_uW6HHDkO{hhRYGZPWym zHv4eR-jN4pP~#6sAGT-((JYs$Xr>ALww;Uol~qv2a^l$>p7J#4$pnqfr$^bNw|M3j zk4Dt4rV4!dGkURj^xS&4%^rsEbys=zr7+DLBII{3N_G!P%?{(K84iUr$=(tv%#LN` z9ZC(0t#Y6B6_UCt00XaF5}@&`Z$;hXf*v!{*v}MqkiW3wqo9 z2Rga*9|z~0lPB3|44VF*Be;{br~g3Vg_xLytQ!l~%Qh~04(Ycu2E}0)o7R)6#*O^! zj9$PCt(h~Lc}e~SPa?ec6Hfj+FBK=tKWygzZ67=v))cgasrr0Q7S`^}YE5)feaJKY zVk>~#$!foXuo3G4WHn3p+w?`ir+>LXaF+I`ETaA)$IlR@=(VsR08fCB(yW3>I?{UY~^0xap#jTuFtb*a~_SH>)W_+EfX z!=kQ}1lc-$8Z=3l7vA}dXvJ$J)3}J4HY;Y|JYL`h{<6ql)+~Qkv(;~H+~72iP4Q;M z=GK;oE#+IzZyDLDzqNJi{cW1tLbkPTCm3eroV0V*&a0#C zE`h6O_+qbjK6Jw)vSUSnxSw8`nZ?72ylLXl6w&Nz>^xu*LUUTiTa|0wpiRbBRUR$q%CKF!3x9!(Ba}_*K2R_vueuO~ zG+aZzXXleNA_YxfbK&&9&un!OFcSp=NOhNkuYdT7c(Us6tpB-(QRFn zLyAaA#aO4ORiQH~i&O}b;s7uMC$OSDfgmGHwZ>t1rvWw`%hI*h#sC-G&XP(f1+0cv z2sZ)-VVyX~>B0mNj1Y}M86IUVVl3xCD^wwd2!0pSfGE7?He`y)5-tK7nM)Dsjlg7} zskT{~1+9Jvmo}|ww&ol#B6l#;5eB(HQ-#7&n`5HzknHhwq}N%!73D_aWeKydiE4t8@*Cw$XNnJ@-($Zx9n>1|7 zH*?l}Pv0UF%CyXE)knFOqI6|7c8F)XzPjye*H11x4^#`=u)W(Pyr;!yAqnWh<|We6 zKI!OtoTw53x^N6Tz)k1%-M6@2wfad0HA8N!iLN}Xq@Mj8RkQhr9k3&Pr6{L3uOwMX zaWbYXcDo3oNzkDfOYLsKO3m**74|%<;ue69D7Hw5iNN1pSO}gv3g5e%Rj{6xu%Q5S zpG33k5>+H*ByIo38Qvt@lx~)4K^76i5ZazFIo$>Pm6Y1A0BX;%*W6|D=Fi67KU{J- zj6|7{fH6k~i~U|V99w~WvW!hoi6aO|iGV5GAd92dow%w&NE$@Lc#ngS6J0WcUnb%K zRXC2D1~$V_*K=DR(7;FoNJvG)F^1~^&b8;L~abPHGC)EbJ1~`LU%?2k=26Yjj@|SW6k~GVE{JKb zdz(z?F|i|{n~)sIs0&g>_BpFWb}~2jagX=2i)uv5mu;D7yme-Il1MYAQjpMWqP)`& z1N-l1lnDhH=CNAB&dRNjS0X<=xt>7OV@aV%myKC6E%PGL!(UIlZGya3EVKJm>Ib;6 z>SZL6k3UjsCDOV(JkD#{0e-moGpSO_5x3Cv(VE@YRmkw`(zbH>Tyop*U|Dx2& z(vPM0cYdDOH|vm6o=a#RfVm@-O@?5$2slFE6j3AeZ_#|6_D(O3MGVAHa;HGi(n-kD z9+S+Yuyt=)+_K-b#UUdDSsbndC1M~qz#f^Fu6sWrp48yshzyqt3czWKbl>==DNTrS%8Jpf$rUNyBu!q>(K5|xXToQtu zLX^_niUg&f3rlQ8r@K9Km8*%7y@XU!5JdYcASOyda-td?$vOi* zqz$l@4NudCv_>jrK&&m{8G9C0O319(2w#MLlGqXJODs=_2#cIa1r3f%_=n;#HsPfu2KX{JNY^n z)Yj0Y@ikFi*LI3bqkvQhxm@!?$5OFW)l_S#_EX7B>s#WWilyqv60}b!l{CyYC`?~# zRZ$E$<)2>Dj~;=9jAcV?=rJg&WjrLme*tlyPl}MdNQgtyAVhB%#G7riXt~vN5bt&q zF{)*um?>lOjI?@?B?@Y5zb6}+Q{7Tm6Z2n>ceVp^uFG;B%L`5SqGal6n|eDZ{hgF6 zVbQ%>8&Xfs82;Y_PD?Sj=V%`xkPm#jp%OVrkDoh64%fO#`h&(#rHiwB)q`1EgLT9q40dtiUy#^ zlK=)I@3}|-%~bpXK%s3=02J&9`U*e@WbXY}TJQotFHFh*kwDu~rvw1+=1BnLc7on$KVCs~Ef%uDwn9n)+gT0;~Y?RSr;LsqTL&AUw3pO0M2L)|n6rvX$SdFLA za$3lcqm2R`bkUpf1{h+55@Sp-1!TUwuq?5{8XIg;VTU~qIO2peF1X@`JLB-c6EEI; z`10c~K%k(ZKDRL8B1DQ3Ek>+3xDx=1WXT4|4*=^F%5Mzr%L7nlIe@7E0CLO( zXaL9&fC8lluvMq|GXL93!X&f%1z>@4Z7)^Ekx%(79iNCsIs)KyDuDdYpZqms#eK`q z{8pyULiK7iYBI%a&}s>Q7Avi?!pHa|$dvrzp8&H8PGEfDb%UpSBsAmza9C)o9ro(X zX@B}G%vd1N&?3LMU34@ewm6#5ymTUY5i4ZLQ({Du{m~lz*c7qHnhnQs1{d*3d6mSO zFw^<#&#{m!01oTu8$0NOrIynFUuY(t|5nk^kjCV=5^F&QD7083H^~iYus2$+ADI+8 z9854~t-|__BoJACEJK{TjdktJPVeN^Cvgz~z~74&p5OZH&9RlkIrQuY!gm*R`swF_ ztb792Id$AAUXqmYC&>ViE!Q-~07?KX1W;>Tir53j8pk-tHGT<5P{IIm2_RR@&4`xS zOyS^j=rpVxwv_F`S=9{ zh0>5N5m7O52}vnw8Cf}b1w|#KvWjX?oCcPySXI~1{D1CiY3o?m{SuU)^3>*DLw3Fp zWg{=`*>~X3k-P4>?|}+v1w{VQLgN3#!D)AHJ%gecAbqYV)BdGF={)zJfXy2KaR1(v zJ^vIS*M_~_r1fPlTo2uk|03k8HTMh;gIJ9=zz$i@ zUX~5;jR{$8#54v!9LT1#5&@-ai4^kdd%q3}a)+7p8N2I<{Q4`d3EeuQRXe5JT9kii_!Bo5 zcm}k5)e3*$`jM0eNQ2tc-;U8C?B+1{CNh~3`+-LKn05fU4sKMr5D>=#K@(}DBJ%dN zYTbz&$JZ_*KjTd>A#3owL}xhAeE8U)Oqg(K)?Wj@r)jnvt0TA-680PJI^zn(aXYR% zh$X<#Pd%Tr__o@Vi>&JKtHA0idiRl&J8QNWH6w-t2+#Yq@l`B@^KJ?7e1ye2gPa?- zLv&=h+$TRE8V(5fj-AKA1$G;|XkHVi5tM?*y$`kEz;_>Z#gwH~oh=T}`vYpe`8Y>A zVo39`T1Qw38jlgW3iqI!vA^rRh37-$KlDSmUtN~*M{^WAd6_JedwTY99@AimOs!}w z)#q-7V(Mmc_W>jQF2&eWI54t^)^t=FK7RT-GqPo*(p9 z&=DqYA~d@HXup|5TCS6iQjIKzxIwMa10zXB6Wd9La0fh-dfO$!d~_5N&-YBLdP*}s z+3p{cTG2Qf?Q1iu1#U$QSJb>_^yQPdAGc=tu?$Sv_l}Wz^+;>NhYcOcR9h~Ys7-Cj zRm0|{;nQ;SL`iKQ9R!+Ybk&24^s}TFe?!%?)rWGnD1*^5?Q0YGotC}EHyj@7;OgS- zzAncX8*(Ec@Yb8xZ;bM~?atshfQ_FhNMvl- zVN&0s*AbQvV$e}ksmQJ%-50{&B+9L{ABa5WY>NT<3?VYscB|zSu0IJpL`Qj%?cFmm zno{&qe-*^jpG@3Jy04fmKn^e)AodfqKj^scXdc1#EPA^!ZNql~p=W&37f9QQtHX{e zbLFTiN%O$^fST^xV{V7~hVP$dk5PZe0Xe5J8KI5QKwrmXi+azu2oKv69bUgKnn+nUH#`zQioHZ z9boJjY%i@N7GtJ~3I}1f_#PzoAMRjal55#9W9oG(`cfaR9wQ~XuUbv-kh=+;pKd%r z@}O5Fm&gFb6*M^7Q+ddAB)T7Y_vn0ml<8r(1DMl-=|`FIa@CKwu3obWfyi7i>O*)e zhtAOI+fJ}HWa)Y|b%?stln)M^`VjHBVI-G$1lRA@JEjGg2++!s)^vsBe_-Un&FaruxQ{oxc7$v5aIca8--4w8$(Hi8;79S zO@qf=L~OwZaMQ7;#Z4mS0%SDYbu;ny!OcQTE68pLa&uT-CgO$$R>MG63;?J+0k{#^ zEp?-C+vvs!yLN={H;lSzD2C=HV2^>DPX1%C*gNenS2a5^O(J)&I0P4`3tO`k~gn*TUX0@+E?|}U+e#)_q+Iapx?{C z-UGdVIcOhfm%fzY-`Q+*sG1^p8Pma>&&o**%G63Uq7ocLVR*n&Nf^K~o#Y8A>=66DR`z^l;>_GBd#BA>xq$!GDt}Ea?Q!3ph;B1`;wvbG@VgP68vQ z0$dXI^+9BPu$5s_e)N^Sz!Ucrmd`&-egW+SAH)=zF+nYf&iqEU;Jr>2tiyJ2NXll9 zgfi(J`RXlCxpf>~QfC46EhUyYLk#An1S^MDz%})D$W=VMDw(m#tNQA%>;85RK*}CS z`+=Rg2c`}r+JR(##GA?l#bx++wqbdktfo8?lO0TVV9NllXq@rtBL$7VIK110Kl7y_X;-bvftrKi}(mlw^X zvz|PNM#q$!2)@v)NYkx4Z-N|o5?Y#a+_t&i_ZbB|_|}OpFQZ5^^2g`Oqm36C006G- BBWC~r literal 0 HcmV?d00001 diff --git a/shadow-cljs.edn b/shadow-cljs.edn index 32fea3cc0..006f6078a 100644 --- a/shadow-cljs.edn +++ b/shadow-cljs.edn @@ -12,6 +12,9 @@ :depends-on #{:main}} :age-encryption {:entries [frontend.extensions.age-encryption] + :depends-on #{:main}} + :excalidraw + {:entries [frontend.extensions.excalidraw] :depends-on #{:main}}} :output-dir "./static/js" diff --git a/src/main/frontend/commands.cljs b/src/main/frontend/commands.cljs index f4a659a77..5ab2989f6 100644 --- a/src/main/frontend/commands.cljs +++ b/src/main/frontend/commands.cljs @@ -8,7 +8,9 @@ [goog.dom :as gdom] [goog.object :as gobj] [frontend.format :as format] - [frontend.handler.common :as common-handler])) + [frontend.handler.common :as common-handler] + [frontend.handler.draw :as draw] + [promesa.core :as p])) ;; TODO: move to frontend.handler.editor.commands @@ -102,10 +104,13 @@ ["Scheduled" [[:editor/clear-current-slash] [:editor/show-date-picker]]] ["Query" [[:editor/input "{{query }}" {:backward-pos 2}]]] - ["Draw" [[:editor/input "/draw "] - [:editor/show-input [{:command :draw - :id :title - :placeholder "Draw title"}]]]] + ["Draw" (fn [] + (let [file (draw/file-name) + path (str config/default-draw-directory "/" file) + text (util/format "[[%s]]" path)] + (p/let [_ (draw/create-draw-with-default-content path)] + (println "draw file created, " path)) + text))] ["WAITING" (->marker "WAITING")] ["CANCELED" (->marker "CANCELED")] ["Tomorrow" #(get-page-ref-text (date/tomorrow))] diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index 30043e761..8eaeeb0e8 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -16,7 +16,6 @@ [goog.dom :as gdom] [frontend.handler.expand :as expand] [frontend.components.svg :as svg] - [frontend.components.draw :as draw] [frontend.components.datetime :as datetime-comp] [frontend.ui :as ui] [frontend.handler.editor :as editor-handler] @@ -48,7 +47,8 @@ [frontend.commands :as commands] [lambdaisland.glogi :as log] [frontend.context.i18n :as i18n] - [frontend.template :as template])) + [frontend.template :as template] + [shadow.loader :as loader])) ;; TODO: remove rum/with-context because it'll make reactive queries not working @@ -385,32 +385,41 @@ full-path (.. util/node-path (join repo-path (config/get-local-asset-absolute-path path)))] [:a.asset-ref {:target "_blank" :href full-path} (or title path)])) +(defonce excalidraw-loaded? (atom false)) +(rum/defc excalidraw < rum/reactive + {:init (fn [state] + (p/let [_ (loader/load :excalidraw)] + (reset! excalidraw-loaded? true)) + state)} + [file] + (let [loaded? (rum/react excalidraw-loaded?) + draw-component (if loaded? + (resolve 'frontend.extensions.excalidraw/draw))] + (when draw-component + (draw-component {:file file})))) + (rum/defc page-reference < rum/reactive [html-export? s config label] (let [show-brackets? (state/show-brackets?) nested-link? (:nested-link? config) - contents-page? (= "contents" (string/lower-case (str (:id config))))] - [:span.page-reference - (when (and (or show-brackets? nested-link?) - (not html-export?) - (not contents-page?)) - [:span.text-gray-500.bracket "[["]) - (if (string/ends-with? s ".excalidraw") - [:a.page-ref - {:on-click (fn [e] - (util/stop e) - (set! (.-href js/window.location) - (rfe/href :draw nil {:file (string/replace s (str config/default-draw-directory "/") "")})))} - [:span - (svg/excalidraw-logo) - (string/capitalize (draw/get-file-title s))]] + contents-page? (= "contents" (string/lower-case (str (:id config)))) + draw? (string/ends-with? s ".excalidraw")] + (if (string/ends-with? s ".excalidraw") + [:div.draw {:on-click (fn [e] + (.stopPropagation e))} + (excalidraw s)] + [:span.page-reference + (when (and (or show-brackets? nested-link?) + (not html-export?) + (not contents-page?)) + [:span.text-gray-500.bracket "[["]) (page-cp (assoc config :label (mldoc/plain->text label) - :contents-page? contents-page?) {:page/name s})) - (when (and (or show-brackets? nested-link?) - (not html-export?) - (not contents-page?)) - [:span.text-gray-500.bracket "]]"])])) + :contents-page? contents-page?) {:page/name s}) + (when (and (or show-brackets? nested-link?) + (not html-export?) + (not contents-page?)) + [:span.text-gray-500.bracket "]]"])]))) (defn- latex-environment-content [name option content] diff --git a/src/main/frontend/components/draw.cljs b/src/main/frontend/components/draw.cljs deleted file mode 100644 index 1ff7e2d4c..000000000 --- a/src/main/frontend/components/draw.cljs +++ /dev/null @@ -1,497 +0,0 @@ -(ns frontend.components.draw - (:require [rum.core :as rum] - [goog.object :as gobj] - [frontend.rum :as r] - [frontend.util :as util :refer-macros [profile]] - [frontend.mixins :as mixins] - [frontend.storage :as storage] - [frontend.components.svg :as svg] - [cljs-bean.core :as bean] - [dommy.core :as d] - [clojure.string :as string] - [frontend.handler.notification :as notification] - [frontend.handler.draw :as draw :refer - [*files - *current-file - *current-title - *file-loading? - *elements - *unsaved? - *search-files - *saving-title - *excalidraw]] - [frontend.handler.file :as file] - [frontend.ui :as ui] - [frontend.loader :as loader] - [frontend.config :as config] - [frontend.state :as state] - [frontend.search :as search] - [frontend.components.repo :as repo] - [promesa.core :as p] - [reitit.frontend.easy :as rfe])) - -(defn loaded? [] - js/window.Excalidraw) - -(defonce *loaded? (atom false)) - -(defonce draw-state :draw-state) - -(defn get-draw-state [] - (storage/get draw-state)) -(defn set-draw-state! [value] - (storage/set draw-state value)) -(defn get-k - ([k] - (get-k k (state/get-current-repo))) - ([repo k] - (when repo - (get-in (get-draw-state) [repo k])))) - -(defn set-k - [k v] - (when-let [repo (state/get-current-repo)] - (let [state (get-draw-state)] - (let [new-state (assoc-in state [repo k] v)] - (set-draw-state! new-state))))) - -(defn get-last-file - ([] - (get-k :last-file)) - ([repo] - (get-k repo :last-file))) - -(defn get-last-title - ([] - (get-k :last-title)) - ([repo] - (get-k repo :last-title))) - -(defn set-last-file! - [value] - (set-k :last-file value)) -(defn set-last-title! - [value] - (set-k :last-title value)) - -(defn get-last-elements - [] - (storage/get-json (str (state/get-current-repo) "-" "last-elements"))) -(defn get-last-app-state - [] - (storage/get-json (str (state/get-current-repo) "-" "last-app-state"))) - -(defn set-last-elements! - [value] - (storage/set-json (str (state/get-current-repo) "-" "last-elements") value)) -(defn set-last-app-state! - [value] - (storage/set-json (str (state/get-current-repo) "-" "last-app-state") value)) - -(defn set-excalidraw-component! - [] - (reset! *excalidraw (r/adapt-class - (gobj/get js/window.Excalidraw "default")))) - -(defn serialize-as-json - [elements app-state] - (when (loaded?) - (when-let [f (gobj/get js/window.Excalidraw "serializeAsJSON")] - (f elements app-state)))) - -;; api restore - -(defn from-json - [text] - (when-not (string/blank? text) - (try - (when-let [data (js/JSON.parse text)] - (if (not= "excalidraw" (gobj/get data "type")) - (notification/show! - (util/format "Could not load this invalid excalidraw file") - :error) - {:elements (gobj/get data "elements") - :app-state (gobj/get data "appState")})) - (catch js/Error e - (prn "from json error:") - (js/console.dir e) - (notification/show! - (util/format "Could not load this invalid excalidraw file") - :error))))) - -(defn get-file-title - [file] - (when file - (let [s (subs file 20) - title (string/replace s ".excalidraw" "")] - (string/replace title "-" " ")))) - -(defn save-excalidraw! - [state _event file ok-handler] - (let [title @*current-title] - (cond - (string/blank? title) - (do - (reset! *saving-title nil) - (notification/show! - "Please specify a title first!" - :error) - ;; TODO: focus the title input -) - - (= title @*saving-title) - nil - - :else - (when-let [elements (get-last-elements)] - (reset! *saving-title title) - (let [app-state (get-last-app-state) - [option] (:rum/args state) - file (util/trim-safe - (or - file - @*current-file - (:file option) - (draw/title->file-name title))) - data (serialize-as-json elements app-state)] - (when file - (draw/save-excalidraw! file data - (fn [file] - (reset! *files - (distinct (conj @*files file))) - (reset! *current-file file) - (reset! *unsaved? false) - (set-last-file! file) - (when ok-handler (ok-handler file)) - (reset! *saving-title nil))))))))) - -(defn- clear-canvas! - [] - (when-let [canvas (d/by-id "canvas")] - (let [context (.getContext canvas "2d")] - (.clearRect context 0 0 (gobj/get canvas "width") (gobj/get canvas "height")) - (set! (.-fillStyle context) "#FFF") - (.fillRect context 0 0 (gobj/get canvas "width") (gobj/get canvas "height"))))) - -(defn- new-file! - [] - ;; TODO: save current firstly - (clear-canvas!) - (reset! *current-title "") - (reset! *current-file nil) - (reset! *elements nil) - (set-last-elements! nil) - (set-last-title! nil) - (set-last-file! nil) - (set-last-app-state! nil)) - -(defn- rename-file! - [file new-title] - (when-not (string/blank? new-title) - (let [new-file (draw/title->file-name new-title)] - (when-not (= (string/trim file) (string/trim new-file)) - (save-excalidraw! - {} {} new-file - (fn [] - (set-last-file! new-file) - (util/p-handle - (file/remove-file! - (state/get-current-repo) - (str config/default-draw-directory "/" file)) - (fn [_] - (reset! *files (->> (conj @*files new-file) - (remove #(= file %)) - distinct - (vec))) - (reset! *current-file new-file) - (notification/show! - "File was renamed successfully!" - :success)) - (fn [error] - (println "Rename file failed, reason: ") - (js/console.dir error))))))))) - -(rum/defc draw-title < rum/reactive - (mixins/event-mixin - (fn [state] - (let [old-title @*current-title] - (mixins/hide-when-esc-or-outside - state - :on-hide (fn [state e event] - (let [title (and @*current-title (string/trim @*current-title)) - file @*current-file] - (when (or - (string/blank? old-title) - (not= (string/trim old-title) title)) - (cond - (and file (not (string/blank? title))) - (rename-file! file title) - - (and (not file) - (not (string/blank? title)) - (seq @*elements)) ; new file - (save-excalidraw! {} {} nil nil) - - :else - nil)))))) - state)) - [] - (let [current-title (rum/react *current-title)] - [:input#draw-title.font-medium.w-48.px-2.py-1.ml-2 - {:on-click (fn [e] - (util/stop e)) - :placeholder "Untitled" - :auto-complete "off" - :default-value (or (and current-title (string/capitalize current-title)) "") - :on-change (fn [e] - (when-let [value (util/evalue e)] - (set-last-title! value) - (reset! *current-title value)))}])) - -(rum/defc files-search < rum/reactive - [state] - [:div#search-wrapper.relative.w-full.text-gray-400.focus-within:text-gray-600 - [:div.absolute.inset-y-0.flex.items-center.pointer-events-none.left-3 - [:svg.h-4.w-4 - {:view-box "0 0 20 20", :fill "currentColor"} - [:path - {:d - "M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z", - :clip-rule "evenodd", - :fill-rule "evenodd"}]]] - [:input.block.w-full.pl-2.sm:text-sm.sm:leading-3.mb-2.mt-2.border-none.outline-none.focus:outline-none - {:style {:padding-left "2rem" - :border-radius 0} - :placeholder "Search" - :auto-complete "off" - :on-change (fn [e] - (let [value (util/evalue e) - files @*files] - (reset! *search-files - (if (string/blank? value) - files - (search/fuzzy-search files value :limit 10)))))}]]) - -(rum/defcs save-button < rum/reactive - [state] - (let [unsaved? (rum/react *unsaved?)] - [:a.ml-2 {:title (if unsaved? "Save changes" "Save") - :on-click (fn [e] - (save-excalidraw! state e nil nil))} - [:div.ToolIcon__icon {:class (if unsaved? "bg-orange-400" "bg-gray-200") - :style {:width "2rem" - :height "2rem"}} - svg/save]])) - -(rum/defcs files < rum/reactive - [state] - (let [all-files (rum/react *files) - search-files (rum/react *search-files) - files (if (seq search-files) search-files all-files) - current-file (rum/react *current-file) - unsaved? (rum/react *unsaved?)] - [:div.flex-row.flex.items-center - [:a.ml-2 {:title "New file" - :on-click new-file!} - [:div.ToolIcon__icon.bg-gray-200 {:style {:width "2rem" - :height "2rem"}} - svg/plus]] - - (ui/dropdown-with-links - (fn [{:keys [toggle-fn]}] - [:div.ToolIcon__icon.ml-2.cursor.bg-gray-200 {:title "List files" - :on-click toggle-fn - :style {:width "2rem" - :height "2rem"}} - svg/folder]) - (mapv - (fn [file] - {:title (get-file-title file) - :options {:title file - :on-click - (fn [e] - (util/stop e) - (set-last-file! file) - (reset! *current-file file) - (reset! *current-title (get-file-title file)) - (reset! *search-files []))}}) - files) - {:modal-class (util/hiccup->class - "origin-top-right.absolute.left-0.mt-2.rounded-md.shadow-lg.whitespace-no-wrap.bg-white.w-48.dropdown-overflow-auto") - :links-header (when (>= (count all-files) 5) - (files-search))}) - - (save-button) - - (let [links (->> [(when @*current-file - {:title "Delete" - :options {:style {:color "#db1111"} - :on-click (fn [e] - (util/stop e) - (when-let [current-file @*current-file] - (p/let [_ (file/remove-file! (state/get-current-repo) - (str config/default-draw-directory "/" current-file))] - (reset! *files (remove #(= current-file %) @*files)) - (new-file!))))}})] - (remove nil?))] - (when (seq links) - (ui/dropdown-with-links - (fn [{:keys [toggle-fn]}] - [:div.ToolIcon__icon.ml-2.cursor.bg-gray-200 - {:title "More options" - :on-click toggle-fn - :style {:width "2rem" - :height "2rem"}} - (svg/vertical-dots nil)]) - links - {:modal-class (util/hiccup->class - "origin-top-right.absolute.left-0.mt-2.rounded-md.shadow-lg.whitespace-no-wrap.bg-white.w-48.dropdown-overflow-auto")}))) - - (draw-title)])) - -(defn- set-canvas-actions-style! - [state] - (when-let [section (first (d/by-tag "section"))] - (when (= "canvasActions-title" (d/attr section "aria-labelledby")) - (d/set-style! section "margin-top" "48px"))) - state) - -(rum/defcs draw-inner < rum/reactive - (mixins/keyboard-mixin (util/->system-modifier "ctrl+s") - (fn [state e] - (save-excalidraw! state e nil nil))) - (mixins/keyboard-mixin "alt+z" set-canvas-actions-style!) - {:init (fn [state] - (reset! *elements nil) - (let [[option] (:rum/args state) - file (or @*current-file - (:file option))] - (do - (reset! *current-title (get-file-title file)) - (set-last-file! file)) - (cond - file - (do - (reset! *file-loading? true) - (draw/load-excalidraw-file - file - (fn [data] - (let [{:keys [elements app-state]} (from-json data)] - (reset! *elements elements) - (reset! *file-loading? false))))) - - :else - (when-let [elements (get-last-elements)] - ;; TODO: keep this for history undo - (reset! *elements (remove #(gobj/get % "isDeleted") elements)))) - (assoc state - ::layout (atom [js/window.innerWidth js/window.innerHeight])))) - :did-mount set-canvas-actions-style! - :did-update set-canvas-actions-style!} - [state option] - (let [current-repo (state/sub :git/current-repo) - elements (rum/react *elements) - loading? (rum/react *file-loading?) - file (rum/react *current-file) - layout (get state ::layout) - [width height] (rum/react layout) - options (bean/->js {:zenModeEnabled true - :viewBackgroundColor "#FFF"}) - excalidraw-component @*excalidraw] - [:div.draw.white-theme {:style {:background "#FFF"}} - (when (and (or (and file elements) - (nil? file)) - excalidraw-component) - (excalidraw-component - {:width (get option :width width) - :height (get option :height height) - :on-resize (fn [] - (reset! layout [js/window.innerWidth js/window.innerHeight])) - - :on-change (or (:on-change option) - (fn [elements state] - (when (not= (bean/->clj elements) - (bean/->clj @*elements)) - (reset! *unsaved? true)) - (set-last-elements! elements) - (set-last-app-state! state) - (reset! *elements elements))) - :options options - :user (bean/->js {:name (or (:user-name option) - (:name (state/get-me)) - (util/unique-id))}) - :on-username-change (fn []) - :initial-data (or elements #js [])})) - [:div.absolute.top-4.left-4.hidden.md:block - [:div.flex.flex-row.items-center - [:a.mr-3.opacity-70.hover:opacity-100 {:href (rfe/href :home) - :title "Back to logseq"} - (svg/logo false)] - (files) - (when loading? - svg/loading)]] - (ui/notification) - - (when current-repo - [:div.absolute.top-4.right-4.hidden.md:block - [:div.flex.flex-row.items-center - (repo/sync-status current-repo) - (repo/repos-dropdown true - (fn [repo] - (reset! *current-file (get-last-file repo))))]])])) - -(rum/defcs draw-2 < rum/reactive - {:init (fn [state] - (let [repo (storage/get :git/current-repo)] - - (let [current-title (get-last-title repo)] - (reset! *current-title current-title)) - (let [current-file (or - (get-in (first (:rum/args state)) - [:query-params :file]) - (get-last-file repo))] - (reset! *current-file current-file) - (reset! *current-title (get-file-title current-file)))) - - (if (loaded?) - (set-excalidraw-component!) - (loader/load - (config/asset-uri "/static/js/excalidraw.min.js") - (fn [] - (reset! *loaded? true) - (set-excalidraw-component!)))) - - (draw/get-all-excalidraw-files - (fn [files] - (reset! *files (distinct files)))) - - (state/set-draw! true) - state) - :will-unmount (fn [state] - (state/set-draw! false) - state)} - [state option] - (let [loaded? (or (loaded?) - (rum/react *loaded?)) - current-repo (state/sub :git/current-repo) - component (rum/react *excalidraw)] - (if component - (let [current-file (rum/react *current-file) - current-file (or current-file - (and current-repo - (get-last-file current-repo)))] - (let [key (if current-repo - (str current-repo "-" - (or (and current-file (str "draw-" current-file)) - "draw-with-no-file")) - "draw-with-no-file")] - (rum/with-key (draw-inner option) key))) - [:div.center svg/loading]))) - -(rum/defc draw < rum/reactive - [option] - (let [db-restoring? (state/sub :db/restoring?)] - (if db-restoring? - [:div.ls-center - (ui/loading "Loading")] - (draw-2 option)))) diff --git a/src/main/frontend/components/draw.css b/src/main/frontend/components/draw.css deleted file mode 100644 index bb62ea316..000000000 --- a/src/main/frontend/components/draw.css +++ /dev/null @@ -1,23 +0,0 @@ -#draw { - -webkit-app-region: no-drag; - overflow: hidden; -} - -#draw iframe { - width: 100%; - height: 100%; - border: none; -} - -.draw { - display: flex; - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; -} - -.excalidraw-embed .draw { - position: relative; -} \ No newline at end of file diff --git a/src/main/frontend/components/sidebar.cljs b/src/main/frontend/components/sidebar.cljs index 3f09dd9c3..d81bade7d 100644 --- a/src/main/frontend/components/sidebar.cljs +++ b/src/main/frontend/components/sidebar.cljs @@ -131,7 +131,7 @@ (ui/loading (t :loading))]] :else - [:div {:style {:margin-bottom (if global-graph-pages? 0 120)}} + [:div.max-w-7xl.mx-auto {:style {:margin-bottom (if global-graph-pages? 0 120)}} main-content])]] (right-sidebar/sidebar)])) @@ -176,7 +176,7 @@ preferred-format (state/sub [:me :preferred_format]) logged? (:name me)] (rum/with-context [[t] i18n/*tongue-context*] - [:div.max-w-7xl.mx-auto + [:div (cond (and default-home (= :home (state/get-current-route)) diff --git a/src/main/frontend/encrypt.cljs b/src/main/frontend/encrypt.cljs index 5fef0a5c7..b5be16315 100644 --- a/src/main/frontend/encrypt.cljs +++ b/src/main/frontend/encrypt.cljs @@ -14,8 +14,9 @@ (defn content-encrypted? [content] - (or (str/starts-with? content age-pem-header-line) - (str/starts-with? content age-version-line))) + (when content + (or (str/starts-with? content age-pem-header-line) + (str/starts-with? content age-version-line)))) (defn encrypted-db? [repo-url] @@ -100,4 +101,4 @@ lazy-decrypt-with-user-passphrase (resolve 'frontend.extensions.age-encryption/decrypt-with-user-passphrase) content (utf8/encode content) decrypted (lazy-decrypt-with-user-passphrase passphrase content)] - (utf8/decode decrypted))) \ No newline at end of file + (utf8/decode decrypted))) diff --git a/src/main/frontend/extensions/excalidraw.cljs b/src/main/frontend/extensions/excalidraw.cljs new file mode 100644 index 000000000..8321b1021 --- /dev/null +++ b/src/main/frontend/extensions/excalidraw.cljs @@ -0,0 +1,136 @@ +(ns frontend.extensions.excalidraw + (:require [rum.core :as rum] + [goog.object :as gobj] + [frontend.rum :as r] + [frontend.util :as util :refer-macros [profile]] + [frontend.mixins :as mixins] + [frontend.storage :as storage] + [frontend.components.svg :as svg] + [cljs-bean.core :as bean] + [dommy.core :as d] + [clojure.string :as string] + [frontend.handler.notification :as notification] + [frontend.handler.draw :as draw] + [frontend.handler.file :as file] + [frontend.handler.ui :as ui-handler] + [frontend.ui :as ui] + [frontend.loader :as loader] + [frontend.config :as config] + [frontend.state :as state] + [frontend.search :as search] + [frontend.components.repo :as repo] + [promesa.core :as p] + [reitit.frontend.easy :as rfe] + ["@excalidraw/excalidraw" :as Excalidraw])) + +(def excalidraw (r/adapt-class (gobj/get Excalidraw "default"))) + +(defn from-json + [text] + (when-not (string/blank? text) + (try + (js/JSON.parse text) + (catch js/Error e + (println "from json error:") + (js/console.dir e) + (notification/show! + (util/format "Could not load this invalid excalidraw file") + :error))))) + +(defonce *bounding-width (atom nil)) +(defn- get-bounding-width + [ref] + (when ref + (when-let [current (gobj/get ref "current")] + (-> current + (.getBoundingClientRect) + (gobj/get "width"))))) + +(rum/defcs draw-inner < rum/reactive + (rum/local true ::zen-mode?) + (rum/local false ::view-mode?) + (rum/local nil ::elements) + [state data option] + (let [current-repo (state/sub :git/current-repo) + bounding-width (rum/react *bounding-width) + *zen-mode? (get state ::zen-mode?) + *view-mode? (get state ::view-mode?) + wide-mode? (state/sub :ui/wide-mode?) + *elements (get state ::elements) + file (:file option)] + (when data + [:div.overflow-hidden + [:div.my-1 {:style {:font-size 10}} + [:a.mr-2 {:on-click ui-handler/toggle-wide-mode!} + (util/format "Wide Mode (%s)" (if wide-mode? "ON" "OFF"))] + [:a.mr-2 {:on-click #(swap! *zen-mode? not)} + (util/format "Zen Mode (%s)" (if @*zen-mode? "ON" "OFF"))] + [:a.mr-2 {:on-click #(swap! *view-mode? not)} + (util/format "View Mode (%s)" (if @*view-mode? "ON" "OFF"))]] + [:div + (excalidraw + (merge + {:on-change (fn [elements state] + (let [elements->clj (bean/->clj elements)] + (when (and (seq elements->clj) + (not= elements @*elements)) + (let [state (bean/->clj state)] + (draw/save-excalidraw! + file + (-> {:type "excalidraw" + :version 2 + :source config/website + :elements elements + :appState (select-keys state [:gridSize :viewBackgroundColor])} + bean/->js + (js/JSON.stringify))) + (reset! *elements elements))))) + :zen-mode-enabled @*zen-mode? + :view-mode-enabled @*view-mode? + :grid-mode-enabled false + :initial-data data} + (if wide-mode? + {:height 650} + {:width 800 + :height 500})))]]))) + +(rum/defcs draw-container < rum/reactive + {:init (fn [state] + (let [[option] (:rum/args state) + file (:file option) + *data (atom nil) + *loading? (atom true)] + (when file + (draw/load-excalidraw-file + file + (fn [data] + (let [data (from-json data)] + (reset! *data data) + (reset! *loading? false))))) + (assoc state + ::data *data + ::loading? *loading?)))} + [state option] + (let [*data (get state ::data) + *loading? (get state ::loading?) + loading? (rum/react *loading?) + data (rum/react *data) + db-restoring? (state/sub :db/restoring?)] + (when (:file option) + (cond + db-restoring? + [:div.ls-center + (ui/loading "Loading")] + + (false? loading?) + (draw-inner data option) + + :else ; loading + nil)))) + +(rum/defc draw < rum/reactive + [option] + (let [repo (state/get-current-repo) + granted? (state/sub [:nfs/user-granted? repo])] + (when-not (and (config/local-db? repo) (not granted?)) + (draw-container option)))) diff --git a/src/main/frontend/fs/nfs.cljs b/src/main/frontend/fs/nfs.cljs index d44b5ef40..8749751ff 100644 --- a/src/main/frontend/fs/nfs.cljs +++ b/src/main/frontend/fs/nfs.cljs @@ -133,11 +133,13 @@ not-changed? (= last-modified-at local-last-modified-at) format (-> (util/get-file-ext path) (config/get-file-format)) - pending-writes (state/get-write-chan-length)] + pending-writes (state/get-write-chan-length) + draw? (and path (string/ends-with? path ".excalidraw"))] (if (and local-content (or old-content ;; temporally fix - (and path (string/ends-with? path ".excalidraw"))) new? + draw?) new? (or + draw? ;; Writing not finished (> pending-writes 0) ;; not changed by other editors diff --git a/src/main/frontend/handler/draw.cljs b/src/main/frontend/handler/draw.cljs index 3e23d1d33..ba333b199 100644 --- a/src/main/frontend/handler/draw.cljs +++ b/src/main/frontend/handler/draw.cljs @@ -14,37 +14,6 @@ [cljs-time.core :as t] [cljs-time.coerce :as tc])) -;; state -(defonce *files (atom nil)) -(defonce *current-file (atom nil)) -(defonce *current-title (atom "")) -(defonce *file-loading? (atom nil)) -(defonce *elements (atom nil)) -(defonce *unsaved? (atom false)) -(defonce *search-files (atom [])) -(defonce *saving-title (atom nil)) -(defonce *excalidraw (atom nil)) - -;; TODO: refactor -(defonce draw-state :draw-state) - -(defn get-draw-state [] - (storage/get draw-state)) -(defn set-draw-state! [value] - (storage/set draw-state value)) - -(defn set-k - [k v] - (when-let [repo (state/get-current-repo)] - (let [state (get-draw-state)] - (let [new-state (assoc-in state [repo k] v)] - (set-draw-state! new-state))))) - -(defn set-last-file! - [value] - (set-k :last-file value)) - -;; excalidraw (defn create-draws-directory! [repo] (when repo @@ -55,8 +24,8 @@ (fn [_error] nil))))) (defn save-excalidraw! - [file data ok-handler] - (let [path (str config/default-draw-directory "/" file) + [file data] + (let [path file repo (state/get-current-repo)] (when repo (let [repo-dir (config/get-repo-dir repo)] @@ -65,7 +34,6 @@ (create-draws-directory! repo) (fs/write-file! repo repo-dir path data nil) (git-handler/git-add repo path) - (ok-handler file) (db/transact! repo [{:file/path path :page/name file @@ -75,58 +43,30 @@ (prn "Write file failed, path: " path ", data: " data) (js/console.dir error)))))))) -(defn get-all-excalidraw-files - [ok-handler] - (when-let [repo (state/get-current-repo)] - (p/let [_ (create-draws-directory! repo)] - (let [dir (str (config/get-repo-dir repo) - "/" - config/default-draw-directory)] - (util/p-handle - (fs/readdir dir) - (fn [files] - (let [files (-> (filter #(string/ends-with? % ".excalidraw") files) - (distinct) - (sort) - (reverse))] - (ok-handler files))) - (fn [error] - (js/console.dir error))))))) - (defn load-excalidraw-file [file ok-handler] (when-let [repo (state/get-current-repo)] (util/p-handle - (file-handler/load-file repo (str config/default-draw-directory "/" file)) + (file-handler/load-file repo file) (fn [content] (ok-handler content)) (fn [error] - (prn "Error loading " file ": " - error))))) + (println "Error loading " file ": " + error))))) (defonce default-content (util/format "{\n \"type\": \"excalidraw\",\n \"version\": 2,\n \"source\": \"%s\",\n \"elements\": [],\n \"appState\": {\n \"viewBackgroundColor\": \"#FFF\",\n \"gridSize\": null\n }\n}" config/website)) -(defn title->file-name - [title] - (when (not (string/blank? title)) - (let [title (string/lower-case (string/replace title " " "-"))] - (str (date/get-date-time-string-2) "-" title ".excalidraw")))) +(defn file-name + [] + (str (date/get-date-time-string-2) ".excalidraw")) (defn create-draw-with-default-content - [current-file ok-handler] + [current-file] (when-let [repo (state/get-current-repo)] (p/let [exists? (fs/file-exists? (config/get-repo-dir repo) (str config/default-draw-directory current-file))] (when-not exists? - (save-excalidraw! current-file default-content - (fn [file] - (reset! *files - (distinct (conj @*files file))) - (reset! *current-file file) - (reset! *unsaved? false) - (set-last-file! file) - (reset! *saving-title nil) - (ok-handler))))))) + (save-excalidraw! current-file default-content))))) diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index 222b33375..f9594b3b3 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -10,7 +10,6 @@ [frontend.handler.repo :as repo-handler] [frontend.handler.file :as file-handler] [frontend.handler.notification :as notification] - [frontend.handler.draw :as draw] [frontend.handler.expand :as expand] [frontend.handler.block :as block-handler] [frontend.format.mldoc :as mldoc] @@ -2112,22 +2111,6 @@ (get-link format link label) format {:last-pattern (str commands/slash "link")}))) - :draw - (when-not (string/blank? (:title m)) - (let [file (draw/title->file-name (:title m)) - value (util/format - "[[%s]]\n" - file - file)] - (insert-command! id - value - format - {:last-pattern (str commands/slash "draw ")}) - (draw/create-draw-with-default-content - file - (fn [] - (let [input (gdom/getElement "download")] - (.click input)))))) nil) (state/set-editor-show-input! nil) diff --git a/src/main/frontend/handler/ui.cljs b/src/main/frontend/handler/ui.cljs index 161f6c2e0..5dd9a2db8 100644 --- a/src/main/frontend/handler/ui.cljs +++ b/src/main/frontend/handler/ui.cljs @@ -92,3 +92,12 @@ ;; (state/get-custom-css-link) )] (util/add-style! style))) + +(defn toggle-wide-mode! + [] + (let [wide? (state/get-wide-mode?) + elements (array-seq (js/document.getElementsByClassName "cp__sidebar-main-content")) + max-width (if wide? "var(--ls-main-content-max-width)" "100%")] + (when-let [element (first elements)] + (dom/set-style! element :max-width max-width)) + (state/toggle-wide-mode!))) diff --git a/src/main/frontend/keyboards.cljs b/src/main/frontend/keyboards.cljs index 152f65ef2..793804811 100644 --- a/src/main/frontend/keyboards.cljs +++ b/src/main/frontend/keyboards.cljs @@ -51,6 +51,8 @@ (enable-when-not-editing-mode! ui-handler/toggle-contents!) (or (shortcut :editor/toggle-settings) "t s") (enable-when-not-editing-mode! ui-handler/toggle-settings-modal!) + (or (shortcut :ui/toggle-wide-mode) "t w") + (enable-when-not-editing-mode! ui-handler/toggle-wide-mode!) (or (shortcut :ui/toggle-between-page-and-file) "s") (enable-when-not-editing-mode! route-handler/toggle-between-page-and-file!) (or (shortcut :git/commit) "c") diff --git a/src/main/frontend/routes.cljs b/src/main/frontend/routes.cljs index 9a598f043..640f0d288 100644 --- a/src/main/frontend/routes.cljs +++ b/src/main/frontend/routes.cljs @@ -4,7 +4,6 @@ [frontend.components.file :as file] [frontend.components.page :as page] [frontend.components.diff :as diff] - [frontend.components.draw :as draw] [frontend.components.journal :as journal] [frontend.components.settings :as settings] [frontend.components.external :as external] @@ -52,10 +51,6 @@ {:name :diff :view diff/diff}] - ["/draw" - {:name :draw - :view draw/draw}] - ["/settings" {:name :settings :view settings/settings}] diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index 7f18c7923..3dbece8d7 100644 --- a/src/main/frontend/state.cljs +++ b/src/main/frontend/state.cljs @@ -54,6 +54,7 @@ :ui/sidebar-open? false :ui/left-sidebar-open? false :ui/theme (or (storage/get :ui/theme) "dark") + :ui/wide-mode? false ;; :show-all, :hide-block-body, :hide-block-children :ui/cycle-collapse :show-all :ui/collapsed-blocks {} @@ -899,10 +900,13 @@ (set-state! :indexeddb/support? value)) (defn set-modal! - [modal-panel-content] - (swap! state assoc - :modal/show? (boolean modal-panel-content) - :modal/panel-content modal-panel-content)) + ([modal-panel-content] + (set-modal! modal-panel-content false)) + ([modal-panel-content fullscreen?] + (swap! state assoc + :modal/show? (boolean modal-panel-content) + :modal/panel-content modal-panel-content + :modal/fullscreen? fullscreen?))) (defn close-modal! [] @@ -992,6 +996,14 @@ [] (get-in @state [:repo/changed-files (get-current-repo)])) +(defn get-wide-mode? + [] + (:ui/wide-mode? @state)) + +(defn toggle-wide-mode! + [] + (update-state! :ui/wide-mode? not)) + (defn set-online! [value] (set-state! :network/online? value)) diff --git a/src/main/frontend/ui.cljs b/src/main/frontend/ui.cljs index d218d1d5f..ff289b20b 100644 --- a/src/main/frontend/ui.cljs +++ b/src/main/frontend/ui.cljs @@ -424,7 +424,7 @@ [:div.absolute.inset-0.opacity-75]]) (rum/defc modal-panel - [panel-content transition-state close-fn] + [panel-content transition-state close-fn fullscreen?] [:div.ui__modal-panel.transform.transition-all.sm:min-w-lg.sm {:class (case transition-state "entering" "ease-out duration-300 opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" @@ -444,7 +444,7 @@ :stroke-linejoin "round" :stroke-linecap "round"}]]]] - [:div.panel-content + [:div {:class (if fullscreen? "" "panel-content")} (panel-content close-fn)]]) (rum/defc modal < rum/reactive @@ -458,6 +458,7 @@ :outside? false))) [] (let [modal-panel-content (state/sub :modal/panel-content) + fullscreen? (state/sub :modal/fullscreen?) show? (boolean modal-panel-content) close-fn #(state/close-modal!) modal-panel-content (or modal-panel-content (fn [close] [:div]))] @@ -470,7 +471,7 @@ (css-transition {:in show? :timeout 0} (fn [state] - (modal-panel modal-panel-content state close-fn)))])) + (modal-panel modal-panel-content state close-fn fullscreen?)))])) (defn make-confirm-modal [{:keys [tag title sub-title sub-checkbox? on-cancel on-confirm] :as opts}]