From a504a49004671287d9e0c78fd107c4abf669cc2a Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Thu, 08 Jan 2026 16:52:14 +0000
Subject: [PATCH] Merge branch 'main' of https://github.com/jakevdwerf/jvb

---
 assets/css/icons.css                  |    2 
 assets/js/min/crud.min.js             |    2 
 assets/css/forms.min.css              |    2 
 inc/helpers/ui.php                    |   56 
 inc/forms/TaxonomySelector.php        |   77 
 assets/js/concise/TaxonomyCreator.js  |  118 
 inc/rest/routes/TermRoutes.php        |    6 
 inc/managers/OperationQueue.php       |   48 
 assets/js/concise/QueueOld.js         |  960 +++++++++
 inc/managers/CRUDManager.php          |    3 
 assets/js/concise/UtilityFunctions.js |   65 
 inc/meta/MetaForm.php                 |    3 
 inc/rest/routes/UploadRoutes.php      |   14 
 assets/js/min/queue.min.js            |    2 
 assets/js/min/utility.min.js          |    2 
 assets/js/concise/CRUD.js             |    6 
 inc/rest/routes/QueueRoutes.php       |    2 
 checks.php                            |    7 
 assets/js/concise/TaxonomySelector.js |  565 +++-
 assets/js/min/uploader.min.js         |    2 
 assets/js/concise/Queue.js            | 1319 ++++++-------
 inc/ui/CRUDSkeleton.php               |   35 
 assets/js/min/creator.min.js          |    2 
 build/feed/view.asset.php             |    2 
 assets/js/concise/DataStore.js        |  187 +
 src/feed/style.scss                   |  107 +
 build/feed/style-index-rtl.css        |    2 
 inc/ui/Navigation.php                 |    6 
 assets/js/min/dataStore.min.js        |    2 
 build/feed/view.js                    |    2 
 assets/js/min/selector.min.js         |    2 
 src/feed/viewOld.js                   | 1277 ++++++------
 build/feed/style-index.css            |    2 
 assets/js/concise/UploadManager.js    |    3 
 inc/blocks/FeedBlock.php              |    6 
 src/feed/view.js                      |  972 ++++-----
 36 files changed, 3,585 insertions(+), 2,283 deletions(-)

diff --git a/assets/css/forms.min.css b/assets/css/forms.min.css
index d108d0a..a0dac7b 100644
--- a/assets/css/forms.min.css
+++ b/assets/css/forms.min.css
@@ -1 +1 @@
-input:is([type=date],[type=number],[type=text],[type=url],[type=email],[type=tel],[type=password],[type=search],[type=datetime-local],[type=time]),textarea{font-family:var(--body);font-size:var(--txt-medium);color:var(--contrast);padding:var(--p-y) var(--p-x);border-radius:var(--radius);background-color:var(--base);outline:0;border:1px solid var(--base-100);border-bottom:2px solid var(--contrast-200);width:100%;max-width:100%;margin:0 4px}input:is([type=date],[type=number],[type=text],[type=url],[type=email],[type=tel],[type=password],[type=search],[type=datetime-local],[type=time]):focus,textarea:focus{outline:var(--action-50);background-color:var(--base-100);color:var(--contrast)}input::placeholder,textarea::placeholder{font-family:var(--body);color:var(--base-200)}@media (min-width:768px){:root{--p-y:1rem}}select{background:var(--base);border:2px solid var(--base-100);border-radius:var(--radius);color:var(--contrast);cursor:pointer;font-family:var(--body);font-size:var(--txt-small);padding:.5rem 1rem;width:100%}select:disabled{background-color:var(--base-50);border-color:var(--base-100);color:var(--base-200);cursor:not-allowed}select option{background:var(--base);color:var(--contrast);padding:.5rem}select option:active,select option:checked,select option:focus,select option:hover{background:var(--action-0);color:var(--base);box-shadow:0 0 0 100px var(--action-0) inset}select option:checked{background:var(--action-0) linear-gradient(0deg,var(--action-0) 0,var(--action-0) 100%);color:var(--base)}select:hover{border-color:var(--action-0)}select:focus{border-color:var(--action-0)}input[type=search]:focus+.clear-search{opacity:1;cursor:pointer}.search-container .clear-search{opacity:0;cursor:default}.search-container .icon.search{padding:4px 8px;color:var(--contrast-200);--w:3rem}input[type=search]::-moz-search-clear-button,input[type=search]::-ms-clear,input[type=search]::-ms-reveal,input[type=search]::search-cancel-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;display:none;visibility:hidden}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration,input[type=search]::-webkit-search-results-button,input[type=search]::-webkit-search-results-decoration{-webkit-appearance:none}input[type=url]{background:var(--linkIcon);background-position:.5em;background-size:1em;background-repeat:no-repeat;padding-left:2em}.integration .label,label{text-transform:uppercase;font-weight:700;margin-bottom:.5rem;display:block}.field{margin:2rem 0;position:relative}.field:has(.has-tooltip) label{margin-left:2rem}legend{padding:0 1rem}.date-wrapper{position:relative;display:inline-block}input[type=date]{padding:8px 36px 8px 8px;border-radius:4px}input[type=date]::-webkit-calendar-picker-indicator{opacity:0;width:100%;height:100%;position:absolute;top:0;left:0;cursor:pointer}input[type=date]+.icon{--w:20px;position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none}input:is([type=time],[type=datetime-local],[type=date]){padding:.5rem;border:1px solid var(--contrast-200);border-radius:4px;font-size:14px;min-width:180px;background:var(--base);color:var(--contrast);cursor:pointer}.date-wrapper input[type=date]:focus,.datetime-wrapper input[type=datetime-local]:focus,.field-input-wrapper input:is([type=time],[type=datetime-local],[type=date]):focus,.time-wrapper input[type=time]:focus{border-color:var(--action-0);box-shadow:0 0 0 2px rgba(var(--action-rgb),.1)}.date-wrapper .icon,.datetime-wrapper .icon,.field-input-wrapper .icon,.time-wrapper .icon{width:18px;height:18px;background-color:var(--contrast);opacity:.7}.selected-items{--justify:flex-start;--gap:.5rem;margin-bottom:.5rem}.selected-item{padding:.25rem .5rem;margin:.125em;background:var(--base-100);border-radius:.25rem;font-size:var(--txt-medium);border:1px solid var(--base-200);position:relative}.remove-item{background:0 0;border:none;padding:.25rem;cursor:pointer;color:#666;border-radius:var(--radius);width:1.5em;height:1.5em}.remove-item .close{width:.5em;height:.5em}.remove-item:hover{color:var(--action-0);background:#fee}.clear-filters{margin-left:auto;border:1px solid var(--base-200)}[type=checkbox],[type=radio],input.ch{position:absolute;opacity:0;left:-200vw}[type=checkbox]+label,[type=radio]+label,input.ch+label{position:relative;cursor:pointer}[type=checkbox]+label:hover,[type=radio]+label:hover{color:var(--action-0)}[type=checkbox]+label::after,[type=checkbox]+label::before,[type=radio]+label::after,[type=radio]+label::before,input.ch+label::after,input.ch+label::before{content:'';position:absolute;top:50%}[type=checkbox]+label::after,[type=radio]+label::after,input.ch+label::after{left:5px;transform:translateY(-70%) rotate(45deg);width:5px;height:10px;border:solid var(--light-0);border-width:0 2px 2px 0;display:none}[type=checkbox]+label::before,[type=radio]+label::before,input.ch+label::before{left:0;transform:translateY(-50%);width:1rem;height:1rem;border:2px solid var(--contrast-200);background-color:var(--base);border-radius:var(--radius)}[type=checkbox]:hover+label::before,[type=radio]:hover+label::before,input.ch:hover+label::before{border-color:var(--action-200)}[type=checkbox]:checked+label::before,[type=radio]:checked+label::before,input.ch:checked+label::before{background-color:var(--action-0);border-color:var(--action-100)}[type=radio]:checked+label::before{border-radius:50%}[type=checkbox]:checked+label::after,input.ch:checked+label::after{display:block;left:5px;top:50%;transform:translateY(-70%) rotate(45deg);width:.35rem;height:.66rem;border:solid var(--light-0);border-width:0 2px 2px 0}[type=checkbox]:disabled+label,[type=radio]:disabled+label,input.ch:disabled+label{cursor:not-allowed;background-color:var(--base-50);color:var(--base-200);border-color:var(--base-200)}[type=checkbox]:disabled+label:hover,[type=radio]:disabled+label:hover,input.ch:disabled+label:hover{background-color:var(--base-50);color:var(--base-200);border-color:var(--base-200)}[type=checkbox]:disabled+label::before,[type=radio]:disabled+label::before,input.ch:disabled+label::before{border-color:var(--base-200)}[type=checkbox]:not(.btn)+label,[type=radio]:not(.btn)+label,input.ch+label{flex:1;padding-left:2rem;transform-origin:top center;will-change:transform}.btn+label::after,.btn+label::before{display:none}.btn+label{--w:1.2em;border:1px solid var(--base-200);border-radius:var(--radius);min-width:2rem;min-height:2rem;margin:0;display:flex;justify-content:center;align-items:center;flex-wrap:nowrap;gap:.5rem;color:var(--contrast-200);opacity:.8}.radio-options.status label{padding:0 .5rem}.btn:checked+label{border-color:var(--contrast);color:var(--contrast);opacity:1}.btn+label:hover{color:var(--action-50);border-color:var(--action-50)}.btn[hidden]+label,input[hidden]+label{display:none!important}.checkbox-options{--gap:.5rem 2rem}.checkbox-options label{flex:unset!important}.radio-options{--gap:.125rem .5rem}.radio-options input:not(.ch)+label::before{display:none!important}.radio-options input:not(.ch)+label{flex:unset!important;padding:.25rem!important;border-radius:4px;border:1px solid var(--base-100);color:var(--contrast-200);font-weight:400;text-align:center}.radio-options input:not(.ch)+label:hover,.radio-options input:not(.ch):checked+label{border-color:var(--action-0);color:var(--action-0)}.quantity{margin:0;display:inline-flex;width:fit-content;align-items:center;justify-content:center;border:1px solid transparent;border-radius:4px;position:relative}.quantity:focus-within{border-color:var(--action-0)}.quantity label{margin:0;font-size:var(--txt-small)}.quantity button{background:var(--base);padding:0;width:38px;height:38px;z-index:0;position:relative;border:1px solid var(--base-200);color:var(--contrast-200)}.quantity button:hover:not(:disabled){color:var(--action-0);border-color:var(--action-0);background-color:var(--base)}.quantity button:active:not(:disabled){background-color:var(--action-0);color:var(--light-0);transform:scale(.95)}.quantity button:disabled{opacity:.5;cursor:not-allowed}.quantity input[type=number]{z-index:1;border:1px solid var(--base-200);background:var(--base);text-align:center;font-size:1.1rem;width:60px;height:48px;margin:0;padding:0!important;appearance:textfield}.quantity input[type=number]::-webkit-inner-spin-button,.quantity input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.quantity input[type=number]:focus{background-color:var(--base-50)}.quantity button.increase{left:-2px;border-radius:0 4px 4px 0}.quantity button.decrease{right:-2px;border-radius:4px 0 0 4px}.items-container{margin:0;padding:0;width:100%}.create-new-term{margin-top:1rem;width:100%}.create-new-term .field,.create-new-term[open] summary{margin-bottom:1rem}.create-new-term .field{max-width:100%}#jvb-selector>.wrap{--wrap:nowrap;--justify:flex-start}#jvb-selector .items-wrap{width:100%}#jvb-selector .items-container{display:grid;grid-template-columns:repeat(auto-fit,minmax(1fr,100%))}.tab-content[hidden]{display:block!important;transform:scaleY(0);height:0;overflow:hidden}.tab-content[hidden]:focus-within{transform:scaleY(1);height:auto}nav.tabs h2{margin:0!important;line-height:1;font-size:var(--txt-medium);display:flex;color:var(--contrast);white-space:nowrap;gap:1rem}nav.tabs .active h2{color:var(--action-contrast)}nav.tabs button{padding:.75rem 1.5rem;border-radius:0;position:relative;border:2px solid var(--action-0)}nav.tabs>button:first-of-type{border-top-left-radius:var(--radius)}nav.tabs>button:last-of-type{border-top-right-radius:var(--radius)}.tabs>button:focus,.tabs>button:hover{background-color:var(--base-200)}.tabs>button::after{content:'';position:absolute;bottom:-2px;left:0;width:0;height:3px;background-color:var(--action-50);transition:width .3s}.tabs>button.active::after,.tabs>button:hover::after{width:100%}.tabs>button.active::after{background-color:var(--action-200)}.tabs>button.active{background-color:var(--action-0);color:var(--action-contrast)}.tabs>button.active:focus,.tabs>button.active:hover{background-color:var(--action-100)}.tab-content h2{display:none}details.uploader .file-upload-container{margin:1rem 0;max-width:100%}@media (min-width:768px){details.uploader .file-upload-container{margin:1rem var(--mr) 1rem var(--ml);max-width:var(--content)}}.empty-group,.file-upload-wrapper{border:2px dashed var(--action-0);border-radius:4px;padding:2rem;text-align:center;transition:all .3s ease;background:rgba(var(--action-rgb),var(--op-1));position:relative;cursor:pointer}.file-upload-wrapper h2{margin:0!important;font-size:var(--txt-large)}.dragover,.empty-group,.file-upload-wrapper:hover{background:rgba(var(--action-rgb),var(--op-2));border-color:var(--action-0)!important}.file-upload-wrapper input[type=file]{position:absolute;left:0;top:0;width:100%;height:100%;opacity:0;cursor:pointer}.empty-group p,.file-upload-text{color:var(--contrast);margin:0}.empty-group p strong,.file-upload-text strong{color:var(--action-0);text-decoration:underline}.field.upload{position:relative}.field.upload:not(.uploading) .progress{display:none}.field.upload .actions{position:absolute;top:0;right:0}.item-grid.groups{grid-template-columns:repeat(1,1fr)}.item-grid.group{margin-bottom:0}.item-grid.group .item,.item-grid.preview .item,.item-grid.restore .item{display:block}.item-grid.group button,.item-grid.preview button,.item-grid.restore button{padding:.25rem .5rem}.item-grid.group button .icon,.item-grid.preview button .icon,.item-grid.restore button .icon{--w:1.1em}.item-grid.group .item .preview>input[type=checkbox]:not(.label-button)+label,.item-grid.preview .item .preview>input[type=checkbox]:not(.label-button)+label,.item-grid.restore .item .preview>input[type=checkbox]:not(.label-button)+label{padding-left:0;margin:0}.item-grid.group .item .preview>input[type=checkbox]+label:before,.item-grid.preview .item .preview>input[type=checkbox]+label:before,.item-grid.restore .item .preview>input[type=checkbox]+label:before{transform:unset;top:.5rem;left:.5rem}.item-grid.group .item .preview>input[type=checkbox]+label::after,.item-grid.preview .item .preview>input[type=checkbox]+label::after,.item-grid.restore .item .preview>input[type=checkbox]+label::after{top:.5rem;left:.75rem;transform:translateY(20%) rotate(45deg)}.item-grid.group .item .item-actions,.item-grid.preview .item .item-actions,.item-grid.restore .item .item-actions{position:absolute;top:0;right:0;padding-left:var(--chipchip)}.item-grid.group summary,.item-grid.preview summary,.item-grid.restore summary{padding:.5rem}.item-grid.group:has([type=checkbox]:checked),.item-grid.preview:has([type=checkbox]:checked),.item-grid.restore:has([type=checkbox]:checked){padding:1rem;background-color:rgba(var(--contrast-rgb),var(--op-1))}.item-grid.group:has([type=checkbox]:checked) .item,.item-grid.preview:has([type=checkbox]:checked) .item,.item-grid.restore:has([type=checkbox]:checked) .item{padding:.75rem;opacity:.8}.item-grid.group:has([type=checkbox]:checked) .item img,.item-grid.preview:has([type=checkbox]:checked) .item img,.item-grid.restore:has([type=checkbox]:checked) .item img{filter:var(--filter)}.item-grid.group:has([type=checkbox]:checked) details,.item-grid.preview:has([type=checkbox]:checked) details,.item-grid.restore:has([type=checkbox]:checked) details{display:none}.item-grid.group .item:has([type=checkbox]:checked),.item-grid.preview .item:has([type=checkbox]:checked),.item-grid.restore .item:has([type=checkbox]:checked){padding:.5rem;background-color:rgba(var(--action-rgb),var(--op-4));opacity:1}.item-grid.preview summary span{display:none}.item-grid.group .item:has([type=checkbox]:checked) img,.item-grid.preview .item:has([type=checkbox]:checked) img,.item-grid.restore .item:has([type=checkbox]:checked) img{filter:none}[type=radio].featured+label .icon-star-fi,[type=radio].featured:checked+label .icon-star{display:none}[type=radio].featured+label .icon-star,[type=radio].featured:checked+label .icon-star-fi{display:inline-block}.restore.restore.item,.upload.upload.item{border-radius:var(--radius);aspect-ratio:unset;overflow:hidden;background:var(--base);border:1px solid var(--base-200)}.restore-item [for=select-item],.upload.item [for=select-item]{aspect-ratio:1}.upload.item:has(details[open]){grid-column:1/-1}.restore.item img,.upload.item img{transition:transform var(--trans-base)}.restore.item:hover img,.upload.item:hover img{transform:scale(1.02);transition:transform var(--trans-base)}.upload-group{background-image:var(--dashed-action);padding:5px;border-radius:var(--radius);background-color:rgba(var(--action-rgb),var(--op-1))}.upload-group .selected .field{margin:0}.upload-group .selection-actions button{aspect-ratio:unset}.submit-uploads{position:fixed;bottom:0;right:var(--btn_);z-index:var(--z-6);height:var(--btn);box-shadow:rgba(var(--base-rgb),var(--op-45)) var(--shdw);border-radius:var(--radius);animation:pulse-color 5s infinite;animation-delay:1s;background-color:var(--action-0);color:var(--action-contrast)}.submit-uploads:hover{background-color:var(--base-200);color:var(--contrast-200)}.empty-group{order:-1;grid-column:1/-1;padding:20px;background-image:var(--dashed-action);border-radius:var(--radius);margin:10px 0;cursor:pointer;transition:all var(--trans-base);text-align:center;background-color:rgba(var(--action-rgb),var(--op-1))}.group-display:not([hidden])~.file-upload-container{display:none}.dragging,.upload.item.dragging{opacity:.7;transform:scale(.95) rotate(3deg);z-index:var(--z-7);box-shadow:0 8px 25px rgba(0,0,0,.3)}.dragover{background:rgba(var(--action-rgb),var(--op-3))!important;border-color:var(--action-0)!important;transform:scale(1.05);animation:drop-pulse .8s infinite ease-in-out}.drag-preview{position:fixed;z-index:var(--z-9);width:fit-content;overflow:visible;pointer-events:none;opacity:.9;transform:scale(1.05);transition:transform .2s ease}.drag-preview .drag-items{width:max-content;height:max-content;position:relative}.drag-preview .drag-items .drag-item{width:120px;height:120px;position:absolute;top:0;left:0;background:var(--base);border-radius:var(--radius-outer);box-shadow:rgba(var(--base-rgb),var(--op-45)) var(--shdw)}.drag-preview .drag-items .drag-item:nth-child(1){transform:rotate(-3deg);z-index:3}.drag-preview .drag-items .drag-item:nth-child(2){left:8px;top:-4px;transform:rotate(4deg);z-index:2;transition-delay:30ms}.drag-preview .drag-items .drag-item:nth-child(3){left:-6px;top:-8px;transform:rotate(-5deg);z-index:1;transition-delay:60ms}.drag-preview .drag-items .drag-item:nth-child(4){left:12px;top:-12px;transform:rotate(3deg);z-index:0;transition-delay:90ms}.drag-preview .drag-items .drag-item:nth-child(n+5){left:-10px;top:-16px;transform:rotate(-4deg);z-index:0;opacity:.8}.drag-preview .drag-items img,.drag-preview .drag-items video{width:100%;height:100%;object-fit:cover;display:block}.drag-preview .drag-count{position:absolute;top:-8px;right:-8px;background:var(--base-200);color:var(--contrast);border-radius:50%;width:24px;height:24px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;box-shadow:rgba(var(--base-rgb),var(--op-45)) var(--shdw);z-index:var(--z-3)}.item.dragging{opacity:.5;transform:scale(.95);filter:grayscale(50%);transition:opacity .2s ease,transform .2s ease,filter .2s ease}@keyframes drop-pulse{0%,100%{background-color:rgba(var(--action-rgb),var(--op-3));transform:scale(1.02)}50%{background-color:var(rgba(var(--action-rgb),var(--op-4)));transform:scale(1.04)}}.selection-actions{display:flex;gap:.25rem}@media (max-width:767px){body:not(.uploading):has(.group-display:not([hidden])){overflow:hidden}body:not(.uploading):has(.group-display:not([hidden])) .qtoggle{z-index:var(--z-1)}.group-display.group-display{position:fixed;top:var(--btn);bottom:var(--btn);left:0;right:0;max-height:var(--maxHeight);overflow:hidden;z-index:var(--z-6);width:calc(100% - 1rem);height:calc(100% - 1rem);padding:0 0 3rem;--justify:flex-start;--align:flex-start;--gap:0}.group-display::before{content:'';display:block;z-index:-1;top:-.5rem;bottom:-.5rem;left:-.5rem;right:-.5rem;position:absolute;background-color:rgba(var(--base-rgb),var(--op-6));filter:blur(5px)}.group-display .preview-wrap,.group-display .sidebar{--wrap:nowrap;height:50%;overflow:hidden auto;position:relative;padding:.5rem}.group-display .preview-wrap{top:0}.group-display .preview-wrap .selected{display:flex;justify-content:space-between;align-items:center}.group-display .sidebar{bottom:0;flex-wrap:nowrap;overflow:hidden auto;background-color:var(--contrast-200);color:var(--base)}.group-display .sidebar>.hint{color:var(--contrast)}.group-display .sidebar .header{display:none}.group-display .preview-actions{top:0;flex-shrink:0}.group-display .preview-wrap>.hint,.group-display .sidebar>.hint{bottom:0;margin:0;text-align:center}.group-display .preview-actions,.group-display .preview-wrap>.hint,.group-display .sidebar>.hint{position:absolute;left:0;right:0;background-color:rgba(var(--base-rgb),var(--op-6));z-index:var(--z-3);box-shadow:rgba(var(--base-rgb),var(--op-45)) var(--shdw)}.group-display .item-grid{height:100%;overflow:hidden auto;grid-template-columns:repeat(3,1fr);padding:2rem 0}.group-display .sidebar>.item-grid{grid-template-columns:repeat(1,1fr);gap:1rem;padding:0}.group-display .sidebar .empty-group{order:0;position:sticky;height:fit-content;top:0;z-index:var(--z-3);background-color:rgba(var(--action-rgb),var(--op-6))}.group-display .sidebar .upload-group{order:1}.group-display .sidebar .empty-group p{margin:0}.group-display .field,.group-display .field label{margin:0;padding:0}.group-display .sidebar h4{margin:.25rem}.group-display .item{width:100%;height:max-content}.submit-uploads{bottom:var(--btn);left:0;right:0;width:100%;height:3rem}body.uploading .group-display.group-display{position:relative;top:unset;bottom:unset;right:unset;left:unset}}@media (min-width:768px){.group-display.group-display{--wrap:nowrap;--dir:row;--gap:1rem;--align:flex-start}.group-display .preview-wrap,.group-display .sidebar{--justify:flex-start;--wrap:nowrap;max-height:calc(100vh - var(--btnbtn));overflow:hidden auto}.group-display .preview-wrap,.group-display .sidebar{width:50%}.preview-actions,.preview-wrap .hint{position:sticky;z-index:var(--z-3);box-shadow:rgba(var(--base-rgb),var(--op-45)) var(--shdw);background-color:var(--base);width:100%}.preview-actions{top:0;left:0;right:0}.preview-actions .field{margin:0}.preview-wrap .hint,.sidebar>.hint{bottom:-1rem;padding-bottom:1rem;margin:0;left:0;right:0;text-align:center}}.item-grid.restore{grid-template-columns:repeat(1,1fr)}dialog nav.tabs{position:sticky;top:0;background-color:var(--base-50);z-index:var(--z-6);box-shadow:rgba(var(--base-rgb),var(--op-45)) var(--shdw-down);margin-bottom:2rem}.editor-container .ql-toolbar{display:flex;background-color:var(--base-50);justify-content:flex-start;flex-wrap:wrap;padding:.25rem;gap:.5rem 1rem;border-top-left-radius:var(--radius);border-top-right-radius:var(--radius);border-bottom:4px solid var(--base-50)}.ql-toolbar .ql-formats{display:flex;gap:.25rem}.editor-container .ql-container{--padding:1rem;background-color:var(--base);border-bottom-left-radius:var(--radius);border-bottom-right-radius:var(--radius);height:fit-content;padding:2px;border:1px solid var(--base-200)}.editor-container .ql-container .ql-editor{padding:var(--padding);width:100%;height:100%}.ql-editor img{max-width:50%;height:auto}.ql-clipboard{left:-100000px;height:1px;overflow-y:hidden;position:absolute;top:50%}.ql-hidden{display:none}.ql-tooltip{position:absolute;transform:translateY(10px);background-color:var(--base-100);border:1px solid var(--base);box-shadow:0 0 5px rgba(var(--base-rgb),var(--op-6));color:var(--contrast);padding:5px 12px;white-space:nowrap}[data-type=single] .item-grid{display:flex}.repeater-row details summary::after{margin-left:0}.repeater-row details summary button{margin-left:auto}/*!* Group actions buttons - more visible *!*//*!* Group item grid - distinct from preview grid *!*//*!* Group count hint *!*//*!* ============================================================================*//*!* Base drag preview *!*//*!* Single item drag preview *!*//*!* Multi-item drag preview container *!*//*!* Items being dragged - reduce opacity on originals *!*//*!* Count badge on multi-item preview *!*//*!* ============================================================================*//*!* Ensure progress bar is visible when needed *!*//*!* Progress bar track *!*//*!* Progress bar fill *!*//*!* Progress details - styled for row layout with text and count *!*//*!* Individual item progress - overlay style *!*//*!* Item progress icon and status text *!*//*!* ============================================================================*//*!* Hide uploader when we have uploads *!*//*!* Show group display when we have uploads *!*//*!* ============================================================================*//*!* Selected items - more obvious *!*//*!* Selection checkbox - always visible on hover or when checked *!*//*!* Selection controls - more prominent *!*//*!* ============================================================================*//*!* Smooth dragover animation *!*//*!* ============================================================================*//*!* ============================================================================*//*!* Notification container - fixed overlay *!*//*!* Content card *!*//*!* Message section *!*//*!* Scrollable field list *!*//*!* Item grid for restore preview *!*//*!* Restore item *!*//*!* Checked state *!*//*!* Preview section *!*//*!* Item info *!*//*!* Checkbox controls *!*//*!* Actions section *!*//*!* Selection controls *!*//*!* Action buttons *!*//*!* Restore button - primary action *!*//*!* Scrap cache button - destructive action *!*//*!* Dismiss button - secondary action *!*//*!* Mobile responsive *!*//*!* Animation *!*//*!* Scrollbar styling for restore field list *!*/form{--step-size:2.5rem}.form-progress{padding:0 1rem}.form-progress .progress{background:var(--base-100);border-radius:var(--radius);padding:1rem}.form-progress .bar{height:6px;background:var(--base-200);border-radius:3px;overflow:hidden;margin-bottom:.5rem}.form-progress .fill{height:100%;background:linear-gradient(90deg,var(--action-0),var(--action-200));width:0%;transition:width .4s ease;border-radius:3px}.form-progress .step-text{font-size:var(--txt-small);font-weight:600;color:var(--contrast-200)}form nav.tabs{position:relative;top:0;left:0;right:0;padding:1rem 0;gap:0;z-index:0}form nav.tabs button{position:relative;background:0 0;border:none;padding:.5rem 1rem .5rem 3rem;z-index:1}form nav.tabs .step-number{width:2.5rem;height:100%;border-radius:50% 0 0 50%;position:absolute;left:0;top:0;background:var(--base-200);color:var(--contrast-50);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:var(--txt-small);border:3px solid var(--base)}form nav.tabs button.pending .step-number{background:var(--base-100);color:var(--contrast-200)}form nav.tabs button.active .step-number,form nav.tabs button.current .step-number{background:var(--action-0);color:var(--action-contrast);border-color:var(--action-200)}form nav.tabs button.completed .step-number{background:var(--successBack);color:var(--successBack);border-color:var(--successText)}form nav.tabs button.completed .step-number::before{content:'✓';font-size:1.2rem;color:var(--successText);position:absolute}form nav.tabs button.completed h2{color:var(--contrast-200)}.step-navigation{margin-top:2rem;padding-top:2rem;border-top:1px solid var(--base-200);gap:1rem}.step-navigation .prev-step{background:var(--base-100)}.step-navigation .next-step,.step-navigation button[type=submit]{margin-left:auto}.field input.error,.field select.error,.field textarea.error{border-color:var(--errorBack)}.error-message{color:var(--errorText);font-size:var(--txt-small);margin-top:.25rem;display:block}@media (max-width:768px){form nav.tabs button{min-width:80px;font-size:var(--txt-small)}form nav.tabs button h2{font-size:var(--txt-small)}form{--step-size:2rem}}.field-input-wrapper{position:relative;display:flex;align-items:center;gap:.5rem}.field-input-wrapper input,.field-input-wrapper select,.field-input-wrapper textarea{flex:1}.validation-icon{display:flex;align-items:center;justify-content:center;font-size:1.25rem;animation:scaleIn .3s ease;--w:1.25rem}.validation-icon.error{color:var(--error)}.validation-icon.success{color:var(--success)}@keyframes scaleIn{from{transform:scale(0);opacity:0}to{transform:scale(1);opacity:1}}.validation-message{color:var(--error-0);font-size:var(--txt-small);margin-top:.25rem;display:block;animation:slideDown .2s ease}@keyframes slideDown{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.field.has-error input,.field.has-error select,.field.has-error textarea{border-color:var(--error);background-color:var(--errorBack)}.field.has-error input:focus,.field.has-error select:focus,.field.has-error textarea:focus{outline-color:var(--error);box-shadow:0 0 0 3px rgba(var(--error-rgb),.2)}.field.has-success input,.field.has-success select,.field.has-success textarea{border-color:var(--success)}.field label .required{color:var(--error);margin-left:.25rem}.form-summary{padding:2rem;border-radius:8px;margin-top:2rem;border:2px dashed var(--contrast-200)}.form-summary .message{margin-bottom:2rem}.form-summary .result+.result{position:relative;margin-top:1.5rem;padding-top:1.5rem}.form-summary .result+.result::before{position:absolute;top:0;left:16.5%;content:'';width:67%;height:1px;border-bottom:1px solid var(--base-200)}.form-summary h2{margin:1rem 0}.form-summary h4{background-color:var(--base-100);padding:.5rem 2rem;position:relative;left:-2rem;color:var(--contrast-200);font-size:.875rem;text-transform:uppercase;letter-spacing:.05em;margin-bottom:.75rem}.form-summary p{color:var(--text);margin:0}.group-summary,.repeater-summary{background:var(--base-100);padding:1rem;border-radius:4px;margin-top:.5rem}.repeater-row{margin-bottom:1rem}.repeater-row:last-child{margin-bottom:0}.ql-toolbar button{min-height:0;padding:.5rem}.success-message{color:var(--success);background-color:var(--successBack);border:1px solid var(--success);padding:.75rem 1rem;border-radius:var(--radius);margin-bottom:1rem;display:flex;align-items:center;gap:.5rem}.success-message .success-icon{width:1.25rem;height:1.25rem;flex-shrink:0}.success-box{background-color:var(--successBack);border:2px solid var(--success);padding:1.5rem;border-radius:var(--radius-outer);margin-bottom:1rem;text-align:center}.success-box h3{color:var(--success);margin-bottom:.5rem}.success-box p{margin:.5rem 0}.form-success{opacity:.9}.form-success .field:not(.form-success-message):not(.success-box){display:none}.form-success button[type=submit]{opacity:.6;pointer-events:none}.field-error input,.field-error select,.field-error textarea{border-color:var(--error)}.error-message{color:var(--error);font-size:var(--txt-small);margin-top:.25rem;display:block}.form-error{background-color:var(--errorBack);border:1px solid var(--error);padding:.75rem;border-radius:var(--radius);margin-bottom:1rem}.has-success input,.has-success select,.has-success textarea{border-color:var(--success)}.form-error{display:flex;align-items:center;gap:.5rem}.form-error .error-icon{width:1.25rem;height:1.25rem;flex-shrink:0}.autocomplete-dropdown{width:100%;background-color:var(--base-100);padding:.5rem;box-shadow:rgba(var(--base-rgb),var(--op-45)) var(--shdw)}.invite details{margin-bottom:1.5rem}.field.tag-list .tag-input-row{display:flex;gap:.5rem;align-items:flex-start;margin-bottom:1rem;flex-wrap:wrap}.field.tag-list .tag-input-row .field{flex:1;min-width:150px;margin:0}.field.tag-list .tag-input-row .add-tag-item{flex-shrink:0;white-space:nowrap;margin-top:calc(var(--txt-medium) + 1rem)}.field.tag-list .tag-items{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:1rem;min-height:2rem}.field.tag-list .tag-item{background:var(--base-200);padding:.4rem .75rem;border-radius:4px;display:inline-flex;align-items:center;gap:.5rem;font-size:.9rem;line-height:1.2}.field.tag-list .tag-item:hover{background:var(--base-100)}.field.tag-list .tag-label{max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.field.tag-list .remove-tag{min-height:0;padding:.25rem;color:var(--contrast);transition:transform .2s;box-shadow:none}.field.tag-list .remove-tag:hover{transform:scale(1.2)}@media (max-width:768px){.field.tag-list .tag-input-row{flex-direction:column;align-items:stretch}.field.tag-list .tag-input-row .field{min-width:100%}}
\ No newline at end of file
+input:is([type=date],[type=number],[type=text],[type=url],[type=email],[type=tel],[type=password],[type=search],[type=datetime-local],[type=time]),textarea{font-family:var(--body);font-size:var(--txt-medium);color:var(--contrast);padding:var(--p-y) var(--p-x);border-radius:var(--radius);background-color:var(--base);outline:0;border:1px solid var(--base-100);border-bottom:2px solid var(--contrast-200);width:100%;max-width:100%;margin:0 4px}input:is([type=date],[type=number],[type=text],[type=url],[type=email],[type=tel],[type=password],[type=search],[type=datetime-local],[type=time]):focus,textarea:focus{outline:var(--action-50);background-color:var(--base-100);color:var(--contrast)}input::placeholder,textarea::placeholder{font-family:var(--body);color:var(--base-200)}@media (min-width:768px){:root{--p-y:1rem}}select{background:var(--base);border:2px solid var(--base-100);border-radius:var(--radius);color:var(--contrast);cursor:pointer;font-family:var(--body);font-size:var(--txt-small);padding:.5rem 1rem;width:100%}select:disabled{background-color:var(--base-50);border-color:var(--base-100);color:var(--base-200);cursor:not-allowed}select option{background:var(--base);color:var(--contrast);padding:.5rem}select option:active,select option:checked,select option:focus,select option:hover{background:var(--action-0);color:var(--base);box-shadow:0 0 0 100px var(--action-0) inset}select option:checked{background:var(--action-0) linear-gradient(0deg,var(--action-0) 0,var(--action-0) 100%);color:var(--base)}select:hover{border-color:var(--action-0)}select:focus{border-color:var(--action-0)}input[type=search]:focus+.clear-search{opacity:1;cursor:pointer}.search-container .clear-search{opacity:0;cursor:default}.search-container .icon.search{padding:4px 8px;color:var(--contrast-200);--w:3rem}input[type=search]::-moz-search-clear-button,input[type=search]::-ms-clear,input[type=search]::-ms-reveal,input[type=search]::search-cancel-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;display:none;visibility:hidden}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration,input[type=search]::-webkit-search-results-button,input[type=search]::-webkit-search-results-decoration{-webkit-appearance:none}input[type=url]{background:var(--linkIcon);background-position:.5em;background-size:1em;background-repeat:no-repeat;padding-left:2em}.integration .label,label{text-transform:uppercase;font-weight:700;margin-bottom:.5rem;display:block}.field{margin:2rem 0;position:relative}.field:has(.has-tooltip) label{margin-left:2rem}legend{padding:0 1rem}.date-wrapper{position:relative;display:inline-block}input[type=date]{padding:8px 36px 8px 8px;border-radius:4px}input[type=date]::-webkit-calendar-picker-indicator{opacity:0;width:100%;height:100%;position:absolute;top:0;left:0;cursor:pointer}input[type=date]+.icon{--w:20px;position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none}input:is([type=time],[type=datetime-local],[type=date]){padding:.5rem;border:1px solid var(--contrast-200);border-radius:4px;font-size:14px;min-width:180px;background:var(--base);color:var(--contrast);cursor:pointer}.date-wrapper input[type=date]:focus,.datetime-wrapper input[type=datetime-local]:focus,.field-input-wrapper input:is([type=time],[type=datetime-local],[type=date]):focus,.time-wrapper input[type=time]:focus{border-color:var(--action-0);box-shadow:0 0 0 2px rgba(var(--action-rgb),.1)}.date-wrapper .icon,.datetime-wrapper .icon,.field-input-wrapper .icon,.time-wrapper .icon{width:18px;height:18px;background-color:var(--contrast);opacity:.7}[type=checkbox],[type=radio],input.ch{position:absolute;opacity:0;left:-200vw}[type=checkbox]+label,[type=radio]+label,input.ch+label{position:relative;cursor:pointer}[type=checkbox]+label:hover,[type=radio]+label:hover{color:var(--action-0)}[type=checkbox]+label::after,[type=checkbox]+label::before,[type=radio]+label::after,[type=radio]+label::before,input.ch+label::after,input.ch+label::before{content:'';position:absolute;top:50%}[type=checkbox]+label::after,[type=radio]+label::after,input.ch+label::after{left:5px;transform:translateY(-70%) rotate(45deg);width:5px;height:10px;border:solid var(--light-0);border-width:0 2px 2px 0;display:none}[type=checkbox]+label::before,[type=radio]+label::before,input.ch+label::before{left:0;transform:translateY(-50%);width:1rem;height:1rem;border:2px solid var(--contrast-200);background-color:var(--base);border-radius:var(--radius)}[type=checkbox]:hover+label::before,[type=radio]:hover+label::before,input.ch:hover+label::before{border-color:var(--action-200)}[type=checkbox]:checked+label::before,[type=radio]:checked+label::before,input.ch:checked+label::before{background-color:var(--action-0);border-color:var(--action-100)}[type=radio]:checked+label::before{border-radius:50%}[type=checkbox]:checked+label::after,input.ch:checked+label::after{display:block;left:5px;top:50%;transform:translateY(-70%) rotate(45deg);width:.35rem;height:.66rem;border:solid var(--light-0);border-width:0 2px 2px 0}[type=checkbox]:disabled+label,[type=radio]:disabled+label,input.ch:disabled+label{cursor:not-allowed;background-color:var(--base-50);color:var(--base-200);border-color:var(--base-200)}[type=checkbox]:disabled+label:hover,[type=radio]:disabled+label:hover,input.ch:disabled+label:hover{background-color:var(--base-50);color:var(--base-200);border-color:var(--base-200)}[type=checkbox]:disabled+label::before,[type=radio]:disabled+label::before,input.ch:disabled+label::before{border-color:var(--base-200)}[type=checkbox]:not(.btn)+label,[type=radio]:not(.btn)+label,input.ch+label{flex:1;padding-left:2rem;transform-origin:top center;will-change:transform}.btn+label::after,.btn+label::before{display:none}.btn+label{--w:1.2em;border:1px solid var(--base-200);border-radius:var(--radius);min-width:2rem;min-height:2rem;margin:0;display:flex;justify-content:center;align-items:center;flex-wrap:nowrap;gap:.5rem;color:var(--contrast-200);opacity:.8}.radio-options.status label{padding:0 .5rem}.btn:checked+label{border-color:var(--contrast);color:var(--contrast);opacity:1}.btn+label:hover{color:var(--action-50);border-color:var(--action-50)}.btn[hidden]+label,input[hidden]+label{display:none!important}.checkbox-options{--gap:.5rem 2rem}.checkbox-options label{flex:unset!important}.radio-options{--gap:.125rem .5rem}.radio-options input:not(.ch)+label::before{display:none!important}.radio-options input:not(.ch)+label{flex:unset!important;padding:.25rem!important;border-radius:4px;border:1px solid var(--base-100);color:var(--contrast-200);font-weight:400;text-align:center}.radio-options input:not(.ch)+label:hover,.radio-options input:not(.ch):checked+label{border-color:var(--action-0);color:var(--action-0)}.quantity{margin:0;display:inline-flex;width:fit-content;align-items:center;justify-content:center;border:1px solid transparent;border-radius:4px;position:relative}.quantity:focus-within{border-color:var(--action-0)}.quantity label{margin:0;font-size:var(--txt-small)}.quantity button{background:var(--base);padding:0;width:var(--chip_);height:var(--chip_);min-height:0;z-index:0;position:relative;border:1px solid var(--base-200);color:var(--contrast-200)}.quantity button:hover:not(:disabled){color:var(--action-0);border-color:var(--action-0);background-color:var(--base)}.quantity button:active:not(:disabled){background-color:var(--action-0);color:var(--light-0);transform:scale(.95)}.quantity button:disabled{opacity:.5;cursor:not-allowed}.quantity input[type=number]{z-index:1;border:1px solid var(--base-200);background:var(--base);text-align:center;font-size:1.1rem;width:60px;height:48px;margin:0;padding:0!important;appearance:textfield}.quantity input[type=number]::-webkit-inner-spin-button,.quantity input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.quantity input[type=number]:focus{background-color:var(--base-50)}.quantity button.increase{left:-2px;border-radius:0 4px 4px 0}.quantity button.decrease{right:-2px;border-radius:4px 0 0 4px}.tab-content[hidden]{display:block!important;transform:scaleY(0);height:0;overflow:hidden}.tab-content[hidden]:focus-within{transform:scaleY(1);height:auto}nav.tabs h2{margin:0!important;line-height:1;font-size:var(--txt-medium);display:flex;color:var(--contrast);white-space:nowrap;gap:1rem}nav.tabs .active h2{color:var(--action-contrast)}nav.tabs button{padding:.75rem 1.5rem;border-radius:0;position:relative;border:2px solid var(--action-0)}nav.tabs>button:first-of-type{border-top-left-radius:var(--radius)}nav.tabs>button:last-of-type{border-top-right-radius:var(--radius)}.tabs>button:focus,.tabs>button:hover{background-color:var(--base-200)}.tabs>button::after{content:'';position:absolute;bottom:-2px;left:0;width:0;height:3px;background-color:var(--action-50);transition:width .3s}.tabs>button.active::after,.tabs>button:hover::after{width:100%}.tabs>button.active::after{background-color:var(--action-200)}.tabs>button.active{background-color:var(--action-0);color:var(--action-contrast)}.tabs>button.active:focus,.tabs>button.active:hover{background-color:var(--action-100)}.tab-content h2{display:none}details.uploader .file-upload-container{margin:1rem 0;max-width:100%}@media (min-width:768px){details.uploader .file-upload-container{margin:1rem var(--mr) 1rem var(--ml);max-width:var(--content)}}.empty-group,.file-upload-wrapper{border:2px dashed var(--action-0);border-radius:4px;padding:2rem;text-align:center;transition:all .3s ease;background:rgba(var(--action-rgb),var(--op-1));position:relative;cursor:pointer}.file-upload-wrapper h2{margin:0!important;font-size:var(--txt-large)}.dragover,.empty-group,.file-upload-wrapper:hover{background:rgba(var(--action-rgb),var(--op-2));border-color:var(--action-0)!important}.file-upload-wrapper input[type=file]{position:absolute;left:0;top:0;width:100%;height:100%;opacity:0;cursor:pointer}.empty-group p,.file-upload-text{color:var(--contrast);margin:0}.empty-group p strong,.file-upload-text strong{color:var(--action-0);text-decoration:underline}.field.upload{position:relative}.field.upload:not(.uploading) .progress{display:none}.field.upload .actions{position:absolute;top:0;right:0}.item-grid.groups{grid-template-columns:repeat(1,1fr)}.item-grid.group{margin-bottom:0}.item-grid.group .item,.item-grid.preview .item,.item-grid.restore .item{display:block}.item-grid.group button,.item-grid.preview button,.item-grid.restore button{padding:.25rem .5rem}.item-grid.group button .icon,.item-grid.preview button .icon,.item-grid.restore button .icon{--w:1.1em}.item-grid.group .item .preview>input[type=checkbox]:not(.label-button)+label,.item-grid.preview .item .preview>input[type=checkbox]:not(.label-button)+label,.item-grid.restore .item .preview>input[type=checkbox]:not(.label-button)+label{padding-left:0;margin:0}.item-grid.group .item .preview>input[type=checkbox]+label:before,.item-grid.preview .item .preview>input[type=checkbox]+label:before,.item-grid.restore .item .preview>input[type=checkbox]+label:before{transform:unset;top:.5rem;left:.5rem}.item-grid.group .item .preview>input[type=checkbox]+label::after,.item-grid.preview .item .preview>input[type=checkbox]+label::after,.item-grid.restore .item .preview>input[type=checkbox]+label::after{top:.5rem;left:.75rem;transform:translateY(20%) rotate(45deg)}.item-grid.group .item .item-actions,.item-grid.preview .item .item-actions,.item-grid.restore .item .item-actions{position:absolute;top:0;right:0;padding-left:var(--chipchip)}.item-grid.group summary,.item-grid.preview summary,.item-grid.restore summary{padding:.5rem}.item-grid.group:has([type=checkbox]:checked),.item-grid.preview:has([type=checkbox]:checked),.item-grid.restore:has([type=checkbox]:checked){padding:1rem;background-color:rgba(var(--contrast-rgb),var(--op-1))}.item-grid.group:has([type=checkbox]:checked) .item,.item-grid.preview:has([type=checkbox]:checked) .item,.item-grid.restore:has([type=checkbox]:checked) .item{padding:.75rem;opacity:.8}.item-grid.group:has([type=checkbox]:checked) .item img,.item-grid.preview:has([type=checkbox]:checked) .item img,.item-grid.restore:has([type=checkbox]:checked) .item img{filter:var(--filter)}.item-grid.group:has([type=checkbox]:checked) details,.item-grid.preview:has([type=checkbox]:checked) details,.item-grid.restore:has([type=checkbox]:checked) details{display:none}.item-grid.group .item:has([type=checkbox]:checked),.item-grid.preview .item:has([type=checkbox]:checked),.item-grid.restore .item:has([type=checkbox]:checked){padding:.5rem;background-color:rgba(var(--action-rgb),var(--op-4));opacity:1}.item-grid.preview summary span{display:none}.item-grid.group .item:has([type=checkbox]:checked) img,.item-grid.preview .item:has([type=checkbox]:checked) img,.item-grid.restore .item:has([type=checkbox]:checked) img{filter:none}[type=radio].featured+label .icon-star-fi,[type=radio].featured:checked+label .icon-star{display:none}[type=radio].featured+label .icon-star,[type=radio].featured:checked+label .icon-star-fi{display:inline-block}.restore.restore.item,.upload.upload.item{border-radius:var(--radius);aspect-ratio:unset;overflow:hidden;background:var(--base);border:1px solid var(--base-200)}.restore-item [for=select-item],.upload.item [for=select-item]{aspect-ratio:1}.upload.item:has(details[open]){grid-column:1/-1}.restore.item img,.upload.item img{transition:transform var(--trans-base)}.restore.item:hover img,.upload.item:hover img{transform:scale(1.02);transition:transform var(--trans-base)}.upload-group{background-image:var(--dashed-action);padding:5px;border-radius:var(--radius);background-color:rgba(var(--action-rgb),var(--op-1))}.upload-group .selected .field{margin:0}.upload-group .selection-actions button{aspect-ratio:unset}.submit-uploads{position:fixed;bottom:0;right:var(--btn_);z-index:var(--z-6);height:var(--btn);box-shadow:rgba(var(--base-rgb),var(--op-45)) var(--shdw);border-radius:var(--radius);animation:pulse-color 5s infinite;animation-delay:1s;background-color:var(--action-0);color:var(--action-contrast)}.submit-uploads:hover{background-color:var(--base-200);color:var(--contrast-200)}.empty-group{order:-1;grid-column:1/-1;padding:20px;background-image:var(--dashed-action);border-radius:var(--radius);margin:10px 0;cursor:pointer;transition:all var(--trans-base);text-align:center;background-color:rgba(var(--action-rgb),var(--op-1))}.group-display:not([hidden])~.file-upload-container{display:none}.dragging,.upload.item.dragging{opacity:.7;transform:scale(.95) rotate(3deg);z-index:var(--z-7);box-shadow:0 8px 25px rgba(0,0,0,.3)}.dragover{background:rgba(var(--action-rgb),var(--op-3))!important;border-color:var(--action-0)!important;transform:scale(1.05);animation:drop-pulse .8s infinite ease-in-out}.drag-preview{position:fixed;z-index:var(--z-9);width:fit-content;overflow:visible;pointer-events:none;opacity:.9;transform:scale(1.05);transition:transform .2s ease}.drag-preview .drag-items{width:max-content;height:max-content;position:relative}.drag-preview .drag-items .drag-item{width:120px;height:120px;position:absolute;top:0;left:0;background:var(--base);border-radius:var(--radius-outer);box-shadow:rgba(var(--base-rgb),var(--op-45)) var(--shdw)}.drag-preview .drag-items .drag-item:nth-child(1){transform:rotate(-3deg);z-index:3}.drag-preview .drag-items .drag-item:nth-child(2){left:8px;top:-4px;transform:rotate(4deg);z-index:2;transition-delay:30ms}.drag-preview .drag-items .drag-item:nth-child(3){left:-6px;top:-8px;transform:rotate(-5deg);z-index:1;transition-delay:60ms}.drag-preview .drag-items .drag-item:nth-child(4){left:12px;top:-12px;transform:rotate(3deg);z-index:0;transition-delay:90ms}.drag-preview .drag-items .drag-item:nth-child(n+5){left:-10px;top:-16px;transform:rotate(-4deg);z-index:0;opacity:.8}.drag-preview .drag-items img,.drag-preview .drag-items video{width:100%;height:100%;object-fit:cover;display:block}.drag-preview .drag-count{position:absolute;top:-8px;right:-8px;background:var(--base-200);color:var(--contrast);border-radius:50%;width:24px;height:24px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;box-shadow:rgba(var(--base-rgb),var(--op-45)) var(--shdw);z-index:var(--z-3)}.item.dragging{opacity:.5;transform:scale(.95);filter:grayscale(50%);transition:opacity .2s ease,transform .2s ease,filter .2s ease}@keyframes drop-pulse{0%,100%{background-color:rgba(var(--action-rgb),var(--op-3));transform:scale(1.02)}50%{background-color:var(rgba(var(--action-rgb),var(--op-4)));transform:scale(1.04)}}.selection-actions{display:flex;gap:.25rem}@media (max-width:767px){body:not(.uploading):has(.group-display:not([hidden])){overflow:hidden}body:not(.uploading):has(.group-display:not([hidden])) .qtoggle{z-index:var(--z-1)}.group-display.group-display{position:fixed;top:var(--btn);bottom:var(--btn);left:0;right:0;max-height:var(--maxHeight);overflow:hidden;z-index:var(--z-6);width:calc(100% - 1rem);height:calc(100% - 1rem);padding:0 0 3rem;--justify:flex-start;--align:flex-start;--gap:0}.group-display::before{content:'';display:block;z-index:-1;top:-.5rem;bottom:-.5rem;left:-.5rem;right:-.5rem;position:absolute;background-color:rgba(var(--base-rgb),var(--op-6));filter:blur(5px)}.group-display .preview-wrap,.group-display .sidebar{--wrap:nowrap;height:50%;overflow:hidden auto;position:relative;padding:.5rem}.group-display .preview-wrap{top:0}.group-display .preview-wrap .selected{display:flex;justify-content:space-between;align-items:center}.group-display .sidebar{bottom:0;flex-wrap:nowrap;overflow:hidden auto;background-color:var(--contrast-200);color:var(--base)}.group-display .sidebar>.hint{color:var(--contrast)}.group-display .sidebar .header{display:none}.group-display .preview-actions{top:0;flex-shrink:0}.group-display .preview-wrap>.hint,.group-display .sidebar>.hint{bottom:0;margin:0;text-align:center}.group-display .preview-actions,.group-display .preview-wrap>.hint,.group-display .sidebar>.hint{position:absolute;left:0;right:0;background-color:rgba(var(--base-rgb),var(--op-6));z-index:var(--z-3);box-shadow:rgba(var(--base-rgb),var(--op-45)) var(--shdw)}.group-display .item-grid{height:100%;overflow:hidden auto;grid-template-columns:repeat(3,1fr);padding:2rem 0}.group-display .sidebar>.item-grid{grid-template-columns:repeat(1,1fr);gap:1rem;padding:0}.group-display .sidebar .empty-group{order:0;position:sticky;height:fit-content;top:0;z-index:var(--z-3);background-color:rgba(var(--action-rgb),var(--op-6))}.group-display .sidebar .upload-group{order:1}.group-display .sidebar .empty-group p{margin:0}.group-display .field,.group-display .field label{margin:0;padding:0}.group-display .sidebar h4{margin:.25rem}.group-display .item{width:100%;height:max-content}.submit-uploads{bottom:var(--btn);left:0;right:0;width:100%;height:3rem}body.uploading .group-display.group-display{position:relative;top:unset;bottom:unset;right:unset;left:unset}}@media (min-width:768px){.group-display.group-display{--wrap:nowrap;--dir:row;--gap:1rem;--align:flex-start}.group-display .preview-wrap,.group-display .sidebar{--justify:flex-start;--wrap:nowrap;max-height:calc(100vh - var(--btnbtn));overflow:hidden auto}.group-display .preview-wrap,.group-display .sidebar{width:50%}.preview-actions,.preview-wrap .hint{position:sticky;z-index:var(--z-3);box-shadow:rgba(var(--base-rgb),var(--op-45)) var(--shdw);background-color:var(--base);width:100%}.preview-actions{top:0;left:0;right:0}.preview-actions .field{margin:0}.preview-wrap .hint,.sidebar>.hint{bottom:-1rem;padding-bottom:1rem;margin:0;left:0;right:0;text-align:center}}.item-grid.restore{grid-template-columns:repeat(1,1fr)}dialog nav.tabs{position:sticky;top:0;background-color:var(--base-50);z-index:var(--z-6);box-shadow:rgba(var(--base-rgb),var(--op-45)) var(--shdw-down);margin-bottom:2rem}.editor-container .ql-toolbar{display:flex;background-color:var(--base-50);justify-content:flex-start;flex-wrap:wrap;padding:.25rem;gap:.5rem 1rem;border-top-left-radius:var(--radius);border-top-right-radius:var(--radius);border-bottom:4px solid var(--base-50)}.ql-toolbar .ql-formats{display:flex;gap:.25rem}.editor-container .ql-container{--padding:1rem;background-color:var(--base);border-bottom-left-radius:var(--radius);border-bottom-right-radius:var(--radius);height:fit-content;padding:2px;border:1px solid var(--base-200)}.editor-container .ql-container .ql-editor{padding:var(--padding);width:100%;height:100%}.ql-editor img{max-width:50%;height:auto}.ql-clipboard{left:-100000px;height:1px;overflow-y:hidden;position:absolute;top:50%}.ql-hidden{display:none}.ql-tooltip{position:absolute;transform:translateY(10px);background-color:var(--base-100);border:1px solid var(--base);box-shadow:0 0 5px rgba(var(--base-rgb),var(--op-6));color:var(--contrast);padding:5px 12px;white-space:nowrap}[data-type=single] .item-grid{display:flex}.repeater-row details summary::after{margin-left:0}.repeater-row details summary button{margin-left:auto}/*!* Group actions buttons - more visible *!*//*!* Group item grid - distinct from preview grid *!*//*!* Group count hint *!*//*!* ============================================================================*//*!* Base drag preview *!*//*!* Single item drag preview *!*//*!* Multi-item drag preview container *!*//*!* Items being dragged - reduce opacity on originals *!*//*!* Count badge on multi-item preview *!*//*!* ============================================================================*//*!* Ensure progress bar is visible when needed *!*//*!* Progress bar track *!*//*!* Progress bar fill *!*//*!* Progress details - styled for row layout with text and count *!*//*!* Individual item progress - overlay style *!*//*!* Item progress icon and status text *!*//*!* ============================================================================*//*!* Hide uploader when we have uploads *!*//*!* Show group display when we have uploads *!*//*!* ============================================================================*//*!* Selected items - more obvious *!*//*!* Selection checkbox - always visible on hover or when checked *!*//*!* Selection controls - more prominent *!*//*!* ============================================================================*//*!* Smooth dragover animation *!*//*!* ============================================================================*//*!* ============================================================================*//*!* Notification container - fixed overlay *!*//*!* Content card *!*//*!* Message section *!*//*!* Scrollable field list *!*//*!* Item grid for restore preview *!*//*!* Restore item *!*//*!* Checked state *!*//*!* Preview section *!*//*!* Item info *!*//*!* Checkbox controls *!*//*!* Actions section *!*//*!* Selection controls *!*//*!* Action buttons *!*//*!* Restore button - primary action *!*//*!* Scrap cache button - destructive action *!*//*!* Dismiss button - secondary action *!*//*!* Mobile responsive *!*//*!* Animation *!*//*!* Scrollbar styling for restore field list *!*/form{--step-size:2.5rem}.form-progress{padding:0 1rem}.form-progress .progress{background:var(--base-100);border-radius:var(--radius);padding:1rem}.form-progress .bar{height:6px;background:var(--base-200);border-radius:3px;overflow:hidden;margin-bottom:.5rem}.form-progress .fill{height:100%;background:linear-gradient(90deg,var(--action-0),var(--action-200));width:0%;transition:width .4s ease;border-radius:3px}.form-progress .step-text{font-size:var(--txt-small);font-weight:600;color:var(--contrast-200)}form nav.tabs{position:relative;top:0;left:0;right:0;padding:1rem 0;gap:0;z-index:0}form nav.tabs button{position:relative;background:0 0;border:none;padding:.5rem 1rem .5rem 3rem;z-index:1}form nav.tabs .step-number{width:2.5rem;height:100%;border-radius:50% 0 0 50%;position:absolute;left:0;top:0;background:var(--base-200);color:var(--contrast-50);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:var(--txt-small);border:3px solid var(--base)}form nav.tabs button.pending .step-number{background:var(--base-100);color:var(--contrast-200)}form nav.tabs button.active .step-number,form nav.tabs button.current .step-number{background:var(--action-0);color:var(--action-contrast);border-color:var(--action-200)}form nav.tabs button.completed .step-number{background:var(--successBack);color:var(--successBack);border-color:var(--successText)}form nav.tabs button.completed .step-number::before{content:'✓';font-size:1.2rem;color:var(--successText);position:absolute}form nav.tabs button.completed h2{color:var(--contrast-200)}.step-navigation{margin-top:2rem;padding-top:2rem;border-top:1px solid var(--base-200);gap:1rem}.step-navigation .prev-step{background:var(--base-100)}.step-navigation .next-step,.step-navigation button[type=submit]{margin-left:auto}.field input.error,.field select.error,.field textarea.error{border-color:var(--errorBack)}.error-message{color:var(--errorText);font-size:var(--txt-small);margin-top:.25rem;display:block}@media (max-width:768px){form nav.tabs button{min-width:80px;font-size:var(--txt-small)}form nav.tabs button h2{font-size:var(--txt-small)}form{--step-size:2rem}}.field-input-wrapper{position:relative;display:flex;align-items:center;gap:.5rem}.field-input-wrapper input,.field-input-wrapper select,.field-input-wrapper textarea{flex:1}.validation-icon{display:flex;align-items:center;justify-content:center;font-size:1.25rem;animation:scaleIn .3s ease;--w:1.25rem}.validation-icon.error{color:var(--error)}.validation-icon.success{color:var(--success)}@keyframes scaleIn{from{transform:scale(0);opacity:0}to{transform:scale(1);opacity:1}}.validation-message{color:var(--error-0);font-size:var(--txt-small);margin-top:.25rem;display:block;animation:slideDown .2s ease}@keyframes slideDown{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.field.has-error input,.field.has-error select,.field.has-error textarea{border-color:var(--error);background-color:var(--errorBack)}.field.has-error input:focus,.field.has-error select:focus,.field.has-error textarea:focus{outline-color:var(--error);box-shadow:0 0 0 3px rgba(var(--error-rgb),.2)}.field.has-success input,.field.has-success select,.field.has-success textarea{border-color:var(--success)}.field label .required{color:var(--error);margin-left:.25rem}.form-summary{padding:2rem;border-radius:8px;margin-top:2rem;border:2px dashed var(--contrast-200)}.form-summary .message{margin-bottom:2rem}.form-summary .result+.result{position:relative;margin-top:1.5rem;padding-top:1.5rem}.form-summary .result+.result::before{position:absolute;top:0;left:16.5%;content:'';width:67%;height:1px;border-bottom:1px solid var(--base-200)}.form-summary h2{margin:1rem 0}.form-summary h4{background-color:var(--base-100);padding:.5rem 2rem;position:relative;left:-2rem;color:var(--contrast-200);font-size:.875rem;text-transform:uppercase;letter-spacing:.05em;margin-bottom:.75rem}.form-summary p{color:var(--text);margin:0}.group-summary,.repeater-summary{background:var(--base-100);padding:1rem;border-radius:4px;margin-top:.5rem}.repeater-row{margin-bottom:1rem}.repeater-row:last-child{margin-bottom:0}.ql-toolbar button{min-height:0;padding:.5rem}.success-message{color:var(--success);background-color:var(--successBack);border:1px solid var(--success);padding:.75rem 1rem;border-radius:var(--radius);margin-bottom:1rem;display:flex;align-items:center;gap:.5rem}.success-message .success-icon{width:1.25rem;height:1.25rem;flex-shrink:0}.success-box{background-color:var(--successBack);border:2px solid var(--success);padding:1.5rem;border-radius:var(--radius-outer);margin-bottom:1rem;text-align:center}.success-box h3{color:var(--success);margin-bottom:.5rem}.success-box p{margin:.5rem 0}.form-success{opacity:.9}.form-success .field:not(.form-success-message):not(.success-box){display:none}.form-success button[type=submit]{opacity:.6;pointer-events:none}.field-error input,.field-error select,.field-error textarea{border-color:var(--error)}.error-message{color:var(--error);font-size:var(--txt-small);margin-top:.25rem;display:block}.form-error{background-color:var(--errorBack);border:1px solid var(--error);padding:.75rem;border-radius:var(--radius);margin-bottom:1rem}.has-success input,.has-success select,.has-success textarea{border-color:var(--success)}.form-error{display:flex;align-items:center;gap:.5rem}.form-error .error-icon{width:1.25rem;height:1.25rem;flex-shrink:0}.invite details{margin-bottom:1.5rem}.field.tag-list .tag-input-row{display:flex;gap:.5rem;align-items:flex-start;margin-bottom:1rem;flex-wrap:wrap}.field.tag-list .tag-input-row .field{flex:1;min-width:150px;margin:0}.field.tag-list .tag-input-row .add-tag-item{flex-shrink:0;white-space:nowrap;margin-top:calc(var(--txt-medium) + 1rem)}.field.tag-list .tag-items{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:1rem;min-height:2rem}.field.tag-list .tag-item{background:var(--base-200);padding:.4rem .75rem;border-radius:4px;display:inline-flex;align-items:center;gap:.5rem;font-size:.9rem;line-height:1.2}.field.tag-list .tag-item:hover{background:var(--base-100)}.field.tag-list .tag-label{max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.field.tag-list .remove-tag{min-height:0;padding:.25rem;color:var(--contrast);transition:transform .2s;box-shadow:none}.field.tag-list .remove-tag:hover{transform:scale(1.2)}@media (max-width:768px){.field.tag-list .tag-input-row{flex-direction:column;align-items:stretch}.field.tag-list .tag-input-row .field{min-width:100%}}
\ No newline at end of file
diff --git a/assets/css/icons.css b/assets/css/icons.css
index 9df0057..b82cd88 100644
--- a/assets/css/icons.css
+++ b/assets/css/icons.css
@@ -1 +1 @@
-.icon-google-logo{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjIsMTI4YTk0LDk0LDAsMSwxLTIxLjQ5LTU5LjgyLDYsNiwwLDEsMS05LjI1LDcuNjRBODIsODIsMCwxLDAsMjA5Ljc4LDEzNEgxMjhhNiw2LDAsMCwxLDAtMTJoODhBNiw2LDAsMCwxLDIyMiwxMjhaIi8+PC9zdmc+');}.icon-apple-logo{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTkuNCwxNjcuODRDMjAxLjcxLDE1NS42OSwxOTgsMTM1LjEyLDE5OCwxMjBjMC0xOC40MiwxMy44Ni0zNC4yOSwyMi4xMi00Mi4xMmE2LDYsMCwwLDAsMC04LjcxQzIwOCw1Ny43LDE4Ny4wNyw1MCwxNjgsNTBhNzAuMjMsNzAuMjMsMCwwLDAtNDAsMTIuNTUsNjkuNiw2OS42LDAsMCwwLTg5LjMxLDguMDhBNzIuNjMsNzIuNjMsMCwwLDAsMTgsMTIzLjM1YTEyNS4xMSwxMjUuMTEsMCwwLDAsMzkuNTMsODguMzNBMzcuODUsMzcuODUsMCwwLDAsODMuNiwyMjJoODcuN0EzNy44MywzNy44MywwLDAsMCwxOTksMjEwLjA3YTEyMi42LDEyMi42LDAsMCwwLDE3LjU0LTI0LjJjNi41NS0xMiw1Ljc3LTEzLjc1LDUtMTUuNDhBNi4wNyw2LjA3LDAsMCwwLDIxOS40LDE2Ny44NFptLTI5LjIzLDM0QTI1LjgyLDI1LjgyLDAsMCwxLDE3MS4zLDIxMEg4My42QTI1Ljg1LDI1Ljg1LDAsMCwxLDY1Ljc4LDIwMywxMTMuMjEsMTEzLjIxLDAsMCwxLDMwLDEyM2E2MC41NSw2MC41NSwwLDAsMSwxNy4yMS00NEE1Ni44Miw1Ni44MiwwLDAsMSw4OCw2MmguODFhNTcuMzUsNTcuMzUsMCwwLDEsMzUuNDQsMTIuNzEsNiw2LDAsMCwwLDcuNSwwQTU3LjM5LDU3LjM5LDAsMCwxLDE2OCw2MmMxMy44OSwwLDI4LjgxLDQuNjgsMzkuMTEsMTItOS40NCwxMC4xNC0yMS4xLDI2LjU5LTIxLjEsNDYsMCwyMy43OCw3LjgxLDQyLjYsMjIuNjYsNTQuNzdBMTA3LjMzLDEwNy4zMywwLDAsMSwxOTAuMTcsMjAxLjg5Wm0tNjAtMTcxLjM5QTM4LDM4LDAsMCwxLDE2NywyaDFhNiw2LDAsMCwxLDAsMTJoLTFhMjYsMjYsMCwwLDAtMjUuMTgsMTkuNSw2LDYsMCwxLDEtMTEuNjItM1oiLz48L3N2Zz4=');}.icon-check-circle{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNzIuMjQsOTkuNzZhNiw2LDAsMCwxLDAsOC40OGwtNTYsNTZhNiw2LDAsMCwxLTguNDgsMGwtMjQtMjRhNiw2LDAsMCwxLDguNDgtOC40OEwxMTIsMTUxLjUxbDUxLjc2LTUxLjc1QTYsNiwwLDAsMSwxNzIuMjQsOTkuNzZaTTIzMCwxMjhBMTAyLDEwMiwwLDEsMSwxMjgsMjYsMTAyLjEyLDEwMi4xMiwwLDAsMSwyMzAsMTI4Wm0tMTIsMGE5MCw5MCwwLDEsMC05MCw5MEE5MC4xLDkwLjEsMCwwLDAsMjE4LDEyOFoiLz48L3N2Zz4=');}.icon-cloud-slash{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik01Mi40NCwzNkE2LDYsMCwwLDAsNDMuNTYsNDRsNDAuMTgsNDQuMmMtLjQ1Ljg3LS45LDEuNzUtMS4zMiwyLjY0QTYyLDYyLDAsMSwwLDcyLDIxNGg4OGE4NS4yMyw4NS4yMywwLDAsMCwzMi4zNS02LjNMMjAzLjU2LDIyMGE2LDYsMCwwLDAsOC44OC04LjA4Wk0xNjAsMjAySDcyYTUwLDUwLDAsMSwxLDUuOS05OS42NEE4Ni4yNSw4Ni4yNSwwLDAsMCw3NCwxMjhhNiw2LDAsMCwwLDEyLDAsNzMuOTIsNzMuOTIsMCwwLDEsNi40NC0zMC4ybDkxLjIyLDEwMC4zNEE3My42NSw3My42NSwwLDAsMSwxNjAsMjAyWm04Ni03NGE4NS44NSw4NS44NSwwLDAsMS0yMS44NSw1Ny4yNyw2LDYsMCwwLDEtNC40NywyLDYsNiwwLDAsMS00LjQ3LTEwLDc0LDc0LDAsMCwwLTk5LTEwOC45Miw2LDYsMCwxLDEtNy4xMS05LjY3QTg2LDg2LDAsMCwxLDI0NiwxMjhaIi8+PC9zdmc+');}.icon-exclamation-mark{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNDIsMjAwYTE0LDE0LDAsMSwxLTE0LTE0QTE0LDE0LDAsMCwxLDE0MiwyMDBabS0xNC00MmE2LDYsMCwwLDAsNi02VjQ4YTYsNiwwLDAsMC0xMiwwVjE1MkE2LDYsMCwwLDAsMTI4LDE1OFoiLz48L3N2Zz4=');}.icon-cloud-arrow-down{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yNDYsMTI4YTg1LjI3LDg1LjI3LDAsMCwxLTE3LjIsNTEuNiw2LDYsMCwxLDEtOS42LTcuMkE3NCw3NCwwLDEsMCw4NiwxMjhhNiw2LDAsMCwxLTEyLDAsODUuNTQsODUuNTQsMCwwLDEsMy45MS0yNS42NEE1MC42OCw1MC42OCwwLDAsMCw3MiwxMDJhNTAsNTAsMCwwLDAsMCwxMDBIOTZhNiw2LDAsMCwxLDAsMTJINzJBNjIsNjIsMCwxLDEsODIuNDMsOTAuODgsODYsODYsMCwwLDEsMjQ2LDEyOFptLTY2LjI0LDQzLjc2TDE1OCwxOTMuNTFWMTI4YTYsNiwwLDAsMC0xMiwwdjY1LjUxbC0yMS43Ni0yMS43NWE2LDYsMCwwLDAtOC40OCw4LjQ4bDMyLDMyYTYsNiwwLDAsMCw4LjQ4LDBsMzItMzJhNiw2LDAsMCwwLTguNDgtOC40OFoiLz48L3N2Zz4=');}.icon-caret-down{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTIuMjQsMTAwLjI0bC04MCw4MGE2LDYsMCwwLDEtOC40OCwwbC04MC04MGE2LDYsMCwwLDEsOC40OC04LjQ4TDEyOCwxNjcuNTFsNzUuNzYtNzUuNzVhNiw2LDAsMCwxLDguNDgsOC40OFoiLz48L3N2Zz4=');}.icon-cloud-arrow-up{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xODguMjQsMTY0LjI0YTYsNiwwLDAsMS04LjQ4LDBMMTU4LDE0Mi40OVYyMDhhNiw2LDAsMCwxLTEyLDBWMTQyLjQ5bC0yMS43NiwyMS43NWE2LDYsMCwwLDEtOC40OC04LjQ4bDMyLTMyYTYsNiwwLDAsMSw4LjQ4LDBsMzIsMzJBNiw2LDAsMCwxLDE4OC4yNCwxNjQuMjRaTTE2MCw0MkE4Ni4xLDg2LjEsMCwwLDAsODIuNDMsOTAuODgsNjIsNjIsMCwxLDAsNzIsMjE0aDQwYTYsNiwwLDAsMCwwLTEySDcyYTUwLDUwLDAsMCwxLDAtMTAwLDUwLjY4LDUwLjY4LDAsMCwxLDUuOTEuMzZBODUuNTQsODUuNTQsMCwwLDAsNzQsMTI4YTYsNiwwLDAsMCwxMiwwLDc0LDc0LDAsMSwxLDEwMy42LDY3Ljg1LDYsNiwwLDAsMCw0LjgsMTFBODYsODYsMCwwLDAsMTYwLDQyWiIvPjwvc3ZnPg==');}.icon-cloud-check{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjAsNDJBODYuMTEsODYuMTEsMCwwLDAsODIuNDMsOTAuODgsNjIsNjIsMCwxLDAsNzIsMjE0aDg4YTg2LDg2LDAsMCwwLDAtMTcyWm0wLDE2MEg3MmE1MCw1MCwwLDAsMSwwLTEwMCw1MC42Nyw1MC42NywwLDAsMSw1LjkxLjM1QTg1LjYxLDg1LjYxLDAsMCwwLDc0LDEyOGE2LDYsMCwwLDAsMTIsMCw3NCw3NCwwLDEsMSw3NCw3NFptMzYuMjQtOTQuMjRhNiw2LDAsMCwxLDAsOC40OGwtNDgsNDhhNiw2LDAsMCwxLTguNDgsMGwtMjQtMjRhNiw2LDAsMCwxLDguNDgtOC40OEwxNDQsMTUxLjUxbDQzLjc2LTQzLjc1QTYsNiwwLDAsMSwxOTYuMjQsMTA3Ljc2WiIvPjwvc3ZnPg==');}.icon-cloud-warning{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjAsNDJBODYuMTEsODYuMTEsMCwwLDAsODIuNDMsOTAuODgsNjIsNjIsMCwxLDAsNzIsMjE0aDg4YTg2LDg2LDAsMCwwLDAtMTcyWm0wLDE2MEg3MmE1MCw1MCwwLDAsMSwwLTEwMCw1MC42Nyw1MC42NywwLDAsMSw1LjkxLjM1QTg1LjYxLDg1LjYxLDAsMCwwLDc0LDEyOGE2LDYsMCwwLDAsMTIsMCw3NCw3NCwwLDEsMSw3NCw3NFptLTYtNzRWODhhNiw2LDAsMCwxLDEyLDB2NDBhNiw2LDAsMCwxLTEyLDBabTE2LDM2YTEwLDEwLDAsMSwxLTEwLTEwQTEwLDEwLDAsMCwxLDE3MCwxNjRaIi8+PC9zdmc+');}.icon-syncing{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0iY3VycmVudENvbG9yIiB2aWV3Qm94PSIwIDAgMjU2IDI1NiI+PHBhdGggaWQ9InJlZnJlc2giIGQ9Ik0xNjAuMDQ3IDEyMi44NzVhMzAuNzg0IDMwLjc4NCAwIDAgMC0yMS43NSA4Ljc5N2MtMi44NDIgMy4wMDMtLjQ2NyA0Ljk3MSAxLjMxMiAzLjE1NiAxMS4wNDMtMTAuNzg2IDI4LjcxLTEwLjY4IDM5LjYyNS4yMzRsNy4yMDMgNy4yMDRoLTEyLjg3NWMtMy4zNDcuMDA4LTMuMTY1IDMuODc1IDAgMy44NzVoMTYuMTFjMi4wNjIgMCAyLjU0LTEuNDE4IDIuNTYyLTQuOTdsLjA5NC0xNC45MjFjLjAyLTMuMjktMy40MzctMy4xNjUtMy40MzcgMHYxMi44NmwtNy4yMDMtNy4xODhhMzAuNzY4IDMwLjc2OCAwIDAgMC0yMS42NDEtOS4wNDd6bS0yOS41OTQgMzkuNzk3Yy0yLjA2MiAwLTIuNTI0IDEuNDAyLTIuNTQ3IDQuOTUzbC0uMDk0IDE0LjkyMmMtLjAyIDMuMjkgMy40MjIgMy4xNjQgMy40MjIgMHYtMTIuODZsNy4yMDMgNy4yMDRjMTEuOTU2IDExLjk1NSAzMS4zMTIgMTIuMDY0IDQzLjQwNy4yNSAyLjg0Mi0zLjAwMy40NTEtNC45ODgtMS4zMjgtMy4xNzItMTEuMDQzIDEwLjc4Ni0yOC43MSAxMC42OC0zOS42MjUtLjIzNWwtNy4xODgtNy4yMDNoMTIuODZjMy4zNDctLjAwOCAzLjE2NS0zLjg2IDAtMy44NmgtMTYuMTF6Ii8+PHBhdGggZD0iTTE2MCA0NGE4NC4xMSA4NC4xMSAwIDAgMC03Ni40MSA0OS4xMkE2MC43MSA2MC43MSAwIDAgMCA3MiA5MmE2MCA2MCAwIDAgMCAwIDEyMGg4OGE4NCA4NCAwIDAgMCAwLTE2OFptMCAxNjBINzJhNTIgNTIgMCAxIDEgOC41NS0xMDMuM0E4My42NiA4My42NiAwIDAgMCA3NiAxMjhhNCA0IDAgMCAwIDggMCA3NiA3NiAwIDEgMSA3NiA3NloiLz48L3N2Zz4=');}.icon-cloud-x{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjAsNDJBODYuMTEsODYuMTEsMCwwLDAsODIuNDMsOTAuODgsNjIsNjIsMCwxLDAsNzIsMjE0aDg4YTg2LDg2LDAsMCwwLDAtMTcyWm0wLDE2MEg3MmE1MCw1MCwwLDAsMSwwLTEwMCw1MC42Nyw1MC42NywwLDAsMSw1LjkxLjM1QTg1LjYxLDg1LjYxLDAsMCwwLDc0LDEyOGE2LDYsMCwwLDAsMTIsMCw3NCw3NCwwLDEsMSw3NCw3NFptMjguMjQtODUuNzZMMTY4LjQ4LDEzNmwxOS43NiwxOS43NmE2LDYsMCwxLDEtOC40OCw4LjQ4TDE2MCwxNDQuNDhsLTE5Ljc2LDE5Ljc2YTYsNiwwLDAsMS04LjQ4LTguNDhMMTUxLjUyLDEzNmwtMTkuNzYtMTkuNzZhNiw2LDAsMCwxLDguNDgtOC40OEwxNjAsMTI3LjUybDE5Ljc2LTE5Ljc2YTYsNiwwLDAsMSw4LjQ4LDguNDhaIi8+PC9zdmc+');}.icon-arrows-clockwise{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjIsNDhWOTZhNiw2LDAsMCwxLTYsNkgxNjhhNiw2LDAsMCwxLDAtMTJoMzMuNTJMMTgzLjQ3LDcyYTgxLjUxLDgxLjUxLDAsMCwwLTU3LjUzLTI0aC0uNDZBODEuNSw4MS41LDAsMCwwLDY4LjE5LDcxLjI4YTYsNiwwLDEsMS04LjM4LTguNTgsOTMuMzgsOTMuMzgsMCwwLDEsNjUuNjctMjYuNzZIMTI2YTkzLjQ1LDkzLjQ1LDAsMCwxLDY2LDI3LjUzbDE4LDE4VjQ4YTYsNiwwLDAsMSwxMiwwWk0xODcuODEsMTg0LjcyYTgxLjUsODEuNSwwLDAsMS01Ny4yOSwyMy4zNGgtLjQ2YTgxLjUxLDgxLjUxLDAsMCwxLTU3LjUzLTI0TDU0LjQ4LDE2Nkg4OGE2LDYsMCwwLDAsMC0xMkg0MGE2LDYsMCwwLDAtNiw2djQ4YTYsNiwwLDAsMCwxMiwwVjE3NC40OGwxOCwxOC4wNWE5My40NSw5My40NSwwLDAsMCw2NiwyNy41M2guNTJhOTMuMzgsOTMuMzgsMCwwLDAsNjUuNjctMjYuNzYsNiw2LDAsMSwwLTguMzgtOC41OFoiLz48L3N2Zz4=');}.icon-share-fat{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzYuMjQsMTA3Ljc2bC04MC04MEE2LDYsMCwwLDAsMTQ2LDMyVjc0LjJjLTU0LjQ4LDMuNTktMTIwLjM5LDU1LTEyNy45MywxMjAuNjZhMTAsMTAsMCwwLDAsMTcuMjMsOGgwQzQ2LjU2LDE5MC44NSw4NywxNTIuNiwxNDYsMTUwLjEzVjE5MmE2LDYsMCwwLDAsMTAuMjQsNC4yNGw4MC04MEE2LDYsMCwwLDAsMjM2LjI0LDEwNy43NlpNMTU4LDE3Ny41MlYxNDRhNiw2LDAsMCwwLTYtNmMtMjcuNzMsMC01NC43Niw3LjI1LTgwLjMyLDIxLjU1YTE5My4zOCwxOTMuMzgsMCwwLDAtNDAuODEsMzAuNjVjNC43LTI2LjU2LDIwLjE2LTUyLDQ0LTcyLjI3Qzk4LjQ3LDk3Ljk0LDEyNy4yOSw4NiwxNTIsODZhNiw2LDAsMCwwLDYtNlY0Ni40OUwyMjMuNTEsMTEyWiIvPjwvc3ZnPg==');}.icon-trash{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTYsNTBIMTc0VjQwYTIyLDIyLDAsMCwwLTIyLTIySDEwNEEyMiwyMiwwLDAsMCw4Miw0MFY1MEg0MGE2LDYsMCwwLDAsMCwxMkg1MFYyMDhhMTQsMTQsMCwwLDAsMTQsMTRIMTkyYTE0LDE0LDAsMCwwLDE0LTE0VjYyaDEwYTYsNiwwLDAsMCwwLTEyWk05NCw0MGExMCwxMCwwLDAsMSwxMC0xMGg0OGExMCwxMCwwLDAsMSwxMCwxMFY1MEg5NFpNMTk0LDIwOGEyLDIsMCwwLDEtMiwySDY0YTIsMiwwLDAsMS0yLTJWNjJIMTk0Wk0xMTAsMTA0djY0YTYsNiwwLDAsMS0xMiwwVjEwNGE2LDYsMCwwLDEsMTIsMFptNDgsMHY2NGE2LDYsMCwwLDEtMTIsMFYxMDRhNiw2LDAsMCwxLDEyLDBaIi8+PC9zdmc+');}.icon-star{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzcuMjgsOTcuODdBMTQuMTgsMTQuMTgsMCwwLDAsMjI0Ljc2LDg4bC02MC4yNS00Ljg3LTIzLjIyLTU2LjJhMTQuMzcsMTQuMzcsMCwwLDAtMjYuNTgsMEw5MS40OSw4My4xMSwzMS4yNCw4OGExNC4xOCwxNC4xOCwwLDAsMC0xMi41Miw5Ljg5QTE0LjQzLDE0LjQzLDAsMCwwLDIzLDExMy4zMkw2OSwxNTIuOTNsLTE0LDU5LjI1YTE0LjQsMTQuNCwwLDAsMCw1LjU5LDE1LDE0LjEsMTQuMSwwLDAsMCwxNS45MS42TDEyOCwxOTYuMTJsNTEuNTgsMzEuNzFhMTQuMSwxNC4xLDAsMCwwLDE1LjkxLS42LDE0LjQsMTQuNCwwLDAsMCw1LjU5LTE1bC0xNC01OS4yNUwyMzMsMTEzLjMyQTE0LjQzLDE0LjQzLDAsMCwwLDIzNy4yOCw5Ny44N1ptLTEyLjE0LDYuMzctNDguNjksNDJhNiw2LDAsMCwwLTEuOTIsNS45MmwxNC44OCw2Mi43OWEyLjM1LDIuMzUsMCwwLDEtLjk1LDIuNTcsMi4yNCwyLjI0LDAsMCwxLTIuNi4xTDEzMS4xNCwxODRhNiw2LDAsMCwwLTYuMjgsMEw3MC4xNCwyMTcuNjFhMi4yNCwyLjI0LDAsMCwxLTIuNi0uMSwyLjM1LDIuMzUsMCwwLDEtMS0yLjU3bDE0Ljg4LTYyLjc5YTYsNiwwLDAsMC0xLjkyLTUuOTJsLTQ4LjY5LTQyYTIuMzcsMi4zNywwLDAsMS0uNzMtMi42NSwyLjI4LDIuMjgsMCwwLDEsMi4wNy0xLjY1bDYzLjkyLTUuMTZhNiw2LDAsMCwwLDUuMDYtMy42OWwyNC42My01OS42YTIuMzUsMi4zNSwwLDAsMSw0LjM4LDBsMjQuNjMsNTkuNmE2LDYsMCwwLDAsNS4wNiwzLjY5bDYzLjkyLDUuMTZhMi4yOCwyLjI4LDAsMCwxLDIuMDcsMS42NUEyLjM3LDIuMzcsMCwwLDEsMjI1LjE0LDEwNC4yNFoiLz48L3N2Zz4=');}.icon-alphabetical{--icon:url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIGZpbGw9ImN1cnJlbnRDb2xvciIgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSIwIDAgMTgzLjc4IDE4NC4wNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNTkuNTg2IDY5Ljc0MmMtMC44NTEzIDAtMS40NjEgMC4xOTY1Ni0xLjgzNjYgMC41OTcxOC0wLjM1MDU0IDAuMzc1NTgtMC41Mjk1OCAxLjAyMjktMC41Mjk1OCAxLjk0OTNzMC4xNzkwMyAxLjU5MzcgMC41Mjk1OCAxLjk5NDRjMC4zNzU1OCAwLjM3NTU4IDAuOTg1MjkgMC41NjMzOCAxLjgzNjYgMC41NjMzOGg3LjAxOTdsLTEyLjQyOCAzNC4zNjZoLTIuMTA3Yy0wLjg1MTMgMC0xLjQ2MSAwLjE5NjU2LTEuODM2NiAwLjU5NzE4LTAuMzUwNTQgMC4zNzU1OC0wLjUyOTU3IDEuMDM0MS0wLjUyOTU3IDEuOTYwNiAwIDAuOTI2NDQgMC4xNzkwMyAxLjU4MjUgMC41Mjk1NyAxLjk4MyAwLjM3NTU4IDAuMzc1NTkgMC45ODUyOSAwLjU2MzM4IDEuODM2NiAwLjU2MzM4aDEyLjU1MmMwLjg1MTMgMCAxLjQ1MjItMC4xODc3OSAxLjgwMjgtMC41NjMzOCAwLjM3NTU4LTAuNDAwNjIgMC41NjMzNy0xLjA1NjYgMC41NjMzNy0xLjk4MyAwLTAuOTI2NDUtMC4xODc3OS0xLjU4NS0wLjU2MzM3LTEuOTYwNi0wLjM1MDU0LTAuNDAwNjItMC45NTE0Ny0wLjU5NzE4LTEuODAyOC0wLjU5NzE4aC00LjU1MjFsMy4xMjExLTguOTM0OWgxOC4yMmwzLjA3NiA4LjkzNDloLTUuMDcwNGMtMC44NTEzIDAtMS40NjEgMC4xOTY1Ni0xLjgzNjYgMC41OTcxOC0wLjM1MDU0IDAuMzc1NTgtMC41Mjk1OCAxLjAzNDEtMC41Mjk1OCAxLjk2MDYgMCAwLjkyNjQ0IDAuMTc5MDMgMS41ODI1IDAuNTI5NTggMS45ODMgMC4zNzU1OCAwLjM3NTU5IDAuOTg1MjkgMC41NjMzOCAxLjgzNjYgMC41NjMzOGgxMy4yOTZjMC44NTEzIDAgMS40NTIyLTAuMTg3NzkgMS44MDI4LTAuNTYzMzggMC4zNzU1OC0wLjQwMDYyIDAuNTYzMzctMS4wNTY2IDAuNTYzMzctMS45ODMgMC0wLjkyNjQ1LTAuMTg3NzktMS41ODUtMC41NjMzNy0xLjk2MDYtMC4zNTA1NC0wLjQwMDYyLTAuOTUxNDctMC41OTcxOC0xLjgwMjgtMC41OTcxOGgtMi4yODczbC0xMy4yNjItMzcuMDM2Yy0wLjMwMDQ3LTAuODUxMy0wLjc1OTk0LTEuNDYxLTEuMzg1OS0xLjgzNjYtMC42MDA5My0wLjQwMDYyLTEuNDA5Ny0wLjU5NzE4LTIuNDExMy0wLjU5NzE4em00NC4xNDYgMGMtMC44NTEzIDAtMS40NzIzIDAuMTk2NTYtMS44NDc4IDAuNTk3MTgtMC4zNTA1NSAwLjM3NTU4LTAuNTE4MyAxLjAyMjktMC41MTgzIDEuOTQ5M3YxMS45MWMwIDAuODc2MzMgMC4yMDUzMiAxLjUwNjEgMC42MzA5OCAxLjg4MTcgMC40MjU2NiAwLjM3NTU4IDEuMTU5MyAwLjU2MzM3IDIuMTg1OSAwLjU2MzM3czEuNzQ5LTAuMTg3NzkgMi4xNzQ3LTAuNTYzMzdjMC40MjU2OS0wLjM3NTU4IDAuNjQyMjYtMS4wMDUzIDAuNjQyMjYtMS44ODE3di05LjM1MTdoMTguODUxbC0yNC43NTQgMzUuMzAxYy0wLjM1MDU0IDAuNTI1ODItMC41MTgzMSAxLjA3MTctMC41MTgzMSAxLjYyMjYgMCAwLjkyNjQ1IDAuMTY3NzcgMS41ODI1IDAuNTE4MzEgMS45ODMxIDAuMzc1NTggMC4zNzU1OCAwLjk5NjU0IDAuNTYzMzggMS44NDc4IDAuNTYzMzhoMjguNzY2YzAuODUxMyAwIDEuNDUyMi0wLjE4NzggMS44MDI4LTAuNTYzMzggMC4zNzU1OC0wLjQwMDYyIDAuNTYzMzgtMS4wNTY2IDAuNTYzMzgtMS45ODMxdi0xMi42NjVjMC0wLjg3NjMzLTAuMjE2NTgtMS40OTQ4LTAuNjQyMjUtMS44NzA0LTAuNDI1NjYtMC4zNzU1OC0xLjE0OC0wLjU2MzM4LTIuMTc0Ny0wLjU2MzM4LTEuMDI2NiAwLTEuNzQ5IDAuMTg3NzktMi4xNzQ3IDAuNTYzMzgtMC40MjU2NiAwLjM3NTU4LTAuNjQyMjQgMC45OTQwMi0wLjY0MjI0IDEuODcwNHYxMC4xMDdoLTE5Ljk3OGwyNC45MDEtMzUuNDU5YzAuMjUwMzktMC4zNTA1NCAwLjM3MTgzLTAuODM4ODMgMC4zNzE4My0xLjQ2NDggMC0wLjkyNjQ1LTAuMTg3OC0xLjU3MzctMC41NjMzOC0xLjk0OTMtMC4zNTA1NS0wLjQwMDYyLTAuOTUxNDctMC41OTcxOC0xLjgwMjgtMC41OTcxOHptLTMxLjc1MiA1LjEwNDJoMC43MDk4NWw2Ljk4NTkgMjAuMzE1aC0xNC43MTZ6bS0zNy43MjMtNDkuMTgzYy00LjczNDIgMC04LjYzMTMgMy44OTctOC42MzEzIDguNjMxM3YxMTUuNDdjMCA0LjczNDIgMy44OTcgOC42MzEzIDguNjMxMyA4LjYzMTNoMTE1LjI2YzQuNzM0MiAwIDguNjQyMS0zLjg5NyA4LjY0MjEtOC42MzEzdi0xMTUuNDdjMC00LjczNDItMy45MDgyLTguNjMxMy04LjY0MjEtOC42MzEzem0wIDUuNzI0aDExNS4yNmMxLjY1OCAwIDIuOTA3IDEuMjQ5MSAyLjkwNyAyLjkwNzF2MTE1LjQ3YzAgMS42NTgtMS4yNDkxIDIuOTA3LTIuOTA3IDIuOTA3aC0xMTUuMjZjLTEuNjU4IDAtMi44OTU4LTEuMjQ5MS0yLjg5NTgtMi45MDd2LTExNS40N2MwLTEuNjU4IDEuMjM3OC0yLjkwNzEgMi44OTU4LTIuOTA3MXoiIGZpbGw9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIuNzIxMTQiLz48L3N2Zz4=');}.icon-scribble{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDQuMjUsMTg4LjI0YTE2LjYzLDE2LjYzLDAsMCwwLDAsMjMuNTIsNiw2LDAsMSwxLTguNDgsOC40OCwyOC42MSwyOC42MSwwLDAsMSwwLTQwLjQ4bDkuMzctOS4zOGExNi42MywxNi42MywwLDAsMC0yMy41Mi0yMy41MWwtNjYuNzUsNjYuNzVhMjguNjMsMjguNjMsMCwwLDEtNDAuNDktNDAuNDlsOTguNzYtOTguNzVhMTYuNjMsMTYuNjMsMCwwLDAtMjMuNTItMjMuNTFMODIuODYsMTE3LjYyQTI4LjYzLDI4LjYzLDAsMCwxLDQyLjM3LDc3LjEzTDgzLjc1LDM1Ljc2YTYsNiwwLDEsMSw4LjQ5LDguNDhMNTAuODYsODUuNjJhMTYuNjMsMTYuNjMsMCwwLDAsMjMuNTIsMjMuNTFsNjYuNzUtNjYuNzVhMjguNjMsMjguNjMsMCwwLDEsNDAuNDksNDAuNDlMODIuODYsMTgxLjYyYTE2LjYzLDE2LjYzLDAsMCwwLDIzLjUyLDIzLjUxbDY2Ljc2LTY2Ljc1YTI4LjYzLDI4LjYzLDAsMCwxLDQwLjQ5LDQwLjQ5WiIvPjwvc3ZnPg==');}.icon-brackets-angle{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik04NS4wNiw0My4yMiwzMS4xMSwxMjhsNTQsODQuNzhhNiw2LDAsMCwxLTEuODQsOC4yOCw2LDYsMCwwLDEtOC4yOC0xLjg0bC01Ni04OGE2LDYsMCwwLDEsMC02LjQ0bDU2LTg4YTYsNiwwLDAsMSwxMC4xMiw2LjQ0Wm0xNTIsODEuNTYtNTYtODhhNiw2LDAsMSwwLTEwLjEyLDYuNDRMMjI0Ljg5LDEyOGwtNTMuOTUsODQuNzhhNiw2LDAsMCwwLDEuODQsOC4yOCw2LDYsMCwwLDAsOC4yOC0xLjg0bDU2LTg4QTYsNiwwLDAsMCwyMzcuMDYsMTI0Ljc4WiIvPjwvc3ZnPg==');}.icon-brain{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yNDYsMTI0YTU0LjEzLDU0LjEzLDAsMCwwLTMyLTQ5LjMzVjcyYTQ2LDQ2LDAsMCwwLTg2LTIyLjY3QTQ2LDQ2LDAsMCwwLDQyLDcydjIuNjdhNTQsNTQsMCwwLDAsMCw5OC42M1YxNzZhNDYsNDYsMCwwLDAsODYsMjIuNjdBNDYsNDYsMCwwLDAsMjE0LDE3NnYtMi43QTU0LjA3LDU0LjA3LDAsMCwwLDI0NiwxMjRaTTg4LDIxMGEzNCwzNCwwLDAsMS0zNC0zMi45NEE1My42Nyw1My42NywwLDAsMCw2NCwxNzhoOGE2LDYsMCwwLDAsMC0xMkg2NEE0Miw0MiwwLDAsMSw1MCw4NC4zOWE2LDYsMCwwLDAsNC01LjY2VjcyYTM0LDM0LDAsMCwxLDY4LDB2NzMuMDVBNDUuODksNDUuODksMCwwLDAsODgsMTMwYTYsNiwwLDAsMCwwLDEyLDM0LDM0LDAsMCwxLDAsNjhabTEwNC00NGgtOGE2LDYsMCwwLDAsMCwxMmg4YTUzLjY3LDUzLjY3LDAsMCwwLDEwLS45NEEzNCwzNCwwLDEsMSwxNjgsMTQyYTYsNiwwLDAsMCwwLTEyLDQ1Ljg5LDQ1Ljg5LDAsMCwwLTM0LDE1LjA1VjcyYTM0LDM0LDAsMCwxLDY4LDB2Ni43M2E2LDYsMCwwLDAsNCw1LjY2QTQyLDQyLDAsMCwxLDE5MiwxNjZabTE0LTU0YTYsNiwwLDAsMS02LDZoLTRhMzQsMzQsMCwwLDEtMzQtMzRWODBhNiw2LDAsMCwxLDEyLDB2NGEyMiwyMiwwLDAsMCwyMiwyMmg0QTYsNiwwLDAsMSwyMDYsMTEyWk02MCwxMThINTZhNiw2LDAsMCwxLDAtMTJoNEEyMiwyMiwwLDAsMCw4Miw4NFY4MGE2LDYsMCwwLDEsMTIsMHY0QTM0LDM0LDAsMCwxLDYwLDExOFoiLz48L3N2Zz4=');}.icon-palette{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xOTkuMzcsNTUuMzFBMTAxLjMyLDEwMS4zMiwwLDAsMCwxMjgsMjZoLTFBMTAyLDEwMiwwLDAsMCwyNiwxMjhjMCw0Mi4wOSwyNi4wNyw3Ny40NCw2OCw5Mi4yNkEzMC4yMSwzMC4yMSwwLDAsMCwxMDQuMTEsMjIyLDMwLjA2LDMwLjA2LDAsMCwwLDEzNCwxOTJhMTgsMTgsMCwwLDEsMTgtMThoNDYuMjFhMjkuODIsMjkuODIsMCwwLDAsMjkuMjUtMjMuMzFBMTAyLjcxLDEwMi43MSwwLDAsMCwyMzAsMTI3LjExLDEwMS4yNSwxMDEuMjUsMCwwLDAsMTk5LjM3LDU1LjMxWk0yMTUuNzYsMTQ4YTE3Ljg5LDE3Ljg5LDAsMCwxLTE3LjU1LDE0SDE1MmEzMCwzMCwwLDAsMC0zMCwzMCwxOCwxOCwwLDAsMS0yNCwxN0M2MSwxOTUuODYsMzgsMTY0Ljg1LDM4LDEyOGE5MCw5MCwwLDAsMSw4OS4wNy05MEgxMjhhOTAuMzQsOTAuMzQsMCwwLDEsOTAsODkuMjJBOTAuNDYsOTAuNDYsMCwwLDEsMjE1Ljc2LDE0OFpNMTM4LDc2YTEwLDEwLDAsMSwxLTEwLTEwQTEwLDEwLDAsMCwxLDEzOCw3NlpNOTQsMTAwQTEwLDEwLDAsMSwxLDg0LDkwLDEwLDEwLDAsMCwxLDk0LDEwMFptMCw1NmExMCwxMCwwLDEsMS0xMC0xMEExMCwxMCwwLDAsMSw5NCwxNTZabTg4LTU2YTEwLDEwLDAsMSwxLTEwLTEwQTEwLDEwLDAsMCwxLDE4MiwxMDBaIi8+PC9zdmc+');}.icon-pen-nib{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yNDYsOTIuNjhhMTMuOTQsMTMuOTQsMCwwLDAtNC4xLTkuOUwxNzMuMjEsMTQuMWExNCwxNCwwLDAsMC0xOS44LDBMMTI0LjY4LDQyLjgzLDY2LjIyLDY0Ljc2YTE0LDE0LDAsMCwwLTguOSwxMC44TDM0LjA4LDIxNUE2LDYsMCwwLDAsNDAsMjIyYTYuNjEsNi42MSwwLDAsMCwxLS4wOGwxMzkuNDQtMjMuMjRhMTQsMTQsMCwwLDAsMTAuODEtOC45bDIxLjkyLTU4LjQ2LDI4Ljc0LTI4Ljc0QTEzLjkyLDEzLjkyLDAsMCwwLDI0Niw5Mi42OFptLTY2LDkyLjg5YTIsMiwwLDAsMS0xLjU0LDEuMjdMNTcuNDksMjA3bDUyLjg3LTUyLjg4YTI2LDI2LDAsMSwwLTguNDgtOC40OEw0OSwxOTguNTNsMjAuMTctMTIxQTIsMiwwLDAsMSw3MC40Myw3Nmw1Ni4wNi0yMUwyMDEsMTI5LjUxWk0xMTAsMTMyYTE0LDE0LDAsMSwxLDE0LDE0QTE0LDE0LDAsMCwxLDExMCwxMzJaTTIzMy40MSw5NC4xLDIwOCwxMTkuNTEsMTM2LjQ4LDQ4LDE2MS45LDIyLjU4YTIsMiwwLDAsMSwyLjgzLDBsNjguNjgsNjguNjlhMiwyLDAsMCwxLDAsMi44M1oiLz48L3N2Zz4=');}.icon-question{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMzgsMTgwYTEwLDEwLDAsMSwxLTEwLTEwQTEwLDEwLDAsMCwxLDEzOCwxODBaTTEyOCw3NGMtMjEsMC0zOCwxNS4yNS0zOCwzNHY0YTYsNiwwLDAsMCwxMiwwdi00YzAtMTIuMTMsMTEuNjYtMjIsMjYtMjJzMjYsOS44NywyNiwyMi0xMS42NiwyMi0yNiwyMmE2LDYsMCwwLDAtNiw2djhhNiw2LDAsMCwwLDEyLDB2LTIuNDJjMTguMTEtMi41OCwzMi0xNi42NiwzMi0zMy41OEMxNjYsODkuMjUsMTQ5LDc0LDEyOCw3NFptMTAyLDU0QTEwMiwxMDIsMCwxLDEsMTI4LDI2LDEwMi4xMiwxMDIuMTIsMCwwLDEsMjMwLDEyOFptLTEyLDBhOTAsOTAsMCwxLDAtOTAsOTBBOTAuMSw5MC4xLDAsMCwwLDIxOCwxMjhaIi8+PC9zdmc+');}.icon-city{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yNDAsMjEwSDIzMFY4OGE2LDYsMCwwLDAtNi02SDE2MGE2LDYsMCwwLDAtNiw2djQySDEwMlY0MGE2LDYsMCwwLDAtNi02SDMyYTYsNiwwLDAsMC02LDZWMjEwSDE2YTYsNiwwLDAsMCwwLDEySDI0MGE2LDYsMCwwLDAsMC0xMlpNMTY2LDk0aDUyVjIxMEgxNjZabS0xMiw0OHY2OEgxMDJWMTQyWk0zOCw0Nkg5MFYyMTBIMzhaTTcwLDcyVjg4YTYsNiwwLDAsMS0xMiwwVjcyYTYsNiwwLDAsMSwxMiwwWm0wLDQ4djE2YTYsNiwwLDAsMS0xMiwwVjEyMGE2LDYsMCwwLDEsMTIsMFptMCw0OHYxNmE2LDYsMCwwLDEtMTIsMFYxNjhhNiw2LDAsMCwxLDEyLDBabTUyLDE2VjE2OGE2LDYsMCwwLDEsMTIsMHYxNmE2LDYsMCwwLDEtMTIsMFptNjQsMFYxNjhhNiw2LDAsMCwxLDEyLDB2MTZhNiw2LDAsMCwxLTEyLDBabTAtNDhWMTIwYTYsNiwwLDAsMSwxMiwwdjE2YTYsNiwwLDAsMS0xMiwwWiIvPjwvc3ZnPg==');}.icon-folder{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTYsNzRIMTMwLjQ5bC0yNy45LTI3LjlhMTMuOTQsMTMuOTQsMCwwLDAtOS45LTQuMUg0MEExNCwxNCwwLDAsMCwyNiw1NlYyMDAuNjJBMTMuMzksMTMuMzksMCwwLDAsMzkuMzgsMjE0SDIxNi44OUExMy4xMiwxMy4xMiwwLDAsMCwyMzAsMjAwLjg5Vjg4QTE0LDE0LDAsMCwwLDIxNiw3NFpNNDAsNTRIOTIuNjlhMiwyLDAsMCwxLDEuNDEuNTlMMTEzLjUxLDc0SDM4VjU2QTIsMiwwLDAsMSw0MCw1NFpNMjE4LDIwMC44OWExLjExLDEuMTEsMCwwLDEtMS4xMSwxLjExSDM5LjM4QTEuNCwxLjQsMCwwLDEsMzgsMjAwLjYyVjg2SDIxNmEyLDIsMCwwLDEsMiwyWiIvPjwvc3ZnPg==');}.icon-hash{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjQsOTBIMTczbDguODktNDguOTNhNiw2LDAsMSwwLTExLjgtMi4xNEwxNjAuODEsOTBIMTA5bDguODktNDguOTNhNiw2LDAsMCwwLTExLjgtMi4xNEw5Ni44MSw5MEg0OGE2LDYsMCwwLDAsMCwxMkg5NC42M2wtOS40Niw1MkgzMmE2LDYsMCwwLDAsMCwxMkg4M0w3NC4xLDIxNC45M2E2LDYsMCwwLDAsNC44Myw3QTUuNjQsNS42NCwwLDAsMCw4MCwyMjJhNiw2LDAsMCwwLDUuODktNC45M0w5NS4xOSwxNjZIMTQ3bC04Ljg5LDQ4LjkzYTYsNiwwLDAsMCw0LjgzLDcsNS42NCw1LjY0LDAsMCwwLDEuMDguMSw2LDYsMCwwLDAsNS44OS00LjkzTDE1OS4xOSwxNjZIMjA4YTYsNiwwLDAsMCwwLTEySDE2MS4zN2w5LjQ2LTUySDIyNGE2LDYsMCwwLDAsMC0xMlptLTc0LjgzLDY0SDk3LjM3bDkuNDYtNTJoNTEuOFoiLz48L3N2Zz4=');}.icon-shapes{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik02OS42OSw2Mi4xYTYsNiwwLDAsMC0xMS4zOCwwbC00MCwxMjBBNiw2LDAsMCwwLDI0LDE5MGg4MGE2LDYsMCwwLDAsNS42OS03LjlaTTMyLjMyLDE3OCw2NCw4M2wzMS42OCw5NVpNMjA2LDc2YTUwLDUwLDAsMSwwLTUwLDUwQTUwLjA2LDUwLjA2LDAsMCwwLDIwNiw3NlptLTg4LDBhMzgsMzgsMCwxLDEsMzgsMzhBMzgsMzgsMCwwLDEsMTE4LDc2Wm0xMDYsNzBIMTM2YTYsNiwwLDAsMC02LDZ2NTZhNiw2LDAsMCwwLDYsNmg4OGE2LDYsMCwwLDAsNi02VjE1MkE2LDYsMCwwLDAsMjI0LDE0NlptLTYsNTZIMTQyVjE1OGg3NloiLz48L3N2Zz4=');}.icon-diamonds-four{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMjMuNzYsMTA4LjI0YTYsNiwwLDAsMCw4LjQ4LDBsNDAtNDBhNiw2LDAsMCwwLDAtOC40OGwtNDAtNDBhNiw2LDAsMCwwLTguNDgsMGwtNDAsNDBhNiw2LDAsMCwwLDAsOC40OFpNMTI4LDMyLjQ5LDE1OS41MSw2NCwxMjgsOTUuNTEsOTYuNDksNjRabTQuMjQsMTE1LjI3YTYsNiwwLDAsMC04LjQ4LDBsLTQwLDQwYTYsNiwwLDAsMCwwLDguNDhsNDAsNDBhNiw2LDAsMCwwLDguNDgsMGw0MC00MGE2LDYsMCwwLDAsMC04LjQ4Wk0xMjgsMjIzLjUxLDk2LjQ5LDE5MiwxMjgsMTYwLjQ5LDE1OS41MSwxOTJabTEwOC4yNC05OS43NS00MC00MGE2LDYsMCwwLDAtOC40OCwwbC00MCw0MGE2LDYsMCwwLDAsMCw4LjQ4bDQwLDQwYTYsNiwwLDAsMCw4LjQ4LDBsNDAtNDBBNiw2LDAsMCwwLDIzNi4yNCwxMjMuNzZaTTE5MiwxNTkuNTEsMTYwLjQ5LDEyOCwxOTIsOTYuNDksMjIzLjUxLDEyOFptLTgzLjc2LTM1Ljc1LTQwLTQwYTYsNiwwLDAsMC04LjQ4LDBsLTQwLDQwYTYsNiwwLDAsMCwwLDguNDhsNDAsNDBhNiw2LDAsMCwwLDguNDgsMGw0MC00MEE2LDYsMCwwLDAsMTA4LjI0LDEyMy43NlpNNjQsMTU5LjUxLDMyLjQ5LDEyOCw2NCw5Ni40OSw5NS41MSwxMjhaIi8+PC9zdmc+');}.icon-crosshair-simple{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMjgsMjZBMTAyLDEwMiwwLDEsMCwyMzAsMTI4LDEwMi4xMiwxMDIuMTIsMCwwLDAsMTI4LDI2Wm02LDE5MS44VjE4NGE2LDYsMCwwLDAtMTIsMHYzMy44QTkwLjE1LDkwLjE1LDAsMCwxLDM4LjIsMTM0SDcyYTYsNiwwLDAsMCwwLTEySDM4LjJBOTAuMTUsOTAuMTUsMCwwLDEsMTIyLDM4LjJWNzJhNiw2LDAsMCwwLDEyLDBWMzguMkE5MC4xNSw5MC4xNSwwLDAsMSwyMTcuOCwxMjJIMTg0YTYsNiwwLDAsMCwwLDEyaDMzLjhBOTAuMTUsOTAuMTUsMCwwLDEsMTM0LDIxNy44WiIvPjwvc3ZnPg==');}.icon-circle-notch{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzAsMTI4YTEwMiwxMDIsMCwwLDEtMjA0LDBjMC00MC4xOCwyMy4zNS03Ni44Niw1OS41LTkzLjQ1YTYsNiwwLDAsMSw1LDEwLjlDNTguNjEsNjAuMDksMzgsOTIuNDksMzgsMTI4YTkwLDkwLDAsMCwwLDE4MCwwYzAtMzUuNTEtMjAuNjEtNjcuOTEtNTIuNS04Mi41NWE2LDYsMCwwLDEsNS0xMC45QzIwNi42NSw1MS4xNCwyMzAsODcuODIsMjMwLDEyOFoiLz48L3N2Zz4=');}.icon-cards-three{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDgsOTBINDhhMTQsMTQsMCwwLDAtMTQsMTR2OTZhMTQsMTQsMCwwLDAsMTQsMTRIMjA4YTE0LDE0LDAsMCwwLDE0LTE0VjEwNEExNCwxNCwwLDAsMCwyMDgsOTBabTIsMTEwYTIsMiwwLDAsMS0yLDJINDhhMiwyLDAsMCwxLTItMlYxMDRhMiwyLDAsMCwxLDItMkgyMDhhMiwyLDAsMCwxLDIsMlpNNTAsNjRhNiw2LDAsMCwxLDYtNkgyMDBhNiw2LDAsMCwxLDAsMTJINTZBNiw2LDAsMCwxLDUwLDY0Wk02NiwzMmE2LDYsMCwwLDEsNi02SDE4NGE2LDYsMCwwLDEsMCwxMkg3MkE2LDYsMCwwLDEsNjYsMzJaIi8+PC9zdmc+');}.icon-sun-dim{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMjIsNDBWMzJhNiw2LDAsMCwxLDEyLDB2OGE2LDYsMCwwLDEtMTIsMFptNjgsODhhNjIsNjIsMCwxLDEtNjItNjJBNjIuMDcsNjIuMDcsMCwwLDEsMTkwLDEyOFptLTEyLDBhNTAsNTAsMCwxLDAtNTAsNTBBNTAuMDYsNTAuMDYsMCwwLDAsMTc4LDEyOFpNNTkuNzYsNjguMjRhNiw2LDAsMSwwLDguNDgtOC40OGwtOC04YTYsNiwwLDAsMC04LjQ4LDguNDhabTAsMTE5LjUyLTgsOGE2LDYsMCwxLDAsOC40OCw4LjQ4bDgtOGE2LDYsMCwxLDAtOC40OC04LjQ4Wm0xMzYtMTM2LTgsOGE2LDYsMCwxLDAsOC40OCw4LjQ4bDgtOGE2LDYsMCwwLDAtOC40OC04LjQ4Wm0uNDgsMTM2YTYsNiwwLDAsMC04LjQ4LDguNDhsOCw4YTYsNiwwLDAsMCw4LjQ4LTguNDhaTTQwLDEyMkgzMmE2LDYsMCwwLDAsMCwxMmg4YTYsNiwwLDAsMCwwLTEyWm04OCw4OGE2LDYsMCwwLDAtNiw2djhhNiw2LDAsMCwwLDEyLDB2LThBNiw2LDAsMCwwLDEyOCwyMTBabTk2LTg4aC04YTYsNiwwLDAsMCwwLDEyaDhhNiw2LDAsMCwwLDAtMTJaIi8+PC9zdmc+');}.icon-moon{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzIuMTMsMTQzLjY0YTYsNiwwLDAsMC02LTEuNDlBOTAuMDcsOTAuMDcsMCwwLDEsMTEzLjg2LDI5Ljg1YTYsNiwwLDAsMC03LjQ5LTcuNDhBMTAyLjg4LDEwMi44OCwwLDAsMCw1NC40OCw1OC42OCwxMDIsMTAyLDAsMCwwLDE5Ny4zMiwyMDEuNTJhMTAyLjg4LDEwMi44OCwwLDAsMCwzNi4zMS01MS44OUE2LDYsMCwwLDAsMjMyLjEzLDE0My42NFptLTQyLDQ4LjI5YTkwLDkwLDAsMCwxLTEyNi0xMjZBOTAuOSw5MC45LDAsMCwxLDk5LjY1LDM3LjY2LDEwMi4wNiwxMDIuMDYsMCwwLDAsMjE4LjM0LDE1Ni4zNSw5MC45LDkwLjksMCwwLDEsMTkwLjEsMTkxLjkzWiIvPjwvc3ZnPg==');}.icon-plus-square{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDgsMzRINDhBMTQsMTQsMCwwLDAsMzQsNDhWMjA4YTE0LDE0LDAsMCwwLDE0LDE0SDIwOGExNCwxNCwwLDAsMCwxNC0xNFY0OEExNCwxNCwwLDAsMCwyMDgsMzRabTIsMTc0YTIsMiwwLDAsMS0yLDJINDhhMiwyLDAsMCwxLTItMlY0OGEyLDIsMCwwLDEsMi0ySDIwOGEyLDIsMCwwLDEsMiwyWm0tMzYtODBhNiw2LDAsMCwxLTYsNkgxMzR2MzRhNiw2LDAsMCwxLTEyLDBWMTM0SDg4YTYsNiwwLDAsMSwwLTEyaDM0Vjg4YTYsNiwwLDAsMSwxMiwwdjM0aDM0QTYsNiwwLDAsMSwxNzQsMTI4WiIvPjwvc3ZnPg==');}.icon-arrow-elbow-left-up{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzgsMTkyYTYsNiwwLDAsMS02LDZIODhhNiw2LDAsMCwxLTYtNlY2Mi40OUw0NC4yNCwxMDAuMjRhNiw2LDAsMCwxLTguNDgtOC40OGw0OC00OGE2LDYsMCwwLDEsOC40OCwwbDQ4LDQ4YTYsNiwwLDEsMS04LjQ4LDguNDhMOTQsNjIuNDlWMTg2SDIzMkE2LDYsMCwwLDEsMjM4LDE5MloiLz48L3N2Zz4=');}.icon-arrow-elbow-right-up{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjAuMjQsMTAwLjI0YTYsNiwwLDAsMS04LjQ4LDBMMTc0LDYyLjQ5VjE5MmE2LDYsMCwwLDEtNiw2SDI0YTYsNiwwLDAsMSwwLTEySDE2MlY2Mi40OWwtMzcuNzYsMzcuNzVhNiw2LDAsMCwxLTguNDgtOC40OGw0OC00OGE2LDYsMCwwLDEsOC40OCwwbDQ4LDQ4QTYsNiwwLDAsMSwyMjAuMjQsMTAwLjI0WiIvPjwvc3ZnPg==');}.icon-x{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDQuMjQsMTk1Ljc2YTYsNiwwLDEsMS04LjQ4LDguNDhMMTI4LDEzNi40OSw2MC4yNCwyMDQuMjRhNiw2LDAsMCwxLTguNDgtOC40OEwxMTkuNTEsMTI4LDUxLjc2LDYwLjI0YTYsNiwwLDAsMSw4LjQ4LTguNDhMMTI4LDExOS41MWw2Ny43Ni02Ny43NWE2LDYsMCwwLDEsOC40OCw4LjQ4TDEzNi40OSwxMjhaIi8+PC9zdmc+');}.icon-floppy-disk{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTcuOSw3My40MiwxODIuNTgsMzguMWExMy45LDEzLjksMCwwLDAtOS44OS00LjFINDhBMTQsMTQsMCwwLDAsMzQsNDhWMjA4YTE0LDE0LDAsMCwwLDE0LDE0SDIwOGExNCwxNCwwLDAsMCwxNC0xNFY4My4zMUExMy45LDEzLjksMCwwLDAsMjE3LjksNzMuNDJaTTE3MCwyMTBIODZWMTUyYTIsMiwwLDAsMSwyLTJoODBhMiwyLDAsMCwxLDIsMlptNDAtMmEyLDIsMCwwLDEtMiwySDE4MlYxNTJhMTQsMTQsMCwwLDAtMTQtMTRIODhhMTQsMTQsMCwwLDAtMTQsMTR2NThINDhhMiwyLDAsMCwxLTItMlY0OGEyLDIsMCwwLDEsMi0ySDE3Mi42OWEyLDIsMCwwLDEsMS40MS41OEwyMDkuNDIsODEuOWEyLDIsMCwwLDEsLjU4LDEuNDFaTTE1OCw3MmE2LDYsMCwwLDEtNiw2SDk2YTYsNiwwLDAsMSwwLTEyaDU2QTYsNiwwLDAsMSwxNTgsNzJaIi8+PC9zdmc+');}.icon-x-circle{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjQuMjQsMTAwLjI0LDEzNi40OCwxMjhsMjcuNzYsMjcuNzZhNiw2LDAsMSwxLTguNDgsOC40OEwxMjgsMTM2LjQ4bC0yNy43NiwyNy43NmE2LDYsMCwwLDEtOC40OC04LjQ4TDExOS41MiwxMjgsOTEuNzYsMTAwLjI0YTYsNiwwLDAsMSw4LjQ4LTguNDhMMTI4LDExOS41MmwyNy43Ni0yNy43NmE2LDYsMCwwLDEsOC40OCw4LjQ4Wk0yMzAsMTI4QTEwMiwxMDIsMCwxLDEsMTI4LDI2LDEwMi4xMiwxMDIuMTIsMCwwLDEsMjMwLDEyOFptLTEyLDBhOTAsOTAsMCwxLDAtOTAsOTBBOTAuMSw5MC4xLDAsMCwwLDIxOCwxMjhaIi8+PC9zdmc+');}.icon-minus-square{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDgsMzRINDhBMTQsMTQsMCwwLDAsMzQsNDhWMjA4YTE0LDE0LDAsMCwwLDE0LDE0SDIwOGExNCwxNCwwLDAsMCwxNC0xNFY0OEExNCwxNCwwLDAsMCwyMDgsMzRabTIsMTc0YTIsMiwwLDAsMS0yLDJINDhhMiwyLDAsMCwxLTItMlY0OGEyLDIsMCwwLDEsMi0ySDIwOGEyLDIsMCwwLDEsMiwyWm0tMzYtODBhNiw2LDAsMCwxLTYsNkg4OGE2LDYsMCwwLDEsMC0xMmg4MEE2LDYsMCwwLDEsMTc0LDEyOFoiLz48L3N2Zz4=');}.icon-pencil-simple{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjUuOSw3NC43OCwxODEuMjEsMzAuMDlhMTQsMTQsMCwwLDAtMTkuOCwwTDM4LjEsMTUzLjQxYTEzLjk0LDEzLjk0LDAsMCwwLTQuMSw5LjlWMjA4YTE0LDE0LDAsMCwwLDE0LDE0SDkyLjY5YTEzLjk0LDEzLjk0LDAsMCwwLDkuOS00LjFMMjI1LjksOTQuNThhMTQsMTQsMCwwLDAsMC0xOS44Wk05NC4xLDIwOS40MWEyLDIsMCwwLDEtMS40MS41OUg0OGEyLDIsMCwwLDEtMi0yVjE2My4zMWEyLDIsMCwwLDEsLjU5LTEuNDFMMTM2LDcyLjQ4LDE4My41MSwxMjBaTTIxNy40MSw4Ni4xLDE5MiwxMTEuNTEsMTQ0LjQ5LDY0LDE2OS45LDM4LjU4YTIsMiwwLDAsMSwyLjgzLDBsNDQuNjgsNDQuNjlhMiwyLDAsMCwxLDAsMi44M1oiLz48L3N2Zz4=');}.icon-dots-six-vertical{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMDIsNjBBMTAsMTAsMCwxLDEsOTIsNTAsMTAsMTAsMCwwLDEsMTAyLDYwWm02MiwxMGExMCwxMCwwLDEsMC0xMC0xMEExMCwxMCwwLDAsMCwxNjQsNzBaTTkyLDExOGExMCwxMCwwLDEsMCwxMCwxMEExMCwxMCwwLDAsMCw5MiwxMThabTcyLDBhMTAsMTAsMCwxLDAsMTAsMTBBMTAsMTAsMCwwLDAsMTY0LDExOFpNOTIsMTg2YTEwLDEwLDAsMSwwLDEwLDEwQTEwLDEwLDAsMCwwLDkyLDE4NlptNzIsMGExMCwxMCwwLDEsMCwxMCwxMEExMCwxMCwwLDAsMCwxNjQsMTg2WiIvPjwvc3ZnPg==');}.icon-list{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjIsMTI4YTYsNiwwLDAsMS02LDZINDBhNiw2LDAsMCwxLDAtMTJIMjE2QTYsNiwwLDAsMSwyMjIsMTI4Wk00MCw3MEgyMTZhNiw2LDAsMCwwLDAtMTJINDBhNiw2LDAsMCwwLDAsMTJaTTIxNiwxODZINDBhNiw2LDAsMCwwLDAsMTJIMjE2YTYsNiwwLDAsMCwwLTEyWiIvPjwvc3ZnPg==');}.icon-loading{--icon:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyAgICB3aWR0aD0iMzIiICAgIGhlaWdodD0iMzIiICAgIHZpZXdCb3g9IjAgMCAzMiAzMiIgICAgdmVyc2lvbj0iMS4xIiAgICB4bWw6c3BhY2U9InByZXNlcnZlIiAgICBzdHlsZT0iY2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNSIgICAgaWQ9InN2ZzEwIiAgICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciICAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxkZWZzICAgIGlkPSJkZWZzMTAiIC8+PHBhdGggICAgaWQ9InBhdGgxMSIgICAgc3R5bGU9ImJhc2VsaW5lLXNoaWZ0OmJhc2VsaW5lO2Rpc3BsYXk6aW5saW5lO292ZXJmbG93OnZpc2libGU7dmVjdG9yLWVmZmVjdDpub25lO2ZpbGw6IzIyMjIyMjtlbmFibGUtYmFja2dyb3VuZDphY2N1bXVsYXRlO3N0b3AtY29sb3I6IzAwMDAwMDtzdG9wLW9wYWNpdHk6MSIgICAgZD0ibSAxNi42MjEwOTQsMS4xNDI1NzgxIGMgLTguMjY2MzIzMiwwIC0xNi4yMjA4NjczOCw2LjQ0MjgwOTUgLTE1LjU4NTkzNzgsMTQuNjg1NTQ2OSAwLjYwMTM0NTUsNy44MDczMDggNy40MzQxMjY0LDE0LjEyNjk4IDE0LjkzMzU5MzgsMTQuOTQzMzU5IDguODM5ODQ1LDAuOTYyMjgzIDE1LjUwNTQ2OSwtNi4zNzY5MTkgMTUuMDA1ODU5LC0xNC45ODYzMjggQyAzMC40OTU5LDcuNTM2MjY4NCAyNC44ODMzOTcsMS4xNDI1NzgxIDE2LjYyMTA5NCwxLjE0MjU3ODEgWiBtIDAsMC42NTAzOTA3IEMgMjYuNDg4Nzg2LDEuODAzODY0NSAyOS43MTQ1MTgsOS41OTM1ODMzIDMwLjMwMjczNCwxNS44MDQ2ODggMzEuMTQxOTgyLDI0LjY2NjM2NSAyMi4xNjA0NTksMzEuMTY4MDc3IDE2LjAzOTA2MiwzMC4xMjUgOC44OTUxMzI3LDI4LjkwNzY4MSAyLjI2MTMxNDIsMjMuMjc5Mzc2IDEuNjgzNTkzOCwxNS43NzkyOTcgMS4wNzY5MzM4LDcuOTAzMjc1NCA4LjcyMjU0NTEsMS43ODQyNjk5IDE2LjYyMTA5NCwxLjc5Mjk2ODggWiBtIC0wLjA2NDQ1LDEuMjE4NzUgYyAtMy42MTAwODMsMCAtNy4xNTQ3OTk1LDEuNDAxMDY4NyAtOS43MzA0NjkxLDMuNzAzMTI1IEMgNC4yNTA1MDIzLDkuMDE2OTAwMiAyLjY0MjAzNzIsMTIuMjI2Mjk1IDIuOTE5OTIxOSwxNS44MzM5ODQgMy40NDY5MzUsMjIuNjc1NzEyIDkuNDI4OTY0OSwyOC4xOTg5ODUgMTUuOTk4MDQ3LDI4LjkxNDA2MiAyMy43MTQyNTYsMjkuNzU0MDIzIDI5LjUzMTYwMywyMy4zMzE3IDI5LjA5NTcwMywxNS44MjAzMTIgMjguNjc3OTQ4LDguNjIxMzk1MyAyMy43NzY2ODYsMy4wMTE3MTg4IDE2LjU1NjY0MSwzLjAxMTcxODggWiBtIDAsMC4xOTUzMTI0IGMgNy4xMTkxMzQsMCAxMS45MzI3MSw1LjUwODEzNzMgMTIuMzQ1NzAzLDEyLjYyNDk5OTggQyAyOS4zMzIwNjIsMjMuMjM2ODk2IDIzLjYxODk1OCwyOS41NDU5OTggMTYuMDE5NTMxLDI4LjcxODc1IDkuNTQ1NDMyMSwyOC4wMTQwMTIgMy42MzQxNjM3LDIyLjU1NTE0MyAzLjExNTIzNDQsMTUuODE4MzU5IDIuODQyNDU2MywxMi4yNzY5NjcgNC40MTg0MTA5LDkuMTI4MzE2OSA2Ljk1NzAzMTIsNi44NTkzNzUgOS40OTU2NTE2LDQuNTkwNDMzMSAxMi45OTcwOTMsMy4yMDcwMzEyIDE2LjU1NjY0MSwzLjIwNzAzMTIgWiBtIC0wLjA3MDMxLDEuNDE2MDE1NyBjIC0zLjE2MTk3MywwIC02LjI2MzUwOSwxLjIyNTgxMzkgLTguNTE5NTMxMSwzLjI0MjE4NzUgQyA1LjcxMDc2OTEsOS44ODE2MDggNC4zMDE0NTQyLDEyLjY5NDU4OSA0LjU0NDkyMTksMTUuODU1NDY5IDUuMDA2NTYyNCwyMS44NDg1NTQgMTAuMjQ0MTc4LDI2LjY4NjE1OSAxNS45OTgwNDcsMjcuMzEyNSAyMi43NTcwMTMsMjguMDQ4MjYxIDI3Ljg1NDQ1MSwyMi40MjA5MzYgMjcuNDcyNjU2LDE1Ljg0MTc5NyAyNy4xMDY4MjQsOS41Mzc2MDI1IDIyLjgxMDE2LDQuNjIzMDQ2OSAxNi40ODYzMjgsNC42MjMwNDY5IFogbSAwLDAuMTk1MzEyNSBjIDYuMjIyOTIsMCAxMC40Mjk5NDYsNC44MTMwMTM4IDEwLjc5MTAxNiwxMS4wMzUxNTY2IDAuMzc1NjEzLDYuNDcyNjE1IC00LjYxNzU4NCwxMS45ODY3MiAtMTEuMjU5NzY2LDExLjI2MzY3MiBDIDEwLjM1ODY4NSwyNi41MDExODYgNS4xOTE4MzgxLDIxLjcyNzk4NSA0LjczODI4MTIsMTUuODM5ODQ0IDQuNDk5OTIwMSwxMi43NDUyNjIgNS44NzY3MzE1LDkuOTk0OTc3OCA4LjA5NTcwMzEsOC4wMTE3MTg4IDEwLjMxNDY3NSw2LjAyODQ1OTUgMTMuMzc0ODksNC44MTgzNTk0IDE2LjQ4NjMyOCw0LjgxODM1OTQgWiBtIC0wLjA2ODM2LDEuNDE2MDE1NiBjIC0yLjcxMzg3NywwIC01LjM3NjExOCwxLjA1MjUxNjQgLTcuMzEyNTAwMiwyLjc4MzIwMzEgLTEuOTM2MzgyOCwxLjczMDY4NjkgLTMuMTQ2NTUxNyw0LjE0NTMxMTkgLTIuOTM3NSw2Ljg1OTM3NDkgMC4zOTYyNjk5LDUuMTQ0NDMgNC44ODk0NDQyLDkuMjk0NDI5IDkuODI4MTI1Miw5LjgzMjAzMSA1LjgwMTc0OSwwLjYzMTU2MiAxMC4xNzkyNTcsLTQuMTk4ODI4IDkuODUxNTYyLC05Ljg0NTcwMyBDIDI1LjUzMzc1LDEwLjQ1MzgyMiAyMS44NDU2MTYsNi4yMzQzNzUgMTYuNDE3OTc0LDYuMjM0Mzc1IFogbSAwLDAuMTk1MzEyNSBjIDUuMzI2NzMsMCA4LjkyNTIyNiw0LjExNzkwNTUgOS4yMzQzNzUsOS40NDUzMTI1IDAuMzIxNTEzLDUuNTQwMzUxIC0zLjk0OTgwMSwxMC4yNTk0NzQgLTkuNjM0NzY2LDkuNjQwNjI1IEMgMTEuMTczODc1LDI0Ljk4ODM2MiA2Ljc0OTUxNDMsMjAuOTAwODE0IDYuMzYxMzI4MSwxNS44NjEzMjggNi4xNTczODMxLDEzLjIxMzU2MyA3LjMzNTA0MzEsMTAuODU5NjgyIDkuMjM0Mzc1LDkuMTYyMTA5NCAxMS4xMzM3MDcsNy40NjQ1MzcyIDEzLjc1NDYyOCw2LjQyOTY4NzUgMTYuNDE3OTY5LDYuNDI5Njg3NSBaIG0gLTAuMDY4MzYsMS40MTYwMTU2IGMgLTIuMjY1Nzc1LDAgLTQuNDg4NzI5LDAuODc5MjE5NiAtNi4xMDU0NjgsMi4zMjQyMTg5IC0xLjYxNjc0MDgsMS40NDQ5OTkgLTIuNjI3NzYwNywzLjQ2MTI2OSAtMi40NTMxMjU0LDUuNzI4NTE2IDAuMzMwODk4Niw0LjI5NTc2OCA0LjA4MTU5NjQsNy43NjAxMiA4LjIwNTA3ODQsOC4yMDg5ODQgNC44NDQ1MjUsMC41MjczNiA4LjUwMDE1NiwtMy41MDYwOTcgOC4yMjY1NjIsLTguMjIwNzAzIEMgMjMuOTYwNjcyLDExLjM3MTk5NiAyMC44ODEwNiw3Ljg0NTcwMzEgMTYuMzQ5NjE0LDcuODQ1NzAzMSBaIG0gMCwwLjE5NTMxMjUgYyA0LjQzMDUzNCwwIDcuNDIyNDYxLDMuNDIyNzk5NCA3LjY3OTY4OCw3Ljg1NTQ2ODQgMC4yNjc0MTIsNC42MDgwODIgLTMuMjgzOTc4LDguNTMyMjI2IC04LjAxMTcxOSw4LjAxNzU3OCBDIDExLjk4OTA3NSwyMy40NzU1MzggOC4zMDcxODk5LDIwLjA3NTU5MyA3Ljk4NDM3NSwxNS44ODQ3NjYgNy44MTQ4NDYzLDEzLjY4MzgxOSA4Ljc5NTMxMDUsMTEuNzI2MzM4IDEwLjM3NSwxMC4zMTQ0NTMgMTEuOTU0Njg5LDguOTAyNTY4OSAxNC4xMzQzNyw4LjA0MTAxNTYgMTYuMzQ5NjA5LDguMDQxMDE1NiBaIG0gLTAuMDY4MzYsMS40MTYwMTU2IGMgLTEuODE3NjcyLDAgLTMuNjAxMzQyLDAuNzAzOTY4OCAtNC44OTg0MzgsMS44NjMyODA4IC0xLjI5NzA5NSwxLjE1OTMxIC0yLjEwODk2ODMsMi43NzkxODUgLTEuOTY4NzQ5NSw0LjU5OTYxIDAuMjY1NTI2OSwzLjQ0NzExMSAzLjI3Mzc1MDUsNi4yMjU4MTMgNi41ODIwMzE1LDYuNTg1OTM3IDMuODg3Mjk1LDAuNDIzMTYgNi44MjMwMDgsLTIuODE1MzE4IDYuNjAzNTE1LC02LjU5NzY1NiBDIDIyLjM4OTU0MSwxMi4yODgyMjIgMTkuOTE2NDk1LDkuNDU3MDMxMSAxNi4yODEyNSw5LjQ1NzAzMTIgWiBtIDAsMC4xOTUzMTI2IGMgMy41MzQzMzMsMCA1LjkxNzc0MiwyLjcyNzY5NjIgNi4xMjMwNDcsNi4yNjU2MjUyIDAuMjEzMzExLDMuNjc1ODE0IC0yLjYxNjIwOCw2LjgwMzAyNSAtNi4zODY3MTksNi4zOTI1NzggLTMuMjEzMjk4LC0wLjM0OTc4NSAtNi4xNTA3NTk3LC0zLjA2MjEzIC02LjQwODIwMywtNi40MDQyOTcgLTAuMTM1MTEyMiwtMS43NTQxMjcgMC42NDQyNTIsLTMuMzEzMjU3IDEuOTA0Mjk3LC00LjQzOTQ1MyAxLjI2MDA0NSwtMS4xMjYxOTYgMy4wMDA0NDEsLTEuODE0NDUzMyA0Ljc2NzU3OCwtMS44MTQ0NTMyIHogbSAtMC4wNzAzMSwxLjQxNjAxNTIgYyAtMS4zNjk1NzIsMCAtMi43MTIsMC41MzA2NzUgLTMuNjg5NDU0LDEuNDA0Mjk3IC0wLjk3NzQ1MywwLjg3MzYyMiAtMS41OTAxNzcsMi4wOTUxNDUgLTEuNDg0Mzc1LDMuNDY4NzUgMC4yMDAxNTYsMi41OTg0NTIgMi40NjU5LDQuNjg5NTUxIDQuOTU4OTg1LDQuOTYwOTM4IDIuOTMwMDcsMC4zMTg5NTggNS4xNDM5MDgsLTIuMTIyNTg3IDQuOTc4NTE1LC00Ljk3MjY1NiAtMC4xNTgxNDUsLTIuNzI1MjQ0IC0yLjAyNDYyMiwtNC44NjEzMjkgLTQuNzYzNjcxLC00Ljg2MTMyOSB6IG0gMCwwLjE5NTMxMyBjIDIuNjM4MTM1LDAgNC40MTQ5NzUsMi4wMzQ1NDQgNC41NjgzNTksNC42Nzc3MzQgMC4xNTkyMTEsMi43NDM1NDYgLTEuOTUwMzg2LDUuMDczODI0IC00Ljc2MzY3Miw0Ljc2NzU3OCAtMi4zOTgxMDIsLTAuMjYxMDQ3IC00LjU5MTEzMSwtMi4yODc3NDEgLTQuNzgzMjAzLC00Ljc4MTI1IC0wLjEwMDY5NiwtMS4zMDczMDggMC40Nzk1MTksLTIuNDcwMDM5IDEuNDE5OTIyLC0zLjMxMDU0NiAwLjk0MDQwMywtMC44NDA1MDggMi4yMzk1NTcsLTEuMzUzNTE2IDMuNTU4NTk0LC0xLjM1MzUxNiB6IG0gLTAuMDY4MzYsMS40MTYwMTYgYyAtMC45MjE0NzIsMCAtMS44MjI2NTcsMC4zNTU0MjUgLTIuNDgwNDY5LDAuOTQzMzU5IC0wLjY1NzgxMSwwLjU4NzkzNCAtMS4wNzMzMzksMS40MTUwMSAtMS4wMDE5NTMsMi4zNDE3OTcgMC4xMzQ3ODUsMS43NDk3OTIgMS42NTYwOTUsMy4xNTMyOTEgMy4zMzM5ODUsMy4zMzU5MzcgMS45NzI4NDYsMC4yMTQ3NTkgMy40NjY3NiwtMS40MzE4MDkgMy4zNTU0NjgsLTMuMzQ5NjA5IC0wLjEwNjIyNCwtMS44MzA1MDMgLTEuMzY0MTc3LC0zLjI3MTQ4NyAtMy4yMDcwMzEsLTMuMjcxNDg0IHogbSAwLDAuMTk1MzEyIGMgMS43NDE5NDIsMCAyLjkxMjIwOSwxLjMzOTQ0IDMuMDEzNjcyLDMuMDg3ODkxIDAuMTA1MTEsMS44MTEyNzYgLTEuMjg0NTYyLDMuMzQ2NTc3IC0zLjE0MDYyNSwzLjE0NDUzMSAtMS41ODI5MDcsLTAuMTcyMzA3IC0zLjAzMzQ1NSwtMS41MTMzNTUgLTMuMTYwMTU2LC0zLjE1ODIwMyAtMC4wNjYyOCwtMC44NjA0OSAwLjMxNDc4NSwtMS42MjQ4NjggMC45MzU1NDcsLTIuMTc5Njg4IDAuNjIwNzQ5LC0wLjU1NDgxOSAxLjQ4MDYyLC0wLjg5NDUzMSAyLjM1MTU1NiwtMC44OTQ1MzEgeiBtIC0wLjA2ODM2LDEuNDE2MDE2IGMgLTAuNDczMzY5LDAgLTAuOTM1MjcxLDAuMTgyMTI5IC0xLjI3MzQzOCwwLjQ4NDM3NSAtMC4zMzgxNjcsMC4zMDIyNDYgLTAuNTU0NTQ2LDAuNzMwOTY5IC0wLjUxNzU3OCwxLjIxMDkzNyAwLjA2OTQxLDAuOTAxMTMzIDAuODQ4MjQ5LDEuNjE4OTgxIDEuNzEwOTM4LDEuNzEyODkxIDEuMDE1NjE2LDAuMTEwNTU3IDEuNzg5NjE0LC0wLjc0MTAzMSAxLjczMjQyMSwtMS43MjY1NjMgLTAuMDU0MywtMC45MzU3NjYgLTAuNzA1NjkxLC0xLjY4MTY0IC0xLjY1MjM0MywtMS42ODE2NCB6IG0gMCwwLjE5NTMxMiBjIDAuODQ1NzQsMCAxLjQwNzQ5LDAuNjQ0MzMzIDEuNDU3MDMxLDEuNDk4MDQ3IDAuMDUxMDEsMC44NzkwMDggLTAuNjE2NzkzLDEuNjE5MzI5IC0xLjUxNTYyNSwxLjUyMTQ4NCAtMC43Njc3MDYsLTAuMDgzNTcgLTEuNDc1NzgsLTAuNzM4OTY3IC0xLjUzNzEwOSwtMS41MzUxNTYgLTAuMDMxODYsLTAuNDEzNjcxIDAuMTUwMDU1LC0wLjc3OTY5NyAwLjQ1MTE3MiwtMS4wNDg4MjggMC4zMDExMTYsLTAuMjY5MTMxIDAuNzIxNjk4LC0wLjQzNTU0NyAxLjE0NDUzMSwtMC40MzU1NDcgeiIgLz48L3N2Zz4=');}.icon-magnifying-glass{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjguMjQsMjE5Ljc2bC01MS4zOC01MS4zOGE4Ni4xNSw4Ni4xNSwwLDEsMC04LjQ4LDguNDhsNTEuMzgsNTEuMzhhNiw2LDAsMCwwLDguNDgtOC40OFpNMzgsMTEyYTc0LDc0LDAsMSwxLDc0LDc0QTc0LjA5LDc0LjA5LDAsMCwxLDM4LDExMloiLz48L3N2Zz4=');}.icon-infinity{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yNDYsMTI4YTU0LDU0LDAsMCwxLTkyLjE4LDM4LjE4LDMuMDcsMy4wNywwLDAsMS0uMjUtLjI2bC02MC02Ny43NGE0Miw0MiwwLDEsMCwwLDU5LjY0bDguNTctOS42N2E2LDYsMCwxLDEsOSw4bC04LjY5LDkuODFhMy4wNywzLjA3LDAsMCwxLS4yNS4yNiw1NCw1NCwwLDEsMSwwLTc2LjM2LDMuMDcsMy4wNywwLDAsMSwuMjUuMjZsNjAsNjcuNzRhNDIsNDIsMCwxLDAsMC01OS42NGwtOC41Nyw5LjY3YTYsNiwwLDEsMS05LThsOC42OS05LjgxYTMuMDcsMy4wNywwLDAsMSwuMjUtLjI2QTU0LDU0LDAsMCwxLDI0NiwxMjhaIi8+PC9zdmc+');}.icon-arrow-counter-clockwise{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjIsMTI4YTk0LDk0LDAsMCwxLTkyLjc0LDk0SDEyOGE5My40Myw5My40MywwLDAsMS02NC41LTI1LjY1LDYsNiwwLDEsMSw4LjI0LTguNzJBODIsODIsMCwxLDAsNzAsNzBsLS4xOS4xOUwzOS40NCw5OEg3MmE2LDYsMCwwLDEsMCwxMkgyNGE2LDYsMCwwLDEtNi02VjU2YTYsNiwwLDAsMSwxMiwwVjkwLjM0TDYxLjYzLDYxLjRBOTQsOTQsMCwwLDEsMjIyLDEyOFoiLz48L3N2Zz4=');}.icon-clock{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMjgsMjZBMTAyLDEwMiwwLDEsMCwyMzAsMTI4LDEwMi4xMiwxMDIuMTIsMCwwLDAsMTI4LDI2Wm0wLDE5MmE5MCw5MCwwLDEsMSw5MC05MEE5MC4xLDkwLjEsMCwwLDEsMTI4LDIxOFptNjItOTBhNiw2LDAsMCwxLTYsNkgxMjhhNiw2LDAsMCwxLTYtNlY3MmE2LDYsMCwwLDEsMTIsMHY1MGg1MEE2LDYsMCwwLDEsMTkwLDEyOFoiLz48L3N2Zz4=');}.icon-house{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTcuOSwxMTAuMWwtODAtODBhMTQsMTQsMCwwLDAtMTkuOCwwbC04MCw4MEExMy45MiwxMy45MiwwLDAsMCwzNCwxMjB2OTZhNiw2LDAsMCwwLDYsNmg2NGE2LDYsMCwwLDAsNi02VjE1OGgzNnY1OGE2LDYsMCwwLDAsNiw2aDY0YTYsNiwwLDAsMCw2LTZWMTIwQTEzLjkyLDEzLjkyLDAsMCwwLDIxNy45LDExMC4xWk0yMTAsMjEwSDE1OFYxNTJhNiw2LDAsMCwwLTYtNkgxMDRhNiw2LDAsMCwwLTYsNnY1OEg0NlYxMjBhMiwyLDAsMCwxLC41OC0xLjQybDgwLTgwYTIsMiwwLDAsMSwyLjg0LDBsODAsODBBMiwyLDAsMCwxLDIxMCwxMjBaIi8+PC9zdmc+');}.icon-logo{--icon:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyAgICB3aWR0aD0iMzIiICAgIGhlaWdodD0iMzIiICAgIHZpZXdCb3g9IjAgMCAzMiAzMiIgICAgdmVyc2lvbj0iMS4xIiAgICB4bWw6c3BhY2U9InByZXNlcnZlIiAgICBzdHlsZT0iY2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVjYXA6c3F1YXJlO3N0cm9rZS1saW5lam9pbjpiZXZlbDtzdHJva2UtbWl0ZXJsaW1pdDoxLjUiICAgIGlkPSJzdmcxMiIgICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiAgICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcyAgICBpZD0iZGVmczEyIiAvPjxwYXRoICAgIGQ9Ik0gMTYsMi4wOTE3OTY5IEMgOC4yODYyNTM4LDIuMDkxNzk2OSAyLjAyNTM5MDcsOC4zMjE0NzYzIDIuMDI1MzkwNiwxNiAyLjAyNTM5MDYsMjMuNjc4NTI0IDguMjg2MjUzOCwyOS45MDgyMDMgMTYsMjkuOTA4MjAzIDIzLjcxMzc0NiwyOS45MDgyMDMgMjkuOTc0NjA5LDIzLjY3ODUyNCAyOS45NzQ2MDksMTYgMjkuOTc0NjA5LDguMzIxNDc2MyAyMy43MTM3NDYsMi4wOTE3OTY5IDE2LDIuMDkxNzk2OSBaIG0gMCwwLjYwNTQ2ODcgYyAwLjIwMzk4LDAgMC40MDU2ODMsMC4wMDY2NCAwLjYwNzQyMiwwLjAxNTYyNSAwLjE5NjUxNiwwLjAwODc1IDAuMzkxNzI4LDAuMDIxOTcyIDAuNTg1OTM3LDAuMDM5MDYzIC0wLjE5NDE2NiwtMC4wMTcwODEgLTAuMzg5NDY3LC0wLjAzMDMxNiAtMC41ODU5MzcsLTAuMDM5MDYzIFYgMjkuMjg3MTA5IGMgMC4xOTY0NywtMC4wMDg3IDAuMzkxNzcxLC0wLjAyMTk4IDAuNTg1OTM3LC0wLjAzOTA2IC0wLjE5NDIwOSwwLjAxNzA5IC0wLjM4OTQyMSwwLjAzMDMxIC0wLjU4NTkzNywwLjAzOTA2IEMgMTYuNDA1NjgzLDI5LjI5NjA5IDE2LjIwMzk4LDI5LjMwMjczNCAxNiwyOS4zMDI3MzQgOC42MTIxNjcsMjkuMzAyNzM0IDIuNjMwODU5NCwyMy4zNDk0MDggMi42MzA4NTk0LDE2IDIuNjMwODU5NCw4LjY1MDU5MTggOC42MTIxNjcxLDIuNjk3MjY1NiAxNiwyLjY5NzI2NTYgWiBtIDEuMjgxMjUsMC4wNjI1IGMgMC4yMTQ5ODYsMC4wMjAzMjkgMC40Mjg3NCwwLjA0NTg0NSAwLjY0MDYyNSwwLjA3NjE3MiAwLjIxMTQxMiwwLjAzMDI1OSAwLjQyMDgyMywwLjA2NTQ5NyAwLjYyODkwNiwwLjEwNTQ2ODggQyAxOC4zNDI4MiwyLjkwMTQ3NDYgMTguMTMzMTU5LDIuODY2MTcxOCAxNy45MjE4NzUsMi44MzU5Mzc1IDE3LjcwOTkxNSwyLjgwNTYwNjYgMTcuNDk2MzEsMi43ODAwOTU1IDE3LjI4MTI1LDIuNzU5NzY1NiBaIG0gMS4yODcxMDksMC4xODM1OTM4IGMgMC4yMTExMDcsMC4wNDA4NDEgMC40MTk1MzMsMC4wODgwODEgMC42MjY5NTMsMC4xMzg2NzE5IDAuMTc2MDc3LDAuMDQyOTQ2IDAuMzUwMTg2LDAuMDkwODIgMC41MjM0MzgsMC4xNDA2MjUgLTAuMTczMDk1LC0wLjA0OTczMSAtMC4zNDc1MjUsLTAuMDk3NzM4IC0wLjUyMzQzOCwtMC4xNDA2MjUgLTAuMjA3NDI4LC0wLjA1MDU3MSAtMC40MTU4NCwtMC4wOTc4NDcgLTAuNjI2OTUzLC0wLjEzODY3MTkgeiBtIDEuMjg3MTEsMC4zMTgzNTk0IGMgMC4xNDQ0MTEsMC4wNDMxODUgMC4yODczODQsMC4wODg4NTMgMC40Mjk2ODcsMC4xMzY3MTg3IC0wLjE0MjM0OCwtMC4wNDc4NTcgLTAuMjg1MjMxLC0wLjA5MzU0MyAtMC40Mjk2ODcsLTAuMTM2NzE4NyB6IG0gMC42MTcxODcsMC4yMDExNzE4IGMgMC4xNjc2NzIsMC4wNTkxOTEgMC4zMzM1MzcsMC4xMjE5MTcxIDAuNDk4MDQ3LDAuMTg3NSAtMC4xNjQ1NjEsLTAuMDY1NTc0IC0wLjMzMDMyNCwtMC4xMjgzMTg3IC0wLjQ5ODA0NywtMC4xODc1IHogbSAwLjU2MjUsMC4yMTI4OTA3IGMgMC4xNzYxNzgsMC4wNzEyOTcgMC4zNTExMDcsMC4xNDYxNDY0IDAuNTIzNDM4LDAuMjI0NjA5MyAtMC4xNzIyMTgsLTAuMDc4MzcxIC0wLjM0NzM4LC0wLjE1MzM5MTYgLTAuNTIzNDM4LC0wLjIyNDYwOTMgeiBtIC01LjUyNzM0MywwLjExOTE0MDYgLTAuMTIxMDk0LDAuMDA1ODYgQyA4Ljg5ODA2NTIsNC4xMTkzODMgMy43MjY1NjI1LDkuNDY0MjE4NSAzLjcyNjU2MjUsMTYgYyAwLDYuNTM1ODE3IDUuMTcxNTAyNSwxMS44ODA2NTIgMTEuNjYwMTU2NSwxMi4xOTkyMTkgbCAwLjEyMTA5NCwwLjAwNTkgMC4wMTE3MiwtMC4yNDIxODcgLTAuMTIxMDkzLC0wLjAwNTkgQyA5LjAzNjA5MjgsMjcuNjQ0NjY0IDMuOTY4NzUsMjIuNDA3OTY1IDMuOTY4NzUsMTYgMy45Njg3NSw5LjU5MjA3MjEgOS4wMzYwOTY0LDQuMzU1MzY5OCAxNS4zOTg0MzgsNC4wNDI5Njg3IGwgMC4xMjEwOTMsLTAuMDA1ODYgeiBtIDYuMTA5Mzc0LDAuMTMwODU5NCBjIDAuMTY0NjM1LDAuMDc1OTExIDAuMzI3MzY0LDAuMTU1OTgyOCAwLjQ4ODI4MiwwLjIzODI4MTIgLTAuMTYxNTE3LC0wLjA4MjU5NCAtMC4zMjMwMjEsLTAuMTYyMTIwMyAtMC40ODgyODIsLTAuMjM4MjgxMiB6IG0gMC41ODM5ODUsMC4yODcxMDkzIGMgMC4xNTIwMjYsMC4wNzkzIDAuMzAwNzE1LDAuMTYzMTY1MyAwLjQ0OTIxOSwwLjI0ODA0NjkgLTAuMTQ4MjE1LC0wLjA4NDY5MiAtMC4yOTc0OTcsLTAuMTY4OTEzIC0wLjQ0OTIxOSwtMC4yNDgwNDY5IHogbSAwLjU1NjY0LDAuMzA4NTkzOCBjIDAuMTM4NDkzLDAuMDgwODY2IDAuMjc0OTEzLDAuMTY0MzcwOCAwLjQxMDE1NywwLjI1IC0wLjEzNTA3OSwtMC4wODU0ODYgLTAuMjcxODM3LC0wLjE2OTI2MjkgLTAuNDEwMTU3LC0wLjI1IHogbSAwLjU0ODgyOSwwLjMzOTg0MzcgYyAwLjEyMzIwMSwwLjA4MDE1MSAwLjI0NDkwMywwLjE2MjA0OTcgMC4zNjUyMzQsMC4yNDYwOTM4IC0wLjEyMDM0OSwtMC4wODQwMiAtMC4yNDIwMTUsLTAuMTY1OTY2MyAtMC4zNjUyMzQsLTAuMjQ2MDkzOCB6IG0gMC41NDY4NzUsMC4zNzUgYyAwLjEwMzM0OCwwLjA3NDc3MSAwLjIwNTU2LDAuMTUwODk4NiAwLjMwNjY0LDAuMjI4NTE1NiAtMC4xMDEwNzEsLTAuMDc3NTc1IC0wLjIwMzMwMiwtMC4xNTM3ODUgLTAuMzA2NjQsLTAuMjI4NTE1NiB6IG0gLTguMzQ3NjU3LDAuMDcwMzEyIC0wLjEyMTA5MywwLjAwNzgxIEMgOS43MzUzODExLDUuNjMxODMwOCA1LjI0NDE0MDYsMTAuMjk4OTk4IDUuMjQ0MTQwNiwxNiBjIDAsNS43MDEwMzMgNC40OTExNDg1LDEwLjM2ODE3NCAxMC4xNDA2MjU0LDEwLjY4NTU0NyBsIDAuMTIxMDkzLDAuMDA3OCAwLjAxMzY3LC0wLjI0MjE4NyAtMC4xMjEwOTMsLTAuMDA3OCBDIDkuODc0NjI3MiwyNi4xMzMwNDQgNS40ODgyODE0LDIxLjU3Mzc1NyA1LjQ4ODI4MTIsMTYgYyAwLC01LjU3MzcyNCA0LjM4NjM0MiwtMTAuMTMzMDQ2MSA5LjkxMDE1NjgsLTEwLjQ0MzM1OTQgbCAwLjEyMTA5MywtMC4wMDc4MSB6IG0gOC44NDk2MSwwLjMxMDU0NjkgYyAwLjEwMDk1NiwwLjA4MDUyNyAwLjIwMDMwNCwwLjE2Mjc0MTEgMC4yOTg4MjgsMC4yNDYwOTM3IC0wLjA5ODcsLTAuMDgzNDc1IC0wLjE5NzY5MiwtMC4xNjU0NTM1IC0wLjI5ODgyOCwtMC4yNDYwOTM3IHogbSAwLjQ5MDIzNCwwLjQxMDE1NjIgYyAwLjA5NDk3LDAuMDgzNDYyIDAuMTg4NzEzLDAuMTY3ODI3MiAwLjI4MTI1LDAuMjUzOTA2MyAtMC4wOTIzLC0wLjA4NTgxMyAtMC4xODY1MzUsLTAuMTcwNjk0OSAtMC4yODEyNSwtMC4yNTM5MDYzIHogbSAwLjQ0MzM1OSwwLjQwODIwMzIgQyAyNS4zOTM4NzcsNi41MzYzNjA5IDI1LjQ5ODE0Nyw2LjYzODAzNCAyNS41OTk2MDksNi43NDIxODcgMjUuNDk3OTc5LDYuNjM3OTAyIDI1LjM5NDA1NCw2LjUzNjQ4MjggMjUuMjg5MDYyLDYuNDM1NTQ2NCBaIE0gMTUuNTA1ODU5LDYuODIwMzEyIDE1LjM4NDc2Niw2LjgyODEyMiBDIDEwLjU3NDc5Niw3LjE0Mzc4OTUgNi43NjM2NzE5LDExLjEzMzk2MyA2Ljc2MzY3MTksMTYgYyAwLDQuODY2MDM4IDMuODExMDMyMSw4Ljg1NjE4OCA4LjYyMTA5NDEsOS4xNzE4NzUgbCAwLjEyMTA5MywwLjAwNzggMC4wMTU2MywtMC4yNDIxODcgLTAuMTIxMDkzLC0wLjAwNzggQyAxMC43MTUxLDI0LjYyMjE4OCA3LjAwNTg1OTQsMjAuNzM5NTMgNy4wMDU4NTk0LDE2IGMgMCwtNC43Mzk1MjkgMy43MDkyNTE2LC04LjYyMjIxNjggOC4zOTQ1MzE2LC04LjkyOTY4NzUgTCAxNS41MjE0ODQsNy4wNjI1IFogbSAxMC4yMTg3NSwwLjA1MjczNCBjIDAuMDkzNzcsMC4wOTg4ODYgMC4xODY2MjgsMC4xOTkwNjk0IDAuMjc3MzQ0LDAuMzAwNzgxMiBDIDI1LjkxMTE0Myw3LjA3MjAzNDUgMjUuODE4NDc5LDYuOTcyMDA3OSAyNS43MjQ2MDksNi44NzMwNDYgWiBtIDAuNDM5NDUzLDAuNDg2MzI4MSBjIDAuMDk0MzksMC4xMDk4MzY1IDAuMTg2NTM0LDAuMjIxMDkyNCAwLjI3NzM0NCwwLjMzMzk4NDQgLTAuMDkwNjksLTAuMTEyNzA0NCAtMC4xODMwODEsLTAuMjI0MzI0OSAtMC4yNzczNDQsLTAuMzMzOTg0NCB6IG0gMC4zNTM1MTYsMC40Mjk2ODc1IGMgMC4xMDE5NDcsMC4xMjkxNDA4IDAuMjAxNjQ3LDAuMjU5NjQ5NiAwLjI5ODgyOCwwLjM5MjU3ODEgQyAyNi43MTkwODUsOC4wNDg1NTI4IDI2LjYxOTY3OSw3LjkxODM1MiAyNi41MTc1NzgsNy43ODkwNjE2IFogTSAyNi45MTAxNTYsOC4zMTI1IGMgMC4wODU5NywwLjEyMDYyOTIgMC4xNzE5MTgsMC4yNDE2NzMzIDAuMjUzOTA2LDAuMzY1MjM0NCBDIDI3LjA4MjE2MSw4LjU1NDM0MzYgMjYuOTk2MDM1LDguNDMyOTY1NSAyNi45MTAxNTYsOC4zMTI1IFogbSAtMTEuNDA2MjUsMC4wMjM0MzcgLTAuMTIxMDkzLDAuMDA3ODEgQyAxMS40MTI3OTgsOC42NTcxMTA1IDguMjgzMjAzMSwxMS45NjkxODcgOC4yODMyMDMxLDE2IGMgMCw0LjAzMDgzNSAzLjEyOTQwNzksNy4zNDI5MTggNy4wOTk2MDk5LDcuNjU2MjUgbCAwLjEyMTA5MywwLjAwNzggMC4wMTk1MywtMC4yNDAyMzQgLTAuMTIxMDk0LC0wLjAwOTggQyAxMS41NTU2NjUsMjMuMTEwNTcyIDguNTI1MzkwNiwxOS45MDU0MDkgOC41MjUzOTA2LDE2IGMgMCwtMy45MDUzODcgMy4wMzAyNzA0LC03LjExMDQ1NTggNi44NzY5NTM0LC03LjQxNDA2MjUgbCAwLjEyMTA5NCwtMC4wMDk3NyB6IG0gMTEuNzg3MTEsMC41NDI5Njg4IGMgMC4wNjkwMywwLjEwODE3MDQgMC4xMzkxMzMsMC4yMTU5MTA0IDAuMjA1MDc4LDAuMzI2MTcxOCAtMC4wNjU5LC0wLjExMDE1MTMgLTAuMTM2MDk5LC0wLjIxODEwODQgLTAuMjA1MDc4LC0wLjMyNjE3MTggeiBtIDAuMzQ1NzAzLDAuNTcyMjY1NiBjIDAuMDUzMjcsMC4wOTM1NTkgMC4xMDcxNjIsMC4xODYyOTU0IDAuMTU4MjAzLDAuMjgxMjUgLTAuMDUxMTIsLTAuMDk1MDgyIC0wLjEwNDg0NCwtMC4xODc1Njg1IC0wLjE1ODIwMywtMC4yODEyNSB6IG0gLTEyLjEzNDc2NiwwLjM5ODQzOCAtMC4xMjEwOTQsMC4wMTM2NzIgQyAxMi4yNTE1MjcsMTAuMTczMDgxIDkuODAyNzM0NCwxMi44MDQ4NzMgOS44MDI3MzQ0LDE2IGMgMCwzLjE5NTE0NCAyLjQ0ODUxMjYsNS44MjY5MiA1LjU3ODEyNDYsNi4xMzY3MTkgbCAwLjEyMTA5NCwwLjAxMzY3IDAuMDIzNDQsLTAuMjQyMTg4IC0wLjEyMTA5NCwtMC4wMTE3MiBDIDEyLjM5NjI0NiwyMS41OTg3MjUgMTAuMDQ0OTIyLDE5LjA3MTM0OCAxMC4wNDQ5MjIsMTYgYyAwLC0zLjA3MTMyOSAyLjM1MTMyOCwtNS41OTg3MTkgNS4zNTkzNzUsLTUuODk2NDg0IGwgMC4xMjEwOTQsLTAuMDExNzIgeiBtIDEyLjQ3NDYwOSwwLjI0MDIzNDYgYyAwLjAzMDk1LDAuMDYyMDIgMC4wNjM3NSwwLjEyMjk4NiAwLjA5Mzc1LDAuMTg1NTQ3IC0wLjAyOTk1LC0wLjA2MjQzIC0wLjA2Mjg1LC0wLjEyMzY2NCAtMC4wOTM3NSwtMC4xODU1NDcgeiBtIDAuMjgzMjA0LDAuNTk5NjA5IGMgMC4wMjU0LDAuMDU4MDIgMC4wNTE1OCwwLjExNTM4NCAwLjA3NjE3LDAuMTczODI4IC0wLjAyNDU4LC0wLjA1ODQxIC0wLjA1MDc4LC0wLjExNTg0OSAtMC4wNzYxNywtMC4xNzM4MjggeiBtIDAuMjM0Mzc1LDAuNTc0MjE5IGMgMC4wMjY0MiwwLjA2OTAyIDAuMDU0NzgsMC4xMzc0NyAwLjA4MDA4LDAuMjA3MDMxIC0wLjAyNTM2LC0wLjA2OTcyIC0wLjA1MzU5LC0wLjEzNzg2MSAtMC4wODAwOCwtMC4yMDcwMzEgeiBtIC0xMi45OTgwNDcsMC4xMDU0NjkgLTAuMTE5MTQxLDAuMDE1NjMgQyAxMy4wODk4MDUsMTEuNjg4NjA0IDExLjMyMjI2NiwxMy42NDE0OTMgMTEuMzIyMjY2LDE2IGMgMCwyLjM1ODUyMSAxLjc2NzE3Nyw0LjMxMTM4NyA0LjA1NDY4Nyw0LjYxNTIzNCBsIDAuMTE5MTQxLDAuMDE1NjMgMC4wMzMyLC0wLjI0MDIzNCBMIDE1LjQwODIsMjAuMzc1IEMgMTMuMjM4ODQ1LDIwLjA4Njg0NyAxMS41NjQ0NSwxOC4yMzc0NjMgMTEuNTY0NDUsMTYgYyAwLC0yLjIzNzQ0NyAxLjY3NDM5NSwtNC4wODY4NDYgMy44NDM3NSwtNC4zNzUgbCAwLjEyMTA5NCwtMC4wMTU2MyB6IE0gMjguODc1LDEyLjQxNjAxNiBjIDAuMDMwOCwwLjEwOTg3NSAwLjA2Mzc4LDAuMjE5MDczIDAuMDkxOCwwLjMzMDA3OCAtMC4wMjc5OSwtMC4xMTA4NDYgLTAuMDYxMDMsLTAuMjIwMzYgLTAuMDkxOCwtMC4zMzAwNzggeiBtIC0xMy4zODg2NzIsMC40Nzg1MTUgLTAuMTE3MTg3LDAuMDIzNDQgQyAxMy45MjgwNzYsMTMuMjA5NjMyIDEyLjgzOTg0NCwxNC40ODA2NTEgMTIuODM5ODQ0LDE2IGMgMCwxLjUxOTM1IDEuMDg3ODAyLDIuNzkwMzY1IDIuNTI5Mjk3LDMuMDgyMDMxIGwgMC4xMTcxODcsMC4wMjM0NCAwLjA0ODgzLC0wLjIzODI4MiAtMC4xMTkxNCwtMC4wMjM0NCBDIDE0LjA4NTM0MiwxOC41NzQ1MSAxMy4wODM5ODQsMTcuNDAzODUyIDEzLjA4Mzk4NCwxNiBjIDAsLTEuNDAzODUxIDEuMDAxMzYyLC0yLjU3NDUwNyAyLjMzMjAzMiwtMi44NDM3NSBsIDAuMTE5MTQsLTAuMDIzNDQgeiBNIDI5LDEyLjg5NjQ4NCBDIDI5LjAzODA2LDEzLjA1NTA3IDI5LjA3NTEyLDEzLjIxNDI2MiAyOS4xMDc0MjIsMTMuMzc1IDI5LjA3NTA2NywxMy4yMTQwNTQgMjkuMDM4MTMyLDEzLjA1NTI3MSAyOSwxMi44OTY0ODQgWiBtIDAuMTM4NjcyLDAuNjQ2NDg1IGMgMC4wMjk1NywwLjE1NzcwOCAwLjA1ODEsMC4zMTQ5OTEgMC4wODIwMywwLjQ3NDYwOSAtMC4wMjM5MSwtMC4xNTkyNjIgLTAuMDUyNTEsLTAuMzE3MjUgLTAuMDgyMDMsLTAuNDc0NjA5IHogbSAtMTMuNjgzNTk0LDAuOTEyMTA5IC0wLjExMTMyOCwwLjA0ODgzIEMgMTQuNzY0OTMyLDE0Ljc1NjA0MyAxNC4zNTkzNzUsMTUuMzMxNjcyIDE0LjM1OTM3NSwxNiBjIDAsMC42NjgzMjkgMC40MDUxMjcsMS4yNDM5NTIgMC45ODQzNzUsMS40OTYwOTQgbCAwLjExMTMyOCwwLjA0ODgzIDAuMDk3NjYsLTAuMjIyNjU2IC0wLjExMTMyOCwtMC4wNDY4NyBDIDE0Ljk0ODAwMywxNy4wNjA2MDYgMTQuNjAxNTYsMTYuNTcwNDM5IDE0LjYwMTU2MywxNiBjIDAsLTAuNTcwNDM4IDAuMzQ2NDQ3LC0xLjA2MDYyIDAuODM5ODQzLC0xLjI3NTM5MSBsIDAuMTExMzI4LC0wLjA0Njg3IHogbSAxMy43NjU2MjUsMy41MjczNDQgYyAtMC4wMjM5MywwLjE1OTYxOCAtMC4wNTI0NiwwLjMxNjkwMSAtMC4wODIwMywwLjQ3NDYwOSAwLjAyOTUyLC0wLjE1NzM1OSAwLjA1ODEzLC0wLjMxNTM0NyAwLjA4MjAzLC0wLjQ3NDYwOSB6IE0gMjkuMTA3NDIyLDE4LjYyNSBjIC0wLjAzMjMsMC4xNjA3MzggLTAuMDY5MzYsMC4zMTk5MyAtMC4xMDc0MjIsMC40Nzg1MTYgMC4wMzgxMywtMC4xNTg3ODcgMC4wNzUwNywtMC4zMTc1NyAwLjEwNzQyMiwtMC40Nzg1MTYgeiBtIC0wLjE0MDYyNSwwLjYyODkwNiBjIC0wLjAyODAyLDAuMTExMDA1IC0wLjA2MSwwLjIyMDIwMyAtMC4wOTE4LDAuMzMwMDc4IDAuMDMwNzcsLTAuMTA5NzE4IDAuMDYzOCwtMC4yMTkyMzIgMC4wOTE4LC0wLjMzMDA3OCB6IG0gLTAuMzkyNTc4LDEuMjc1MzkxIGMgLTAuMDI1MywwLjA2OTU2IC0wLjA1MzY2LDAuMTM4MDE2IC0wLjA4MDA4LDAuMjA3MDMxIDAuMDI2NDksLTAuMDY5MTcgMC4wNTQ3MiwtMC4xMzczMTIgMC4wODAwOCwtMC4yMDcwMzEgeiBtIC0wLjIzODI4MiwwLjYwNzQyMiBjIC0wLjAyNDU5LDAuMDU4NDQgLTAuMDUwNzcsMC4xMTU4MTEgLTAuMDc2MTcsMC4xNzM4MjggMC4wMjUzOSwtMC4wNTc5OCAwLjA1MTU5LC0wLjExNTQyMiAwLjA3NjE3LC0wLjE3MzgyOCB6IG0gLTAuMjY1NjI1LDAuNTg3ODkgYyAtMC4wMywwLjA2MjU2IC0wLjA2MjgsMC4xMjM1MzEgLTAuMDkzNzUsMC4xODU1NDcgMC4wMzA5LC0wLjA2MTg4IDAuMDYzOCwtMC4xMjMxMiAwLjA5Mzc1LC0wLjE4NTU0NyB6IG0gLTAuMjc1MzksMC41NDI5NjkgYyAtMC4wNTEwNCwwLjA5NDk1IC0wLjEwNDkzMiwwLjE4NzY5MSAtMC4xNTgyMDMsMC4yODEyNSAwLjA1MzM2LC0wLjA5MzY4IDAuMTA3MDgxLC0wLjE4NjE2OCAwLjE1ODIwMywtMC4yODEyNSB6IG0gLTAuMjk4ODI4LDAuNTI3MzQ0IGMgLTAuMDY1OTQsMC4xMTAyNjEgLTAuMTM2MDUxLDAuMjE4MDAxIC0wLjIwNTA3OCwwLjMyNjE3MiAwLjA2ODk4LC0wLjEwODA2NCAwLjEzOTE3NiwtMC4yMTYwMjEgMC4yMDUwNzgsLTAuMzI2MTcyIHogbSAtMC4zMzIwMzIsMC41MjczNDQgYyAtMC4wODE5OSwwLjEyMzU2MSAtMC4xNjc5MzEsMC4yNDQ2MDUgLTAuMjUzOTA2LDAuMzY1MjM0IDAuMDg1ODgsLTAuMTIwNDY2IDAuMTcyMDA1LC0wLjI0MTg0NCAwLjI1MzkwNiwtMC4zNjUyMzQgeiBtIC0wLjM0NzY1NiwwLjQ5NjA5MyBjIC0wLjA5NzE4LDAuMTMyOTI5IC0wLjE5Njg4MSwwLjI2MzQzOCAtMC4yOTg4MjgsMC4zOTI1NzggMC4xMDIxMDEsLTAuMTI5Mjg5IDAuMjAxNTA3LC0wLjI1OTQ5IDAuMjk4ODI4LC0wLjM5MjU3OCB6IG0gLTAuMzc1LDAuNDg4MjgyIGMgLTAuMDkwODEsMC4xMTI4OTIgLTAuMTgyOTU0LDAuMjI0MTQ4IC0wLjI3NzM0NCwwLjMzMzk4NCAwLjA5NDI2LC0wLjEwOTY1OSAwLjE4NjY1MSwtMC4yMjEyNzkgMC4yNzczNDQsLTAuMzMzOTg0IHogbSAtMC40Mzk0NTMsMC41MTk1MzEgYyAtMC4wOTA3MiwwLjEwMTcxMiAtMC4xODM1NzUsMC4yMDE4OTUgLTAuMjc3MzQ0LDAuMzAwNzgxIDAuMDkzODcsLTAuMDk4OTYgMC4xODY1MzMsLTAuMTk4OTg4IDAuMjc3MzQ0LC0wLjMwMDc4MSB6IG0gLTAuNDAyMzQ0LDAuNDMxNjQgYyAtMC4xMDE0NjIsMC4xMDQxNTMgLTAuMjA1NzMyLDAuMjA1ODI3IC0wLjMxMDU0NywwLjMwNjY0MSAwLjEwNDk5MiwtMC4xMDA5MzYgMC4yMDg5MTcsLTAuMjAyMzU1IDAuMzEwNTQ3LC0wLjMwNjY0MSB6IG0gLTAuNDcyNjU2LDAuNDYwOTM4IGMgLTAuMDkyNTQsMC4wODYwOCAtMC4xODYyNzksMC4xNzA0NDQgLTAuMjgxMjUsMC4yNTM5MDYgMC4wOTQ3MiwtMC4wODMyMSAwLjE4ODk1NSwtMC4xNjgwOTMgMC4yODEyNSwtMC4yNTM5MDYgeiBtIC0wLjQ3MjY1NiwwLjQxNzk2OSBjIC0wLjA5ODUyLDAuMDgzMzUgLTAuMTk3ODcyLDAuMTY1NTY2IC0wLjI5ODgyOCwwLjI0NjA5MyAwLjEwMTEzNiwtMC4wODA2NCAwLjIwMDEzMiwtMC4xNjI2MTkgMC4yOTg4MjgsLTAuMjQ2MDkzIHogbSAtMC40OTQxNDEsMC4zOTg0MzcgYyAtMC4xMDEwOCwwLjA3NzYyIC0wLjIwMzI5MiwwLjE1Mzc0NSAtMC4zMDY2NCwwLjIyODUxNiAwLjEwMzMzOCwtMC4wNzQ3MyAwLjIwNTU2OSwtMC4xNTA5NCAwLjMwNjY0LC0wLjIyODUxNiB6IG0gLTAuNDg4MjgxLDAuMzU3NDIyIGMgLTAuMTIwMzMxLDAuMDg0MDQgLTAuMjQyMDMzLDAuMTY1OTQzIC0wLjM2NTIzNCwwLjI0NjA5NCAwLjEyMzIxOSwtMC4wODAxMyAwLjI0NDg4NSwtMC4xNjIwNzQgMC4zNjUyMzQsLTAuMjQ2MDk0IHogbSAtMC41MDM5MDYsMC4zMzU5MzggYyAtMC4xMzUyNDQsMC4wODU2MyAtMC4yNzE2NjQsMC4xNjkxMzMgLTAuNDEwMTU3LDAuMjUgMC4xMzgzMiwtMC4wODA3NCAwLjI3NTA3OCwtMC4xNjQ1MTQgMC40MTAxNTcsLTAuMjUgeiBtIC0wLjUxNzU3OCwwLjMxMDU0NiBjIC0wLjE0ODUwNCwwLjA4NDg4IC0wLjI5NzE5MywwLjE2ODc0NyAtMC40NDkyMTksMC4yNDgwNDcgMC4xNTE3MjIsLTAuMDc5MTMgMC4zMDEwMDQsLTAuMTYzMzU1IDAuNDQ5MjE5LC0wLjI0ODA0NyB6IG0gLTAuNTQ0OTIyLDAuMjk2ODc1IGMgLTAuMTYwOTE4LDAuMDgyMyAtMC4zMjM2NDcsMC4xNjIzNyAtMC40ODgyODIsMC4yMzgyODIgMC4xNjUyNjEsLTAuMDc2MTYgMC4zMjY3NjUsLTAuMTU1Njg4IDAuNDg4MjgyLC0wLjIzODI4MiB6IG0gLTAuNTQ2ODc1LDAuMjYzNjcyIGMgLTAuMTcyMzMxLDAuMDc4NDYgLTAuMzQ3MjYsMC4xNTMzMTIgLTAuNTIzNDM4LDAuMjI0NjEgMC4xNzYwNTgsLTAuMDcxMjIgMC4zNTEyMiwtMC4xNDYyMzkgMC41MjM0MzgsLTAuMjI0NjEgeiBtIC0wLjU4Nzg5MSwwLjI1IGMgLTAuMTY0NTEsMC4wNjU1OCAtMC4zMzAzNzUsMC4xMjgzMDkgLTAuNDk4MDQ3LDAuMTg3NSAwLjE2NzcyMywtMC4wNTkxOCAwLjMzMzQ4NiwtMC4xMjE5MjUgMC40OTgwNDcsLTAuMTg3NSB6IG0gLTAuNjg1NTQ3LDAuMjUxOTUzIGMgLTAuMTQyMzAzLDAuMDQ3ODcgLTAuMjg1Mjc2LDAuMDkzNTMgLTAuNDI5Njg3LDAuMTM2NzE5IDAuMTQ0NDU2LC0wLjA0MzE4IDAuMjg3MzM5LC0wLjA4ODg2IDAuNDI5Njg3LC0wLjEzNjcxOSB6IG0gLTAuNTY2NDA2LDAuMTc1NzgyIGMgLTAuMTczMjUyLDAuMDQ5OCAtMC4zNDczNjEsMC4wOTc2OCAtMC41MjM0MzgsMC4xNDA2MjUgLTAuMjA3NDIsMC4wNTA1OSAtMC40MTU4NDYsMC4wOTc4MyAtMC42MjY5NTMsMC4xMzg2NzIgMC4yMTExMTMsLTAuMDQwODIgMC40MTk1MjUsLTAuMDg4MSAwLjYyNjk1MywtMC4xMzg2NzIgMC4xNzU5MTMsLTAuMDQyODkgMC4zNTAzNDMsLTAuMDkwODkgMC41MjM0MzgsLTAuMTQwNjI1IHogbSAtMS4xNjc5NjksMC4yODEyNSBjIC0wLjIwODA4MywwLjAzOTk3IC0wLjQxNzQ5NCwwLjA3NTIxIC0wLjYyODkwNiwwLjEwNTQ2OCAtMC4yMTE4ODUsMC4wMzAzMyAtMC40MjU2MzksMC4wNTU4NCAtMC42NDA2MjUsMC4wNzYxNyAwLjIxNTA2LC0wLjAyMDMzIDAuNDI4NjY1LC0wLjA0NTg0IDAuNjQwNjI1LC0wLjA3NjE3IDAuMjExMjg0LC0wLjAzMDIzIDAuNDIwOTQ1LC0wLjA2NTU0IDAuNjI4OTA2LC0wLjEwNTQ2OCB6IiAgICBzdHlsZT0iYmFzZWxpbmUtc2hpZnQ6YmFzZWxpbmU7Y2xpcC1ydWxlOm5vbnplcm87ZGlzcGxheTppbmxpbmU7b3ZlcmZsb3c6dmlzaWJsZTt2ZWN0b3ItZWZmZWN0Om5vbmU7ZmlsbDojMjIyMjIyO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtlbmFibGUtYmFja2dyb3VuZDphY2N1bXVsYXRlO3N0b3AtY29sb3I6IzAwMDAwMDtzdG9wLW9wYWNpdHk6MSIgICAgaWQ9InBhdGgxNCIgLz48L3N2Zz4=');}.icon-jakevan{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHN0eWxlPSJjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsLXJ1bGU6ZXZlbm9kZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MiIgdmlld0JveD0iMCAwIDMyIDMyIj48cGF0aCBkPSJNMTcuODggMTQuNjhIMTIuOWwtLjQzLTEuNjNIOS41OGwtLjQ1IDEuNjNINi41bDIuODktOC43NGgzLjJsMi44OSA4LjY0di04LjZoMi40djMuNzhjLjEtLjIuMjItLjM4LjM1LS41Ny4xMy0uMi4yNi0uMzcuMzktLjU0bDEuODYtMi42N2g3Ljh2MS44OUgyNS40djEuMzdoMi42NXYxLjg4SDI1LjR2MS42NWgyLjg2djEuOTFoLTcuOTNsLTEuNzUtMy4zMi0uNy40MXptNS4xMy04LjU5LTIuNyAzLjc5IDIuNyA0Ljc0em0tMTEuMDUgNS4wMy0uMzgtMS40M2ExMzYuODYgMTM2Ljg2IDAgMCAwLS40LTEuNTVMMTEgNy4zOGExNy43NiAxNy43NiAwIDAgMS0uMzYgMS42bC0uMTguNzEtLjM5IDEuNDN6bS04LjU4IDYuM2E1Ljc0IDUuNzQgMCAwIDEtMS4yNC0uMTN2LTEuODNsLjQxLjA4Yy4xNS4wMy4zLjA1LjQ3LjA1LjMgMCAuNTEtLjA2LjY3LS4xN2EuOTIuOTIgMCAwIDAgLjM0LS41MmMuMDYtLjIzLjEtLjUyLjEtLjg2VjUuOThoMi40djcuODVjMCAuODgtLjEzIDEuNTctLjQgMi4xLS4yNi41Mi0uNjMuOS0xLjEgMS4xNC0uNDguMjMtMS4wMy4zNS0xLjY1LjM1WiIgc3R5bGU9ImZpbGw6Y3VycmVudENvbG9yO3N0cm9rZS13aWR0aDouMDE4NDM5MiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMS40IC42Nikgc2NhbGUoLjk2MDUwMTM0KSIvPjxwYXRoIGQ9Ik0yMi44MiAyMi4yN2gtNC4wNmwtLjM3LTEuNEgxNS45bC0uMzkgMS40aC0yLjI2bDIuNDktNy41M2gyLjc1bDIuNDkgNy40NHYtNy40MWgyLjdsMi43NyA1LjIxaC4wM2E0MS4xIDQxLjEgMCAwIDEtLjA3LTEuODJ2LTMuMzloMS44M3Y3LjVoLTIuN2wtMi43OS01LjI4aC0uMDRhMTIuODMgMTIuODMgMCAwIDEgLjA4IDEuMjZsLjAyLjY0em0tNC44Ni0zLjA3LS4zMy0xLjIzYTg5LjA3IDg5LjA3IDAgMCAwLS4zNS0xLjM0bC0uMTQtLjY1YTE1LjA0IDE1LjA0IDAgMCAxLS4zMSAxLjM3bC0uMTYuNjItLjMzIDEuMjN6bS0zLjg1LTQuNDMtMi41IDcuNUg5LjJsLTIuNS03LjVoMi4zMmwxLjA0IDMuOGExNS4wMyAxNS4wMyAwIDAgMSAuMzYgMS43NiA3LjYxIDcuNjEgMCAwIDEgLjItMS4ybC4xNC0uNTQgMS4wNi0zLjgyeiIgc3R5bGU9ImZpbGw6Y3VycmVudENvbG9yO3N0cm9rZS13aWR0aDouMDE1OTg4NCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMS40IC42Nikgc2NhbGUoLjk2MDUwMTM0KSIvPjxwYXRoIGQ9Ik0xMS45IDI0LjIxYzAgLjQtLjA3LjcyLS4yLjk5LS4xNS4yNi0uMzYuNDYtLjYzLjYtLjI4LjEzLS42Mi4yLTEuMDMuMkg5LjJ2LTMuNWguOTdjLjM4IDAgLjcuMDYuOTYuMTkuMjUuMTMuNDUuMzIuNTguNTguMTQuMjUuMi41Ny4yLjk0em0tLjI2LjAxYzAtLjMzLS4wNS0uNjEtLjE2LS44M2ExLjEgMS4xIDAgMCAwLS41MS0uNTEgMS45NSAxLjk1IDAgMCAwLS44Ny0uMTdoLS42NnYzLjA3aC42Yy41MyAwIC45My0uMTMgMS4yLS4zOS4yNy0uMjYuNC0uNjUuNC0xLjE3ek0xNC4yNyAyNmgtMS45NXYtMy41aDEuOTV2LjIyaC0xLjd2MS4zMmgxLjZ2LjIzaC0xLjZ2MS41aDEuN3ptMS4yOC0zLjVjLjI4IDAgLjUyLjAyLjcuMDhhLjguOCAwIDAgMSAuNDQuM2MuMS4xNC4xNC4zMy4xNC41N2EuOS45IDAgMCAxLS4xLjQ1Ljg3Ljg3IDAgMCAxLS4yNy4zMmMtLjEyLjA4LS4yNS4xNC0uNC4xOGwuOTggMS42aC0uM2wtLjkyLTEuNTNoLS44OVYyNmgtLjI1di0zLjV6bS0uMDMuMjFoLS41OXYxLjU1aC43MWMuMyAwIC41Mi0uMDcuNjktLjIxLjE2LS4xNC4yNC0uMzQuMjQtLjYgMC0uMjgtLjA5LS40Ny0uMjYtLjU4LS4xNy0uMS0uNDMtLjE2LS43OS0uMTZ6bTUuNTctLjIyTDIwLjEyIDI2aC0uMjVsLS43Ni0yLjY1LS4wNS0uMTYtLjA0LS4xNGExOC44IDE4LjggMCAwIDEtLjA2LS4yNCAyMC42IDIwLjYgMCAwIDEtLjExLjQ4TDE4LjA5IDI2aC0uMjVsLS45Ni0zLjVoLjI2bC42NyAyLjQ3YTI3LjM2IDI3LjM2IDAgMCAxIC4wOS4zNWwuMDQuMTcuMDMuMTUuMDMtLjE2YTQuODMgNC44MyAwIDAgMSAuMTQtLjUzbC43LTIuNDZoLjI1bC43MyAyLjQ4YTExLjk4IDExLjk4IDAgMCAxIC4xMy41M2wuMDQuMTVhMTEuMDIgMTEuMDIgMCAwIDEgLjE1LS42OGwuNjktMi40OHpNMjMuMjYgMjZoLTEuOTV2LTMuNWgxLjk1di4yMmgtMS43djEuMzJoMS42di4yM2gtMS42djEuNWgxLjd6bTEuMjgtMy41Yy4yOCAwIC41Mi4wMi43MS4wOGEuOC44IDAgMCAxIC40My4zYy4xLjE0LjE0LjMzLjE0LjU3YS45LjkgMCAwIDEtLjEuNDUuODcuODcgMCAwIDEtLjI3LjMyYy0uMTEuMDgtLjI1LjE0LS40LjE4bC45OCAxLjZoLS4zbC0uOTItMS41M2gtLjg4VjI2aC0uMjZ2LTMuNXptLS4wMi4yMWgtLjZ2MS41NWguNzJjLjI5IDAgLjUxLS4wNy42OC0uMjEuMTYtLjE0LjI0LS4zNC4yNC0uNiAwLS4yOC0uMDgtLjQ3LS4yNi0uNTgtLjE3LS4xLS40My0uMTYtLjc4LS4xNnpNMjYuNSAyNmgtLjI1di0zLjVoMS45NXYuMjJoLTEuN3YxLjQ5aDEuNnYuMjJoLTEuNnoiIHN0eWxlPSJmaWxsOmN1cnJlbnRDb2xvcjtzdHJva2Utd2lkdGg6LjAxMDEwNjgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEuNCAuNjYpIHNjYWxlKC45NjA1MDEzNCkiLz48L3N2Zz4=');}.icon-user-square{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDgsMzRINDhBMTQsMTQsMCwwLDAsMzQsNDhWMjA4YTE0LDE0LDAsMCwwLDE0LDE0SDIwOGExNCwxNCwwLDAsMCwxNC0xNFY0OEExNCwxNCwwLDAsMCwyMDgsMzRaTTk0LDEyMGEzNCwzNCwwLDEsMSwzNCwzNEEzNCwzNCwwLDAsMSw5NCwxMjBaTTY1Ljc3LDIxMGE2Ni40Myw2Ni40MywwLDAsMSwyMC43Ny0yOS4zNiw2Niw2NiwwLDAsMSw4Mi45MiwwQTY2LjQzLDY2LjQzLDAsMCwxLDE5MC4yMywyMTBaTTIxMCwyMDhhMiwyLDAsMCwxLTIsMmgtNS4xN2E3Ny44NSw3Ny44NSwwLDAsMC00OS4zOC01MS43MSw0Niw0NiwwLDEsMC01MC45LDBBNzcuODUsNzcuODUsMCwwLDAsNTMuMTcsMjEwSDQ4YTIsMiwwLDAsMS0yLTJWNDhhMiwyLDAsMCwxLDItMkgyMDhhMiwyLDAsMCwxLDIsMloiLz48L3N2Zz4=');}.icon-chat-teardrop{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMzIsMjZhOTguMTEsOTguMTEsMCwwLDAtOTgsOTh2ODRhMTQsMTQsMCwwLDAsMTQsMTRoODRhOTgsOTgsMCwwLDAsMC0xOTZabTAsMTg0SDQ4YTIsMiwwLDAsMS0yLTJWMTI0YTg2LDg2LDAsMSwxLDg2LDg2WiIvPjwvc3ZnPg==');}.icon-house-simple{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTcuOSwxMTAuMWwtODAtODBhMTQsMTQsMCwwLDAtMTkuOCwwbC04MCw4MEExMy45MiwxMy45MiwwLDAsMCwzNCwxMjB2OTZhNiw2LDAsMCwwLDYsNkgyMTZhNiw2LDAsMCwwLDYtNlYxMjBBMTMuOTIsMTMuOTIsMCwwLDAsMjE3LjksMTEwLjFaTTIxMCwyMTBINDZWMTIwYTIsMiwwLDAsMSwuNTgtMS40Mmw4MC04MGEyLDIsMCwwLDEsMi44NCwwbDgwLDgwQTIsMiwwLDAsMSwyMTAsMTIwWiIvPjwvc3ZnPg==');}.icon-caret-left{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjQuMjQsMjAzLjc2YTYsNiwwLDEsMS04LjQ4LDguNDhsLTgwLTgwYTYsNiwwLDAsMSwwLTguNDhsODAtODBhNiw2LDAsMCwxLDguNDgsOC40OEw4OC40OSwxMjhaIi8+PC9zdmc+');}.icon-chat{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTYsNTBINDBBMTQsMTQsMCwwLDAsMjYsNjRWMjI0YTEzLjg4LDEzLjg4LDAsMCwwLDguMDksMTIuNjlBMTQuMTEsMTQuMTEsMCwwLDAsNDAsMjM4YTEzLjg3LDEzLjg3LDAsMCwwLDktMy4zMWwuMDYtLjA1TDgyLjIzLDIwNkgyMTZhMTQsMTQsMCwwLDAsMTQtMTRWNjRBMTQsMTQsMCwwLDAsMjE2LDUwWm0yLDE0MmEyLDIsMCwwLDEtMiwySDgwYTYsNiwwLDAsMC0zLjkyLDEuNDZMNDEuMjYsMjI1LjUzQTIsMiwwLDAsMSwzOCwyMjRWNjRhMiwyLDAsMCwxLDItMkgyMTZhMiwyLDAsMCwxLDIsMloiLz48L3N2Zz4=');}.icon-envelope{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjQsNTBIMzJhNiw2LDAsMCwwLTYsNlYxOTJhMTQsMTQsMCwwLDAsMTQsMTRIMjE2YTE0LDE0LDAsMCwwLDE0LTE0VjU2QTYsNiwwLDAsMCwyMjQsNTBabS05Niw4NS44Nkw0Ny40Miw2MkgyMDguNThaTTEwMS42NywxMjgsMzgsMTg2LjM2VjY5LjY0Wm04Ljg4LDguMTRMMTI0LDE0OC40MmE2LDYsMCwwLDAsOC4xLDBsMTMuNC0xMi4yOEwyMDguNTgsMTk0SDQ3LjQzWk0xNTQuMzMsMTI4LDIxOCw2OS42NFYxODYuMzZaIi8+PC9zdmc+');}.icon-caret-right{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xODAuMjQsMTMyLjI0bC04MCw4MGE2LDYsMCwwLDEtOC40OC04LjQ4TDE2Ny41MSwxMjgsOTEuNzYsNTIuMjRhNiw2LDAsMCwxLDguNDgtOC40OGw4MCw4MEE2LDYsMCwwLDEsMTgwLjI0LDEzMi4yNFoiLz48L3N2Zz4=');}.icon-calendar{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDgsMzRIMTgyVjI0YTYsNiwwLDAsMC0xMiwwVjM0SDg2VjI0YTYsNiwwLDAsMC0xMiwwVjM0SDQ4QTE0LDE0LDAsMCwwLDM0LDQ4VjIwOGExNCwxNCwwLDAsMCwxNCwxNEgyMDhhMTQsMTQsMCwwLDAsMTQtMTRWNDhBMTQsMTQsMCwwLDAsMjA4LDM0Wk00OCw0Nkg3NFY1NmE2LDYsMCwwLDAsMTIsMFY0Nmg4NFY1NmE2LDYsMCwwLDAsMTIsMFY0NmgyNmEyLDIsMCwwLDEsMiwyVjgySDQ2VjQ4QTIsMiwwLDAsMSw0OCw0NlpNMjA4LDIxMEg0OGEyLDIsMCwwLDEtMi0yVjk0SDIxMFYyMDhBMiwyLDAsMCwxLDIwOCwyMTBabS05OC05MHY2NGE2LDYsMCwwLDEtMTIsMFYxMjkuNzFsLTcuMzIsMy42NmE2LDYsMCwxLDEtNS4zNi0xMC43NGwxNi04QTYsNiwwLDAsMSwxMTAsMTIwWm01OS41NywyOS4yNUwxNDgsMTc4aDIwYTYsNiwwLDAsMSwwLDEySDEzNmE2LDYsMCwwLDEtNC44LTkuNkwxNjAsMTQyYTEwLDEwLDAsMSwwLTE2LjY1LTExQTYsNiwwLDEsMSwxMzMsMTI1YTIyLDIyLDAsMSwxLDM2LjYyLDI0LjI2WiIvPjwvc3ZnPg==');}.icon-shuffle{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzYuMjQsMTc5Ljc2YTYsNiwwLDAsMSwwLDguNDhsLTI0LDI0YTYsNiwwLDAsMS04LjQ4LTguNDhMMjE3LjUyLDE5MEgyMDAuOTRhNzAuMTYsNzAuMTYsMCwwLDEtNTctMjkuMzFsLTQxLjcxLTU4LjRBNTguMTEsNTguMTEsMCwwLDAsNTUuMDYsNzhIMzJhNiw2LDAsMCwxLDAtMTJINTUuMDZhNzAuMTYsNzAuMTYsMCwwLDEsNTcsMjkuMzFsNDEuNzEsNTguNEE1OC4xMSw1OC4xMSwwLDAsMCwyMDAuOTQsMTc4aDE2LjU4bC0xMy43Ni0xMy43NmE2LDYsMCwwLDEsOC40OC04LjQ4Wm0tOTIuMDYtNzQuNDFhNS45MSw1LjkxLDAsMCwwLDMuNDgsMS4xMiw2LDYsMCwwLDAsNC44OS0yLjUxbDEuMTktMS42N0E1OC4xMSw1OC4xMSwwLDAsMSwyMDAuOTQsNzhoMTYuNThMMjAzLjc2LDkxLjc2YTYsNiwwLDEsMCw4LjQ4LDguNDhsMjQtMjRhNiw2LDAsMCwwLDAtOC40OGwtMjQtMjRhNiw2LDAsMCwwLTguNDgsOC40OEwyMTcuNTIsNjZIMjAwLjk0YTcwLjE2LDcwLjE2LDAsMCwwLTU3LDI5LjMxTDE0Mi43OCw5N0E2LDYsMCwwLDAsMTQ0LjE4LDEwNS4zNVptLTMyLjM2LDQ1LjNhNiw2LDAsMCwwLTguMzcsMS4zOWwtMS4xOSwxLjY3QTU4LjExLDU4LjExLDAsMCwxLDU1LjA2LDE3OEgzMmE2LDYsMCwwLDAsMCwxMkg1NS4wNmE3MC4xNiw3MC4xNiwwLDAsMCw1Ny0yOS4zMWwxLjE5LTEuNjdBNiw2LDAsMCwwLDExMS44MiwxNTAuNjVaIi8+PC9zdmc+');}.icon-sort-descending{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik00MiwxMjhhNiw2LDAsMCwxLDYtNmg3MmE2LDYsMCwwLDEsMCwxMkg0OEE2LDYsMCwwLDEsNDIsMTI4Wm02LTU4aDU2YTYsNiwwLDAsMCwwLTEySDQ4YTYsNiwwLDAsMCwwLDEyWk0xODQsMTg2SDQ4YTYsNiwwLDAsMCwwLDEySDE4NGE2LDYsMCwwLDAsMC0xMlpNMjI4LjI0LDgzLjc2bC00MC00MGE2LDYsMCwwLDAtOC40OCwwbC00MCw0MGE2LDYsMCwwLDAsOC40OCw4LjQ4TDE3OCw2Mi40OVYxNDRhNiw2LDAsMCwwLDEyLDBWNjIuNDlsMjkuNzYsMjkuNzVhNiw2LDAsMCwwLDguNDgtOC40OFoiLz48L3N2Zz4=');}.icon-sort-ascending{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMjYsMTI4YTYsNiwwLDAsMS02LDZINDhhNiw2LDAsMCwxLDAtMTJoNzJBNiw2LDAsMCwxLDEyNiwxMjhaTTQ4LDcwSDE4NGE2LDYsMCwwLDAsMC0xMkg0OGE2LDYsMCwwLDAsMCwxMlptNTYsMTE2SDQ4YTYsNiwwLDAsMCwwLDEyaDU2YTYsNiwwLDAsMCwwLTEyWm0xMjQuMjQtMjIuMjRhNiw2LDAsMCwwLTguNDgsMEwxOTAsMTkzLjUxVjExMmE2LDYsMCwwLDAtMTIsMHY4MS41MWwtMjkuNzYtMjkuNzVhNiw2LDAsMCwwLTguNDgsOC40OGw0MCw0MGE2LDYsMCwwLDAsOC40OCwwbDQwLTQwQTYsNiwwLDAsMCwyMjguMjQsMTYzLjc2WiIvPjwvc3ZnPg==');}.icon-arrow-elbow-left-down{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzgsNzJhNiw2LDAsMCwxLTYsNkg5NFYyMDEuNTFsMzcuNzYtMzcuNzVhNiw2LDAsMCwxLDguNDgsOC40OGwtNDgsNDhhNiw2LDAsMCwxLTguNDgsMGwtNDgtNDhhNiw2LDAsMCwxLDguNDgtOC40OEw4MiwyMDEuNTFWNzJhNiw2LDAsMCwxLDYtNkgyMzJBNiw2LDAsMCwxLDIzOCw3MloiLz48L3N2Zz4=');}.icon-arrow-elbow-right-down{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjguMjQsMTY0LjI0bC00OCw0OGE2LDYsMCwwLDEtOC40OCwwbC00OC00OGE2LDYsMCwxLDEsOC40OC04LjQ4TDE3MCwxOTMuNTFWNzBIMzJhNiw2LDAsMCwxLDAtMTJIMTc2YTYsNiwwLDAsMSw2LDZWMTkzLjUxbDM3Ljc2LTM3Ljc1YTYsNiwwLDAsMSw4LjQ4LDguNDhaIi8+PC9zdmc+');}.icon-heart{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNzgsNDJjLTIxLDAtMzkuMjYsOS40Ny01MCwyNS4zNEMxMTcuMjYsNTEuNDcsOTksNDIsNzgsNDJhNjAuMDcsNjAuMDcsMCwwLDAtNjAsNjBjMCwyOS4yLDE4LjIsNTkuNTksNTQuMSw5MC4zMWEzMzQuNjgsMzM0LjY4LDAsMCwwLDUzLjA2LDM3LDYsNiwwLDAsMCw1LjY4LDAsMzM0LjY4LDMzNC42OCwwLDAsMCw1My4wNi0zN0MyMTkuOCwxNjEuNTksMjM4LDEzMS4yLDIzOCwxMDJBNjAuMDcsNjAuMDcsMCwwLDAsMTc4LDQyWk0xMjgsMjE3LjExQzExMS41OSwyMDcuNjQsMzAsMTU3LjcyLDMwLDEwMkE0OC4wNSw0OC4wNSwwLDAsMSw3OCw1NGMyMC4yOCwwLDM3LjMxLDEwLjgzLDQ0LjQ1LDI4LjI3YTYsNiwwLDAsMCwxMS4xLDBDMTQwLjY5LDY0LjgzLDE1Ny43Miw1NCwxNzgsNTRhNDguMDUsNDguMDUsMCwwLDEsNDgsNDhDMjI2LDE1Ny43MiwxNDQuNDEsMjA3LjY0LDEyOCwyMTcuMTFaIi8+PC9zdmc+');}.icon-dots-three{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMzgsMTI4YTEwLDEwLDAsMSwxLTEwLTEwQTEwLDEwLDAsMCwxLDEzOCwxMjhaTTYwLDExOGExMCwxMCwwLDEsMCwxMCwxMEExMCwxMCwwLDAsMCw2MCwxMThabTEzNiwwYTEwLDEwLDAsMSwwLDEwLDEwQTEwLDEwLDAsMCwwLDE5NiwxMThaIi8+PC9zdmc+');}.icon-logo-jakevan{--icon:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyAgICB3aWR0aD0iMzIiICAgIGhlaWdodD0iMzIiICAgIHZpZXdCb3g9IjAgMCAzMiAzMiIgICAgdmVyc2lvbj0iMS4xIiAgICB4bWw6c3BhY2U9InByZXNlcnZlIiAgICBzdHlsZT0iY2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVjYXA6c3F1YXJlO3N0cm9rZS1saW5lam9pbjpiZXZlbDtzdHJva2UtbWl0ZXJsaW1pdDoxLjUiICAgIGlkPSJzdmcxMCIgICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiAgICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcyAgICBpZD0iZGVmczEwIiAvPjxwYXRoICAgIGQ9Ik0gMTUuNTA3ODEzLDMuNzEyODkwNiAxNS4zODQ3NjYsMy43MTg3NSBDIDguODg0Mzg3NCw0LjAzOTQ5NDEgMy43MDUwNzgxLDkuNDIxMjM3MiAzLjcwNTA3ODEsMTYgYyAwLDYuNTc4Nzk5IDUuMTc5MzA4OSwxMS45NjA1NDMgMTEuNjc5Njg3OSwxMi4yODEyNSBsIDAuMTIzMDQ3LDAuMDA1OSAwLjAxMTcyLC0wLjI0NDE0IC0wLjEyMzA0NywtMC4wMDU5IEMgOS4wMjM1NjQ2LDI3LjcyMjY5IDMuOTQ3MjY1NiwyMi40NTEwMzcgMy45NDcyNjU2LDE2IGMgMCwtNi40NTEwMDA2IDUuMDc2MzAwNiwtMTEuNzIyNjU0NCAxMS40NDkyMTg0LC0xMi4wMzcxMDk0IGwgMC4xMjMwNDcsLTAuMDA1ODYgeiBtIC0wLjAwMiwxLjUyMzQzNzUgLTAuMTIxMDkzLDAuMDA3ODEgQyA5LjcyNTA3MDMsNS41NjM2NTE2IDUuMjI2NTYyNSwxMC4yNjE1NjYgNS4yMjY1NjI1LDE2IGMgMCw1LjczODQ2NSA0LjQ5ODQ2MTgsMTAuNDM2MzUgMTAuMTU4MjAzNSwxMC43NTU4NTkgbCAwLjEyMTA5MywwLjAwNzggMC4wMTM2NywtMC4yNDIxODggLTAuMTIxMDkzLC0wLjAwNzggQyA5Ljg2NTQ5OTYsMjYuMjAxMzIyIDUuNDY4NzUsMjEuNjExMjc5IDUuNDY4NzUsMTYgYyAwLC01LjYxMTI0OCA0LjM5Njc0NzYsLTEwLjIwMTMyMTcgOS45Mjk2ODgsLTEwLjUxMzY3MTkgbCAwLjEyMTA5MywtMC4wMDU4NiB6IG0gLTAuMDAyLDEuNTIzNDM3NSAtMC4xMjEwOTMsMC4wMDc4MSBDIDEwLjU2NDAzOCw3LjA4NTM2ODggNi43NDgwNDY5LDExLjEwMjA3NiA2Ljc0ODA0NjksMTYgYyAwLDQuODk3OTIzIDMuODE1ODk5MSw4LjkxNDYwNiA4LjYzNDc2NjEsOS4yMzI0MjIgbCAwLjEyMTA5MywwLjAwNzggMC4wMTc1OCwtMC4yNDQxNCAtMC4xMjMwNDYsLTAuMDA3OCBDIDEwLjcwNTQ3NywyNC42Nzg3NjggNi45OTIxODc1LDIwLjc3MTUwNSA2Ljk5MjE4NzUsMTYgYyAwLC00Ljc3MTUwNiAzLjcxMzI5MzUsLTguNjc4Nzk2NCA4LjQwNjI1MDUsLTguOTg4MjgxMyBsIDAuMTIzMDQ2LC0wLjAwNzgxIHogbSAwLDEuNTI1MzkwNyAtMC4xMjMwNDcsMC4wMDk3NyBDIDExLjQwMzQxMiw4LjYxMDM5MTkgOC4yNjk1MzExLDExLjk0Mjg1MiA4LjI2OTUzMTMsMTYgYyAwLDQuMDU3MTcgMy4xMzM3ODY3LDcuMzg5NjI3IDcuMTExMzI3Nyw3LjcwNTA3OCBsIDAuMTIzMDQ3LDAuMDA5OCAwLjAxNzU4LC0wLjI0MjE4OCAtMC4xMjEwOTMsLTAuMDA5OCBDIDExLjU0NzQ4LDIzLjE1NzMyNSA4LjUxMzY3MTksMTkuOTMxODM0IDguNTEzNjcxOSwxNiBjIDAsLTMuOTMxODEyIDMuMDMzODA5MSwtNy4xNTczMDEyIDYuODg2NzE5MSwtNy40NjI4OTA2IGwgMC4xMjEwOTMsLTAuMDA5NzcgeiBNIDE1LjUsOS44MTA1NDY5IDE1LjM3ODkwNiw5LjgyMjI2NTYgQyAxMi4yNDM0MjMsMTAuMTM0MTY4IDkuNzkxMDE1NiwxMi43ODQwODcgOS43OTEwMTU2LDE2IGMgMCwzLjIxNTkzIDIuNDUyNDA3NCw1Ljg2NTgzMiA1LjU4Nzg5MDQsNi4xNzc3MzQgTCAxNS41LDIyLjE4OTQ1NCAxNS41MjUzOSwyMS45NDcyNjcgMTUuNDA0Mjk2LDIxLjkzNTU0NyBDIDEyLjM5MTQ3LDIxLjYzNTg0NSAxMC4wMzUxNTYsMTkuMDkyMjIyIDEwLjAzNTE1NiwxNiBjIDAsLTMuMDkyMjAzIDIuMzU2MzEzLC01LjYzNTg0NiA1LjM2OTE0MSwtNS45MzU1NDcgbCAwLjEyMTA5NCwtMC4wMTE3MiB6IG0gLTAuMDAzOSwxLjUyNzM0NDEgLTAuMTIxMDk0LDAuMDE1NjMgQyAxMy4wODMwOTMsMTEuNjU5NDM1IDExLjMxMjUsMTMuNjI2MjU5IDExLjMxMjUsMTYgYyAwLDIuMzczNzU0IDEuNzcwNTk5LDQuMzQwNTYxIDQuMDYyNSw0LjY0NjQ4NCBsIDAuMTIxMDk0LDAuMDE1NjMgMC4wMzEyNSwtMC4yNDIxODcgLTAuMTE5MTQxLC0wLjAxNTYzIEMgMTMuMjM1NTA0LDIwLjExNDI4NCAxMS41NTY2NDEsMTguMjUyNzgyIDExLjU1NjY0MSwxNiBjIDAsLTIuMjUyNzY5IDEuNjc4ODYzLC00LjExNDI4MyAzLjg1MTU2MiwtNC40MDQyOTcgbCAwLjExOTE0MSwtMC4wMTU2MyB6IG0gLTAuMDA5OCwxLjUzNTE1NiAtMC4xMTkxNCwwLjAyNTM5IEMgMTMuOTIyODQzLDEzLjE5MjExOSAxMi44MzM5ODQsMTQuNDcwOTc1IDEyLjgzMzk4NCwxNiBjIDAsMS41MjkwMjUgMS4wODg4MywyLjgwNzg4IDIuNTMzMjA0LDMuMTAxNTYyIGwgMC4xMTkxNCwwLjAyNTM5IDAuMDQ4ODMsLTAuMjQwMjM0IC0wLjExOTE0LC0wLjAyMzQ0IEMgMTQuMDgzNDExLDE4LjU5MjMyOCAxMy4wNzgxMjUsMTcuNDEzNjA5IDEzLjA3ODEyNSwxNiBjIDAsLTEuNDEzNjA5IDEuMDA1Mjg3LC0yLjU5MjMyNSAyLjMzNzg5MSwtMi44NjMyODEgbCAwLjExOTE0LC0wLjAyMzQ0IHogbSAtMC4wMzMyLDEuNTcyMjY2IC0wLjExMTMyOCwwLjA0ODgzIEMgMTQuNzYxMzU0LDE0Ljc0ODA1IDE0LjM1NzQyMiwxNS4zMjc1ODggMTQuMzU3NDIyLDE2IGMgMCwwLjY3MjQxMSAwLjQwMzkwNiwxLjI1MTk0OCAwLjk4NDM3NSwxLjUwNTg1OSBsIDAuMTExMzI4LDAuMDQ4ODMgMC4wOTc2NiwtMC4yMjI2NTYgLTAuMTExMzI4LC0wLjA0ODgzIEMgMTQuOTQ1NDEyLDE3LjA2NzA5OSAxNC41OTk2MDksMTYuNTc0NTkxIDE0LjU5OTYwOSwxNiBjIDAsLTAuNTc0NTkyIDAuMzQ1ODA2LC0xLjA2NzA5OSAwLjgzOTg0NCwtMS4yODMyMDMgbCAwLjExMTMyOCwtMC4wNDg4MyB6IiAgICBzdHlsZT0iZmlsbDojMjIyMjIyIiAgICBpZD0icGF0aDExIiAvPjxwYXRoICAgIGQ9Ik0gMTYsMiBDIDguMjczMTU0NiwyIDIsOC4yNzMxNjYzIDIsMTYgMiwyMy43MjY4NzQgOC4yNzMxNTQ2LDMwIDE2LDMwIDIzLjcyNjgwMywzMCAzMCwyMy43MjY4NzQgMzAsMTYgMzAsOC4yNzMxNjYzIDIzLjcyNjgwMywyIDE2LDIgWiBtIDAsMC42MDkzNzUgYyAwLjIwMzk4OCwwIDAuNDA3NiwwLjAwNDYzIDAuNjA5Mzc1LDAuMDEzNjcyIFYgMjkuMzc2OTUzIEMgMTYuNDA3NiwyOS4zODU5NTMgMTYuMjAzOTg4LDI5LjM5MDYyNSAxNiwyOS4zOTA2MjUgOC42MDkxMjYxLDI5LjM5MDYyNSAyLjYwOTM3NSwyMy4zOTA5IDIuNjA5Mzc1LDE2IDIuNjA5Mzc1LDguNjA5MTQwNyA4LjYwOTEyNjEsMi42MDkzNzUgMTYsMi42MDkzNzUgWiBtIDQuNTcyMjY2LDguOTQzMzU5IGggMS40MTc5NjggbCAxLjI4MTI1LDMuODMwMDc5IHYgLTMuODE0NDU0IGggMS4wNjgzNiB2IDEuNjc1NzgyIGMgMC4wNDQ4NiwtMC4wODQ0OCAwLjA5NjA0LC0wLjE2NzM5MyAwLjE1NDI5NywtMC4yNTE5NTMgMC4wNTgyNiwtMC4wODQ1MiAwLjExNDQxMSwtMC4xNjQ1NTUgMC4xNjk5MjEsLTAuMjQwMjM1IGwgMC44MjYxNzIsLTEuMTgzNTk0IGggMy40NTcwMzIgdiAwLjgzNTkzOCBoIC0xLjI3MTQ4NSB2IDAuNjA3NDIyIGggMS4xNzc3MzUgdiAwLjgzNzg5IGggLTEuMTc3NzM1IHYgMC43Mjg1MTYgaCAxLjI3MTQ4NSB2IDAuODUxNTYzIGggLTMuNTE1NjI1IGwgLTAuNzc3MzQ0LC0xLjQ3NjU2MyAtMC4zMTQ0NTMsMC4xODU1NDcgdiAxLjI5MTAxNiBoIC0yLjIxMjg5MSBsIC0wLjE5MzM1OSwtMC43MjQ2MSBIIDIwLjY1NjI1IGwgLTAuMTk5MjE5LDAuNzI0NjEgaCAtMS4xNjYwMTUgeiBtIC0yLjMzMzk4NSwwLjAxNTYzIGggMS4wNjgzNiB2IDMuNDgyNDIyIGMgMCwwLjM4NzQxNiAtMC4wNTk0NSwwLjY5NzI1NSAtMC4xNzc3MzUsMC45Mjk2ODggLTAuMTE4MjgzLDAuMjMyNDMzIC0wLjI4MjUxOCwwLjQwMjAzIC0wLjQ5MjE4NywwLjUwNTg1OSAtMC4yMDk3MTEsMC4xMDM5MDcgLTAuNDUyNTIyLDAuMTU2MjUgLTAuNzI4NTE2LDAuMTU2MjUgLTAuMTIwMDgsMCAtMC4yMjU4OTYsLTAuMDA2MSAtMC4zMTY0MDYsLTAuMDE3NTggLTAuMDkwNTEsLTAuMDExMzggLTAuMTY4MDk1LC0wLjAyNDk3IC0wLjIzNDM3NSwtMC4wMzkwNiB2IC0wLjgxMDU0NiBjIDAuMDU3MzUsMC4wMTA1MSAwLjExNzE1LDAuMDIxOTMgMC4xODE2NCwwLjAzNTE2IDAuMDY0NTMsMC4wMTMyIDAuMTM1Njc4LDAuMDE5NTMgMC4yMTA5MzgsMC4wMTk1MyAwLjEyNzI2MywwIDAuMjI2MDc1LC0wLjAyNTEgMC4yOTY4NzUsLTAuMDc2MTcgMC4wNzA3NSwtMC4wNTEwNyAwLjExOTc0NywtMC4xMjYzNzEgMC4xNDg0MzcsLTAuMjI4NTE1IDAuMDI4NjUsLTAuMTAyMDYxIDAuMDQyOTcsLTAuMjMxNTUgMC4wNDI5NywtMC4zODQ3NjYgeiBtIDguMzc1LDAuMDUwNzggLTEuMjAxMTcyLDEuNjc3NzM0IDEuMjAxMTcyLDIuMTA1NDY5IHogTSAyMS4yODcxMDksMTIuMTg3NSBjIC0wLjAxNjEyLDAuMDg4MDUgLTAuMDM4NzksMC4xOTg2OTggLTAuMDY4MzYsMC4zMjgxMjUgLTAuMDI5NTcsMC4xMjk0MjYgLTAuMDYwMzksMC4yNTYwNTggLTAuMDkxOCwwLjM4MjgxMyAtMC4wMzEzNywwLjEyNjc5NiAtMC4wNTg3MiwwLjIzMzg3OSAtMC4wODIwMywwLjMxODM1OSBsIC0wLjE2Nzk2OSwwLjYzMjgxMiBoIDAuODM1OTM4IGwgLTAuMTY5OTIyLC0wLjYzMjgxMiBjIC0wLjAxNzkyLC0wLjA2ODY2IC0wLjA0NDA1LC0wLjE2NzI2MiAtMC4wNzgxMywtMC4yOTQ5MjIgLTAuMDM0MDQsLTAuMTI3NjU5IC0wLjA2ODQ0LC0wLjI2MDAzMSAtMC4xMDE1NjMsLTAuMzk2NDg0IC0wLjAzMzE2LC0wLjEzNjQ1MiAtMC4wNTgyNSwtMC4yNDk4NDEgLTAuMDc2MTcsLTAuMzM3ODkxIHogbSAyLjEwNTQ2OSwzLjI2NTYyNSBoIDEuMjIwNzAzIGwgMS4xMDM1MTYsMy4yOTg4MjggdiAtMy4yODUxNTYgaCAxLjE5NTMxMiBsIDEuMjMwNDY5LDIuMzEwNTQ3IGggMC4wMTM2NyBjIC0wLjAwNDUsLTAuMDcyODEgLTAuMDA5MSwtMC4xNTU2NDMgLTAuMDEzNjcsLTAuMjUxOTUzIC0wLjAwNDcsLTAuMDk2MjcgLTAuMDA3OCwtMC4xOTQzOTkgLTAuMDExNzIsLTAuMjkyOTY5IC0wLjAwMzgsLTAuMDk4NTcgLTAuMDA1OSwtMC4xODU4NjkgLTAuMDA1OSwtMC4yNjE3MTkgdiAtMS41MDM5MDYgaCAwLjgxNDQ1MyB2IDMuMzI2MTcyIGggLTEuMTk5MjE5IGwgLTEuMjM2MzI4LC0yLjM0Mzc1IGggLTAuMDE5NTMgYyAwLjAwNzgsMC4wNzEyOSAwLjAxMzMzLDAuMTU3NzIyIDAuMDE5NTMsMC4yNTc4MTIgMC4wMDYyLDAuMTAwMDkgMC4wMTI5OCwwLjIwMjc3MSAwLjAxNzU4LDAuMzA2NjQxIDAuMDA0NywwLjEwMzg3IDAuMDA1OSwwLjE5NTg4NyAwLjAwNTksMC4yNzkyOTcgdiAxLjUgaCAtMS43OTY4NzUgbCAtMC4xNjYwMTYsLTAuNjIzMDQ3IGggLTEuMDk5NjA5IGwgLTAuMTcxODc1LDAuNjIzMDQ3IGggLTEuMDAzOTA3IHogbSAtNC4wMTM2NzIsMC4wMTM2NyBoIDEuMDI3MzQ0IGwgMC40NjA5MzcsMS42ODU1NDcgYyAwLjAxNjk2LDAuMDYzNjUgMC4wMzYyLDAuMTQ0NzkgMC4wNTg1OSwwLjI0NDE0IDAuMDIyMzgsMC4wOTkzMSAwLjA0MzI1LDAuMTk4MzA1IDAuMDYyNSwwLjI5Njg3NSAwLjAxOTMsMC4wOTg1NyAwLjAzMDU2LDAuMTgwMDE4IDAuMDM1MTYsMC4yNDIxODggMC4wMDYyLC0wLjA2MjE3IDAuMDE4MiwtMC4xNDEyNzEgMC4wMzUxNiwtMC4yMzgyODEgMC4wMTY5NiwtMC4wOTcwNSAwLjAzNTgsLTAuMTk1MTc5IDAuMDU2NjQsLTAuMjkyOTY5IDAuMDIwODQsLTAuMDk3ODMgMC4wNDAwOSwtMC4xNzg0OTggMC4wNTg1OSwtMC4yNDIxODggbCAwLjQ3MDcwMywtMS42OTUzMTIgaCAxLjAyMzQzOCBsIC0xLjEwOTM3NSwzLjMyNjE3MiBoIC0xLjA3NjE3MiB6IG0gNC42Mjg5MDYsMC41MzUxNTYgYyAtMC4wMTM3OCwwLjA3NTgxIC0wLjAzMzExLDAuMTY5Nzc5IC0wLjA1ODU5LDAuMjgxMjUgLTAuMDI1NDQsMC4xMTE0MyAtMC4wNTExNCwwLjIyMDkwOCAtMC4wNzgxMywwLjMzMDA3OCAtMC4wMjcwMywwLjEwOTE3IC0wLjA1MDIyLDAuMjAwNjI4IC0wLjA3MDMxLDAuMjczNDM4IGwgLTAuMTQ2NDg0LDAuNTQ0OTIyIEggMjQuMzc1IGwgLTAuMTQ2NDg0LC0wLjU0NDkyMiBjIC0wLjAxNTM3LC0wLjA1OTE3IC0wLjAzNzA1LC0wLjE0Mzk5NyAtMC4wNjY0MSwtMC4yNTM5MDcgLTAuMDI5MjgsLTAuMTA5OTUgLTAuMDU5MzIsLTAuMjI0Mjg1IC0wLjA4Nzg5LC0wLjM0MTc5NiAtMC4wMjg1NywtMC4xMTc1MTEgLTAuMDUwOTEsLTAuMjEzMjUzIC0wLjA2NjQxLC0wLjI4OTA2MyB6IG0gLTMuNTIzNDM3LDIuODkwNjI1IGggMC40Mjc3MzQgYyAwLjE2ODkwNSwwIDAuMzExMDA3LDAuMDI5NzUgMC40MjU3ODIsMC4wODc4OSAwLjExNDc3NSwwLjA1ODE0IDAuMjAyNTM4LDAuMTQyNzQ1IDAuMjYxNzE4LDAuMjU1ODU5IDAuMDU5MTksMC4xMTMxMTUgMC4wODc4OSwwLjI1Mzk2OSAwLjA4Nzg5LDAuNDE5OTIyIDAsMC4xNzM3NiAtMC4wMzEzMSwwLjMxNzc4OSAtMC4wOTM3NSwwLjQzNTU0NyAtMC4wNjI0NCwwLjExNzcxNiAtMC4xNTUwMDksMC4yMDc5OTggLTAuMjc3MzQ0LDAuMjY3NTc4IC0wLjEyMjM3NiwwLjA1OTU4IC0wLjI3MjY1MSwwLjA4Nzg5IC0wLjQ1MzEyNSwwLjA4Nzg5IGggLTAuMzc4OTA2IHogbSAxLjM4ODY3MiwwIGggMC44NjUyMzQgdiAwLjA5OTYxIGggLTAuNzUzOTA2IHYgMC41ODc4OTEgaCAwLjcxMDkzNyB2IDAuMDk5NjEgaCAtMC43MTA5MzcgdiAwLjY2OTkyMiBoIDAuNzUzOTA2IHYgMC4wOTc2NiBoIC0wLjg2NTIzNCB6IG0gMS4wNDY4NzUsMCBoIDAuMzg0NzY1IGMgMC4xMjU1OTMsMCAwLjIzMDM3NCwwLjAxNDA3IDAuMzE0NDU0LDAuMDQxMDIgMC4wODQxMiwwLjAyNjk1IDAuMTQ2ODEzLDAuMDcxMTQgMC4xODk0NTMsMC4xMzI4MTIgMC4wNDI1MiwwLjA2MTcxIDAuMDY0NDUsMC4xNDUwMjEgMC4wNjQ0NSwwLjI1IDAsMC4wNzg3MiAtMC4wMTU2NCwwLjE0NjcxNSAtMC4wNDQ5MiwwLjIwMzEyNSAtMC4wMjkyMywwLjA1NjM3IC0wLjA2OTkyLDAuMTAyNTEyIC0wLjEyMTA5NCwwLjEzODY3MiAtMC4wNTEyOSwwLjAzNjIgLTAuMTA4NzAxLDAuMDYyODggLTAuMTc1NzgxLDAuMDgyMDMgbCAwLjQzMzU5NCwwLjcwNzAzMiBIIDIzLjgzMjAzMSBMIDIzLjQyMzgyOCwxOS43NzE0ODQgSCAyMy4wMzEyNSB2IDAuNjc1NzgyIGggLTAuMTExMzI4IHogbSAwLjk3MjY1NiwwIGggMC4xMTUyMzQgbCAwLjI5ODgyOSwxLjA5NzY1NiBjIDAuMDA3OSwwLjAyOTA5IDAuMDE0NTgsMC4wNTU3OCAwLjAyMTQ4LDAuMDgyMDMgMC4wMDY4LDAuMDI2MjEgMC4wMTM3MywwLjA1MTcyIDAuMDE5NTMsMC4wNzYxNyAwLjAwNTcsMC4wMjQ0OSAwLjAxMDIyLDAuMDQ5MjIgMC4wMTU2MywwLjA3MjI3IDAuMDA1NCwwLjAyMzA0IDAuMDExMzIsMC4wNDQ5NCAwLjAxNTYzLDAuMDY4MzYgMC4wMDUxLC0wLjAyMzQyIDAuMDA4NywtMC4wNDYxOSAwLjAxMzY3LC0wLjA3MDMxIDAuMDA1MSwtMC4wMjQxMiAwLjAxMTQ4LC0wLjA0OTQgMC4wMTc1OCwtMC4wNzQyMiAwLjAwNjIsLTAuMDI0ODUgMC4wMTI2MywtMC4wNDk1NSAwLjAxOTUzLC0wLjA3NjE3IDAuMDA2OCwtMC4wMjY1OCAwLjAxNDg0LC0wLjA1NDkzIDAuMDIzNDQsLTAuMDgzOTggbCAwLjMxMDU0NywtMS4wOTE3OTcgSCAyNC44NzUgbCAwLjMyMjI2NiwxLjA5NzY1NiBjIDAuMDA4NywwLjAzMDQ5IDAuMDE4MTksMC4wNTg5OSAwLjAyNTM5LDAuMDg1OTQgMC4wMDcyLDAuMDI2OTUgMC4wMTM3MywwLjA1MzYzIDAuMDE5NTMsMC4wNzgxMyAwLjAwNTcsMC4wMjQ0NSAwLjAxMDUyLDAuMDQ3MjYgMC4wMTU2MywwLjA3MDMxIDAuMDA1LDAuMDIzMDUgMC4wMTA2MiwwLjA0Njg5IDAuMDE1NjMsMC4wNzAzMSAwLjAwNTgsLTAuMDMxODggMC4wMTEzOCwtMC4wNjI4OSAwLjAxNzU4LC0wLjA5Mzc1IDAuMDA2MSwtMC4wMzA4NiAwLjAxMjg4LC0wLjA2MzY0IDAuMDIxNDgsLTAuMDk3NjYgMC4wMDg3LC0wLjAzNDA2IDAuMDE4NDQsLTAuMDcwOSAwLjAyOTMsLTAuMTExMzI5IGwgMC4zMDQ2ODcsLTEuMDk5NjA5IGggMC4xMTUyMzUgbCAtMC40MzE2NDEsMS41NTQ2ODggaCAtMC4xMDc0MjIgbCAtMC4zMzk4NDQsLTEuMTczODI5IGMgLTAuMDA4LC0wLjAyNDgxIC0wLjAxNTI4LC0wLjA0OCAtMC4wMjE0OCwtMC4wNzAzMSAtMC4wMDYxLC0wLjAyMjM1IC0wLjAxMjA4LC0wLjA0NDIzIC0wLjAxNzU4LC0wLjA2NDQ1IC0wLjAwNTQsLTAuMDIwMjIgLTAuMDA5LC0wLjAzODU2IC0wLjAxMzY3LC0wLjA1NjY0IC0wLjAwNDcsLTAuMDE4MDggLTAuMDA4OCwtMC4wMzU5MSAtMC4wMTE3MiwtMC4wNTA3OCAtMC4wMDI5LDAuMDE0ODcgLTAuMDA2NSwwLjAzMjE1IC0wLjAwOTgsMC4wNDg4MyAtMC4wMDMzLDAuMDE2NjkgLTAuMDA3NCwwLjAzMzAzIC0wLjAxMTcyLDAuMDUwNzggLTAuMDA0NCwwLjAxNzcgLTAuMDA4NiwwLjAzNTU0IC0wLjAxMzY3LDAuMDU0NjkgLTAuMDA1MSwwLjAxOTE1IC0wLjAwOTgsMC4wNDAwMSAtMC4wMTU2MywwLjA2MDU1IGwgLTAuMzM3ODkxLDEuMjAxMTcyIGggLTAuMTA5Mzc1IHogbSAxLjk2ODc1LDAgaCAwLjg2NTIzNCB2IDAuMDk5NjEgaCAtMC43NTM5MDYgdiAwLjU4Nzg5MSBoIDAuNzEwOTM4IHYgMC4wOTk2MSBoIC0wLjcxMDkzOCB2IDAuNjY5OTIyIGggMC43NTM5MDYgdiAwLjA5NzY2IGggLTAuODY1MjM0IHogbSAxLjA0Njg3NSwwIGggMC4zODQ3NjYgYyAwLjEyNTU1MSwwIDAuMjMwMzczLDAuMDE0MDcgMC4zMTQ0NTMsMC4wNDEwMiAwLjA4NDEyLDAuMDI2OTUgMC4xNDY4NTMsMC4wNzExNCAwLjE4OTQ1MywwLjEzMjgxMiAwLjA0MjUyLDAuMDYxNzEgMC4wNjQ0NSwwLjE0NTAyMSAwLjA2NDQ1LDAuMjUgMCwwLjA3ODcyIC0wLjAxNTY0LDAuMTQ2NzE1IC0wLjA0NDkyLDAuMjAzMTI1IC0wLjAyOTIzLDAuMDU2MzcgLTAuMDY3OTgsMC4xMDI1MTIgLTAuMTE5MTQsMC4xMzg2NzIgLTAuMDUxMjksMC4wMzYyIC0wLjExMDYxNSwwLjA2Mjg4IC0wLjE3NzczNSwwLjA4MjAzIGwgMC40MzM1OTQsMC43MDcwMzIgSCAyNy44MjAzMTEgTCAyNy40MTIxMDgsMTkuNzcxNDg1IEggMjcuMDE5NTMgdiAwLjY3NTc4MiBoIC0wLjExMTMyOCB6IG0gMS4xNDA2MjUsMCBoIDAuODY1MjM0IHYgMC4wOTk2MSBoIC0wLjc1MzkwNiB2IDAuNjYyMTEgaCAwLjcxMjg5MSB2IDAuMDk3NjYgaCAtMC43MTI4OTEgdiAwLjY5NTMxMyBoIC0wLjExMTMyOCB6IG0gLTcuNDUzMTI1LDAuMDk3NjYgdiAxLjM2MTMyOCBoIDAuMjYxNzE5IGMgMC4yMzg5NDcsMWUtNiAwLjQxNjc4OSwtMC4wNTg1OCAwLjUzNTE1NiwtMC4xNzM4MjggMC4xMTg0MTIsLTAuMTE1MjUxIDAuMTc3NzM0LC0wLjI4NzAzNSAwLjE3NzczNCwtMC41MTc1NzggMCwtMC4xNDgyMDMgLTAuMDIzMTksLTAuMjcxNzg0IC0wLjA3MjI3LC0wLjM3MTA5NCAtMC4wNDkwOCwtMC4wOTkzMSAtMC4xMjU1MjksLTAuMTc0NjA5IC0wLjIyNjU2MywtMC4yMjQ2MDkgLTAuMTAxMDc1LC0wLjA0OTk3IC0wLjIyNzYwNiwtMC4wNzQyMiAtMC4zODI4MTIsLTAuMDc0MjIgeiBtIDIuNDM1NTQ3LDAgdiAwLjY4MzU5NCBoIDAuMzE0NDUzIGMgMC4xMjkyMjcsMCAwLjIzMDIyNCwtMC4wMjg4MiAwLjMwMjczNCwtMC4wODk4NCAwLjA3MjU5LC0wLjA2MDk4IDAuMTA5Mzc1LC0wLjE0OTQ5IDAuMTA5Mzc1LC0wLjI2MzY3MiAwLC0wLjEyNTU2NCAtMC4wMzg3NiwtMC4yMTIyNjUgLTAuMTE1MjM0LC0wLjI1OTc2NSAtMC4wNzY2LC0wLjA0NzU0IC0wLjE5Mjk0MiwtMC4wNzAzMSAtMC4zNDk2MDksLTAuMDcwMzEgeiBtIDMuOTg4MjgxLDAgdiAwLjY4MzU5NCBoIDAuMzE0NDUzIGMgMC4xMjkyNjgsMCAwLjIzMDIyNSwtMC4wMjg4MiAwLjMwMjczNSwtMC4wODk4NCAwLjA3MjU5LC0wLjA2MDk4IDAuMTA5Mzc1LC0wLjE0OTQ5IDAuMTA5Mzc1LC0wLjI2MzY3MiAwLC0wLjEyNTU2NCAtMC4wMzg3NSwtMC4yMTIyNjUgLTAuMTE1MjM1LC0wLjI1OTc2NSAtMC4wNzY2LC0wLjA0NzU0IC0wLjE5Mjk0MiwtMC4wNzAzMSAtMC4zNDk2MDksLTAuMDcwMzEgeiIgICAgc3R5bGU9ImJhc2VsaW5lLXNoaWZ0OmJhc2VsaW5lO2NsaXAtcnVsZTpub256ZXJvO2Rpc3BsYXk6aW5saW5lO292ZXJmbG93OnZpc2libGU7dmVjdG9yLWVmZmVjdDpub25lO2ZpbGw6IzIyMjIyMjtmaWxsLXJ1bGU6bm9uemVybztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjptaXRlcjtlbmFibGUtYmFja2dyb3VuZDphY2N1bXVsYXRlO3N0b3AtY29sb3I6IzAwMDAwMDtzdG9wLW9wYWNpdHk6MSIgICAgaWQ9InBhdGgxMCIgLz48L3N2Zz4=');}.icon-sign-out{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMTgsMjE2YTYsNiwwLDAsMS02LDZINDhhNiw2LDAsMCwxLTYtNlY0MGE2LDYsMCwwLDEsNi02aDY0YTYsNiwwLDAsMSwwLDEySDU0VjIxMGg1OEE2LDYsMCwwLDEsMTE4LDIxNlptMTEwLjI0LTkyLjI0LTQwLTQwYTYsNiwwLDAsMC04LjQ4LDguNDhMMjA5LjUxLDEyMkgxMTJhNiw2LDAsMCwwLDAsMTJoOTcuNTFsLTI5Ljc1LDI5Ljc2YTYsNiwwLDEsMCw4LjQ4LDguNDhsNDAtNDBBNiw2LDAsMCwwLDIyOC4yNCwxMjMuNzZaIi8+PC9zdmc+');}.icon-star-half-fi{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzkuMTgsOTcuMjZBMTYuMzgsMTYuMzgsMCwwLDAsMjI0LjkyLDg2bC01OS00Ljc2TDE0My4xNCwyNi4xNWExNi4zNiwxNi4zNiwwLDAsMC0zMC4yNywwTDkwLjExLDgxLjIzLDMxLjA4LDg2YTE2LjQ2LDE2LjQ2LDAsMCwwLTkuMzcsMjguODZsNDUsMzguODNMNTMsMjExLjc1YTE2LjQsMTYuNCwwLDAsMCwyNC41LDE3LjgyTDEyOCwxOTguNDlsNTAuNTMsMzEuMDhBMTYuNCwxNi40LDAsMCwwLDIwMywyMTEuNzVsLTEzLjc2LTU4LjA3LDQ1LTM4LjgzQTE2LjQzLDE2LjQzLDAsMCwwLDIzOS4xOCw5Ny4yNlptLTE1LjM0LDUuNDctNDguNyw0MmE4LDgsMCwwLDAtMi41Niw3LjkxbDE0Ljg4LDYyLjhhLjM3LjM3LDAsMCwxLS4xNy40OGMtLjE4LjE0LS4yMy4xMS0uMzgsMGwtNTQuNzItMzMuNjVBOCw4LDAsMCwwLDEyOCwxODEuMVYzMmMuMjQsMCwuMjcuMDguMzUuMjZMMTUzLDkxLjg2YTgsOCwwLDAsMCw2Ljc1LDQuOTJsNjMuOTEsNS4xNmMuMTYsMCwuMjUsMCwuMzQuMjlTMjI0LDEwMi42MywyMjMuODQsMTAyLjczWiIvPjwvc3ZnPg==');}.icon-star-fi{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzQuMjksMTE0Ljg1bC00NSwzOC44M0wyMDMsMjExLjc1YTE2LjQsMTYuNCwwLDAsMS0yNC41LDE3LjgyTDEyOCwxOTguNDksNzcuNDcsMjI5LjU3QTE2LjQsMTYuNCwwLDAsMSw1MywyMTEuNzVsMTMuNzYtNTguMDctNDUtMzguODNBMTYuNDYsMTYuNDYsMCwwLDEsMzEuMDgsODZsNTktNC43NiwyMi43Ni01NS4wOGExNi4zNiwxNi4zNiwwLDAsMSwzMC4yNywwbDIyLjc1LDU1LjA4LDU5LDQuNzZhMTYuNDYsMTYuNDYsMCwwLDEsOS4zNywyOC44NloiLz48L3N2Zz4=');}.icon-heart-fi{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yNDAsMTAyYzAsNzAtMTAzLjc5LDEyNi42Ni0xMDguMjEsMTI5YTgsOCwwLDAsMS03LjU4LDBDMTE5Ljc5LDIyOC42NiwxNiwxNzIsMTYsMTAyQTYyLjA3LDYyLjA3LDAsMCwxLDc4LDQwYzIwLjY1LDAsMzguNzMsOC44OCw1MCwyMy44OUMxMzkuMjcsNDguODgsMTU3LjM1LDQwLDE3OCw0MEE2Mi4wNyw2Mi4wNywwLDAsMSwyNDAsMTAyWiIvPjwvc3ZnPg==');}
\ No newline at end of file
+.icon-google-logo{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjIsMTI4YTk0LDk0LDAsMSwxLTIxLjQ5LTU5LjgyLDYsNiwwLDEsMS05LjI1LDcuNjRBODIsODIsMCwxLDAsMjA5Ljc4LDEzNEgxMjhhNiw2LDAsMCwxLDAtMTJoODhBNiw2LDAsMCwxLDIyMiwxMjhaIi8+PC9zdmc+');}.icon-apple-logo{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTkuNCwxNjcuODRDMjAxLjcxLDE1NS42OSwxOTgsMTM1LjEyLDE5OCwxMjBjMC0xOC40MiwxMy44Ni0zNC4yOSwyMi4xMi00Mi4xMmE2LDYsMCwwLDAsMC04LjcxQzIwOCw1Ny43LDE4Ny4wNyw1MCwxNjgsNTBhNzAuMjMsNzAuMjMsMCwwLDAtNDAsMTIuNTUsNjkuNiw2OS42LDAsMCwwLTg5LjMxLDguMDhBNzIuNjMsNzIuNjMsMCwwLDAsMTgsMTIzLjM1YTEyNS4xMSwxMjUuMTEsMCwwLDAsMzkuNTMsODguMzNBMzcuODUsMzcuODUsMCwwLDAsODMuNiwyMjJoODcuN0EzNy44MywzNy44MywwLDAsMCwxOTksMjEwLjA3YTEyMi42LDEyMi42LDAsMCwwLDE3LjU0LTI0LjJjNi41NS0xMiw1Ljc3LTEzLjc1LDUtMTUuNDhBNi4wNyw2LjA3LDAsMCwwLDIxOS40LDE2Ny44NFptLTI5LjIzLDM0QTI1LjgyLDI1LjgyLDAsMCwxLDE3MS4zLDIxMEg4My42QTI1Ljg1LDI1Ljg1LDAsMCwxLDY1Ljc4LDIwMywxMTMuMjEsMTEzLjIxLDAsMCwxLDMwLDEyM2E2MC41NSw2MC41NSwwLDAsMSwxNy4yMS00NEE1Ni44Miw1Ni44MiwwLDAsMSw4OCw2MmguODFhNTcuMzUsNTcuMzUsMCwwLDEsMzUuNDQsMTIuNzEsNiw2LDAsMCwwLDcuNSwwQTU3LjM5LDU3LjM5LDAsMCwxLDE2OCw2MmMxMy44OSwwLDI4LjgxLDQuNjgsMzkuMTEsMTItOS40NCwxMC4xNC0yMS4xLDI2LjU5LTIxLjEsNDYsMCwyMy43OCw3LjgxLDQyLjYsMjIuNjYsNTQuNzdBMTA3LjMzLDEwNy4zMywwLDAsMSwxOTAuMTcsMjAxLjg5Wm0tNjAtMTcxLjM5QTM4LDM4LDAsMCwxLDE2NywyaDFhNiw2LDAsMCwxLDAsMTJoLTFhMjYsMjYsMCwwLDAtMjUuMTgsMTkuNSw2LDYsMCwxLDEtMTEuNjItM1oiLz48L3N2Zz4=');}.icon-check-circle{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNzIuMjQsOTkuNzZhNiw2LDAsMCwxLDAsOC40OGwtNTYsNTZhNiw2LDAsMCwxLTguNDgsMGwtMjQtMjRhNiw2LDAsMCwxLDguNDgtOC40OEwxMTIsMTUxLjUxbDUxLjc2LTUxLjc1QTYsNiwwLDAsMSwxNzIuMjQsOTkuNzZaTTIzMCwxMjhBMTAyLDEwMiwwLDEsMSwxMjgsMjYsMTAyLjEyLDEwMi4xMiwwLDAsMSwyMzAsMTI4Wm0tMTIsMGE5MCw5MCwwLDEsMC05MCw5MEE5MC4xLDkwLjEsMCwwLDAsMjE4LDEyOFoiLz48L3N2Zz4=');}.icon-cloud-slash{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik01Mi40NCwzNkE2LDYsMCwwLDAsNDMuNTYsNDRsNDAuMTgsNDQuMmMtLjQ1Ljg3LS45LDEuNzUtMS4zMiwyLjY0QTYyLDYyLDAsMSwwLDcyLDIxNGg4OGE4NS4yMyw4NS4yMywwLDAsMCwzMi4zNS02LjNMMjAzLjU2LDIyMGE2LDYsMCwwLDAsOC44OC04LjA4Wk0xNjAsMjAySDcyYTUwLDUwLDAsMSwxLDUuOS05OS42NEE4Ni4yNSw4Ni4yNSwwLDAsMCw3NCwxMjhhNiw2LDAsMCwwLDEyLDAsNzMuOTIsNzMuOTIsMCwwLDEsNi40NC0zMC4ybDkxLjIyLDEwMC4zNEE3My42NSw3My42NSwwLDAsMSwxNjAsMjAyWm04Ni03NGE4NS44NSw4NS44NSwwLDAsMS0yMS44NSw1Ny4yNyw2LDYsMCwwLDEtNC40NywyLDYsNiwwLDAsMS00LjQ3LTEwLDc0LDc0LDAsMCwwLTk5LTEwOC45Miw2LDYsMCwxLDEtNy4xMS05LjY3QTg2LDg2LDAsMCwxLDI0NiwxMjhaIi8+PC9zdmc+');}.icon-exclamation-mark{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNDIsMjAwYTE0LDE0LDAsMSwxLTE0LTE0QTE0LDE0LDAsMCwxLDE0MiwyMDBabS0xNC00MmE2LDYsMCwwLDAsNi02VjQ4YTYsNiwwLDAsMC0xMiwwVjE1MkE2LDYsMCwwLDAsMTI4LDE1OFoiLz48L3N2Zz4=');}.icon-cloud-arrow-down{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yNDYsMTI4YTg1LjI3LDg1LjI3LDAsMCwxLTE3LjIsNTEuNiw2LDYsMCwxLDEtOS42LTcuMkE3NCw3NCwwLDEsMCw4NiwxMjhhNiw2LDAsMCwxLTEyLDAsODUuNTQsODUuNTQsMCwwLDEsMy45MS0yNS42NEE1MC42OCw1MC42OCwwLDAsMCw3MiwxMDJhNTAsNTAsMCwwLDAsMCwxMDBIOTZhNiw2LDAsMCwxLDAsMTJINzJBNjIsNjIsMCwxLDEsODIuNDMsOTAuODgsODYsODYsMCwwLDEsMjQ2LDEyOFptLTY2LjI0LDQzLjc2TDE1OCwxOTMuNTFWMTI4YTYsNiwwLDAsMC0xMiwwdjY1LjUxbC0yMS43Ni0yMS43NWE2LDYsMCwwLDAtOC40OCw4LjQ4bDMyLDMyYTYsNiwwLDAsMCw4LjQ4LDBsMzItMzJhNiw2LDAsMCwwLTguNDgtOC40OFoiLz48L3N2Zz4=');}.icon-caret-down{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTIuMjQsMTAwLjI0bC04MCw4MGE2LDYsMCwwLDEtOC40OCwwbC04MC04MGE2LDYsMCwwLDEsOC40OC04LjQ4TDEyOCwxNjcuNTFsNzUuNzYtNzUuNzVhNiw2LDAsMCwxLDguNDgsOC40OFoiLz48L3N2Zz4=');}.icon-cloud-arrow-up{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xODguMjQsMTY0LjI0YTYsNiwwLDAsMS04LjQ4LDBMMTU4LDE0Mi40OVYyMDhhNiw2LDAsMCwxLTEyLDBWMTQyLjQ5bC0yMS43NiwyMS43NWE2LDYsMCwwLDEtOC40OC04LjQ4bDMyLTMyYTYsNiwwLDAsMSw4LjQ4LDBsMzIsMzJBNiw2LDAsMCwxLDE4OC4yNCwxNjQuMjRaTTE2MCw0MkE4Ni4xLDg2LjEsMCwwLDAsODIuNDMsOTAuODgsNjIsNjIsMCwxLDAsNzIsMjE0aDQwYTYsNiwwLDAsMCwwLTEySDcyYTUwLDUwLDAsMCwxLDAtMTAwLDUwLjY4LDUwLjY4LDAsMCwxLDUuOTEuMzZBODUuNTQsODUuNTQsMCwwLDAsNzQsMTI4YTYsNiwwLDAsMCwxMiwwLDc0LDc0LDAsMSwxLDEwMy42LDY3Ljg1LDYsNiwwLDAsMCw0LjgsMTFBODYsODYsMCwwLDAsMTYwLDQyWiIvPjwvc3ZnPg==');}.icon-cloud-check{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjAsNDJBODYuMTEsODYuMTEsMCwwLDAsODIuNDMsOTAuODgsNjIsNjIsMCwxLDAsNzIsMjE0aDg4YTg2LDg2LDAsMCwwLDAtMTcyWm0wLDE2MEg3MmE1MCw1MCwwLDAsMSwwLTEwMCw1MC42Nyw1MC42NywwLDAsMSw1LjkxLjM1QTg1LjYxLDg1LjYxLDAsMCwwLDc0LDEyOGE2LDYsMCwwLDAsMTIsMCw3NCw3NCwwLDEsMSw3NCw3NFptMzYuMjQtOTQuMjRhNiw2LDAsMCwxLDAsOC40OGwtNDgsNDhhNiw2LDAsMCwxLTguNDgsMGwtMjQtMjRhNiw2LDAsMCwxLDguNDgtOC40OEwxNDQsMTUxLjUxbDQzLjc2LTQzLjc1QTYsNiwwLDAsMSwxOTYuMjQsMTA3Ljc2WiIvPjwvc3ZnPg==');}.icon-cloud-warning{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjAsNDJBODYuMTEsODYuMTEsMCwwLDAsODIuNDMsOTAuODgsNjIsNjIsMCwxLDAsNzIsMjE0aDg4YTg2LDg2LDAsMCwwLDAtMTcyWm0wLDE2MEg3MmE1MCw1MCwwLDAsMSwwLTEwMCw1MC42Nyw1MC42NywwLDAsMSw1LjkxLjM1QTg1LjYxLDg1LjYxLDAsMCwwLDc0LDEyOGE2LDYsMCwwLDAsMTIsMCw3NCw3NCwwLDEsMSw3NCw3NFptLTYtNzRWODhhNiw2LDAsMCwxLDEyLDB2NDBhNiw2LDAsMCwxLTEyLDBabTE2LDM2YTEwLDEwLDAsMSwxLTEwLTEwQTEwLDEwLDAsMCwxLDE3MCwxNjRaIi8+PC9zdmc+');}.icon-syncing{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0iY3VycmVudENvbG9yIiB2aWV3Qm94PSIwIDAgMjU2IDI1NiI+PHBhdGggaWQ9InJlZnJlc2giIGQ9Ik0xNjAuMDQ3IDEyMi44NzVhMzAuNzg0IDMwLjc4NCAwIDAgMC0yMS43NSA4Ljc5N2MtMi44NDIgMy4wMDMtLjQ2NyA0Ljk3MSAxLjMxMiAzLjE1NiAxMS4wNDMtMTAuNzg2IDI4LjcxLTEwLjY4IDM5LjYyNS4yMzRsNy4yMDMgNy4yMDRoLTEyLjg3NWMtMy4zNDcuMDA4LTMuMTY1IDMuODc1IDAgMy44NzVoMTYuMTFjMi4wNjIgMCAyLjU0LTEuNDE4IDIuNTYyLTQuOTdsLjA5NC0xNC45MjFjLjAyLTMuMjktMy40MzctMy4xNjUtMy40MzcgMHYxMi44NmwtNy4yMDMtNy4xODhhMzAuNzY4IDMwLjc2OCAwIDAgMC0yMS42NDEtOS4wNDd6bS0yOS41OTQgMzkuNzk3Yy0yLjA2MiAwLTIuNTI0IDEuNDAyLTIuNTQ3IDQuOTUzbC0uMDk0IDE0LjkyMmMtLjAyIDMuMjkgMy40MjIgMy4xNjQgMy40MjIgMHYtMTIuODZsNy4yMDMgNy4yMDRjMTEuOTU2IDExLjk1NSAzMS4zMTIgMTIuMDY0IDQzLjQwNy4yNSAyLjg0Mi0zLjAwMy40NTEtNC45ODgtMS4zMjgtMy4xNzItMTEuMDQzIDEwLjc4Ni0yOC43MSAxMC42OC0zOS42MjUtLjIzNWwtNy4xODgtNy4yMDNoMTIuODZjMy4zNDctLjAwOCAzLjE2NS0zLjg2IDAtMy44NmgtMTYuMTF6Ii8+PHBhdGggZD0iTTE2MCA0NGE4NC4xMSA4NC4xMSAwIDAgMC03Ni40MSA0OS4xMkE2MC43MSA2MC43MSAwIDAgMCA3MiA5MmE2MCA2MCAwIDAgMCAwIDEyMGg4OGE4NCA4NCAwIDAgMCAwLTE2OFptMCAxNjBINzJhNTIgNTIgMCAxIDEgOC41NS0xMDMuM0E4My42NiA4My42NiAwIDAgMCA3NiAxMjhhNCA0IDAgMCAwIDggMCA3NiA3NiAwIDEgMSA3NiA3NloiLz48L3N2Zz4=');}.icon-cloud-x{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjAsNDJBODYuMTEsODYuMTEsMCwwLDAsODIuNDMsOTAuODgsNjIsNjIsMCwxLDAsNzIsMjE0aDg4YTg2LDg2LDAsMCwwLDAtMTcyWm0wLDE2MEg3MmE1MCw1MCwwLDAsMSwwLTEwMCw1MC42Nyw1MC42NywwLDAsMSw1LjkxLjM1QTg1LjYxLDg1LjYxLDAsMCwwLDc0LDEyOGE2LDYsMCwwLDAsMTIsMCw3NCw3NCwwLDEsMSw3NCw3NFptMjguMjQtODUuNzZMMTY4LjQ4LDEzNmwxOS43NiwxOS43NmE2LDYsMCwxLDEtOC40OCw4LjQ4TDE2MCwxNDQuNDhsLTE5Ljc2LDE5Ljc2YTYsNiwwLDAsMS04LjQ4LTguNDhMMTUxLjUyLDEzNmwtMTkuNzYtMTkuNzZhNiw2LDAsMCwxLDguNDgtOC40OEwxNjAsMTI3LjUybDE5Ljc2LTE5Ljc2YTYsNiwwLDAsMSw4LjQ4LDguNDhaIi8+PC9zdmc+');}.icon-arrows-clockwise{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjIsNDhWOTZhNiw2LDAsMCwxLTYsNkgxNjhhNiw2LDAsMCwxLDAtMTJoMzMuNTJMMTgzLjQ3LDcyYTgxLjUxLDgxLjUxLDAsMCwwLTU3LjUzLTI0aC0uNDZBODEuNSw4MS41LDAsMCwwLDY4LjE5LDcxLjI4YTYsNiwwLDEsMS04LjM4LTguNTgsOTMuMzgsOTMuMzgsMCwwLDEsNjUuNjctMjYuNzZIMTI2YTkzLjQ1LDkzLjQ1LDAsMCwxLDY2LDI3LjUzbDE4LDE4VjQ4YTYsNiwwLDAsMSwxMiwwWk0xODcuODEsMTg0LjcyYTgxLjUsODEuNSwwLDAsMS01Ny4yOSwyMy4zNGgtLjQ2YTgxLjUxLDgxLjUxLDAsMCwxLTU3LjUzLTI0TDU0LjQ4LDE2Nkg4OGE2LDYsMCwwLDAsMC0xMkg0MGE2LDYsMCwwLDAtNiw2djQ4YTYsNiwwLDAsMCwxMiwwVjE3NC40OGwxOCwxOC4wNWE5My40NSw5My40NSwwLDAsMCw2NiwyNy41M2guNTJhOTMuMzgsOTMuMzgsMCwwLDAsNjUuNjctMjYuNzYsNiw2LDAsMSwwLTguMzgtOC41OFoiLz48L3N2Zz4=');}.icon-share-fat{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzYuMjQsMTA3Ljc2bC04MC04MEE2LDYsMCwwLDAsMTQ2LDMyVjc0LjJjLTU0LjQ4LDMuNTktMTIwLjM5LDU1LTEyNy45MywxMjAuNjZhMTAsMTAsMCwwLDAsMTcuMjMsOGgwQzQ2LjU2LDE5MC44NSw4NywxNTIuNiwxNDYsMTUwLjEzVjE5MmE2LDYsMCwwLDAsMTAuMjQsNC4yNGw4MC04MEE2LDYsMCwwLDAsMjM2LjI0LDEwNy43NlpNMTU4LDE3Ny41MlYxNDRhNiw2LDAsMCwwLTYtNmMtMjcuNzMsMC01NC43Niw3LjI1LTgwLjMyLDIxLjU1YTE5My4zOCwxOTMuMzgsMCwwLDAtNDAuODEsMzAuNjVjNC43LTI2LjU2LDIwLjE2LTUyLDQ0LTcyLjI3Qzk4LjQ3LDk3Ljk0LDEyNy4yOSw4NiwxNTIsODZhNiw2LDAsMCwwLDYtNlY0Ni40OUwyMjMuNTEsMTEyWiIvPjwvc3ZnPg==');}.icon-trash{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTYsNTBIMTc0VjQwYTIyLDIyLDAsMCwwLTIyLTIySDEwNEEyMiwyMiwwLDAsMCw4Miw0MFY1MEg0MGE2LDYsMCwwLDAsMCwxMkg1MFYyMDhhMTQsMTQsMCwwLDAsMTQsMTRIMTkyYTE0LDE0LDAsMCwwLDE0LTE0VjYyaDEwYTYsNiwwLDAsMCwwLTEyWk05NCw0MGExMCwxMCwwLDAsMSwxMC0xMGg0OGExMCwxMCwwLDAsMSwxMCwxMFY1MEg5NFpNMTk0LDIwOGEyLDIsMCwwLDEtMiwySDY0YTIsMiwwLDAsMS0yLTJWNjJIMTk0Wk0xMTAsMTA0djY0YTYsNiwwLDAsMS0xMiwwVjEwNGE2LDYsMCwwLDEsMTIsMFptNDgsMHY2NGE2LDYsMCwwLDEtMTIsMFYxMDRhNiw2LDAsMCwxLDEyLDBaIi8+PC9zdmc+');}.icon-star{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzcuMjgsOTcuODdBMTQuMTgsMTQuMTgsMCwwLDAsMjI0Ljc2LDg4bC02MC4yNS00Ljg3LTIzLjIyLTU2LjJhMTQuMzcsMTQuMzcsMCwwLDAtMjYuNTgsMEw5MS40OSw4My4xMSwzMS4yNCw4OGExNC4xOCwxNC4xOCwwLDAsMC0xMi41Miw5Ljg5QTE0LjQzLDE0LjQzLDAsMCwwLDIzLDExMy4zMkw2OSwxNTIuOTNsLTE0LDU5LjI1YTE0LjQsMTQuNCwwLDAsMCw1LjU5LDE1LDE0LjEsMTQuMSwwLDAsMCwxNS45MS42TDEyOCwxOTYuMTJsNTEuNTgsMzEuNzFhMTQuMSwxNC4xLDAsMCwwLDE1LjkxLS42LDE0LjQsMTQuNCwwLDAsMCw1LjU5LTE1bC0xNC01OS4yNUwyMzMsMTEzLjMyQTE0LjQzLDE0LjQzLDAsMCwwLDIzNy4yOCw5Ny44N1ptLTEyLjE0LDYuMzctNDguNjksNDJhNiw2LDAsMCwwLTEuOTIsNS45MmwxNC44OCw2Mi43OWEyLjM1LDIuMzUsMCwwLDEtLjk1LDIuNTcsMi4yNCwyLjI0LDAsMCwxLTIuNi4xTDEzMS4xNCwxODRhNiw2LDAsMCwwLTYuMjgsMEw3MC4xNCwyMTcuNjFhMi4yNCwyLjI0LDAsMCwxLTIuNi0uMSwyLjM1LDIuMzUsMCwwLDEtMS0yLjU3bDE0Ljg4LTYyLjc5YTYsNiwwLDAsMC0xLjkyLTUuOTJsLTQ4LjY5LTQyYTIuMzcsMi4zNywwLDAsMS0uNzMtMi42NSwyLjI4LDIuMjgsMCwwLDEsMi4wNy0xLjY1bDYzLjkyLTUuMTZhNiw2LDAsMCwwLDUuMDYtMy42OWwyNC42My01OS42YTIuMzUsMi4zNSwwLDAsMSw0LjM4LDBsMjQuNjMsNTkuNmE2LDYsMCwwLDAsNS4wNiwzLjY5bDYzLjkyLDUuMTZhMi4yOCwyLjI4LDAsMCwxLDIuMDcsMS42NUEyLjM3LDIuMzcsMCwwLDEsMjI1LjE0LDEwNC4yNFoiLz48L3N2Zz4=');}.icon-alphabetical{--icon:url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIGZpbGw9ImN1cnJlbnRDb2xvciIgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSIwIDAgMTgzLjc4IDE4NC4wNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNTkuNTg2IDY5Ljc0MmMtMC44NTEzIDAtMS40NjEgMC4xOTY1Ni0xLjgzNjYgMC41OTcxOC0wLjM1MDU0IDAuMzc1NTgtMC41Mjk1OCAxLjAyMjktMC41Mjk1OCAxLjk0OTNzMC4xNzkwMyAxLjU5MzcgMC41Mjk1OCAxLjk5NDRjMC4zNzU1OCAwLjM3NTU4IDAuOTg1MjkgMC41NjMzOCAxLjgzNjYgMC41NjMzOGg3LjAxOTdsLTEyLjQyOCAzNC4zNjZoLTIuMTA3Yy0wLjg1MTMgMC0xLjQ2MSAwLjE5NjU2LTEuODM2NiAwLjU5NzE4LTAuMzUwNTQgMC4zNzU1OC0wLjUyOTU3IDEuMDM0MS0wLjUyOTU3IDEuOTYwNiAwIDAuOTI2NDQgMC4xNzkwMyAxLjU4MjUgMC41Mjk1NyAxLjk4MyAwLjM3NTU4IDAuMzc1NTkgMC45ODUyOSAwLjU2MzM4IDEuODM2NiAwLjU2MzM4aDEyLjU1MmMwLjg1MTMgMCAxLjQ1MjItMC4xODc3OSAxLjgwMjgtMC41NjMzOCAwLjM3NTU4LTAuNDAwNjIgMC41NjMzNy0xLjA1NjYgMC41NjMzNy0xLjk4MyAwLTAuOTI2NDUtMC4xODc3OS0xLjU4NS0wLjU2MzM3LTEuOTYwNi0wLjM1MDU0LTAuNDAwNjItMC45NTE0Ny0wLjU5NzE4LTEuODAyOC0wLjU5NzE4aC00LjU1MjFsMy4xMjExLTguOTM0OWgxOC4yMmwzLjA3NiA4LjkzNDloLTUuMDcwNGMtMC44NTEzIDAtMS40NjEgMC4xOTY1Ni0xLjgzNjYgMC41OTcxOC0wLjM1MDU0IDAuMzc1NTgtMC41Mjk1OCAxLjAzNDEtMC41Mjk1OCAxLjk2MDYgMCAwLjkyNjQ0IDAuMTc5MDMgMS41ODI1IDAuNTI5NTggMS45ODMgMC4zNzU1OCAwLjM3NTU5IDAuOTg1MjkgMC41NjMzOCAxLjgzNjYgMC41NjMzOGgxMy4yOTZjMC44NTEzIDAgMS40NTIyLTAuMTg3NzkgMS44MDI4LTAuNTYzMzggMC4zNzU1OC0wLjQwMDYyIDAuNTYzMzctMS4wNTY2IDAuNTYzMzctMS45ODMgMC0wLjkyNjQ1LTAuMTg3NzktMS41ODUtMC41NjMzNy0xLjk2MDYtMC4zNTA1NC0wLjQwMDYyLTAuOTUxNDctMC41OTcxOC0xLjgwMjgtMC41OTcxOGgtMi4yODczbC0xMy4yNjItMzcuMDM2Yy0wLjMwMDQ3LTAuODUxMy0wLjc1OTk0LTEuNDYxLTEuMzg1OS0xLjgzNjYtMC42MDA5My0wLjQwMDYyLTEuNDA5Ny0wLjU5NzE4LTIuNDExMy0wLjU5NzE4em00NC4xNDYgMGMtMC44NTEzIDAtMS40NzIzIDAuMTk2NTYtMS44NDc4IDAuNTk3MTgtMC4zNTA1NSAwLjM3NTU4LTAuNTE4MyAxLjAyMjktMC41MTgzIDEuOTQ5M3YxMS45MWMwIDAuODc2MzMgMC4yMDUzMiAxLjUwNjEgMC42MzA5OCAxLjg4MTcgMC40MjU2NiAwLjM3NTU4IDEuMTU5MyAwLjU2MzM3IDIuMTg1OSAwLjU2MzM3czEuNzQ5LTAuMTg3NzkgMi4xNzQ3LTAuNTYzMzdjMC40MjU2OS0wLjM3NTU4IDAuNjQyMjYtMS4wMDUzIDAuNjQyMjYtMS44ODE3di05LjM1MTdoMTguODUxbC0yNC43NTQgMzUuMzAxYy0wLjM1MDU0IDAuNTI1ODItMC41MTgzMSAxLjA3MTctMC41MTgzMSAxLjYyMjYgMCAwLjkyNjQ1IDAuMTY3NzcgMS41ODI1IDAuNTE4MzEgMS45ODMxIDAuMzc1NTggMC4zNzU1OCAwLjk5NjU0IDAuNTYzMzggMS44NDc4IDAuNTYzMzhoMjguNzY2YzAuODUxMyAwIDEuNDUyMi0wLjE4NzggMS44MDI4LTAuNTYzMzggMC4zNzU1OC0wLjQwMDYyIDAuNTYzMzgtMS4wNTY2IDAuNTYzMzgtMS45ODMxdi0xMi42NjVjMC0wLjg3NjMzLTAuMjE2NTgtMS40OTQ4LTAuNjQyMjUtMS44NzA0LTAuNDI1NjYtMC4zNzU1OC0xLjE0OC0wLjU2MzM4LTIuMTc0Ny0wLjU2MzM4LTEuMDI2NiAwLTEuNzQ5IDAuMTg3NzktMi4xNzQ3IDAuNTYzMzgtMC40MjU2NiAwLjM3NTU4LTAuNjQyMjQgMC45OTQwMi0wLjY0MjI0IDEuODcwNHYxMC4xMDdoLTE5Ljk3OGwyNC45MDEtMzUuNDU5YzAuMjUwMzktMC4zNTA1NCAwLjM3MTgzLTAuODM4ODMgMC4zNzE4My0xLjQ2NDggMC0wLjkyNjQ1LTAuMTg3OC0xLjU3MzctMC41NjMzOC0xLjk0OTMtMC4zNTA1NS0wLjQwMDYyLTAuOTUxNDctMC41OTcxOC0xLjgwMjgtMC41OTcxOHptLTMxLjc1MiA1LjEwNDJoMC43MDk4NWw2Ljk4NTkgMjAuMzE1aC0xNC43MTZ6bS0zNy43MjMtNDkuMTgzYy00LjczNDIgMC04LjYzMTMgMy44OTctOC42MzEzIDguNjMxM3YxMTUuNDdjMCA0LjczNDIgMy44OTcgOC42MzEzIDguNjMxMyA4LjYzMTNoMTE1LjI2YzQuNzM0MiAwIDguNjQyMS0zLjg5NyA4LjY0MjEtOC42MzEzdi0xMTUuNDdjMC00LjczNDItMy45MDgyLTguNjMxMy04LjY0MjEtOC42MzEzem0wIDUuNzI0aDExNS4yNmMxLjY1OCAwIDIuOTA3IDEuMjQ5MSAyLjkwNyAyLjkwNzF2MTE1LjQ3YzAgMS42NTgtMS4yNDkxIDIuOTA3LTIuOTA3IDIuOTA3aC0xMTUuMjZjLTEuNjU4IDAtMi44OTU4LTEuMjQ5MS0yLjg5NTgtMi45MDd2LTExNS40N2MwLTEuNjU4IDEuMjM3OC0yLjkwNzEgMi44OTU4LTIuOTA3MXoiIGZpbGw9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIuNzIxMTQiLz48L3N2Zz4=');}.icon-scribble{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDQuMjUsMTg4LjI0YTE2LjYzLDE2LjYzLDAsMCwwLDAsMjMuNTIsNiw2LDAsMSwxLTguNDgsOC40OCwyOC42MSwyOC42MSwwLDAsMSwwLTQwLjQ4bDkuMzctOS4zOGExNi42MywxNi42MywwLDAsMC0yMy41Mi0yMy41MWwtNjYuNzUsNjYuNzVhMjguNjMsMjguNjMsMCwwLDEtNDAuNDktNDAuNDlsOTguNzYtOTguNzVhMTYuNjMsMTYuNjMsMCwwLDAtMjMuNTItMjMuNTFMODIuODYsMTE3LjYyQTI4LjYzLDI4LjYzLDAsMCwxLDQyLjM3LDc3LjEzTDgzLjc1LDM1Ljc2YTYsNiwwLDEsMSw4LjQ5LDguNDhMNTAuODYsODUuNjJhMTYuNjMsMTYuNjMsMCwwLDAsMjMuNTIsMjMuNTFsNjYuNzUtNjYuNzVhMjguNjMsMjguNjMsMCwwLDEsNDAuNDksNDAuNDlMODIuODYsMTgxLjYyYTE2LjYzLDE2LjYzLDAsMCwwLDIzLjUyLDIzLjUxbDY2Ljc2LTY2Ljc1YTI4LjYzLDI4LjYzLDAsMCwxLDQwLjQ5LDQwLjQ5WiIvPjwvc3ZnPg==');}.icon-brackets-angle{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik04NS4wNiw0My4yMiwzMS4xMSwxMjhsNTQsODQuNzhhNiw2LDAsMCwxLTEuODQsOC4yOCw2LDYsMCwwLDEtOC4yOC0xLjg0bC01Ni04OGE2LDYsMCwwLDEsMC02LjQ0bDU2LTg4YTYsNiwwLDAsMSwxMC4xMiw2LjQ0Wm0xNTIsODEuNTYtNTYtODhhNiw2LDAsMSwwLTEwLjEyLDYuNDRMMjI0Ljg5LDEyOGwtNTMuOTUsODQuNzhhNiw2LDAsMCwwLDEuODQsOC4yOCw2LDYsMCwwLDAsOC4yOC0xLjg0bDU2LTg4QTYsNiwwLDAsMCwyMzcuMDYsMTI0Ljc4WiIvPjwvc3ZnPg==');}.icon-brain{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yNDYsMTI0YTU0LjEzLDU0LjEzLDAsMCwwLTMyLTQ5LjMzVjcyYTQ2LDQ2LDAsMCwwLTg2LTIyLjY3QTQ2LDQ2LDAsMCwwLDQyLDcydjIuNjdhNTQsNTQsMCwwLDAsMCw5OC42M1YxNzZhNDYsNDYsMCwwLDAsODYsMjIuNjdBNDYsNDYsMCwwLDAsMjE0LDE3NnYtMi43QTU0LjA3LDU0LjA3LDAsMCwwLDI0NiwxMjRaTTg4LDIxMGEzNCwzNCwwLDAsMS0zNC0zMi45NEE1My42Nyw1My42NywwLDAsMCw2NCwxNzhoOGE2LDYsMCwwLDAsMC0xMkg2NEE0Miw0MiwwLDAsMSw1MCw4NC4zOWE2LDYsMCwwLDAsNC01LjY2VjcyYTM0LDM0LDAsMCwxLDY4LDB2NzMuMDVBNDUuODksNDUuODksMCwwLDAsODgsMTMwYTYsNiwwLDAsMCwwLDEyLDM0LDM0LDAsMCwxLDAsNjhabTEwNC00NGgtOGE2LDYsMCwwLDAsMCwxMmg4YTUzLjY3LDUzLjY3LDAsMCwwLDEwLS45NEEzNCwzNCwwLDEsMSwxNjgsMTQyYTYsNiwwLDAsMCwwLTEyLDQ1Ljg5LDQ1Ljg5LDAsMCwwLTM0LDE1LjA1VjcyYTM0LDM0LDAsMCwxLDY4LDB2Ni43M2E2LDYsMCwwLDAsNCw1LjY2QTQyLDQyLDAsMCwxLDE5MiwxNjZabTE0LTU0YTYsNiwwLDAsMS02LDZoLTRhMzQsMzQsMCwwLDEtMzQtMzRWODBhNiw2LDAsMCwxLDEyLDB2NGEyMiwyMiwwLDAsMCwyMiwyMmg0QTYsNiwwLDAsMSwyMDYsMTEyWk02MCwxMThINTZhNiw2LDAsMCwxLDAtMTJoNEEyMiwyMiwwLDAsMCw4Miw4NFY4MGE2LDYsMCwwLDEsMTIsMHY0QTM0LDM0LDAsMCwxLDYwLDExOFoiLz48L3N2Zz4=');}.icon-palette{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xOTkuMzcsNTUuMzFBMTAxLjMyLDEwMS4zMiwwLDAsMCwxMjgsMjZoLTFBMTAyLDEwMiwwLDAsMCwyNiwxMjhjMCw0Mi4wOSwyNi4wNyw3Ny40NCw2OCw5Mi4yNkEzMC4yMSwzMC4yMSwwLDAsMCwxMDQuMTEsMjIyLDMwLjA2LDMwLjA2LDAsMCwwLDEzNCwxOTJhMTgsMTgsMCwwLDEsMTgtMThoNDYuMjFhMjkuODIsMjkuODIsMCwwLDAsMjkuMjUtMjMuMzFBMTAyLjcxLDEwMi43MSwwLDAsMCwyMzAsMTI3LjExLDEwMS4yNSwxMDEuMjUsMCwwLDAsMTk5LjM3LDU1LjMxWk0yMTUuNzYsMTQ4YTE3Ljg5LDE3Ljg5LDAsMCwxLTE3LjU1LDE0SDE1MmEzMCwzMCwwLDAsMC0zMCwzMCwxOCwxOCwwLDAsMS0yNCwxN0M2MSwxOTUuODYsMzgsMTY0Ljg1LDM4LDEyOGE5MCw5MCwwLDAsMSw4OS4wNy05MEgxMjhhOTAuMzQsOTAuMzQsMCwwLDEsOTAsODkuMjJBOTAuNDYsOTAuNDYsMCwwLDEsMjE1Ljc2LDE0OFpNMTM4LDc2YTEwLDEwLDAsMSwxLTEwLTEwQTEwLDEwLDAsMCwxLDEzOCw3NlpNOTQsMTAwQTEwLDEwLDAsMSwxLDg0LDkwLDEwLDEwLDAsMCwxLDk0LDEwMFptMCw1NmExMCwxMCwwLDEsMS0xMC0xMEExMCwxMCwwLDAsMSw5NCwxNTZabTg4LTU2YTEwLDEwLDAsMSwxLTEwLTEwQTEwLDEwLDAsMCwxLDE4MiwxMDBaIi8+PC9zdmc+');}.icon-pen-nib{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yNDYsOTIuNjhhMTMuOTQsMTMuOTQsMCwwLDAtNC4xLTkuOUwxNzMuMjEsMTQuMWExNCwxNCwwLDAsMC0xOS44LDBMMTI0LjY4LDQyLjgzLDY2LjIyLDY0Ljc2YTE0LDE0LDAsMCwwLTguOSwxMC44TDM0LjA4LDIxNUE2LDYsMCwwLDAsNDAsMjIyYTYuNjEsNi42MSwwLDAsMCwxLS4wOGwxMzkuNDQtMjMuMjRhMTQsMTQsMCwwLDAsMTAuODEtOC45bDIxLjkyLTU4LjQ2LDI4Ljc0LTI4Ljc0QTEzLjkyLDEzLjkyLDAsMCwwLDI0Niw5Mi42OFptLTY2LDkyLjg5YTIsMiwwLDAsMS0xLjU0LDEuMjdMNTcuNDksMjA3bDUyLjg3LTUyLjg4YTI2LDI2LDAsMSwwLTguNDgtOC40OEw0OSwxOTguNTNsMjAuMTctMTIxQTIsMiwwLDAsMSw3MC40Myw3Nmw1Ni4wNi0yMUwyMDEsMTI5LjUxWk0xMTAsMTMyYTE0LDE0LDAsMSwxLDE0LDE0QTE0LDE0LDAsMCwxLDExMCwxMzJaTTIzMy40MSw5NC4xLDIwOCwxMTkuNTEsMTM2LjQ4LDQ4LDE2MS45LDIyLjU4YTIsMiwwLDAsMSwyLjgzLDBsNjguNjgsNjguNjlhMiwyLDAsMCwxLDAsMi44M1oiLz48L3N2Zz4=');}.icon-question{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMzgsMTgwYTEwLDEwLDAsMSwxLTEwLTEwQTEwLDEwLDAsMCwxLDEzOCwxODBaTTEyOCw3NGMtMjEsMC0zOCwxNS4yNS0zOCwzNHY0YTYsNiwwLDAsMCwxMiwwdi00YzAtMTIuMTMsMTEuNjYtMjIsMjYtMjJzMjYsOS44NywyNiwyMi0xMS42NiwyMi0yNiwyMmE2LDYsMCwwLDAtNiw2djhhNiw2LDAsMCwwLDEyLDB2LTIuNDJjMTguMTEtMi41OCwzMi0xNi42NiwzMi0zMy41OEMxNjYsODkuMjUsMTQ5LDc0LDEyOCw3NFptMTAyLDU0QTEwMiwxMDIsMCwxLDEsMTI4LDI2LDEwMi4xMiwxMDIuMTIsMCwwLDEsMjMwLDEyOFptLTEyLDBhOTAsOTAsMCwxLDAtOTAsOTBBOTAuMSw5MC4xLDAsMCwwLDIxOCwxMjhaIi8+PC9zdmc+');}.icon-city{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yNDAsMjEwSDIzMFY4OGE2LDYsMCwwLDAtNi02SDE2MGE2LDYsMCwwLDAtNiw2djQySDEwMlY0MGE2LDYsMCwwLDAtNi02SDMyYTYsNiwwLDAsMC02LDZWMjEwSDE2YTYsNiwwLDAsMCwwLDEySDI0MGE2LDYsMCwwLDAsMC0xMlpNMTY2LDk0aDUyVjIxMEgxNjZabS0xMiw0OHY2OEgxMDJWMTQyWk0zOCw0Nkg5MFYyMTBIMzhaTTcwLDcyVjg4YTYsNiwwLDAsMS0xMiwwVjcyYTYsNiwwLDAsMSwxMiwwWm0wLDQ4djE2YTYsNiwwLDAsMS0xMiwwVjEyMGE2LDYsMCwwLDEsMTIsMFptMCw0OHYxNmE2LDYsMCwwLDEtMTIsMFYxNjhhNiw2LDAsMCwxLDEyLDBabTUyLDE2VjE2OGE2LDYsMCwwLDEsMTIsMHYxNmE2LDYsMCwwLDEtMTIsMFptNjQsMFYxNjhhNiw2LDAsMCwxLDEyLDB2MTZhNiw2LDAsMCwxLTEyLDBabTAtNDhWMTIwYTYsNiwwLDAsMSwxMiwwdjE2YTYsNiwwLDAsMS0xMiwwWiIvPjwvc3ZnPg==');}.icon-folder{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTYsNzRIMTMwLjQ5bC0yNy45LTI3LjlhMTMuOTQsMTMuOTQsMCwwLDAtOS45LTQuMUg0MEExNCwxNCwwLDAsMCwyNiw1NlYyMDAuNjJBMTMuMzksMTMuMzksMCwwLDAsMzkuMzgsMjE0SDIxNi44OUExMy4xMiwxMy4xMiwwLDAsMCwyMzAsMjAwLjg5Vjg4QTE0LDE0LDAsMCwwLDIxNiw3NFpNNDAsNTRIOTIuNjlhMiwyLDAsMCwxLDEuNDEuNTlMMTEzLjUxLDc0SDM4VjU2QTIsMiwwLDAsMSw0MCw1NFpNMjE4LDIwMC44OWExLjExLDEuMTEsMCwwLDEtMS4xMSwxLjExSDM5LjM4QTEuNCwxLjQsMCwwLDEsMzgsMjAwLjYyVjg2SDIxNmEyLDIsMCwwLDEsMiwyWiIvPjwvc3ZnPg==');}.icon-hash{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjQsOTBIMTczbDguODktNDguOTNhNiw2LDAsMSwwLTExLjgtMi4xNEwxNjAuODEsOTBIMTA5bDguODktNDguOTNhNiw2LDAsMCwwLTExLjgtMi4xNEw5Ni44MSw5MEg0OGE2LDYsMCwwLDAsMCwxMkg5NC42M2wtOS40Niw1MkgzMmE2LDYsMCwwLDAsMCwxMkg4M0w3NC4xLDIxNC45M2E2LDYsMCwwLDAsNC44Myw3QTUuNjQsNS42NCwwLDAsMCw4MCwyMjJhNiw2LDAsMCwwLDUuODktNC45M0w5NS4xOSwxNjZIMTQ3bC04Ljg5LDQ4LjkzYTYsNiwwLDAsMCw0LjgzLDcsNS42NCw1LjY0LDAsMCwwLDEuMDguMSw2LDYsMCwwLDAsNS44OS00LjkzTDE1OS4xOSwxNjZIMjA4YTYsNiwwLDAsMCwwLTEySDE2MS4zN2w5LjQ2LTUySDIyNGE2LDYsMCwwLDAsMC0xMlptLTc0LjgzLDY0SDk3LjM3bDkuNDYtNTJoNTEuOFoiLz48L3N2Zz4=');}.icon-shapes{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik02OS42OSw2Mi4xYTYsNiwwLDAsMC0xMS4zOCwwbC00MCwxMjBBNiw2LDAsMCwwLDI0LDE5MGg4MGE2LDYsMCwwLDAsNS42OS03LjlaTTMyLjMyLDE3OCw2NCw4M2wzMS42OCw5NVpNMjA2LDc2YTUwLDUwLDAsMSwwLTUwLDUwQTUwLjA2LDUwLjA2LDAsMCwwLDIwNiw3NlptLTg4LDBhMzgsMzgsMCwxLDEsMzgsMzhBMzgsMzgsMCwwLDEsMTE4LDc2Wm0xMDYsNzBIMTM2YTYsNiwwLDAsMC02LDZ2NTZhNiw2LDAsMCwwLDYsNmg4OGE2LDYsMCwwLDAsNi02VjE1MkE2LDYsMCwwLDAsMjI0LDE0NlptLTYsNTZIMTQyVjE1OGg3NloiLz48L3N2Zz4=');}.icon-diamonds-four{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMjMuNzYsMTA4LjI0YTYsNiwwLDAsMCw4LjQ4LDBsNDAtNDBhNiw2LDAsMCwwLDAtOC40OGwtNDAtNDBhNiw2LDAsMCwwLTguNDgsMGwtNDAsNDBhNiw2LDAsMCwwLDAsOC40OFpNMTI4LDMyLjQ5LDE1OS41MSw2NCwxMjgsOTUuNTEsOTYuNDksNjRabTQuMjQsMTE1LjI3YTYsNiwwLDAsMC04LjQ4LDBsLTQwLDQwYTYsNiwwLDAsMCwwLDguNDhsNDAsNDBhNiw2LDAsMCwwLDguNDgsMGw0MC00MGE2LDYsMCwwLDAsMC04LjQ4Wk0xMjgsMjIzLjUxLDk2LjQ5LDE5MiwxMjgsMTYwLjQ5LDE1OS41MSwxOTJabTEwOC4yNC05OS43NS00MC00MGE2LDYsMCwwLDAtOC40OCwwbC00MCw0MGE2LDYsMCwwLDAsMCw4LjQ4bDQwLDQwYTYsNiwwLDAsMCw4LjQ4LDBsNDAtNDBBNiw2LDAsMCwwLDIzNi4yNCwxMjMuNzZaTTE5MiwxNTkuNTEsMTYwLjQ5LDEyOCwxOTIsOTYuNDksMjIzLjUxLDEyOFptLTgzLjc2LTM1Ljc1LTQwLTQwYTYsNiwwLDAsMC04LjQ4LDBsLTQwLDQwYTYsNiwwLDAsMCwwLDguNDhsNDAsNDBhNiw2LDAsMCwwLDguNDgsMGw0MC00MEE2LDYsMCwwLDAsMTA4LjI0LDEyMy43NlpNNjQsMTU5LjUxLDMyLjQ5LDEyOCw2NCw5Ni40OSw5NS41MSwxMjhaIi8+PC9zdmc+');}.icon-crosshair-simple{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMjgsMjZBMTAyLDEwMiwwLDEsMCwyMzAsMTI4LDEwMi4xMiwxMDIuMTIsMCwwLDAsMTI4LDI2Wm02LDE5MS44VjE4NGE2LDYsMCwwLDAtMTIsMHYzMy44QTkwLjE1LDkwLjE1LDAsMCwxLDM4LjIsMTM0SDcyYTYsNiwwLDAsMCwwLTEySDM4LjJBOTAuMTUsOTAuMTUsMCwwLDEsMTIyLDM4LjJWNzJhNiw2LDAsMCwwLDEyLDBWMzguMkE5MC4xNSw5MC4xNSwwLDAsMSwyMTcuOCwxMjJIMTg0YTYsNiwwLDAsMCwwLDEyaDMzLjhBOTAuMTUsOTAuMTUsMCwwLDEsMTM0LDIxNy44WiIvPjwvc3ZnPg==');}.icon-circle-notch{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzAsMTI4YTEwMiwxMDIsMCwwLDEtMjA0LDBjMC00MC4xOCwyMy4zNS03Ni44Niw1OS41LTkzLjQ1YTYsNiwwLDAsMSw1LDEwLjlDNTguNjEsNjAuMDksMzgsOTIuNDksMzgsMTI4YTkwLDkwLDAsMCwwLDE4MCwwYzAtMzUuNTEtMjAuNjEtNjcuOTEtNTIuNS04Mi41NWE2LDYsMCwwLDEsNS0xMC45QzIwNi42NSw1MS4xNCwyMzAsODcuODIsMjMwLDEyOFoiLz48L3N2Zz4=');}.icon-cards-three{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDgsOTBINDhhMTQsMTQsMCwwLDAtMTQsMTR2OTZhMTQsMTQsMCwwLDAsMTQsMTRIMjA4YTE0LDE0LDAsMCwwLDE0LTE0VjEwNEExNCwxNCwwLDAsMCwyMDgsOTBabTIsMTEwYTIsMiwwLDAsMS0yLDJINDhhMiwyLDAsMCwxLTItMlYxMDRhMiwyLDAsMCwxLDItMkgyMDhhMiwyLDAsMCwxLDIsMlpNNTAsNjRhNiw2LDAsMCwxLDYtNkgyMDBhNiw2LDAsMCwxLDAsMTJINTZBNiw2LDAsMCwxLDUwLDY0Wk02NiwzMmE2LDYsMCwwLDEsNi02SDE4NGE2LDYsMCwwLDEsMCwxMkg3MkE2LDYsMCwwLDEsNjYsMzJaIi8+PC9zdmc+');}.icon-sun-dim{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMjIsNDBWMzJhNiw2LDAsMCwxLDEyLDB2OGE2LDYsMCwwLDEtMTIsMFptNjgsODhhNjIsNjIsMCwxLDEtNjItNjJBNjIuMDcsNjIuMDcsMCwwLDEsMTkwLDEyOFptLTEyLDBhNTAsNTAsMCwxLDAtNTAsNTBBNTAuMDYsNTAuMDYsMCwwLDAsMTc4LDEyOFpNNTkuNzYsNjguMjRhNiw2LDAsMSwwLDguNDgtOC40OGwtOC04YTYsNiwwLDAsMC04LjQ4LDguNDhabTAsMTE5LjUyLTgsOGE2LDYsMCwxLDAsOC40OCw4LjQ4bDgtOGE2LDYsMCwxLDAtOC40OC04LjQ4Wm0xMzYtMTM2LTgsOGE2LDYsMCwxLDAsOC40OCw4LjQ4bDgtOGE2LDYsMCwwLDAtOC40OC04LjQ4Wm0uNDgsMTM2YTYsNiwwLDAsMC04LjQ4LDguNDhsOCw4YTYsNiwwLDAsMCw4LjQ4LTguNDhaTTQwLDEyMkgzMmE2LDYsMCwwLDAsMCwxMmg4YTYsNiwwLDAsMCwwLTEyWm04OCw4OGE2LDYsMCwwLDAtNiw2djhhNiw2LDAsMCwwLDEyLDB2LThBNiw2LDAsMCwwLDEyOCwyMTBabTk2LTg4aC04YTYsNiwwLDAsMCwwLDEyaDhhNiw2LDAsMCwwLDAtMTJaIi8+PC9zdmc+');}.icon-moon{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzIuMTMsMTQzLjY0YTYsNiwwLDAsMC02LTEuNDlBOTAuMDcsOTAuMDcsMCwwLDEsMTEzLjg2LDI5Ljg1YTYsNiwwLDAsMC03LjQ5LTcuNDhBMTAyLjg4LDEwMi44OCwwLDAsMCw1NC40OCw1OC42OCwxMDIsMTAyLDAsMCwwLDE5Ny4zMiwyMDEuNTJhMTAyLjg4LDEwMi44OCwwLDAsMCwzNi4zMS01MS44OUE2LDYsMCwwLDAsMjMyLjEzLDE0My42NFptLTQyLDQ4LjI5YTkwLDkwLDAsMCwxLTEyNi0xMjZBOTAuOSw5MC45LDAsMCwxLDk5LjY1LDM3LjY2LDEwMi4wNiwxMDIuMDYsMCwwLDAsMjE4LjM0LDE1Ni4zNSw5MC45LDkwLjksMCwwLDEsMTkwLjEsMTkxLjkzWiIvPjwvc3ZnPg==');}.icon-plus-square{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDgsMzRINDhBMTQsMTQsMCwwLDAsMzQsNDhWMjA4YTE0LDE0LDAsMCwwLDE0LDE0SDIwOGExNCwxNCwwLDAsMCwxNC0xNFY0OEExNCwxNCwwLDAsMCwyMDgsMzRabTIsMTc0YTIsMiwwLDAsMS0yLDJINDhhMiwyLDAsMCwxLTItMlY0OGEyLDIsMCwwLDEsMi0ySDIwOGEyLDIsMCwwLDEsMiwyWm0tMzYtODBhNiw2LDAsMCwxLTYsNkgxMzR2MzRhNiw2LDAsMCwxLTEyLDBWMTM0SDg4YTYsNiwwLDAsMSwwLTEyaDM0Vjg4YTYsNiwwLDAsMSwxMiwwdjM0aDM0QTYsNiwwLDAsMSwxNzQsMTI4WiIvPjwvc3ZnPg==');}.icon-arrow-elbow-left-up{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzgsMTkyYTYsNiwwLDAsMS02LDZIODhhNiw2LDAsMCwxLTYtNlY2Mi40OUw0NC4yNCwxMDAuMjRhNiw2LDAsMCwxLTguNDgtOC40OGw0OC00OGE2LDYsMCwwLDEsOC40OCwwbDQ4LDQ4YTYsNiwwLDEsMS04LjQ4LDguNDhMOTQsNjIuNDlWMTg2SDIzMkE2LDYsMCwwLDEsMjM4LDE5MloiLz48L3N2Zz4=');}.icon-arrow-elbow-right-up{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjAuMjQsMTAwLjI0YTYsNiwwLDAsMS04LjQ4LDBMMTc0LDYyLjQ5VjE5MmE2LDYsMCwwLDEtNiw2SDI0YTYsNiwwLDAsMSwwLTEySDE2MlY2Mi40OWwtMzcuNzYsMzcuNzVhNiw2LDAsMCwxLTguNDgtOC40OGw0OC00OGE2LDYsMCwwLDEsOC40OCwwbDQ4LDQ4QTYsNiwwLDAsMSwyMjAuMjQsMTAwLjI0WiIvPjwvc3ZnPg==');}.icon-x{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDQuMjQsMTk1Ljc2YTYsNiwwLDEsMS04LjQ4LDguNDhMMTI4LDEzNi40OSw2MC4yNCwyMDQuMjRhNiw2LDAsMCwxLTguNDgtOC40OEwxMTkuNTEsMTI4LDUxLjc2LDYwLjI0YTYsNiwwLDAsMSw4LjQ4LTguNDhMMTI4LDExOS41MWw2Ny43Ni02Ny43NWE2LDYsMCwwLDEsOC40OCw4LjQ4TDEzNi40OSwxMjhaIi8+PC9zdmc+');}.icon-floppy-disk{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTcuOSw3My40MiwxODIuNTgsMzguMWExMy45LDEzLjksMCwwLDAtOS44OS00LjFINDhBMTQsMTQsMCwwLDAsMzQsNDhWMjA4YTE0LDE0LDAsMCwwLDE0LDE0SDIwOGExNCwxNCwwLDAsMCwxNC0xNFY4My4zMUExMy45LDEzLjksMCwwLDAsMjE3LjksNzMuNDJaTTE3MCwyMTBIODZWMTUyYTIsMiwwLDAsMSwyLTJoODBhMiwyLDAsMCwxLDIsMlptNDAtMmEyLDIsMCwwLDEtMiwySDE4MlYxNTJhMTQsMTQsMCwwLDAtMTQtMTRIODhhMTQsMTQsMCwwLDAtMTQsMTR2NThINDhhMiwyLDAsMCwxLTItMlY0OGEyLDIsMCwwLDEsMi0ySDE3Mi42OWEyLDIsMCwwLDEsMS40MS41OEwyMDkuNDIsODEuOWEyLDIsMCwwLDEsLjU4LDEuNDFaTTE1OCw3MmE2LDYsMCwwLDEtNiw2SDk2YTYsNiwwLDAsMSwwLTEyaDU2QTYsNiwwLDAsMSwxNTgsNzJaIi8+PC9zdmc+');}.icon-x-circle{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjQuMjQsMTAwLjI0LDEzNi40OCwxMjhsMjcuNzYsMjcuNzZhNiw2LDAsMSwxLTguNDgsOC40OEwxMjgsMTM2LjQ4bC0yNy43NiwyNy43NmE2LDYsMCwwLDEtOC40OC04LjQ4TDExOS41MiwxMjgsOTEuNzYsMTAwLjI0YTYsNiwwLDAsMSw4LjQ4LTguNDhMMTI4LDExOS41MmwyNy43Ni0yNy43NmE2LDYsMCwwLDEsOC40OCw4LjQ4Wk0yMzAsMTI4QTEwMiwxMDIsMCwxLDEsMTI4LDI2LDEwMi4xMiwxMDIuMTIsMCwwLDEsMjMwLDEyOFptLTEyLDBhOTAsOTAsMCwxLDAtOTAsOTBBOTAuMSw5MC4xLDAsMCwwLDIxOCwxMjhaIi8+PC9zdmc+');}.icon-minus-square{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDgsMzRINDhBMTQsMTQsMCwwLDAsMzQsNDhWMjA4YTE0LDE0LDAsMCwwLDE0LDE0SDIwOGExNCwxNCwwLDAsMCwxNC0xNFY0OEExNCwxNCwwLDAsMCwyMDgsMzRabTIsMTc0YTIsMiwwLDAsMS0yLDJINDhhMiwyLDAsMCwxLTItMlY0OGEyLDIsMCwwLDEsMi0ySDIwOGEyLDIsMCwwLDEsMiwyWm0tMzYtODBhNiw2LDAsMCwxLTYsNkg4OGE2LDYsMCwwLDEsMC0xMmg4MEE2LDYsMCwwLDEsMTc0LDEyOFoiLz48L3N2Zz4=');}.icon-pencil-simple{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjUuOSw3NC43OCwxODEuMjEsMzAuMDlhMTQsMTQsMCwwLDAtMTkuOCwwTDM4LjEsMTUzLjQxYTEzLjk0LDEzLjk0LDAsMCwwLTQuMSw5LjlWMjA4YTE0LDE0LDAsMCwwLDE0LDE0SDkyLjY5YTEzLjk0LDEzLjk0LDAsMCwwLDkuOS00LjFMMjI1LjksOTQuNThhMTQsMTQsMCwwLDAsMC0xOS44Wk05NC4xLDIwOS40MWEyLDIsMCwwLDEtMS40MS41OUg0OGEyLDIsMCwwLDEtMi0yVjE2My4zMWEyLDIsMCwwLDEsLjU5LTEuNDFMMTM2LDcyLjQ4LDE4My41MSwxMjBaTTIxNy40MSw4Ni4xLDE5MiwxMTEuNTEsMTQ0LjQ5LDY0LDE2OS45LDM4LjU4YTIsMiwwLDAsMSwyLjgzLDBsNDQuNjgsNDQuNjlhMiwyLDAsMCwxLDAsMi44M1oiLz48L3N2Zz4=');}.icon-dots-six-vertical{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMDIsNjBBMTAsMTAsMCwxLDEsOTIsNTAsMTAsMTAsMCwwLDEsMTAyLDYwWm02MiwxMGExMCwxMCwwLDEsMC0xMC0xMEExMCwxMCwwLDAsMCwxNjQsNzBaTTkyLDExOGExMCwxMCwwLDEsMCwxMCwxMEExMCwxMCwwLDAsMCw5MiwxMThabTcyLDBhMTAsMTAsMCwxLDAsMTAsMTBBMTAsMTAsMCwwLDAsMTY0LDExOFpNOTIsMTg2YTEwLDEwLDAsMSwwLDEwLDEwQTEwLDEwLDAsMCwwLDkyLDE4NlptNzIsMGExMCwxMCwwLDEsMCwxMCwxMEExMCwxMCwwLDAsMCwxNjQsMTg2WiIvPjwvc3ZnPg==');}.icon-list{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjIsMTI4YTYsNiwwLDAsMS02LDZINDBhNiw2LDAsMCwxLDAtMTJIMjE2QTYsNiwwLDAsMSwyMjIsMTI4Wk00MCw3MEgyMTZhNiw2LDAsMCwwLDAtMTJINDBhNiw2LDAsMCwwLDAsMTJaTTIxNiwxODZINDBhNiw2LDAsMCwwLDAsMTJIMjE2YTYsNiwwLDAsMCwwLTEyWiIvPjwvc3ZnPg==');}.icon-loading{--icon:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyAgICB3aWR0aD0iMzIiICAgIGhlaWdodD0iMzIiICAgIHZpZXdCb3g9IjAgMCAzMiAzMiIgICAgdmVyc2lvbj0iMS4xIiAgICB4bWw6c3BhY2U9InByZXNlcnZlIiAgICBzdHlsZT0iY2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNSIgICAgaWQ9InN2ZzEwIiAgICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciICAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxkZWZzICAgIGlkPSJkZWZzMTAiIC8+PHBhdGggICAgaWQ9InBhdGgxMSIgICAgc3R5bGU9ImJhc2VsaW5lLXNoaWZ0OmJhc2VsaW5lO2Rpc3BsYXk6aW5saW5lO292ZXJmbG93OnZpc2libGU7dmVjdG9yLWVmZmVjdDpub25lO2ZpbGw6IzIyMjIyMjtlbmFibGUtYmFja2dyb3VuZDphY2N1bXVsYXRlO3N0b3AtY29sb3I6IzAwMDAwMDtzdG9wLW9wYWNpdHk6MSIgICAgZD0ibSAxNi42MjEwOTQsMS4xNDI1NzgxIGMgLTguMjY2MzIzMiwwIC0xNi4yMjA4NjczOCw2LjQ0MjgwOTUgLTE1LjU4NTkzNzgsMTQuNjg1NTQ2OSAwLjYwMTM0NTUsNy44MDczMDggNy40MzQxMjY0LDE0LjEyNjk4IDE0LjkzMzU5MzgsMTQuOTQzMzU5IDguODM5ODQ1LDAuOTYyMjgzIDE1LjUwNTQ2OSwtNi4zNzY5MTkgMTUuMDA1ODU5LC0xNC45ODYzMjggQyAzMC40OTU5LDcuNTM2MjY4NCAyNC44ODMzOTcsMS4xNDI1NzgxIDE2LjYyMTA5NCwxLjE0MjU3ODEgWiBtIDAsMC42NTAzOTA3IEMgMjYuNDg4Nzg2LDEuODAzODY0NSAyOS43MTQ1MTgsOS41OTM1ODMzIDMwLjMwMjczNCwxNS44MDQ2ODggMzEuMTQxOTgyLDI0LjY2NjM2NSAyMi4xNjA0NTksMzEuMTY4MDc3IDE2LjAzOTA2MiwzMC4xMjUgOC44OTUxMzI3LDI4LjkwNzY4MSAyLjI2MTMxNDIsMjMuMjc5Mzc2IDEuNjgzNTkzOCwxNS43NzkyOTcgMS4wNzY5MzM4LDcuOTAzMjc1NCA4LjcyMjU0NTEsMS43ODQyNjk5IDE2LjYyMTA5NCwxLjc5Mjk2ODggWiBtIC0wLjA2NDQ1LDEuMjE4NzUgYyAtMy42MTAwODMsMCAtNy4xNTQ3OTk1LDEuNDAxMDY4NyAtOS43MzA0NjkxLDMuNzAzMTI1IEMgNC4yNTA1MDIzLDkuMDE2OTAwMiAyLjY0MjAzNzIsMTIuMjI2Mjk1IDIuOTE5OTIxOSwxNS44MzM5ODQgMy40NDY5MzUsMjIuNjc1NzEyIDkuNDI4OTY0OSwyOC4xOTg5ODUgMTUuOTk4MDQ3LDI4LjkxNDA2MiAyMy43MTQyNTYsMjkuNzU0MDIzIDI5LjUzMTYwMywyMy4zMzE3IDI5LjA5NTcwMywxNS44MjAzMTIgMjguNjc3OTQ4LDguNjIxMzk1MyAyMy43NzY2ODYsMy4wMTE3MTg4IDE2LjU1NjY0MSwzLjAxMTcxODggWiBtIDAsMC4xOTUzMTI0IGMgNy4xMTkxMzQsMCAxMS45MzI3MSw1LjUwODEzNzMgMTIuMzQ1NzAzLDEyLjYyNDk5OTggQyAyOS4zMzIwNjIsMjMuMjM2ODk2IDIzLjYxODk1OCwyOS41NDU5OTggMTYuMDE5NTMxLDI4LjcxODc1IDkuNTQ1NDMyMSwyOC4wMTQwMTIgMy42MzQxNjM3LDIyLjU1NTE0MyAzLjExNTIzNDQsMTUuODE4MzU5IDIuODQyNDU2MywxMi4yNzY5NjcgNC40MTg0MTA5LDkuMTI4MzE2OSA2Ljk1NzAzMTIsNi44NTkzNzUgOS40OTU2NTE2LDQuNTkwNDMzMSAxMi45OTcwOTMsMy4yMDcwMzEyIDE2LjU1NjY0MSwzLjIwNzAzMTIgWiBtIC0wLjA3MDMxLDEuNDE2MDE1NyBjIC0zLjE2MTk3MywwIC02LjI2MzUwOSwxLjIyNTgxMzkgLTguNTE5NTMxMSwzLjI0MjE4NzUgQyA1LjcxMDc2OTEsOS44ODE2MDggNC4zMDE0NTQyLDEyLjY5NDU4OSA0LjU0NDkyMTksMTUuODU1NDY5IDUuMDA2NTYyNCwyMS44NDg1NTQgMTAuMjQ0MTc4LDI2LjY4NjE1OSAxNS45OTgwNDcsMjcuMzEyNSAyMi43NTcwMTMsMjguMDQ4MjYxIDI3Ljg1NDQ1MSwyMi40MjA5MzYgMjcuNDcyNjU2LDE1Ljg0MTc5NyAyNy4xMDY4MjQsOS41Mzc2MDI1IDIyLjgxMDE2LDQuNjIzMDQ2OSAxNi40ODYzMjgsNC42MjMwNDY5IFogbSAwLDAuMTk1MzEyNSBjIDYuMjIyOTIsMCAxMC40Mjk5NDYsNC44MTMwMTM4IDEwLjc5MTAxNiwxMS4wMzUxNTY2IDAuMzc1NjEzLDYuNDcyNjE1IC00LjYxNzU4NCwxMS45ODY3MiAtMTEuMjU5NzY2LDExLjI2MzY3MiBDIDEwLjM1ODY4NSwyNi41MDExODYgNS4xOTE4MzgxLDIxLjcyNzk4NSA0LjczODI4MTIsMTUuODM5ODQ0IDQuNDk5OTIwMSwxMi43NDUyNjIgNS44NzY3MzE1LDkuOTk0OTc3OCA4LjA5NTcwMzEsOC4wMTE3MTg4IDEwLjMxNDY3NSw2LjAyODQ1OTUgMTMuMzc0ODksNC44MTgzNTk0IDE2LjQ4NjMyOCw0LjgxODM1OTQgWiBtIC0wLjA2ODM2LDEuNDE2MDE1NiBjIC0yLjcxMzg3NywwIC01LjM3NjExOCwxLjA1MjUxNjQgLTcuMzEyNTAwMiwyLjc4MzIwMzEgLTEuOTM2MzgyOCwxLjczMDY4NjkgLTMuMTQ2NTUxNyw0LjE0NTMxMTkgLTIuOTM3NSw2Ljg1OTM3NDkgMC4zOTYyNjk5LDUuMTQ0NDMgNC44ODk0NDQyLDkuMjk0NDI5IDkuODI4MTI1Miw5LjgzMjAzMSA1LjgwMTc0OSwwLjYzMTU2MiAxMC4xNzkyNTcsLTQuMTk4ODI4IDkuODUxNTYyLC05Ljg0NTcwMyBDIDI1LjUzMzc1LDEwLjQ1MzgyMiAyMS44NDU2MTYsNi4yMzQzNzUgMTYuNDE3OTc0LDYuMjM0Mzc1IFogbSAwLDAuMTk1MzEyNSBjIDUuMzI2NzMsMCA4LjkyNTIyNiw0LjExNzkwNTUgOS4yMzQzNzUsOS40NDUzMTI1IDAuMzIxNTEzLDUuNTQwMzUxIC0zLjk0OTgwMSwxMC4yNTk0NzQgLTkuNjM0NzY2LDkuNjQwNjI1IEMgMTEuMTczODc1LDI0Ljk4ODM2MiA2Ljc0OTUxNDMsMjAuOTAwODE0IDYuMzYxMzI4MSwxNS44NjEzMjggNi4xNTczODMxLDEzLjIxMzU2MyA3LjMzNTA0MzEsMTAuODU5NjgyIDkuMjM0Mzc1LDkuMTYyMTA5NCAxMS4xMzM3MDcsNy40NjQ1MzcyIDEzLjc1NDYyOCw2LjQyOTY4NzUgMTYuNDE3OTY5LDYuNDI5Njg3NSBaIG0gLTAuMDY4MzYsMS40MTYwMTU2IGMgLTIuMjY1Nzc1LDAgLTQuNDg4NzI5LDAuODc5MjE5NiAtNi4xMDU0NjgsMi4zMjQyMTg5IC0xLjYxNjc0MDgsMS40NDQ5OTkgLTIuNjI3NzYwNywzLjQ2MTI2OSAtMi40NTMxMjU0LDUuNzI4NTE2IDAuMzMwODk4Niw0LjI5NTc2OCA0LjA4MTU5NjQsNy43NjAxMiA4LjIwNTA3ODQsOC4yMDg5ODQgNC44NDQ1MjUsMC41MjczNiA4LjUwMDE1NiwtMy41MDYwOTcgOC4yMjY1NjIsLTguMjIwNzAzIEMgMjMuOTYwNjcyLDExLjM3MTk5NiAyMC44ODEwNiw3Ljg0NTcwMzEgMTYuMzQ5NjE0LDcuODQ1NzAzMSBaIG0gMCwwLjE5NTMxMjUgYyA0LjQzMDUzNCwwIDcuNDIyNDYxLDMuNDIyNzk5NCA3LjY3OTY4OCw3Ljg1NTQ2ODQgMC4yNjc0MTIsNC42MDgwODIgLTMuMjgzOTc4LDguNTMyMjI2IC04LjAxMTcxOSw4LjAxNzU3OCBDIDExLjk4OTA3NSwyMy40NzU1MzggOC4zMDcxODk5LDIwLjA3NTU5MyA3Ljk4NDM3NSwxNS44ODQ3NjYgNy44MTQ4NDYzLDEzLjY4MzgxOSA4Ljc5NTMxMDUsMTEuNzI2MzM4IDEwLjM3NSwxMC4zMTQ0NTMgMTEuOTU0Njg5LDguOTAyNTY4OSAxNC4xMzQzNyw4LjA0MTAxNTYgMTYuMzQ5NjA5LDguMDQxMDE1NiBaIG0gLTAuMDY4MzYsMS40MTYwMTU2IGMgLTEuODE3NjcyLDAgLTMuNjAxMzQyLDAuNzAzOTY4OCAtNC44OTg0MzgsMS44NjMyODA4IC0xLjI5NzA5NSwxLjE1OTMxIC0yLjEwODk2ODMsMi43NzkxODUgLTEuOTY4NzQ5NSw0LjU5OTYxIDAuMjY1NTI2OSwzLjQ0NzExMSAzLjI3Mzc1MDUsNi4yMjU4MTMgNi41ODIwMzE1LDYuNTg1OTM3IDMuODg3Mjk1LDAuNDIzMTYgNi44MjMwMDgsLTIuODE1MzE4IDYuNjAzNTE1LC02LjU5NzY1NiBDIDIyLjM4OTU0MSwxMi4yODgyMjIgMTkuOTE2NDk1LDkuNDU3MDMxMSAxNi4yODEyNSw5LjQ1NzAzMTIgWiBtIDAsMC4xOTUzMTI2IGMgMy41MzQzMzMsMCA1LjkxNzc0MiwyLjcyNzY5NjIgNi4xMjMwNDcsNi4yNjU2MjUyIDAuMjEzMzExLDMuNjc1ODE0IC0yLjYxNjIwOCw2LjgwMzAyNSAtNi4zODY3MTksNi4zOTI1NzggLTMuMjEzMjk4LC0wLjM0OTc4NSAtNi4xNTA3NTk3LC0zLjA2MjEzIC02LjQwODIwMywtNi40MDQyOTcgLTAuMTM1MTEyMiwtMS43NTQxMjcgMC42NDQyNTIsLTMuMzEzMjU3IDEuOTA0Mjk3LC00LjQzOTQ1MyAxLjI2MDA0NSwtMS4xMjYxOTYgMy4wMDA0NDEsLTEuODE0NDUzMyA0Ljc2NzU3OCwtMS44MTQ0NTMyIHogbSAtMC4wNzAzMSwxLjQxNjAxNTIgYyAtMS4zNjk1NzIsMCAtMi43MTIsMC41MzA2NzUgLTMuNjg5NDU0LDEuNDA0Mjk3IC0wLjk3NzQ1MywwLjg3MzYyMiAtMS41OTAxNzcsMi4wOTUxNDUgLTEuNDg0Mzc1LDMuNDY4NzUgMC4yMDAxNTYsMi41OTg0NTIgMi40NjU5LDQuNjg5NTUxIDQuOTU4OTg1LDQuOTYwOTM4IDIuOTMwMDcsMC4zMTg5NTggNS4xNDM5MDgsLTIuMTIyNTg3IDQuOTc4NTE1LC00Ljk3MjY1NiAtMC4xNTgxNDUsLTIuNzI1MjQ0IC0yLjAyNDYyMiwtNC44NjEzMjkgLTQuNzYzNjcxLC00Ljg2MTMyOSB6IG0gMCwwLjE5NTMxMyBjIDIuNjM4MTM1LDAgNC40MTQ5NzUsMi4wMzQ1NDQgNC41NjgzNTksNC42Nzc3MzQgMC4xNTkyMTEsMi43NDM1NDYgLTEuOTUwMzg2LDUuMDczODI0IC00Ljc2MzY3Miw0Ljc2NzU3OCAtMi4zOTgxMDIsLTAuMjYxMDQ3IC00LjU5MTEzMSwtMi4yODc3NDEgLTQuNzgzMjAzLC00Ljc4MTI1IC0wLjEwMDY5NiwtMS4zMDczMDggMC40Nzk1MTksLTIuNDcwMDM5IDEuNDE5OTIyLC0zLjMxMDU0NiAwLjk0MDQwMywtMC44NDA1MDggMi4yMzk1NTcsLTEuMzUzNTE2IDMuNTU4NTk0LC0xLjM1MzUxNiB6IG0gLTAuMDY4MzYsMS40MTYwMTYgYyAtMC45MjE0NzIsMCAtMS44MjI2NTcsMC4zNTU0MjUgLTIuNDgwNDY5LDAuOTQzMzU5IC0wLjY1NzgxMSwwLjU4NzkzNCAtMS4wNzMzMzksMS40MTUwMSAtMS4wMDE5NTMsMi4zNDE3OTcgMC4xMzQ3ODUsMS43NDk3OTIgMS42NTYwOTUsMy4xNTMyOTEgMy4zMzM5ODUsMy4zMzU5MzcgMS45NzI4NDYsMC4yMTQ3NTkgMy40NjY3NiwtMS40MzE4MDkgMy4zNTU0NjgsLTMuMzQ5NjA5IC0wLjEwNjIyNCwtMS44MzA1MDMgLTEuMzY0MTc3LC0zLjI3MTQ4NyAtMy4yMDcwMzEsLTMuMjcxNDg0IHogbSAwLDAuMTk1MzEyIGMgMS43NDE5NDIsMCAyLjkxMjIwOSwxLjMzOTQ0IDMuMDEzNjcyLDMuMDg3ODkxIDAuMTA1MTEsMS44MTEyNzYgLTEuMjg0NTYyLDMuMzQ2NTc3IC0zLjE0MDYyNSwzLjE0NDUzMSAtMS41ODI5MDcsLTAuMTcyMzA3IC0zLjAzMzQ1NSwtMS41MTMzNTUgLTMuMTYwMTU2LC0zLjE1ODIwMyAtMC4wNjYyOCwtMC44NjA0OSAwLjMxNDc4NSwtMS42MjQ4NjggMC45MzU1NDcsLTIuMTc5Njg4IDAuNjIwNzQ5LC0wLjU1NDgxOSAxLjQ4MDYyLC0wLjg5NDUzMSAyLjM1MTU1NiwtMC44OTQ1MzEgeiBtIC0wLjA2ODM2LDEuNDE2MDE2IGMgLTAuNDczMzY5LDAgLTAuOTM1MjcxLDAuMTgyMTI5IC0xLjI3MzQzOCwwLjQ4NDM3NSAtMC4zMzgxNjcsMC4zMDIyNDYgLTAuNTU0NTQ2LDAuNzMwOTY5IC0wLjUxNzU3OCwxLjIxMDkzNyAwLjA2OTQxLDAuOTAxMTMzIDAuODQ4MjQ5LDEuNjE4OTgxIDEuNzEwOTM4LDEuNzEyODkxIDEuMDE1NjE2LDAuMTEwNTU3IDEuNzg5NjE0LC0wLjc0MTAzMSAxLjczMjQyMSwtMS43MjY1NjMgLTAuMDU0MywtMC45MzU3NjYgLTAuNzA1NjkxLC0xLjY4MTY0IC0xLjY1MjM0MywtMS42ODE2NCB6IG0gMCwwLjE5NTMxMiBjIDAuODQ1NzQsMCAxLjQwNzQ5LDAuNjQ0MzMzIDEuNDU3MDMxLDEuNDk4MDQ3IDAuMDUxMDEsMC44NzkwMDggLTAuNjE2NzkzLDEuNjE5MzI5IC0xLjUxNTYyNSwxLjUyMTQ4NCAtMC43Njc3MDYsLTAuMDgzNTcgLTEuNDc1NzgsLTAuNzM4OTY3IC0xLjUzNzEwOSwtMS41MzUxNTYgLTAuMDMxODYsLTAuNDEzNjcxIDAuMTUwMDU1LC0wLjc3OTY5NyAwLjQ1MTE3MiwtMS4wNDg4MjggMC4zMDExMTYsLTAuMjY5MTMxIDAuNzIxNjk4LC0wLjQzNTU0NyAxLjE0NDUzMSwtMC40MzU1NDcgeiIgLz48L3N2Zz4=');}.icon-magnifying-glass{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjguMjQsMjE5Ljc2bC01MS4zOC01MS4zOGE4Ni4xNSw4Ni4xNSwwLDEsMC04LjQ4LDguNDhsNTEuMzgsNTEuMzhhNiw2LDAsMCwwLDguNDgtOC40OFpNMzgsMTEyYTc0LDc0LDAsMSwxLDc0LDc0QTc0LjA5LDc0LjA5LDAsMCwxLDM4LDExMloiLz48L3N2Zz4=');}.icon-infinity{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yNDYsMTI4YTU0LDU0LDAsMCwxLTkyLjE4LDM4LjE4LDMuMDcsMy4wNywwLDAsMS0uMjUtLjI2bC02MC02Ny43NGE0Miw0MiwwLDEsMCwwLDU5LjY0bDguNTctOS42N2E2LDYsMCwxLDEsOSw4bC04LjY5LDkuODFhMy4wNywzLjA3LDAsMCwxLS4yNS4yNiw1NCw1NCwwLDEsMSwwLTc2LjM2LDMuMDcsMy4wNywwLDAsMSwuMjUuMjZsNjAsNjcuNzRhNDIsNDIsMCwxLDAsMC01OS42NGwtOC41Nyw5LjY3YTYsNiwwLDEsMS05LThsOC42OS05LjgxYTMuMDcsMy4wNywwLDAsMSwuMjUtLjI2QTU0LDU0LDAsMCwxLDI0NiwxMjhaIi8+PC9zdmc+');}.icon-arrow-counter-clockwise{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjIsMTI4YTk0LDk0LDAsMCwxLTkyLjc0LDk0SDEyOGE5My40Myw5My40MywwLDAsMS02NC41LTI1LjY1LDYsNiwwLDEsMSw4LjI0LTguNzJBODIsODIsMCwxLDAsNzAsNzBsLS4xOS4xOUwzOS40NCw5OEg3MmE2LDYsMCwwLDEsMCwxMkgyNGE2LDYsMCwwLDEtNi02VjU2YTYsNiwwLDAsMSwxMiwwVjkwLjM0TDYxLjYzLDYxLjRBOTQsOTQsMCwwLDEsMjIyLDEyOFoiLz48L3N2Zz4=');}.icon-clock{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMjgsMjZBMTAyLDEwMiwwLDEsMCwyMzAsMTI4LDEwMi4xMiwxMDIuMTIsMCwwLDAsMTI4LDI2Wm0wLDE5MmE5MCw5MCwwLDEsMSw5MC05MEE5MC4xLDkwLjEsMCwwLDEsMTI4LDIxOFptNjItOTBhNiw2LDAsMCwxLTYsNkgxMjhhNiw2LDAsMCwxLTYtNlY3MmE2LDYsMCwwLDEsMTIsMHY1MGg1MEE2LDYsMCwwLDEsMTkwLDEyOFoiLz48L3N2Zz4=');}.icon-house{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTcuOSwxMTAuMWwtODAtODBhMTQsMTQsMCwwLDAtMTkuOCwwbC04MCw4MEExMy45MiwxMy45MiwwLDAsMCwzNCwxMjB2OTZhNiw2LDAsMCwwLDYsNmg2NGE2LDYsMCwwLDAsNi02VjE1OGgzNnY1OGE2LDYsMCwwLDAsNiw2aDY0YTYsNiwwLDAsMCw2LTZWMTIwQTEzLjkyLDEzLjkyLDAsMCwwLDIxNy45LDExMC4xWk0yMTAsMjEwSDE1OFYxNTJhNiw2LDAsMCwwLTYtNkgxMDRhNiw2LDAsMCwwLTYsNnY1OEg0NlYxMjBhMiwyLDAsMCwxLC41OC0xLjQybDgwLTgwYTIsMiwwLDAsMSwyLjg0LDBsODAsODBBMiwyLDAsMCwxLDIxMCwxMjBaIi8+PC9zdmc+');}.icon-logo{--icon:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyAgICB3aWR0aD0iMzIiICAgIGhlaWdodD0iMzIiICAgIHZpZXdCb3g9IjAgMCAzMiAzMiIgICAgdmVyc2lvbj0iMS4xIiAgICB4bWw6c3BhY2U9InByZXNlcnZlIiAgICBzdHlsZT0iY2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVjYXA6c3F1YXJlO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxLjUiICAgIGlkPSJzdmcxNCIgICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiAgICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcyAgICBpZD0iZGVmczE0IiAvPjxwYXRoICAgIGQ9Ik0gMTYuNTgwMDc4LDIuMTMyODEyNSBDIDguODY0ODQ0OSwyLjEzMjgxMjUgMS40NDA2MDIxLDguMTQ2NjIxOCAyLjAzMzIwMzEsMTUuODM5ODQ0IDIuNTk0NDU4OCwyMy4xMjY2NjYgOC45NzEyMDEyLDI5LjAyNTE1NSAxNS45NzA3MDMsMjkuNzg3MTA5IDI0LjIyMTIyNCwzMC42ODUyNCAzMC40NDA5MTEsMjMuODM0Mjc3IDI5Ljk3NDYwOSwxNS43OTg4MjggMjkuNTI3ODEzLDguMDk5ODY1NSAyNC4yOTE1NiwyLjEzMjgxMjUgMTYuNTgwMDc4LDIuMTMyODEyNSBaIG0gMCwwLjYwNzQyMTkgYyAwLjAxMDQ2LDAgMC4wMjA4MywwIDAuMDMxMjUsMCBWIDI5LjIzMjQyMiBjIC0wLjE5MDMyMywtMC4wMTIxOCAtMC4zODE1MjEsLTAuMDI3ODMgLTAuNTc0MjE5LC0wLjA0ODgzIEMgOS4zMTMwNDUzLDI4LjQ1MTYxNSAzLjE3Nzg3NzUsMjIuNzkzMDQ0IDIuNjM4NjcxOSwxNS43OTI5NjkgMi4wNzI0NTYsOC40NDIwMTUzIDkuMjA4MTAwOCwyLjc0MDIzNDQgMTYuNTgwMDc4LDIuNzQwMjM0NCBaIE0gMTYuMDkxNzk3LDMuODg0NzY1NiAxNiwzLjg4ODY3MTkgQyAxMi43MjU0NTQsNC4wMTgzNDg5IDkuNTUyMzM3OSw1LjM2NDY4MzggNy4yNTU4NTk0LDcuNSA0Ljk1OTM4MDksOS42MzUzMTYyIDMuNTQwMjcwMywxMi41NjQ5NzIgMy43OTI5Njg4LDE1Ljg0NTcwMyA0LjI4NDc3MzksMjIuMjMwMDQ1IDkuODY0NDgxMiwyNy4zODM2MDYgMTUuOTk0MTQxLDI4LjA1MjczNCBsIDAuMDg5ODQsMC4wMDk4IDAuMDIxNDgsLTAuMTgxNjQxIC0wLjA5MTgsLTAuMDA5OCBDIDkuOTcyNjc0OSwyNy4yMTE2NDQgNC40NTg4NjkxLDIyLjExNjQ2OCAzLjk3NDYwOTQsMTUuODMwMDc4IDMuNzI2NTU1OSwxMi42MDk2NTEgNS4xMTU4MDg0LDkuNzM5MDQzNyA3LjM3ODkwNjIsNy42MzQ3NjU2IDkuNjQyMDA0MSw1LjUzMDQ4NzUgMTIuNzc4NTM5LDQuMTk4MTk2OCAxNi4wMDc4MTIsNC4wNzAzMTI1IGwgMC4wOTE4LC0wLjAwMzkxIHogbSAwLDEuNTAxOTUzMSBMIDE2LDUuMzkwNjI1IEMgMTMuMTMxOTQ5LDUuNTA0MjA0NyAxMC4zNTMyOTgsNi42ODQzNDE1IDguMzQxNzk2OSw4LjU1NDY4NzUgNi4zMzAyOTYyLDEwLjQyNTAzMyA1LjA4NzE5MjksMTIuOTkwODE5IDUuMzA4NTkzNywxNS44NjUyMzQgNS43MzkzOTQsMjEuNDU3NjY5IDEwLjYyNTE2MSwyNS45NzA1NDcgMTUuOTk0MTQxLDI2LjU1NjY0MSBsIDAuMDg5ODQsMC4wMDk4IDAuMDIxNDgsLTAuMTc5Njg3IC0wLjA5MTgsLTAuMDA5OCBDIDEwLjczMzM1NCwyNS44MDA1MzMgNS45MTM0ODkyLDIxLjM0NjA0NiA1LjQ5MDIzNDQsMTUuODUxNTYzIDUuMjczNDc4NCwxMy4wMzc0NTEgNi40ODY3MjM3LDEwLjUyNjgwOCA4LjQ2NDg0MzgsOC42ODc1IDEwLjQ0Mjk2NCw2Ljg0ODE5MjIgMTMuMTg1MDMyLDUuNjg0MDUyNiAxNi4wMDc4MTIsNS41NzIyNjU2IGwgMC4wOTE4LC0wLjAwMzkxIHogbSAwLDEuNTAzOTA2MyBMIDE2LDYuODkyNTc4MSBjIC0yLjQ2MTU3NywwLjA5NzQ4MyAtNC44NDU3MjgsMS4xMTE0MTc0IC02LjU3MjI2NTYsMi43MTY3OTY5IC0xLjcyNjUzOCwxLjYwNTM4IC0yLjc5NTU3NDEsMy44MDcyODIgLTIuNjA1NDY4OCw2LjI3NTM5MSAwLjM2OTc5ODYsNC44MDA1NCA0LjU2MzUzMzQsOC42NzQ2NzQgOS4xNzE4NzU0LDkuMTc3NzM0IGwgMC4wODk4NCwwLjAwOTggMC4wMjE0OCwtMC4xODE2NDEgLTAuMDkxOCwtMC4wMDk4IEMgMTEuNDk0MDM3LDI0LjM4NzQ4MSA3LjM2NjE1NTcsMjAuNTczNjM0IDcuMDAzOTA2MiwxNS44NzEwOTQgNi44MTg0NDgxLDEzLjQ2MzMyIDcuODU3NjQwNSwxMS4zMTY1MTMgOS41NTA3ODEzLDkuNzQyMTg3NSAxMS4yNDM5MjIsOC4xNjc4NjE4IDEzLjU5MTUyOSw3LjE3MTg2MDggMTYuMDA3ODEyLDcuMDc2MTcxOSBsIDAuMDkxOCwtMC4wMDM5MSB6IG0gMCwxLjUwMTk1MzEgTCAxNiw4LjM5NjQ4NDQgYyAtMi4wNTUwNzMsMC4wODEzODQgLTQuMDQ0Nzc1LDAuOTI1MjMzNCAtNS40ODYzMjgsMi4yNjU2MjQ2IC0xLjQ0MTU1MzUsMS4zNDAzOTMgLTIuMzM0NTg4MSwzLjE4MjM3OSAtMi4xNzU3ODE0LDUuMjQ0MTQxIDAuMzA4NzkyLDQuMDA4NTc5IDMuODA4NjA1NCw3LjI0MDEzNiA3LjY1NjI1MDQsNy42NjAxNTYgbCAwLjA4OTg0LDAuMDA5OCAwLjAwNzgsLTAuMDY4MzYgdiAtMC4wMDIgbCAwLjAwMiwtMC4wMDk4IGMgOS40OWUtNCwtMC4wMDM0IDAuMDAzNSwtMC4wMDYyIDAuMDAzOSwtMC4wMDk4IDYuNDJlLTQsLTAuMDA2NyA4LjAyZS00LC0wLjAxMzAxIDAsLTAuMDE5NTMgbCAwLjAwNzgsLTAuMDcyMjcgLTAuMDkxOCwtMC4wMDk4IEMgMTIuMjU0NjY3LDIyLjk3NDQyMiA4LjgyMDc3OTYsMTkuODAzMjMxIDguNTE5NTMxMywxNS44OTI1NzggOC4zNjUzNjgyLDEzLjg5MTEwNSA5LjIyODUzNzMsMTIuMTA2MjM3IDEwLjYzNjcxOSwxMC43OTY4NzUgMTIuMDQ0OSw5LjQ4NzUxMyAxMy45OTc5OTksOC42NTc3MTcgMTYuMDA3ODEyLDguNTc4MTI1IGwgMC4wOTE4LC0wLjAwMzkxIHogbSAwLDEuNTAxOTUzMiBMIDE2LDkuODk4NDM3NSBjIC0xLjY0ODU4OCwwLjA2NTI4NyAtMy4yNDU3NjEsMC43NDI5Mzg1IC00LjQwMjM0NCwxLjgxODM1OTUgLTEuMTU2NTgyLDEuMDc1NDIxIC0xLjg3MTY1MDYsMi41NTM1MzggLTEuNzQ0MTQwNCw0LjIwODk4NCAwLjI0Nzc4ODQsMy4yMTY2NjkgMy4wNTM2NDE0LDUuODA5NTAxIDYuMTQwNjI1NCw2LjE0NjQ4NSBsIDAuMDg5ODQsMC4wMDk4IDAuMDIxNDgsLTAuMTgxNjQgLTAuMDkxOCwtMC4wMDk4IGMgLTIuOTk4MzQ0LC0wLjMyNzMwOCAtNS43MzgyNzMsLTIuODU5Nzk4IC01Ljk3ODUxNiwtNS45Nzg1MTYgLTAuMTIyODY0NSwtMS41OTUxNDIgMC41NjQyOTgsLTMuMDE4MTE3IDEuNjg3NSwtNC4wNjI1IDEuMTIzMjAyLC0xLjA0NDM4MiAyLjY4MTgzOSwtMS43MDYwMzcgNC4yODUxNTYsLTEuNzY5NTMxIGwgMC4wOTE4LC0wLjAwMzkgeiBtIDAsMS41MDM5MDY3IC0wLjA5MTgsMC4wMDIgYyAtMS4yNDIwOTUsMC4wNDkxOSAtMi40NDQ4LDAuNTYwNjUyIC0zLjMxNjQwNiwxLjM3MTA5MyAtMC44NzE2MDYsMC44MTA0NDIgLTEuNDEyNjE5LDEuOTI0NzEzIC0xLjMxNjQwNiwzLjE3MzgyOSAwLjE4Njc4MywyLjQyNDczMiAyLjMwMDY0Myw0LjM3NjkxMyA0LjYyNjk1Myw0LjYzMDg1OSBsIDAuMDg5ODQsMC4wMDk4IDAuMDIxNDgsLTAuMTgxNjQgLTAuMDkxOCwtMC4wMDk4IGMgLTIuMjM3NjkyLC0wLjI0NDI3MiAtNC4yODU2MDQsLTIuMTM2MDgzIC00LjQ2NDg0NCwtNC40NjI4OSAtMC4wOTE1NywtMS4xODg4MjYgMC40MjE1MzIsLTIuMjQ3OTMzIDEuMjU5NzY2LC0zLjAyNzM0NCAwLjgzODIzNCwtMC43Nzk0MTEgMi4wMDIzODMsLTEuMjcyOTE2IDMuMTk5MjE4LC0xLjMyMDMxMyBsIDAuMDkxOCwtMC4wMDM5IHogbSAwLDEuNTAxOTUzIC0wLjA5MTgsMC4wMDM5IGMgLTAuODM1NjEzLDAuMDMzMDkgLTEuNjQzODMxLDAuMzc0NDUyIC0yLjIzMDQ2OSwwLjkxOTkyMiAtMC41ODY2MzcsMC41NDU0NyAtMC45NTE2MzYsMS4yOTk3NzggLTAuODg2NzE4LDIuMTQyNTc4IDAuMTI1NzgsMS42MzI4MjEgMS41NDU2NzMsMi45NDIzNyAzLjExMTMyOCwzLjExMzI4MSAtMC4wMDI2LC0yLjhlLTQgLTAuMDA1MywyLjg2ZS00IC0wLjAwNzgsMCAwLjAwMyw2LjAzZS00IDAuMDA2NiwwLjAwMTcgMC4wMDk4LDAuMDAyIDAuMDAzMSwzLjA4ZS00IDAuMDA2NywxLjJlLTUgMC4wMDk4LDAgbCAwLjA3ODEzLDAuMDA5OCAwLjAyMTQ4LC0wLjE4MTY0MSAtMC4wOTE4LC0wLjAwOTggYyAtMS40NzcwMTUsLTAuMTYxMjM1IC0yLjgzMDk4NCwtMS40MTIzOTYgLTIuOTQ5MjE5LC0yLjk0NzI2NiAtMC4wNjAyNywtMC43ODI0OTYgMC4yNzY4MjIsLTEuNDc5NzA5IDAuODMwMDc4LC0xLjk5NDE0MSAwLjU1MzI1NywtMC41MTQ0MzEgMS4zMjI5MzksLTAuODQxNzQ4IDIuMTEzMjgxLC0wLjg3MzA0NiBsIDAuMDkxOCwtMC4wMDM5IHogbSAwLDEuNTAxOTUzIEwgMTYsMTQuNDA2MjUgYyAtMC40MjkxMTcsMC4wMTY5OSAtMC44NDI4NzMsMC4xOTIxNjYgLTEuMTQ0NTMxLDAuNDcyNjU2IC0wLjMwMTY1OSwwLjI4MDQ5MSAtMC40OTA2NDgsMC42NzA5NTUgLTAuNDU3MDMxLDEuMTA3NDIyIDAuMDY0NzcsMC44NDA4ODYgMC43OTA3MjksMS41MTE3MzIgMS41OTU3MDMsMS41OTk2MDkgbCAwLjA4OTg0LDAuMDA5OCAwLjAyMTQ4LC0wLjE4MTY0MSAtMC4wOTE4LC0wLjAwOTggYyAtMC43MTYzNTcsLTAuMDc4MiAtMS4zNzYzNjIsLTAuNjg4NjgxIC0xLjQzMzU5NCwtMS40MzE2NDEgLTAuMDI4OTcsLTAuMzc2MTc5IDAuMTMyMTA1LC0wLjcxMTQ3NyAwLjQwMDM5MSwtMC45NjA5MzcgMC4yNjgyODYsLTAuMjQ5NDYxIDAuNjQzNDg1LC0wLjQwODYyNyAxLjAyNzM0MywtMC40MjM4MjggbCAwLjA5MTgsLTAuMDAzOSB6IiAgICBzdHlsZT0iYmFzZWxpbmUtc2hpZnQ6YmFzZWxpbmU7Y2xpcC1ydWxlOm5vbnplcm87ZGlzcGxheTppbmxpbmU7b3ZlcmZsb3c6dmlzaWJsZTt2ZWN0b3ItZWZmZWN0Om5vbmU7ZmlsbDojMjIyMjIyO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOm1pdGVyO2VuYWJsZS1iYWNrZ3JvdW5kOmFjY3VtdWxhdGU7c3RvcC1jb2xvcjojMDAwMDAwO3N0b3Atb3BhY2l0eToxIiAgICBpZD0icGF0aDI3IiAvPjwvc3ZnPg==');}.icon-jakevan{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHN0eWxlPSJjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsLXJ1bGU6ZXZlbm9kZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MiIgdmlld0JveD0iMCAwIDMyIDMyIj48cGF0aCBkPSJNMTcuODggMTQuNjhIMTIuOWwtLjQzLTEuNjNIOS41OGwtLjQ1IDEuNjNINi41bDIuODktOC43NGgzLjJsMi44OSA4LjY0di04LjZoMi40djMuNzhjLjEtLjIuMjItLjM4LjM1LS41Ny4xMy0uMi4yNi0uMzcuMzktLjU0bDEuODYtMi42N2g3Ljh2MS44OUgyNS40djEuMzdoMi42NXYxLjg4SDI1LjR2MS42NWgyLjg2djEuOTFoLTcuOTNsLTEuNzUtMy4zMi0uNy40MXptNS4xMy04LjU5LTIuNyAzLjc5IDIuNyA0Ljc0em0tMTEuMDUgNS4wMy0uMzgtMS40M2ExMzYuODYgMTM2Ljg2IDAgMCAwLS40LTEuNTVMMTEgNy4zOGExNy43NiAxNy43NiAwIDAgMS0uMzYgMS42bC0uMTguNzEtLjM5IDEuNDN6bS04LjU4IDYuM2E1Ljc0IDUuNzQgMCAwIDEtMS4yNC0uMTN2LTEuODNsLjQxLjA4Yy4xNS4wMy4zLjA1LjQ3LjA1LjMgMCAuNTEtLjA2LjY3LS4xN2EuOTIuOTIgMCAwIDAgLjM0LS41MmMuMDYtLjIzLjEtLjUyLjEtLjg2VjUuOThoMi40djcuODVjMCAuODgtLjEzIDEuNTctLjQgMi4xLS4yNi41Mi0uNjMuOS0xLjEgMS4xNC0uNDguMjMtMS4wMy4zNS0xLjY1LjM1WiIgc3R5bGU9ImZpbGw6Y3VycmVudENvbG9yO3N0cm9rZS13aWR0aDouMDE4NDM5MiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMS40IC42Nikgc2NhbGUoLjk2MDUwMTM0KSIvPjxwYXRoIGQ9Ik0yMi44MiAyMi4yN2gtNC4wNmwtLjM3LTEuNEgxNS45bC0uMzkgMS40aC0yLjI2bDIuNDktNy41M2gyLjc1bDIuNDkgNy40NHYtNy40MWgyLjdsMi43NyA1LjIxaC4wM2E0MS4xIDQxLjEgMCAwIDEtLjA3LTEuODJ2LTMuMzloMS44M3Y3LjVoLTIuN2wtMi43OS01LjI4aC0uMDRhMTIuODMgMTIuODMgMCAwIDEgLjA4IDEuMjZsLjAyLjY0em0tNC44Ni0zLjA3LS4zMy0xLjIzYTg5LjA3IDg5LjA3IDAgMCAwLS4zNS0xLjM0bC0uMTQtLjY1YTE1LjA0IDE1LjA0IDAgMCAxLS4zMSAxLjM3bC0uMTYuNjItLjMzIDEuMjN6bS0zLjg1LTQuNDMtMi41IDcuNUg5LjJsLTIuNS03LjVoMi4zMmwxLjA0IDMuOGExNS4wMyAxNS4wMyAwIDAgMSAuMzYgMS43NiA3LjYxIDcuNjEgMCAwIDEgLjItMS4ybC4xNC0uNTQgMS4wNi0zLjgyeiIgc3R5bGU9ImZpbGw6Y3VycmVudENvbG9yO3N0cm9rZS13aWR0aDouMDE1OTg4NCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMS40IC42Nikgc2NhbGUoLjk2MDUwMTM0KSIvPjxwYXRoIGQ9Ik0xMS45IDI0LjIxYzAgLjQtLjA3LjcyLS4yLjk5LS4xNS4yNi0uMzYuNDYtLjYzLjYtLjI4LjEzLS42Mi4yLTEuMDMuMkg5LjJ2LTMuNWguOTdjLjM4IDAgLjcuMDYuOTYuMTkuMjUuMTMuNDUuMzIuNTguNTguMTQuMjUuMi41Ny4yLjk0em0tLjI2LjAxYzAtLjMzLS4wNS0uNjEtLjE2LS44M2ExLjEgMS4xIDAgMCAwLS41MS0uNTEgMS45NSAxLjk1IDAgMCAwLS44Ny0uMTdoLS42NnYzLjA3aC42Yy41MyAwIC45My0uMTMgMS4yLS4zOS4yNy0uMjYuNC0uNjUuNC0xLjE3ek0xNC4yNyAyNmgtMS45NXYtMy41aDEuOTV2LjIyaC0xLjd2MS4zMmgxLjZ2LjIzaC0xLjZ2MS41aDEuN3ptMS4yOC0zLjVjLjI4IDAgLjUyLjAyLjcuMDhhLjguOCAwIDAgMSAuNDQuM2MuMS4xNC4xNC4zMy4xNC41N2EuOS45IDAgMCAxLS4xLjQ1Ljg3Ljg3IDAgMCAxLS4yNy4zMmMtLjEyLjA4LS4yNS4xNC0uNC4xOGwuOTggMS42aC0uM2wtLjkyLTEuNTNoLS44OVYyNmgtLjI1di0zLjV6bS0uMDMuMjFoLS41OXYxLjU1aC43MWMuMyAwIC41Mi0uMDcuNjktLjIxLjE2LS4xNC4yNC0uMzQuMjQtLjYgMC0uMjgtLjA5LS40Ny0uMjYtLjU4LS4xNy0uMS0uNDMtLjE2LS43OS0uMTZ6bTUuNTctLjIyTDIwLjEyIDI2aC0uMjVsLS43Ni0yLjY1LS4wNS0uMTYtLjA0LS4xNGExOC44IDE4LjggMCAwIDEtLjA2LS4yNCAyMC42IDIwLjYgMCAwIDEtLjExLjQ4TDE4LjA5IDI2aC0uMjVsLS45Ni0zLjVoLjI2bC42NyAyLjQ3YTI3LjM2IDI3LjM2IDAgMCAxIC4wOS4zNWwuMDQuMTcuMDMuMTUuMDMtLjE2YTQuODMgNC44MyAwIDAgMSAuMTQtLjUzbC43LTIuNDZoLjI1bC43MyAyLjQ4YTExLjk4IDExLjk4IDAgMCAxIC4xMy41M2wuMDQuMTVhMTEuMDIgMTEuMDIgMCAwIDEgLjE1LS42OGwuNjktMi40OHpNMjMuMjYgMjZoLTEuOTV2LTMuNWgxLjk1di4yMmgtMS43djEuMzJoMS42di4yM2gtMS42djEuNWgxLjd6bTEuMjgtMy41Yy4yOCAwIC41Mi4wMi43MS4wOGEuOC44IDAgMCAxIC40My4zYy4xLjE0LjE0LjMzLjE0LjU3YS45LjkgMCAwIDEtLjEuNDUuODcuODcgMCAwIDEtLjI3LjMyYy0uMTEuMDgtLjI1LjE0LS40LjE4bC45OCAxLjZoLS4zbC0uOTItMS41M2gtLjg4VjI2aC0uMjZ2LTMuNXptLS4wMi4yMWgtLjZ2MS41NWguNzJjLjI5IDAgLjUxLS4wNy42OC0uMjEuMTYtLjE0LjI0LS4zNC4yNC0uNiAwLS4yOC0uMDgtLjQ3LS4yNi0uNTgtLjE3LS4xLS40My0uMTYtLjc4LS4xNnpNMjYuNSAyNmgtLjI1di0zLjVoMS45NXYuMjJoLTEuN3YxLjQ5aDEuNnYuMjJoLTEuNnoiIHN0eWxlPSJmaWxsOmN1cnJlbnRDb2xvcjtzdHJva2Utd2lkdGg6LjAxMDEwNjgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEuNCAuNjYpIHNjYWxlKC45NjA1MDEzNCkiLz48L3N2Zz4=');}.icon-user-square{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDgsMzRINDhBMTQsMTQsMCwwLDAsMzQsNDhWMjA4YTE0LDE0LDAsMCwwLDE0LDE0SDIwOGExNCwxNCwwLDAsMCwxNC0xNFY0OEExNCwxNCwwLDAsMCwyMDgsMzRaTTk0LDEyMGEzNCwzNCwwLDEsMSwzNCwzNEEzNCwzNCwwLDAsMSw5NCwxMjBaTTY1Ljc3LDIxMGE2Ni40Myw2Ni40MywwLDAsMSwyMC43Ny0yOS4zNiw2Niw2NiwwLDAsMSw4Mi45MiwwQTY2LjQzLDY2LjQzLDAsMCwxLDE5MC4yMywyMTBaTTIxMCwyMDhhMiwyLDAsMCwxLTIsMmgtNS4xN2E3Ny44NSw3Ny44NSwwLDAsMC00OS4zOC01MS43MSw0Niw0NiwwLDEsMC01MC45LDBBNzcuODUsNzcuODUsMCwwLDAsNTMuMTcsMjEwSDQ4YTIsMiwwLDAsMS0yLTJWNDhhMiwyLDAsMCwxLDItMkgyMDhhMiwyLDAsMCwxLDIsMloiLz48L3N2Zz4=');}.icon-chat-teardrop{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMzIsMjZhOTguMTEsOTguMTEsMCwwLDAtOTgsOTh2ODRhMTQsMTQsMCwwLDAsMTQsMTRoODRhOTgsOTgsMCwwLDAsMC0xOTZabTAsMTg0SDQ4YTIsMiwwLDAsMS0yLTJWMTI0YTg2LDg2LDAsMSwxLDg2LDg2WiIvPjwvc3ZnPg==');}.icon-house-simple{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTcuOSwxMTAuMWwtODAtODBhMTQsMTQsMCwwLDAtMTkuOCwwbC04MCw4MEExMy45MiwxMy45MiwwLDAsMCwzNCwxMjB2OTZhNiw2LDAsMCwwLDYsNkgyMTZhNiw2LDAsMCwwLDYtNlYxMjBBMTMuOTIsMTMuOTIsMCwwLDAsMjE3LjksMTEwLjFaTTIxMCwyMTBINDZWMTIwYTIsMiwwLDAsMSwuNTgtMS40Mmw4MC04MGEyLDIsMCwwLDEsMi44NCwwbDgwLDgwQTIsMiwwLDAsMSwyMTAsMTIwWiIvPjwvc3ZnPg==');}.icon-caret-left{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjQuMjQsMjAzLjc2YTYsNiwwLDEsMS04LjQ4LDguNDhsLTgwLTgwYTYsNiwwLDAsMSwwLTguNDhsODAtODBhNiw2LDAsMCwxLDguNDgsOC40OEw4OC40OSwxMjhaIi8+PC9zdmc+');}.icon-chat{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTYsNTBINDBBMTQsMTQsMCwwLDAsMjYsNjRWMjI0YTEzLjg4LDEzLjg4LDAsMCwwLDguMDksMTIuNjlBMTQuMTEsMTQuMTEsMCwwLDAsNDAsMjM4YTEzLjg3LDEzLjg3LDAsMCwwLDktMy4zMWwuMDYtLjA1TDgyLjIzLDIwNkgyMTZhMTQsMTQsMCwwLDAsMTQtMTRWNjRBMTQsMTQsMCwwLDAsMjE2LDUwWm0yLDE0MmEyLDIsMCwwLDEtMiwySDgwYTYsNiwwLDAsMC0zLjkyLDEuNDZMNDEuMjYsMjI1LjUzQTIsMiwwLDAsMSwzOCwyMjRWNjRhMiwyLDAsMCwxLDItMkgyMTZhMiwyLDAsMCwxLDIsMloiLz48L3N2Zz4=');}.icon-envelope{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjQsNTBIMzJhNiw2LDAsMCwwLTYsNlYxOTJhMTQsMTQsMCwwLDAsMTQsMTRIMjE2YTE0LDE0LDAsMCwwLDE0LTE0VjU2QTYsNiwwLDAsMCwyMjQsNTBabS05Niw4NS44Nkw0Ny40Miw2MkgyMDguNThaTTEwMS42NywxMjgsMzgsMTg2LjM2VjY5LjY0Wm04Ljg4LDguMTRMMTI0LDE0OC40MmE2LDYsMCwwLDAsOC4xLDBsMTMuNC0xMi4yOEwyMDguNTgsMTk0SDQ3LjQzWk0xNTQuMzMsMTI4LDIxOCw2OS42NFYxODYuMzZaIi8+PC9zdmc+');}.icon-caret-right{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xODAuMjQsMTMyLjI0bC04MCw4MGE2LDYsMCwwLDEtOC40OC04LjQ4TDE2Ny41MSwxMjgsOTEuNzYsNTIuMjRhNiw2LDAsMCwxLDguNDgtOC40OGw4MCw4MEE2LDYsMCwwLDEsMTgwLjI0LDEzMi4yNFoiLz48L3N2Zz4=');}.icon-calendar{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDgsMzRIMTgyVjI0YTYsNiwwLDAsMC0xMiwwVjM0SDg2VjI0YTYsNiwwLDAsMC0xMiwwVjM0SDQ4QTE0LDE0LDAsMCwwLDM0LDQ4VjIwOGExNCwxNCwwLDAsMCwxNCwxNEgyMDhhMTQsMTQsMCwwLDAsMTQtMTRWNDhBMTQsMTQsMCwwLDAsMjA4LDM0Wk00OCw0Nkg3NFY1NmE2LDYsMCwwLDAsMTIsMFY0Nmg4NFY1NmE2LDYsMCwwLDAsMTIsMFY0NmgyNmEyLDIsMCwwLDEsMiwyVjgySDQ2VjQ4QTIsMiwwLDAsMSw0OCw0NlpNMjA4LDIxMEg0OGEyLDIsMCwwLDEtMi0yVjk0SDIxMFYyMDhBMiwyLDAsMCwxLDIwOCwyMTBabS05OC05MHY2NGE2LDYsMCwwLDEtMTIsMFYxMjkuNzFsLTcuMzIsMy42NmE2LDYsMCwxLDEtNS4zNi0xMC43NGwxNi04QTYsNiwwLDAsMSwxMTAsMTIwWm01OS41NywyOS4yNUwxNDgsMTc4aDIwYTYsNiwwLDAsMSwwLDEySDEzNmE2LDYsMCwwLDEtNC44LTkuNkwxNjAsMTQyYTEwLDEwLDAsMSwwLTE2LjY1LTExQTYsNiwwLDEsMSwxMzMsMTI1YTIyLDIyLDAsMSwxLDM2LjYyLDI0LjI2WiIvPjwvc3ZnPg==');}.icon-shuffle{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzYuMjQsMTc5Ljc2YTYsNiwwLDAsMSwwLDguNDhsLTI0LDI0YTYsNiwwLDAsMS04LjQ4LTguNDhMMjE3LjUyLDE5MEgyMDAuOTRhNzAuMTYsNzAuMTYsMCwwLDEtNTctMjkuMzFsLTQxLjcxLTU4LjRBNTguMTEsNTguMTEsMCwwLDAsNTUuMDYsNzhIMzJhNiw2LDAsMCwxLDAtMTJINTUuMDZhNzAuMTYsNzAuMTYsMCwwLDEsNTcsMjkuMzFsNDEuNzEsNTguNEE1OC4xMSw1OC4xMSwwLDAsMCwyMDAuOTQsMTc4aDE2LjU4bC0xMy43Ni0xMy43NmE2LDYsMCwwLDEsOC40OC04LjQ4Wm0tOTIuMDYtNzQuNDFhNS45MSw1LjkxLDAsMCwwLDMuNDgsMS4xMiw2LDYsMCwwLDAsNC44OS0yLjUxbDEuMTktMS42N0E1OC4xMSw1OC4xMSwwLDAsMSwyMDAuOTQsNzhoMTYuNThMMjAzLjc2LDkxLjc2YTYsNiwwLDEsMCw4LjQ4LDguNDhsMjQtMjRhNiw2LDAsMCwwLDAtOC40OGwtMjQtMjRhNiw2LDAsMCwwLTguNDgsOC40OEwyMTcuNTIsNjZIMjAwLjk0YTcwLjE2LDcwLjE2LDAsMCwwLTU3LDI5LjMxTDE0Mi43OCw5N0E2LDYsMCwwLDAsMTQ0LjE4LDEwNS4zNVptLTMyLjM2LDQ1LjNhNiw2LDAsMCwwLTguMzcsMS4zOWwtMS4xOSwxLjY3QTU4LjExLDU4LjExLDAsMCwxLDU1LjA2LDE3OEgzMmE2LDYsMCwwLDAsMCwxMkg1NS4wNmE3MC4xNiw3MC4xNiwwLDAsMCw1Ny0yOS4zMWwxLjE5LTEuNjdBNiw2LDAsMCwwLDExMS44MiwxNTAuNjVaIi8+PC9zdmc+');}.icon-sort-descending{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik00MiwxMjhhNiw2LDAsMCwxLDYtNmg3MmE2LDYsMCwwLDEsMCwxMkg0OEE2LDYsMCwwLDEsNDIsMTI4Wm02LTU4aDU2YTYsNiwwLDAsMCwwLTEySDQ4YTYsNiwwLDAsMCwwLDEyWk0xODQsMTg2SDQ4YTYsNiwwLDAsMCwwLDEySDE4NGE2LDYsMCwwLDAsMC0xMlpNMjI4LjI0LDgzLjc2bC00MC00MGE2LDYsMCwwLDAtOC40OCwwbC00MCw0MGE2LDYsMCwwLDAsOC40OCw4LjQ4TDE3OCw2Mi40OVYxNDRhNiw2LDAsMCwwLDEyLDBWNjIuNDlsMjkuNzYsMjkuNzVhNiw2LDAsMCwwLDguNDgtOC40OFoiLz48L3N2Zz4=');}.icon-sort-ascending{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMjYsMTI4YTYsNiwwLDAsMS02LDZINDhhNiw2LDAsMCwxLDAtMTJoNzJBNiw2LDAsMCwxLDEyNiwxMjhaTTQ4LDcwSDE4NGE2LDYsMCwwLDAsMC0xMkg0OGE2LDYsMCwwLDAsMCwxMlptNTYsMTE2SDQ4YTYsNiwwLDAsMCwwLDEyaDU2YTYsNiwwLDAsMCwwLTEyWm0xMjQuMjQtMjIuMjRhNiw2LDAsMCwwLTguNDgsMEwxOTAsMTkzLjUxVjExMmE2LDYsMCwwLDAtMTIsMHY4MS41MWwtMjkuNzYtMjkuNzVhNiw2LDAsMCwwLTguNDgsOC40OGw0MCw0MGE2LDYsMCwwLDAsOC40OCwwbDQwLTQwQTYsNiwwLDAsMCwyMjguMjQsMTYzLjc2WiIvPjwvc3ZnPg==');}.icon-arrow-elbow-left-down{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzgsNzJhNiw2LDAsMCwxLTYsNkg5NFYyMDEuNTFsMzcuNzYtMzcuNzVhNiw2LDAsMCwxLDguNDgsOC40OGwtNDgsNDhhNiw2LDAsMCwxLTguNDgsMGwtNDgtNDhhNiw2LDAsMCwxLDguNDgtOC40OEw4MiwyMDEuNTFWNzJhNiw2LDAsMCwxLDYtNkgyMzJBNiw2LDAsMCwxLDIzOCw3MloiLz48L3N2Zz4=');}.icon-arrow-elbow-right-down{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjguMjQsMTY0LjI0bC00OCw0OGE2LDYsMCwwLDEtOC40OCwwbC00OC00OGE2LDYsMCwxLDEsOC40OC04LjQ4TDE3MCwxOTMuNTFWNzBIMzJhNiw2LDAsMCwxLDAtMTJIMTc2YTYsNiwwLDAsMSw2LDZWMTkzLjUxbDM3Ljc2LTM3Ljc1YTYsNiwwLDAsMSw4LjQ4LDguNDhaIi8+PC9zdmc+');}.icon-heart{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNzgsNDJjLTIxLDAtMzkuMjYsOS40Ny01MCwyNS4zNEMxMTcuMjYsNTEuNDcsOTksNDIsNzgsNDJhNjAuMDcsNjAuMDcsMCwwLDAtNjAsNjBjMCwyOS4yLDE4LjIsNTkuNTksNTQuMSw5MC4zMWEzMzQuNjgsMzM0LjY4LDAsMCwwLDUzLjA2LDM3LDYsNiwwLDAsMCw1LjY4LDAsMzM0LjY4LDMzNC42OCwwLDAsMCw1My4wNi0zN0MyMTkuOCwxNjEuNTksMjM4LDEzMS4yLDIzOCwxMDJBNjAuMDcsNjAuMDcsMCwwLDAsMTc4LDQyWk0xMjgsMjE3LjExQzExMS41OSwyMDcuNjQsMzAsMTU3LjcyLDMwLDEwMkE0OC4wNSw0OC4wNSwwLDAsMSw3OCw1NGMyMC4yOCwwLDM3LjMxLDEwLjgzLDQ0LjQ1LDI4LjI3YTYsNiwwLDAsMCwxMS4xLDBDMTQwLjY5LDY0LjgzLDE1Ny43Miw1NCwxNzgsNTRhNDguMDUsNDguMDUsMCwwLDEsNDgsNDhDMjI2LDE1Ny43MiwxNDQuNDEsMjA3LjY0LDEyOCwyMTcuMTFaIi8+PC9zdmc+');}.icon-dots-three{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMzgsMTI4YTEwLDEwLDAsMSwxLTEwLTEwQTEwLDEwLDAsMCwxLDEzOCwxMjhaTTYwLDExOGExMCwxMCwwLDEsMCwxMCwxMEExMCwxMCwwLDAsMCw2MCwxMThabTEzNiwwYTEwLDEwLDAsMSwwLDEwLDEwQTEwLDEwLDAsMCwwLDE5NiwxMThaIi8+PC9zdmc+');}.icon-logo-jakevan{--icon:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyAgICB3aWR0aD0iMzIiICAgIGhlaWdodD0iMzIiICAgIHZpZXdCb3g9IjAgMCAzMiAzMiIgICAgdmVyc2lvbj0iMS4xIiAgICB4bWw6c3BhY2U9InByZXNlcnZlIiAgICBzdHlsZT0iY2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVjYXA6c3F1YXJlO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxLjUiICAgIGlkPSJzdmcxNCIgICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiAgICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcyAgICBpZD0iZGVmczE0IiAvPjxwYXRoICAgIGQ9Ik0gMTYuNTgwMDc4LDIuMTMyODEyNSBDIDguODY0ODQ1LDIuMTMyODEyNSAxLjQ0MDYwMjEsOC4xNDY2MjE2IDIuMDMzMjAzMSwxNS44Mzk4NDQgMi41OTQ0NTg4LDIzLjEyNjY2NiA4Ljk3MTIwMTMsMjkuMDI1MTU1IDE1Ljk3MDcwMywyOS43ODcxMDkgMjQuMjIxMjI0LDMwLjY4NTI0IDMwLjQ0MDkxMSwyMy44MzQyNzcgMjkuOTc0NjA5LDE1Ljc5ODgyOCAyOS41Mjc4MTMsOC4wOTk4NjU2IDI0LjI5MTU2LDIuMTMyODEyNSAxNi41ODAwNzgsMi4xMzI4MTI1IFogbSAwLDAuNjA3NDIxOSBoIDAuMDMxMjUgViAyOS4yMzI0MjIgYyAtMC4xOTAzMjMsLTAuMDEyMTggLTAuMzgxNTIxLC0wLjAyNzgzIC0wLjU3NDIxOSwtMC4wNDg4MyBDIDkuMzEzMDQ1NywyOC40NTE2MTcgMy4xNzc4Nzc1LDIyLjc5MzA0NCAyLjYzODY3MTksMTUuNzkyOTY5IDIuMDcyNDU2LDguNDQyMDE1IDkuMjA4MTAwOSwyLjc0MDIzNDQgMTYuNTgwMDc4LDIuNzQwMjM0NCBaIG0gLTAuNDkyMTg3LDEuMTQ0NTMxMiAtMC4wOTE4LDAuMDAzOTEgQyAxMi43MjE1Niw0LjAxODM0MTMgOS41NDY0NzQzLDUuMzY0Njg3NyA3LjI1LDcuNSA0Ljk1MzUyNTcsOS42MzUzMTIzIDMuNTM2MzY0NywxMi41NjQ5OCAzLjc4OTA2MjUsMTUuODQ1NzAzIDQuMjgwODY2OCwyMi4yMzAwMzIgOS44NjA1ODc5LDI3LjM4MzYwOCAxNS45OTAyMzQsMjguMDUyNzM0IGwgMC4wODk4NCwwLjAwOTggMC4wMTk1MywtMC4xODE2NDEgLTAuMDg5ODQsLTAuMDA5OCBDIDkuOTY4NzM4OSwyNy4yMTE2NDMgNC40NTQ5NjM4LDIyLjExNjQ4MSAzLjk3MDcwMzEsMTUuODMwMDc4IDMuNzIyNjQ5MSwxMi42MDk2NDQgNS4xMTE4OTc5LDkuNzM5MDQ3NyA3LjM3NSw3LjYzNDc2NTYgOS42MzgxMDIxLDUuNTMwNDgzNiAxMi43NzQ2MjUsNC4xOTgxOTcgMTYuMDAzOTA2LDQuMDcwMzEyNSBsIDAuMDg5ODQsLTAuMDAzOTEgeiBtIDAsMS41MDE5NTMxIC0wLjA5MTgsMC4wMDM5MSBDIDEzLjEyODA1NCw1LjUwNDE5NzEgMTAuMzQ3NDM0LDYuNjg0MzQ1NCA4LjMzNTkzNzUsOC41NTQ2ODc1IDYuMzI0NDQxMSwxMC40MjUwMyA1LjA4MTMzNDEsMTIuOTkwODI3IDUuMzAyNzM0NCwxNS44NjUyMzQgNS43MzM1MzM2LDIxLjQ1NzY1NiAxMC42MjEyNjUsMjUuOTcwNTQ4IDE1Ljk5MDIzNCwyNi41NTY2NDEgbCAwLjA4OTg0LDAuMDA5OCAwLjAxOTUzLC0wLjE3OTY4NyAtMC4wODk4NCwtMC4wMDk4IEMgMTAuNzI5NDE5LDI1LjgwMDUzMiA1LjkwNzYzMDcsMjEuMzQ2MDU2IDUuNDg0Mzc1LDE1Ljg1MTU2MyA1LjI2NzYxODQsMTMuMDM3NDQyIDYuNDgyODEzMywxMC41MjY4MTIgOC40NjA5Mzc1LDguNjg3NSAxMC40MzkwNjIsNi44NDgxODgzIDEzLjE4MTEyLDUuNjg0MDUyOCAxNi4wMDM5MDYsNS41NzIyNjU2IGwgMC4wODk4NCwtMC4wMDM5MSB6IG0gMCwxLjUwMzkwNjMgLTAuMDkxOCwwLjAwMTk1IEMgMTMuNTM0NTQsNi45OTAwNjYzIDExLjE0ODQsOC4wMDQwMDcyIDkuNDIxODc1LDkuNjA5Mzc1IDcuNjk1MzQ5NywxMS4yMTQ3NDMgNi42MjgyNTU4LDEzLjQxNjY4IDYuODE4MzU5NCwxNS44ODQ3NjYgNy4xODgxNTUxLDIwLjY4NTI2OSAxMS4zODE5NiwyNC41NTk0NDQgMTUuOTkwMjM0LDI1LjA2MjUgbCAwLjA4OTg0LDAuMDA5OCAwLjAxOTUzLC0wLjE4MTY0MSAtMC4wODk4NCwtMC4wMDk4IEMgMTEuNDkwMTE0LDI0LjM4NzQ3NyA3LjM2MjI1MjIsMjAuNTczNjcxIDcsMTUuODcxMDk0IDYuODE0NTQwMSwxMy40NjMyOTcgNy44NTM3MjE5LDExLjMxNjUyNSA5LjU0Njg3NSw5Ljc0MjE4NzUgYyAxLjY5MzE1MywtMS41NzQzMzc0IDQuMDQwNzMsLTIuNTcwMzI2IDYuNDU3MDMxLC0yLjY2NjAxNTYgbCAwLjA4OTg0LC0wLjAwMzkxIHogbSAwLDEuNTAxOTUzMSAtMC4wOTE4LDAuMDAzOTEgYyAtMi4wNTUwNzMsMC4wODEzODQgLTQuMDQ2NzI4LDAuOTI1MjMzMSAtNS40ODgyODEsMi4yNjU2MjQ5IC0xLjQ0MTU1NDcsMS4zNDAzOTMgLTIuMzMyNjM1NCwzLjE4MjM3OSAtMi4xNzM4Mjg2LDUuMjQ0MTQxIDAuMzA2Mzk5NCwzLjk3NzUyIDMuNzU3OTY0Niw3LjE3NDg3NyA3LjU3MDMxMjYsNy42MzQ3NjYgbCAtMC4wMDIsMC4wMTc1OCAwLjA4Nzg5LDAuMDA3OCBoIDAuMDAyIGwgMC4wMDk4LDAuMDAyIDAuMDgwMDgsMC4wMDk4IDAuMDIxNDgsLTAuMTgxNjQxIGggLTAuMDAzOSB2IC0wLjAwMiBsIC0wLjA4OTg0LC0wLjAwOTggaCAtMC4wMDIgQyAxMi4yNDk0NzYsMjIuOTczNTY1IDguODE2ODE1NSwxOS44MDI1NzYgOC41MTU2MTcsMTUuODkyNTcxIDguMzYxNDU0LDEzLjg5MTA5OCA5LjIyNDYyMjUsMTIuMTA2MjMgMTAuNjMyODA1LDEwLjc5Njg2OCAxMi4wNDA5ODUsOS40ODc1MDU0IDEzLjk5NDA4NCw4LjY1NzcwOTcgMTYuMDAzODk4LDguNTc4MTE3NyBsIDAuMDg5ODQsLTAuMDAzOTEgeiBtIDAsMS41MDE5NTMyIC0wLjA5MTgsMC4wMDM5MSBjIC0xLjY0ODU4MiwwLjA2NTI4NyAtMy4yNDU3NjYsMC43NDI5NDI3IC00LjQwMjM0NCwxLjgxODM1OTcgLTEuMTU2NTc4LDEuMDc1NDE3IC0xLjg3MTY1MDMsMi41NTM1NDUgLTEuNzQ0MTQwNiw0LjIwODk4NCAwLjI0NTM5NDYsMy4xODU1OSAzLjAwMzEwMzYsNS43NDQzODEgNi4wNTQ2ODc2LDYuMTIxMDk0IGwgLTAuMDAyLDAuMDE3NTggMC4wODc4OSwwLjAwNzggaCAwLjAwMiBsIDAuMDg3ODksMC4wMDk4IGggMC4wMDIgbCAwLjAyMTQ4LC0wLjE4MTY0IGggLTAuMDAzOSBsIC0wLjA4Nzg5LC0wLjAwOTggaCAtMC4wMDIgLTAuMDAyIGMgLTIuOTk3NjIzLC0wLjMyODE1NiAtNS43MzYzNjgsLTIuODYwNDMzIC01Ljk3NjU2MiwtNS45Nzg1MTYgLTAuMTIyODY1OSwtMS41OTUxNSAwLjU2NDI5NCwtMy4wMTgxMTMgMS42ODc1LC00LjA2MjUgMS4xMjMyMDYsLTEuMDQ0Mzg2IDIuNjgxODMzLC0xLjcwNjAzNyA0LjI4NTE1NiwtMS43Njk1MzEgbCAwLjA4OTg0LC0wLjAwMzkgeiBtIDQuMTIxMDkzLDEuMzIwMzEyNyBoIDEuNDY2Nzk3IGwgMS4zMjgxMjUsMy45NjI4OSB2IC0zLjk0NzI2NSBoIDEuMTAzNTE2IHYgMS43MzYzMjggYyAwLjA0NjM5LC0wLjA4NzQyIDAuMDk5ODksLTAuMTc2MjEyIDAuMTYwMTU2LC0wLjI2MzY3MiAwLjA2MDMxLC0wLjA4NzQ2IDAuMTIwMjk0LC0wLjE2OTY4NyAwLjE3NzczNCwtMC4yNDgwNDcgbCAwLjg1MzUxNiwtMS4yMjQ2MDkgaCAzLjU3ODEyNSB2IDAuODY3MTg3IGggLTEuMzE2NDA2IHYgMC42MjY5NTMgaCAxLjIxODc1IHYgMC44NjcxODggaCAtMS4yMTg3NSB2IDAuNzUzOTA2IGggMS4zMTY0MDYgdiAwLjg4MDg2IGggLTMuNjM4NjcyIGwgLTAuODA0Njg3LC0xLjUyNzM0NCAtMC4zMjYxNzIsMC4xOTE0MDYgdiAxLjMzNTkzOCBoIC0yLjI4OTA2MyBsIC0wLjIwMTE3MiwtMC43NDgwNDcgaCAtMS4zMjAzMTIgbCAtMC4yMDcwMzEsMC43NDgwNDcgaCAtMS4yMDcwMzIgeiBtIC0yLjQxNDA2MiwwLjAxNTYzIGggMS4xMDM1MTUgdiAzLjYwNTQ2OSBjIDEwZS03LDAuNDAwOTA1IC0wLjA2MTE3LDAuNzIyMzU1IC0wLjE4MzU5MywwLjk2Mjg5IC0wLjEyMjQyMiwwLjI0MDUzNSAtMC4yOTA4MTMsMC40MTQwMTEgLTAuNTA3ODEzLDAuNTIxNDg0IC0wLjIxNjk5OSwwLjEwNzUxMyAtMC40NjgyNTUsMC4xNjAxNTcgLTAuNzUzOTA2LDAuMTYwMTU3IC0wLjEyNDI1NiwwIC0wLjIzNDQ2NSwtMC4wMDU3IC0wLjMyODEyNSwtMC4wMTc1OCAtMC4wOTM2NiwtMC4wMTE3NyAtMC4xNzM1NzgsLTAuMDI0NDYgLTAuMjQyMTg4LC0wLjAzOTA2IFYgMTUuNTgzOTkgYyAwLjA1OTM2LDAuMDEwODYgMC4xMjI2NzQsMC4wMjM0MSAwLjE4OTQ1NCwwLjAzNzExIDAuMDY2NzcsMC4wMTM3IDAuMTM4OTM2LDAuMDIxNDggMC4yMTY3OTYsMC4wMjE0OCAwLjEzMTY3NiwwIDAuMjMzMzYxLC0wLjAyNzIzIDAuMzA2NjQxLC0wLjA4MDA4IDAuMDczMjMsLTAuMDUyODYgMC4xMjQ2MTcsLTAuMTMyNjExIDAuMTU0Mjk3LC0wLjIzODI4MSAwLjAyOTY4LC0wLjEwNTY3IDAuMDQ0OTIsLTAuMjM3OTE5IDAuMDQ0OTIsLTAuMzk2NDg1IHogbSA4LjY2Nzk2OSwwLjA1NDY5IC0xLjI0NDE0MSwxLjczNjMyOCAxLjI0NDE0MSwyLjE3NTc4MiB6IG0gLTEwLjM3NSwwLjExMzI4MiAtMC4wOTE4LDAuMDAyIGMgLTEuMjQyMDk1LDAuMDQ5MTkgLTIuNDQ0OCwwLjU2MDY1MiAtMy4zMTY0MDYsMS4zNzEwOTMgLTAuODcxNjA4LDAuODEwNDQyIC0xLjQxMjYyLDEuOTI0NzEyIC0xLjMxNjQwNywzLjE3MzgyOSAwLjE4NDM5LDIuMzkzNjU0IDIuMjUwMTk1LDQuMzEyMDIyIDQuNTQxMDE2LDQuNjA1NDY4IGwgLTAuMDAyLDAuMDE3NTggMC4wODc4OSwwLjAwNzggaCAwLjAwMiBsIDAuMDg3ODksMC4wMDk4IGggMC4wMDIgbCAwLjAxOTUzLC0wLjE3OTY4NyBoIC0wLjAwMiB2IC0wLjAwMiBsIC0wLjA3ODEzLC0wLjAwNzggLTAuMDA5OCwtMC4wMDIgaCAtMC4wMDIgLTAuMDAyIGMgLTIuMjM2OTYxLC0wLjI0NTEyMSAtNC4yODM3LC0yLjEzNjczMSAtNC40NjI4OSwtNC40NjI4OSAtMC4wOTE1NywtMS4xODg4MjYgMC40MjE1MzEsLTIuMjQ3OTMzIDEuMjU5NzY2LC0zLjAyNzM0NCAwLjgzODIzNCwtMC43Nzk0MTEgMi4wMDIzODIsLTEuMjcyOTE2IDMuMTk5MjE4LC0xLjMyMDMxMyBsIDAuMDg5ODQsLTAuMDAzOSB6IG0gNC44NjEzMjgsMC40NzQ2MDkgYyAtMC4wMTY3MSwwLjA5MTExIC0wLjAzOTcyLDAuMjAzOTI4IC0wLjA3MDMxLDAuMzM3ODkxIC0wLjAzMDYsMC4xMzM5MjIgLTAuMDYxMjgsMC4yNjUyNjkgLTAuMDkzNzUsMC4zOTY0ODQgLTAuMDMyNDIsMC4xMzExNzUgLTAuMDYxODUsMC4yNDA2NjUgLTAuMDg1OTQsMC4zMjgxMjUgbCAtMC4xNzU3ODIsMC42NTYyNSBoIDAuODY1MjM1IGwgLTAuMTczODI4LC0wLjY1NjI1IGMgLTAuMDE4NTEsLTAuMDcxMDYgLTAuMDQ2ODEsLTAuMTcyNTI5IC0wLjA4MjAzLC0wLjMwNDY4OCAtMC4wMzUyNiwtMC4xMzIxMTggLTAuMDY5MjEsLTAuMjY4OTM1IC0wLjEwMzUxNSwtMC40MTAxNTYgLTAuMDM0MywtMC4xNDEyMjEgLTAuMDYxNTMsLTAuMjU2NTQ2IC0wLjA4MDA4LC0wLjM0NzY1NiB6IG0gLTQuODYxMzI4LDEuMDI3MzQ0IC0wLjA5MTgsMC4wMDM5IGMgLTAuODM1NjA4LDAuMDMzMDkgLTEuNjQzODM2LDAuMzc0NDU2IC0yLjIzMDQ2OSwwLjkxOTkyMiAtMC41ODY2MzMsMC41NDU0NjYgLTAuOTUxNjM1LDEuMjk5Nzg2IC0wLjg4NjcxOSwyLjE0MjU3OCAwLjEyMzIwNSwxLjU5OTM3OCAxLjQ5ODEyOCwyLjg1OTQ2NyAzLjAyNTM5MSwzLjA3MjI2NSBsIC0wLjAwMzksMC4wMzMyIDAuMDg5ODQsMC4wMDk4IDAuMDgyMDMsMC4wMDc4IDAuMDA3OCwwLjAwMiBoIDAuMDAyIGwgMC4wMTk1MywtMC4xODE2NDEgaCAtMC4wMDIgbCAtMC4wODc4OSwtMC4wMDk4IGggLTAuMDAyIC0wLjAwMiBjIC0xLjQ3NjMzNywtMC4xNjIwNDEgLTIuODI5MDc2LC0xLjQxMjk5NiAtMi45NDcyNjUsLTIuOTQ3MjY2IC0wLjA2MDI3LC0wLjc4MjUwMyAwLjI3NjgxNywtMS40Nzk3MDUgMC44MzAwNzgsLTEuOTk0MTQxIDAuNTUzMjYxLC0wLjUxNDQzNSAxLjMyMjkzMywtMC44NDE3NDggMi4xMTMyODEsLTAuODczMDQ2IGwgMC4wODk4NCwtMC4wMDM5IHogbSAwLDEuNTAxOTUzIC0wLjA5MTgsMC4wMDM5IGMgLTAuNDI5MTE4LDAuMDE2OTkgLTAuODQyODczLDAuMTkyMTY2IC0xLjE0NDUzMSwwLjQ3MjY1NiAtMC4zMDE2NiwwLjI4MDQ5MSAtMC40OTA2NDgsMC42NzA5NTUgLTAuNDU3MDMyLDEuMTA3NDIyIDAuMDYyMTksMC44MDczNiAwLjc0MzgwMSwxLjQzMDI1NyAxLjUwOTc2NiwxLjU1ODU5NCBsIC0wLjAwMzksMC4wMzMyIDAuMDg5ODQsMC4wMDc4IGggMC4wMDIgbCAwLjA4Nzg5LDAuMDA5OCAwLjAyMTQ4LC0wLjE3OTY4NyBoIC0wLjAwMiB2IC0wLjAwMiBsIC0wLjA3ODEzLC0wLjAwNzggLTAuMDA5OCwtMC4wMDIgaCAtMC4wMDIgLTAuMDAyIGMgLTAuNzE1Njc1LC0wLjA3OTAxIC0xLjM3NDQ1NSwtMC42ODkyOSAtMS40MzE2NCwtMS40MzE2NDEgLTAuMDI4OTcsLTAuMzc2MTc5IDAuMTMyMTA0LC0wLjcxMTQ3NyAwLjQwMDM5MSwtMC45NjA5MzcgMC4yNjgyODYsLTAuMjQ5NDYxIDAuNjQzNDg1LC0wLjQwODYyNyAxLjAyNzM0MywtMC40MjM4MjggbCAwLjA4OTg0LC0wLjAwMzkgeiBtIDcuMDQxMDE1LDAuODQ5NjA5IGggMS4yNjE3MTkgbCAxLjE0MjU3OCwzLjQxNDA2MyB2IC0zLjQwMDM5MSBoIDEuMjM2MzI4IGwgMS4yNzUzOTEsMi4zOTI1NzggaCAwLjAxMzY3IGMgLTAuMDA0NywtMC4wNzUzNyAtMC4wMDg5LC0wLjE2NDAzMiAtMC4wMTM2NywtMC4yNjM2NzIgLTAuMDA0OCwtMC4wOTk2NCAtMC4wMDk3LC0wLjIwMDcxMyAtMC4wMTM2NywtMC4zMDI3MzQgLTAuMDA0LC0wLjEwMjAyIC0wLjAwNTksLTAuMTkxMDUxIC0wLjAwNTksLTAuMjY5NTMxIHYgLTEuNTU2NjQxIGggMC44NDM3NSB2IDMuNDQxNDA2IGggLTEuMjQyMTg4IGwgLTEuMjc5Mjk3LC0yLjQyMzgyOCBoIC0wLjAyMTQ4IGMgMC4wMDgsMC4wNzM3NyAwLjAxNTA4LDAuMTYyMDg4IDAuMDIxNDgsMC4yNjU2MjUgMC4wMDY0LDAuMTAzNTc5IDAuMDEyODgsMC4yMDg4OTEgMC4wMTc1OCwwLjMxNjQwNiAwLjAwNDgsMC4xMDc0NzQgMC4wMDc4LDAuMjA0NzA2IDAuMDA3OCwwLjI5MTAxNiB2IDEuNTUwNzgxIEggMjQuNTEzNjcyIEwgMjQuMzM5ODQ0LDE4LjA2MjUgaCAtMS4xMzY3MTkgbCAtMC4xNzc3MzQsMC42NDQ1MzEgaCAtMS4wMzkwNjMgeiBtIC00LjE1NDI5NywwLjAxMzY3IGggMS4wNjI1IGwgMC40NzY1NjMsMS43NDQxNDEgYyAwLjAxNzU0LDAuMDY1ODkgMC4wMzkzNywwLjE1MTEwNyAwLjA2MjUsMC4yNTM5MDYgMC4wMjMxNywwLjEwMjc1OCAwLjA0NDQ4LDAuMjA0NjYxIDAuMDY0NDUsMC4zMDY2NCAwLjAxOTk3LDAuMTAyMDIgMC4wMzIzMSwwLjE4NTYyIDAuMDM3MTEsMC4yNSAwLjAwNjQsLTAuMDY0MzggMC4wMTc2MSwtMC4xNDc2MjUgMC4wMzUxNiwtMC4yNDgwNDYgMC4wMTc1OSwtMC4xMDA0MjEgMC4wMzcwNCwtMC4yMDE1MzUgMC4wNTg1OSwtMC4zMDI3MzUgMC4wMjE2LC0wLjEwMTI0MSAwLjA0MTM4LC0wLjE4NDA2IDAuMDYwNTUsLTAuMjUgbCAwLjQ4NjMyOCwtMS43NTM5MDYgaCAxLjA2MDU0NyBsIC0xLjE0ODQzNywzLjQ0MTQwNiBoIC0xLjExMzI4MiB6IG0gNC43OTEwMTYsMC41NTI3MzQgYyAtMC4wMTQyOSwwLjA3ODQ0IC0wLjAzNDIxLDAuMTc1NjY5IC0wLjA2MDU1LDAuMjkxMDE2IC0wLjAyNjM0LDAuMTE1MzQ3IC0wLjA1NDA2LDAuMjMwNzgyIC0wLjA4MjAzLDAuMzQzNzUgLTAuMDI3OTMsMC4xMTI5NjkgLTAuMDUxNDcsMC4yMDU5MiAtMC4wNzIyNywwLjI4MTI1IGwgLTAuMTUyMzQ0LDAuNTY0NDUzIGggMC43NDYwOTQgbCAtMC4xNTAzOSwtMC41NjQ0NTMgYyAtMC4wMTU5MiwtMC4wNjEyMiAtMC4wMzk4OCwtMC4xNDc5NzEgLTAuMDcwMzEsLTAuMjYxNzE5IC0wLjAzMDI3LC0wLjExMzc4OSAtMC4wNjAyOSwtMC4yMzE5MzUgLTAuMDg5ODQsLTAuMzUzNTE1IC0wLjAyOTU2LC0wLjEyMTYyIC0wLjA1MjM1LC0wLjIyMjM0MiAtMC4wNjgzNiwtMC4zMDA3ODIgeiBtIC0zLjY0NjQ4NCwyLjk5MjE4OCBIIDIwLjU2MjUgYyAwLjE3NDc3NSwwIDAuMzIwNjU4LDAuMDI5NjQgMC40Mzk0NTMsMC4wODk4NCAwLjExODc1NCwwLjA2MDIgMC4yMTAyNTUsMC4xNDg1NTYgMC4yNzE0ODQsMC4yNjU2MjUgMC4wNjEyNywwLjExNzA2OSAwLjA5MTgsMC4yNjE4NjQgMC4wOTE4LDAuNDMzNTkzIDAsMC4xNzk4MDcgLTAuMDMzMDEsMC4zMzEzIC0wLjA5NzY2LDAuNDUzMTI1IC0wLjA2NDYxLDAuMTIxODI2IC0wLjE2MDQ3NywwLjIxMzc2MSAtMC4yODcxMDksMC4yNzUzOTEgLTAuMTI2NTksMC4wNjE2NyAtMC4yODM5NjUsMC4wOTE4IC0wLjQ3MDcwMywwLjA5MTggSCAyMC4xMTkxNCBaIG0gMS40MzU1NDYsMCBoIDAuODk2NDg1IHYgMC4xMDE1NjIgaCAtMC43ODEyNSB2IDAuNjExMzI4IEggMjIuNDA2MjUgViAxOS42MjUgaCAtMC43MzYzMjggdiAwLjY5MzM1OSBoIDAuNzgxMjUgdiAwLjEwMTU2MyBoIC0wLjg5NjQ4NSB6IG0gMS4wODM5ODUsMCBoIDAuMzk4NDM3IGMgMC4xMzAwMDgsMCAwLjIzNzIyOSwwLjAxMzA5IDAuMzI0MjE5LDAuMDQxMDIgMC4wODcwMywwLjAyNzg4IDAuMTUzMTY2LDAuMDc0NzggMC4xOTcyNjYsMC4xMzg2NzIgMC4wNDQwMiwwLjA2Mzg0IDAuMDY2NDEsMC4xNDkxOTEgMC4wNjY0MSwwLjI1NzgxMyAwLDAuMDgxNDggLTAuMDE0NjIsMC4xNTI1ODcgLTAuMDQ0OTIsMC4yMTA5MzcgLTAuMDMwMywwLjA1ODM1IC0wLjA3MjAyLDAuMTA1MTc4IC0wLjEyNSwwLjE0MjU3OCAtMC4wNTMxLDAuMDM3NDggLTAuMTE0MTU0LDAuMDY2MTMgLTAuMTgzNTk0LDAuMDg1OTQgbCAwLjQ0OTIxOSwwLjczMjQyMiBIIDIzLjU4Mzk5IGwgLTAuNDIzODI4LC0wLjY5OTIxOSBoIC0wLjQwNjI1IHYgMC42OTkyMTkgaCAtMC4xMTUyMzQgeiBtIDEuMDA3ODEyLDAgaCAwLjExOTE0MSBsIDAuMzA4NTk0LDEuMTM0NzY1IGMgMC4wMDgxLDAuMDMwMDkgMC4wMTQzOCwwLjA1ODc5IDAuMDIxNDgsMC4wODU5NCAwLjAwNywwLjAyNzE1IDAuMDEzNTMsMC4wNTI4MSAwLjAxOTUzLDAuMDc4MTMgMC4wMDYsMC4wMjUzNCAwLjAxMTk4LDAuMDUwMzUgMC4wMTc1OCwwLjA3NDIyIDAuMDA1NiwwLjAyMzgzIDAuMDExMTIsMC4wNDgwNCAwLjAxNTYzLDAuMDcyMjcgMC4wMDUyLC0wLjAyNDI0IDAuMDEwNDMsLTAuMDQ5MjUgMC4wMTU2MywtMC4wNzQyMiAwLjAwNTIsLTAuMDI0OTMgMC4wMTEyOCwtMC4wNDg1NSAwLjAxNzU4LC0wLjA3NDIyIDAuMDA2NCwtMC4wMjU3MSAwLjAxMjMzLC0wLjA1MjU2IDAuMDE5NTMsLTAuMDgwMDggMC4wMDcsLTAuMDI3NTIgMC4wMTYzOSwtMC4wNTc3OSAwLjAyNTM5LC0wLjA4Nzg5IGwgMC4zMjAzMTMsLTEuMTI4OTA2IGggMC4xMTUyMzQgbCAwLjMzMzk4NSwxLjEzNjcxOSBjIDAuMDA5LDAuMDMxNTMgMC4wMTc5OSwwLjA1OTk3IDAuMDI1MzksMC4wODc4OSAwLjAwNzUsMC4wMjc4OSAwLjAxMzUzLDAuMDU0NzQgMC4wMTk1MywwLjA4MDA4IDAuMDA1OSwwLjAyNTMgMC4wMTIyOCwwLjA1MDM1IDAuMDE3NTgsMC4wNzQyMiAwLjAwNTIsMC4wMjM4MyAwLjAxMDQzLDAuMDQ4MDggMC4wMTU2MywwLjA3MjI3IDAuMDA2LC0wLjAzMzAxIDAuMDExMTgsLTAuMDY1NzIgMC4wMTc1OCwtMC4wOTc2NiAwLjAwNjMsLTAuMDMxOSAwLjAxNDQ0LC0wLjA2NDM5IDAuMDIzNDQsLTAuMDk5NjEgMC4wMDksLTAuMDM1MjYgMC4wMiwtMC4wNzUzNyAwLjAzMTI1LC0wLjExNzE4NyBsIDAuMzE0NDUzLC0xLjEzNjcxOSBoIDAuMTE5MTQxIGwgLTAuNDQ3MjY2LDEuNjA5Mzc1IGggLTAuMTExMzI4IGwgLTAuMzUxNTYyLC0xLjIxNDg0NCBjIC0wLjAwODMsLTAuMDI1NjcgLTAuMDE1MDgsLTAuMDUxMDkgLTAuMDIxNDgsLTAuMDc0MjIgLTAuMDA2MywtMC4wMjMxMyAtMC4wMTE4OCwtMC4wNDM1NCAtMC4wMTc1OCwtMC4wNjQ0NSAtMC4wMDU2LC0wLjAyMDkyIC0wLjAxMDczLC0wLjA0MTg1IC0wLjAxNTYzLC0wLjA2MDU1IC0wLjAwNDgsLTAuMDE4NjkgLTAuMDA4NywtMC4wMzU0IC0wLjAxMTcyLC0wLjA1MDc4IC0wLjAwMjksMC4wMTUzOCAtMC4wMDY0LDAuMDMxNjEgLTAuMDA5OCwwLjA0ODgzIC0wLjAwMzQsMC4wMTcyNiAtMC4wMDcyLDAuMDM0MzggLTAuMDExNzIsMC4wNTI3MyAtMC4wMDQ1LDAuMDE4MzMgLTAuMDA4NCwwLjAzODc0IC0wLjAxMzY3LDAuMDU4NTkgLTAuMDA1MiwwLjAxOTgxIC0wLjAxMTU4LDAuMDM5MjcgLTAuMDE3NTgsMC4wNjA1NSBsIC0wLjM0OTYwOSwxLjI0NDE0MSBoIC0wLjExMzI4MSB6IG0gMi4wMzUxNTcsMCBoIDAuODk2NDg0IHYgMC4xMDE1NjIgaCAtMC43NzkyOTcgdiAwLjYxMTMyOCBoIDAuNzM2MzI4IFYgMTkuNjI1IGggLTAuNzM2MzI4IHYgMC42OTMzNTkgaCAwLjc3OTI5NyB2IDAuMTAxNTYzIGggLTAuODk2NDg0IHogbSAxLjA4Mzk4NCwwIGggMC4zOTg0MzcgYyAwLjEyOTkyNiwwIDAuMjM5MTQyLDAuMDEzMDkgMC4zMjYxNzIsMC4wNDEwMiAwLjA4Njk5LDAuMDI3ODggMC4xNTEyMTMsMC4wNzQ3OCAwLjE5NTMxMywwLjEzODY3MiAwLjA0NDAyLDAuMDYzODQgMC4wNjY0MSwwLjE0OTE5MSAwLjA2NjQxLDAuMjU3ODEzIDAsMC4wODE0OCAtMC4wMTQ2MiwwLjE1MjU4NyAtMC4wNDQ5MiwwLjIxMDkzNyAtMC4wMzAyNiwwLjA1ODM1IC0wLjA3MjAyLDAuMTA1MTc4IC0wLjEyNSwwLjE0MjU3OCAtMC4wNTMwNiwwLjAzNzQ4IC0wLjExNDE1MywwLjA2NjEzIC0wLjE4MzU5NCwwLjA4NTk0IGwgMC40NDkyMTksMC43MzI0MjIgaCAtMC4xMzY3MTkgbCAtMC40MjE4NzUsLTAuNjk5MjE5IGggLTAuNDA4MjAzIHYgMC42OTkyMTkgaCAtMC4xMTUyMzQgeiBtIDEuMTgxNjQxLDAgaCAwLjg5NjQ4NCB2IDAuMTAxNTYyIEggMjguMDYyNSB2IDAuNjg3NSBoIDAuNzM4MjgxIHYgMC4wOTk2MSBIIDI4LjA2MjUgdiAwLjcyMDcwMyBoIC0wLjExNTIzNCB6IG0gLTcuNzEyODkxLDAuMDk5NjEgdiAxLjQxMDE1NiBoIDAuMjcxNDg0IGMgMC4yNDcyNjEsMCAwLjQzMjE4MywtMC4wNjA0IDAuNTU0Njg4LC0wLjE3OTY4NyAwLjEyMjU0OSwtMC4xMTkyNDIgMC4xODM1OTQsLTAuMjk4NTQyIDAuMTgzNTk0LC0wLjUzNzEwOSAwLC0wLjE1MzM1OCAtMC4wMjUzNiwtMC4yODAwNTQgLTAuMDc2MTcsLTAuMzgyODEzIC0wLjA1MDc3LC0wLjEwMjc1OCAtMC4xMjk3OTMsLTAuMTgwNjcyIC0wLjIzNDM3NSwtMC4yMzI0MjIgLTAuMTA0NTgyLC0wLjA1MTcxIC0wLjIzNTg4MiwtMC4wNzgxMyAtMC4zOTY0ODUsLTAuMDc4MTMgeiBtIDIuNTE5NTMxLDAgdiAwLjcwODk4NSBoIDAuMzI2MTcyIGMgMC4xMzM3NiwwIDAuMjM3NDcsLTAuMDMwNjQgMC4zMTI1LC0wLjA5Mzc1IDAuMDc1MTYsLTAuMDYzMTUgMC4xMTMyODEsLTAuMTUzMzUgMC4xMTMyODEsLTAuMjcxNDg1IDAsLTAuMTI5OTQ0IC0wLjAzOTk4LC0wLjIyMDMyMSAtMC4xMTkxNCwtMC4yNjk1MzEgLTAuMDc5MjQsLTAuMDQ5MTcgLTAuMTk5MjI0LC0wLjA3NDIyIC0wLjM2MTMyOCwtMC4wNzQyMiB6IG0gNC4xMjY5NTMsMCB2IDAuNzA4OTg1IGggMC4zMjYxNzIgYyAwLjEzMzc1OSwwIDAuMjM5NDIzLC0wLjAzMDY0IDAuMzE0NDUzLC0wLjA5Mzc1IDAuMDc1MTIsLTAuMDYzMTUgMC4xMTEzMjgsLTAuMTUzMzUgMC4xMTEzMjgsLTAuMjcxNDg1IDAsLTAuMTI5OTQ0IC0wLjAzODA4LC0wLjIyMDMyMSAtMC4xMTcxODcsLTAuMjY5NTMxIC0wLjA3OTI0LC0wLjA0OTE3IC0wLjIwMTE3OCwtMC4wNzQyMiAtMC4zNjMyODEsLTAuMDc0MjIgeiIgICAgc3R5bGU9ImJhc2VsaW5lLXNoaWZ0OmJhc2VsaW5lO2NsaXAtcnVsZTpub256ZXJvO2Rpc3BsYXk6aW5saW5lO292ZXJmbG93OnZpc2libGU7dmVjdG9yLWVmZmVjdDpub25lO2ZpbGw6IzIyMjIyMjtmaWxsLXJ1bGU6bm9uemVybztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjptaXRlcjtlbmFibGUtYmFja2dyb3VuZDphY2N1bXVsYXRlO3N0b3AtY29sb3I6IzAwMDAwMDtzdG9wLW9wYWNpdHk6MSIgICAgaWQ9InBhdGgxNyIgLz48L3N2Zz4=');}.icon-sign-out{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMTgsMjE2YTYsNiwwLDAsMS02LDZINDhhNiw2LDAsMCwxLTYtNlY0MGE2LDYsMCwwLDEsNi02aDY0YTYsNiwwLDAsMSwwLDEySDU0VjIxMGg1OEE2LDYsMCwwLDEsMTE4LDIxNlptMTEwLjI0LTkyLjI0LTQwLTQwYTYsNiwwLDAsMC04LjQ4LDguNDhMMjA5LjUxLDEyMkgxMTJhNiw2LDAsMCwwLDAsMTJoOTcuNTFsLTI5Ljc1LDI5Ljc2YTYsNiwwLDEsMCw4LjQ4LDguNDhsNDAtNDBBNiw2LDAsMCwwLDIyOC4yNCwxMjMuNzZaIi8+PC9zdmc+');}.icon-arrow-clockwise{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzgsNTZ2NDhhNiw2LDAsMCwxLTYsNkgxODRhNiw2LDAsMCwxLDAtMTJoMzIuNTVsLTMwLjM4LTI3LjhjLS4wNi0uMDYtLjEyLS4xMy0uMTktLjE5YTgyLDgyLDAsMSwwLTEuNywxMTcuNjUsNiw2LDAsMCwxLDguMjQsOC43M0E5My40Niw5My40NiwwLDAsMSwxMjgsMjIyaC0xLjI4QTk0LDk0LDAsMSwxLDE5NC4zNyw2MS40TDIyNiw5MC4zNVY1NmE2LDYsMCwxLDEsMTIsMFoiLz48L3N2Zz4=');}.icon-x-square{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDgsMzRINDhBMTQsMTQsMCwwLDAsMzQsNDhWMjA4YTE0LDE0LDAsMCwwLDE0LDE0SDIwOGExNCwxNCwwLDAsMCwxNC0xNFY0OEExNCwxNCwwLDAsMCwyMDgsMzRabTIsMTc0YTIsMiwwLDAsMS0yLDJINDhhMiwyLDAsMCwxLTItMlY0OGEyLDIsMCwwLDEsMi0ySDIwOGEyLDIsMCwwLDEsMiwyWk0xNjQuMjQsMTAwLjI0LDEzNi40OCwxMjhsMjcuNzYsMjcuNzZhNiw2LDAsMSwxLTguNDgsOC40OEwxMjgsMTM2LjQ4bC0yNy43NiwyNy43NmE2LDYsMCwwLDEtOC40OC04LjQ4TDExOS41MiwxMjgsOTEuNzYsMTAwLjI0YTYsNiwwLDAsMSw4LjQ4LTguNDhMMTI4LDExOS41MmwyNy43Ni0yNy43NmE2LDYsMCwwLDEsOC40OCw4LjQ4WiIvPjwvc3ZnPg==');}.icon-eye-closed{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjkuMjEsMTY1YTYsNiwwLDAsMS0xMC40Miw2bC0yMC0zNS4wOGExMjIsMTIyLDAsMCwxLTM5LDE4LjA5bDYuMTcsMzdhNiw2LDAsMCwxLTQuOTMsNi45MSw2Ljg1LDYuODUsMCwwLDEtMSwuMDgsNiw2LDAsMCwxLTUuOTEtNUwxNDgsMTU2LjQ0YTEyOC44NiwxMjguODYsMCwwLDEtNDAsMEwxMDEuOTIsMTkzQTYsNiwwLDAsMSw5NiwxOThhNi44NSw2Ljg1LDAsMCwxLTEtLjA4QTYsNiwwLDAsMSw5MC4wOCwxOTFsNi4xNy0zN2ExMjIsMTIyLDAsMCwxLTM5LTE4LjA5TDM3LjIxLDE3MWE2LDYsMCwxLDEtMTAuNDItNmwyMC44NS0zNi40OGExNTIsMTUyLDAsMCwxLTIwLjMxLTIwLjc3LDYsNiwwLDAsMSw5LjM0LTcuNTRDNTMuNTQsMTIxLjExLDgzLjA3LDE0NiwxMjgsMTQ2czc0LjQ2LTI0Ljg5LDkxLjMzLTQ1Ljc3YTYsNiwwLDAsMSw5LjM0LDcuNTQsMTUyLDE1MiwwLDAsMS0yMC4zMSwyMC43N1oiLz48L3N2Zz4=');}.icon-hourglass{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xOTgsNzUuNjRWNDBhMTQsMTQsMCwwLDAtMTQtMTRINzJBMTQsMTQsMCwwLDAsNTgsNDBWNzZhMTQuMDYsMTQuMDYsMCwwLDAsNS42LDExLjJMMTE4LDEyOCw2My42LDE2OC44QTE0LjA2LDE0LjA2LDAsMCwwLDU4LDE4MHYzNmExNCwxNCwwLDAsMCwxNCwxNEgxODRhMTQsMTQsMCwwLDAsMTQtMTRWMTgwLjM2YTE0LjA4LDE0LjA4LDAsMCwwLTUuNTYtMTEuMTdMMTM4LDEyOGw1NC40OS00MS4xOUExNC4wOCwxNC4wOCwwLDAsMCwxOTgsNzUuNjRaTTE4NiwxODAuMzZWMjE2YTIsMiwwLDAsMS0yLDJINzJhMiwyLDAsMCwxLTItMlYxODBhMiwyLDAsMCwxLC44LTEuNkwxMjgsMTM1LjUxbDU3LjIyLDQzLjI1QTIsMiwwLDAsMSwxODYsMTgwLjM2Wm0wLTEwNC43MmEyLDIsMCwwLDEtLjc5LDEuNkwxMjgsMTIwLjQ5LDcwLjgsNzcuNkEyLDIsMCwwLDEsNzAsNzZWNDBhMiwyLDAsMCwxLDItMkgxODRhMiwyLDAsMCwxLDIsMloiLz48L3N2Zz4=');}.icon-star-half-fi{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzkuMTgsOTcuMjZBMTYuMzgsMTYuMzgsMCwwLDAsMjI0LjkyLDg2bC01OS00Ljc2TDE0My4xNCwyNi4xNWExNi4zNiwxNi4zNiwwLDAsMC0zMC4yNywwTDkwLjExLDgxLjIzLDMxLjA4LDg2YTE2LjQ2LDE2LjQ2LDAsMCwwLTkuMzcsMjguODZsNDUsMzguODNMNTMsMjExLjc1YTE2LjQsMTYuNCwwLDAsMCwyNC41LDE3LjgyTDEyOCwxOTguNDlsNTAuNTMsMzEuMDhBMTYuNCwxNi40LDAsMCwwLDIwMywyMTEuNzVsLTEzLjc2LTU4LjA3LDQ1LTM4LjgzQTE2LjQzLDE2LjQzLDAsMCwwLDIzOS4xOCw5Ny4yNlptLTE1LjM0LDUuNDctNDguNyw0MmE4LDgsMCwwLDAtMi41Niw3LjkxbDE0Ljg4LDYyLjhhLjM3LjM3LDAsMCwxLS4xNy40OGMtLjE4LjE0LS4yMy4xMS0uMzgsMGwtNTQuNzItMzMuNjVBOCw4LDAsMCwwLDEyOCwxODEuMVYzMmMuMjQsMCwuMjcuMDguMzUuMjZMMTUzLDkxLjg2YTgsOCwwLDAsMCw2Ljc1LDQuOTJsNjMuOTEsNS4xNmMuMTYsMCwuMjUsMCwuMzQuMjlTMjI0LDEwMi42MywyMjMuODQsMTAyLjczWiIvPjwvc3ZnPg==');}.icon-star-fi{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzQuMjksMTE0Ljg1bC00NSwzOC44M0wyMDMsMjExLjc1YTE2LjQsMTYuNCwwLDAsMS0yNC41LDE3LjgyTDEyOCwxOTguNDksNzcuNDcsMjI5LjU3QTE2LjQsMTYuNCwwLDAsMSw1MywyMTEuNzVsMTMuNzYtNTguMDctNDUtMzguODNBMTYuNDYsMTYuNDYsMCwwLDEsMzEuMDgsODZsNTktNC43NiwyMi43Ni01NS4wOGExNi4zNiwxNi4zNiwwLDAsMSwzMC4yNywwbDIyLjc1LDU1LjA4LDU5LDQuNzZhMTYuNDYsMTYuNDYsMCwwLDEsOS4zNywyOC44NloiLz48L3N2Zz4=');}.icon-heart-fi{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yNDAsMTAyYzAsNzAtMTAzLjc5LDEyNi42Ni0xMDguMjEsMTI5YTgsOCwwLDAsMS03LjU4LDBDMTE5Ljc5LDIyOC42NiwxNiwxNzIsMTYsMTAyQTYyLjA3LDYyLjA3LDAsMCwxLDc4LDQwYzIwLjY1LDAsMzguNzMsOC44OCw1MCwyMy44OUMxMzkuMjcsNDguODgsMTU3LjM1LDQwLDE3OCw0MEE2Mi4wNyw2Mi4wNywwLDAsMSwyNDAsMTAyWiIvPjwvc3ZnPg==');}
\ No newline at end of file
diff --git a/assets/js/concise/CRUD.js b/assets/js/concise/CRUD.js
index 368d4bf..641a928 100644
--- a/assets/js/concise/CRUD.js
+++ b/assets/js/concise/CRUD.js
@@ -117,6 +117,7 @@
 		}
 
 		let itemsToRemove = [];
+		console.log(data);
 		switch (true) {
 			case data.config.element === this.ui.forms.edit:
 				theChanges[this.currentItemID] = changes;
@@ -198,6 +199,7 @@
 			data: {
 				posts: changes,
 			},
+			delay: true,
 			popup: `Saving changes`,
 			title: title
 		};
@@ -241,7 +243,7 @@
 					console.log(data);
 					if (data === this.ui.uploader.querySelector('[data-uploader]')?.dataset.uploader) {
 						window.debouncer.schedule('crud-complete', ()=> {
-							this.store.clearHttpHeaders();
+							this.store.clearCache();
 						});
 					}
 				}
@@ -674,7 +676,7 @@
 
 	setupFilters() {
 		// Search
-		const searchInput = document.querySelector('input[type="search"]');
+		const searchInput = document.querySelector('.all-filters input[type="search"]');
 		if (searchInput) {
 			let searchTimeout;
 			searchInput.addEventListener('input', () => {
diff --git a/assets/js/concise/DataStore.js b/assets/js/concise/DataStore.js
index 95027e3..439225d 100644
--- a/assets/js/concise/DataStore.js
+++ b/assets/js/concise/DataStore.js
@@ -648,7 +648,8 @@
 			endpoint: store.config.endpoint,
 			filters: { ...store.filters },
 			etag: response.headers.get('ETag'),
-			lastModified: response.headers.get('Last-Modified')
+			lastModified: response.headers.get('Last-Modified'),
+			has_more: data.has_more || false
 		};
 
 		store.cache.set(cacheKey, cacheEntry);
@@ -669,6 +670,12 @@
 			queue_stats: data.queue_stats || {}
 		};
 
+		for (let [key, value] of Object.entries(store.filters)) {
+			if (typeof value === 'string' && value.includes(',')) {
+				this.createSplitCacheEntries(name, items, key, store.filters, response);
+			}
+		}
+
 		// Emit events for items with status changes
 		changes.forEach(changeInfo => {
 			if (changeInfo.statusChanged) {
@@ -681,6 +688,39 @@
 		});
 	}
 
+	createSplitCacheEntries(name, items, key, filters, response) {
+		const store = this.stores.get(name);
+		const keys = filters[key].split(',').map(v => v.trim());
+
+		keys.forEach(value => {
+			let temp = {};
+			temp[key] = value;
+			const newFilters = {
+				... filters,
+				[key]: value
+			};
+			const cacheKey = this.generateCacheKey(newFilters);
+			if(store.cache.has(cacheKey)) return;
+			let filteredItems = this.filterByIndex(name,temp).map(item => this.getItemKey(item, store.config.keyPath));
+
+			const entry = {
+				key: cacheKey,
+				items: filteredItems,
+				timestamp: Date.now(),
+				endpoint: store.config.endpoint,
+				filters: newFilters,
+				etag: response.headers.get('Etag'),
+				lastModified: response.headers.get('Last-Modified'),
+				has_more: filteredItems.length === 20,
+			}
+			store.cache.set(cacheKey, entry);
+			if (store.db?.objectStoreNames.contains('cache')) {
+				this.withTransaction(name, 'cache', 'readwrite', (objectStore) =>{
+					objectStore.put(entry);
+				});
+			}
+		})
+	}
 	/***********************************************************************
 	 * SAVE OPERATIONS
 	 ***********************************************************************/
@@ -764,8 +804,7 @@
 
 		// FormData - convert and continue
 		if (obj instanceof FormData) {
-			if (validate) return { valid: false, error: `FormData at ${path}` };
-			console.debug(`[DataStore] Converted FormData at ${path}`);
+			console.debug(`[DataStore] Converting FormData at ${path}`);
 			return { valid: true, data: this.formDataToObject(obj) };
 		}
 
@@ -899,6 +938,7 @@
 		const cacheKey = this.generateCacheKey(store.filters);
 		const cacheEntry = store.cache.get(cacheKey);
 
+		// First check if we have cached results for exact filters
 		if (cacheEntry && cacheEntry.items) {
 			return cacheEntry.items.reduce((acc, id) => {
 				const item = store.data.get(id);
@@ -907,6 +947,42 @@
 			}, []);
 		}
 
+		// If we have a search filter and complete base data, filter locally
+		if (store.filters.search && store.filters.search.trim()) {
+			const searchQuery = store.filters.search.toLowerCase().trim();
+
+			// Get all items and filter them locally
+			const allItems = Array.from(store.data.values());
+
+			// Filter by current filters (excluding search and page)
+			let filtered = allItems.filter(item => {
+				// Apply all filters except search and page
+				for (const [key, value] of Object.entries(store.filters)) {
+					if (key === 'search' || key === 'page') continue;
+
+					if (value !== null && value !== undefined && value !== '') {
+						if (item[key] !== value) return false;
+					}
+				}
+				return true;
+			});
+
+			// Apply search filter to common searchable fields
+			filtered = filtered.filter(item => {
+				// Search in common fields: name, title, path, description
+				const searchableFields = ['name', 'title', 'path', 'description', 'slug'];
+
+				return searchableFields.some(field => {
+					const value = item[field];
+					if (!value) return false;
+					return value.toLowerCase().includes(searchQuery);
+				});
+			});
+
+			return filtered;
+		}
+
+		// Fallback to all data
 		return this.getAll(name);
 	}
 
@@ -931,28 +1007,111 @@
 
 		if (clearAll) {
 			store.filters = { ...store.config.filters };
-		} else {
-			// Apply updates (null/undefined/'' = delete)
-			Object.entries(updates).forEach(([key, value]) => {
-				if (value === null || value === undefined || value === '') {
-					delete store.filters[key];
-				} else {
-					store.filters[key] = value;
-				}
-			});
 		}
 
+		Object.entries(updates).forEach(([key, value]) => {
+			if (value === null || value === undefined || value === '') {
+				delete store.filters[key];
+			} else {
+				store.filters[key] = value;
+			}
+		});
+
+		const shouldFetch = await this.shouldFetchWithFilters(name, updates, oldFilters);
+
 		this.notify(name, 'filters-changed', {
 			oldFilters,
 			filters: store.filters,
 			updates
 		});
 
-		if (store.config.endpoint) {
+		if (store.config.endpoint && shouldFetch) {
 			await this.fetch(name);
+		} else if (store.config.endpoint) {
+			this.notify(name, 'data-loaded');
 		}
 	}
 
+	/**
+	 * Determine if we need to fetch or can use local data
+	 * @param {string} name - Store name
+	 * @param {object} updates - Filter updates being applied
+	 * @param {object} oldFilters - Previous filter state
+	 * @returns {Promise<boolean>} - True if fetch is needed, false if local filtering suffices
+	 */
+	async shouldFetchWithFilters(name, updates, oldFilters) {
+		const store = this.stores.get(name);
+
+		// If no endpoint or no lastResponse, always fetch
+		if (!store.config.endpoint || !store.lastResponse) {
+			return true;
+		}
+
+		// PAGE OPTIMIZATION: Don't fetch if trying to go beyond available pages
+		if ('page' in updates) {
+			const newPage = updates.page;
+			const oldPage = oldFilters.page || 1;
+
+			// If trying to go to a higher page but no more data available
+			if (newPage > oldPage && !store.lastResponse.has_more) {
+				// Reset page to last valid page
+				store.filters.page = oldPage;
+				return false;
+			}
+		}
+
+		// SEARCH OPTIMIZATION: Check if we need to fetch for search
+		if ('search' in updates) {
+			const searchQuery = updates.search?.trim() || '';
+			const oldSearch = oldFilters.search?.trim() || '';
+
+			// If search is being cleared, we might already have the data
+			if (!searchQuery && oldSearch) {
+				// Check if we have all base data (without search)
+				const baseFilters = { ...store.filters };
+				delete baseFilters.search;
+				baseFilters.page = 1;
+
+				// If we have complete base data, no need to fetch
+				if (this.hasCompleteData(store, baseFilters)) {
+					return false;
+				}
+			}
+
+			// If search is new or changed, check if we have all data to filter locally
+			if (searchQuery && searchQuery !== oldSearch) {
+				// Check: do we have all data for base filters (no search, page 1)?
+				const baseFilters = { ...store.filters };
+				delete baseFilters.search;
+				baseFilters.page = 1;
+
+				// If we have complete base data, we can filter locally
+				if (this.hasCompleteData(store, baseFilters)) {
+					return false;
+				}
+			}
+		}
+
+		// Default: fetch is needed
+		return true;
+	}
+
+	/**
+	 * Check if we have complete data for given filters
+	 * @param {object} store - Store instance
+	 * @param {object} filters - Filters to check
+	 * @returns {boolean} - True if we have all data
+	 */
+	hasCompleteData(store, filters) {
+		const cacheKey = this.generateCacheKey(filters);
+		const cached = store.cache.get(cacheKey);
+
+		if (!cached) return false;
+
+		// Check if cache indicates no more data
+		return cached.has_more === false || store.lastResponse?.has_more === false;
+	}
+
 	setFilter(name, key, value) {
 		return this.updateFilters(name, { [key]: value });
 	}
@@ -962,6 +1121,8 @@
 
 		const hasChanges = Object.keys(filters).some(
 			key => store.filters[key] !== filters[key]
+		) || Object.keys(store.filters).some(
+			key => !(key in filters) && filters !== store.config.filters
 		);
 
 		if (!hasChanges) return;
diff --git a/assets/js/concise/Queue.js b/assets/js/concise/Queue.js
index 7e3033c..478be92 100644
--- a/assets/js/concise/Queue.js
+++ b/assets/js/concise/Queue.js
@@ -1,161 +1,296 @@
-/**
- * QueueManager
- * Uses DataStore for persistent storage
- */
 class QueueManager {
-	constructor(config = {}) {
-		this.canUpdateUI = true;
-		this.config = {
-			apiBase: jvbSettings.api,
-			maxRetries: 3,
-			pollInterval: 5000,
-			activityDelay: 2000, //2 seconds
-			autosync: true,
-			endpoint: 'queue',
-			...config
-		};
-
-		// Queue state
-		this.isProcessing = false;
-		this.isPolling = false;
-		this.subscribers = new Set();
-
-		// Status definitions
-		this.statuses = [
-			'queued',
-			'localProcessing',
-			'uploading',
-			'pending',
-			'processing',
-			'completed',
-			'failed',
-			'failed_permanent'
-		];
+	constructor() {
+		this.a11y = window.jvbA11y;
+		this.error = window.jvbError;
 
 		this.user = window.auth.getUser();
 
-		if (!this.user) {
-			console.log('Queue: User not logged in, queue disabled');
-			this.store = null;
-			this.canUpdateUI = false;
-			return;
-		}
+		this.canUpdateUI = true;
+		this.isProcessing = false;
+		this.isPolling = false;
+		this.queue = new Map();
+		this.items = new Map();
+		this.subscribers = new Set();
 
+		this.api = jvbSettings.api;
+		this.endpoint = 'queue';
+
+		this.init();
+	}
+	init() {
 		this.headers = {
 			'X-WP-Nonce': window.auth.getNonce(),
-			...config.headers
 		};
-
-		this.a11y = window.jvbA11y;
-		this.errors = window.jvbError;
-
-		// Initialize DataStore for queue persistence
-		const store = window.jvbStore.register('queue', {
-			storeName: 'queue',
-			keyPath: 'id',
-			endpoint: this.config.endpoint,
-			TTL: Infinity,
-			indexes: [
-				{name: 'status', keyPath: 'status'},
-				{name: 'type', keyPath: 'type'},
-			],
-			showLoading: false,
-			delayFetch: false, // Queue should fetch immediately
-		});
-		this.store = store.queue;
-
-		this.classes = [
-			'offline',
-			'synced',
-			'pending'
-		];
-
-
-
-		// Initialize
-		this.initUI();
+		this.initElements();
 		this.initListeners();
-		if (this.ui.panel) {
+		this.initStore();
+		if (this.canUpdateUI) {
 			this.popup = new window.jvbPopup({
 				popup: this.ui.panel,
-				toggle: this.ui.toggle,
+				toggle: this.ui.toggle.button,
 				name: 'Queue Panel',
 			});
 		}
-		this.updateUI = () => window.debouncer.schedule('queue-ui-update', this._updateUI.bind(this), 100);
-		this.initQueue();
 	}
 
-	async initQueue() {
-		let polling = this.maybeStartPolling();
-		if (!polling) {
-			this.updateStatusPanel('synced');
+	initElements() {
+		this.panelStatuses = ['syncing', 'synced', 'pending', 'offline'];
+		this.statuses = ['queued', 'localProcessing', 'uploading', 'pending', 'processing', 'completed', 'failed', 'failed_permanent'];
+		this.pendingStatuses = ['queued', 'localProcessing', 'uploading'];
+		this.workingStatuses = ['pending','processing'];
+		this.completedStatuses = ['completed', 'failed', 'failed_permanent'];
+
+		this.icons = {
+			queued: 'arrows-clockwise', localProcessing: 'arrows-clockwise', uploading: 'syncing',
+			pending: 'cloud', processing: 'syncing', completed: 'cloud-check',
+			failed: 'cloud-warning', failed_permanent: 'cloud-warning'
+		};
+		this.selectors = {
+			panel: 'aside#queue',
+			toggle: {
+				button: 'button.qtoggle',
+				indicator: '.qtoggle .indicator',
+				count: '.qtoggle .count'
+			},
+			refresh: {
+				button: '#queue .refresh .refreshNow',
+				countdown: '#queue .refresh .countdown'
+			},
+			popup: {
+				popup: '#queue .popup',
+				message: '#queue .popup span'
+			},
+			items: {
+				container: '#queue .qitems',
+			},
+			actions: {
+				retry: '#queue .retry-all',
+				clear: '#queue .dismiss-all'
+			},
+			filters: {
+				filter: '#queue [data-filter]',
+				all: {
+					label: '#queue [for="qfilter-all"]',
+					radio: '#queue [data-filter="all"]',
+					count: '#queue [data-filter="all"] .count'
+				},
+				queued: {
+					label: '#queue [for="qfilter-queued"]',
+					input: '#queue [data-filter="queued"]',
+					count: '#queue [for="qfilter-queued"] .count'
+				},
+				localProcessing: {
+					label: '#queue [for="qfilter-localProcessing"]',
+					input: '#queue [data-filter="localProcessing"]',
+					count: '#queue [for="qfilter-localProcessing"] .count',
+				},
+				uploading: {
+					label: '#queue [for="qfilter-uploading"]',
+					input: '#queue [data-filter="uploading"]',
+					count: '#queue [for="qfilter-uploading"] .count',
+				},
+				pending: {
+					label: '#queue [for="qfilter-pending"]',
+					input: '#queue [data-filter="pending"]',
+					count: '#queue [for="qfilter-pending"] .count',
+				},
+				processing: {
+					label: '#queue [for="qfilter-processing"]',
+					input: '#queue [data-filter="processing"]',
+					count: '#queue [for="qfilter-processing"] .count',
+				},
+				completed: {
+					label: '#queue [for="qfilter-completed"]',
+					input: '#queue [data-filter="completed"]',
+					count: '#queue [for="qfilter-completed"] .count',
+				},
+				failed: {
+					label: '#queue [for="qfilter-failed"]',
+					input: '#queue [data-filter="failed"]',
+					count: '#queue [for="qfilter-failed"] .count',
+				},
+			},
+			item: {
+				type: '.type',
+				status: '.status',
+				details: '.info .details',
+				icon: '.status .icon',
+				startedAt: '.started time',
+				completed: {
+					wrap: '.completed',
+					label: '.completed span',
+					time: '.completed time',
+				},
+				progress: {
+					progress: '.progress',
+					fill: '.progress .fill',
+					details: '.progress .details',
+					icon: '.progress .icon'
+				},
+				actions: {
+					cancel: 'button.cancel',
+					retry: 'button.retry',
+					dismiss: 'button.dismiss',
+				}
+			},
+		};
+		this.ui = window.uiFromSelectors(this.selectors);
+		if (!this.ui.panel) this.canUpdateUI = false;
+	}
+
+
+	initListeners() {
+		this.activityListeners = null;
+		this.clickHandler = this.handleClick.bind(this);
+		this.onlineHandler = this.handleOnline.bind(this);
+		this.offlineHandler = this.handleOffline.bind(this);
+		this.unloadHandler = this.handleBeforeUnload.bind(this);
+
+		document.addEventListener('click', this.clickHandler);
+		window.addEventListener('online', this.onlineHandler);
+		window.addEventListener('offline', this.offlineHandler);
+		window.addEventListener('beforeunload', this.unloadHandler);
+	}
+		handleOnline() {
+			this.updatePanel();
+			if (this.getQueueByStatus(this.pendingStatuses).length > 0) {
+				this.processQueue();
+			}
+		}
+		handleOffline() {
+			this.updatePanel('offline');
+		}
+	handleBeforeUnload(e) {
+		const total = this.getQueueByStatus(this.pendingStatuses).length;
+		if (total > 0) {
+			// Modern browsers ignore custom messages, but this triggers the native dialog
+			e.preventDefault();
+			e.returnValue = '';  // Required for Chrome
+			return '';  // Required for some older browsers
+		}
+	}
+		handleClick(e) {
+			if (!window.targetCheck(e, this.selectors.panel+', '+this.selectors.toggle.button)) return;
+			const refresh = window.targetCheck(e, this.selectors.refresh.button);
+			if (refresh) {
+				this.store.clearCache();
+				this.store.fetch();
+				return;
+			}
+
+			const clear = window.targetCheck(e, this.selectors.actions.clear);
+			if (clear) {
+				this.opActions('completed', 'dismiss').then(()=>{});
+				return;
+			}
+
+			const retry = window.targetCheck(e, this.selectors.actions.retry);
+			if (retry) {
+				this.opActions('failed', 'retry').then(()=>{});
+				return;
+			}
+
+			const action = window.targetCheck(e, '[data-action]');
+			if (action) {
+				const opId = action.closest('[data-id]')?.dataset.id;
+				if (opId) {
+					this.opActions(opId, action.dataset.action);
+				}
+				return;
+			}
+
+			const filter = window.targetCheck(e, this.selectors.filters.filter);
+			if (filter) {
+				this.setFilter(filter.dataset.filter);
+			}
 		}
 
+	setFilter(filter) {
+		// Update active button
+		Object.values(this.ui.filters).forEach(filterObj => {
+			if (filterObj.input?.dataset.filter === filter) {
+				filterObj.input.checked = true;
+			}
+		});
 
+		if (filter === 'all') {
+			this.store.clearFilters();
+		} else {
+			this.store.setFilter('status', filter);
+		}
+	}
+
+		trackActivity() {
+			if (!this.activityListeners) {
+				const events = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart'];
+				this.activityListeners = events.map(event => {
+					const handler = () => this.resetActivityTimer();
+					document.addEventListener(event, handler, {passive: true});
+					return {event, handler};
+				});
+			}
+			this.resetActivityTimer();
+		}
+		resetActivityTimer() {
+			if (this.activityTimer) {
+				clearTimeout(this.activityTimer);
+			}
+			this.activityTimer = setTimeout(() => {
+				this.processQueue();
+			}, 1750);
+		}
+		stopActivityTracking() {
+			if (this.activityTimer) {
+				clearTimeout(this.activityTimer);
+				this.activityTimer = null;
+			}
+			if (this.activityListeners) {
+				this.activityListeners.forEach(({event, handler}) => {
+					document.removeEventListener(event, handler);
+				});
+				this.activityListeners = null;
+			}
+		}
+
+	initStore() {
+		if (!this.user) return;
+		const store = window.jvbStore.register(
+			'queue',
+			{
+				storeName: 'queue',
+				keyPath: 'id',
+				endpoint: this.endpoint,
+				TTL: Infinity,
+				indexes: [
+					{name: 'status', keyPath: 'status'},
+					{name: 'type', keyPath: 'type'},
+				],
+				showLoading: false,
+			}
+		)
+		this.store = store.queue;
 		this.store.subscribe((event, data) => {
 			switch (event) {
 				case 'data-loaded':
-				case 'items-saved':
+				case 'items-save':
 					this.maybeStartPolling();
 					this.updateUI();
 					break;
 				case 'item-saved':
-					console.log(data,'Item saved data');
 					if (data.previousItem && data.previousItem.status !== data.item.status) {
-						this.handleOperationStatusChange(data.item, data.previousItem.status);
+						this.updateOperationStatus(data.item.id, data.item.status);
 					}
 					this.maybeStartPolling();
 					break;
 				default:
-					this.updateUI();
+
 					break;
 			}
-
 		});
 	}
-
-	maybeStartPolling()
-	{
-		const incomplete = this.getOperationsByStatus(['completed', 'failed_permanent'], false);
-		if (incomplete.length > 0) {
-			this.startPolling();
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Handle operation status changes and notify subscribers
-	 */
-	handleOperationStatusChange(operation) {
-
-		// Notify based on new status
-		switch(operation.status) {
-			case 'completed':
-				console.log(operation);
-				this.notify('operation-completed', operation);
-				break;
-			case 'failed':
-				this.notify('operation-failed', operation);
-				break;
-			case 'failed_permanent':
-				this.notify('operation-failed-permanent', operation);
-				break;
-		}
-	}
-	/**
-	 *
-	 * @param {object} operation
-	 * @param {string} operation.endpoint The endpoint, excluding the apiBase
-	 * @param {object} operation.data The data to save
-	 * @param {boolean} operation.canMerge Whether data can merge
-	 * @param {string} operation.title The title of the operation for the Queue Panel
-	 * @param {string} operation.popup The string to show in the popup
-	 * @param {object} operation.headers Optional additional headers. Defaults to the API nonce
-	 *
-	 * @returns {string|null} Returns the operation id, for reference
-	 */
+	/****************************************************************************
+	 OPERATIONS
+	****************************************************************************/
 	addToQueue(operation) {
 		const item = {
 			id: `u${this.user}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
@@ -163,7 +298,7 @@
 			method: 'POST',
 			headers: {},
 			data: {},
-			sendNow: false,				// true = process immediately
+			delay: false,
 			canMerge: true,
 			popup: 'Saving changes...',
 			title: 'Operation',
@@ -175,29 +310,31 @@
 		};
 
 		item.headers = {
-			...this.headers,
-			...item.headers
-		};
+			... this.headers,
+			... item.headers
+		}
+		if (!item.endpoint || !item.data) return null;
 
-		if (!item.endpoint || !item.data) {
-			console.error('Invalid operation queued: missing endpoint or data');
-			return null;
+		if (item.popup && this.ui.popup?.message) {  // Add popup support
+			this.ui.popup.message.textContent = item.popup;
+			this.ui.popup.popup.hidden = false;
+			setTimeout(() => this.ui.popup.popup.hidden = true, 2000);
 		}
 
-		if (item.sendNow) {
+		if (!item.delay) {
+			this.queue.set(item.id, item);
 			this.processOperation(item).then(()=> {});
 			this.store.clearCache();
-			window.debouncer.schedule('fastQueue', this.startPolling.bind(this), 200);
-			this.showQueue();
+			this.maybeStartPolling();
+			this.toggleQueue();
 			return item.id;
 		}
 
-		const existingOps = Array.from(this.store.data.values()).filter(op=>
-			op.status === 'queued' &&
+		const existingOps = Array.from(this.getAllQueue()).filter(op=> {
+			return op.status === 'queued' &&
 			op.endpoint === item.endpoint &&
 			op.canMerge
-		);
-
+		});
 		if (existingOps.length > 0) {
 			const existing = existingOps[0];
 			existing.data = window.deepMerge(existing.data, item.data);
@@ -205,111 +342,97 @@
 
 			this.updateOperationStatus(existing.id, existing.status);
 			this.updateUI();
-
-			this.startActivityTracking();
+			this.trackActivity();
 			return existing.id;
 		}
 
 		this.store.clearCache();
-
-		//Add new operation to DataStore
 		this.setQueue(item);
-
 		this.updateOperationStatus(item.id, item.status);
 		this.updateUI();
-
-		this.startActivityTracking();
+		this.trackActivity();
 		return item.id;
-
-
 	}
 
+	async opActions(statusOrId, action) {
+		//Extract ids based on status, if it exists
+		if (this.statuses.includes(statusOrId)) {
+			statusOrId = this.getQueueByStatus(statusOrId).map(op => op.id);
+		} else if (typeof statusOrId === 'string') {
+			//If it's still a string, wrap the id inside an array
+			statusOrId = [statusOrId];
+		}
+		if (statusOrId.length ===0) return;
+		if (!['cancel', 'dismiss', 'retry'].includes(action)) return;
+		const shouldRemove = ['cancel', 'dismiss'].includes(action);
+		if (shouldRemove) {
+			statusOrId.forEach(id => this.removeOperationUI(id));
+		}
 
-	setQueue(item) {
-		this.store.save(item);
-	}
-
-	updateOperationStatus(itemID, status) {
-		let item = this.store.get(itemID);
-		if (!item) return;
-
-		// Update status
-		item.status = status;
-
-		this.notify('operation-status', item);
-		this.updateOperationUI(item);
-	}
-
-	getQueue(itemID) {
-		return this.store.get(itemID);
-	}
-
-	clearQueue(itemID) {
-		this.store.delete(itemID);
-	}
-
-	startActivityTracking() {
-		if (!this.activityListeners) {
-			const activityEvents = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart'];
-			this.activityListeners = activityEvents.map(event => {
-				const handler = () => this.resetActivityTimer();
-				document.addEventListener(event, handler, {passive: true});
-				return {event, handler};
+		try {
+			const response = await fetch(
+				`${this.api}${this.endpoint}`,
+				{
+					method: 'POST',
+					headers: {
+						'Content-Type': 'application/json',
+						... this.headers
+					},
+					body: JSON.stringify({
+						action,
+						ids: statusOrId,
+						user: this.user
+					})
+				}
+			);
+			if (!response.ok) {
+				throw new Error(`${action} failed: ${response.status}`);
+			}
+			const result = await response.json();
+			if (!result.success) {
+				throw new Error(result.message || `${action} operation failed`);
+			}
+			statusOrId.forEach(id => {
+				let item = this.getQueue(id);
+				this.notify(`${action}-operation`, item);
+				if (shouldRemove) {
+					this.clearQueue(id);
+				} else {
+					let item = this.getQueue(id);
+					item.status = 'queued';
+					this.setQueue(item);
+					this.updateOperationStatus(item.id, item.status);
+				}
 			});
-		}
-		this.resetActivityTimer();
-	}
 
-	resetActivityTimer() {
-		if (this.activityTimer) {
-			clearTimeout(this.activityTimer);
-		}
-
-		this.activityTimer = setTimeout(() => {
-			this.processQueue();
-		}, this.config.activityDelay);
-	}
-
-	stopActivityTracking() {
-		if (this.activityTimer) {
-			clearTimeout(this.activityTimer);
-			this.activityTimer = null;
-		}
-		if (this.activityListeners) {
-			this.activityListeners.forEach(({event, handler}) => {
-				document.removeEventListener(event, handler);
-			});
-			this.activityListeners = null;
+			if (action === 'retry') {
+				this.trackActivity();
+			}
+			this.updateUI();
+			return result;
+		} catch (error) {
+			await window.jvbError.log(error, {
+				component: 'Queue',
+				operation: 'performQueueAction',
+				action: action,
+				operationIds: statusOrId,
+				itemCount: statusOrId.length
+			}, () => this.opActions(statusOrId, action));
+			return {success: false, error: error.message};
 		}
 	}
 
-	hideQueue(){
-		this.ui.panel.hidden = true;
-		this.ui.toggle.hidden = true;
-	}
-	showQueue() {
-		this.ui.panel.hidden = false;
-		this.ui.toggle.hidden = false;
-	}
 
-	setProcessing(on) {
-		this.isProcessing = on;
-		this.ui.toggle.classList.toggle('saving', on);
-	}
-	/**
-	 * Send any queued operations to the server
-	 * @returns {Promise<void>}
-	 */
 	async processQueue() {
 		if (this.isProcessing) return;
 
-		const queue = this.getOperationsByStatus('queued');
+		const queue = this.getQueueByStatus('queued');
 
 		if (queue.length === 0) {
 			this.stopActivityTracking();
 			return;
 		}
-		this.setProcessing(true);
+		this.setProcessing();
 
 		for (const operation of queue) {
 			await this.processOperation(operation);
@@ -318,22 +441,25 @@
 		this.setProcessing(false);
 		this.stopActivityTracking();
 
-		this.maybeStartPolling() ? this.showQueue() : this.hideQueue();
+		// this.toggleQueue(this.maybeStartPolling());
+
 	}
 
-	async processOperation(operation, skip = false) {
+	async processOperation(operation) {
 		try {
-			if (!skip) {
-				this.updateOperationStatus(operation.id, 'uploading');
-
-				if (operation.data?._isFormData) {
-					operation.data = await this.store.objectToFormData(operation.data);
-				}
+			//Add it to memory if it isn't already there
+			if (!this.queue.has(operation.id)) {
+				this.queue.set(operation.id, operation);
+			}
+			let skip = false;
+			if (operation.data?._isFormData && !operation.data instanceof FormData) {
+				skip = true;
+				operation.data = await this.store.objectToFormData(operation.data);
 			}
 
-			const url = `${this.config.apiBase}${operation.endpoint}`;
-			let requestBody;
+			this.updateOperationStatus(operation.id, 'uploading');
 
+			let requestBody;
 			if (operation.data instanceof FormData) {
 				operation.data.append('id', operation.id);
 				operation.data.append('user', this.user);
@@ -346,91 +472,149 @@
 				});
 				operation.headers['Content-Type'] = 'application/json';
 			}
-			const response = await fetch(url, {
-				method: operation.method,
-				headers: operation.headers,
-				body: requestBody
-			});
+			if (requestBody === undefined || requestBody === null) return;
 
+			const response = await fetch(
+				`${this.api}${operation.endpoint}`,
+				{
+					method: operation.method,
+					headers: operation.headers,
+					body: requestBody
+				}
+			);
 			const result = await response.json();
 			if (skip) {
 				operation.data = {};
 			}
-			if (response.ok && result.success !== false) {
-				// Handle server-side merge
+			if (response.ok && result.success) {
 				if (result.id && operation.id !== result.id) {
 					operation = await this.handleServerMerge(operation, result);
 				} else {
-					operation.status = result.status || 'pending';
+					operation.status = result.status??'pending';
 					operation.serverData = result;
 					this.updateOperationStatus(operation.id, operation.status);
 				}
-
-				this.a11y.announce(`${operation.title} sent to server for processing.`);
-
+				this.a11y.announce(`${operation.title} sent to server for processing`);
 			} else {
 				throw new Error(result.message || `HTTP ${response.status}`);
 			}
+			this.setQueue(operation);
 		} catch (error) {
-			console.error('Operation failed:', error);
-
+			console.error('Operation failed: ', error);
 			operation.retries++;
 			operation.lastError = error.message;
-
-			if (operation.retries >= this.config.maxRetries) {
+			if (operation.retries >= 3) {
 				operation.status = 'failed_permanent';
 			} else {
 				operation.status = 'failed';
-				operation.nextRetry = Date.now() + (Math.pow(2, operation.retries) * 1000);
 			}
 			this.updateOperationStatus(operation.id, operation.status);
-
 			this.setQueue(operation);
 		}
 	}
 
 	async handleServerMerge(operation, result) {
 		const existingOp = this.getQueue(result.id);
-
 		if (existingOp) {
-			// Merge with existing local operation
-			existingOp.data = window.deepMerge(existingOp.data, operation.data);
-			existingOp.status = result.status || 'pending';
-			existingOp.serverData = result;
-			this.updateOperationStatus(existingOp.id, existingOp.status);
-			this.removeOperationFromUI(operation.id);
-			this.clearQueue(operation.id);
-			return existingOp;
-		} else {
-			// Server merged with unknown operation
-			this.clearQueue(operation.id);
-			operation.id = result.id;
-			operation.status = result.status || 'pending';
+			operation.status = result.status||'pending';
 			operation.serverData = result;
-			this.updateOperationStatus(operation.id, operation.status);
-			return operation;
+			return this.mergeOp(existingOp, operation);
+		} else {
+			this.clearQueue(operation.id);
+			this.setQueue(result);
+			return result;
 		}
 	}
 
+	mergeOp(oldOp, newOp) {
+		oldOp.data = window.deepMerge(oldOp.data, newOp.data);
+		oldOp.status = newOp.status;
+		if (Object.hasOwn(newOp, 'serverData')) {
+			oldOp.serverData =	newOp.serverData;
+		}
+		this.updateOperationStatus(oldOp.id, oldOp.status);
+		this.removeOperationUI(newOp.id);
+		this.clearQueue(newOp.id);
+		return oldOp;
+	}
+	sortByDate(ops) {
+		return ops.sort((a, b) => {
+			const aTime = a.updated_at ?? a.timestamp ?? 0;
+			const bTime = b.updated_at ?? b.timestamp ?? 0;
+			return aTime - bTime;
+		});
+	}
+
+	getAllQueue() {
+		let ops = [... new Set([
+			...Array.from(this.store.data.values()),
+			... Array.from(this.queue.values())
+		])];
+		//Sort operations by operation updated_at
+		return this.sortByDate(ops);
+	}
+
+	getQueueByStatus(status) {
+		if (typeof status === 'string') {
+			status = [status];
+		}
+
+		let ops = [...new Set([
+			...Array.from(this.store.filterByIndex({status: status})),
+			...Array.from(this.queue.values()).filter(op => status.includes(op.status))
+		])];
+		return this.sortByDate(ops);
+	}
+
+
+	updateOperationStatus(itemID, status) {
+		let item = this.getQueue(itemID);
+		if (!item || !this.statuses.includes(status)) return;
+		item.status = status;
+		this.notify('operation-status', item);
+		this.setQueue(item);
+	}
+	setQueue(item) {
+		this.store.save(item);
+		this.queue.set(item.id, item);
+	}
+	getQueue(itemID) {
+		return this.queue.has(itemID) ? this.queue.get(itemID) : this.store.get(itemID);
+	}
+	clearQueue(itemID) {
+		this.queue.delete(itemID);
+		this.store.delete(itemID);
+	}
+	/****************************************************************************
+	 POLLING
+	****************************************************************************/
+	maybeStartPolling() {
+		const incomplete = this.getQueueByStatus(this.pendingStatuses);
+		if (incomplete.length > 0) {
+			this.startPolling();
+			return true;
+		}
+		return false;
+	}
 	startPolling() {
 		if (this.isPolling) return;
-
 		this.isPolling = true;
-		this.updateStatusPanel('pending');
+		this.updatePanel('pending');
 
 		this.pollTimer = setInterval(async () => {
 			try {
 				this.store.clearCache();
-				await this.store.fetch(); // Fetches from server, updates store.data
-
+				await this.store.fetch();
 				if (!this.maybeStartPolling()) {
 					this.stopPolling();
-					this.updateStatusPanel('synced');
+					this.updatePanel('synced');
 				}
 			} catch (error) {
 				console.error('Polling error:', error);
 			}
-		}, this.config.pollInterval);
+		},
+			5000);
+		this.startCountdown();
 	}
 
 	stopPolling() {
@@ -440,257 +624,176 @@
 			clearInterval(this.pollTimer);
 			this.pollTimer = null;
 		}
+		this.stopCountdown();
+	}
+	startCountdown(count = 5) {
+		if (!this.isPolling) return;
+		this.ui.refresh.countdown.textContent = count;
+		this.countdownTimer = setInterval(async() => {
+			count--;
+			if (count >= 0) {
+				this.ui.refresh.countdown.textContent = count;
+			}else {
+				this.ui.refresh.countdown.textContent = '';
+				this.stopCountdown();
+			}
+		},1000);
+	}
+	stopCountdown() {
 		if (this.countdownTimer) {
 			clearInterval(this.countdownTimer);
 			this.countdownTimer = null;
 		}
 	}
-	getOperationIds(operations) {
-		return operations.map(op => op.id);
+	/****************************************************************************
+	 UI
+	****************************************************************************/
+	updateUI() {
+		if (!this.canUpdateUI) return;
+
+		window.debouncer.schedule(
+			'queue-ui',
+			this.handleUpdateUI.bind(this)
+		)
 	}
-	/***********************************************************
-	USER ACTIONS
-	 ***********************************************************/
+		handleUpdateUI() {
+			const operations = this.getAllQueue();
+			this.ui.actions.retry.disabled = operations.filter(op => op.status === 'failed').length === 0;
+			this.ui.actions.clear.disabled = operations.filter(op => op.status === 'completed').length ===0;
 
-	/**
-	 *
-	 * @param {array} ids
-	 * @param {string }action
-	 * @returns {Promise<void>}
-	 */
-	async updateServerOperations(ids, action) {
-		ids = Array.isArray(ids) ? ids : (ids.includes(',') ? ids.split(',') : [ids]);
-		ids = ids.filter(id => {
-			let item = this.getQueue(id);
-			return this.getAllowedActions(item.status).includes(action);
-		});
-
-		if (ids.length === 0) return;
-
-		// SINGLE place to handle UI removal
-		const shouldRemove = ['cancel', 'dismiss'].includes(action);
-		if (shouldRemove) {
-			ids.forEach(id => this.removeOperationFromUI(id));
-		}
-
-		try {
-			const response = await fetch(`${this.config.apiBase}${this.config.endpoint}`, {
-				method: 'POST',
-				headers: { 'Content-Type': 'application/json', ...this.headers },
-				body: JSON.stringify({ ids, action, user: window.auth.getUser() })
-			});
-
-			if (!response.ok) {
-				throw new Error(`${action} failed: ${response.status}`);
-			}
-
-			const result = await response.json();
-			if (!result.success) {
-				throw new Error(result.message || `${action} operation failed`);
-			}
-
-			// SINGLE place to handle store updates
-			ids.forEach(id => {
-				let item = this.getQueue(id);
-				this.notify(`${action}-operation`, item);
-
-				if (shouldRemove) {
-					this.clearQueue(id);
+			for (let status of this.statuses) {
+				if (status === 'failed_permanent') continue;
+				let total = operations.filter(op => op.status === status).length;
+				this.ui.filters[status].label.hidden = total === 0;
+				this.ui.filters[status].input.dataset.count = `${total}`;
+				if (total > 0) {
+					this.ui.filters[status].count.textContent = total;
 				} else {
-					item.status = 'queued';
-					item.retries = 0;
-					this.setQueue(item);
-					this.updateOperationStatus(item.id, item.status);
+					this.ui.filters[status].count.textContent = '';
 				}
-			});
-
-			if (action === 'retry') {
-				this.startActivityTracking();
 			}
 
-			this.updateUI();
-			return result;
-
-		} catch (error) {
-			// Log and let jvbError handle retry
-			await window.jvbError.log(error, {
-				component: 'QueueManager',
-				operation: 'performQueueAction',
-				action: action,
-				operationIds: ids,
-				itemCount: ids.length
-			}, () => this.updateServerOperations(ids, action));
-
-			// Don't re-throw - error is logged and handled
-			return { success: false, error: error.message };
-		}
-	}
-
-	getAllowedActions(status) {
-		const actionMap = {
-			'queued': ['cancel'],
-			'localProcessing': ['cancel'],
-			'pending': ['cancel'],
-			'processing': [],
-			'completed': ['dismiss'],
-			'failed': ['retry', 'dismiss'],
-			'failed_permanent': ['dismiss']
-		};
-		return actionMap[status] || [];
-	}
-
-
-	/*********************************************
-	 LISTENERS
-	*********************************************/
-	initListeners() {
-		this.clickHandler = this.handleClick.bind(this);
-
-		document.addEventListener('click', this.clickHandler);
-
-		this.handleOnline = () => {
-			this.updateStatusPanel();
-			if (this.hasQueuedOperations()) {
-				this.processQueue();
-			}
-		};
-		this.handleOffline = () => this.updateStatusPanel('offline');
-		this.handleBeforeUnload = (e) => {
-			if (this.isPolling || this.isProcessing) {
-				e.preventDefault();
-				return 'You have unsaved changes in the queue. Proceed?';
-			}
-		};
-
-		window.addEventListener('online', this.handleOnline);
-		window.addEventListener('offline', this.handleOffline);
-		window.addEventListener('beforeunload', this.handleBeforeUnload);
-	}
-	handleClick(e) {
-		if (!e.target.closest(this.selectors.panel, this.selectors.toggle)) {
-			return;
-		}
-		if (e.target.closest(this.selectors.refreshButton)) {
-			this.store.clearCache();
-			this.store.clearHttpHeaders(); // Clear cached headers first
-			this.store.fetch();
-		} else if (e.target.closest(this.selectors.clearButton)) {
-			const completedOps = this.getOperationIds(this.getOperationsByStatus('completed'));
-			if (completedOps.length > 0) {
-				this.updateServerOperations(completedOps, 'dismiss');
-			}
-		} else if (e.target.closest(this.selectors.retryButton)) {
-			const failedOps = this.getOperationIds(this.getOperationsByStatus('failed'));
-			if (failedOps.length > 0) {
-				this.updateServerOperations(failedOps, 'retry');
-			}
-		} else if (e.target.closest('[data-action]')) {
-			const button = e.target.closest('[data-action]');
-			const operationId = button.closest('[data-id]')?.dataset.id;
-			if (operationId) {
-				this.updateServerOperations(operationId, button.dataset.action);
-			}
-		} else if (e.target.closest('.filters [data-filter]')) {
-			const filter = e.target.closest('[data-filter]').dataset.filter;
-			this.setFilter(filter);
+			this.renderOperations();
 		}
 
-	}
+	renderOperations() {
+		if (!this.ui.items.container) return;
 
-	/*********************************************
-	UI
-	 *********************************************/
-	initUI() {
-		this.icons = {
-			queued: 'arrows-clockwise', localProcessing: 'arrows-clockwise', uploading: 'syncing',
-			pending: 'cloud', processing: 'syncing', completed: 'cloud-check',
-			failed: 'cloud-warning', failed_permanent: 'cloud-warning'
-		};
+		const status = this.store.filters?.status ?? 'all';
+		const operations = (status === 'all') ? this.getAllQueue() : this.getQueueByStatus(status);
 
-		this.selectors = {
-			panel: 'aside#queue',
-			toggle: 'button.qtoggle',
-			refreshButton: 'button.refreshNow',
-			countdown: '.countdown',
-			indicator: '.qtoggle .indicator',
-			count: '.qtoggle .count',
-			popup: '.popup',
-			itemsContainer: '.qitems',
-			clearButton: '.dismiss-all',
-			retryButton: '.retry-all',
-			filters: {
-				all: '.filters [data-filter="all"]',
-				received: '.filters [data-filter="queued"]',
-				localProcessing: '.filters [data-filter="localProcessing"]',
-				uploading: '.filters [data-filter="uploading"]',
-				pending: '.filters [data-filter="pending"]',
-				processing: '.filters [data-filter="processing"]',
-				completed: '.filters [data-filter="completed"]',
-				failed: '.filters [data-filter="failed"]',
-			}
-		};
+		window.removeChildren(this.ui.items.container);
 
-		this.ui = window.uiFromSelectors(this.selectors);
-		if (!this.ui.panel) {
-			this.canUpdateUI = false;
-		}
-	}
-
-	_updateUI() {
-		if (!this.canUpdateUI) {
+		if (operations.length === 0) {
+			const empty = window.getTemplate('emptyQueue');
+			this.ui.items.container.append(empty);
+			this.a11y.announce('No items in queue');
 			return;
 		}
 
-		// Get current operations from store
-		const operations = Array.from(this.store.data.values());
+		operations.forEach(op => {
+			let item = this.items.get(op.id);
 
-		// Get stats from last fetch response (server-provided)
-		const stats = this.store.lastResponse?.queue_stats || {
-			queued: 0,
-			localProcessing: 0,
-			uploading: 0,
-			pending: 0,
-			processing: 0,
-			completed: 0,
-			failed: 0,
-			failed_permanent: 0
-		};
-
-		// Update count badge
-		if (this.ui.count) {
-			const activeCount = operations.length - stats.completed;
-			this.ui.count.textContent = activeCount > 0 ? activeCount : '';
-			this.ui.count.style.display = activeCount > 0 ? '' : 'none';
-		}
-
-		// Update indicator
-		if (this.ui.indicator) {
-			const hasActive = stats.queued > 0 || stats.uploading > 0 ||
-				stats.pending > 0 || stats.processing > 0;
-			this.ui.indicator.classList.toggle('active', hasActive);
-		}
-
-		// Update button states
-		this.ui.clearButton.disabled = this.getOperationsByStatus('completed').length === 0;
-		this.ui.retryButton.disabled = this.getOperationsByStatus('failed').length === 0 && this.getOperationsByStatus('failed_permanent').length === 0;
-
-		// Update filter counts (from server stats)
-		Object.entries(this.ui.filters).forEach(([status, button]) => {
-			const count = status === 'all'
-				? operations.length
-				: stats[status] || 0;
-			const countEl = button.querySelector('.count');
-			if (countEl) {
-				countEl.textContent = count > 0 ? count : '';
+			if (!item) {
+				// Create new element and reference
+				item = this.createOperationElement(op);
 			}
-			button.setAttribute('data-count', count);
+
+			if (item?.element) {
+				this.updateOperationUI(op.id);
+				this.ui.items.container.append(item.element);
+			}
 		});
-
-		// Render current operations
-		this.renderOperations();
 	}
 
-	getStatusLabel(status) {
+	createOperationElement(op) {
+		const el = window.getTemplate('queueItem');
+		el.dataset.id = op.id;
+
+		const item = {
+			element: el,
+			ui: window.uiFromSelectors(this.selectors.item, el)
+		};
+
+		this.items.set(op.id, item);
+		return item;
+	}
+
+		updateOperationUI(opId) {
+			let item = (this.items.has(opId)) ? this.items.get(opId) : this.createOperationElement(opId);
+			if (!item) return;
+			let op = this.getQueue(opId);
+
+			let element = item.element;
+			element.classList.remove(this.statuses);
+			element.classList.add(op.status);
+
+			let progress = this.getProgress(op);
+			if (item.ui.type && item.ui.type.textContent !== op.title) item.ui.type.textContent = op.title;
+			if (item.ui.status) {
+				item.ui.status.title = this.statusLabel(op.status);
+			}
+			if (item.ui.icon) {
+				item.ui.icon.className = `icon icon-${this.icons[op.status]}`;
+			}
+			if (item.ui.details) item.ui.details.textContent = this.itemMessage(op);
+			if (item.ui.startedAt) {
+				item.ui.startedAt.setAttribute('datetime', op.created_at);
+				item.ui.startedAt.textContent = window.formatTimeAgo(op.created_at);
+			}
+			let text = op.status === 'completed' ? 'Completed: ' : 'Last updated: ';
+			let shouldShow =Object.hasOwn(op, 'updated_at') || Object.hasOwn(op, 'completed_at');
+			item.ui.completed.wrap.hidden = !shouldShow;
+			if (shouldShow && item.ui.completed.label && item.ui.completed.time) {
+				let time;
+				if (Object.hasOwn(op, 'completed_at')) {
+					time = op.completed_at;
+				} else {
+					time = op.updated_at;
+				}
+
+				item.ui.completed.label.textContent = text;
+				item.ui.completed.time.setAttribute('datetime', time);
+				item.ui.completed.time.textContent = window.formatTimeAgo(time);
+			}
+			window.showProgress(item.ui.progress, progress, 100, this.statusLabel(op.status));
+			if (item.ui.actions.cancel) item.ui.actions.cancel.hidden = this.completedStatuses.includes(op.status);
+			if (item.ui.actions['retry']) {
+				if (op.retries >= 3) item.ui.actions['retry'].disabled = true;
+				item.ui.actions['retry'].hidden = op.status !=='failed';
+			}
+			if (item.ui.actions.dismiss) item.ui.actions.dismiss.hidden = this.pendingStatuses.includes(op.status);
+		}
+		getProgress(op) {
+			if (op.progress) return op.progress;
+			if (!this.statuses.includes(op.status)) return 0;
+			let statusProgress = {
+				'queued': 10,
+				'uploading': 25,
+				'pending': 40,
+				'processing':70,
+				'completed':100,
+				'failed':0,
+				'failed_permanent':0
+			};
+			return statusProgress[op.status]??0;
+		}
+	removeOperationUI(opId) {
+		let op = this.items.get(opId);
+		if (!op) return;
+		window.fade(op.element, false);
+	}
+
+	updatePanel(status = 'syncing') {
+		if (!this.panelStatuses.includes(status)) return;
+		this.ui.panel.classList.remove(this.panelStatuses);
+		this.ui.panel.classList.add(status);
+	}
+	/****************************************************************************
+	 UTILITY
+	 ****************************************************************************/
+	statusLabel(status) {
+		if (!this.statuses.includes(status)) return'';
 		const labels = {
 			'queued': 'Queued',
 			'localProcessing': 'Processing locally',
@@ -698,15 +801,14 @@
 			'pending': 'Waiting on server',
 			'processing': 'Processing',
 			'completed': 'Completed',
-			'failed': 'Failed (will retry)',
+			'failed': 'Failed',
 			'failed_permanent': 'Failed permanently'
 		};
-		return labels[status] || status;
+		return labels[status];
 	}
-
-	getItemMessage(item) {
-		if (item.message) return item.message;
-		if (item.error_message) return item.error_message;
+	itemMessage(item) {
+		if (Object.hasOwn(item, 'message') && item.message !== '') return item.message;
+		if (Object.hasOwn(item, 'error_message') && item.error_message) return item.error_message;
 
 		switch(item.status) {
 			case 'queued':
@@ -727,198 +829,17 @@
 				return '';
 		}
 	}
-
-	calculateProgress(item) {
-		if (item.progress) return item.progress;
-
-		// Estimate progress based on status
-		const statusProgress = {
-			'queued': 10,
-			'uploading': 25,
-			'pending': 40,
-			'processing': 70,
-			'completed': 100,
-			'failed': 0,
-			'failed_permanent': 0
-		};
-
-		return statusProgress[item.status] || 0;
+	toggleQueue(on = true) {
+		this.ui.panel.hidden = !on;
+		this.ui.toggle.button.hidden = !on;
 	}
-
-
-	renderOperations() {
-		if (!this.ui.itemsContainer) return;
-
-		const operations = this.store.getFiltered();
-
-		// Clear container
-		window.removeChildren(this.ui.itemsContainer);
-
-		// Render operations or empty state
-		if (operations.length === 0) {
-			let empty = window.getTemplate('emptyQueue');
-			this.ui.itemsContainer.append(empty);
-			this.a11y.announce('Nothing queued.');
-		} else {
-			operations.forEach(op => {
-				const element = this.createOperationUI(op);
-				this.ui.itemsContainer.append(element);
-			});
-		}
+	setProcessing(on = true) {
+		this.isProcessing = on;
+		this.ui.toggle.button.classList.toggle('saving', on);
 	}
-
-	createOperationUI(operation) {
-		const listItem = window.getTemplate('queueItem');
-		listItem.dataset.id = operation.id;
-
-		this.updateOperationUI(operation, listItem);
-		return listItem;
-	}
-
-	updateOperationUI(item, element = null) {
-		if (!element) {
-			element = this.ui.itemsContainer?.querySelector(`[data-id="${item.id}"]`);
-		}
-		if (!element) {
-			element = this.createOperationUI(item);
-		}
-
-		// Remove old status classes
-		this.statuses.forEach(status => element.classList.remove(status));
-		element.classList.add(item.status);
-
-		// Update content
-		let timeDisplay = '';
-
-		if (item.updated_at) {
-			// Server now sends ISO format timestamps - much more reliable!
-			timeDisplay = window.formatTimeAgo(new Date(item.updated_at));
-		} else if (item.created_at) {
-			timeDisplay = window.formatTimeAgo(new Date(item.created_at));
-		}
-		const progressPercent = this.calculateProgress(item);
-
-		// Update text content safely
-		const typeEl = element.querySelector('.type');
-		const statusEl = element.querySelector('.status');
-		const detailsEl = element.querySelector('.info .details');
-		const timeEl = element.querySelector('.info .time');
-		const progressFill = element.querySelector('.progress .fill');
-
-		if (typeEl) typeEl.textContent = item.title;
-		if (statusEl)  {
-			statusEl.querySelector('.icon')?.remove();
-			let status = this.getStatusLabel(item.status);
-			statusEl.title = status;
-			statusEl.prepend(window.getIcon(this.icons[item.status]));
-			statusEl.querySelector('span').textContent = status;
-		}
-		if (detailsEl) detailsEl.textContent = this.getItemMessage(item);
-		if (timeEl) timeEl.textContent = timeDisplay;
-		if (progressFill) progressFill.style.width = `${progressPercent}%`;
-
-		// Update action buttons
-		const actionsContainer = element.querySelector('.actions');
-		if (actionsContainer) {
-			this.updateActionButtons(item, actionsContainer);
-		}
-	}
-
-	updateActionButtons(item, container) {
-		window.removeChildren(container);
-
-		switch (item.status) {
-			case 'queued':
-			case 'localProcessing':
-			case 'pending':
-				// Show cancel button for in-progress items
-				const cancelBtn = window.getTemplate('button');
-				cancelBtn.classList.add('cancel');
-				cancelBtn.dataset.action = 'cancel';
-				cancelBtn.textContent = 'Cancel';
-				container.appendChild(cancelBtn);
-				break;
-
-			case 'failed':
-			case 'failed_permanent':
-				// Show retry and dismiss buttons
-				const retryBtn = window.getTemplate('button');
-				const dismissBtn = window.getTemplate('button');
-
-				retryBtn.classList.add('retry');
-				retryBtn.textContent = 'Retry';
-				retryBtn.disabled = item.retries >= this.maxRetries;
-				retryBtn.dataset.action = 'retry';
-
-				dismissBtn.classList.add('dismiss');
-				dismissBtn.textContent = 'Dismiss';
-				dismissBtn.dataset.action = 'dismiss';
-
-				container.appendChild(retryBtn);
-				container.appendChild(dismissBtn);
-				break;
-
-			case 'completed':
-				// Show dismiss button only
-				const dismissCompletedBtn = window.getTemplate('button');
-				dismissCompletedBtn.dataset.action = 'dismiss';
-				dismissCompletedBtn.classList.add('dismiss');
-				dismissCompletedBtn.textContent = 'Dismiss';
-				container.appendChild(dismissCompletedBtn);
-				break;
-		}
-	}
-
-	removeOperationFromUI(operationId) {
-		const element = this.ui.itemsContainer?.querySelector(`[data-id="${operationId}"]`);
-		if (element) {
-			element.style.opacity = '0';
-			element.style.transform = 'scale(0.9)';
-			setTimeout(() => element.remove(), 300);
-		}
-	}
-
-	updateStatusPanel(status) {
-		this.ui.panel?.classList.remove(...this.classes);
-		if (!this.classes.includes(status)) {
-			return;
-		}
-		this.ui.panel?.classList.add(status);
-	}
-
-	/***************************************************
-	 FILTERS
-	 **************************************************/
-	setFilter(filter) {
-		// Update active button
-		Object.values(this.ui.filters).forEach(button => {
-			if (button) {
-				button.classList.toggle('active', button.dataset.filter === filter);
-			}
-		});
-
-		if (filter === 'all') {
-			this.store.clearFilters();
-		} else {
-			this.store.setFilter('status', filter);
-		}
-	}
-
-	/**************************************************************************
-	 HELPERS
-	**************************************************************************/
-	getOperationsByStatus(status, include = true) {
-
-		if (!Array.isArray(status) && typeof status === 'string') {
-			status = [status];
-		}
-		return (include)
-			? Array.from(this.store.data.values()).filter((item) => status.includes(item.status))
-			: Array.from(this.store.data.values()).filter((item) => !status.includes(item.status));
-	}
-	hasQueuedOperations() {
-		return this.getOperationsByStatus('queued').length > 0;
-	}
+	/****************************************************************************
+	 SUBSCRIPTION
+	 ****************************************************************************/
 	subscribe(callback) {
 		if (!this.subscribers) {
 			return;
@@ -930,26 +851,18 @@
 	notify(event, data) {
 		this.subscribers.forEach(cb => cb(event, data));
 	}
-
-	/**************************************************************************
+	/****************************************************************************
 	 CLEANUP
-	**************************************************************************/
+	 ****************************************************************************/
 	destroy() {
-		this.stopPolling();
+		if (this.isPolling) {
+			this.stopPolling();
+		}
 		this.stopActivityTracking();
-
-		if (this.clickHandler) {
-			document.removeEventListener('click', this.clickHandler);
-		}
-
-		if (this.keyHandler) {
-			document.removeEventListener('keydown', this.keyHandler);
-		}
-
+		document.removeEventListener('click', this.clickHandler);
 		this.subscribers.clear();
 	}
 }
-
 document.addEventListener('DOMContentLoaded', async function() {
 	window.auth.subscribe((event) => {
 		if (event === 'auth-loaded') {
diff --git a/assets/js/concise/QueueOld.js b/assets/js/concise/QueueOld.js
new file mode 100644
index 0000000..cee19eb
--- /dev/null
+++ b/assets/js/concise/QueueOld.js
@@ -0,0 +1,960 @@
+/**
+ * QueueManager
+ * Uses DataStore for persistent storage
+ */
+class QueueManager {
+	constructor(config = {}) {
+		this.canUpdateUI = true;
+		this.config = {
+			apiBase: jvbSettings.api,
+			maxRetries: 3,
+			pollInterval: 5000,
+			activityDelay: 2000, //2 seconds
+			autosync: true,
+			endpoint: 'queue',
+			...config
+		};
+
+		// Queue state
+		this.isProcessing = false;
+		this.isPolling = false;
+		this.queue = new Map();
+		this.subscribers = new Set();
+
+		// Status definitions
+		this.statuses = [
+			'queued',
+			'localProcessing',
+			'uploading',
+			'pending',
+			'processing',
+			'completed',
+			'failed',
+			'failed_permanent'
+		];
+
+		this.user = window.auth.getUser();
+
+		if (!this.user) {
+			console.log('Queue: User not logged in, queue disabled');
+			this.store = null;
+			this.canUpdateUI = false;
+			return;
+		}
+
+		this.headers = {
+			'X-WP-Nonce': window.auth.getNonce(),
+			...config.headers
+		};
+
+		this.a11y = window.jvbA11y;
+		this.errors = window.jvbError;
+
+		// Initialize DataStore for queue persistence
+		const store = window.jvbStore.register('queue', {
+			storeName: 'queue',
+			keyPath: 'id',
+			endpoint: this.config.endpoint,
+			TTL: Infinity,
+			indexes: [
+				{name: 'status', keyPath: 'status'},
+				{name: 'type', keyPath: 'type'},
+			],
+			showLoading: false,
+			delayFetch: false, // Queue should fetch immediately
+		});
+		this.store = store.queue;
+
+		this.classes = [
+			'offline',
+			'synced',
+			'pending'
+		];
+
+
+
+		// Initialize
+		this.initUI();
+		this.initListeners();
+		if (this.ui.panel) {
+			this.popup = new window.jvbPopup({
+				popup: this.ui.panel,
+				toggle: this.ui.toggle,
+				name: 'Queue Panel',
+			});
+		}
+		this.updateUI = () => window.debouncer.schedule('queue-ui-update', this._updateUI.bind(this), 100);
+		this.initQueue();
+	}
+
+	async initQueue() {
+		let polling = this.maybeStartPolling();
+		if (!polling) {
+			this.updateStatusPanel('synced');
+		}
+
+
+		this.store.subscribe((event, data) => {
+			switch (event) {
+				case 'data-loaded':
+				case 'items-saved':
+					this.maybeStartPolling();
+					this.updateUI();
+					break;
+				case 'item-saved':
+					console.log(data,'Item saved data');
+					if (data.previousItem && data.previousItem.status !== data.item.status) {
+						this.handleOperationStatusChange(data.item, data.previousItem.status);
+					}
+					this.maybeStartPolling();
+					break;
+				default:
+					this.updateUI();
+					break;
+			}
+
+		});
+	}
+
+	maybeStartPolling()
+	{
+		const incomplete = this.getOperationsByStatus(['completed', 'failed_permanent'], false);
+		if (incomplete.length > 0) {
+			this.startPolling();
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Handle operation status changes and notify subscribers
+	 */
+	handleOperationStatusChange(operation) {
+
+		// Notify based on new status
+		switch(operation.status) {
+			case 'completed':
+				console.log(operation);
+				this.notify('operation-completed', operation);
+				break;
+			case 'failed':
+				this.notify('operation-failed', operation);
+				break;
+			case 'failed_permanent':
+				this.notify('operation-failed-permanent', operation);
+				break;
+		}
+	}
+	/**
+	 *
+	 * @param {object} operation
+	 * @param {string} operation.endpoint The endpoint, excluding the apiBase
+	 * @param {object} operation.data The data to save
+	 * @param {boolean} operation.canMerge Whether data can merge
+	 * @param {string} operation.title The title of the operation for the Queue Panel
+	 * @param {string} operation.popup The string to show in the popup
+	 * @param {object} operation.headers Optional additional headers. Defaults to the API nonce
+	 *
+	 * @returns {string|null} Returns the operation id, for reference
+	 */
+	addToQueue(operation) {
+		const item = {
+			id: `u${this.user}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
+			endpoint: null,
+			method: 'POST',
+			headers: {},
+			data: {},
+			sendNow: false,				// true = process immediately
+			canMerge: true,
+			popup: 'Saving changes...',
+			title: 'Operation',
+			status: 'queued',
+			timestamp: Date.now(),
+			retries: 0,
+			user: this.user,
+			... operation
+		};
+
+		item.headers = {
+			...this.headers,
+			...item.headers
+		};
+
+		if (!item.endpoint || !item.data) {
+			console.error('Invalid operation queued: missing endpoint or data');
+			return null;
+		}
+
+		if (item.sendNow) {
+			this.processOperation(item).then(()=> {});
+			this.store.clearCache();
+			window.debouncer.schedule('fastQueue', this.startPolling.bind(this), 200);
+			this.showQueue();
+			return item.id;
+		}
+
+		const existingOps = Array.from(this.store.data.values()).filter(op=>
+			op.status === 'queued' &&
+			op.endpoint === item.endpoint &&
+			op.canMerge
+		);
+
+		if (existingOps.length > 0) {
+			const existing = existingOps[0];
+			existing.data = window.deepMerge(existing.data, item.data);
+			existing.timestamp = Date.now();
+
+			this.updateOperationStatus(existing.id, existing.status);
+			this.updateUI();
+
+			this.startActivityTracking();
+			return existing.id;
+		}
+
+		this.store.clearCache();
+
+		//Add new operation to DataStore
+		this.setQueue(item);
+
+		this.updateOperationStatus(item.id, item.status);
+		this.updateUI();
+
+		this.startActivityTracking();
+		return item.id;
+
+
+	}
+
+
+	setQueue(item) {
+		this.store.save(item);
+	}
+
+	updateOperationStatus(itemID, status) {
+		let item = this.store.get(itemID);
+		if (!item) return;
+
+		// Update status
+		item.status = status;
+
+		this.notify('operation-status', item);
+		this.updateOperationUI(item);
+	}
+
+	getQueue(itemID) {
+		return this.store.get(itemID);
+	}
+
+	clearQueue(itemID) {
+		this.store.delete(itemID);
+	}
+
+	startActivityTracking() {
+		if (!this.activityListeners) {
+			const activityEvents = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart'];
+			this.activityListeners = activityEvents.map(event => {
+				const handler = () => this.resetActivityTimer();
+				document.addEventListener(event, handler, {passive: true});
+				return {event, handler};
+			});
+		}
+		this.resetActivityTimer();
+	}
+
+	resetActivityTimer() {
+		if (this.activityTimer) {
+			clearTimeout(this.activityTimer);
+		}
+
+		this.activityTimer = setTimeout(() => {
+			this.processQueue();
+		}, this.config.activityDelay);
+	}
+
+	stopActivityTracking() {
+		if (this.activityTimer) {
+			clearTimeout(this.activityTimer);
+			this.activityTimer = null;
+		}
+		if (this.activityListeners) {
+			this.activityListeners.forEach(({event, handler}) => {
+				document.removeEventListener(event, handler);
+			});
+			this.activityListeners = null;
+		}
+	}
+
+	hideQueue(){
+		this.ui.panel.hidden = true;
+		this.ui.toggle.hidden = true;
+	}
+	showQueue() {
+		this.ui.panel.hidden = false;
+		this.ui.toggle.hidden = false;
+	}
+
+	setProcessing(on) {
+		this.isProcessing = on;
+		this.ui.toggle.classList.toggle('saving', on);
+	}
+	/**
+	 * Send any queued operations to the server
+	 * @returns {Promise<void>}
+	 */
+	async processQueue() {
+		if (this.isProcessing) return;
+
+		const queue = this.getOperationsByStatus('queued');
+
+		if (queue.length === 0) {
+			this.stopActivityTracking();
+			return;
+		}
+		this.setProcessing(true);
+
+		for (const operation of queue) {
+			await this.processOperation(operation);
+		}
+
+		this.setProcessing(false);
+		this.stopActivityTracking();
+
+		this.maybeStartPolling() ? this.showQueue() : this.hideQueue();
+	}
+
+	async processOperation(operation, skip = false) {
+		try {
+			if (!skip) {
+				this.updateOperationStatus(operation.id, 'uploading');
+
+				if (operation.data?._isFormData) {
+					operation.data = await this.store.objectToFormData(operation.data);
+				}
+			}
+
+			const url = `${this.config.apiBase}${operation.endpoint}`;
+			let requestBody;
+
+			if (operation.data instanceof FormData) {
+				operation.data.append('id', operation.id);
+				operation.data.append('user', this.user);
+				requestBody = operation.data;
+			} else {
+				requestBody = JSON.stringify({
+					...operation.data,
+					id: operation.id,
+					user: this.user
+				});
+				operation.headers['Content-Type'] = 'application/json';
+			}
+			const response = await fetch(url, {
+				method: operation.method,
+				headers: operation.headers,
+				body: requestBody
+			});
+
+			const result = await response.json();
+			if (skip) {
+				operation.data = {};
+			}
+			if (response.ok && result.success !== false) {
+				// Handle server-side merge
+				if (result.id && operation.id !== result.id) {
+					operation = await this.handleServerMerge(operation, result);
+				} else {
+					operation.status = result.status || 'pending';
+					operation.serverData = result;
+					this.updateOperationStatus(operation.id, operation.status);
+				}
+
+				this.a11y.announce(`${operation.title} sent to server for processing.`);
+
+			} else {
+				throw new Error(result.message || `HTTP ${response.status}`);
+			}
+		} catch (error) {
+			console.error('Operation failed:', error);
+
+			operation.retries++;
+			operation.lastError = error.message;
+
+			if (operation.retries >= this.config.maxRetries) {
+				operation.status = 'failed_permanent';
+			} else {
+				operation.status = 'failed';
+				operation.nextRetry = Date.now() + (Math.pow(2, operation.retries) * 1000);
+			}
+			this.updateOperationStatus(operation.id, operation.status);
+
+			this.setQueue(operation);
+		}
+	}
+
+	async handleServerMerge(operation, result) {
+		const existingOp = this.getQueue(result.id);
+
+		if (existingOp) {
+			// Merge with existing local operation
+			existingOp.data = window.deepMerge(existingOp.data, operation.data);
+			existingOp.status = result.status || 'pending';
+			existingOp.serverData = result;
+			this.updateOperationStatus(existingOp.id, existingOp.status);
+			this.removeOperationFromUI(operation.id);
+			this.clearQueue(operation.id);
+			return existingOp;
+		} else {
+			// Server merged with unknown operation
+			this.clearQueue(operation.id);
+			operation.id = result.id;
+			operation.status = result.status || 'pending';
+			operation.serverData = result;
+			this.updateOperationStatus(operation.id, operation.status);
+			return operation;
+		}
+	}
+
+	startPolling() {
+		if (this.isPolling) return;
+
+		this.isPolling = true;
+		this.updateStatusPanel('pending');
+
+		this.pollTimer = setInterval(async () => {
+			try {
+				this.store.clearCache();
+				await this.store.fetch(); // Fetches from server, updates store.data
+
+				if (!this.maybeStartPolling()) {
+					this.stopPolling();
+					this.updateStatusPanel('synced');
+				}
+			} catch (error) {
+				console.error('Polling error:', error);
+			}
+		}, this.config.pollInterval);
+	}
+
+	stopPolling() {
+		if (!this.isPolling) return;
+		this.isPolling = false;
+		if (this.pollTimer) {
+			clearInterval(this.pollTimer);
+			this.pollTimer = null;
+		}
+		if (this.countdownTimer) {
+			clearInterval(this.countdownTimer);
+			this.countdownTimer = null;
+		}
+	}
+	getOperationIds(operations) {
+		return operations.map(op => op.id);
+	}
+	/***********************************************************
+	USER ACTIONS
+	 ***********************************************************/
+
+	/**
+	 *
+	 * @param {array} ids
+	 * @param {string }action
+	 * @returns {Promise<void>}
+	 */
+	async updateServerOperations(ids, action) {
+		ids = Array.isArray(ids) ? ids : (ids.includes(',') ? ids.split(',') : [ids]);
+		ids = ids.filter(id => {
+			let item = this.getQueue(id);
+			return this.getAllowedActions(item.status).includes(action);
+		});
+
+		if (ids.length === 0) return;
+
+		// SINGLE place to handle UI removal
+		const shouldRemove = ['cancel', 'dismiss'].includes(action);
+		if (shouldRemove) {
+			ids.forEach(id => this.removeOperationFromUI(id));
+		}
+
+		try {
+			const response = await fetch(`${this.config.apiBase}${this.config.endpoint}`, {
+				method: 'POST',
+				headers: { 'Content-Type': 'application/json', ...this.headers },
+				body: JSON.stringify({ ids, action, user: window.auth.getUser() })
+			});
+
+			if (!response.ok) {
+				throw new Error(`${action} failed: ${response.status}`);
+			}
+
+			const result = await response.json();
+			if (!result.success) {
+				throw new Error(result.message || `${action} operation failed`);
+			}
+
+			// SINGLE place to handle store updates
+			ids.forEach(id => {
+				let item = this.getQueue(id);
+				this.notify(`${action}-operation`, item);
+
+				if (shouldRemove) {
+					this.clearQueue(id);
+				} else {
+					item.status = 'queued';
+					item.retries = 0;
+					this.setQueue(item);
+					this.updateOperationStatus(item.id, item.status);
+				}
+			});
+
+			if (action === 'retry') {
+				this.startActivityTracking();
+			}
+
+			this.updateUI();
+			return result;
+
+		} catch (error) {
+			// Log and let jvbError handle retry
+			await window.jvbError.log(error, {
+				component: 'QueueManager',
+				operation: 'performQueueAction',
+				action: action,
+				operationIds: ids,
+				itemCount: ids.length
+			}, () => this.updateServerOperations(ids, action));
+
+			// Don't re-throw - error is logged and handled
+			return { success: false, error: error.message };
+		}
+	}
+
+	getAllowedActions(status) {
+		const actionMap = {
+			'queued': ['cancel'],
+			'localProcessing': ['cancel'],
+			'pending': ['cancel'],
+			'processing': [],
+			'completed': ['dismiss'],
+			'failed': ['retry', 'dismiss'],
+			'failed_permanent': ['dismiss']
+		};
+		return actionMap[status] || [];
+	}
+
+
+	/*********************************************
+	 LISTENERS
+	 *********************************************/
+	initListeners() {
+		this.clickHandler = this.handleClick.bind(this);
+
+		document.addEventListener('click', this.clickHandler);
+
+		this.handleOnline = () => {
+			this.updateStatusPanel();
+			if (this.hasQueuedOperations()) {
+				this.processQueue();
+			}
+		};
+		this.handleOffline = () => this.updateStatusPanel('offline');
+		this.handleBeforeUnload = (e) => {
+			if (this.isPolling || this.isProcessing) {
+				e.preventDefault();
+				return 'You have unsaved changes in the queue. Proceed?';
+			}
+		};
+
+		window.addEventListener('online', this.handleOnline);
+		window.addEventListener('offline', this.handleOffline);
+		window.addEventListener('beforeunload', this.handleBeforeUnload);
+	}
+	handleClick(e) {
+		if (!e.target.closest(this.selectors.panel, this.selectors.toggle)) {
+			return;
+		}
+		if (e.target.closest(this.selectors.refreshButton)) {
+			this.store.clearCache();
+			this.store.clearCache(); // Clear cached headers first
+			this.store.fetch();
+		} else if (e.target.closest(this.selectors.clearButton)) {
+			const completedOps = this.getOperationIds(this.getOperationsByStatus('completed'));
+			if (completedOps.length > 0) {
+				this.updateServerOperations(completedOps, 'dismiss');
+			}
+		} else if (e.target.closest(this.selectors.retryButton)) {
+			const failedOps = this.getOperationIds(this.getOperationsByStatus('failed'));
+			if (failedOps.length > 0) {
+				this.updateServerOperations(failedOps, 'retry');
+			}
+		} else if (e.target.closest('[data-action]')) {
+			const button = e.target.closest('[data-action]');
+			const operationId = button.closest('[data-id]')?.dataset.id;
+			if (operationId) {
+				this.updateServerOperations(operationId, button.dataset.action);
+			}
+		} else if (e.target.closest('.filters [data-filter]')) {
+			const filter = e.target.closest('[data-filter]').dataset.filter;
+			this.setFilter(filter);
+		}
+
+	}
+
+	/*********************************************
+	UI
+	 *********************************************/
+	initUI() {
+		this.icons = {
+			queued: 'arrows-clockwise', localProcessing: 'arrows-clockwise', uploading: 'syncing',
+			pending: 'cloud', processing: 'syncing', completed: 'cloud-check',
+			failed: 'cloud-warning', failed_permanent: 'cloud-warning'
+		};
+
+		this.selectors = {
+			panel: 'aside#queue',
+			toggle: 'button.qtoggle',
+			refreshButton: 'button.refreshNow',
+			countdown: '.countdown',
+			indicator: '.qtoggle .indicator',
+			count: '.qtoggle .count',
+			popup: '.popup',
+			itemsContainer: '.qitems',
+			clearButton: '.dismiss-all',
+			retryButton: '.retry-all',
+			filters: {
+				all: '.filters [data-filter="all"]',
+				received: '.filters [data-filter="queued"]',
+				localProcessing: '.filters [data-filter="localProcessing"]',
+				uploading: '.filters [data-filter="uploading"]',
+				pending: '.filters [data-filter="pending"]',
+				processing: '.filters [data-filter="processing"]',
+				completed: '.filters [data-filter="completed"]',
+				failed: '.filters [data-filter="failed"]',
+			}
+		};
+
+		this.ui = window.uiFromSelectors(this.selectors);
+		if (!this.ui.panel) {
+			this.canUpdateUI = false;
+		}
+	}
+
+	_updateUI() {
+		if (!this.canUpdateUI) {
+			return;
+		}
+
+		// Get current operations from store
+		const operations = Array.from(this.store.data.values());
+
+		// Get stats from last fetch response (server-provided)
+		const stats = this.store.lastResponse?.queue_stats || {
+			queued: 0,
+			localProcessing: 0,
+			uploading: 0,
+			pending: 0,
+			processing: 0,
+			completed: 0,
+			failed: 0,
+			failed_permanent: 0
+		};
+
+		// Update count badge
+		if (this.ui.count) {
+			const activeCount = operations.length - stats.completed;
+			this.ui.count.textContent = activeCount > 0 ? activeCount : '';
+			this.ui.count.style.display = activeCount > 0 ? '' : 'none';
+		}
+
+		// Update indicator
+		if (this.ui.indicator) {
+			const hasActive = stats.queued > 0 || stats.uploading > 0 ||
+				stats.pending > 0 || stats.processing > 0;
+			this.ui.indicator.classList.toggle('active', hasActive);
+		}
+
+		// Update button states
+		this.ui.clearButton.disabled = this.getOperationsByStatus('completed').length === 0;
+		this.ui.retryButton.disabled = this.getOperationsByStatus('failed').length === 0 && this.getOperationsByStatus('failed_permanent').length === 0;
+
+		// Update filter counts (from server stats)
+		Object.entries(this.ui.filters).forEach(([status, button]) => {
+			const count = status === 'all'
+				? operations.length
+				: stats[status] || 0;
+			const countEl = button.querySelector('.count');
+			if (countEl) {
+				countEl.textContent = count > 0 ? count : '';
+			}
+			button.setAttribute('data-count', count);
+		});
+
+		// Render current operations
+		this.renderOperations();
+	}
+
+	getStatusLabel(status) {
+		const labels = {
+			'queued': 'Queued',
+			'localProcessing': 'Processing locally',
+			'uploading': 'Uploading',
+			'pending': 'Waiting on server',
+			'processing': 'Processing',
+			'completed': 'Completed',
+			'failed': 'Failed (will retry)',
+			'failed_permanent': 'Failed permanently'
+		};
+		return labels[status] || status;
+	}
+
+	getItemMessage(item) {
+		if (item.message) return item.message;
+		if (item.error_message) return item.error_message;
+
+		switch(item.status) {
+			case 'queued':
+				return 'Waiting to send...';
+			case 'uploading':
+				return 'Sending to server...';
+			case 'pending':
+				return item.position ? `Position ${item.position} in queue` : 'In server queue';
+			case 'processing':
+				return item.progress ? `${item.progress}% complete` : 'Processing...';
+			case 'completed':
+				return 'Successfully completed';
+			case 'failed':
+				return `Failed: ${item.lastError || 'Unknown error'} (Retry ${item.retries}/${this.config.maxRetries})`;
+			case 'failed_permanent':
+				return `Failed: ${item.lastError || 'Unknown error'}`;
+			default:
+				return '';
+		}
+	}
+
+	calculateProgress(item) {
+		if (item.progress) return item.progress;
+
+		// Estimate progress based on status
+		const statusProgress = {
+			'queued': 10,
+			'uploading': 25,
+			'pending': 40,
+			'processing': 70,
+			'completed': 100,
+			'failed': 0,
+			'failed_permanent': 0
+		};
+
+		return statusProgress[item.status] || 0;
+	}
+
+
+	renderOperations() {
+		if (!this.ui.itemsContainer) return;
+
+		const operations = this.store.getFiltered();
+
+		// Clear container
+		window.removeChildren(this.ui.itemsContainer);
+
+		// Render operations or empty state
+		if (operations.length === 0) {
+			let empty = window.getTemplate('emptyQueue');
+			this.ui.itemsContainer.append(empty);
+			this.a11y.announce('Nothing queued.');
+		} else {
+			operations.forEach(op => {
+				const element = this.createOperationUI(op);
+				this.ui.itemsContainer.prepend(element);
+			});
+		}
+	}
+
+	createOperationUI(operation) {
+		const listItem = window.getTemplate('queueItem');
+		listItem.dataset.id = operation.id;
+
+		this.updateOperationUI(operation, listItem);
+		return listItem;
+	}
+
+	updateOperationUI(item, element = null) {
+		if (!element) {
+			element = this.ui.itemsContainer?.querySelector(`[data-id="${item.id}"]`);
+		}
+		if (!element) {
+			element = this.createOperationUI(item);
+		}
+
+		// Remove old status classes
+		this.statuses.forEach(status => element.classList.remove(status));
+		element.classList.add(item.status);
+
+		// Update content
+		let timeDisplay = '';
+
+		if (item.updated_at) {
+			// Server now sends ISO format timestamps - much more reliable!
+			timeDisplay = window.formatTimeAgo(new Date(item.updated_at));
+		} else if (item.created_at) {
+			timeDisplay = window.formatTimeAgo(new Date(item.created_at));
+		}
+		const progressPercent = this.calculateProgress(item);
+
+		// Update text content safely
+		const typeEl = element.querySelector('.type');
+		const statusEl = element.querySelector('.status');
+		const detailsEl = element.querySelector('.info .details');
+		const timeEl = element.querySelector('.info .time');
+		const progressFill = element.querySelector('.progress .fill');
+
+		if (typeEl) typeEl.textContent = item.title;
+		if (statusEl)  {
+			statusEl.querySelector('.icon')?.remove();
+			let status = this.getStatusLabel(item.status);
+			statusEl.title = status;
+			statusEl.prepend(window.getIcon(this.icons[item.status]));
+			statusEl.querySelector('span').textContent = status;
+		}
+		if (detailsEl) detailsEl.textContent = this.getItemMessage(item);
+		if (timeEl) timeEl.textContent = timeDisplay;
+		if (progressFill) progressFill.style.width = `${progressPercent}%`;
+
+		// Update action buttons
+		const actionsContainer = element.querySelector('.actions');
+		if (actionsContainer) {
+			this.updateActionButtons(item, actionsContainer);
+		}
+	}
+
+	updateActionButtons(item, container) {
+		window.removeChildren(container);
+
+		switch (item.status) {
+			case 'queued':
+			case 'localProcessing':
+			case 'pending':
+				// Show cancel button for in-progress items
+				const cancelBtn = window.getTemplate('button');
+				cancelBtn.classList.add('cancel');
+				cancelBtn.dataset.action = 'cancel';
+				cancelBtn.textContent = 'Cancel';
+				container.appendChild(cancelBtn);
+				break;
+
+			case 'failed':
+			case 'failed_permanent':
+				// Show retry and dismiss buttons
+				const retryBtn = window.getTemplate('button');
+				const dismissBtn = window.getTemplate('button');
+
+				retryBtn.classList.add('retry');
+				retryBtn.textContent = 'Retry';
+				retryBtn.disabled = item.retries >= this.maxRetries;
+				retryBtn.dataset.action = 'retry';
+
+				dismissBtn.classList.add('dismiss');
+				dismissBtn.textContent = 'Dismiss';
+				dismissBtn.dataset.action = 'dismiss';
+
+				container.appendChild(retryBtn);
+				container.appendChild(dismissBtn);
+				break;
+
+			case 'completed':
+				// Show dismiss button only
+				const dismissCompletedBtn = window.getTemplate('button');
+				dismissCompletedBtn.dataset.action = 'dismiss';
+				dismissCompletedBtn.classList.add('dismiss');
+				dismissCompletedBtn.textContent = 'Dismiss';
+				container.appendChild(dismissCompletedBtn);
+				break;
+		}
+	}
+
+	removeOperationFromUI(operationId) {
+		const element = this.ui.itemsContainer?.querySelector(`[data-id="${operationId}"]`);
+		if (element) {
+			element.style.opacity = '0';
+			element.style.transform = 'scale(0.9)';
+			setTimeout(() => element.remove(), 300);
+		}
+	}
+
+	updateStatusPanel(status) {
+		this.ui.panel?.classList.remove(...this.classes);
+		if (!this.classes.includes(status)) {
+			return;
+		}
+		this.ui.panel?.classList.add(status);
+	}
+
+	/***************************************************
+	 FILTERS
+	 **************************************************/
+	setFilter(filter) {
+		// Update active button
+		Object.values(this.ui.filters).forEach(button => {
+			if (button) {
+				button.classList.toggle('active', button.dataset.filter === filter);
+			}
+		});
+
+		if (filter === 'all') {
+			this.store.clearFilters();
+		} else {
+			this.store.setFilter('status', filter);
+		}
+	}
+
+	/**************************************************************************
+	 HELPERS
+	 **************************************************************************/
+	getOperationsByStatus(status, include = true) {
+
+		if (!Array.isArray(status) && typeof status === 'string') {
+			status = [status];
+		}
+		return (include)
+			? Array.from(this.store.data.values()).filter((item) => status.includes(item.status))
+			: Array.from(this.store.data.values()).filter((item) => !status.includes(item.status));
+	}
+	hasQueuedOperations() {
+		return this.getOperationsByStatus('queued').length > 0;
+	}
+	subscribe(callback) {
+		if (!this.subscribers) {
+			return;
+		}
+		this.subscribers.add(callback);
+		return () => this.subscribers.delete(callback);
+	}
+
+	notify(event, data) {
+		this.subscribers.forEach(cb => cb(event, data));
+	}
+
+	/**************************************************************************
+	 CLEANUP
+	 **************************************************************************/
+	destroy() {
+		this.stopPolling();
+		this.stopActivityTracking();
+
+		if (this.clickHandler) {
+			document.removeEventListener('click', this.clickHandler);
+		}
+
+		if (this.keyHandler) {
+			document.removeEventListener('keydown', this.keyHandler);
+		}
+
+		this.subscribers.clear();
+	}
+}
+
+document.addEventListener('DOMContentLoaded', async function() {
+	window.auth.subscribe((event) => {
+		if (event === 'auth-loaded') {
+			window.jvbQueue = new QueueManager();
+		}
+	});
+});
diff --git a/assets/js/concise/TaxonomyCreator.js b/assets/js/concise/TaxonomyCreator.js
index b9adaf7..11281e3 100644
--- a/assets/js/concise/TaxonomyCreator.js
+++ b/assets/js/concise/TaxonomyCreator.js
@@ -13,9 +13,9 @@
 
 	initElements() {
 		this.selectors = {
-			details: 'details.create-new',
+			details: 'details.create-term',
 			parent: '#select_parent',
-			summary: '.create-new summary',
+			summary: '.create-term summary',
 			suggestion: '.term-suggestions',
 			name: '#term_name',
 			button: '.submit-term',
@@ -29,6 +29,23 @@
 		this.ui = window.uiFromSelectors(this.selectors, this.selector.container);
 	}
 
+	handleOpen(field) {
+		this.field = field;
+		if (this.ui.details) {
+			this.ui.details.hidden = !field.canCreate;
+
+			if (this.ui.summary) {
+				this.ui.summary.textContent = `Add new ${field.singular}`;
+			}
+			if (this.ui.label.name) {
+				this.ui.label.name.textContent = `Name this ${field.singular}`;
+			}
+			if (this.ui.label.parent) {
+				this.ui.label.parent.textContent = `Nest it under`;
+			}
+		}
+	}
+
 	/**
 	 * Initialize event listeners
 	 */
@@ -38,9 +55,10 @@
 
 		if (this.ui.form) {
 			this.ui.form.addEventListener('change', (e) => {
+				console.log('Creator form change, prevents default');
 				e.preventDefault();
 				e.stopPropagation();
-			})
+			});
 		}
 	}
 
@@ -54,54 +72,47 @@
 				this.ui.name?.focus();
 			}
 			this.resetParentOptions();
-		}
-
-		// Handle term creation submission
-		if (window.targetCheck(e, this.selectors.button)) {
-			this.handleTermCreation(e).then(() => {});
+			return;
 		}
 	}
 
 	/**
 	 * Handle term creation from modal form
 	 */
-	async handleTermCreation(e) {
-		let field = this.selector.currentField();
-		const taxonomy = field.taxonomy;
-		if (!taxonomy) return;
-
-		let data = {
-			parent: 0,
-			taxonomy: taxonomy
-		};
-		// If it's open, we can get the parent element and everything
-		if (this.selector.container.open) {
-			data.name = this.ui.name.value.trim();
-			data.parent = parseInt(this.ui.parent?.value??0);
-		} else if (this.selector.activeField) {
-			//It's autocomplete, so just the term name
-			data.name = this.selector.store.query;
-		}
-		if (!data.name || data.name.length < 2) return;
-
+	async handleTermCreation(data) {
+		if (!data.name || data.name.length < 2) return false;
 		try {
-			if (this.ui.button) {
-				this.ui.button.disabled = true;
-			}
-
 			const response = await this.createTerm(data);
 
+			if (!response.success) {
+				// Term already exists - still add it
+				if (response.term && response.term.id) {
+					this.selector.setMessage(true, `Using existing "${response.term.name}"`);
+					return response.term;
+				}
+
+				// Other failure
+				this.selector.setMessage(true, response.message || 'Creation failed', false);
+				return false;
+			}
+			if (response.term?.pending) {
+				// Term requires approval
+				this.selector.setMessage(
+					true,
+					`"${data.name}" submitted for approval`,
+					false
+				);
+				// Don't add to selection since it's pending
+				return false;
+			}
 			if (response.success && response.term) {
 				await this.handleSuccessfulCreation(response.term, data);
 				this.clearForm();
 			}
+			return response.term;
 		} catch (error) {
 			console.error('Error creating term:', error);
-			this.selector.handleError(error, 'handleTermCreation');
-		} finally {
-			if (this.ui.button) {
-				this.ui.button.disabled = false;
-			}
+			return false;
 		}
 	}
 
@@ -109,40 +120,12 @@
 	 * Handle successful term creation
 	 */
 	async handleSuccessfulCreation(term, data) {
-		const termPath = term.path || term.name;
 		// Close create form
 		this.ui.details.open = false;
 
 		// Clear cache to ensure fresh data
-		await this.selector.store.clearCache();
-
-		// Add to DataStore
-		this.selector.store.data.set(term.id, {
-			id: term.id,
-			name: term.name,
-			path: termPath,
-			taxonomy: data.taxonomy,
-			parent: data.parent,
-			count: 0,
-			hasChildren: false,
-			slug: term.slug || term.name.toLowerCase().replace(/\s+/g, '-')
-		});
-
-		// Add to modal selection
-		this.selector.addSelected(term.id,this.selector.activeField);
-
-		// Refresh current view if we're viewing the same parent
-		if (this.selector.container.open) {
-			const currentParent = this.selector.store.filters.parent || 0;
-			if (currentParent === data.parent) {
-				await this.selector.store.setFilters({
-					taxonomy: data.taxonomy,
-					parent: data.parent,
-					page: 1,
-					search: ''
-				});
-			}
-		}
+		this.selector.store.clearCache();
+		await this.selector.store.fetch();
 	}
 
 	/**
@@ -233,6 +216,9 @@
 		if (this.ui.name) {
 			this.ui.name.value = '';
 		}
+		if (this.selector.ui.search.input){
+			this.selector.ui.search.input.value = '';
+		}
 	}
 
 	/**
diff --git a/assets/js/concise/TaxonomySelector.js b/assets/js/concise/TaxonomySelector.js
index fcd9364..1d84d93 100644
--- a/assets/js/concise/TaxonomySelector.js
+++ b/assets/js/concise/TaxonomySelector.js
@@ -1,3 +1,4 @@
+
 class TaxonomySelector {
 	constructor() {
 		this.container = document.querySelector('dialog#jvb-selector');
@@ -9,11 +10,11 @@
 		this.subscribers = new Set();
 		this.fields = new Map();
 		this.selectedTerms = new Map();  // a map of fieldId => Set of selected term Ids
-		this.loadedTaxonomies = new Set(); // a set of taxonomies, to know whether we should preload a newly registered field
 		this.batchFetch = new Set();
 
 		this.activeField = null;
 		this.isInitializing = true;
+		this.messageText = {}
 		this.init();
 	}
 
@@ -67,10 +68,14 @@
 	initElements() {
 		this.selectors = {
 			search: {
-				input: '[type=search]',
+				input: '[type="search"]',
 				clear: '.clear-search',
 				container: '.search-wrapper',
-				results: '.search-results'
+				results: '.search-results',
+			},
+			create: {
+				button: 'button.submit-term',
+				span: '.submit-term span',
 			},
 			terms: {
 				list: '.items-container',
@@ -83,9 +88,9 @@
 				child: '.toggle-children',
 				pathLevel: '.path-level',
 			},
-			loading: {
-				loading: '.loading',
-				text: '.loading span',
+			message: {
+				message: 'p.message',
+				text: 'p.message span',
 			},
 			selected: '.selected-items',
 			modal: {
@@ -95,15 +100,26 @@
 			},
 			favourites: '.favourite-terms',
 			field: {
-				toggle: 'button.taxonomy-toggle',
+				toggle: 'button.taxonomy-toggle, [data-filter="taxonomy"]',
 				value: 'input[type="hidden"]',
 				selected: '.selected-items',
-				dropdown: '.search-results',
-				search: '[data-autocomplete]',
+				dropdown: {
+					list: '.search-results',
+					wrapper: '.auto-wrapper',
+				},
+				create: {
+					button: '.auto-wrapper .submit-term',
+					span: '.auto-wrapper button span',
+				},
+				search: 'input[data-autocomplete]',
+				message: {
+					message: 'p.message',
+					text: 'p.message span',
+				},
 			}
 		}
 
-		this.ui = window.uiFromSelectors(this.selectors);
+		this.ui = window.uiFromSelectors(this.selectors, this.container);
 	}
 
 	initListeners() {
@@ -132,41 +148,40 @@
 	}
 
 	handleClick(e) {
-		const fieldId = this.getFieldId(e.target);
+		const fieldId = this.getFieldId(e.target) || this.activeField;
 		const field = this.fields.get(fieldId);
 		if (!fieldId || !field) return;
 
-		const autoComplete = window.targetCheck(e, '[data-autocomplete-select]');
+		const autoComplete = window.targetCheck(e, '.item.autocomplete');
+
 		if (autoComplete) {
 			let termId = parseInt(autoComplete.dataset.id);
 			this.addSelected(termId, fieldId);
-			if (field.ui.dropdown) {
-				field.ui.dropdown.hidden = true;
-			}
-
+			this.scheduleHideDropdown(fieldId);
 			if (field.ui.search) {
 				field.ui.search.value = '';
 			}
 		}
 
-		const toggleButton = window.targetCheck(e, field.ui.toggle);
+		const toggleButton = window.targetCheck(e, this.selectors.field.toggle);
+
 		if (toggleButton) {
 			e.preventDefault();
 			this.openModal(fieldId);
 			return;
 		}
 
-		const removeButton = window.targetCheck(e, 'button.remove-item');
+		const removeButton = window.targetCheck(e, '.remove-term');
 		if (removeButton) {
-			const fieldId = this.getFieldId(removeButton);
-			const termId = removeButton.closest('.selected-item').dataset.id??false;
+			const termId = removeButton.closest('[data-id]').dataset.id??false;
 			if (fieldId && termId) {
-				this.removeSelected(termId, fieldId);
+				this.removeSelected(parseInt(termId), fieldId);
 			}
 			return;
 		}
 
 		if (e.target.matches('.modal-close')) {
+			this.updateFieldValue(fieldId);
 			this.modal?.handleClose();
 			return;
 		}
@@ -194,11 +209,10 @@
 			this.navigateTo(termId);
 		}
 
-		const dropdown = window.targetCheck(e, field.selectors.dropdown);
+		const dropdown = window.targetCheck(e, this.selectors.field.dropdown);
 		if (dropdown) {
 			// reset the timer for hiding the dropdown
 			this.scheduleHideDropdown(fieldId);
-			return;
 		}
 
 		const clearSearch = window.targetCheck(e, this.selectors.search.clear);
@@ -217,12 +231,19 @@
 			}
 		}
 
+		if (this.creator) {
+			let button = window.targetCheck(e, this.selectors.create.button);
+			if (button) {
+				this.maybeCreateTerm(e).then(()=>{});
+			}
+		}
+
 	}
 	handleChange(e) {
 		if (!this.container.contains(e.target)) {
 			return;
 		}
-		if (e.target.type !== 'checkbox') return;
+		if (!['checkbox', 'button'].includes(e.target.type)) return;
 		e.preventDefault();
 		e.stopPropagation();
 
@@ -240,29 +261,59 @@
 		if (!fieldId) return;
 		const field = this.fields.get(fieldId);
 		if (!field) return;
+		if (['checkbox', 'button'].includes(e.target.type)) return;
 
+		e.preventDefault();
+		e.stopPropagation();
+
+		//If it's the autocomplete field, we need to set the active field
 		if (!this.container.open) {
-			this.activeField = fieldId;
+			this.setField(fieldId);
 		}
 
-		const query = e.target.value.trim();
+		let query = e.target.value.trim();
+		this.setMessage(true, `Searching for "${query}" in ${field.plural??'items'}`);
 		window.debouncer.schedule(
 			`${fieldId}-search`,
 			async () => {
+				if (this.container.open) {
+					window.removeChildren(this.ui.terms.list);
+				}
 				await this.store.setFilters({
 					taxonomy: field.taxonomy,
 					search: query,
 					page: 1,
 					parent: query ? 0 : (this.store.filters.parent || 0)
 				});
-				if (this.container.open) {
-					window.removeChildren(this.ui.terms.list);
-				}
 			},
 			100
 		);
 	}
 
+	setField(fieldId) {
+		const field = this.fields.get(fieldId);
+		if (!field) {
+			console.error('No field found...');
+			return;
+		}
+		this.activeField = fieldId;
+		this.setMessage(true, `Loading ${field.plural}...`);
+		this.resetFilters({taxonomy: field.taxonomy});
+	}
+
+	resetFilters(filters) {
+		if (!Object.hasOwn(filters, 'taxonomy')) {
+			return;
+		}
+		filters = {
+			page: 1,
+			search: '',
+			parent: 0,
+			... filters
+		};
+		this.store.setFilters(filters);
+	}
+
 	handleFocus(e) {
 		const fieldId = this.getFieldId(e.target);
 		const field = this.fields.get(fieldId);
@@ -272,8 +323,7 @@
 		window.debouncer.cancel(`${fieldId}-search-results`);
 
 		if (!this.container.open){
-			this.activeField = fieldId;
-			this.preloadTaxonomy(field.taxonomy);
+			this.setField(fieldId);
 		}
 	}
 
@@ -282,7 +332,8 @@
 		const fieldId = this.getFieldId(e.target);
 		const field = this.fields.get(fieldId);
 		if (!fieldId || ! field) return;
-		if (!field.hasAutocomplete) return;
+		if (!field.hasAutocomplete || this.container.open) return;
+		if (e.relatedTarget && field.ui.dropdown.wrapper?.contains(e.relatedTarget)) return;
 
 		this.scheduleHideDropdown(fieldId);
 	}
@@ -294,8 +345,12 @@
 		window.debouncer.schedule(
 			`${fieldId}-search-results`,
 			() => {
-				this.activeField = null;
-				field.ui.dropdown.hidden = true;
+				if (!this.container.open) {
+					this.activeField = null;
+				}
+				if (field.ui.dropdown.wrapper) {
+					field.ui.dropdown.wrapper.hidden = true;
+				}
 			},
 			1500
 		);
@@ -312,13 +367,14 @@
 			this.container,
 			{
 				handleForm: false,
-				save: null,
 				open: null
 			}
 		);
 		this.modal.subscribe((event, data) => {
 			switch (event) {
-
+				case 'modal-close':
+					this.closeModal()
+					break;
 			}
 		});
 	}
@@ -338,42 +394,24 @@
 		const field = this.fields.get(fieldId);
 		if (!field) return;
 
-		this.activeField = fieldId;
-		this.ui.modal.title.textContent = `Select ${field.plural}`;
+		this.setField(fieldId);
+		this.ui.modal.title.textContent = (field.isFilter) ?`Filter by ${field.singular}` : `Select ${field.plural}`;
 		if (this.ui.search.container) {
 			this.ui.search.container.hidden = !field.canSearch;
 		}
-		if (this.ui.create.details) {
-			this.ui.create.details.hidden = !field.canCreate;
-
-			if (this.ui.create.summary) {
-				this.ui.create.summary.textContent = `Add new ${field.singular}`;
-			}
-			if (this.ui.create.label.name) {
-				this.ui.create.label.name.textContent = `Name this ${field.singular}`;
-			}
-			if (this.ui.create.label.parent) {
-				this.ui.create.label.parent.textContent = `Nest it under`;
-			}
+		if (this.creator) {
+			this.creator.handleOpen(field);
 		}
 		let message = `Opened ${field.singular} selection. Choose from checkboxes, or search to filter results.`;
 
+		window.removeChildren(this.ui.selected);
 		window.removeChildren(this.ui.terms.list);
 		this.modal.handleOpen();
-		this.setLoading();
-
-		this.store.setFilters({
-			taxonomy: field.taxonomy,
-			page: 1,
-			search: '',
-			parent: 0,
-		});
 
 		this.a11y.announce(message);
 	}
 
 	closeModal() {
-		this.modal.handleClose();
 		const field = this.fields.get(this.activeField);
 		if (!field) return;
 		this.observer.unobserve(this.ui.terms.sentinel);
@@ -394,7 +432,10 @@
 		const current = this.store.filters.parent;
 		if (current === 0) return;
 		let term = this.store.get(parseInt(current));
-		if (!term) return;
+		if (!term) {
+			this.navigateTo(0);
+			return;
+		}
 		let parent = term.parent;
 		this.navigateTo(parseInt(parent));
 	}
@@ -419,11 +460,17 @@
 	addTermToModal(termId) {
 		const term = this.store.get(termId);
 		if (!term) return;
+		const field = this.currentField();
+		if (!field) return;
+		if (this.ui.selected.querySelector(`[data-id="${termId}"]`)) return;
 
 		const item = window.getTemplate('selectedTerm');
+		if (!item) return;
+
 		item.dataset.id = termId;
-		item.querySelector('span').textContent = term.path;
-		item.querySelector('button').title = `Remove ${name}`;
+		item.dataset.taxonomy = field.taxonomy;
+		item.querySelector('.item-name').textContent = term.path;
+		item.querySelector('button').title = `Remove ${term.name}`;
 
 		this.ui.selected.append(item);
 	}
@@ -448,7 +495,7 @@
 
 	registerField(element, options = {}) {
 		let input = element.querySelector('input[type="hidden"]');
-		if (!input) {
+		if (!input && !Object.hasOwn(element.dataset, 'filter')) {
 			console.warn('TaxonomySelector: No hidden input found for field', element);
 			return;
 		}
@@ -460,11 +507,20 @@
 
 
 		let selectors = this.selectors.field;
-		let button = element.querySelector('button.taxonomy-toggle');
-		if (options.size === 0){
+		const isFilter = Object.hasOwn(element.dataset,'filter') && element.dataset.filter === 'taxonomy';
+		let button = (isFilter) ? element : element.querySelector('button.taxonomy-toggle');
+
+		if (Object.keys(options).length === 0){
 			if (!button) return;
-			options = button.dataset;
-			if (options.size === 0) return;
+			options = {
+				taxonomy: button.dataset.taxonomy,
+				single: button.dataset.single,
+				plural: button.dataset.plural,
+				search: Object.hasOwn(button.dataset, 'search'),
+				autocomplete: Object.hasOwn(button.dataset, 'autocomplete'),
+				creatable: Object.hasOwn(button.dataset, 'creatable')
+			};
+			if (Object.keys(options).length === 0) return;
 		} else if (Object.hasOwn(options, 'toggle')) {
 			button = document.querySelector(options.toggle);
 			selectors.toggle = options.toggle;
@@ -478,21 +534,38 @@
 			singular: options.single??'',
 			plural: options.plural??'',
 			name: element.dataset.field,
-			canSearch: Object.hasOwn(options, 'search'),
+			canSearch: options.search??false,
 			limit: options.limit??0,
-			hasAutocomplete: Object.hasOwn(options, 'autocomplete'),
-			canCreate: Object.hasOwn(options, 'creatable'),
-			isRequired: Object.hasOwn(options, 'required'),
+			hasAutocomplete: options.autocomplete??false,
+			canCreate: options.creatable??false,
+			isRequired: options.required??false,
+			isFilter: isFilter,
 			toggle: button,
+			create: {
+				button: null,
+				span: null
+			},
 			selectors: selectors,
 			ui: window.uiFromSelectors(selectors, element),
 			checked: false,
 		};
-		if (!config.taxonomy) return;
+
+		if (isFilter && !config.ui.toggle) {
+			config.ui.toggle = element;
+		}
+		if (!config.taxonomy) {
+			console.error('TaxonomySelector: Field missing taxonomy', element);
+			return;
+		}
+		if (!config.singular || !config.plural) {
+			console.warn('TaxonomySelector: Field missing singular/plural labels', element);
+			config.singular = config.taxonomy.replace('jvb_', '');
+			config.plural = config.singular + 's';
+		}
 		this.fields.set(fieldId, config);
 
 		//Check for stored selected terms in hidden input
-		this.setSelectedFromValue(input);
+		this.setSelectedFromValue(fieldId, input);
 
 
 		if (this.isInitializing) {
@@ -504,12 +577,19 @@
 	}
 
 	setSelectedFromValue(fieldId, input) {
+		if (!fieldId) return;
+		let field = this.fields.get(fieldId);
+		if (!field) return;
+		if (!input && !field.isFilter) return;
+
 		let selected = new Set();
-		input.value.value.trim()
-			.split(',')
-			.map(id => parseInt(id.trim()))
-			.filter(id => !isNaN(id))
-			.forEach(id => selected.add(id));
+		if (input) {
+			input.value.trim()
+				.split(',')
+				.map(id => parseInt(id.trim()))
+				.filter(id => !isNaN(id))
+				.forEach(id => selected.add(id));
+		}
 		this.selectedTerms.set(fieldId, selected);
 	}
 
@@ -524,8 +604,10 @@
 		if (field.limit !== 0 && selected.size >= field.limit) return;
 
 		selected.add(parseInt(termId));
+		if (!this.container.open && !field.isFilter) {
+			this.updateFieldValue(fieldId);
+		}
 		this.addTermToDisplay(termId, fieldId);
-		this.updateFieldValue(fieldId);
 		this.checkLimits(fieldId);
 	}
 	removeSelected(termId, fieldId = null) {
@@ -535,34 +617,42 @@
 		if (!field || !term) return;
 		this.selectedTerms.get(fieldId).delete(parseInt(termId));
 
-		const selectedItem = field.ui.selected.querySelector(`[data-i"${termId}"]`);
+		const selectedItem = (field.ui.selected) ? field.ui.selected.querySelector(`[data-id="${termId}"]`) : false;
 		if (selectedItem) selectedItem.remove();
 		if (this.container.open) {
-			let item = this.ui.selected.querySelector(`[data-id="${termId}"]`);
+			let item = (this.ui.selected) ? this.ui.selected.querySelector(`[data-id="${termId}"]`) : false;
 			if (item) item.remove();
+			let checkbox = this.ui.terms.list.querySelector(`[type=checkbox][data-id="${termId}"]`);
+			if (checkbox) {
+				checkbox.checked = false;
+			}
 		}
-		this.updateFieldValue(fieldId);
+		if (!this.container.open && !field.isFilter) {
+			this.updateFieldValue(fieldId);
+		}
+
 		this.checkLimits(fieldId);
 	}
 	updateFieldValue(fieldId) {
 		const field = this.fields.get(fieldId);
 		if (!field) return;
 		let selected = Array.from(this.selectedTerms.get(fieldId));
-		field.ui.value = selected.join(',');
+		field.ui.value.value = selected.join(',');
 	}
 
 	checkLimits(fieldId) {
 		if (!this.container.open) return;
 		const field = this.fields.get(fieldId);
-		if (!field || field.limit === 0) return;
+		if (!field || !field.isFilter || field.limit === 0) return;
 		const disabled = this.selectedTerms.get(fieldId).size >= field.limit;
 		this.setCheckboxes(disabled);
 	}
 
 	updateFieldFromInput(input) {
 		const fieldId = this.getFieldId(input);
+		if (!fieldId) return;
 		const field = this.fields.get(fieldId);
-		if (!fieldId || !field) return;
+		if(!field) return;
 
 		this.setSelectedFromValue(fieldId, input);
 		this.updateFieldUI(fieldId);
@@ -570,8 +660,8 @@
 
 	updateFieldUI(fieldId) {
 		const field = this.fields.get(fieldId);
-		let selected = this.selectedTerms.get(fieldId);
-		if (!field || selected.size === 0) return;
+		let selected = this.selectedTerms.get(fieldId)??new Set();
+		if (!field || field.isFilter || selected.size === 0) return;
 
 		Array.from(selected).forEach(termId => {
 			this.addTermToDisplay(termId, fieldId);
@@ -585,8 +675,8 @@
 			.some(term=>term.taxonomy === taxonomy);
 
 		fields.forEach(field => {
-			field.ui.toggle.disabled = !hasItems && !field.canCreate;
-			field.ui.toggle.title = !hasItems
+			field.toggle.disabled = !hasItems && !field.canCreate;
+			field.toggle.title = !hasItems
 				? `No ${field.singular} available`
 				: `Select ${field.plural}`;
 
@@ -594,11 +684,30 @@
 		});
 	}
 
-	showModalTerms(append = true, showPath = false) {
+	showModalTerms(showPath = false) {
+		const field = this.currentField();
 		const terms = this.store.getFiltered();
-		if (terms.size === 0) return;
-		if (!append) {
-			window.removeChildren(this.ui.terms.list);
+		if (terms.length === 0) {
+			if (this.store.filters.page??1 === 1) {
+				window.removeChildren(this.ui.terms.list);
+			}
+			this.setMessage(true, this.store.filters.search === ''
+				? `No matching ${field.plural}.`
+				: `No ${field.plural} found.`,
+				false);
+			if (this.ui.terms.sentinel) {
+				this.observer.unobserve(this.ui.terms.sentinel);
+			}
+		}
+
+		this.setCreateButton(true);
+
+		if (this.ui.terms.sentinel) {
+			if (this.store.lastResponse?.has_more) {
+				this.observer.observe(this.ui.terms.sentinel);
+			} else {
+				this.observer.unobserve(this.ui.terms.sentinel);
+			}
 		}
 
 		const currentParent = this.store.filters.parent??0;
@@ -611,10 +720,14 @@
 				... term
 			});
 			if (element) {
-				fragment.appendChild(element);
+				fragment.append(element);
 			}
 		});
 
+		if (terms.length > 0) {
+			this.setMessage(false);
+		}
+
 		this.ui.terms.list.append(fragment);
 	}
 	createTermElement(term) {
@@ -638,6 +751,7 @@
 		let limitReached = field.limit > 0 && this.selectedTerms.get(this.activeField).size >= field.limit;
 		if (checkbox && label && nameSpan) {
 			[
+				checkbox.dataset.id,
 				checkbox.id,
 				checkbox.name,
 				checkbox.value,
@@ -648,8 +762,9 @@
 				label.dataset.path,
 				nameSpan.textContent
 			] = [
+				term.id,
 				`${field.element.id}-${term.id}`,
-				`${field.container.id}-${field.taxonomy}-select`,
+				`${field.element.id}-${field.taxonomy}-select`,
 				term.id,
 				!isSelected && limitReached,
 				isSelected,
@@ -673,30 +788,28 @@
 	showAutocompleteTerms() {
 		const field = this.currentField();
 		const terms = this.currentTerms();
-		if (!field || terms.size ===0) return;
+		if (!field) return;
 
-		const dropdown = field.ui.dropdown;
+		const dropdown = field.ui.dropdown.list;
+		if (!dropdown) return;
+
 		window.removeChildren(dropdown);
 		if (terms.length === 0) {
-			this.showEmptyState(`No ${field.plural} found.`, dropdown);
+			this.setMessage(true, `No ${field.plural} found.`, false);
 		} else {
 			terms.forEach(term => {
 				const item = this.createAutocompleteTerm(term);
 				if (item) {
 					dropdown.append(item);
 				}
-			})
+			});
+			this.setMessage(false);
 		}
+		this.setCreateButton(true);
 
-		const query = field.ui.search?.value;
-		if (field.canCreate && query.length >= 2 && this.creator) {
-			const createButton = this.createTermButton(query);
-			if (createButton) {
-				dropdown.append(createButton);
-			}
+		if (field.ui.dropdown.wrapper) {
+			field.ui.dropdown.wrapper.hidden = false;
 		}
-
-		dropdown.hidden = false;
 	}
 	createAutocompleteTerm(term) {
 		const item = window.getTemplate('autocompleteItem');
@@ -704,6 +817,7 @@
 
 		item.dataset.id = term.id;
 		item.textContent = term.path || term.name;
+
 		return item;
 	}
 	/******************************************************************
@@ -714,7 +828,7 @@
 		const field = this.fields.get(fieldId);
 		if (!term || !field) return;
 		//if the term already exists in the selected items, bail early
-		if (field.ui.selected.querySelector(`[data-id="${termId}"]`)) return;
+		if (field.ui.selected && field.ui.selected.querySelector(`[data-id="${termId}"]`)) return;
 
 		const item = window.getTemplate('selectedTerm');
 		if (!item) return;
@@ -724,7 +838,9 @@
 		item.querySelector('.item-name').textContent = term.path;
 		item.querySelector('button').title = `Remove ${term.name}`;
 
-		field.ui.selected.append(item);
+		if (field.ui.selected) {
+			field.ui.selected.append(item);
+		}
 
 		if (this.container.open) {
 			this.addTermToModal(termId);
@@ -732,15 +848,6 @@
 			if (checkbox) checkbox.checked = true;
 		}
 	}
-	createTermButton(query) {
-		const button = window.getTemplate('autocompleteButton');
-		if(!button) return;
-
-		let queryEl = button.querySelector('span');
-		queryEl.textContent = `"${query}"`;
-
-		return button;
-	}
 
 	updateBreadcrumbs(termId) {
 		const nav = this.ui.nav.nav;
@@ -826,15 +933,22 @@
 	handleStoreEvent(event, data) {
 		const handlers = {
 			'data-loaded': () => this.handleDataLoaded(),
-			'filters-changed': () => this.handleFiltersChanged(),
+			'filters-changed': () => this.handleFiltersChanged(data),
 			'fetch-error': () => this.handleFetchError()
 		};
 
-		handlers[event]?.();
+		try {
+			handlers[event]?.(data);
+		} catch (error) {
+			console.error(`Error handling store event "${event}":`, error);
+			this.setMessage(true, 'An error occurred loading data', false);
+		}
 	}
 	handleDataLoaded() {
 		const taxonomy = this.store.filters.taxonomy;
-		if (taxonomy?.includes(',')) {
+
+		// Always update fields for loaded taxonomies (handles both single and batch)
+		if (taxonomy) {
 			const taxonomies = taxonomy.split(',').map(t => t.trim());
 			taxonomies.forEach(tax => this.updateFieldsForTaxonomy(tax));
 		}
@@ -845,63 +959,52 @@
 		}
 		if (this.activeField) {
 			this.showResults(true);
+			return;
 		}
+		this.setMessage(false);
 	}
 
 	showResults(isAutoComplete = false) {
-		this.setLoading(false);
+		this.setMessage(false);
 		const terms = this.store.getFiltered();
 		const filters = this.store.filters;
-		const response = this.store.lastResponse?.page || {};
 		const isSearch = filters.search && filters.search.length > 0;
-		const append = filters.page > 1;
-		const field = this.currentField();
 
 		this.notify('terms-loaded', {
 			terms,
 			filters
 		});
 
-		if (terms.length === 0) {
-			if (!append) {
-				this.showEmptyState(isSearch ? `No matching ${field.plural}.` : `No ${field.plural} available.`);
-			}
-			this.observer.unobserve(this.ui.terms.sentinel);
-		} else {
-			if (!isAutoComplete) {
-				this.showModalTerms(append, isSearch);
 
-				if (response.has_more) {
-					this.observer.observe(this.ui.terms.sentinel);
-				} else {
-					this.observer.unobserve(this.ui.terms.sentinel);
-				}
-			} else {
-				this.showAutocompleteTerms()
-			}
+		if (isAutoComplete) {
+			this.showAutocompleteTerms();
+		} else {
+			this.showModalTerms(isSearch);
 		}
 
-		this.a11y.announce(terms.length, append);
+
+		this.a11y.announce(terms.length);
 	}
-	handleFiltersChanged() {
-		// if (this.modal?.open) {
-		// 	this.setLoading();
-		// }
+	handleFiltersChanged(data) {
+		//maybe do something?
 	}
 
 	handleFetchError(error) {
-		this.setLoading(false);
+		const field = this.currentField();
+		const message = field
+			? `Failed to load ${field.plural}`
+			: 'Failed to load data';
+
+		this.setMessage(true, message, false);
+		console.error('Store fetch error:', error);
 	}
 	async batchFetchTaxonomies() {
 		if (this.batchFetch.size === 0) return;
 
 		const taxonomies = Array.from(this.batchFetch);
-		taxonomies.forEach(tax => this.loadedTaxonomies.add(tax));
 		this.batchFetch.clear();
 
 		try {
-			taxonomies.forEach(tax => this.loadedTaxonomies.add(tax));
-
 			await this.store.setFilters({
 				taxonomy: taxonomies.join(','),
 				page: 1,
@@ -914,55 +1017,112 @@
 	}
 
 	preloadTaxonomy(taxonomy) {
-		if (this.loadedTaxonomies.has(taxonomy)) return;
-
 		this.store.setFilters( {
 			taxonomy: taxonomy,
 			page: 1,
 			search: '',
 			parent: 0
 		});
-
-		this.loadedTaxonomies.add(taxonomy);
 	}
 
 	/**************************************************
 	 LOADING
 	**************************************************/
-	setLoading(on = true) {
-		this.ui.loading.loading.hidden = on;
-		this.modal.classList.toggle('loading', on);
+	setCreateButton(show = true) {
+		const field = this.currentField();
+		if (!field || !field.canCreate || !this.creator) return;
 
-		if (on) {
-			let searchQuery = this.store.filters.search || '';
-			searchQuery = searchQuery === '' ? false : searchQuery;
-			const currentParent = this.store.filters.parent || 0;
-			const message = searchQuery
-				? `Searching for "${searchQuery} items` :
-				currentParent === 0
-					? 'loading items'
-					: 'loading child items';
+		const conf = (this.container.open) ? this.ui : field.ui;
+		if (!conf.create?.button || !conf.create?.span) return;
 
-			if (window.typeLoop && this.ui.loading.text) {
-				this.stopTyping = window.typeLoop(this.ui.loading.text, message);
-			} else {
-				this.ui.loading.text.textContenet = message;
-			}
-		} else {
-			if (this.stopTyping) {
-				this.stopTyping();
-				this.stopTyping = null;
-			}
+		const createButton = conf.create.button;
+		const buttonSpan = conf.create.span;
+		const input = (this.container.open) ? conf.search.input : conf.search;
+		if (!input) return;
+
+		let results = this.currentTerms()??[];
+		let matches = results.map(t => t.name);
+
+		let query = input.value;
+		const willShow = show && query.length >= 2 && !matches.includes(query);
+		createButton.hidden = !willShow;
+		if (willShow) {
+			buttonSpan.textContent = input.value??'';
 		}
 	}
-	showEmptyState(message = 'No items found.', container = null) {
-		if (!container) container = this.ui.terms.list;
-		const emptyElement = window.getTemplate('noTermResults');
-		const span = emptyElement.querySelector('span');
-		if (message && span) {
-			span.textContent = message;
+	async maybeCreateTerm(e) {
+		const field = this.currentField();
+		if (!field) return;
+
+		window.debouncer.cancel(`${field.id}-search-results`);
+		let data = {
+			taxonomy: field.taxonomy,
+			parent: this.store.filters.parent??0
 		}
-		container.append(emptyElement);
+		//If it's autocomplete or the selector's search input, we just need the name
+		if (!this.container.open || this.ui.search.input.value !== '') {
+			data.name = (this.container.open) ? this.ui.search.input.value : field.ui.search.value;
+		} else {
+			//Otherwise, we've created it from the details element
+			data.parent = this.creator.ui.parent.value??data.parent;
+			data.name = this.creator.ui.name.value??false;
+		}
+		if (data.parent !== undefined && data.name) {
+			this.setMessage(true, `Creating "${data.name}"...`);
+			this.setCreateButton(false);
+			if (this.container.open) {
+				window.removeChildren(this.ui.terms.list);
+			} else {
+				field.ui.search.disabled = true;
+				window.removeChildren(field.ui.dropdown.list);
+				if (field.ui.dropdown.wrapper) {
+					field.ui.dropdown.wrapper.hidden = false;
+				}
+			}
+			let term = await this.creator.handleTermCreation(data);
+			if (term) {
+				this.addSelected(term.id, field.id);
+			}
+			if (!this.container.open) {
+				field.ui.search.disabled = false;
+				field.ui.search.value = '';
+			}
+			this.scheduleHideDropdown(field.id);
+			this.setMessage(false);
+		}
+	}
+	setMessage(show = true, message = '', type = true) {
+		const field = this.currentField();
+		if (!field) return;
+
+		const conf = this.container.open||field.isFilter ? this.ui : (field.isFilter ? null : field.ui);
+		if (!conf?.message?.message) return;
+
+		message = (message === '') ? `No ${field.plural??'items'} found.` : message;
+
+		const p = conf.message.message;
+		const pText = conf.message.text;
+
+		p.hidden = !show;
+		if (show) {
+			if (message && pText) {
+				if (type && window.typeLoop && pText) {
+					if (this.messageText[field.id]) {
+						this.messageText[field.id]();
+						delete this.messageText[field.id];
+					}
+					this.messageText[field.id] = window.typeLoop(pText, message);
+				} else {
+					pText.textContent = message;
+				}
+
+			}
+		} else {
+			if (this.messageText[field.id]) {
+				this.messageText[field.id]();
+				delete this.messageText[field.id];
+			}
+		}
 	}
 	/**************************************************
 	 SUBSCRIBERS
@@ -984,16 +1144,49 @@
 	 CLEANUP
 	******************************************************/
 	destroy() {
+		// Cancel all debounced operations for this instance
+		this.fields.forEach((field, fieldId) => {
+			window.debouncer.cancel(`${fieldId}-search`);
+			window.debouncer.cancel(`${fieldId}-search-results`);
+		});
+
+		// Stop any typeLoop animations
+		Object.keys(this.messageText).forEach(key => {
+			if (this.messageText[key]) {
+				this.messageText[key]();
+			}
+		});
+		this.messageText = {};
+
+		// Disconnect observer
+		if (this.ui.terms?.sentinel) {
+			this.observer?.unobserve(this.ui.terms.sentinel);
+		}
+		this.observer?.disconnect();
+
+		// Remove event listeners
 		document.removeEventListener('click', this.clickHandler);
 		document.removeEventListener('change', this.changeHandler);
 		document.removeEventListener('input', this.inputHandler);
-		document.removeEventListener('focus', this.focusHandler);
-		document.removeEventListener('blur', this.blurHandler);
+		document.removeEventListener('focus', this.focusHandler, true);
+		document.removeEventListener('blur', this.blurHandler, true);
 
-		this.observer?.disconnect();
+		// Clear data structures
 		this.subscribers.clear();
 		this.fields.clear();
 		this.selectedTerms.clear();
+		this.batchFetch.clear();
+
+		// Cleanup creator if exists
+		if (this.creator) {
+			this.creator.destroy();
+			this.creator = null;
+		}
+
+		// Unsubscribe from store
+		if (this.store) {
+			this.store = null;
+		}
 	}
 }
 
diff --git a/assets/js/concise/UploadManager.js b/assets/js/concise/UploadManager.js
index 7301390..e743fa8 100644
--- a/assets/js/concise/UploadManager.js
+++ b/assets/js/concise/UploadManager.js
@@ -57,7 +57,8 @@
 		this.stores.uploads.subscribe(this.handleStores.bind(this, 'uploads'));
 		this.stores.groups.subscribe(this.handleStores.bind(this, 'groups'));
 		this.queue.subscribe((event, operation) => {
-			if (!['uploads', 'uploads/meta', 'uploads/groups'].includes(operation.endpoint)) {
+			console.log(event, operation);
+			if (!Object.hasOwn(operation, 'endpoint') || !['uploads', 'uploads/meta', 'uploads/groups'].includes(operation.endpoint)) {
 				return;
 			}
 
diff --git a/assets/js/concise/UtilityFunctions.js b/assets/js/concise/UtilityFunctions.js
index fe2f543..d80a661 100644
--- a/assets/js/concise/UtilityFunctions.js
+++ b/assets/js/concise/UtilityFunctions.js
@@ -389,17 +389,23 @@
  * @returns {Promise<unknown>}
  */
 window.typeText = function(container, text, speed = 50) {
-	container.classList.add('typeText');
 	return new Promise((resolve) => {
+		// Cancel any existing animation on this container
+		if (container._typeInterval) {
+			clearInterval(container._typeInterval);
+			delete container._typeInterval;
+		}
+
 		let index = 0;
 		container.textContent = '';
 
-		const interval = setInterval(() => {
+		container._typeInterval = setInterval(() => {
 			if (index < text.length) {
 				container.textContent += text.charAt(index);
 				index++;
 			} else {
-				clearInterval(interval);
+				clearInterval(container._typeInterval);
+				delete container._typeInterval;
 				resolve();
 			}
 		}, speed);
@@ -407,22 +413,29 @@
 }
 
 /**
- * Erases text like a keyboard would. TODO: erase a set word from existing text
+ * Erases text like a keyboard would.
  * @param container
  * @param speed
  * @returns {Promise<unknown>}
  */
 window.eraseText = function(container, speed = 10) {
 	return new Promise((resolve) => {
+		// Cancel any existing animation on this container
+		if (container._eraseInterval) {
+			clearInterval(container._eraseInterval);
+			delete container._eraseInterval;
+		}
+
 		let text = container.textContent;
 		let index = text.length;
 
-		const interval = setInterval(() => {
+		container._eraseInterval = setInterval(() => {
 			if (index > 0) {
 				index--;
 				container.textContent = text.substring(0, index);
 			} else {
-				clearInterval(interval);
+				clearInterval(container._eraseInterval);
+				delete container._eraseInterval;
 				resolve();
 			}
 		}, speed);
@@ -440,31 +453,47 @@
  * @returns {Function} - Call this function to stop the loop
  */
 window.typeLoop = function(container, text, typeSpeed = 50, eraseSpeed = 10, pauseAfterType = 1000, pauseAfterErase = 250) {
+	// Generate unique key for this container
+	const containerId = container.id || container.dataset.typeKey || `type-${Date.now()}`;
+	if (!container.dataset.typeKey) {
+		container.dataset.typeKey = containerId;
+	}
+
+	// Stop any existing loop immediately
+	if (container._stopTyping) {
+		container._stopTyping();
+	}
+
 	let isRunning = true;
 
 	async function loop() {
 		while (isRunning) {
-			// Type the text
 			await window.typeText(container, text, typeSpeed);
-
-			// Wait 1 second
+			if (!isRunning) break;
 			await new Promise(resolve => setTimeout(resolve, pauseAfterType));
-
-			// Erase the text
+			if (!isRunning) break;
 			await window.eraseText(container, eraseSpeed);
-
-			// Wait 0.25 seconds before next iteration
+			if (!isRunning) break;
 			await new Promise(resolve => setTimeout(resolve, pauseAfterErase));
 		}
 	}
 
-	// Start the loop
-	loop();
-
-	// Return a function to stop the loop
-	return function stopLoop() {
+	const stopLoop = function() {
 		isRunning = false;
+		if (container._typeInterval) {
+			clearInterval(container._typeInterval);
+			delete container._typeInterval;
+		}
+		if (container._eraseInterval) {
+			clearInterval(container._eraseInterval);
+			delete container._eraseInterval;
+		}
 	};
+
+	container._stopTyping = stopLoop;
+	loop(); // Start immediately
+
+	return stopLoop;
 };
 
 window.toCamelCase = function (string) {
diff --git a/assets/js/min/creator.min.js b/assets/js/min/creator.min.js
index a08c3d8..4d76819 100644
--- a/assets/js/min/creator.min.js
+++ b/assets/js/min/creator.min.js
@@ -1 +1 @@
-window.jvbTaxCreator=class{constructor(e){this.selector=e,this.queue=window.jvbQueue,this.initElements(),this.initListeners()}initElements(){this.selectors={details:"details.create-new",parent:"#select_parent",summary:".create-new summary",suggestion:".term-suggestions",name:"#term_name",button:".submit-term",form:"form.create-term",label:{name:'[for="term_name"]',parent:'[for="select_parent"]'},loading:".loading-message.create-term"},this.ui=window.uiFromSelectors(this.selectors,this.selector.container)}initListeners(){this.clickHandler=this.handleClick.bind(this),document.addEventListener("click",this.clickHandler),this.ui.form&&this.ui.form.addEventListener("change",(e=>{e.preventDefault(),e.stopPropagation()}))}handleClick(e){window.targetCheck(e,this.selectors.summary)&&(this.ui.details.open&&this.ui.name?.focus(),this.resetParentOptions()),window.targetCheck(e,this.selectors.button)&&this.handleTermCreation(e).then((()=>{}))}async handleTermCreation(e){const t=this.selector.currentField().taxonomy;if(!t)return;let r={parent:0,taxonomy:t};if(this.selector.container.open?(r.name=this.ui.name.value.trim(),r.parent=parseInt(this.ui.parent?.value??0)):this.selector.activeField&&(r.name=this.selector.store.query),r.name&&!(r.name.length<2))try{this.ui.button&&(this.ui.button.disabled=!0);const e=await this.createTerm(r);e.success&&e.term&&(await this.handleSuccessfulCreation(e.term,r),this.clearForm())}catch(e){console.error("Error creating term:",e),this.selector.handleError(e,"handleTermCreation")}finally{this.ui.button&&(this.ui.button.disabled=!1)}}async handleSuccessfulCreation(e,t){const r=e.path||e.name;this.ui.details.open=!1,await this.selector.store.clearCache(),this.selector.store.data.set(e.id,{id:e.id,name:e.name,path:r,taxonomy:t.taxonomy,parent:t.parent,count:0,hasChildren:!1,slug:e.slug||e.name.toLowerCase().replace(/\s+/g,"-")}),this.selector.addSelected(e.id,this.selector.activeField),this.selector.container.open&&(this.selector.store.filters.parent||0)===t.parent&&await this.selector.store.setFilters({taxonomy:t.taxonomy,parent:t.parent,page:1,search:""})}resetParentOptions(){const e=this.selector.currentField();if(!e)return;const t=e.taxonomy;if(!t)return;if(!this.ui.parent)return;let r=this.ui.parent.querySelector("option");if(!r)return;window.removeChildren(this.ui.parent),this.ui.parent.append(r.cloneNode(!0));const i=this.selector.store.filters.parent||0;if(0!==i){const e=this.selector.store.get(i);if(e){let t=r.cloneNode(!0);t.value=e.id,t.textContent=e.name,this.ui.parent.append(t)}}const n=[];this.selector.store.getFiltered().forEach((e=>{e.taxonomy===t&&e.parent===i&&n.push(e)})),n.sort(((e,t)=>e.name.localeCompare(t.name))),n.forEach((e=>{let t=r.cloneNode(!0);t.id=`select-parent-${e.id}`,t.value=e.id,t.textContent="  — "+e.name,this.ui.parent.append(t)}))}async createTerm(e){if(e.name&&void 0!==e.parent&&e.taxonomy)try{const t=await fetch(`${jvbSettings.api}terms`,{method:"POST",headers:{"Content-Type":"application/json","X-WP-Nonce":window.auth.getNonce()},body:JSON.stringify(e)});if(!t.ok)throw new Error(`Server error: ${t.status}`);return await t.json()}catch(e){throw console.error("Error creating term:",e),e}}clearForm(){this.ui.name&&(this.ui.name.value="")}destroy(){this.clickHandler&&document.removeEventListener("click",this.clickHandler),this.ui.loading&&(this.ui.loading.hidden=!0)}};
\ No newline at end of file
+window.jvbTaxCreator=class{constructor(e){this.selector=e,this.queue=window.jvbQueue,this.initElements(),this.initListeners()}initElements(){this.selectors={details:"details.create-term",parent:"#select_parent",summary:".create-term summary",suggestion:".term-suggestions",name:"#term_name",button:".submit-term",form:"form.create-term",label:{name:'[for="term_name"]',parent:'[for="select_parent"]'},loading:".loading-message.create-term"},this.ui=window.uiFromSelectors(this.selectors,this.selector.container)}handleOpen(e){this.field=e,this.ui.details&&(this.ui.details.hidden=!e.canCreate,this.ui.summary&&(this.ui.summary.textContent=`Add new ${e.singular}`),this.ui.label.name&&(this.ui.label.name.textContent=`Name this ${e.singular}`),this.ui.label.parent&&(this.ui.label.parent.textContent="Nest it under"))}initListeners(){this.clickHandler=this.handleClick.bind(this),document.addEventListener("click",this.clickHandler),this.ui.form&&this.ui.form.addEventListener("change",(e=>{console.log("Creator form change, prevents default"),e.preventDefault(),e.stopPropagation()}))}handleClick(e){if(window.targetCheck(e,this.selectors.summary))return this.ui.details.open&&this.ui.name?.focus(),void this.resetParentOptions()}async handleTermCreation(e){if(!e.name||e.name.length<2)return!1;try{const t=await this.createTerm(e);return t.success?t.term?.pending?(this.selector.setMessage(!0,`"${e.name}" submitted for approval`,!1),!1):(t.success&&t.term&&(await this.handleSuccessfulCreation(t.term,e),this.clearForm()),t.term):t.term&&t.term.id?(this.selector.setMessage(!0,`Using existing "${t.term.name}"`),t.term):(this.selector.setMessage(!0,t.message||"Creation failed",!1),!1)}catch(e){return console.error("Error creating term:",e),!1}}async handleSuccessfulCreation(e,t){this.ui.details.open=!1,this.selector.store.clearCache(),await this.selector.store.fetch()}resetParentOptions(){const e=this.selector.currentField();if(!e)return;const t=e.taxonomy;if(!t)return;if(!this.ui.parent)return;let i=this.ui.parent.querySelector("option");if(!i)return;window.removeChildren(this.ui.parent),this.ui.parent.append(i.cloneNode(!0));const r=this.selector.store.filters.parent||0;if(0!==r){const e=this.selector.store.get(r);if(e){let t=i.cloneNode(!0);t.value=e.id,t.textContent=e.name,this.ui.parent.append(t)}}const s=[];this.selector.store.getFiltered().forEach((e=>{e.taxonomy===t&&e.parent===r&&s.push(e)})),s.sort(((e,t)=>e.name.localeCompare(t.name))),s.forEach((e=>{let t=i.cloneNode(!0);t.id=`select-parent-${e.id}`,t.value=e.id,t.textContent="  — "+e.name,this.ui.parent.append(t)}))}async createTerm(e){if(e.name&&void 0!==e.parent&&e.taxonomy)try{const t=await fetch(`${jvbSettings.api}terms`,{method:"POST",headers:{"Content-Type":"application/json","X-WP-Nonce":window.auth.getNonce()},body:JSON.stringify(e)});if(!t.ok)throw new Error(`Server error: ${t.status}`);return await t.json()}catch(e){throw console.error("Error creating term:",e),e}}clearForm(){this.ui.name&&(this.ui.name.value=""),this.selector.ui.search.input&&(this.selector.ui.search.input.value="")}destroy(){this.clickHandler&&document.removeEventListener("click",this.clickHandler),this.ui.loading&&(this.ui.loading.hidden=!0)}};
\ No newline at end of file
diff --git a/assets/js/min/crud.min.js b/assets/js/min/crud.min.js
index 2a4768e..7f71379 100644
--- a/assets/js/min/crud.min.js
+++ b/assets/js/min/crud.min.js
@@ -1 +1 @@
-(()=>{class e{constructor(e){if(this.queue=window.jvbQueue,this.config=e,this.content=e.content||!1,this.settings=window.jvbUserSettings,this.a11y=window.jvbA11y,!this.content)return;this.isTimeline=!1,this.currentItemID=null,this.initElements(),this.updateBulkOptions();const t=window.jvbStore.register(this.content,{storeName:this.content,keyPath:"id",endpoint:"content",headers:{action_nonce:window.auth.getNonce("dash")},indexes:[{name:"id",keyPath:"id"},{name:"status",keyPath:"status"},{name:"date",keyPath:"date"},{name:"modified",keyPath:"modified"},{name:"title",keyPath:"title"}],filters:{content:this.content,user:window.auth.getUser(),page:1,status:"all",orderby:"modified",order:"desc"},TTL:18e5,showLoading:!0});this.store=t[this.content],this.status="all",this.filterTimeout=null,this.viewController=new window.jvbViews(this.ui.container,this.store),this.tableForm=null,this.tableChanges=new Map,this.formController=this.isTimeline?new window.jvbForm({collectFormData:()=>this.collectTimelineData.bind(this)}):new window.jvbForm,this.viewController.subscribe(((e,t)=>{if("table-view"!==e||this.tableForm){if("not-table-view"===e)this.tableForm;else if("order-changed"===e){let e=this.store.get(t);if(!e)return;let s={};s[t]=e,this.savePosts(s,"Updating progression order")}}else this.tableForm||(this.tableForm=this.formController.registerForm(t,{autosave:!1,formStatus:!1,isTable:!0}))})),this.formController.subscribe(((e,t)=>{switch(e){case"form-submit":case"form-autosave":this.handleFormChange(e,t)}})),this.queue.subscribe(((e,t)=>{Object.hasOwn(t,"endpoint")&&["content","uploads/groups"].includes(t.endpoint)&&("operation-completed"===e?this.handleQueueSuccess(e,t):"operation-failed-permanent"===e&&this.handleQueueFailure(e,t))})),this.initialized=!1,this.init()}handleFormChange(e,t){let s=t.fullData.post_title,i=Object.hasOwn(t,"changes")?t.changes:t.fullData,l={};if(this.isTimeline)return l[this.currentItemID]=i,void this.savePosts(l,s);let o=[];switch(!0){case t.config.element===this.ui.forms.edit:l[this.currentItemID]=i,s=`Saving ${s} Changes`,i.post_status&&this.shouldRemoveItem(i.post_status)&&o.push(this.currentItemID);break;case t.config.element===this.ui.forms.bulkEdit:let a=t.config.element.querySelectorAll(".selected input:checked");a.forEach((e=>{l[e.value]=i,i.post_status&&this.shouldRemoveItem(i.post_status)&&o.push(e.value)})),s=`Updating ${a.length} ${this.config.plural??"posts"} Changes`;break;case t.config.element===this.ui.forms.create:"form-submit"===e&&(l[t.config.data["form-id"]]=i,s=`Saving ${s} Changes`)}if(o.length>0){let e=0;o.forEach((t=>{setTimeout((()=>{const e=document.querySelector(`.item[data-id="${t}"]`);e&&window.fade(e,!1)}),e),e+=50})),t.config.element===this.ui.forms.bulkEdit&&setTimeout((()=>{this.viewController.clearSelection()}),e+100)}0!==Object.keys(l).length&&this.savePosts(l,s)}shouldRemoveItem(e){return"all"===this.status&&!["publish","draft"].includes(e)||e!==this.status}savePosts(e,t){if(0===Object.keys(e).length)return;for(let t in e)e[t].content||(e[t].content=this.content);let s={endpoint:"content",headers:{action_nonce:window.auth.getNonce("dash")},data:{posts:e},popup:"Saving changes",title:t};this.queue.addToQueue(s)}async handleQueueSuccess(e,t){this.store.clearCache(),this.store.fetch()}handleQueueFailure(e,t){console.error("Operation failed permanently:",t),this.a11y?.announce(`Operation failed: ${t.error_message||"Unknown error"}`)}initElements(){this.elements={modals:{create:"dialog.create",edit:"dialog.edit",bulkEdit:"dialog.bulkEdit"},container:".crud[data-content]",grid:".item-grid",bulkSelectActions:".bulk-action-select",forms:{create:"dialog.create form",edit:"dialog.edit form",bulkEdit:"dialog.bulkEdit form"},uploader:"details.uploader"},this.ui=window.uiFromSelectors(this.elements),this.ui.uploader&&(window.jvbUploads.scanFields(document.querySelector(this.elements.uploader)),window.jvbUploads.subscribe(((e,t)=>{"sent-to-queue"===e&&(console.log(t),t===this.ui.uploader.querySelector("[data-uploader]")?.dataset.uploader&&window.debouncer.schedule("crud-complete",(()=>{this.store.clearHttpHeaders()})))}))),this.isTimeline=!!document.querySelector("[data-timeline]")}init(){this.ui.uploader&&(this.settings.addSetting(this.ui.uploader,"open"),this.ui.uploader.addEventListener("toggle",(e=>{this.settings.saveSetting("open",this.ui.uploader.open?"on":"off")}))),this.filterHandler=this.handleFilterChange.bind(this),this.changeHandler=this.handleChange.bind(this),this.modals={};for(let[e,t]of Object.entries(this.ui.modals))this.modals[e]=new window.jvbModal(t),this.modals[e].subscribe(((t,s)=>{if("modal-close"===t)this.currentItemID=null,this.formController.cleanupForm(this.modals[e].modal.querySelector("form").dataset.formId)}));this.setupEventDelegation(),this.setupFilters(),this.initialized=!0}setupEventDelegation(){document.addEventListener("change",this.changeHandler),document.addEventListener("click",(e=>{const t=e.target.closest("[data-action]");if(t){e.preventDefault();const s=t.dataset.action,i=t.dataset.id;switch(s){case"edit":this.populateEditForm(i),this.modals.edit.handleOpen();break;case"delete":if(confirm("Delete this item?")){let e={};e[t.dataset.id]={post_status:"delete",content:this.content},window.fade(t.closest(".item"),!1),this.savePosts(e,`Sending ${this.singular} to trash...`),this.store.delete(i)}break;case"trash":let e={};e[t.dataset.id]={post_status:"trash",content:this.content},window.fade(t.closest(".item"),!1),this.savePosts(e,`Sending ${this.singular} to trash...`);break;case"create":this.modals.create.dataset.itemId="new",this.modals.create.dataset.content=this.content,this.modals.create.handleOpen();break;case"bulk-edit":Array.from(this.viewController.selectedItems).length>0&&this.modals.bulkEdit.handleOpen();break;case"bulk-delete":const s=Array.from(this.viewController.selectedItems);s.length>0&&confirm(`Delete ${s.length} items?`)&&(s.forEach((e=>this.store.delete(e))),this.viewController.clearSelection());break;case"sync":break;case"refresh":this.store.fetch()}}e.target.closest(".create-item")&&(this.formController.registerForm(this.ui.forms.create),this.modals.create.handleOpen()),e.target.closest(".cancel-bulk")&&this.viewController.selectAll(!1)})),document.addEventListener("keydown",(e=>{(e.ctrlKey||e.metaKey)&&"a"===e.key&&this.ui.container&&this.ui.container.contains(document.activeElement)&&(e.preventDefault(),this.viewController.selectAll()),"Escape"===e.key&&this.viewController?.selectedItems.size>0&&0===window.jvbModal.getAllModals().length&&this.viewController.clearSelection()}))}handleChange(e){if(e.target.closest("[data-id]"))this.isTimeline?this.handleTimelineTableChange(e):this.handleTableChange(e);else{if(e.target.classList.contains("bulk-action-select")){if(e.target.value.startsWith("tax-")){const t=e.target.value.replace("tax-","");return this.openTaxonomyModal(t),void(e.target.value="")}switch(e.target.value){case"edit":this.populateBulkEdit(),this.modals.bulkEdit.handleOpen();break;case"publish":this.setBulkStatus("publish");break;case"draft":case"restore":this.setBulkStatus("draft");break;case"trash":this.setBulkStatus("trash");break;case"delete":this.setBulkStatus("delete")}}window.targetCheck(e,"select[data-filter]")&&this.handleFilterChange(e)}}handleTableChange(e){const t=e.target.closest("tr[data-id]");if(!t)return;const s=e.target,i=parseInt(t.dataset.id),l=s.closest(["data-field"])?.dataset.field;if(!l)return;const o=this.store.get(i);if(!o)return;o.fields[l]=this.getInputValue(s),this.store.save(o);let a={};a[i]=o.fields,this.savePosts(a,`Saving changes to ${this.content}`)}handleTimelineTableChange(e){const t=e.target.closest("tbody[data-id]");if(!t)return;const s=e.target,i=s.closest("[data-field]")?.dataset.field;if(!i)return;const l=parseInt(t.dataset.id),o=s.closest("tr.timeline-point"),a=this.store.get(l);if(!a)return;const n=this.getInputValue(s);if(o){const e=o.dataset.imageId;a.fields.timeline||(a.fields.timeline={}),a.fields.timeline[e]||(a.fields.timeline[e]={}),a.fields.timeline[e][i]=n}else a.fields[i]=n;this.store.save(a);let r={};r[l]=a.fields,this.savePosts(r,"Updating progress post")}getInputValue(e){return"checkbox"===e.type?e.checked?e.value||"1":"":"radio"===e.type?e.checked?e.value:null:e.value}openTaxonomyModal(e){window.jvbSelector?window.jvbSelector.openForFilter(e,((e,t)=>this.handleBulkTaxonomy(e,t))):console.error("TaxonomySelector not initialized")}handleBulkTaxonomy(e,t){if(e.length>0){e=e.join(",");let s={},i=Array.from(this.viewController.selectedItems);i.forEach((i=>{s[i]={content:this.content},s[i][t]=e}));let l=`Adding ${i.length} ${this.config.plural??"posts"} to ${e.length} ${jvbSettings.labels[t].plural}`;this.viewController.clearSelection(),this.savePosts(s,l)}}setBulkStatus(e){if(!["publish","draft","trash","delete"].includes(e))return;let t,s={};for(let t of this.viewController.selectedItems)s[t]={post_status:e,content:this.content};if("delete"===e)t="Deleting";else t=window.uppercaseFirst(e)+"ing";if("all"===this.status&&!["publish","draft"].includes(e)||e!==this.status){let e=0;for(let t of this.viewController.selectedItems)setTimeout((()=>{const e=document.querySelector(`.item[data-id="${t}"]`);e&&window.fade(e,!1)}),e),e+=50}this.viewController.clearSelection(),0!==Object.keys(s).length&&this.savePosts(s,`${t} ${this.viewController.selectedItems.size} ${this.plural}...`)}handleFilterChange(e){let t=e.target;if("taxonomies"===t.dataset.filter){let e=t.dataset.taxonomy;this.store.setFilter(`tax_${e}`,t.value)}else this[t.dataset.filter]=t.value,this.store.setFilter(t.dataset.filter,t.value),"status"===t.dataset.filter&&this.updateBulkOptions(t.value)}updateBulkOptions(e="all"){if("trash"===e){if(this.ui.bulkSelectActions?.querySelector('[value="edit"]')){window.removeChildren(this.ui.bulkSelectActions),window.getTemplate("trashOptions").querySelectorAll("option").forEach(((e,t)=>{0===t&&(e.checked=!0),this.ui.bulkSelectActions.append(e)}))}}else if(this.ui.bulkSelectActions&&!this.ui.bulkSelectActions.querySelector('[value="edit"]')){window.removeChildren(this.ui.bulkSelectActions),window.getTemplate("notTrashOptions").querySelectorAll("option").forEach(((e,t)=>{this.ui.bulkSelectActions.append(e)}))}this.ui.bulkSelectActions&&(this.ui.bulkSelectActions.value="")}populateBulkEdit(){const e=this.modals.bulkEdit.modal.querySelector("form .selected");if(!e)return;window.removeChildren(e);for(let t of this.viewController.selectedItems){let s=this.store.get(t);const i=window.getTemplate("bulkItem");if(!i)return;const l=i.querySelector("input[type=checkbox]"),o=i.querySelector("img");l&&(l.id=`bulk_${s.id}`,l.value=s.id,l.checked=!0),o&&s.thumbnail&&(o.src=s.thumbnail,o.alt=s.alt||""),e.append(i)}let t=this.modals.bulkEdit.modal;[t.querySelector("h2 span").textContent]=[this.viewController.selectedItems.size],this.formController.registerForm(this.ui.forms.bulkEdit)}populateEditForm(e){this.currentItemID=e;let t=this.store.get(parseInt(e));if(t){this.ui.modals.edit.dataset.itemId=e,this.ui.modals.edit.dataset.content=this.content;let s=this.ui.modals.edit.querySelector("form");this.ui.modals.edit.querySelector("h2").textContent=`Editing ${t.fields.post_title}`,s.dataset.formId=`edit-${e}`,new window.jvbPopulate(s,t),this.formController.registerForm(this.ui.forms.edit)}}setupFilters(){const e=document.querySelector('input[type="search"]');if(e){let t;e.addEventListener("input",(()=>{e.value.length>3?(clearTimeout(t),t=setTimeout((()=>{this.store.setFilter("search",e.value)}),300)):0===e.value.length&&this.store.removeFilter("search")}))}}destroy(){document.querySelectorAll("[data-filter]").forEach((e=>{e.removeEventListener("change",this.filterHandler)}))}}document.addEventListener("DOMContentLoaded",(async function(){window.auth.subscribe((t=>{if("auth-loaded"===t){let t=document.querySelector("[data-content]");t&&!Object.hasOwn(t.dataset,"ignore")&&(window.crudManager=new e({content:t.dataset.content}))}}))}))})();
\ No newline at end of file
+(()=>{class e{constructor(e){if(this.queue=window.jvbQueue,this.config=e,this.content=e.content||!1,this.settings=window.jvbUserSettings,this.a11y=window.jvbA11y,!this.content)return;this.isTimeline=!1,this.currentItemID=null,this.initElements(),this.updateBulkOptions();const t=window.jvbStore.register(this.content,{storeName:this.content,keyPath:"id",endpoint:"content",headers:{action_nonce:window.auth.getNonce("dash")},indexes:[{name:"id",keyPath:"id"},{name:"status",keyPath:"status"},{name:"date",keyPath:"date"},{name:"modified",keyPath:"modified"},{name:"title",keyPath:"title"}],filters:{content:this.content,user:window.auth.getUser(),page:1,status:"all",orderby:"modified",order:"desc"},TTL:18e5,showLoading:!0});this.store=t[this.content],this.status="all",this.filterTimeout=null,this.viewController=new window.jvbViews(this.ui.container,this.store),this.tableForm=null,this.tableChanges=new Map,this.formController=this.isTimeline?new window.jvbForm({collectFormData:()=>this.collectTimelineData.bind(this)}):new window.jvbForm,this.viewController.subscribe(((e,t)=>{if("table-view"!==e||this.tableForm){if("not-table-view"===e)this.tableForm;else if("order-changed"===e){let e=this.store.get(t);if(!e)return;let s={};s[t]=e,this.savePosts(s,"Updating progression order")}}else this.tableForm||(this.tableForm=this.formController.registerForm(t,{autosave:!1,formStatus:!1,isTable:!0}))})),this.formController.subscribe(((e,t)=>{switch(e){case"form-submit":case"form-autosave":this.handleFormChange(e,t)}})),this.queue.subscribe(((e,t)=>{Object.hasOwn(t,"endpoint")&&["content","uploads/groups"].includes(t.endpoint)&&("operation-completed"===e?this.handleQueueSuccess(e,t):"operation-failed-permanent"===e&&this.handleQueueFailure(e,t))})),this.initialized=!1,this.init()}handleFormChange(e,t){let s=t.fullData.post_title,i=Object.hasOwn(t,"changes")?t.changes:t.fullData,l={};if(this.isTimeline)return l[this.currentItemID]=i,void this.savePosts(l,s);let o=[];switch(console.log(t),!0){case t.config.element===this.ui.forms.edit:l[this.currentItemID]=i,s=`Saving ${s} Changes`,i.post_status&&this.shouldRemoveItem(i.post_status)&&o.push(this.currentItemID);break;case t.config.element===this.ui.forms.bulkEdit:let a=t.config.element.querySelectorAll(".selected input:checked");a.forEach((e=>{l[e.value]=i,i.post_status&&this.shouldRemoveItem(i.post_status)&&o.push(e.value)})),s=`Updating ${a.length} ${this.config.plural??"posts"} Changes`;break;case t.config.element===this.ui.forms.create:"form-submit"===e&&(l[t.config.data["form-id"]]=i,s=`Saving ${s} Changes`)}if(o.length>0){let e=0;o.forEach((t=>{setTimeout((()=>{const e=document.querySelector(`.item[data-id="${t}"]`);e&&window.fade(e,!1)}),e),e+=50})),t.config.element===this.ui.forms.bulkEdit&&setTimeout((()=>{this.viewController.clearSelection()}),e+100)}0!==Object.keys(l).length&&this.savePosts(l,s)}shouldRemoveItem(e){return"all"===this.status&&!["publish","draft"].includes(e)||e!==this.status}savePosts(e,t){if(0===Object.keys(e).length)return;for(let t in e)e[t].content||(e[t].content=this.content);let s={endpoint:"content",headers:{action_nonce:window.auth.getNonce("dash")},data:{posts:e},delay:!0,popup:"Saving changes",title:t};this.queue.addToQueue(s)}async handleQueueSuccess(e,t){this.store.clearCache(),this.store.fetch()}handleQueueFailure(e,t){console.error("Operation failed permanently:",t),this.a11y?.announce(`Operation failed: ${t.error_message||"Unknown error"}`)}initElements(){this.elements={modals:{create:"dialog.create",edit:"dialog.edit",bulkEdit:"dialog.bulkEdit"},container:".crud[data-content]",grid:".item-grid",bulkSelectActions:".bulk-action-select",forms:{create:"dialog.create form",edit:"dialog.edit form",bulkEdit:"dialog.bulkEdit form"},uploader:"details.uploader"},this.ui=window.uiFromSelectors(this.elements),this.ui.uploader&&(window.jvbUploads.scanFields(document.querySelector(this.elements.uploader)),window.jvbUploads.subscribe(((e,t)=>{"sent-to-queue"===e&&(console.log(t),t===this.ui.uploader.querySelector("[data-uploader]")?.dataset.uploader&&window.debouncer.schedule("crud-complete",(()=>{this.store.clearCache()})))}))),this.isTimeline=!!document.querySelector("[data-timeline]")}init(){this.ui.uploader&&(this.settings.addSetting(this.ui.uploader,"open"),this.ui.uploader.addEventListener("toggle",(e=>{this.settings.saveSetting("open",this.ui.uploader.open?"on":"off")}))),this.filterHandler=this.handleFilterChange.bind(this),this.changeHandler=this.handleChange.bind(this),this.modals={};for(let[e,t]of Object.entries(this.ui.modals))this.modals[e]=new window.jvbModal(t),this.modals[e].subscribe(((t,s)=>{if("modal-close"===t)this.currentItemID=null,this.formController.cleanupForm(this.modals[e].modal.querySelector("form").dataset.formId)}));this.setupEventDelegation(),this.setupFilters(),this.initialized=!0}setupEventDelegation(){document.addEventListener("change",this.changeHandler),document.addEventListener("click",(e=>{const t=e.target.closest("[data-action]");if(t){e.preventDefault();const s=t.dataset.action,i=t.dataset.id;switch(s){case"edit":this.populateEditForm(i),this.modals.edit.handleOpen();break;case"delete":if(confirm("Delete this item?")){let e={};e[t.dataset.id]={post_status:"delete",content:this.content},window.fade(t.closest(".item"),!1),this.savePosts(e,`Sending ${this.singular} to trash...`),this.store.delete(i)}break;case"trash":let e={};e[t.dataset.id]={post_status:"trash",content:this.content},window.fade(t.closest(".item"),!1),this.savePosts(e,`Sending ${this.singular} to trash...`);break;case"create":this.modals.create.dataset.itemId="new",this.modals.create.dataset.content=this.content,this.modals.create.handleOpen();break;case"bulk-edit":Array.from(this.viewController.selectedItems).length>0&&this.modals.bulkEdit.handleOpen();break;case"bulk-delete":const s=Array.from(this.viewController.selectedItems);s.length>0&&confirm(`Delete ${s.length} items?`)&&(s.forEach((e=>this.store.delete(e))),this.viewController.clearSelection());break;case"sync":break;case"refresh":this.store.fetch()}}e.target.closest(".create-item")&&(this.formController.registerForm(this.ui.forms.create),this.modals.create.handleOpen()),e.target.closest(".cancel-bulk")&&this.viewController.selectAll(!1)})),document.addEventListener("keydown",(e=>{(e.ctrlKey||e.metaKey)&&"a"===e.key&&this.ui.container&&this.ui.container.contains(document.activeElement)&&(e.preventDefault(),this.viewController.selectAll()),"Escape"===e.key&&this.viewController?.selectedItems.size>0&&0===window.jvbModal.getAllModals().length&&this.viewController.clearSelection()}))}handleChange(e){if(e.target.closest("[data-id]"))this.isTimeline?this.handleTimelineTableChange(e):this.handleTableChange(e);else{if(e.target.classList.contains("bulk-action-select")){if(e.target.value.startsWith("tax-")){const t=e.target.value.replace("tax-","");return this.openTaxonomyModal(t),void(e.target.value="")}switch(e.target.value){case"edit":this.populateBulkEdit(),this.modals.bulkEdit.handleOpen();break;case"publish":this.setBulkStatus("publish");break;case"draft":case"restore":this.setBulkStatus("draft");break;case"trash":this.setBulkStatus("trash");break;case"delete":this.setBulkStatus("delete")}}window.targetCheck(e,"select[data-filter]")&&this.handleFilterChange(e)}}handleTableChange(e){const t=e.target.closest("tr[data-id]");if(!t)return;const s=e.target,i=parseInt(t.dataset.id),l=s.closest(["data-field"])?.dataset.field;if(!l)return;const o=this.store.get(i);if(!o)return;o.fields[l]=this.getInputValue(s),this.store.save(o);let a={};a[i]=o.fields,this.savePosts(a,`Saving changes to ${this.content}`)}handleTimelineTableChange(e){const t=e.target.closest("tbody[data-id]");if(!t)return;const s=e.target,i=s.closest("[data-field]")?.dataset.field;if(!i)return;const l=parseInt(t.dataset.id),o=s.closest("tr.timeline-point"),a=this.store.get(l);if(!a)return;const n=this.getInputValue(s);if(o){const e=o.dataset.imageId;a.fields.timeline||(a.fields.timeline={}),a.fields.timeline[e]||(a.fields.timeline[e]={}),a.fields.timeline[e][i]=n}else a.fields[i]=n;this.store.save(a);let r={};r[l]=a.fields,this.savePosts(r,"Updating progress post")}getInputValue(e){return"checkbox"===e.type?e.checked?e.value||"1":"":"radio"===e.type?e.checked?e.value:null:e.value}openTaxonomyModal(e){window.jvbSelector?window.jvbSelector.openForFilter(e,((e,t)=>this.handleBulkTaxonomy(e,t))):console.error("TaxonomySelector not initialized")}handleBulkTaxonomy(e,t){if(e.length>0){e=e.join(",");let s={},i=Array.from(this.viewController.selectedItems);i.forEach((i=>{s[i]={content:this.content},s[i][t]=e}));let l=`Adding ${i.length} ${this.config.plural??"posts"} to ${e.length} ${jvbSettings.labels[t].plural}`;this.viewController.clearSelection(),this.savePosts(s,l)}}setBulkStatus(e){if(!["publish","draft","trash","delete"].includes(e))return;let t,s={};for(let t of this.viewController.selectedItems)s[t]={post_status:e,content:this.content};if("delete"===e)t="Deleting";else t=window.uppercaseFirst(e)+"ing";if("all"===this.status&&!["publish","draft"].includes(e)||e!==this.status){let e=0;for(let t of this.viewController.selectedItems)setTimeout((()=>{const e=document.querySelector(`.item[data-id="${t}"]`);e&&window.fade(e,!1)}),e),e+=50}this.viewController.clearSelection(),0!==Object.keys(s).length&&this.savePosts(s,`${t} ${this.viewController.selectedItems.size} ${this.plural}...`)}handleFilterChange(e){let t=e.target;if("taxonomies"===t.dataset.filter){let e=t.dataset.taxonomy;this.store.setFilter(`tax_${e}`,t.value)}else this[t.dataset.filter]=t.value,this.store.setFilter(t.dataset.filter,t.value),"status"===t.dataset.filter&&this.updateBulkOptions(t.value)}updateBulkOptions(e="all"){if("trash"===e){if(this.ui.bulkSelectActions?.querySelector('[value="edit"]')){window.removeChildren(this.ui.bulkSelectActions),window.getTemplate("trashOptions").querySelectorAll("option").forEach(((e,t)=>{0===t&&(e.checked=!0),this.ui.bulkSelectActions.append(e)}))}}else if(this.ui.bulkSelectActions&&!this.ui.bulkSelectActions.querySelector('[value="edit"]')){window.removeChildren(this.ui.bulkSelectActions),window.getTemplate("notTrashOptions").querySelectorAll("option").forEach(((e,t)=>{this.ui.bulkSelectActions.append(e)}))}this.ui.bulkSelectActions&&(this.ui.bulkSelectActions.value="")}populateBulkEdit(){const e=this.modals.bulkEdit.modal.querySelector("form .selected");if(!e)return;window.removeChildren(e);for(let t of this.viewController.selectedItems){let s=this.store.get(t);const i=window.getTemplate("bulkItem");if(!i)return;const l=i.querySelector("input[type=checkbox]"),o=i.querySelector("img");l&&(l.id=`bulk_${s.id}`,l.value=s.id,l.checked=!0),o&&s.thumbnail&&(o.src=s.thumbnail,o.alt=s.alt||""),e.append(i)}let t=this.modals.bulkEdit.modal;[t.querySelector("h2 span").textContent]=[this.viewController.selectedItems.size],this.formController.registerForm(this.ui.forms.bulkEdit)}populateEditForm(e){this.currentItemID=e;let t=this.store.get(parseInt(e));if(t){this.ui.modals.edit.dataset.itemId=e,this.ui.modals.edit.dataset.content=this.content;let s=this.ui.modals.edit.querySelector("form");this.ui.modals.edit.querySelector("h2").textContent=`Editing ${t.fields.post_title}`,s.dataset.formId=`edit-${e}`,new window.jvbPopulate(s,t),this.formController.registerForm(this.ui.forms.edit)}}setupFilters(){const e=document.querySelector('.all-filters input[type="search"]');if(e){let t;e.addEventListener("input",(()=>{e.value.length>3?(clearTimeout(t),t=setTimeout((()=>{this.store.setFilter("search",e.value)}),300)):0===e.value.length&&this.store.removeFilter("search")}))}}destroy(){document.querySelectorAll("[data-filter]").forEach((e=>{e.removeEventListener("change",this.filterHandler)}))}}document.addEventListener("DOMContentLoaded",(async function(){window.auth.subscribe((t=>{if("auth-loaded"===t){let t=document.querySelector("[data-content]");t&&!Object.hasOwn(t.dataset,"ignore")&&(window.crudManager=new e({content:t.dataset.content}))}}))}))})();
\ No newline at end of file
diff --git a/assets/js/min/dataStore.min.js b/assets/js/min/dataStore.min.js
index ea47195..441b6ec 100644
--- a/assets/js/min/dataStore.min.js
+++ b/assets/js/min/dataStore.min.js
@@ -1 +1 @@
-(()=>{class e{constructor(){if(e.instance)return e.instance;e.instance=this,this.dbConfig=new Map,this.databases=new Map,this.stores=new Map,this.subscribers=new Map,this.pendingInits=new Map,this.fetchQueue=[],this._initialized=!1,this.body=document.body,this.loading=document.querySelector("dialog.loading"),this.init()}async init(){this._initialized||(this._initialized=!0,"indexedDB"in window||console.warn("IndexedDB not supported"))}register(e,t=[],s=1.1){if(Array.isArray(t)||(t=[t]),0===t.length)return;this.dbConfig.has(e)||this.dbConfig.set(e,{dbName:`jvb_${e}`,version:s,stores:{},_initialized:!1});let r=this.dbConfig.get(e);t.forEach((t=>{if(!t.storeName)throw new Error(`Store config for "${e}" missing storeName`);if(!t.keyPath)throw new Error(`Store "${t.storeName}" requires keyPath`);const s=`${e}_${t.storeName}`,i={config:{dbName:r.dbName,storeName:"items",keyPath:"id",indexes:[],endpoint:null,apiBase:jvbSettings.api,filters:{},required:null,TTL:36e5,useHttpCaching:!0,showLoading:!1,delayFetch:!0,validateData:!0,...t},dbKey:e,storeKey:s,data:new Map,cache:new Map,filters:{...t.filters||{}},isFetching:!1,currentRequest:null,lastResponse:null,_initialized:!1};i.config.headers={"X-WP-Nonce":window.auth.getNonce(),...i.config.headers},r.stores[t.storeName]=s,this.stores.set(s,i),this.subscribers.has(s)||this.subscribers.set(s,new Set)})),this.initDB(e).catch((t=>{console.error(`Failed to initialize store "${e}":`,t)}));const i={};for(const[e,t]of Object.entries(r.stores))i[e]=this.getStoreAPI(t);return i}getStoreAPI(e){const t={fetch:()=>this.fetch(e),save:t=>this.save(e,t),delete:t=>this.delete(e,t),get:t=>this.get(e,t),getAll:()=>this.getAll(e),getAllByIndex:(t,s)=>this.getAllByIndex(e,t,s),filterByIndex:t=>this.filterByIndex(e,t),getFiltered:()=>this.getFiltered(e),clear:()=>this.clear(e),setFilter:(t,s)=>this.setFilter(e,t,s),setFilters:t=>this.setFilters(e,t),removeFilter:t=>this.removeFilter(e,t),clearFilters:()=>this.clearFilters(e),clearCache:()=>this.clearCache(e),subscribe:t=>this.subscribe(e,t),ensureInitialized:()=>this.ensureStoreInitialized(e),get filters(){return{...t.getStore().filters}},get lastResponse(){return t.getStore().lastResponse},get data(){return t.getStore().data},getStore:()=>this.stores.get(e)};return t}formDataToObject(e){const t={_isFormData:!0,entries:{}};for(const[s,r]of e.entries())r instanceof File||r instanceof Blob||(t.entries[s]?(Array.isArray(t.entries[s])||(t.entries[s]=[t.entries[s]]),t.entries[s].push(r)):t.entries[s]=r);return t}async objectToFormData(e){if(!e._isFormData)return e;const t=new FormData;for(const[s,r]of Object.entries(e.entries))Array.isArray(r)?r.forEach((e=>t.append(s,e))):t.append(s,r);if(window.jvbUploads&&e.entries.upload_ids){const s=JSON.parse(e.entries.upload_ids);for(const e of s){const s=await window.jvbUploads.getBlobData(e);s&&t.append("files[]",s)}}return t}async initDB(e){const t=this.dbConfig.get(e);if(!t||t._initialized)return;if(this.pendingInits.has(e))return this.pendingInits.get(e);const s=this._performDBInit(e);this.pendingInits.set(e,s);try{await s,t._initialized=!0}finally{this.pendingInits.delete(e)}}async _performDBInit(e){const t=this.dbConfig.get(e),{dbName:s,version:r}=t,i=Object.values(t.stores);try{if(!this.databases.has(s)){const e=await this.openDatabase(s,r,(e=>{i.forEach((t=>{let s=this.stores.get(t);s&&this.setupStores(e,s.config)}))}));this.databases.set(s,e)}i.forEach((e=>{let t=this.stores.get(e);t&&(t.db=this.databases.get(s),t._initialized=!0,this.loadStoreDataInBackground(e),this.notify(e,"db-init"))}))}catch(t){throw console.error(`Failed to initialize database for store "${e}":`,t),t}}openDatabase(e,t,s){return new Promise(((r,i)=>{const a=indexedDB.open(e,t);a.onupgradeneeded=e=>{s&&s(e.target.result,e.oldVersion,e.newVersion)},a.onsuccess=e=>r(e.target.result),a.onerror=e=>i(e.target.error),a.onblocked=()=>{console.warn(`Database ${e} blocked. Close other tabs.`)}}))}setupStores(e,t){if(!e.objectStoreNames.contains(t.storeName)){const s=e.createObjectStore(t.storeName,{keyPath:t.keyPath});t.indexes.forEach((e=>{s.createIndex(e.name,e.keyPath||e.name,{unique:e.unique||!1})}))}if(t.endpoint&&!e.objectStoreNames.contains("cache")){e.createObjectStore("cache",{keyPath:"key"}).createIndex("timestamp","timestamp",{unique:!1})}}async loadFromObjectStore(e,t,s){const r=this.stores.get(e);return r?.db&&r.db.objectStoreNames.contains(t)?new Promise((e=>{const i=r.db.transaction([t],"readonly").objectStore(t).getAll();i.onsuccess=t=>{const r=t.target.result||[];r.forEach(s),e(r)},i.onerror=()=>e([])})):[]}loadStoreDataInBackground(e){const t=this.stores.get(e);t?.db&&Promise.all([this.loadFromObjectStore(e,t.config.storeName,(e=>{const s=this.getItemKey(e,t.config.keyPath);t.data.set(s,e)})),this.loadFromObjectStore(e,"cache",(e=>{this.isCacheValid(e,t.config.TTL)&&t.cache.set(e.key,e)}))]).then((()=>{this.notify(e,"data-ready"),t.config.endpoint&&t.config.delayFetch?(this.fetchQueue.push(e),1===this.fetchQueue.length&&this.processFetchQueue()):t.config.endpoint&&!t.config.delayFetch&&("requestIdleCallback"in window?requestIdleCallback((()=>this.fetch(e)),{timeout:2e3}):setTimeout((()=>this.fetch(e)),100))})).catch((t=>{console.error(`Background load error for store "${e}":`,t)}))}async processFetchQueue(){if(0===this.fetchQueue.length)return;const e=this.fetchQueue.shift();if(!this.stores.get(e))return this.processFetchQueue();try{await this.fetch(e)}catch(t){console.error(`Queue fetch error for "${e}":`,t)}this.fetchQueue.length>0&&("requestIdleCallback"in window?requestIdleCallback((()=>this.processFetchQueue()),{timeout:2e3}):setTimeout((()=>this.processFetchQueue()),50))}async ensureStoreInitialized(e){const t=this.stores.get(e);if(!t)throw new Error(`Store "${e}" not registered`);t._initialized||await this.initDB(t.dbKey)}async withTransaction(e,t,s,r){const i=this.stores.get(e);return i?.db?("string"==typeof t&&(t=[t]),new Promise(((e,a)=>{const o=i.db.transaction(t,s),n=t.map((e=>o.objectStore(e))),c=1===n.length?n[0]:n;let d;o.oncomplete=()=>e(d),o.onerror=()=>a(o.error);try{d=r(c,o)}catch(e){a(e)}}))):null}async fetch(e){await this.ensureStoreInitialized(e);const t=this.stores.get(e);if(!t.isFetching){if(t.config.required){if((Array.isArray(t.config.required)?t.config.required:[t.config.required]).some((e=>!t.filters[e]||""===t.filters[e])))return}t.isFetching=!0;try{const s=this.generateCacheKey(t.filters),r=t.cache.get(s);if(r&&this.isCacheValid(r,t.config.TTL))return this.notify(e,"data-loaded",{cached:!0,items:r.items||[]}),r;t.config.showLoading&&this.setLoading(!0);const i=this.buildFetchUrl(e),a={...t.config.headers};t.config.useHttpCaching&&r&&(r.etag&&(a["If-None-Match"]=r.etag),r.lastModified&&(a["If-Modified-Since"]=r.lastModified));const o=new AbortController;t.currentRequest=o;const n=await fetch(i,{method:"GET",headers:a,signal:o.signal});if(304===n.status)return r?(this.notify(e,"data-loaded",{cached:!0,notModified:!0,items:r.items||[]}),r):(this.notify(e,"data-loaded",{cached:!1,notModified:!0,items:[]}),t.lastResponse={has_more:!1,total:0,pages:1,queue_stats:{}},{items:[]});if(!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText}`);const c=await n.json();return await this.processFetchedData(e,c,s,n),this.notify(e,"data-loaded",{cached:!1,items:c.items||[]}),c}catch(t){throw"AbortError"!==t.name&&(console.error(`Fetch error for store "${e}":`,t),this.notify(e,"fetch-error",{error:t})),t}finally{t.isFetching=!1,t.currentRequest=null,t.config.showLoading&&this.setLoading(!1)}}}buildFetchUrl(e){const t=this.stores.get(e),s=new URLSearchParams;Object.entries(t.filters).forEach((([e,t])=>{null!=t&&""!==t&&("object"==typeof t?s.set(e,JSON.stringify(t)):s.set(e,t))}));const r=t.config.apiBase+t.config.endpoint;return s.toString()?`${r}?${s}`:r}async processFetchedData(e,t,s,r){const i=this.stores.get(e),a=t.items||[],o=[];i.db&&a.length>0&&await this.withTransaction(e,i.config.storeName,"readwrite",(t=>{a.forEach((s=>{try{const r=this._saveItem(e,s);o.push(r),t.put(r.processed)}catch(e){console.error("Error processing item:",e)}}))}));const n={key:s,items:a.map((e=>this.getItemKey(e,i.config.keyPath))),timestamp:Date.now(),endpoint:i.config.endpoint,filters:{...i.filters},etag:r.headers.get("ETag"),lastModified:r.headers.get("Last-Modified")};i.cache.set(s,n),i.db?.objectStoreNames.contains("cache")&&await this.withTransaction(e,"cache","readwrite",(e=>{e.put(n)})),i.lastResponse={...t,has_more:t.has_more||!1,total:t.total||a.length,pages:t.pages||1,queue_stats:t.queue_stats||{}},o.forEach((t=>{t.statusChanged&&this.notify(e,"item-saved",{item:t.item,key:t.key,previousItem:t.previousItem})}))}_saveItem(e,t){const s=this.stores.get(e),r=this.processForStorage(t,s.config.validateData);if(!r.valid)throw new Error(`Non-serializable data: ${r.error}`);const i=r.data,a=this.getItemKey(i,s.config.keyPath),o=s.data.get(a);return s.data.set(a,t),{item:t,previousItem:o,key:a,processed:i,statusChanged:o&&o.status!==t.status}}async save(e,t){const s=this.stores.get(e),r=this._saveItem(e,t);return await this.withTransaction(e,s.config.storeName,"readwrite",(e=>{e.put(r.processed)})),this.notify(e,"item-saved",{item:r.item,key:r.key,previousItem:r.previousItem}),r.key}processForStorage(e,t=!0,s="root"){if(null==e)return{valid:!0,data:e};const r=typeof e;if(["string","number","boolean"].includes(r))return{valid:!0,data:e};if("function"===r)return t?{valid:!1,error:`Function at ${s}`}:(console.debug(`[DataStore] Stripped function at ${s}`),{valid:!0,data:void 0});if(e instanceof HTMLElement||void 0!==e.nodeType)return t?{valid:!1,error:`DOM element at ${s}`}:(console.debug(`[DataStore] Stripped DOM element at ${s}`),{valid:!0,data:void 0});if(e instanceof FormData)return t?{valid:!1,error:`FormData at ${s}`}:(console.debug(`[DataStore] Converted FormData at ${s}`),{valid:!0,data:this.formDataToObject(e)});if(e instanceof Date||e instanceof ArrayBuffer||ArrayBuffer.isView(e)||e instanceof Blob)return{valid:!0,data:e};if(e instanceof Set)return this.processForStorage(Array.from(e),t,s);if(e instanceof Map&&(e=Object.fromEntries(e)),Array.isArray(e)){const r=[];for(let i=0;i<e.length;i++){const a=this.processForStorage(e[i],t,`${s}[${i}]`);if(!a.valid)return a;void 0!==a.data&&r.push(a.data)}return{valid:!0,data:r}}if("object"===r){const r={};for(const[i,a]of Object.entries(e)){const e=this.processForStorage(a,t,`${s}.${i}`);if(!e.valid)return e;void 0!==e.data&&(r[i]=e.data)}return{valid:!0,data:r}}return t?{valid:!1,error:`Unknown type at ${s}`}:(console.debug(`[DataStore] Stripped unknown type at ${s}`),{valid:!0,data:void 0})}async delete(e,t){const s=this.stores.get(e);s.data.delete(t),await this.withTransaction(e,s.config.storeName,"readwrite",(e=>{e.delete(t)})),this.notify(e,"item-deleted",{id:t})}get(e,t){return this.stores.get(e).data.get(t)}getAll(e){const t=this.stores.get(e);return Array.from(t.data.values())}filterByIndex(e,t){const s=this.stores.get(e);return s?Array.from(s.data.values()).filter((e=>Object.entries(t).every((([t,s])=>(Array.isArray(s)?s:[s]).includes(e[t]))))):[]}async getAllByIndex(e,t,s){const r=this.stores.get(e),i=Array.isArray(s)?s:[s];if(r.db&&r.db.objectStoreNames.contains(r.config.storeName))try{const e=r.db.transaction([r.config.storeName],"readonly").objectStore(r.config.storeName);if(e.indexNames.contains(t)){const s=e.index(t);return(await Promise.all(i.map((e=>new Promise(((t,r)=>{const i=s.getAll(e);i.onsuccess=()=>t(i.result||[]),i.onerror=()=>r(i.error)})))))).flat()}}catch(e){console.warn(`Index query failed for "${t}", falling back to filter:`,e)}return Array.from(r.data.values()).filter((e=>i.includes(e[t])))}getFiltered(e){const t=this.stores.get(e),s=this.generateCacheKey(t.filters),r=t.cache.get(s);return r&&r.items?r.items.reduce(((e,s)=>{const r=t.data.get(s);return r&&e.push(r),e}),[]):this.getAll(e)}async clear(e){const t=this.stores.get(e);t.data.clear(),t.cache.clear(),await this.withTransaction(e,t.config.storeName,"readwrite",(e=>{e.clear()})),this.notify(e,"data-cleared")}async updateFilters(e,t,s=!1){const r=this.stores.get(e),i={...r.filters};s?r.filters={...r.config.filters}:Object.entries(t).forEach((([e,t])=>{null==t||""===t?delete r.filters[e]:r.filters[e]=t})),this.notify(e,"filters-changed",{oldFilters:i,filters:r.filters,updates:t}),r.config.endpoint&&await this.fetch(e)}setFilter(e,t,s){return this.updateFilters(e,{[t]:s})}async setFilters(e,t){const s=this.stores.get(e);if(Object.keys(t).some((e=>s.filters[e]!==t[e])))return this.updateFilters(e,t)}removeFilter(e,t){return this.updateFilters(e,{[t]:null})}clearFilters(e){return this.updateFilters(e,{},!0)}clearCache(e){const t=this.stores.get(e);t.cache.clear(),t.db?.objectStoreNames.contains("cache")&&this.withTransaction(e,"cache","readwrite",(e=>{e.clear()})),this.notify(e,"cache-cleared")}generateCacheKey(e){const t=Object.keys(e).sort().reduce(((t,s)=>(t[s]=e[s],t)),{});return JSON.stringify(t)}isCacheValid(e,t){if(!e||!e.timestamp)return!1;return Date.now()-e.timestamp<t}subscribe(e,t){this.subscribers.has(e)||this.subscribers.set(e,new Set);const s=this.subscribers.get(e);return s.add(t),()=>s.delete(t)}notify(e,t,s={}){const r=this.subscribers.get(e);r&&r.forEach((r=>{try{r(t,s)}catch(t){console.error(`Subscriber error for store "${e}":`,t)}}))}getItemKey(e,t){if("function"==typeof t)return t(e);const s=t.split(".");let r=e;for(const e of s)r=r?.[e];return r}setLoading(e){this.body.classList.toggle("loading",e),e?this.loading?.showModal():this.loading?.close()}destroy(){this.stores.forEach((e=>{e.currentRequest&&e.currentRequest.abort()})),this.databases.forEach((e=>e.close())),this.stores.clear(),this.subscribers.clear(),this.databases.clear(),this.pendingInits.clear()}}document.addEventListener("DOMContentLoaded",(async function(){window.auth.subscribe((t=>{"auth-loaded"===t&&(window.jvbStore=new e)}))}))})();
\ No newline at end of file
+(()=>{class e{constructor(){if(e.instance)return e.instance;e.instance=this,this.dbConfig=new Map,this.databases=new Map,this.stores=new Map,this.subscribers=new Map,this.pendingInits=new Map,this.fetchQueue=[],this._initialized=!1,this.body=document.body,this.loading=document.querySelector("dialog.loading"),this.init()}async init(){this._initialized||(this._initialized=!0,"indexedDB"in window||console.warn("IndexedDB not supported"))}register(e,t=[],s=1.1){if(Array.isArray(t)||(t=[t]),0===t.length)return;this.dbConfig.has(e)||this.dbConfig.set(e,{dbName:`jvb_${e}`,version:s,stores:{},_initialized:!1});let r=this.dbConfig.get(e);t.forEach((t=>{if(!t.storeName)throw new Error(`Store config for "${e}" missing storeName`);if(!t.keyPath)throw new Error(`Store "${t.storeName}" requires keyPath`);const s=`${e}_${t.storeName}`,i={config:{dbName:r.dbName,storeName:"items",keyPath:"id",indexes:[],endpoint:null,apiBase:jvbSettings.api,filters:{},required:null,TTL:36e5,useHttpCaching:!0,showLoading:!1,delayFetch:!0,validateData:!0,...t},dbKey:e,storeKey:s,data:new Map,cache:new Map,filters:{...t.filters||{}},isFetching:!1,currentRequest:null,lastResponse:null,_initialized:!1};i.config.headers={"X-WP-Nonce":window.auth.getNonce(),...i.config.headers},r.stores[t.storeName]=s,this.stores.set(s,i),this.subscribers.has(s)||this.subscribers.set(s,new Set)})),this.initDB(e).catch((t=>{console.error(`Failed to initialize store "${e}":`,t)}));const i={};for(const[e,t]of Object.entries(r.stores))i[e]=this.getStoreAPI(t);return i}getStoreAPI(e){const t={fetch:()=>this.fetch(e),save:t=>this.save(e,t),delete:t=>this.delete(e,t),get:t=>this.get(e,t),getAll:()=>this.getAll(e),getAllByIndex:(t,s)=>this.getAllByIndex(e,t,s),filterByIndex:t=>this.filterByIndex(e,t),getFiltered:()=>this.getFiltered(e),clear:()=>this.clear(e),setFilter:(t,s)=>this.setFilter(e,t,s),setFilters:t=>this.setFilters(e,t),removeFilter:t=>this.removeFilter(e,t),clearFilters:()=>this.clearFilters(e),clearCache:()=>this.clearCache(e),subscribe:t=>this.subscribe(e,t),ensureInitialized:()=>this.ensureStoreInitialized(e),get filters(){return{...t.getStore().filters}},get lastResponse(){return t.getStore().lastResponse},get data(){return t.getStore().data},getStore:()=>this.stores.get(e)};return t}formDataToObject(e){const t={_isFormData:!0,entries:{}};for(const[s,r]of e.entries())r instanceof File||r instanceof Blob||(t.entries[s]?(Array.isArray(t.entries[s])||(t.entries[s]=[t.entries[s]]),t.entries[s].push(r)):t.entries[s]=r);return t}async objectToFormData(e){if(!e._isFormData)return e;const t=new FormData;for(const[s,r]of Object.entries(e.entries))Array.isArray(r)?r.forEach((e=>t.append(s,e))):t.append(s,r);if(window.jvbUploads&&e.entries.upload_ids){const s=JSON.parse(e.entries.upload_ids);for(const e of s){const s=await window.jvbUploads.getBlobData(e);s&&t.append("files[]",s)}}return t}async initDB(e){const t=this.dbConfig.get(e);if(!t||t._initialized)return;if(this.pendingInits.has(e))return this.pendingInits.get(e);const s=this._performDBInit(e);this.pendingInits.set(e,s);try{await s,t._initialized=!0}finally{this.pendingInits.delete(e)}}async _performDBInit(e){const t=this.dbConfig.get(e),{dbName:s,version:r}=t,i=Object.values(t.stores);try{if(!this.databases.has(s)){const e=await this.openDatabase(s,r,(e=>{i.forEach((t=>{let s=this.stores.get(t);s&&this.setupStores(e,s.config)}))}));this.databases.set(s,e)}i.forEach((e=>{let t=this.stores.get(e);t&&(t.db=this.databases.get(s),t._initialized=!0,this.loadStoreDataInBackground(e),this.notify(e,"db-init"))}))}catch(t){throw console.error(`Failed to initialize database for store "${e}":`,t),t}}openDatabase(e,t,s){return new Promise(((r,i)=>{const a=indexedDB.open(e,t);a.onupgradeneeded=e=>{s&&s(e.target.result,e.oldVersion,e.newVersion)},a.onsuccess=e=>r(e.target.result),a.onerror=e=>i(e.target.error),a.onblocked=()=>{console.warn(`Database ${e} blocked. Close other tabs.`)}}))}setupStores(e,t){if(!e.objectStoreNames.contains(t.storeName)){const s=e.createObjectStore(t.storeName,{keyPath:t.keyPath});t.indexes.forEach((e=>{s.createIndex(e.name,e.keyPath||e.name,{unique:e.unique||!1})}))}if(t.endpoint&&!e.objectStoreNames.contains("cache")){e.createObjectStore("cache",{keyPath:"key"}).createIndex("timestamp","timestamp",{unique:!1})}}async loadFromObjectStore(e,t,s){const r=this.stores.get(e);return r?.db&&r.db.objectStoreNames.contains(t)?new Promise((e=>{const i=r.db.transaction([t],"readonly").objectStore(t).getAll();i.onsuccess=t=>{const r=t.target.result||[];r.forEach(s),e(r)},i.onerror=()=>e([])})):[]}loadStoreDataInBackground(e){const t=this.stores.get(e);t?.db&&Promise.all([this.loadFromObjectStore(e,t.config.storeName,(e=>{const s=this.getItemKey(e,t.config.keyPath);t.data.set(s,e)})),this.loadFromObjectStore(e,"cache",(e=>{this.isCacheValid(e,t.config.TTL)&&t.cache.set(e.key,e)}))]).then((()=>{this.notify(e,"data-ready"),t.config.endpoint&&t.config.delayFetch?(this.fetchQueue.push(e),1===this.fetchQueue.length&&this.processFetchQueue()):t.config.endpoint&&!t.config.delayFetch&&("requestIdleCallback"in window?requestIdleCallback((()=>this.fetch(e)),{timeout:2e3}):setTimeout((()=>this.fetch(e)),100))})).catch((t=>{console.error(`Background load error for store "${e}":`,t)}))}async processFetchQueue(){if(0===this.fetchQueue.length)return;const e=this.fetchQueue.shift();if(!this.stores.get(e))return this.processFetchQueue();try{await this.fetch(e)}catch(t){console.error(`Queue fetch error for "${e}":`,t)}this.fetchQueue.length>0&&("requestIdleCallback"in window?requestIdleCallback((()=>this.processFetchQueue()),{timeout:2e3}):setTimeout((()=>this.processFetchQueue()),50))}async ensureStoreInitialized(e){const t=this.stores.get(e);if(!t)throw new Error(`Store "${e}" not registered`);t._initialized||await this.initDB(t.dbKey)}async withTransaction(e,t,s,r){const i=this.stores.get(e);return i?.db?("string"==typeof t&&(t=[t]),new Promise(((e,a)=>{const o=i.db.transaction(t,s),n=t.map((e=>o.objectStore(e))),c=1===n.length?n[0]:n;let h;o.oncomplete=()=>e(h),o.onerror=()=>a(o.error);try{h=r(c,o)}catch(e){a(e)}}))):null}async fetch(e){await this.ensureStoreInitialized(e);const t=this.stores.get(e);if(!t.isFetching){if(t.config.required){if((Array.isArray(t.config.required)?t.config.required:[t.config.required]).some((e=>!t.filters[e]||""===t.filters[e])))return}t.isFetching=!0;try{const s=this.generateCacheKey(t.filters),r=t.cache.get(s);if(r&&this.isCacheValid(r,t.config.TTL))return this.notify(e,"data-loaded",{cached:!0,items:r.items||[]}),r;t.config.showLoading&&this.setLoading(!0);const i=this.buildFetchUrl(e),a={...t.config.headers};t.config.useHttpCaching&&r&&(r.etag&&(a["If-None-Match"]=r.etag),r.lastModified&&(a["If-Modified-Since"]=r.lastModified));const o=new AbortController;t.currentRequest=o;const n=await fetch(i,{method:"GET",headers:a,signal:o.signal});if(304===n.status)return r?(this.notify(e,"data-loaded",{cached:!0,notModified:!0,items:r.items||[]}),r):(this.notify(e,"data-loaded",{cached:!1,notModified:!0,items:[]}),t.lastResponse={has_more:!1,total:0,pages:1,queue_stats:{}},{items:[]});if(!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText}`);const c=await n.json();return await this.processFetchedData(e,c,s,n),this.notify(e,"data-loaded",{cached:!1,items:c.items||[]}),c}catch(t){throw"AbortError"!==t.name&&(console.error(`Fetch error for store "${e}":`,t),this.notify(e,"fetch-error",{error:t})),t}finally{t.isFetching=!1,t.currentRequest=null,t.config.showLoading&&this.setLoading(!1)}}}buildFetchUrl(e){const t=this.stores.get(e),s=new URLSearchParams;Object.entries(t.filters).forEach((([e,t])=>{null!=t&&""!==t&&("object"==typeof t?s.set(e,JSON.stringify(t)):s.set(e,t))}));const r=t.config.apiBase+t.config.endpoint;return s.toString()?`${r}?${s}`:r}async processFetchedData(e,t,s,r){const i=this.stores.get(e),a=t.items||[],o=[];i.db&&a.length>0&&await this.withTransaction(e,i.config.storeName,"readwrite",(t=>{a.forEach((s=>{try{const r=this._saveItem(e,s);o.push(r),t.put(r.processed)}catch(e){console.error("Error processing item:",e)}}))}));const n={key:s,items:a.map((e=>this.getItemKey(e,i.config.keyPath))),timestamp:Date.now(),endpoint:i.config.endpoint,filters:{...i.filters},etag:r.headers.get("ETag"),lastModified:r.headers.get("Last-Modified"),has_more:t.has_more||!1};i.cache.set(s,n),i.db?.objectStoreNames.contains("cache")&&await this.withTransaction(e,"cache","readwrite",(e=>{e.put(n)})),i.lastResponse={...t,has_more:t.has_more||!1,total:t.total||a.length,pages:t.pages||1,queue_stats:t.queue_stats||{}};for(let[t,s]of Object.entries(i.filters))"string"==typeof s&&s.includes(",")&&this.createSplitCacheEntries(e,a,t,i.filters,r);o.forEach((t=>{t.statusChanged&&this.notify(e,"item-saved",{item:t.item,key:t.key,previousItem:t.previousItem})}))}createSplitCacheEntries(e,t,s,r,i){const a=this.stores.get(e);r[s].split(",").map((e=>e.trim())).forEach((t=>{let o={};o[s]=t;const n={...r,[s]:t},c=this.generateCacheKey(n);if(a.cache.has(c))return;let h=this.filterByIndex(e,o).map((e=>this.getItemKey(e,a.config.keyPath)));const d={key:c,items:h,timestamp:Date.now(),endpoint:a.config.endpoint,filters:n,etag:i.headers.get("Etag"),lastModified:i.headers.get("Last-Modified"),has_more:20===h.length};a.cache.set(c,d),a.db?.objectStoreNames.contains("cache")&&this.withTransaction(e,"cache","readwrite",(e=>{e.put(d)}))}))}_saveItem(e,t){const s=this.stores.get(e),r=this.processForStorage(t,s.config.validateData);if(!r.valid)throw new Error(`Non-serializable data: ${r.error}`);const i=r.data,a=this.getItemKey(i,s.config.keyPath),o=s.data.get(a);return s.data.set(a,t),{item:t,previousItem:o,key:a,processed:i,statusChanged:o&&o.status!==t.status}}async save(e,t){const s=this.stores.get(e),r=this._saveItem(e,t);return await this.withTransaction(e,s.config.storeName,"readwrite",(e=>{e.put(r.processed)})),this.notify(e,"item-saved",{item:r.item,key:r.key,previousItem:r.previousItem}),r.key}processForStorage(e,t=!0,s="root"){if(null==e)return{valid:!0,data:e};const r=typeof e;if(["string","number","boolean"].includes(r))return{valid:!0,data:e};if("function"===r)return t?{valid:!1,error:`Function at ${s}`}:(console.debug(`[DataStore] Stripped function at ${s}`),{valid:!0,data:void 0});if(e instanceof HTMLElement||void 0!==e.nodeType)return t?{valid:!1,error:`DOM element at ${s}`}:(console.debug(`[DataStore] Stripped DOM element at ${s}`),{valid:!0,data:void 0});if(e instanceof FormData)return console.debug(`[DataStore] Converting FormData at ${s}`),{valid:!0,data:this.formDataToObject(e)};if(e instanceof Date||e instanceof ArrayBuffer||ArrayBuffer.isView(e)||e instanceof Blob)return{valid:!0,data:e};if(e instanceof Set)return this.processForStorage(Array.from(e),t,s);if(e instanceof Map&&(e=Object.fromEntries(e)),Array.isArray(e)){const r=[];for(let i=0;i<e.length;i++){const a=this.processForStorage(e[i],t,`${s}[${i}]`);if(!a.valid)return a;void 0!==a.data&&r.push(a.data)}return{valid:!0,data:r}}if("object"===r){const r={};for(const[i,a]of Object.entries(e)){const e=this.processForStorage(a,t,`${s}.${i}`);if(!e.valid)return e;void 0!==e.data&&(r[i]=e.data)}return{valid:!0,data:r}}return t?{valid:!1,error:`Unknown type at ${s}`}:(console.debug(`[DataStore] Stripped unknown type at ${s}`),{valid:!0,data:void 0})}async delete(e,t){const s=this.stores.get(e);s.data.delete(t),await this.withTransaction(e,s.config.storeName,"readwrite",(e=>{e.delete(t)})),this.notify(e,"item-deleted",{id:t})}get(e,t){return this.stores.get(e).data.get(t)}getAll(e){const t=this.stores.get(e);return Array.from(t.data.values())}filterByIndex(e,t){const s=this.stores.get(e);return s?Array.from(s.data.values()).filter((e=>Object.entries(t).every((([t,s])=>(Array.isArray(s)?s:[s]).includes(e[t]))))):[]}async getAllByIndex(e,t,s){const r=this.stores.get(e),i=Array.isArray(s)?s:[s];if(r.db&&r.db.objectStoreNames.contains(r.config.storeName))try{const e=r.db.transaction([r.config.storeName],"readonly").objectStore(r.config.storeName);if(e.indexNames.contains(t)){const s=e.index(t);return(await Promise.all(i.map((e=>new Promise(((t,r)=>{const i=s.getAll(e);i.onsuccess=()=>t(i.result||[]),i.onerror=()=>r(i.error)})))))).flat()}}catch(e){console.warn(`Index query failed for "${t}", falling back to filter:`,e)}return Array.from(r.data.values()).filter((e=>i.includes(e[t])))}getFiltered(e){const t=this.stores.get(e),s=this.generateCacheKey(t.filters),r=t.cache.get(s);if(r&&r.items)return r.items.reduce(((e,s)=>{const r=t.data.get(s);return r&&e.push(r),e}),[]);if(t.filters.search&&t.filters.search.trim()){const e=t.filters.search.toLowerCase().trim();let s=Array.from(t.data.values()).filter((e=>{for(const[s,r]of Object.entries(t.filters))if("search"!==s&&"page"!==s&&null!=r&&""!==r&&e[s]!==r)return!1;return!0}));return s=s.filter((t=>["name","title","path","description","slug"].some((s=>{const r=t[s];return!!r&&r.toLowerCase().includes(e)})))),s}return this.getAll(e)}async clear(e){const t=this.stores.get(e);t.data.clear(),t.cache.clear(),await this.withTransaction(e,t.config.storeName,"readwrite",(e=>{e.clear()})),this.notify(e,"data-cleared")}async updateFilters(e,t,s=!1){const r=this.stores.get(e),i={...r.filters};s&&(r.filters={...r.config.filters}),Object.entries(t).forEach((([e,t])=>{null==t||""===t?delete r.filters[e]:r.filters[e]=t}));const a=await this.shouldFetchWithFilters(e,t,i);this.notify(e,"filters-changed",{oldFilters:i,filters:r.filters,updates:t}),r.config.endpoint&&a?await this.fetch(e):r.config.endpoint&&this.notify(e,"data-loaded")}async shouldFetchWithFilters(e,t,s){const r=this.stores.get(e);if(!r.config.endpoint||!r.lastResponse)return!0;if("page"in t){const e=t.page,i=s.page||1;if(e>i&&!r.lastResponse.has_more)return r.filters.page=i,!1}if("search"in t){const e=t.search?.trim()||"",i=s.search?.trim()||"";if(!e&&i){const e={...r.filters};if(delete e.search,e.page=1,this.hasCompleteData(r,e))return!1}if(e&&e!==i){const e={...r.filters};if(delete e.search,e.page=1,this.hasCompleteData(r,e))return!1}}return!0}hasCompleteData(e,t){const s=this.generateCacheKey(t),r=e.cache.get(s);return!!r&&(!1===r.has_more||!1===e.lastResponse?.has_more)}setFilter(e,t,s){return this.updateFilters(e,{[t]:s})}async setFilters(e,t){const s=this.stores.get(e);if(Object.keys(t).some((e=>s.filters[e]!==t[e]))||Object.keys(s.filters).some((e=>!(e in t)&&t!==s.config.filters)))return this.updateFilters(e,t)}removeFilter(e,t){return this.updateFilters(e,{[t]:null})}clearFilters(e){return this.updateFilters(e,{},!0)}clearCache(e){const t=this.stores.get(e);t.cache.clear(),t.db?.objectStoreNames.contains("cache")&&this.withTransaction(e,"cache","readwrite",(e=>{e.clear()})),this.notify(e,"cache-cleared")}generateCacheKey(e){const t=Object.keys(e).sort().reduce(((t,s)=>(t[s]=e[s],t)),{});return JSON.stringify(t)}isCacheValid(e,t){if(!e||!e.timestamp)return!1;return Date.now()-e.timestamp<t}subscribe(e,t){this.subscribers.has(e)||this.subscribers.set(e,new Set);const s=this.subscribers.get(e);return s.add(t),()=>s.delete(t)}notify(e,t,s={}){const r=this.subscribers.get(e);r&&r.forEach((r=>{try{r(t,s)}catch(t){console.error(`Subscriber error for store "${e}":`,t)}}))}getItemKey(e,t){if("function"==typeof t)return t(e);const s=t.split(".");let r=e;for(const e of s)r=r?.[e];return r}setLoading(e){this.body.classList.toggle("loading",e),e?this.loading?.showModal():this.loading?.close()}destroy(){this.stores.forEach((e=>{e.currentRequest&&e.currentRequest.abort()})),this.databases.forEach((e=>e.close())),this.stores.clear(),this.subscribers.clear(),this.databases.clear(),this.pendingInits.clear()}}document.addEventListener("DOMContentLoaded",(async function(){window.auth.subscribe((t=>{"auth-loaded"===t&&(window.jvbStore=new e)}))}))})();
\ No newline at end of file
diff --git a/assets/js/min/queue.min.js b/assets/js/min/queue.min.js
index a589cbf..b7501ce 100644
--- a/assets/js/min/queue.min.js
+++ b/assets/js/min/queue.min.js
@@ -1 +1 @@
-(()=>{class e{constructor(e={}){if(this.canUpdateUI=!0,this.config={apiBase:jvbSettings.api,maxRetries:3,pollInterval:5e3,activityDelay:2e3,autosync:!0,endpoint:"queue",...e},this.isProcessing=!1,this.isPolling=!1,this.subscribers=new Set,this.statuses=["queued","localProcessing","uploading","pending","processing","completed","failed","failed_permanent"],this.user=window.auth.getUser(),!this.user)return console.log("Queue: User not logged in, queue disabled"),this.store=null,void(this.canUpdateUI=!1);this.headers={"X-WP-Nonce":window.auth.getNonce(),...e.headers},this.a11y=window.jvbA11y,this.errors=window.jvbError;const t=window.jvbStore.register("queue",{storeName:"queue",keyPath:"id",endpoint:this.config.endpoint,TTL:1/0,indexes:[{name:"status",keyPath:"status"},{name:"type",keyPath:"type"}],showLoading:!1,delayFetch:!1});this.store=t.queue,this.classes=["offline","synced","pending"],this.initUI(),this.initListeners(),this.ui.panel&&(this.popup=new window.jvbPopup({popup:this.ui.panel,toggle:this.ui.toggle,name:"Queue Panel"})),this.updateUI=()=>window.debouncer.schedule("queue-ui-update",this._updateUI.bind(this),100),this.initQueue()}async initQueue(){this.maybeStartPolling()||this.updateStatusPanel("synced"),this.store.subscribe(((e,t)=>{switch(e){case"data-loaded":case"items-saved":this.maybeStartPolling(),this.updateUI();break;case"item-saved":console.log(t,"Item saved data"),t.previousItem&&t.previousItem.status!==t.item.status&&this.handleOperationStatusChange(t.item,t.previousItem.status),this.maybeStartPolling();break;default:this.updateUI()}}))}maybeStartPolling(){return this.getOperationsByStatus(["completed","failed_permanent"],!1).length>0&&(this.startPolling(),!0)}handleOperationStatusChange(e){switch(e.status){case"completed":console.log(e),this.notify("operation-completed",e);break;case"failed":this.notify("operation-failed",e);break;case"failed_permanent":this.notify("operation-failed-permanent",e)}}addToQueue(e){const t={id:`u${this.user}_${Date.now()}_${Math.random().toString(36).substring(2,9)}`,endpoint:null,method:"POST",headers:{},data:{},sendNow:!1,canMerge:!0,popup:"Saving changes...",title:"Operation",status:"queued",timestamp:Date.now(),retries:0,user:this.user,...e};if(t.headers={...this.headers,...t.headers},!t.endpoint||!t.data)return console.error("Invalid operation queued: missing endpoint or data"),null;if(t.sendNow)return this.processOperation(t).then((()=>{})),this.store.clearCache(),window.debouncer.schedule("fastQueue",this.startPolling.bind(this),200),this.showQueue(),t.id;const s=Array.from(this.store.data.values()).filter((e=>"queued"===e.status&&e.endpoint===t.endpoint&&e.canMerge));if(s.length>0){const e=s[0];return e.data=window.deepMerge(e.data,t.data),e.timestamp=Date.now(),this.updateOperationStatus(e.id,e.status),this.updateUI(),this.startActivityTracking(),e.id}return this.store.clearCache(),this.setQueue(t),this.updateOperationStatus(t.id,t.status),this.updateUI(),this.startActivityTracking(),t.id}setQueue(e){this.store.save(e)}updateOperationStatus(e,t){let s=this.store.get(e);s&&(s.status=t,this.notify("operation-status",s),this.updateOperationUI(s))}getQueue(e){return this.store.get(e)}clearQueue(e){this.store.delete(e)}startActivityTracking(){if(!this.activityListeners){const e=["mousedown","mousemove","keypress","scroll","touchstart"];this.activityListeners=e.map((e=>{const t=()=>this.resetActivityTimer();return document.addEventListener(e,t,{passive:!0}),{event:e,handler:t}}))}this.resetActivityTimer()}resetActivityTimer(){this.activityTimer&&clearTimeout(this.activityTimer),this.activityTimer=setTimeout((()=>{this.processQueue()}),this.config.activityDelay)}stopActivityTracking(){this.activityTimer&&(clearTimeout(this.activityTimer),this.activityTimer=null),this.activityListeners&&(this.activityListeners.forEach((({event:e,handler:t})=>{document.removeEventListener(e,t)})),this.activityListeners=null)}hideQueue(){this.ui.panel.hidden=!0,this.ui.toggle.hidden=!0}showQueue(){this.ui.panel.hidden=!1,this.ui.toggle.hidden=!1}setProcessing(e){this.isProcessing=e,this.ui.toggle.classList.toggle("saving",e)}async processQueue(){if(this.isProcessing)return;const e=this.getOperationsByStatus("queued");if(0!==e.length){this.setProcessing(!0);for(const t of e)await this.processOperation(t);this.setProcessing(!1),this.stopActivityTracking(),this.maybeStartPolling()?this.showQueue():this.hideQueue()}else this.stopActivityTracking()}async processOperation(e,t=!1){try{t||(this.updateOperationStatus(e.id,"uploading"),e.data?._isFormData&&(e.data=await this.store.objectToFormData(e.data)));const s=`${this.config.apiBase}${e.endpoint}`;let i;e.data instanceof FormData?(e.data.append("id",e.id),e.data.append("user",this.user),i=e.data):(i=JSON.stringify({...e.data,id:e.id,user:this.user}),e.headers["Content-Type"]="application/json");const a=await fetch(s,{method:e.method,headers:e.headers,body:i}),n=await a.json();if(t&&(e.data={}),!a.ok||!1===n.success)throw new Error(n.message||`HTTP ${a.status}`);n.id&&e.id!==n.id?e=await this.handleServerMerge(e,n):(e.status=n.status||"pending",e.serverData=n,this.updateOperationStatus(e.id,e.status)),this.a11y.announce(`${e.title} sent to server for processing.`)}catch(t){console.error("Operation failed:",t),e.retries++,e.lastError=t.message,e.retries>=this.config.maxRetries?e.status="failed_permanent":(e.status="failed",e.nextRetry=Date.now()+1e3*Math.pow(2,e.retries)),this.updateOperationStatus(e.id,e.status),this.setQueue(e)}}async handleServerMerge(e,t){const s=this.getQueue(t.id);return s?(s.data=window.deepMerge(s.data,e.data),s.status=t.status||"pending",s.serverData=t,this.updateOperationStatus(s.id,s.status),this.removeOperationFromUI(e.id),this.clearQueue(e.id),s):(this.clearQueue(e.id),e.id=t.id,e.status=t.status||"pending",e.serverData=t,this.updateOperationStatus(e.id,e.status),e)}startPolling(){this.isPolling||(this.isPolling=!0,this.updateStatusPanel("pending"),this.pollTimer=setInterval((async()=>{try{this.store.clearCache(),await this.store.fetch(),this.maybeStartPolling()||(this.stopPolling(),this.updateStatusPanel("synced"))}catch(e){console.error("Polling error:",e)}}),this.config.pollInterval))}stopPolling(){this.isPolling&&(this.isPolling=!1,this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),this.countdownTimer&&(clearInterval(this.countdownTimer),this.countdownTimer=null))}getOperationIds(e){return e.map((e=>e.id))}async updateServerOperations(e,t){if(0===(e=(e=Array.isArray(e)?e:e.includes(",")?e.split(","):[e]).filter((e=>{let s=this.getQueue(e);return this.getAllowedActions(s.status).includes(t)}))).length)return;const s=["cancel","dismiss"].includes(t);s&&e.forEach((e=>this.removeOperationFromUI(e)));try{const i=await fetch(`${this.config.apiBase}${this.config.endpoint}`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify({ids:e,action:t,user:window.auth.getUser()})});if(!i.ok)throw new Error(`${t} failed: ${i.status}`);const a=await i.json();if(!a.success)throw new Error(a.message||`${t} operation failed`);return e.forEach((e=>{let i=this.getQueue(e);this.notify(`${t}-operation`,i),s?this.clearQueue(e):(i.status="queued",i.retries=0,this.setQueue(i),this.updateOperationStatus(i.id,i.status))})),"retry"===t&&this.startActivityTracking(),this.updateUI(),a}catch(s){return await window.jvbError.log(s,{component:"QueueManager",operation:"performQueueAction",action:t,operationIds:e,itemCount:e.length},(()=>this.updateServerOperations(e,t))),{success:!1,error:s.message}}}getAllowedActions(e){return{queued:["cancel"],localProcessing:["cancel"],pending:["cancel"],processing:[],completed:["dismiss"],failed:["retry","dismiss"],failed_permanent:["dismiss"]}[e]||[]}initListeners(){this.clickHandler=this.handleClick.bind(this),document.addEventListener("click",this.clickHandler),this.handleOnline=()=>{this.updateStatusPanel(),this.hasQueuedOperations()&&this.processQueue()},this.handleOffline=()=>this.updateStatusPanel("offline"),this.handleBeforeUnload=e=>{if(this.isPolling||this.isProcessing)return e.preventDefault(),"You have unsaved changes in the queue. Proceed?"},window.addEventListener("online",this.handleOnline),window.addEventListener("offline",this.handleOffline),window.addEventListener("beforeunload",this.handleBeforeUnload)}handleClick(e){if(e.target.closest(this.selectors.panel,this.selectors.toggle))if(e.target.closest(this.selectors.refreshButton))this.store.clearCache(),this.store.clearHttpHeaders(),this.store.fetch();else if(e.target.closest(this.selectors.clearButton)){const e=this.getOperationIds(this.getOperationsByStatus("completed"));e.length>0&&this.updateServerOperations(e,"dismiss")}else if(e.target.closest(this.selectors.retryButton)){const e=this.getOperationIds(this.getOperationsByStatus("failed"));e.length>0&&this.updateServerOperations(e,"retry")}else if(e.target.closest("[data-action]")){const t=e.target.closest("[data-action]"),s=t.closest("[data-id]")?.dataset.id;s&&this.updateServerOperations(s,t.dataset.action)}else if(e.target.closest(".filters [data-filter]")){const t=e.target.closest("[data-filter]").dataset.filter;this.setFilter(t)}}initUI(){this.icons={queued:"arrows-clockwise",localProcessing:"arrows-clockwise",uploading:"syncing",pending:"cloud",processing:"syncing",completed:"cloud-check",failed:"cloud-warning",failed_permanent:"cloud-warning"},this.selectors={panel:"aside#queue",toggle:"button.qtoggle",refreshButton:"button.refreshNow",countdown:".countdown",indicator:".qtoggle .indicator",count:".qtoggle .count",popup:".popup",itemsContainer:".qitems",clearButton:".dismiss-all",retryButton:".retry-all",filters:{all:'.filters [data-filter="all"]',received:'.filters [data-filter="queued"]',localProcessing:'.filters [data-filter="localProcessing"]',uploading:'.filters [data-filter="uploading"]',pending:'.filters [data-filter="pending"]',processing:'.filters [data-filter="processing"]',completed:'.filters [data-filter="completed"]',failed:'.filters [data-filter="failed"]'}},this.ui=window.uiFromSelectors(this.selectors),this.ui.panel||(this.canUpdateUI=!1)}_updateUI(){if(!this.canUpdateUI)return;const e=Array.from(this.store.data.values()),t=this.store.lastResponse?.queue_stats||{queued:0,localProcessing:0,uploading:0,pending:0,processing:0,completed:0,failed:0,failed_permanent:0};if(this.ui.count){const s=e.length-t.completed;this.ui.count.textContent=s>0?s:"",this.ui.count.style.display=s>0?"":"none"}if(this.ui.indicator){const e=t.queued>0||t.uploading>0||t.pending>0||t.processing>0;this.ui.indicator.classList.toggle("active",e)}this.ui.clearButton.disabled=0===this.getOperationsByStatus("completed").length,this.ui.retryButton.disabled=0===this.getOperationsByStatus("failed").length&&0===this.getOperationsByStatus("failed_permanent").length,Object.entries(this.ui.filters).forEach((([s,i])=>{const a="all"===s?e.length:t[s]||0,n=i.querySelector(".count");n&&(n.textContent=a>0?a:""),i.setAttribute("data-count",a)})),this.renderOperations()}getStatusLabel(e){return{queued:"Queued",localProcessing:"Processing locally",uploading:"Uploading",pending:"Waiting on server",processing:"Processing",completed:"Completed",failed:"Failed (will retry)",failed_permanent:"Failed permanently"}[e]||e}getItemMessage(e){if(e.message)return e.message;if(e.error_message)return e.error_message;switch(e.status){case"queued":return"Waiting to send...";case"uploading":return"Sending to server...";case"pending":return e.position?`Position ${e.position} in queue`:"In server queue";case"processing":return e.progress?`${e.progress}% complete`:"Processing...";case"completed":return"Successfully completed";case"failed":return`Failed: ${e.lastError||"Unknown error"} (Retry ${e.retries}/${this.config.maxRetries})`;case"failed_permanent":return`Failed: ${e.lastError||"Unknown error"}`;default:return""}}calculateProgress(e){if(e.progress)return e.progress;return{queued:10,uploading:25,pending:40,processing:70,completed:100,failed:0,failed_permanent:0}[e.status]||0}renderOperations(){if(!this.ui.itemsContainer)return;const e=this.store.getFiltered();if(window.removeChildren(this.ui.itemsContainer),0===e.length){let e=window.getTemplate("emptyQueue");this.ui.itemsContainer.append(e),this.a11y.announce("Nothing queued.")}else e.forEach((e=>{const t=this.createOperationUI(e);this.ui.itemsContainer.append(t)}))}createOperationUI(e){const t=window.getTemplate("queueItem");return t.dataset.id=e.id,this.updateOperationUI(e,t),t}updateOperationUI(e,t=null){t||(t=this.ui.itemsContainer?.querySelector(`[data-id="${e.id}"]`)),t||(t=this.createOperationUI(e)),this.statuses.forEach((e=>t.classList.remove(e))),t.classList.add(e.status);let s="";e.updated_at?s=window.formatTimeAgo(new Date(e.updated_at)):e.created_at&&(s=window.formatTimeAgo(new Date(e.created_at)));const i=this.calculateProgress(e),a=t.querySelector(".type"),n=t.querySelector(".status"),r=t.querySelector(".info .details"),o=t.querySelector(".info .time"),d=t.querySelector(".progress .fill");if(a&&(a.textContent=e.title),n){n.querySelector(".icon")?.remove();let t=this.getStatusLabel(e.status);n.title=t,n.prepend(window.getIcon(this.icons[e.status])),n.querySelector("span").textContent=t}r&&(r.textContent=this.getItemMessage(e)),o&&(o.textContent=s),d&&(d.style.width=`${i}%`);const l=t.querySelector(".actions");l&&this.updateActionButtons(e,l)}updateActionButtons(e,t){switch(window.removeChildren(t),e.status){case"queued":case"localProcessing":case"pending":const s=window.getTemplate("button");s.classList.add("cancel"),s.dataset.action="cancel",s.textContent="Cancel",t.appendChild(s);break;case"failed":case"failed_permanent":const i=window.getTemplate("button"),a=window.getTemplate("button");i.classList.add("retry"),i.textContent="Retry",i.disabled=e.retries>=this.maxRetries,i.dataset.action="retry",a.classList.add("dismiss"),a.textContent="Dismiss",a.dataset.action="dismiss",t.appendChild(i),t.appendChild(a);break;case"completed":const n=window.getTemplate("button");n.dataset.action="dismiss",n.classList.add("dismiss"),n.textContent="Dismiss",t.appendChild(n)}}removeOperationFromUI(e){const t=this.ui.itemsContainer?.querySelector(`[data-id="${e}"]`);t&&(t.style.opacity="0",t.style.transform="scale(0.9)",setTimeout((()=>t.remove()),300))}updateStatusPanel(e){this.ui.panel?.classList.remove(...this.classes),this.classes.includes(e)&&this.ui.panel?.classList.add(e)}setFilter(e){Object.values(this.ui.filters).forEach((t=>{t&&t.classList.toggle("active",t.dataset.filter===e)})),"all"===e?this.store.clearFilters():this.store.setFilter("status",e)}getOperationsByStatus(e,t=!0){return Array.isArray(e)||"string"!=typeof e||(e=[e]),t?Array.from(this.store.data.values()).filter((t=>e.includes(t.status))):Array.from(this.store.data.values()).filter((t=>!e.includes(t.status)))}hasQueuedOperations(){return this.getOperationsByStatus("queued").length>0}subscribe(e){if(this.subscribers)return this.subscribers.add(e),()=>this.subscribers.delete(e)}notify(e,t){this.subscribers.forEach((s=>s(e,t)))}destroy(){this.stopPolling(),this.stopActivityTracking(),this.clickHandler&&document.removeEventListener("click",this.clickHandler),this.keyHandler&&document.removeEventListener("keydown",this.keyHandler),this.subscribers.clear()}}document.addEventListener("DOMContentLoaded",(async function(){window.auth.subscribe((t=>{"auth-loaded"===t&&(window.jvbQueue=new e)}))}))})();
\ No newline at end of file
+(()=>{class e{constructor(){this.a11y=window.jvbA11y,this.error=window.jvbError,this.user=window.auth.getUser(),this.canUpdateUI=!0,this.isProcessing=!1,this.isPolling=!1,this.queue=new Map,this.items=new Map,this.subscribers=new Set,this.api=jvbSettings.api,this.endpoint="queue",this.init()}init(){this.headers={"X-WP-Nonce":window.auth.getNonce()},this.initElements(),this.initListeners(),this.initStore(),this.canUpdateUI&&(this.popup=new window.jvbPopup({popup:this.ui.panel,toggle:this.ui.toggle.button,name:"Queue Panel"}))}initElements(){this.panelStatuses=["syncing","synced","pending","offline"],this.statuses=["queued","localProcessing","uploading","pending","processing","completed","failed","failed_permanent"],this.pendingStatuses=["queued","localProcessing","uploading"],this.workingStatuses=["pending","processing"],this.completedStatuses=["completed","failed","failed_permanent"],this.icons={queued:"arrows-clockwise",localProcessing:"arrows-clockwise",uploading:"syncing",pending:"cloud",processing:"syncing",completed:"cloud-check",failed:"cloud-warning",failed_permanent:"cloud-warning"},this.selectors={panel:"aside#queue",toggle:{button:"button.qtoggle",indicator:".qtoggle .indicator",count:".qtoggle .count"},refresh:{button:"#queue .refresh .refreshNow",countdown:"#queue .refresh .countdown"},popup:{popup:"#queue .popup",message:"#queue .popup span"},items:{container:"#queue .qitems"},actions:{retry:"#queue .retry-all",clear:"#queue .dismiss-all"},filters:{filter:"#queue [data-filter]",all:{label:'#queue [for="qfilter-all"]',radio:'#queue [data-filter="all"]',count:'#queue [data-filter="all"] .count'},queued:{label:'#queue [for="qfilter-queued"]',input:'#queue [data-filter="queued"]',count:'#queue [for="qfilter-queued"] .count'},localProcessing:{label:'#queue [for="qfilter-localProcessing"]',input:'#queue [data-filter="localProcessing"]',count:'#queue [for="qfilter-localProcessing"] .count'},uploading:{label:'#queue [for="qfilter-uploading"]',input:'#queue [data-filter="uploading"]',count:'#queue [for="qfilter-uploading"] .count'},pending:{label:'#queue [for="qfilter-pending"]',input:'#queue [data-filter="pending"]',count:'#queue [for="qfilter-pending"] .count'},processing:{label:'#queue [for="qfilter-processing"]',input:'#queue [data-filter="processing"]',count:'#queue [for="qfilter-processing"] .count'},completed:{label:'#queue [for="qfilter-completed"]',input:'#queue [data-filter="completed"]',count:'#queue [for="qfilter-completed"] .count'},failed:{label:'#queue [for="qfilter-failed"]',input:'#queue [data-filter="failed"]',count:'#queue [for="qfilter-failed"] .count'}},item:{type:".type",status:".status",details:".info .details",icon:".status .icon",startedAt:".started time",completed:{wrap:".completed",label:".completed span",time:".completed time"},progress:{progress:".progress",fill:".progress .fill",details:".progress .details",icon:".progress .icon"},actions:{cancel:"button.cancel",retry:"button.retry",dismiss:"button.dismiss"}}},this.ui=window.uiFromSelectors(this.selectors),this.ui.panel||(this.canUpdateUI=!1)}initListeners(){this.activityListeners=null,this.clickHandler=this.handleClick.bind(this),this.onlineHandler=this.handleOnline.bind(this),this.offlineHandler=this.handleOffline.bind(this),this.unloadHandler=this.handleBeforeUnload.bind(this),document.addEventListener("click",this.clickHandler),window.addEventListener("online",this.onlineHandler),window.addEventListener("offline",this.offlineHandler),window.addEventListener("beforeunload",this.unloadHandler)}handleOnline(){this.updatePanel(),this.getQueueByStatus(this.pendingStatuses).length>0&&this.processQueue()}handleOffline(){this.updatePanel("offline")}handleBeforeUnload(e){if(this.getQueueByStatus(this.pendingStatuses).length>0)return e.preventDefault(),e.returnValue="",""}handleClick(e){if(!window.targetCheck(e,this.selectors.panel+", "+this.selectors.toggle.button))return;if(window.targetCheck(e,this.selectors.refresh.button))return this.store.clearCache(),void this.store.fetch();if(window.targetCheck(e,this.selectors.actions.clear))return void this.opActions("completed","dismiss").then((()=>{}));if(window.targetCheck(e,this.selectors.actions.retry))return void this.opActions("failed","retry").then((()=>{}));const t=window.targetCheck(e,"[data-action]");if(t){const e=t.closest("[data-id]")?.dataset.id;return void(e&&this.opActions(e,t.dataset.action))}const s=window.targetCheck(e,this.selectors.filters.filter);s&&this.setFilter(s.dataset.filter)}setFilter(e){Object.values(this.ui.filters).forEach((t=>{t.input?.dataset.filter===e&&(t.input.checked=!0)})),"all"===e?this.store.clearFilters():this.store.setFilter("status",e)}trackActivity(){if(!this.activityListeners){const e=["mousedown","mousemove","keypress","scroll","touchstart"];this.activityListeners=e.map((e=>{const t=()=>this.resetActivityTimer();return document.addEventListener(e,t,{passive:!0}),{event:e,handler:t}}))}this.resetActivityTimer()}resetActivityTimer(){this.activityTimer&&clearTimeout(this.activityTimer),this.activityTimer=setTimeout((()=>{this.processQueue()}),1750)}stopActivityTracking(){this.activityTimer&&(clearTimeout(this.activityTimer),this.activityTimer=null),this.activityListeners&&(this.activityListeners.forEach((({event:e,handler:t})=>{document.removeEventListener(e,t)})),this.activityListeners=null)}initStore(){if(!this.user)return;const e=window.jvbStore.register("queue",{storeName:"queue",keyPath:"id",endpoint:this.endpoint,TTL:1/0,indexes:[{name:"status",keyPath:"status"},{name:"type",keyPath:"type"}],showLoading:!1});this.store=e.queue,this.store.subscribe(((e,t)=>{switch(e){case"data-loaded":case"items-save":this.maybeStartPolling(),this.updateUI();break;case"item-saved":t.previousItem&&t.previousItem.status!==t.item.status&&this.updateOperationStatus(t.item.id,t.item.status),this.maybeStartPolling()}}))}addToQueue(e){const t={id:`u${this.user}_${Date.now()}_${Math.random().toString(36).substring(2,9)}`,endpoint:null,method:"POST",headers:{},data:{},delay:!1,canMerge:!0,popup:"Saving changes...",title:"Operation",status:"queued",timestamp:Date.now(),retries:0,user:this.user,...e};if(t.headers={...this.headers,...t.headers},!t.endpoint||!t.data)return null;if(t.popup&&this.ui.popup?.message&&(this.ui.popup.message.textContent=t.popup,this.ui.popup.popup.hidden=!1,setTimeout((()=>this.ui.popup.popup.hidden=!0),2e3)),!t.delay)return this.queue.set(t.id,t),this.processOperation(t).then((()=>{})),this.store.clearCache(),this.maybeStartPolling(),this.toggleQueue(),t.id;const s=Array.from(this.getAllQueue()).filter((e=>"queued"===e.status&&e.endpoint===t.endpoint&&e.canMerge));if(s.length>0){const e=s[0];return e.data=window.deepMerge(e.data,t.data),e.timestamp=Date.now(),this.updateOperationStatus(e.id,e.status),this.updateUI(),this.trackActivity(),e.id}return this.store.clearCache(),this.setQueue(t),this.updateOperationStatus(t.id,t.status),this.updateUI(),this.trackActivity(),t.id}async opActions(e,t){if(this.statuses.includes(e)?e=this.getQueueByStatus(e).map((e=>e.id)):"string"==typeof e&&(e=[e]),0===e.length)return;if(!["cancel","dismiss","retry"].includes(t))return;const s=["cancel","dismiss"].includes(t);s&&e.forEach((e=>this.removeOperationUI(e)));try{const i=await fetch(`${this.api}${this.endpoint}`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify({action:t,ids:e,user:this.user})});if(!i.ok)throw new Error(`${t} failed: ${i.status}`);const n=await i.json();if(!n.success)throw new Error(n.message||`${t} operation failed`);return e.forEach((e=>{let i=this.getQueue(e);if(this.notify(`${t}-operation`,i),s)this.clearQueue(e);else{let t=this.getQueue(e);t.status="queued",this.setQueue(t),this.updateOperationStatus(t.id,t.status)}})),"retry"===t&&this.trackActivity(),this.updateUI(),n}catch(s){return await window.jvbError.log(s,{component:"Queue",operation:"performQueueAction",action:t,operationIds:e,itemCount:e.length},(()=>this.opActions(e,t))),{success:!1,error:s.message}}}async processQueue(){if(this.isProcessing)return;const e=this.getQueueByStatus("queued");if(0!==e.length){this.setProcessing();for(const t of e)await this.processOperation(t);this.setProcessing(!1),this.stopActivityTracking()}else this.stopActivityTracking()}async processOperation(e){try{this.queue.has(e.id)||this.queue.set(e.id,e);let t,s=!1;if(e.data?._isFormData&&!e.data instanceof FormData&&(s=!0,e.data=await this.store.objectToFormData(e.data)),this.updateOperationStatus(e.id,"uploading"),e.data instanceof FormData?(e.data.append("id",e.id),e.data.append("user",this.user),t=e.data):(t=JSON.stringify({...e.data,id:e.id,user:this.user}),e.headers["Content-Type"]="application/json"),null==t)return;const i=await fetch(`${this.api}${e.endpoint}`,{method:e.method,headers:e.headers,body:t}),n=await i.json();if(s&&(e.data={}),!i.ok||!n.success)throw new Error(n.message||`HTTP ${i.status}`);n.id&&e.id!==n.id?e=await this.handleServerMerge(e,n):(e.status=n.status??"pending",e.serverData=n,this.updateOperationStatus(e.id,e.status)),this.a11y.announce(`${e.title} sent to server for processing`),this.setQueue(e)}catch(t){console.error("Operation failed: ",t),e.retries++,e.lastError=t.message,e.retries>=3?e.status="failed_permanent":e.status="failed",this.updateOperationStatus(e.id,e.status),this.setQueue(e)}}async handleServerMerge(e,t){const s=this.getQueue(t.id);return s?(e.status=t.status||"pending",e.serverData=t,this.mergeOp(s,e)):(this.clearQueue(e.id),this.setQueue(t),t)}mergeOp(e,t){return e.data=window.deepMerge(e.data,t.data),e.status=t.status,Object.hasOwn(t,"serverData")&&(e.serverData=t.serverData),this.updateOperationStatus(e.id,e.status),this.removeOperationUI(t.id),this.clearQueue(t.id),e}sortByDate(e){return e.sort(((e,t)=>(e.updated_at??e.timestamp??0)-(t.updated_at??t.timestamp??0)))}getAllQueue(){let e=[...new Set([...Array.from(this.store.data.values()),...Array.from(this.queue.values())])];return this.sortByDate(e)}getQueueByStatus(e){"string"==typeof e&&(e=[e]);let t=[...new Set([...Array.from(this.store.filterByIndex({status:e})),...Array.from(this.queue.values()).filter((t=>e.includes(t.status)))])];return this.sortByDate(t)}updateOperationStatus(e,t){let s=this.getQueue(e);s&&this.statuses.includes(t)&&(s.status=t,this.notify("operation-status",s),this.setQueue(s))}setQueue(e){this.store.save(e),this.queue.set(e.id,e)}getQueue(e){return this.queue.has(e)?this.queue.get(e):this.store.get(e)}clearQueue(e){this.queue.delete(e),this.store.delete(e)}maybeStartPolling(){return this.getQueueByStatus(this.pendingStatuses).length>0&&(this.startPolling(),!0)}startPolling(){this.isPolling||(this.isPolling=!0,this.updatePanel("pending"),this.pollTimer=setInterval((async()=>{try{this.store.clearCache(),await this.store.fetch(),this.maybeStartPolling()||(this.stopPolling(),this.updatePanel("synced"))}catch(e){console.error("Polling error:",e)}}),5e3),this.startCountdown())}stopPolling(){this.isPolling&&(this.isPolling=!1,this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),this.stopCountdown())}startCountdown(e=5){this.isPolling&&(this.ui.refresh.countdown.textContent=e,this.countdownTimer=setInterval((async()=>{--e>=0?this.ui.refresh.countdown.textContent=e:(this.ui.refresh.countdown.textContent="",this.stopCountdown())}),1e3))}stopCountdown(){this.countdownTimer&&(clearInterval(this.countdownTimer),this.countdownTimer=null)}updateUI(){this.canUpdateUI&&window.debouncer.schedule("queue-ui",this.handleUpdateUI.bind(this))}handleUpdateUI(){const e=this.getAllQueue();this.ui.actions.retry.disabled=0===e.filter((e=>"failed"===e.status)).length,this.ui.actions.clear.disabled=0===e.filter((e=>"completed"===e.status)).length;for(let t of this.statuses){if("failed_permanent"===t)continue;let s=e.filter((e=>e.status===t)).length;this.ui.filters[t].label.hidden=0===s,this.ui.filters[t].input.dataset.count=`${s}`,this.ui.filters[t].count.textContent=s>0?s:""}this.renderOperations()}renderOperations(){if(!this.ui.items.container)return;const e=this.store.filters?.status??"all",t="all"===e?this.getAllQueue():this.getQueueByStatus(e);if(window.removeChildren(this.ui.items.container),0===t.length){const e=window.getTemplate("emptyQueue");return this.ui.items.container.append(e),void this.a11y.announce("No items in queue")}t.forEach((e=>{let t=this.items.get(e.id);t||(t=this.createOperationElement(e)),t?.element&&(this.updateOperationUI(e.id),this.ui.items.container.append(t.element))}))}createOperationElement(e){const t=window.getTemplate("queueItem");t.dataset.id=e.id;const s={element:t,ui:window.uiFromSelectors(this.selectors.item,t)};return this.items.set(e.id,s),s}updateOperationUI(e){let t=this.items.has(e)?this.items.get(e):this.createOperationElement(e);if(!t)return;let s=this.getQueue(e),i=t.element;i.classList.remove(this.statuses),i.classList.add(s.status);let n=this.getProgress(s);t.ui.type&&t.ui.type.textContent!==s.title&&(t.ui.type.textContent=s.title),t.ui.status&&(t.ui.status.title=this.statusLabel(s.status)),t.ui.icon&&(t.ui.icon.className=`icon icon-${this.icons[s.status]}`),t.ui.details&&(t.ui.details.textContent=this.itemMessage(s)),t.ui.startedAt&&(t.ui.startedAt.setAttribute("datetime",s.created_at),t.ui.startedAt.textContent=window.formatTimeAgo(s.created_at));let a="completed"===s.status?"Completed: ":"Last updated: ",r=Object.hasOwn(s,"updated_at")||Object.hasOwn(s,"completed_at");if(t.ui.completed.wrap.hidden=!r,r&&t.ui.completed.label&&t.ui.completed.time){let e;e=Object.hasOwn(s,"completed_at")?s.completed_at:s.updated_at,t.ui.completed.label.textContent=a,t.ui.completed.time.setAttribute("datetime",e),t.ui.completed.time.textContent=window.formatTimeAgo(e)}window.showProgress(t.ui.progress,n,100,this.statusLabel(s.status)),t.ui.actions.cancel&&(t.ui.actions.cancel.hidden=this.completedStatuses.includes(s.status)),t.ui.actions.retry&&(s.retries>=3&&(t.ui.actions.retry.disabled=!0),t.ui.actions.retry.hidden="failed"!==s.status),t.ui.actions.dismiss&&(t.ui.actions.dismiss.hidden=this.pendingStatuses.includes(s.status))}getProgress(e){if(e.progress)return e.progress;if(!this.statuses.includes(e.status))return 0;return{queued:10,uploading:25,pending:40,processing:70,completed:100,failed:0,failed_permanent:0}[e.status]??0}removeOperationUI(e){let t=this.items.get(e);t&&window.fade(t.element,!1)}updatePanel(e="syncing"){this.panelStatuses.includes(e)&&(this.ui.panel.classList.remove(this.panelStatuses),this.ui.panel.classList.add(e))}statusLabel(e){if(!this.statuses.includes(e))return"";return{queued:"Queued",localProcessing:"Processing locally",uploading:"Uploading",pending:"Waiting on server",processing:"Processing",completed:"Completed",failed:"Failed",failed_permanent:"Failed permanently"}[e]}itemMessage(e){if(Object.hasOwn(e,"message")&&""!==e.message)return e.message;if(Object.hasOwn(e,"error_message")&&e.error_message)return e.error_message;switch(e.status){case"queued":return"Waiting to send...";case"uploading":return"Sending to server...";case"pending":return e.position?`Position ${e.position} in queue`:"In server queue";case"processing":return e.progress?`${e.progress}% complete`:"Processing...";case"completed":return"Successfully completed";case"failed":return`Failed: ${e.lastError||"Unknown error"} (Retry ${e.retries}/${this.config.maxRetries})`;case"failed_permanent":return`Failed: ${e.lastError||"Unknown error"}`;default:return""}}toggleQueue(e=!0){this.ui.panel.hidden=!e,this.ui.toggle.button.hidden=!e}setProcessing(e=!0){this.isProcessing=e,this.ui.toggle.button.classList.toggle("saving",e)}subscribe(e){if(this.subscribers)return this.subscribers.add(e),()=>this.subscribers.delete(e)}notify(e,t){this.subscribers.forEach((s=>s(e,t)))}destroy(){this.isPolling&&this.stopPolling(),this.stopActivityTracking(),document.removeEventListener("click",this.clickHandler),this.subscribers.clear()}}document.addEventListener("DOMContentLoaded",(async function(){window.auth.subscribe((t=>{"auth-loaded"===t&&(window.jvbQueue=new e)}))}))})();
\ No newline at end of file
diff --git a/assets/js/min/selector.min.js b/assets/js/min/selector.min.js
index b5270ef..1714dda 100644
--- a/assets/js/min/selector.min.js
+++ b/assets/js/min/selector.min.js
@@ -1 +1 @@
-(()=>{class e{constructor(){this.container=document.querySelector("dialog#jvb-selector"),this.container&&(this.a11y=window.jvbA11y,this.error=window.jvbError,this.subscribers=new Set,this.fields=new Map,this.selectedTerms=new Map,this.loadedTaxonomies=new Set,this.batchFetch=new Set,this.activeField=null,this.isInitializing=!0,this.init())}init(){this.initStore(),this.initElements(),this.initModal(),this.scanExistingFields(),this.initListeners(),this.needsCreator()&&window.jvbTaxCreator&&(this.creator=new window.jvbTaxCreator(this)),this.isInitializing=!1,this.batchFetchTaxonomies().then((()=>{}))}initStore(){const e=window.jvbStore.register("taxonomies",{storeName:"terms",keyPath:"id",showLoading:!1,indexes:[{name:"taxonomy",keyPath:"taxonomy"},{name:"parent",keyPath:"parent"},{name:"slug",keyPath:"slug",unique:!0},{name:"count",keyPath:"count"}],endpoint:"terms",TTL:12e4,filters:{taxonomy:"",page:1,search:"",parent:0},required:"taxonomy",delayFetch:!0});this.store=e.terms,this.store.subscribe(this.handleStoreEvent.bind(this))}initElements(){this.selectors={search:{input:"[type=search]",clear:".clear-search",container:".search-wrapper",results:".search-results"},terms:{list:".items-container",wrap:".items-wrap",sentinel:".scroll-sentinel"},nav:{nav:"nav.term-navigation",back:".back-to-parent",child:".toggle-children",pathLevel:".path-level"},loading:{loading:".loading",text:".loading span"},selected:".selected-items",modal:{title:"#modal-title",content:".modal-content",count:".selection-count"},favourites:".favourite-terms",field:{toggle:"button.taxonomy-toggle",value:'input[type="hidden"]',selected:".selected-items",dropdown:".search-results",search:"[data-autocomplete]"}},this.ui=window.uiFromSelectors(this.selectors)}initListeners(){this.observer=new IntersectionObserver((e=>{e.forEach((e=>{e.isIntersecting&&this.nextPage()}))}),{root:this.ui.terms.sentinel,threshold:.5}),this.clickHandler=this.handleClick.bind(this),this.changeHandler=this.handleChange.bind(this),this.inputHandler=this.handleInput.bind(this),this.focusHandler=this.handleFocus.bind(this),this.blurHandler=this.handleBlur.bind(this),document.addEventListener("click",this.clickHandler),document.addEventListener("change",this.changeHandler),document.addEventListener("input",this.inputHandler),document.addEventListener("focus",this.focusHandler,!0),document.addEventListener("blur",this.blurHandler,!0)}handleClick(e){const t=this.getFieldId(e.target),i=this.fields.get(t);if(!t||!i)return;const s=window.targetCheck(e,"[data-autocomplete-select]");if(s){let e=parseInt(s.dataset.id);this.addSelected(e,t),i.ui.dropdown&&(i.ui.dropdown.hidden=!0),i.ui.search&&(i.ui.search.value="")}if(window.targetCheck(e,i.ui.toggle))return e.preventDefault(),void this.openModal(t);const n=window.targetCheck(e,"button.remove-item");if(n){const e=this.getFieldId(n),t=n.closest(".selected-item").dataset.id??!1;return void(e&&t&&this.removeSelected(t,e))}if(e.target.matches(".modal-close"))return void this.modal?.handleClose();if(window.targetCheck(e,this.selectors.nav.back))return void this.navigateToParent();if(window.targetCheck(e,this.selectors.nav.child)){const t=e.target.closest("li"),i=parseInt(t.dataset.id);return void(i&&this.navigateTo(i))}const r=window.targetCheck(e,this.selectors.nav.pathLevel);if(r){const e=parseInt(r.dataset.id)??0;this.navigateTo(e)}if(window.targetCheck(e,i.selectors.dropdown))return void this.scheduleHideDropdown(t);if(window.targetCheck(e,this.selectors.search.clear)){const e=this.currentField();e&&e.ui.search&&(e.ui.search.value="",this.store.setFilters({search:"",page:1,parent:this.store.filters.parent||0})),this.ui.search.input&&(this.ui.search.input.value="")}}handleChange(e){if(!this.container.contains(e.target))return;if("checkbox"!==e.target.type)return;e.preventDefault(),e.stopPropagation();const t=parseInt(e.target.dataset.id);let i=this.getFieldId(e.target);e.target.checked?this.addSelected(t,i):this.removeSelected(t,i)}handleInput(e){let t=this.getFieldId(e.target)??this.activeField;if(!t)return;const i=this.fields.get(t);if(!i)return;this.container.open||(this.activeField=t);const s=e.target.value.trim();window.debouncer.schedule(`${t}-search`,(async()=>{await this.store.setFilters({taxonomy:i.taxonomy,search:s,page:1,parent:s?0:this.store.filters.parent||0}),this.container.open&&window.removeChildren(this.ui.terms.list)}),100)}handleFocus(e){const t=this.getFieldId(e.target),i=this.fields.get(t);t&&i&&(i.hasAutocomplete||i.hasSearch)&&(window.debouncer.cancel(`${t}-search-results`),this.container.open||(this.activeField=t,this.preloadTaxonomy(i.taxonomy)))}handleBlur(e){const t=this.getFieldId(e.target),i=this.fields.get(t);t&&i&&i.hasAutocomplete&&this.scheduleHideDropdown(t)}scheduleHideDropdown(e){const t=this.fields.get(e);t&&window.debouncer.schedule(`${e}-search-results`,(()=>{this.activeField=null,t.ui.dropdown.hidden=!0}),1500)}initModal(){this.modalID="dialog#jvb-selector",this.container=document.querySelector(this.modalID),this.modal=new window.jvbModal(this.container,{handleForm:!1,save:null,open:null}),this.modal.subscribe(((e,t)=>{e}))}toggleModal(e,t=!0){this.fields.get(e)&&(t?this.openModal(e):this.closeModal())}openModal(e){const t=this.fields.get(e);if(!t)return;this.activeField=e,this.ui.modal.title.textContent=`Select ${t.plural}`,this.ui.search.container&&(this.ui.search.container.hidden=!t.canSearch),this.ui.create.details&&(this.ui.create.details.hidden=!t.canCreate,this.ui.create.summary&&(this.ui.create.summary.textContent=`Add new ${t.singular}`),this.ui.create.label.name&&(this.ui.create.label.name.textContent=`Name this ${t.singular}`),this.ui.create.label.parent&&(this.ui.create.label.parent.textContent="Nest it under"));let i=`Opened ${t.singular} selection. Choose from checkboxes, or search to filter results.`;window.removeChildren(this.ui.terms.list),this.modal.handleOpen(),this.setLoading(),this.store.setFilters({taxonomy:t.taxonomy,page:1,search:"",parent:0}),this.a11y.announce(i)}closeModal(){this.modal.handleClose();const e=this.fields.get(this.activeField);if(!e)return;this.observer.unobserve(this.ui.terms.sentinel),window.removeChildren(this.ui.terms.list),this.notify("selected-terms",{terms:this.selectedTerms.get(this.activeField),taxonomy:e.taxonomy}),this.activeField=null;let t=`Closed ${e.singular} selector.`;this.a11y.announce(t)}navigateToParent(){const e=this.store.filters.parent;if(0===e)return;let t=this.store.get(parseInt(e));if(!t)return;let i=t.parent;this.navigateTo(parseInt(i))}navigateTo(e=0){e=parseInt(e)??0,this.store.setFilters({parent:e,page:1}),window.removeChildren(this.ui.terms.list),this.updateBreadcrumbs(e)}nextPage(){let e=this.store.filters.page,t=Math.min(e++,this.store.lastResponse.total);this.store.setFilters({page:t})}prevPage(){let e=this.store.filters.page,t=Math.max(e-1,1);this.store.setFilters({page:t})}addTermToModal(e){const t=this.store.get(e);if(!t)return;const i=window.getTemplate("selectedTerm");i.dataset.id=e,i.querySelector("span").textContent=t.path,i.querySelector("button").title=`Remove ${name}`,this.ui.selected.append(i)}scanExistingFields(e=document.body){e.querySelectorAll('[data-type="selector"]').forEach((e=>{try{this.registerField(e)}catch(t){this.error.log(t,{component:"TaxonomySelector",action:"scanExistingFields",container:e.dataset.name})}}))}registerField(e,t={}){let i=e.querySelector('input[type="hidden"]');if(!i)return void console.warn("TaxonomySelector: No hidden input found for field",e);"fieldId"in e.dataset||(e.dataset.fieldId=window.generateID("selector"));const s=e.dataset.fieldId;let n=this.selectors.field,r=e.querySelector("button.taxonomy-toggle");if(0===t.size){if(!r)return;if(0===(t=r.dataset).size)return}else Object.hasOwn(t,"toggle")&&(r=document.querySelector(t.toggle),n.toggle=t.toggle);const a={id:s,value:i,element:e,taxonomy:t.taxonomy??!1,singular:t.single??"",plural:t.plural??"",name:e.dataset.field,canSearch:Object.hasOwn(t,"search"),limit:t.limit??0,hasAutocomplete:Object.hasOwn(t,"autocomplete"),canCreate:Object.hasOwn(t,"creatable"),isRequired:Object.hasOwn(t,"required"),toggle:r,selectors:n,ui:window.uiFromSelectors(n,e),checked:!1};return a.taxonomy?(this.fields.set(s,a),this.setSelectedFromValue(i),this.isInitializing&&this.batchFetch.add(a.taxonomy),this.updateFieldUI(s),s):void 0}setSelectedFromValue(e,t){let i=new Set;t.value.value.trim().split(",").map((e=>parseInt(e.trim()))).filter((e=>!isNaN(e))).forEach((e=>i.add(e))),this.selectedTerms.set(e,i)}addSelected(e,t=null){t||(t=this.activeField);const i=this.fields.get(t),s=this.store.get(e);if(!i||!s)return;const n=this.selectedTerms.get(t);0!==i.limit&&n.size>=i.limit||(n.add(parseInt(e)),this.addTermToDisplay(e,t),this.updateFieldValue(t),this.checkLimits(t))}removeSelected(e,t=null){t||(t=this.activeField);const i=this.fields.get(t),s=this.store.get(e);if(!i||!s)return;this.selectedTerms.get(t).delete(parseInt(e));const n=i.ui.selected.querySelector(`[data-i"${e}"]`);if(n&&n.remove(),this.container.open){let t=this.ui.selected.querySelector(`[data-id="${e}"]`);t&&t.remove()}this.updateFieldValue(t),this.checkLimits(t)}updateFieldValue(e){const t=this.fields.get(e);if(!t)return;let i=Array.from(this.selectedTerms.get(e));t.ui.value=i.join(",")}checkLimits(e){if(!this.container.open)return;const t=this.fields.get(e);if(!t||0===t.limit)return;const i=this.selectedTerms.get(e).size>=t.limit;this.setCheckboxes(i)}updateFieldFromInput(e){const t=this.getFieldId(e),i=this.fields.get(t);t&&i&&(this.setSelectedFromValue(t,e),this.updateFieldUI(t))}updateFieldUI(e){const t=this.fields.get(e);let i=this.selectedTerms.get(e);t&&0!==i.size&&Array.from(i).forEach((t=>{this.addTermToDisplay(t,e)}))}updateFieldsForTaxonomy(e){let t=Array.from(this.fields.values()).filter((t=>!t.checked&&t.taxonomy===e));const i=Array.from(this.store.data.values()).some((t=>t.taxonomy===e));t.forEach((e=>{e.ui.toggle.disabled=!i&&!e.canCreate,e.ui.toggle.title=i?`Select ${e.plural}`:`No ${e.singular} available`,e.checked=!0}))}showModalTerms(e=!0,t=!1){const i=this.store.getFiltered();if(0===i.size)return;e||window.removeChildren(this.ui.terms.list);const s=this.store.filters.parent??0;this.ui.nav.back.hidden=0===s;const n=document.createDocumentFragment();i.forEach((e=>{const i=this.createTermElement({show:t,...e});i&&n.appendChild(i)})),this.ui.terms.list.append(n)}createTermElement(e){if(!e||!e.name)return null;const t=window.getTemplate("termListItem");t.dataset.id=e.id;const i=this.selectedTerms.get(this.activeField).has(e.id);let[s,n,r]=[t.querySelector("input"),t.querySelector("label"),t.querySelector("span, .term-name")],a=this.currentField(),o=a.limit>0&&this.selectedTerms.get(this.activeField).size>=a.limit;if(s&&n&&r&&([s.id,s.name,s.value,s.disabled,s.checked,n.htmlFor,n.title,n.dataset.path,r.textContent]=[`${a.element.id}-${e.id}`,`${a.container.id}-${a.taxonomy}-select`,e.id,!i&&o,i,`${a.element.id}-${e.id}`,e.path??e.name,e.path,e.show?e.path:e.name],e.hasChildren)){const i=window.getTemplate("termChildrenToggle");i&&(i.ariaLabel=`View ${a.plural} nested under ${e.name}`,t.append(i))}return t}showAutocompleteTerms(){const e=this.currentField(),t=this.currentTerms();if(!e||0===t.size)return;const i=e.ui.dropdown;window.removeChildren(i),0===t.length?this.showEmptyState(`No ${e.plural} found.`,i):t.forEach((e=>{const t=this.createAutocompleteTerm(e);t&&i.append(t)}));const s=e.ui.search?.value;if(e.canCreate&&s.length>=2&&this.creator){const e=this.createTermButton(s);e&&i.append(e)}i.hidden=!1}createAutocompleteTerm(e){const t=window.getTemplate("autocompleteItem");if(t)return t.dataset.id=e.id,t.textContent=e.path||e.name,t}addTermToDisplay(e,t){const i=this.store.get(e),s=this.fields.get(t);if(!i||!s)return;if(s.ui.selected.querySelector(`[data-id="${e}"]`))return;const n=window.getTemplate("selectedTerm");if(n&&(n.dataset.id=e,n.dataset.taxonomy=s.taxonomy,n.querySelector(".item-name").textContent=i.path,n.querySelector("button").title=`Remove ${i.name}`,s.ui.selected.append(n),this.container.open)){this.addTermToModal(e);const t=this.ui.terms.list.querySelector(`input[value="${e}"]`);t&&(t.checked=!0)}}createTermButton(e){const t=window.getTemplate("autocompleteButton");if(!t)return;return t.querySelector("span").textContent=`"${e}"`,t}updateBreadcrumbs(e){const t=this.ui.nav.nav;if(!t)return;const i=Array.from(t.children).find((t=>parseInt(t.dataset.id)===e));if(i){let e=i.nextElementSibling;for(;e;){const t=e;e=e.nextElementSibling,t.remove()}}else{const i=this.store.get(e);if(!i)return;const s=window.getTemplate("termBreadcrumb");if(!s)return;s.dataset.id=e,s.textContent=i.name,s.title=i.name,t.append(s)}}updateSelectionCount(){if(!this.container.open)return;const e=this.fields.get(this.activeField);if(e&&this.ui.modal.count){const t=this.selectedTerms.get(this.activeField).size;this.ui.modal.count.textContent=e.limit>0?`${t} of ${e.limit} ${e.plural} selected`:`${t} ${e.plural} selected`}}currentField(){return this.fields.get(this.activeField)??!1}currentTerms(){return this.store.getFiltered()}needsCreator(){return Array.from(this.fields.values()).some((e=>e.canCreate||e.hasAutocomplete))}getFieldId(e){if(e.dataset.fieldId)return e.dataset.fieldId;const t=e.closest("[data-field-id]");return t?.dataset.fieldId||null}setCheckboxes(e){this.ui.terms.list.querySelectorAll("input[type=checkbox]").forEach((t=>{t.checked||(t.disabled=e)}))}handleStoreEvent(e,t){const i={"data-loaded":()=>this.handleDataLoaded(),"filters-changed":()=>this.handleFiltersChanged(),"fetch-error":()=>this.handleFetchError()};i[e]?.()}handleDataLoaded(){const e=this.store.filters.taxonomy;if(e?.includes(",")){e.split(",").map((e=>e.trim())).forEach((e=>this.updateFieldsForTaxonomy(e)))}this.container.open?this.showResults():this.activeField&&this.showResults(!0)}showResults(e=!1){this.setLoading(!1);const t=this.store.getFiltered(),i=this.store.filters,s=this.store.lastResponse?.page||{},n=i.search&&i.search.length>0,r=i.page>1,a=this.currentField();this.notify("terms-loaded",{terms:t,filters:i}),0===t.length?(r||this.showEmptyState(n?`No matching ${a.plural}.`:`No ${a.plural} available.`),this.observer.unobserve(this.ui.terms.sentinel)):e?this.showAutocompleteTerms():(this.showModalTerms(r,n),s.has_more?this.observer.observe(this.ui.terms.sentinel):this.observer.unobserve(this.ui.terms.sentinel)),this.a11y.announce(t.length,r)}handleFiltersChanged(){}handleFetchError(e){this.setLoading(!1)}async batchFetchTaxonomies(){if(0===this.batchFetch.size)return;const e=Array.from(this.batchFetch);e.forEach((e=>this.loadedTaxonomies.add(e))),this.batchFetch.clear();try{e.forEach((e=>this.loadedTaxonomies.add(e))),await this.store.setFilters({taxonomy:e.join(","),page:1,search:"",parent:0})}catch(e){console.error("Failed to batch fetch taxonomies:",e)}}preloadTaxonomy(e){this.loadedTaxonomies.has(e)||(this.store.setFilters({taxonomy:e,page:1,search:"",parent:0}),this.loadedTaxonomies.add(e))}setLoading(e=!0){if(this.ui.loading.loading.hidden=e,this.modal.classList.toggle("loading",e),e){let e=this.store.filters.search||"";e=""!==e&&e;const t=this.store.filters.parent||0,i=e?`Searching for "${e} items`:0===t?"loading items":"loading child items";window.typeLoop&&this.ui.loading.text?this.stopTyping=window.typeLoop(this.ui.loading.text,i):this.ui.loading.text.textContenet=i}else this.stopTyping&&(this.stopTyping(),this.stopTyping=null)}showEmptyState(e="No items found.",t=null){t||(t=this.ui.terms.list);const i=window.getTemplate("noTermResults"),s=i.querySelector("span");e&&s&&(s.textContent=e),t.append(i)}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}notify(e,t={}){this.subscribers.forEach((i=>{try{i(e,t)}catch(e){console.error("Subscriber error:",e)}}))}destroy(){document.removeEventListener("click",this.clickHandler),document.removeEventListener("change",this.changeHandler),document.removeEventListener("input",this.inputHandler),document.removeEventListener("focus",this.focusHandler),document.removeEventListener("blur",this.blurHandler),this.observer?.disconnect(),this.subscribers.clear(),this.fields.clear(),this.selectedTerms.clear()}}document.addEventListener("DOMContentLoaded",(function(){window.auth.subscribe((t=>{"auth-loaded"===t&&(window.jvbSelector=new e)}))}))})();
\ No newline at end of file
+(()=>{class e{constructor(){this.container=document.querySelector("dialog#jvb-selector"),this.container&&(this.a11y=window.jvbA11y,this.error=window.jvbError,this.subscribers=new Set,this.fields=new Map,this.selectedTerms=new Map,this.batchFetch=new Set,this.activeField=null,this.isInitializing=!0,this.messageText={},this.init())}init(){this.initStore(),this.initElements(),this.initModal(),this.scanExistingFields(),this.initListeners(),this.needsCreator()&&window.jvbTaxCreator&&(this.creator=new window.jvbTaxCreator(this)),this.isInitializing=!1,this.batchFetchTaxonomies().then((()=>{}))}initStore(){const e=window.jvbStore.register("taxonomies",{storeName:"terms",keyPath:"id",showLoading:!1,indexes:[{name:"taxonomy",keyPath:"taxonomy"},{name:"parent",keyPath:"parent"},{name:"slug",keyPath:"slug",unique:!0},{name:"count",keyPath:"count"}],endpoint:"terms",TTL:12e4,filters:{taxonomy:"",page:1,search:"",parent:0},required:"taxonomy",delayFetch:!0});this.store=e.terms,this.store.subscribe(this.handleStoreEvent.bind(this))}initElements(){this.selectors={search:{input:'[type="search"]',clear:".clear-search",container:".search-wrapper",results:".search-results"},create:{button:"button.submit-term",span:".submit-term span"},terms:{list:".items-container",wrap:".items-wrap",sentinel:".scroll-sentinel"},nav:{nav:"nav.term-navigation",back:".back-to-parent",child:".toggle-children",pathLevel:".path-level"},message:{message:"p.message",text:"p.message span"},selected:".selected-items",modal:{title:"#modal-title",content:".modal-content",count:".selection-count"},favourites:".favourite-terms",field:{toggle:'button.taxonomy-toggle, [data-filter="taxonomy"]',value:'input[type="hidden"]',selected:".selected-items",dropdown:{list:".search-results",wrapper:".auto-wrapper"},create:{button:".auto-wrapper .submit-term",span:".auto-wrapper button span"},search:"input[data-autocomplete]",message:{message:"p.message",text:"p.message span"}}},this.ui=window.uiFromSelectors(this.selectors,this.container)}initListeners(){this.observer=new IntersectionObserver((e=>{e.forEach((e=>{e.isIntersecting&&this.nextPage()}))}),{root:this.ui.terms.sentinel,threshold:.5}),this.clickHandler=this.handleClick.bind(this),this.changeHandler=this.handleChange.bind(this),this.inputHandler=this.handleInput.bind(this),this.focusHandler=this.handleFocus.bind(this),this.blurHandler=this.handleBlur.bind(this),document.addEventListener("click",this.clickHandler),document.addEventListener("change",this.changeHandler),document.addEventListener("input",this.inputHandler),document.addEventListener("focus",this.focusHandler,!0),document.addEventListener("blur",this.blurHandler,!0)}handleClick(e){const t=this.getFieldId(e.target)||this.activeField,s=this.fields.get(t);if(!t||!s)return;const i=window.targetCheck(e,".item.autocomplete");if(i){let e=parseInt(i.dataset.id);this.addSelected(e,t),this.scheduleHideDropdown(t),s.ui.search&&(s.ui.search.value="")}if(window.targetCheck(e,this.selectors.field.toggle))return e.preventDefault(),void this.openModal(t);const r=window.targetCheck(e,".remove-term");if(r){const e=r.closest("[data-id]").dataset.id??!1;return void(t&&e&&this.removeSelected(parseInt(e),t))}if(e.target.matches(".modal-close"))return this.updateFieldValue(t),void this.modal?.handleClose();if(window.targetCheck(e,this.selectors.nav.back))return void this.navigateToParent();if(window.targetCheck(e,this.selectors.nav.child)){const t=e.target.closest("li"),s=parseInt(t.dataset.id);return void(s&&this.navigateTo(s))}const a=window.targetCheck(e,this.selectors.nav.pathLevel);if(a){const e=parseInt(a.dataset.id)??0;this.navigateTo(e)}window.targetCheck(e,this.selectors.field.dropdown)&&this.scheduleHideDropdown(t);if(window.targetCheck(e,this.selectors.search.clear)){const e=this.currentField();e&&e.ui.search&&(e.ui.search.value="",this.store.setFilters({search:"",page:1,parent:this.store.filters.parent||0})),this.ui.search.input&&(this.ui.search.input.value="")}if(this.creator){window.targetCheck(e,this.selectors.create.button)&&this.maybeCreateTerm(e).then((()=>{}))}}handleChange(e){if(!this.container.contains(e.target))return;if(!["checkbox","button"].includes(e.target.type))return;e.preventDefault(),e.stopPropagation();const t=parseInt(e.target.dataset.id);let s=this.getFieldId(e.target);e.target.checked?this.addSelected(t,s):this.removeSelected(t,s)}handleInput(e){let t=this.getFieldId(e.target)??this.activeField;if(!t)return;const s=this.fields.get(t);if(!s)return;if(["checkbox","button"].includes(e.target.type))return;e.preventDefault(),e.stopPropagation(),this.container.open||this.setField(t);let i=e.target.value.trim();this.setMessage(!0,`Searching for "${i}" in ${s.plural??"items"}`),window.debouncer.schedule(`${t}-search`,(async()=>{this.container.open&&window.removeChildren(this.ui.terms.list),await this.store.setFilters({taxonomy:s.taxonomy,search:i,page:1,parent:i?0:this.store.filters.parent||0})}),100)}setField(e){const t=this.fields.get(e);t?(this.activeField=e,this.setMessage(!0,`Loading ${t.plural}...`),this.resetFilters({taxonomy:t.taxonomy})):console.error("No field found...")}resetFilters(e){Object.hasOwn(e,"taxonomy")&&(e={page:1,search:"",parent:0,...e},this.store.setFilters(e))}handleFocus(e){const t=this.getFieldId(e.target),s=this.fields.get(t);t&&s&&(s.hasAutocomplete||s.hasSearch)&&(window.debouncer.cancel(`${t}-search-results`),this.container.open||this.setField(t))}handleBlur(e){const t=this.getFieldId(e.target),s=this.fields.get(t);t&&s&&s.hasAutocomplete&&!this.container.open&&(e.relatedTarget&&s.ui.dropdown.wrapper?.contains(e.relatedTarget)||this.scheduleHideDropdown(t))}scheduleHideDropdown(e){const t=this.fields.get(e);t&&window.debouncer.schedule(`${e}-search-results`,(()=>{this.container.open||(this.activeField=null),t.ui.dropdown.wrapper&&(t.ui.dropdown.wrapper.hidden=!0)}),1500)}initModal(){this.modalID="dialog#jvb-selector",this.container=document.querySelector(this.modalID),this.modal=new window.jvbModal(this.container,{handleForm:!1,open:null}),this.modal.subscribe(((e,t)=>{if("modal-close"===e)this.closeModal()}))}toggleModal(e,t=!0){this.fields.get(e)&&(t?this.openModal(e):this.closeModal())}openModal(e){const t=this.fields.get(e);if(!t)return;this.setField(e),this.ui.modal.title.textContent=t.isFilter?`Filter by ${t.singular}`:`Select ${t.plural}`,this.ui.search.container&&(this.ui.search.container.hidden=!t.canSearch),this.creator&&this.creator.handleOpen(t);let s=`Opened ${t.singular} selection. Choose from checkboxes, or search to filter results.`;window.removeChildren(this.ui.selected),window.removeChildren(this.ui.terms.list),this.modal.handleOpen(),this.a11y.announce(s)}closeModal(){const e=this.fields.get(this.activeField);if(!e)return;this.observer.unobserve(this.ui.terms.sentinel),window.removeChildren(this.ui.terms.list),this.notify("selected-terms",{terms:this.selectedTerms.get(this.activeField),taxonomy:e.taxonomy}),this.activeField=null;let t=`Closed ${e.singular} selector.`;this.a11y.announce(t)}navigateToParent(){const e=this.store.filters.parent;if(0===e)return;let t=this.store.get(parseInt(e));if(!t)return void this.navigateTo(0);let s=t.parent;this.navigateTo(parseInt(s))}navigateTo(e=0){e=parseInt(e)??0,this.store.setFilters({parent:e,page:1}),window.removeChildren(this.ui.terms.list),this.updateBreadcrumbs(e)}nextPage(){let e=this.store.filters.page,t=Math.min(e++,this.store.lastResponse.total);this.store.setFilters({page:t})}prevPage(){let e=this.store.filters.page,t=Math.max(e-1,1);this.store.setFilters({page:t})}addTermToModal(e){const t=this.store.get(e);if(!t)return;const s=this.currentField();if(!s)return;if(this.ui.selected.querySelector(`[data-id="${e}"]`))return;const i=window.getTemplate("selectedTerm");i&&(i.dataset.id=e,i.dataset.taxonomy=s.taxonomy,i.querySelector(".item-name").textContent=t.path,i.querySelector("button").title=`Remove ${t.name}`,this.ui.selected.append(i))}scanExistingFields(e=document.body){e.querySelectorAll('[data-type="selector"]').forEach((e=>{try{this.registerField(e)}catch(t){this.error.log(t,{component:"TaxonomySelector",action:"scanExistingFields",container:e.dataset.name})}}))}registerField(e,t={}){let s=e.querySelector('input[type="hidden"]');if(!s&&!Object.hasOwn(e.dataset,"filter"))return void console.warn("TaxonomySelector: No hidden input found for field",e);"fieldId"in e.dataset||(e.dataset.fieldId=window.generateID("selector"));const i=e.dataset.fieldId;let r=this.selectors.field;const a=Object.hasOwn(e.dataset,"filter")&&"taxonomy"===e.dataset.filter;let n=a?e:e.querySelector("button.taxonomy-toggle");if(0===Object.keys(t).length){if(!n)return;if(t={taxonomy:n.dataset.taxonomy,single:n.dataset.single,plural:n.dataset.plural,search:Object.hasOwn(n.dataset,"search"),autocomplete:Object.hasOwn(n.dataset,"autocomplete"),creatable:Object.hasOwn(n.dataset,"creatable")},0===Object.keys(t).length)return}else Object.hasOwn(t,"toggle")&&(n=document.querySelector(t.toggle),r.toggle=t.toggle);const o={id:i,value:s,element:e,taxonomy:t.taxonomy??!1,singular:t.single??"",plural:t.plural??"",name:e.dataset.field,canSearch:t.search??!1,limit:t.limit??0,hasAutocomplete:t.autocomplete??!1,canCreate:t.creatable??!1,isRequired:t.required??!1,isFilter:a,toggle:n,create:{button:null,span:null},selectors:r,ui:window.uiFromSelectors(r,e),checked:!1};if(a&&!o.ui.toggle&&(o.ui.toggle=e),o.taxonomy)return o.singular&&o.plural||(console.warn("TaxonomySelector: Field missing singular/plural labels",e),o.singular=o.taxonomy.replace("jvb_",""),o.plural=o.singular+"s"),this.fields.set(i,o),this.setSelectedFromValue(i,s),this.isInitializing&&this.batchFetch.add(o.taxonomy),this.updateFieldUI(i),i;console.error("TaxonomySelector: Field missing taxonomy",e)}setSelectedFromValue(e,t){if(!e)return;let s=this.fields.get(e);if(!s)return;if(!t&&!s.isFilter)return;let i=new Set;t&&t.value.trim().split(",").map((e=>parseInt(e.trim()))).filter((e=>!isNaN(e))).forEach((e=>i.add(e))),this.selectedTerms.set(e,i)}addSelected(e,t=null){t||(t=this.activeField);const s=this.fields.get(t),i=this.store.get(e);if(!s||!i)return;const r=this.selectedTerms.get(t);0!==s.limit&&r.size>=s.limit||(r.add(parseInt(e)),this.container.open||s.isFilter||this.updateFieldValue(t),this.addTermToDisplay(e,t),this.checkLimits(t))}removeSelected(e,t=null){t||(t=this.activeField);const s=this.fields.get(t),i=this.store.get(e);if(!s||!i)return;this.selectedTerms.get(t).delete(parseInt(e));const r=!!s.ui.selected&&s.ui.selected.querySelector(`[data-id="${e}"]`);if(r&&r.remove(),this.container.open){let t=!!this.ui.selected&&this.ui.selected.querySelector(`[data-id="${e}"]`);t&&t.remove();let s=this.ui.terms.list.querySelector(`[type=checkbox][data-id="${e}"]`);s&&(s.checked=!1)}this.container.open||s.isFilter||this.updateFieldValue(t),this.checkLimits(t)}updateFieldValue(e){const t=this.fields.get(e);if(!t)return;let s=Array.from(this.selectedTerms.get(e));t.ui.value.value=s.join(",")}checkLimits(e){if(!this.container.open)return;const t=this.fields.get(e);if(!t||!t.isFilter||0===t.limit)return;const s=this.selectedTerms.get(e).size>=t.limit;this.setCheckboxes(s)}updateFieldFromInput(e){const t=this.getFieldId(e);if(!t)return;this.fields.get(t)&&(this.setSelectedFromValue(t,e),this.updateFieldUI(t))}updateFieldUI(e){const t=this.fields.get(e);let s=this.selectedTerms.get(e)??new Set;t&&!t.isFilter&&0!==s.size&&Array.from(s).forEach((t=>{this.addTermToDisplay(t,e)}))}updateFieldsForTaxonomy(e){let t=Array.from(this.fields.values()).filter((t=>!t.checked&&t.taxonomy===e));const s=Array.from(this.store.data.values()).some((t=>t.taxonomy===e));t.forEach((e=>{e.toggle.disabled=!s&&!e.canCreate,e.toggle.title=s?`Select ${e.plural}`:`No ${e.singular} available`,e.checked=!0}))}showModalTerms(e=!1){const t=this.currentField(),s=this.store.getFiltered();0===s.length&&((this.store.filters.page??1)&&window.removeChildren(this.ui.terms.list),this.setMessage(!0,""===this.store.filters.search?`No matching ${t.plural}.`:`No ${t.plural} found.`,!1),this.ui.terms.sentinel&&this.observer.unobserve(this.ui.terms.sentinel)),this.setCreateButton(!0),this.ui.terms.sentinel&&(this.store.lastResponse?.has_more?this.observer.observe(this.ui.terms.sentinel):this.observer.unobserve(this.ui.terms.sentinel));const i=this.store.filters.parent??0;this.ui.nav.back.hidden=0===i;const r=document.createDocumentFragment();s.forEach((t=>{const s=this.createTermElement({show:e,...t});s&&r.append(s)})),s.length>0&&this.setMessage(!1),this.ui.terms.list.append(r)}createTermElement(e){if(!e||!e.name)return null;const t=window.getTemplate("termListItem");t.dataset.id=e.id;const s=this.selectedTerms.get(this.activeField).has(e.id);let[i,r,a]=[t.querySelector("input"),t.querySelector("label"),t.querySelector("span, .term-name")],n=this.currentField(),o=n.limit>0&&this.selectedTerms.get(this.activeField).size>=n.limit;if(i&&r&&a&&([i.dataset.id,i.id,i.name,i.value,i.disabled,i.checked,r.htmlFor,r.title,r.dataset.path,a.textContent]=[e.id,`${n.element.id}-${e.id}`,`${n.element.id}-${n.taxonomy}-select`,e.id,!s&&o,s,`${n.element.id}-${e.id}`,e.path??e.name,e.path,e.show?e.path:e.name],e.hasChildren)){const s=window.getTemplate("termChildrenToggle");s&&(s.ariaLabel=`View ${n.plural} nested under ${e.name}`,t.append(s))}return t}showAutocompleteTerms(){const e=this.currentField(),t=this.currentTerms();if(!e)return;const s=e.ui.dropdown.list;s&&(window.removeChildren(s),0===t.length?this.setMessage(!0,`No ${e.plural} found.`,!1):(t.forEach((e=>{const t=this.createAutocompleteTerm(e);t&&s.append(t)})),this.setMessage(!1)),this.setCreateButton(!0),e.ui.dropdown.wrapper&&(e.ui.dropdown.wrapper.hidden=!1))}createAutocompleteTerm(e){const t=window.getTemplate("autocompleteItem");if(t)return t.dataset.id=e.id,t.textContent=e.path||e.name,t}addTermToDisplay(e,t){const s=this.store.get(e),i=this.fields.get(t);if(!s||!i)return;if(i.ui.selected&&i.ui.selected.querySelector(`[data-id="${e}"]`))return;const r=window.getTemplate("selectedTerm");if(r&&(r.dataset.id=e,r.dataset.taxonomy=i.taxonomy,r.querySelector(".item-name").textContent=s.path,r.querySelector("button").title=`Remove ${s.name}`,i.ui.selected&&i.ui.selected.append(r),this.container.open)){this.addTermToModal(e);const t=this.ui.terms.list.querySelector(`input[value="${e}"]`);t&&(t.checked=!0)}}updateBreadcrumbs(e){const t=this.ui.nav.nav;if(!t)return;const s=Array.from(t.children).find((t=>parseInt(t.dataset.id)===e));if(s){let e=s.nextElementSibling;for(;e;){const t=e;e=e.nextElementSibling,t.remove()}}else{const s=this.store.get(e);if(!s)return;const i=window.getTemplate("termBreadcrumb");if(!i)return;i.dataset.id=e,i.textContent=s.name,i.title=s.name,t.append(i)}}updateSelectionCount(){if(!this.container.open)return;const e=this.fields.get(this.activeField);if(e&&this.ui.modal.count){const t=this.selectedTerms.get(this.activeField).size;this.ui.modal.count.textContent=e.limit>0?`${t} of ${e.limit} ${e.plural} selected`:`${t} ${e.plural} selected`}}currentField(){return this.fields.get(this.activeField)??!1}currentTerms(){return this.store.getFiltered()}needsCreator(){return Array.from(this.fields.values()).some((e=>e.canCreate||e.hasAutocomplete))}getFieldId(e){if(e.dataset.fieldId)return e.dataset.fieldId;const t=e.closest("[data-field-id]");return t?.dataset.fieldId||null}setCheckboxes(e){this.ui.terms.list.querySelectorAll("input[type=checkbox]").forEach((t=>{t.checked||(t.disabled=e)}))}handleStoreEvent(e,t){const s={"data-loaded":()=>this.handleDataLoaded(),"filters-changed":()=>this.handleFiltersChanged(t),"fetch-error":()=>this.handleFetchError()};try{s[e]?.(t)}catch(t){console.error(`Error handling store event "${e}":`,t),this.setMessage(!0,"An error occurred loading data",!1)}}handleDataLoaded(){const e=this.store.filters.taxonomy;if(e){e.split(",").map((e=>e.trim())).forEach((e=>this.updateFieldsForTaxonomy(e)))}this.container.open?this.showResults():this.activeField?this.showResults(!0):this.setMessage(!1)}showResults(e=!1){this.setMessage(!1);const t=this.store.getFiltered(),s=this.store.filters,i=s.search&&s.search.length>0;this.notify("terms-loaded",{terms:t,filters:s}),e?this.showAutocompleteTerms():this.showModalTerms(i),this.a11y.announce(t.length)}handleFiltersChanged(e){}handleFetchError(e){const t=this.currentField(),s=t?`Failed to load ${t.plural}`:"Failed to load data";this.setMessage(!0,s,!1),console.error("Store fetch error:",e)}async batchFetchTaxonomies(){if(0===this.batchFetch.size)return;const e=Array.from(this.batchFetch);this.batchFetch.clear();try{await this.store.setFilters({taxonomy:e.join(","),page:1,search:"",parent:0})}catch(e){console.error("Failed to batch fetch taxonomies:",e)}}preloadTaxonomy(e){this.store.setFilters({taxonomy:e,page:1,search:"",parent:0})}setCreateButton(e=!0){const t=this.currentField();if(!t||!t.canCreate||!this.creator)return;const s=this.container.open?this.ui:t.ui;if(!s.create?.button||!s.create?.span)return;const i=s.create.button,r=s.create.span,a=this.container.open?s.search.input:s.search;if(!a)return;let n=(this.currentTerms()??[]).map((e=>e.name)),o=a.value;const l=e&&o.length>=2&&!n.includes(o);i.hidden=!l,l&&(r.textContent=a.value??"")}async maybeCreateTerm(e){const t=this.currentField();if(!t)return;window.debouncer.cancel(`${t.id}-search-results`);let s={taxonomy:t.taxonomy,parent:this.store.filters.parent??0};if(this.container.open&&""===this.ui.search.input.value?(s.parent=this.creator.ui.parent.value??s.parent,s.name=this.creator.ui.name.value??!1):s.name=this.container.open?this.ui.search.input.value:t.ui.search.value,void 0!==s.parent&&s.name){this.setMessage(!0,`Creating "${s.name}"...`),this.setCreateButton(!1),this.container.open?window.removeChildren(this.ui.terms.list):(t.ui.search.disabled=!0,window.removeChildren(t.ui.dropdown.list),t.ui.dropdown.wrapper&&(t.ui.dropdown.wrapper.hidden=!1));let e=await this.creator.handleTermCreation(s);e&&this.addSelected(e.id,t.id),this.container.open||(t.ui.search.disabled=!1,t.ui.search.value=""),this.scheduleHideDropdown(t.id),this.setMessage(!1)}}setMessage(e=!0,t="",s=!0){const i=this.currentField();if(!i)return;const r=this.container.open||i.isFilter?this.ui:i.isFilter?null:i.ui;if(!r?.message?.message)return;t=""===t?`No ${i.plural??"items"} found.`:t;const a=r.message.message,n=r.message.text;a.hidden=!e,e?t&&n&&(s&&window.typeLoop&&n?(this.messageText[i.id]&&(this.messageText[i.id](),delete this.messageText[i.id]),this.messageText[i.id]=window.typeLoop(n,t)):n.textContent=t):this.messageText[i.id]&&(this.messageText[i.id](),delete this.messageText[i.id])}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}notify(e,t={}){this.subscribers.forEach((s=>{try{s(e,t)}catch(e){console.error("Subscriber error:",e)}}))}destroy(){this.fields.forEach(((e,t)=>{window.debouncer.cancel(`${t}-search`),window.debouncer.cancel(`${t}-search-results`)})),Object.keys(this.messageText).forEach((e=>{this.messageText[e]&&this.messageText[e]()})),this.messageText={},this.ui.terms?.sentinel&&this.observer?.unobserve(this.ui.terms.sentinel),this.observer?.disconnect(),document.removeEventListener("click",this.clickHandler),document.removeEventListener("change",this.changeHandler),document.removeEventListener("input",this.inputHandler),document.removeEventListener("focus",this.focusHandler,!0),document.removeEventListener("blur",this.blurHandler,!0),this.subscribers.clear(),this.fields.clear(),this.selectedTerms.clear(),this.batchFetch.clear(),this.creator&&(this.creator.destroy(),this.creator=null),this.store&&(this.store=null)}}document.addEventListener("DOMContentLoaded",(function(){window.auth.subscribe((t=>{"auth-loaded"===t&&(window.jvbSelector=new e)}))}))})();
\ No newline at end of file
diff --git a/assets/js/min/uploader.min.js b/assets/js/min/uploader.min.js
index 592fa25..7650155 100644
--- a/assets/js/min/uploader.min.js
+++ b/assets/js/min/uploader.min.js
@@ -1 +1 @@
-(()=>{class e{constructor(){this.a11y=window.jvbA11y,this.queue=window.jvbQueue,this.error=window.jvbError,this.subscribers=new Set,this.initStores(),this.initWorker(),this.fields=new Map,this.uploads=new Map,this.groups=new Map,this.selected=new Map,this.selectionHandlers=new Map,this.sortables=new Map,this.previewUrls=new Set,this.initElements(),this.initListeners()}initStores(){const{uploads:e,groups:t}=window.jvbStore.register("uploads",[{storeName:"uploads",keyPath:"id",indexes:[{name:"field",keyPath:"field"},{name:"status",keyPath:"status"},{name:"group",keyPath:"group"},{name:"src",keyPath:"src"}]},{storeName:"groups",keyPath:"id",indexes:[{name:"field",keyPath:"field"},{name:"src",keyPath:"src"}]}]);this.stores={uploads:e,groups:t,ready:[]},this.stores.uploads.subscribe(this.handleStores.bind(this,"uploads")),this.stores.groups.subscribe(this.handleStores.bind(this,"groups")),this.queue.subscribe(((e,t)=>{if(!["uploads","uploads/meta","uploads/groups"].includes(t.endpoint))return;const s=t.data instanceof FormData?t.data.get("fieldId"):t.data?.fieldId;if(s)switch(e){case"cancel-operation":this.handleOperationCancelled(s).then((()=>{}));break;case"operation-status":this.handleFieldStatus(s,t).then((()=>{}));break;case"operation-completed":this.handleOperationComplete(t,s).then((()=>{}));break;case"operation-failed":case"operation-failed-permanent":this.handleOperationFailed(t,s).then((()=>{}))}}))}storesReady(){return 2===this.stores.ready.length}handleStores(e,t){"data-ready"===t&&(this.stores.ready.push(e),this.storesReady()&&this.checkRecovery())}initWorker(){this.worker=null,this.workerState={worker:null,tasks:new Map,restart:{count:0,max:3},settings:{timeout:3e3,maxConcurrent:3,restartAfterTimeout:!0}}}initElements(){this.selectors={fields:{field:"[data-upload-field]",input:'input[type="file"]',dropZone:".file-upload-container",preview:".preview-wrap",grid:".item-grid.preview",progress:{progress:".file-upload-container .progress",fill:".file-upload-container .progress .fill",details:".file-upload-container .progress .details",icon:".file-upload-container .progress .icon"},selectAll:'[name="select-all-uploads"]',actions:".selection-actions",count:".selection-count",hidden:'input[type="hidden"]'},groups:{container:".group-display",grid:".item-grid.groups",empty:".empty-group",header:".sidebar .header"},group:{item:".upload-group",actions:".selection-actions",selectAll:'[name="select-all-group"]',count:".group-header .info",fields:"details .fields",grid:".item-grid.group",total:".group-content .group-count"},items:{item:"[data-upload-id]",checkbox:'[name*="select-item"]',featured:'[name="featured"]',image:"img",details:"details",progress:{progress:".progress",fill:".fill",details:".details",icon:".icon"}}}}initListeners(){this.clickHandler=this.handleClick.bind(this),this.changeHandler=this.handleChange.bind(this),this.dragEnterHandler=this.handleDragEnter.bind(this),this.dragLeaveHandler=this.handleDragLeave.bind(this),this.dragOverHandler=this.handleDragOver.bind(this),this.dropHandler=this.handleDrop.bind(this),document.addEventListener("click",this.clickHandler),document.addEventListener("change",this.changeHandler),document.addEventListener("dragenter",this.dragEnterHandler),document.addEventListener("dragleave",this.dragLeaveHandler),document.addEventListener("dragover",this.dragOverHandler),document.addEventListener("drop",this.dropHandler),window.addEventListener("beforeunload",(()=>{this.cleanupAllPreviewUrls()}))}async setUpload(e,t){const s={...{id:e,attachment:null,group:null,field:null,src:window.location.href,blob:null,status:"local_processing",operationId:null,fields:{}},...t};return Object.preventExtensions(s),await this.stores.uploads.save(s),s}createPreviewUrl(e){const t=URL.createObjectURL(e);return this.previewUrls.add(t),t}revokePreviewUrl(e){e?.startsWith("blob:")&&(URL.revokeObjectURL(e),this.previewUrls.delete(e))}formatFile(e){return e.blob?new File([e.blob],e.fields.originalName||"file",{type:e.fields.type||e.blob.type,lastModified:e.fields.lastModified||Date.now()}):null}handleClick(e){let t=window.targetCheck(e,this.selectors.fields.dropZone);t&&!e.target.matches("input, button, a")&&t.querySelector(this.selectors.fields.input)?.click();const s=window.targetCheck(e,"[data-action]");s&&this.handleAction(s)}handleAction(e){const t=e.dataset.action,s=this.getFieldIdFromElement(e);switch(t){case"add-to-group":this.handleAddToGroup(s).then((()=>{}));break;case"delete-group":this.handleDeleteGroup(e);break;case"delete-upload":case"remove-from-group":this.handleRemoveItem(e).then((()=>{}));break;case"upload":this.queueUploads("uploads/groups",s).then((()=>{}));break;case"restore":this.handleRestoreSelected().then((()=>{}));break;case"restore-all":this.handleRestoreAll().then((()=>{}));break;case"clear-cache":this.handleClearCache().then((()=>{}))}}handleChange(e){let t=this.getFieldIdFromElement(e.target);if(!t)return;if(e.target.matches(this.selectors.fields.input)){const s=Array.from(e.target.files);return void(s.length>0&&this.processFiles(t,s).then((()=>{})))}if(e.target.matches(this.selectors.items.checkbox)||e.target.matches(this.selectors.items.featured)||e.target.matches('[name*="select-"]'))return;let s=this.fields.get(t);s&&s.config.autoUpload&&("post_group"===s.config.destination?this.handleGroupMetaChange(e.target):this.queueUploadMeta(e).then((()=>{})))}handleGroupMetaChange(e){const t=e.closest(this.selectors.group.fields);if(!t)return;const s=t.dataset.groupId,r=this.stores.groups.get(s);r&&window.debouncer.schedule(`group-meta-${s}`,(async(e,t)=>{let s=e.name.replace(`${t}_`,"").replace(`${t}[`,"").replace("]","");r.fields[s]=e.value,await this.setGroup(t,r)}),300)}handleDragEnter(e){if(!e.dataTransfer.types.includes("Files"))return;const t=e.target.closest(this.selectors.fields.dropZone);t&&(e.preventDefault(),t.classList.add("dragover"))}handleDragLeave(e){const t=e.target.closest(this.selectors.fields.dropZone);t&&!t.contains(e.relatedTarget)&&t.classList.remove("dragover")}handleDragOver(e){if(!e.dataTransfer.types.includes("Files"))return;e.target.closest(this.selectors.fields.dropZone)&&(e.preventDefault(),e.dataTransfer.dropEffect="copy")}handleDrop(e){const t=e.target.closest(this.selectors.fields.dropZone);if(!t)return;e.preventDefault(),t.classList.remove("dragover"),t.classList.add("uploading");const s=Array.from(e.dataTransfer.files);if(0===s.length)return;const r=this.getFieldIdFromElement(t);r&&(this.processFiles(r,s).then((()=>{})),this.a11y.announce(`${s.length} file(s) dropped for upload`))}async queueUploads(e,t){let s=new FormData;const r=this.fields.get(t);if(!r)return;let i=this.stores.uploads.filterByIndex({field:t});if(0===i.length)return;const[o,a]=["uploads"===e,"uploads/groups"===e];let l,n,d,u,c;s.append("fieldId",r.id),s.append("content",r.config.content),o&&(s.append("mode",r.config.mode),s.append("field_name",r.config.name),s.append("fieldId",r.id),s.append("field_type",r.config.type),s.append("subtype",r.config.subtype),s.append("item_id",r.config.itemID),s.append("destination",r.config.destination)),a?({posts:l,uploadMap:n,files:d}=this.collectGroups(t)):o&&({uploadMap:n,files:d}=this.collectUploads(t)),a&&s.append("posts",JSON.stringify(l)),d.forEach((e=>{s.append("files[]",e)})),s.append("upload_ids",JSON.stringify(n)),o?(u=`Uploading ${i.length} file${i.length>1?"s":""} to server...`,c=`Uploading ${i.length} file${i.length>1?"s":""}...`):a&&(u=`Creating ${l.length} ${r.config.content}${l.length>1?"s":""} from uploads...`,c=`Creating ${l.length} post${l.length>1?"s":""}...`),await this.setBulkUpload(i,"status","queued");let p=this.sendToQueue(e,s,u,c);if("uploads/groups"===e){let e=r.element.closest("details");e&&(e.open=!1)}return p?(r.operationId=p,await this.setBulkUpload(i,"operationId",p),await this.setBulkUpload(i,"status","uploading"),await this.setBulkGroup(t,"operationId",p),this.fields.set(r.id,r)):await this.setBulkUpload(i,"status","failed"),this.notify("sent-to-queue",t),p}async sendToQueue(e,t,s="",r="",i=!1){""===r&&(r=s);const o={endpoint:e,method:"POST",data:t,title:s,popup:r,canMerge:i,sendNow:"uploads/groups"===e,headers:{action_nonce:window.auth.getNonce("dash")},append:"_upload"};try{return await this.queue.addToQueue(o)}catch(e){return this.error.log(e,{component:"UploadManager",action:"sentToQueue"}),!1}}collectGroups(e){let t=this.stores.uploads.filterByIndex({field:e}),s=this.stores.groups.filterByIndex({field:e}),r=[],i=[],o=[];for(const e of s){const s={images:[],fields:e.fields??{}},a=t.filter((t=>t.group===e.id));for(const e of a){const t=this.formatFile(e);if(t){o.push(t);const r={upload_id:e.id,index:i.length};let a=this.uploads.get(e.id);a.ui?.featured?.checked&&(s.fields.featured=e.id),s.images.push(r),i.push(e.id)}}r.push(s)}const a=t.filter((e=>!e.group));for(const e of a){const t={images:[],fields:{}},s=this.formatFile(e);if(s){o.push(s);const r={upload_id:e.id,index:i.length};t.images.push(r),i.push(e.id)}r.push(t)}return{posts:r,uploadMap:i,files:o}}collectUploads(e){let t=this.stores.uploads.filterByIndex({field:e});if(0===t.length)return;let s=[],r=[];for(const e of t){const t=this.formatFile(e);t&&(r.push(t),s.push(e.id))}return{uploadMap:s,files:r}}async queueUploadMeta(e){const t=e.target.closest(this.selectors.items.item)?.dataset.uploadId,s=this.stores.uploads.get(t);if(!t||!s)return;if(!this.fields.get(s.field))return;let r={};r[e.target.name]=e.target.value,s.fields={...s.fields,...r},await this.setUpload(s.id,s);let i={};return i[s.attachmentId??s.id]=s.fields,await this.sendToQueue("uploads/meta",i,"Uploading Meta","",!0)}async handleOperationComplete(e,t){const s=e.response;if(s?.data){const e=Array.isArray(s.data)?s.data:Object.values(s.data);for(const t of e)if(t.upload_id&&t.attachment_id){const e=this.stores.uploads.get(t.upload_id);e&&(e.attachmentId=t.attachment_id,e.status="completed",await this.stores.uploads.save(e))}}const r=this.stores.uploads.filterByIndex({field:t}),i=this.stores.groups.filterByIndex({field:t});await Promise.all([...r.filter((e=>"completed"===e.status)).map((e=>this.clearUpload(e.id))),...i.map((e=>this.stores.groups.delete(e.id)))]),this.notify("uploads-complete",{fieldId:t,response:s})}scanFields(e,t=!0){e.querySelectorAll(this.selectors.fields.field).forEach((e=>this.registerField(e,t)))}registerField(e,t=!0,s=null){const r={element:e,id:s||this.determineFieldId(e),config:this.extractFieldConfig(e,t),uploads:new Set,operationId:null,groups:[],ui:window.uiFromSelectors(this.selectors.fields,e),groupUI:window.uiFromSelectors(this.selectors.groups,e)};return this.fields.set(r.id,r),e.dataset.uploader=r.id,this.getSelectionHandler(r.id),"single"!==r.config.type&&this.initSortable(r.id),r.id}extractFieldConfig(e,t){return{autoUpload:t,destination:e.dataset.destination||"meta",content:this.extractFieldContent(e),mode:e.dataset.mode||"direct",type:e.dataset.type||"single",name:e.dataset.field,itemID:this.extractFieldItemId(e)??0,maxFiles:parseInt(e.dataset.maxFiles)??25,subType:e.dataset.subtype??"image"}}extractFieldContent(e){return e.dataset.content||e.closest("dialog")?.dataset.content||e.closest("form")?.dataset.save||null}extractFieldItemId(e){return e.dataset.itemId||e.closest("dialog")?.dataset.itemId||null}determineFieldId(e){let t=this.extractFieldContent(e);t=null===t?"":t+"_";let s=this.extractFieldItemId(e);s=null===s?"":s+"_";return`${t}${s}${e.dataset.field||""}`}getFieldIdFromElement(e){const t=e.closest(this.selectors.fields.field);return t?.dataset.uploader||null}updateFieldProgress(e,t,s,r){const i=this.fields.get(e);i&&window.showProgress(i.ui.progress,t,s,r)}getWorker(){return this.workerState.worker||"undefined"==typeof OffscreenCanvas||(this.workerState.worker=new Worker("worker.js"),this.workerState.worker.onmessage=e=>this.handleWorkerMessage(e),this.workerState.worker.onerror=e=>this.handleWorkerError(e)),this.workerState.worker}handleWorkerMessage(e){const{id:t,blob:s}=e.data,r=this.workerState.tasks.get(t);r&&(clearTimeout(r.timeoutId),r.resolve(s),this.workerState.tasks.delete(t))}handleWorkerError(e){this.workerState.tasks.forEach((t=>{clearTimeout(t.timeoutId),t.reject(e)})),this.workerState.tasks.clear(),this.restartWorker()}restartWorker(){this.workerState.worker&&(this.workerState.worker.terminate(),this.workerState.worker=null),this.workerState.restart.count++}async processImages(e,t=2200,s=2200){const r=[],i=[...e],o=this.workerState.settings.maxConcurrent,a=async()=>{for(;i.length>0;){const e=i.shift();r.push(await this.processImage(e,t,s))}};return await Promise.all(Array.from({length:Math.min(o,e.length)},(()=>a()))),r}async processImage(e,t=2200,s=2200,r=3e3){if("undefined"==typeof OffscreenCanvas)return this.resizeImage(e,t,s);try{return await this.withTimeout(this.workerImage(e,t,s),r)}catch(r){return this.resizeImage(e,t,s)}}withTimeout(e,t){return Promise.race([e,new Promise(((e,s)=>setTimeout((()=>s(new Error("Timeout"))),t)))])}async workerImage(e,t=2200,s=2200){const{settings:r,restart:i}=this.workerState;if(i.count>=i.max)throw new Error("Worker max restarts exceeded");const o=await createImageBitmap(e);let{width:a,height:l}=o;if(a>t||l>s){const e=Math.min(t/a,s/l);a=Math.round(a*e),l=Math.round(l*e)}const n=this.getWorker(),d=crypto.randomUUID();return new Promise(((t,s)=>{const i=setTimeout((()=>{this.workerState.tasks.delete(d),r.restartAfterTimeout&&this.restartWorker(),s(new Error("Timeout"))}),r.timeout);this.workerState.tasks.set(d,{resolve:t,reject:s,timeoutId:i}),n.postMessage({id:d,imageBitmap:o,width:a,height:l,type:e.type,quality:.9},[o])}))}resizeImage(e,t,s){return new Promise((r=>{const i=new Image;i.onload=()=>{URL.revokeObjectURL(i.src);let{width:o,height:a}=i;if(o>t||a>s){const e=Math.min(t/o,s/a);o=Math.round(o*e),a=Math.round(a*e)}const l=document.createElement("canvas");l.width=o,l.height=a,l.getContext("2d").drawImage(i,0,0,o,a),l.toBlob(r,e.type,.9)},i.src=URL.createObjectURL(e)}))}async processFiles(e,t){let s=this.fields.get(e);if(!s)return;s.groupUI.container&&(s.groupUI.container.hidden=!1);const r=t.length;let i=0;this.updateFieldProgress(e,0,r,"Processing files...");const o=await Promise.all(t.map((async t=>{const s=window.generateID("upload"),r=await this.setUpload(s,{id:s,field:e,status:"local_processing",blob:null,fields:{originalName:t.name,originalSize:t.size,type:t.type,lastModified:t.lastModified}}),i=await this.createUpload(s,t,e);return this.uploads.set(s,{element:i,ui:window.uiFromSelectors(this.selectors.items,i)}),await this.addToGroup(s,null),{uploadId:s,upload:r,file:t}}))),a=o.filter((e=>e.file.type.startsWith("image/"))),l=o.filter((e=>!e.file.type.startsWith("image/"))),n=await this.processImages(a.map((e=>e.file)));for(let t=0;t<a.length;t++){const{uploadId:s,upload:o}=a[t];o.blob=n[t],o.fields.size=n[t].size,o.status="queued",await this.setUpload(s,o),i++,this.updateFieldProgress(e,i,r,"Processing files...")}for(const{uploadId:t,upload:s,file:o}of l)s.blob=o,s.status="queued",await this.setUpload(t,s),i++,this.updateFieldProgress(e,i,r,"Processing files...");this.maybeLockUploads(e),s.config.autoUpload&&"post_group"!==s.config.destination&&await this.queueUploads("uploads",e)}async checkRecovery(){const e=this.stores.uploads.filterByIndex({status:["local_processing","queued","uploading"]});if(0===e.length)return;let t=window.getTemplate("restoreNotification");if(!t)return void this.error.log("No restore notification",{component:"UploadManager",src:window.location.href});const s=new Map;e.forEach((e=>{const t=e.src||"unknown";s.has(t)||s.set(t,[]),s.get(t).push(e)}));const r=window.location.href;let i=s.size>1?` across ${s.size} pages`:"",o=e.length>1?"uploads":"upload",a=`${e.length} ${o} can be recovered${i}`,l=t.querySelector(".details");l&&(l.textContent=a);let n=1;for(const[e,i]of s){let s=window.getTemplate("restoreField");if(!s)continue;let o=this.registerField(s,!1,"recovery_"+n),a=this.fields.get(o);n++;let l=e===r,[d,u,c]=[s.querySelector("h3"),s.querySelector("h3 a"),s.querySelector(".item-grid")];s.open=l,l?(u.remove(),d.textContent="From this page:"):[u.href,u.title,u.textContent]=[e,"Navigate to Page and Restore",e];let p=[...new Set(i.map((e=>e.group??"preview")))];for(let e of p){let t="preview"===e||this.stores.groups.get(e);if(!t)continue;let s=await this.createGroupElement(e,a.id),r=s.querySelector(".item-grid"),o=i.filter((t=>t.group===("preview"===e)?null:e));for(const[e,r]of Object.entries(t.fields??{})){let t=s.querySelector(`input[name*="${e}"]`);t&&(t.value=r)}for(let e of o){let t=await this.createUpload(e.id,this.formatFile(e),a.id);r.append(t)}c.append(s)}t.querySelector(".wrap").append(s)}document.body.append(t),t=document.querySelector("dialog.restore-uploads"),this.restoreModal=new window.jvbModal(t),this.restoreSelection=new window.jvbHandleSelection({container:t,wrapper:".restore-uploads .wrap",bulkControls:".selection-actions",selectAll:"#select-all-restore",count:".selection-count"}),this.restoreModal.handleOpen()}async handleRestoreSelected(){if(!this.restoreSelection)return;let e=Array.from(this.restoreSelection.selectedItems);0!==e.length&&await this.restoreSelectedUploads(e)}async handleRestoreAll(){if(!this.restoreModal)return;const e=Array.from(this.restoreModal.modal.querySelectorAll(".item.upload")).map((e=>e.dataset.uploadId));await this.restoreSelectedUploads(e)}async restoreSelectedUploads(e){let t=window.location.href,s=Array.from(this.stores.uploads.data.values()).filter((s=>e.includes(s.id)&&s.src===t)),r=[...new Set(s.map((e=>e.group)))].filter(Boolean),i=s[0].field;if(!document.querySelector(`[data-uploader="${i}"]`))return void console.log("No field found for "+i);let o=this.fields.get(i);o.groupUI.container&&(o.groupUI.container.hidden=!1);let a=[];for(let e of r){let t=this.stores.groups.get(e);await this.createGroup(i,e);let r=this.groups.get(e),o=s.filter((t=>t.group===e));if(t&&this.groups.has(e)){let e=t.fields;for(const[t,s]of Object.entries(e)){let e=r.element.querySelector(`input[name*="${t}"]`);e&&(e.value=s)}}else e=null;for(let t of o){let s=await this.createUpload(t.id,this.formatFile(t),i);this.uploads.set(t.id,{element:s,ui:window.uiFromSelectors(this.selectors.items,s)}),await this.addToGroup(t.id,e),a.push(t.id)}}let l=s.filter((e=>!a.includes(e.id)));for(let e of l){let t=await this.createUpload(e.id,this.formatFile(e),i);this.uploads.set(e.id,{element:t,ui:window.uiFromSelectors(this.selectors.items,t)}),await this.addToGroup(e.id,null)}this.cleanupRestore()}cleanupRestore(){this.restoreModal.handleClose(),this.restoreSelection.destroy(),this.restoreSelection=null,this.restoreModal.destroy(),this.restoreModal.modal.remove(),this.restoreModal=null}getStatusText(e){return{received:"Image Received",local_processing:"Processing Image...",queued:"Waiting to upload...",uploading:"Uploading to Server",pending:"Successfully sent to server. In line for further processing.",processing:"Processing on server...",completed:"Upload complete!",failed:"Upload failed (will retry)",failed_permanent:"Upload failed permanently"}[e]||e}getStatusProgress(e){return{local_processing:28,queued:50,uploading:66,pending:75,processing:89,completed:100}[e]??0}async createUpload(e,t,s){let r=window.getTemplate("uploadItem");if(!r)return null;let i=this.fields.get(s);if(!i)return null;r.dataset.uploadId=e;let o=this.getSubtypeFromMime(t.type)||"image";r.dataset.subtype=o;let[a,l,n,d,u]=[r.querySelector('[name="featured"]'),r.querySelector("img"),r.querySelector("video"),r.querySelector("label > span"),r.querySelector("details")];switch(a&&(a.value=e),o){case"image":if(l){const e=this.createPreviewUrl(t);l.src=e,l.alt=t.name||"",l.dataset.previewUrl=e}n?.remove(),d?.remove();break;case"video":if(n){const e=this.createPreviewUrl(t);n.src=e,n.dataset.previewUrl=e}l?.remove(),d?.remove();break;case"document":let e=t.name.split(".").pop()?.toLowerCase()??"",s={pdf:"file-pdf",csv:"file-csv",doc:"file-doc",docx:"file-doc",txt:"file-txt",xls:"file-xls",xlsx:"file-xls"},r=window.getIcon(s[e]??"file");d&&(d.innerText=t.name,d.prepend(r)),l?.remove(),n?.remove()}if(u){let e=window.getTemplate("uploadMeta");e&&u.append(e)}return r.draggable="single"!==i.config.type??!1,r.querySelectorAll("input").forEach((t=>{let s=t.id;if(s){let r=s+e,i=t.parentNode.querySelector(`label[for="${s}"]`);t.id=r,i&&(i.htmlFor=r)}})),r}getSubtypeFromMime(e){return e.startsWith("image/")?"image":e.startsWith("video/")?"video":"document"}async handleRemoveItem(e){const t=e.closest(this.selectors.items.item);if(!t)return;const s=t.dataset.uploadId;confirm("Remove this item?")&&(await this.removeUpload(s),this.a11y.announce("Item removed"))}async setBulkUpload(e,t,s){const r=Array.from(e).map((async e=>("status"===t&&await this.setUploadStatus(e,s),e[t]=s,this.stores.uploads.save(e))));await Promise.all(r)}async setUploadStatus(e,t){e.progress&&window.showProgress(e.progress,this.getStatusProgress(t),100,this.getStatusText(t),this.queue.icons[t]??"")}async removeUpload(e){let t=this.stores.uploads.get(e);if(!t)return;if(t.group){let s=this.stores.groups.get(t.group);s.uploads=s.uploads.filter((t=>t!==e)),0===s.uploads.length&&await this.removeGroup(s.id,!1)}await this.clearUpload(e),this.maybeLockUploads(t.field);let s=this.selectionHandlers.get(t.field);s&&s.deselect(e),this.a11y.announce("Upload removed")}async clearUpload(e){const t=this.uploads.get(e);if(t&&(this.revokePreviewUrl(t.preview),t.element)){const e=t.element.dataset.previewUrl;this.revokePreviewUrl(e),t.element.remove()}this.uploads.delete(e),await this.stores.uploads.delete(e)}async handleAddToGroup(e){const t=this.selected.get(e);if(!t||0===t.size)return;let s=await this.createGroup(e);s&&(await Promise.all(Array.from(t).map((e=>this.addToGroup(e,s)))),this.selectionHandlers.get(e)?.clearSelection(),this.a11y.announce(`Created group with ${t.size} items`))}async createGroup(e,t=null){let s=this.fields.get(e);if(!s)return;t||(t=window.generateID("group"));const r=this.createGroupElement(t,e);if(!r)return null;s.groupUI.grid.append(r);const i=r.querySelector(".item-grid");i&&(i.dataset.groupId=t,this.createSortable(e,i,t));let o=this.stores.groups.data.has(t)?this.stores.groups.data.get(t):{};return await this.setGroup(t,{...o,id:t,field:e}),t}createGroupElement(e,t=null){let s=window.getTemplate("imageGroup");if(!s)return;s.dataset.groupId=e,t&&(s.dataset.fieldId=t);const r=s.querySelector("[data-select-all]");if(r){const t=`select-all-${e}`,i=s.querySelector(`label[for="${r.id}"]`);r.id=t,r.name=t,i&&(i.htmlFor=t)}let i=window.getTemplate("groupMetadata"),o=s.querySelector(".fields");if(i&&o){o.append(i);let t=o.querySelector('[name="post_title"]'),s=o.querySelector('[name="post_excerpt"]');t&&(t.id=`${e}_title`,t.name=`${e}[post_title]`),s&&(s.id=`${e}_excerpt`,s.name=`${e}[post_excerpt]`)}else s.querySelector("details")?.remove();const a=s.querySelector(".item-grid");return a&&(a.dataset.groupId=e),this.groups.set(e,{element:s,ui:window.uiFromSelectors(this.selectors.group,s)}),s}async setGroup(e,t){const s={...{id:e,src:window.location.href,uploads:[],operationId:null,field:null,fields:{}},...t};Object.preventExtensions(s),await this.stores.groups.save(s)}async setBulkGroup(e,t,s){let r=this.stores.groups.filterByIndex({field:e});if(0===r.length)return;let i=r.map((e=>{e[t]=s,this.stores.groups.save(e)}));await Promise.all(i)}async addToGroup(e,t=null){const s=this.stores.uploads.get(e),r=this.uploads.get(e);if(!s||!r)return;const i=this.fields.get(s.field);if(!i)return;if(null!==r.element?.parentElement&&(!t&&null===s.group||t===s.group))return void this.handleReorder(s.field,t);if(s.group){const t=this.stores.groups.get(s.group);t&&(t.uploads=t.uploads.filter((t=>t!==e)),0===t.uploads.length&&await this.removeGroup(t.id,!1))}if(r.ui.checkbox&&(r.ui.checkbox.checked=!1),this.selected.get(s.field)?.has(e)&&this.selected.get(s.field).delete(e),r.ui.featured&&(r.ui.featured.hidden=!t),t){r.ui.featured&&(r.ui.featured.name=`${t}_featured`);let i=this.stores.groups.get(t);i&&(i.uploads.push(e),s.group=t,this.stores.groups.save(i))}else s.group=null;let o=t?this.groups.get(t)?.ui.grid:i.ui.grid;o&&o.append(r.element),this.stores.uploads.save(s)}handleDeleteGroup(e){const t=e.closest(this.selectors.group.item);if(!t)return;let s=t.dataset.groupId;if(!confirm("Delete this group? Items will be moved back to the upload area."))return;let r=this.stores.uploads.filterByIndex({group:s});Promise.all(r.map((e=>this.addToGroup(e.id,null)))).then((()=>{this.removeGroup(s,!1).then((()=>{})),this.a11y.announce("Group deleted. Items returned to upload area")}))}async removeGroup(e,t=!0){let s=this.groups.get(e),r=this.stores.groups.get(e);if(!r)return;let i=!0;t&&r.uploads.length>0&&(i=window.confirm("Keep uploads in this group?")),await Promise.all(r.uploads.map((e=>i?this.addToGroup(e,null):this.removeUpload(e))));const o=this.getGroupKey(r.field,e),a=this.sortables.get(o);a?.destroy&&a.destroy(),this.sortables.delete(o),s?.element&&s.element.remove(),this.groups.delete(e),await this.stores.groups.delete(e),this.a11y.announce("Group removed")}maybeLockUploads(e){let t=this.fields.get(e);if(!t||!t.ui.dropZone)return;let s=this.stores.uploads.filterByIndex({field:e}).length,r=t.config.maxFiles??25;t.ui.dropZone.hidden=s>=r}async handleOperationCancelled(e){const t=this.stores.uploads.filterByIndex({field:e}),s=this.stores.groups.filterByIndex({field:e});await Promise.all([...t.map((e=>this.removeUpload(e.id))),...s.map((e=>this.removeGroup(e.id,!1)))]),this.a11y.announce("Upload Cancelled")}async handleOperationFailed(e,t){await this.setBulkUpload(this.stores.uploads.filterByIndex({field:t}),"status","failed")}async handleFieldStatus(e,t){let s=t.status,r=this.stores.uploads.filterByIndex({field:e});await this.setBulkUpload(r,"status",s)}getGroupKey(e,t=null){return t?`${e}_${t}`:`${e}`}getSelectionHandler(e){let t=this.getGroupKey(e);if(!this.selectionHandlers.has(t)){let s=this.fields.get(e);if(!s)return;let r=new window.jvbHandleSelection({container:s.element,item:this.selectors.items.item,count:this.selectors.fields.count,bulkControls:this.selectors.fields.actions,checkbox:this.selectors.items.checkbox,selectAll:this.selectors.fields.selectAll,wrapper:`${this.selectors.fields.preview}, ${this.selectors.group.item}`});r.subscribe(((t,s)=>{this.selected.set(e,s.selectedItems),console.log(Array.from(this.selected)),this.syncSortableSelection(e,s.selectedItems)})),this.selectionHandlers.set(t,r)}return this.selectionHandlers.get(t)}initSortable(e){if(!window.Sortable)return;const t=this.fields.get(e);t&&(!Sortable._multiDragMounted&&Sortable.MultiDrag&&(Sortable.mount(new Sortable.MultiDrag),Sortable._multiDragMounted=!0),this.createSortable(e,t.ui.grid,null),this.initEmptyGroupDropZone(e))}createSortable(e,t,s){if(!t)return null;const r=this.getGroupKey(e,s);if(this.sortables.has(r))return this.sortables.get(r);const i=new Sortable(t,{animation:150,draggable:".item",multiDrag:!0,selectedClass:"selected",avoidImplicitDeselect:!0,group:{name:e,pull:!0,put:!0},ghostClass:"ghost",chosenClass:"chosen",dragClass:"dragging",onStart:t=>{const s=t.item,r=s?.dataset.uploadId,i=this.selected.get(e);if(r&&(!i||!i.has(r))){const t=this.selectionHandlers.get(e);t&&t.select(r)}this.syncSortableSelection(e)},onEnd:t=>this.sortableDrop(t,e)});return this.sortables.set(r,i),i}initEmptyGroupDropZone(e){const t=this.fields.get(e),s=t?.groupUI?.empty;s&&(s.addEventListener("dragover",(e=>{e.preventDefault(),e.dataTransfer.dropEffect="move",s.classList.add("drag-over")})),s.addEventListener("dragleave",(e=>{s.contains(e.relatedTarget)||s.classList.remove("drag-over")})),s.addEventListener("drop",(async t=>{t.preventDefault(),s.classList.remove("drag-over");const r=this.selected.get(e);if(!r||0===r.size)return;const i=await this.createGroup(e);i&&(await Promise.all(Array.from(r).map((e=>this.addToGroup(e,i)))),this.selectionHandlers.get(e)?.clearSelection())})))}async sortableDrop(e,t){const s=e.to,r=(e.items?.length>0?Array.from(e.items):[e.item]).map((e=>e.dataset.uploadId)).filter(Boolean);if(0===r.length)return;const i=s.dataset.groupId||null;await Promise.all(r.map((e=>this.addToGroup(e,i)))),this.selectionHandlers.get(t)?.clearSelection()}syncSortableSelection(e){const t=this.selected.get(e)||new Set;for(const[s,r]of this.uploads){const i=this.stores.uploads.get(s);if(!i||i.field!==e)continue;const o=r.element;if(!o)continue;const a=t.has(s);a&&!o.classList.contains("selected")?Sortable.utils.select(o):!a&&o.classList.contains("selected")&&Sortable.utils.deselect(o)}}handleReorder(e,t=null){let s=t?this.groups.get(t)?.ui.grid:this.fields.get(e)?.ui.grid;if(!s)return void console.log("Couldn't Reorder items...");let r=Array.from(s.querySelectorAll(this.selectors.items.item+":not(.ghost)")).map((e=>e.dataset.uploadId)).filter((e=>e));if(t){let e=this.groups.get(t);e&&(e.uploads=r)}else{let t=this.fields.get(e)?.ui.hidden;t&&(t.value=r.join(","))}this.a11y.announce("Items reordered")}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}notify(e,t={}){this.subscribers.forEach((s=>{try{s(e,t)}catch(e){console.error("Subscriber error:",e)}}))}destroy(){this.subscribers.clear(),this.previewUrls.forEach((e=>{this.revokePreviewUrl(e)})),this.previewUrls.clear()}cleanupAllPreviewUrls(){this.previewUrls.forEach((e=>this.revokePreviewUrl(e))),this.previewUrls.clear()}async handleClearCache(){const e=window.location.href,t=this.stores.uploads.filterByIndex({src:e}),s=this.stores.groups.filterByIndex({src:e});await Promise.all([...t.map((e=>this.clearUpload(e.id))),...s.map((e=>(this.groups.get(e.id)?.element?.remove(),this.groups.delete(e.id),this.stores.groups.delete(e.id))))]),this.restoreModal&&this.cleanupRestore(),this.a11y.announce("Cache cleared for this page")}async getFilesForForm(e){const t=e.querySelectorAll(this.selectors.fields.field),s=[];for(const e of t){const t=this.determineFieldId(e),r=e.dataset.field,i=this.stores.uploads.filterByIndex({field:t});for(const e of i){const t=this.formatFile(e);t&&s.push({file:t,fieldName:r,uploadId:e.id,meta:e.fields||{}})}}return s}async clearFieldFromStores(e){const t=this.stores.uploads.filterByIndex({field:e}),s=this.stores.groups.filterByIndex({field:e});await Promise.all(t.map((e=>this.clearUpload(e.id)))),await Promise.all(s.map((e=>(this.groups.get(e.id)?.element?.remove(),this.groups.delete(e.id),this.stores.groups.delete(e.id)))))}}document.addEventListener("DOMContentLoaded",(async function(){window.auth.subscribe((t=>{"auth-loaded"===t&&(window.jvbUploads=new e)}))}))})();
\ No newline at end of file
+(()=>{class e{constructor(){this.a11y=window.jvbA11y,this.queue=window.jvbQueue,this.error=window.jvbError,this.subscribers=new Set,this.initStores(),this.initWorker(),this.fields=new Map,this.uploads=new Map,this.groups=new Map,this.selected=new Map,this.selectionHandlers=new Map,this.sortables=new Map,this.previewUrls=new Set,this.initElements(),this.initListeners()}initStores(){const{uploads:e,groups:t}=window.jvbStore.register("uploads",[{storeName:"uploads",keyPath:"id",indexes:[{name:"field",keyPath:"field"},{name:"status",keyPath:"status"},{name:"group",keyPath:"group"},{name:"src",keyPath:"src"}]},{storeName:"groups",keyPath:"id",indexes:[{name:"field",keyPath:"field"},{name:"src",keyPath:"src"}]}]);this.stores={uploads:e,groups:t,ready:[]},this.stores.uploads.subscribe(this.handleStores.bind(this,"uploads")),this.stores.groups.subscribe(this.handleStores.bind(this,"groups")),this.queue.subscribe(((e,t)=>{if(console.log(e,t),!Object.hasOwn(t,"endpoint")||!["uploads","uploads/meta","uploads/groups"].includes(t.endpoint))return;const s=t.data instanceof FormData?t.data.get("fieldId"):t.data?.fieldId;if(s)switch(e){case"cancel-operation":this.handleOperationCancelled(s).then((()=>{}));break;case"operation-status":this.handleFieldStatus(s,t).then((()=>{}));break;case"operation-completed":this.handleOperationComplete(t,s).then((()=>{}));break;case"operation-failed":case"operation-failed-permanent":this.handleOperationFailed(t,s).then((()=>{}))}}))}storesReady(){return 2===this.stores.ready.length}handleStores(e,t){"data-ready"===t&&(this.stores.ready.push(e),this.storesReady()&&this.checkRecovery())}initWorker(){this.worker=null,this.workerState={worker:null,tasks:new Map,restart:{count:0,max:3},settings:{timeout:3e3,maxConcurrent:3,restartAfterTimeout:!0}}}initElements(){this.selectors={fields:{field:"[data-upload-field]",input:'input[type="file"]',dropZone:".file-upload-container",preview:".preview-wrap",grid:".item-grid.preview",progress:{progress:".file-upload-container .progress",fill:".file-upload-container .progress .fill",details:".file-upload-container .progress .details",icon:".file-upload-container .progress .icon"},selectAll:'[name="select-all-uploads"]',actions:".selection-actions",count:".selection-count",hidden:'input[type="hidden"]'},groups:{container:".group-display",grid:".item-grid.groups",empty:".empty-group",header:".sidebar .header"},group:{item:".upload-group",actions:".selection-actions",selectAll:'[name="select-all-group"]',count:".group-header .info",fields:"details .fields",grid:".item-grid.group",total:".group-content .group-count"},items:{item:"[data-upload-id]",checkbox:'[name*="select-item"]',featured:'[name="featured"]',image:"img",details:"details",progress:{progress:".progress",fill:".fill",details:".details",icon:".icon"}}}}initListeners(){this.clickHandler=this.handleClick.bind(this),this.changeHandler=this.handleChange.bind(this),this.dragEnterHandler=this.handleDragEnter.bind(this),this.dragLeaveHandler=this.handleDragLeave.bind(this),this.dragOverHandler=this.handleDragOver.bind(this),this.dropHandler=this.handleDrop.bind(this),document.addEventListener("click",this.clickHandler),document.addEventListener("change",this.changeHandler),document.addEventListener("dragenter",this.dragEnterHandler),document.addEventListener("dragleave",this.dragLeaveHandler),document.addEventListener("dragover",this.dragOverHandler),document.addEventListener("drop",this.dropHandler),window.addEventListener("beforeunload",(()=>{this.cleanupAllPreviewUrls()}))}async setUpload(e,t){const s={...{id:e,attachment:null,group:null,field:null,src:window.location.href,blob:null,status:"local_processing",operationId:null,fields:{}},...t};return Object.preventExtensions(s),await this.stores.uploads.save(s),s}createPreviewUrl(e){const t=URL.createObjectURL(e);return this.previewUrls.add(t),t}revokePreviewUrl(e){e?.startsWith("blob:")&&(URL.revokeObjectURL(e),this.previewUrls.delete(e))}formatFile(e){return e.blob?new File([e.blob],e.fields.originalName||"file",{type:e.fields.type||e.blob.type,lastModified:e.fields.lastModified||Date.now()}):null}handleClick(e){let t=window.targetCheck(e,this.selectors.fields.dropZone);t&&!e.target.matches("input, button, a")&&t.querySelector(this.selectors.fields.input)?.click();const s=window.targetCheck(e,"[data-action]");s&&this.handleAction(s)}handleAction(e){const t=e.dataset.action,s=this.getFieldIdFromElement(e);switch(t){case"add-to-group":this.handleAddToGroup(s).then((()=>{}));break;case"delete-group":this.handleDeleteGroup(e);break;case"delete-upload":case"remove-from-group":this.handleRemoveItem(e).then((()=>{}));break;case"upload":this.queueUploads("uploads/groups",s).then((()=>{}));break;case"restore":this.handleRestoreSelected().then((()=>{}));break;case"restore-all":this.handleRestoreAll().then((()=>{}));break;case"clear-cache":this.handleClearCache().then((()=>{}))}}handleChange(e){let t=this.getFieldIdFromElement(e.target);if(!t)return;if(e.target.matches(this.selectors.fields.input)){const s=Array.from(e.target.files);return void(s.length>0&&this.processFiles(t,s).then((()=>{})))}if(e.target.matches(this.selectors.items.checkbox)||e.target.matches(this.selectors.items.featured)||e.target.matches('[name*="select-"]'))return;let s=this.fields.get(t);s&&s.config.autoUpload&&("post_group"===s.config.destination?this.handleGroupMetaChange(e.target):this.queueUploadMeta(e).then((()=>{})))}handleGroupMetaChange(e){const t=e.closest(this.selectors.group.fields);if(!t)return;const s=t.dataset.groupId,r=this.stores.groups.get(s);r&&window.debouncer.schedule(`group-meta-${s}`,(async(e,t)=>{let s=e.name.replace(`${t}_`,"").replace(`${t}[`,"").replace("]","");r.fields[s]=e.value,await this.setGroup(t,r)}),300)}handleDragEnter(e){if(!e.dataTransfer.types.includes("Files"))return;const t=e.target.closest(this.selectors.fields.dropZone);t&&(e.preventDefault(),t.classList.add("dragover"))}handleDragLeave(e){const t=e.target.closest(this.selectors.fields.dropZone);t&&!t.contains(e.relatedTarget)&&t.classList.remove("dragover")}handleDragOver(e){if(!e.dataTransfer.types.includes("Files"))return;e.target.closest(this.selectors.fields.dropZone)&&(e.preventDefault(),e.dataTransfer.dropEffect="copy")}handleDrop(e){const t=e.target.closest(this.selectors.fields.dropZone);if(!t)return;e.preventDefault(),t.classList.remove("dragover"),t.classList.add("uploading");const s=Array.from(e.dataTransfer.files);if(0===s.length)return;const r=this.getFieldIdFromElement(t);r&&(this.processFiles(r,s).then((()=>{})),this.a11y.announce(`${s.length} file(s) dropped for upload`))}async queueUploads(e,t){let s=new FormData;const r=this.fields.get(t);if(!r)return;let i=this.stores.uploads.filterByIndex({field:t});if(0===i.length)return;const[o,a]=["uploads"===e,"uploads/groups"===e];let l,n,d,u,c;s.append("fieldId",r.id),s.append("content",r.config.content),o&&(s.append("mode",r.config.mode),s.append("field_name",r.config.name),s.append("fieldId",r.id),s.append("field_type",r.config.type),s.append("subtype",r.config.subtype),s.append("item_id",r.config.itemID),s.append("destination",r.config.destination)),a?({posts:l,uploadMap:n,files:d}=this.collectGroups(t)):o&&({uploadMap:n,files:d}=this.collectUploads(t)),a&&s.append("posts",JSON.stringify(l)),d.forEach((e=>{s.append("files[]",e)})),s.append("upload_ids",JSON.stringify(n)),o?(u=`Uploading ${i.length} file${i.length>1?"s":""} to server...`,c=`Uploading ${i.length} file${i.length>1?"s":""}...`):a&&(u=`Creating ${l.length} ${r.config.content}${l.length>1?"s":""} from uploads...`,c=`Creating ${l.length} post${l.length>1?"s":""}...`),await this.setBulkUpload(i,"status","queued");let p=this.sendToQueue(e,s,u,c);if("uploads/groups"===e){let e=r.element.closest("details");e&&(e.open=!1)}return p?(r.operationId=p,await this.setBulkUpload(i,"operationId",p),await this.setBulkUpload(i,"status","uploading"),await this.setBulkGroup(t,"operationId",p),this.fields.set(r.id,r)):await this.setBulkUpload(i,"status","failed"),this.notify("sent-to-queue",t),p}async sendToQueue(e,t,s="",r="",i=!1){""===r&&(r=s);const o={endpoint:e,method:"POST",data:t,title:s,popup:r,canMerge:i,sendNow:"uploads/groups"===e,headers:{action_nonce:window.auth.getNonce("dash")},append:"_upload"};try{return await this.queue.addToQueue(o)}catch(e){return this.error.log(e,{component:"UploadManager",action:"sentToQueue"}),!1}}collectGroups(e){let t=this.stores.uploads.filterByIndex({field:e}),s=this.stores.groups.filterByIndex({field:e}),r=[],i=[],o=[];for(const e of s){const s={images:[],fields:e.fields??{}},a=t.filter((t=>t.group===e.id));for(const e of a){const t=this.formatFile(e);if(t){o.push(t);const r={upload_id:e.id,index:i.length};let a=this.uploads.get(e.id);a.ui?.featured?.checked&&(s.fields.featured=e.id),s.images.push(r),i.push(e.id)}}r.push(s)}const a=t.filter((e=>!e.group));for(const e of a){const t={images:[],fields:{}},s=this.formatFile(e);if(s){o.push(s);const r={upload_id:e.id,index:i.length};t.images.push(r),i.push(e.id)}r.push(t)}return{posts:r,uploadMap:i,files:o}}collectUploads(e){let t=this.stores.uploads.filterByIndex({field:e});if(0===t.length)return;let s=[],r=[];for(const e of t){const t=this.formatFile(e);t&&(r.push(t),s.push(e.id))}return{uploadMap:s,files:r}}async queueUploadMeta(e){const t=e.target.closest(this.selectors.items.item)?.dataset.uploadId,s=this.stores.uploads.get(t);if(!t||!s)return;if(!this.fields.get(s.field))return;let r={};r[e.target.name]=e.target.value,s.fields={...s.fields,...r},await this.setUpload(s.id,s);let i={};return i[s.attachmentId??s.id]=s.fields,await this.sendToQueue("uploads/meta",i,"Uploading Meta","",!0)}async handleOperationComplete(e,t){const s=e.response;if(s?.data){const e=Array.isArray(s.data)?s.data:Object.values(s.data);for(const t of e)if(t.upload_id&&t.attachment_id){const e=this.stores.uploads.get(t.upload_id);e&&(e.attachmentId=t.attachment_id,e.status="completed",await this.stores.uploads.save(e))}}const r=this.stores.uploads.filterByIndex({field:t}),i=this.stores.groups.filterByIndex({field:t});await Promise.all([...r.filter((e=>"completed"===e.status)).map((e=>this.clearUpload(e.id))),...i.map((e=>this.stores.groups.delete(e.id)))]),this.notify("uploads-complete",{fieldId:t,response:s})}scanFields(e,t=!0){e.querySelectorAll(this.selectors.fields.field).forEach((e=>this.registerField(e,t)))}registerField(e,t=!0,s=null){const r={element:e,id:s||this.determineFieldId(e),config:this.extractFieldConfig(e,t),uploads:new Set,operationId:null,groups:[],ui:window.uiFromSelectors(this.selectors.fields,e),groupUI:window.uiFromSelectors(this.selectors.groups,e)};return this.fields.set(r.id,r),e.dataset.uploader=r.id,this.getSelectionHandler(r.id),"single"!==r.config.type&&this.initSortable(r.id),r.id}extractFieldConfig(e,t){return{autoUpload:t,destination:e.dataset.destination||"meta",content:this.extractFieldContent(e),mode:e.dataset.mode||"direct",type:e.dataset.type||"single",name:e.dataset.field,itemID:this.extractFieldItemId(e)??0,maxFiles:parseInt(e.dataset.maxFiles)??25,subType:e.dataset.subtype??"image"}}extractFieldContent(e){return e.dataset.content||e.closest("dialog")?.dataset.content||e.closest("form")?.dataset.save||null}extractFieldItemId(e){return e.dataset.itemId||e.closest("dialog")?.dataset.itemId||null}determineFieldId(e){let t=this.extractFieldContent(e);t=null===t?"":t+"_";let s=this.extractFieldItemId(e);s=null===s?"":s+"_";return`${t}${s}${e.dataset.field||""}`}getFieldIdFromElement(e){const t=e.closest(this.selectors.fields.field);return t?.dataset.uploader||null}updateFieldProgress(e,t,s,r){const i=this.fields.get(e);i&&window.showProgress(i.ui.progress,t,s,r)}getWorker(){return this.workerState.worker||"undefined"==typeof OffscreenCanvas||(this.workerState.worker=new Worker("worker.js"),this.workerState.worker.onmessage=e=>this.handleWorkerMessage(e),this.workerState.worker.onerror=e=>this.handleWorkerError(e)),this.workerState.worker}handleWorkerMessage(e){const{id:t,blob:s}=e.data,r=this.workerState.tasks.get(t);r&&(clearTimeout(r.timeoutId),r.resolve(s),this.workerState.tasks.delete(t))}handleWorkerError(e){this.workerState.tasks.forEach((t=>{clearTimeout(t.timeoutId),t.reject(e)})),this.workerState.tasks.clear(),this.restartWorker()}restartWorker(){this.workerState.worker&&(this.workerState.worker.terminate(),this.workerState.worker=null),this.workerState.restart.count++}async processImages(e,t=2200,s=2200){const r=[],i=[...e],o=this.workerState.settings.maxConcurrent,a=async()=>{for(;i.length>0;){const e=i.shift();r.push(await this.processImage(e,t,s))}};return await Promise.all(Array.from({length:Math.min(o,e.length)},(()=>a()))),r}async processImage(e,t=2200,s=2200,r=3e3){if("undefined"==typeof OffscreenCanvas)return this.resizeImage(e,t,s);try{return await this.withTimeout(this.workerImage(e,t,s),r)}catch(r){return this.resizeImage(e,t,s)}}withTimeout(e,t){return Promise.race([e,new Promise(((e,s)=>setTimeout((()=>s(new Error("Timeout"))),t)))])}async workerImage(e,t=2200,s=2200){const{settings:r,restart:i}=this.workerState;if(i.count>=i.max)throw new Error("Worker max restarts exceeded");const o=await createImageBitmap(e);let{width:a,height:l}=o;if(a>t||l>s){const e=Math.min(t/a,s/l);a=Math.round(a*e),l=Math.round(l*e)}const n=this.getWorker(),d=crypto.randomUUID();return new Promise(((t,s)=>{const i=setTimeout((()=>{this.workerState.tasks.delete(d),r.restartAfterTimeout&&this.restartWorker(),s(new Error("Timeout"))}),r.timeout);this.workerState.tasks.set(d,{resolve:t,reject:s,timeoutId:i}),n.postMessage({id:d,imageBitmap:o,width:a,height:l,type:e.type,quality:.9},[o])}))}resizeImage(e,t,s){return new Promise((r=>{const i=new Image;i.onload=()=>{URL.revokeObjectURL(i.src);let{width:o,height:a}=i;if(o>t||a>s){const e=Math.min(t/o,s/a);o=Math.round(o*e),a=Math.round(a*e)}const l=document.createElement("canvas");l.width=o,l.height=a,l.getContext("2d").drawImage(i,0,0,o,a),l.toBlob(r,e.type,.9)},i.src=URL.createObjectURL(e)}))}async processFiles(e,t){let s=this.fields.get(e);if(!s)return;s.groupUI.container&&(s.groupUI.container.hidden=!1);const r=t.length;let i=0;this.updateFieldProgress(e,0,r,"Processing files...");const o=await Promise.all(t.map((async t=>{const s=window.generateID("upload"),r=await this.setUpload(s,{id:s,field:e,status:"local_processing",blob:null,fields:{originalName:t.name,originalSize:t.size,type:t.type,lastModified:t.lastModified}}),i=await this.createUpload(s,t,e);return this.uploads.set(s,{element:i,ui:window.uiFromSelectors(this.selectors.items,i)}),await this.addToGroup(s,null),{uploadId:s,upload:r,file:t}}))),a=o.filter((e=>e.file.type.startsWith("image/"))),l=o.filter((e=>!e.file.type.startsWith("image/"))),n=await this.processImages(a.map((e=>e.file)));for(let t=0;t<a.length;t++){const{uploadId:s,upload:o}=a[t];o.blob=n[t],o.fields.size=n[t].size,o.status="queued",await this.setUpload(s,o),i++,this.updateFieldProgress(e,i,r,"Processing files...")}for(const{uploadId:t,upload:s,file:o}of l)s.blob=o,s.status="queued",await this.setUpload(t,s),i++,this.updateFieldProgress(e,i,r,"Processing files...");this.maybeLockUploads(e),s.config.autoUpload&&"post_group"!==s.config.destination&&await this.queueUploads("uploads",e)}async checkRecovery(){const e=this.stores.uploads.filterByIndex({status:["local_processing","queued","uploading"]});if(0===e.length)return;let t=window.getTemplate("restoreNotification");if(!t)return void this.error.log("No restore notification",{component:"UploadManager",src:window.location.href});const s=new Map;e.forEach((e=>{const t=e.src||"unknown";s.has(t)||s.set(t,[]),s.get(t).push(e)}));const r=window.location.href;let i=s.size>1?` across ${s.size} pages`:"",o=e.length>1?"uploads":"upload",a=`${e.length} ${o} can be recovered${i}`,l=t.querySelector(".details");l&&(l.textContent=a);let n=1;for(const[e,i]of s){let s=window.getTemplate("restoreField");if(!s)continue;let o=this.registerField(s,!1,"recovery_"+n),a=this.fields.get(o);n++;let l=e===r,[d,u,c]=[s.querySelector("h3"),s.querySelector("h3 a"),s.querySelector(".item-grid")];s.open=l,l?(u.remove(),d.textContent="From this page:"):[u.href,u.title,u.textContent]=[e,"Navigate to Page and Restore",e];let p=[...new Set(i.map((e=>e.group??"preview")))];for(let e of p){let t="preview"===e||this.stores.groups.get(e);if(!t)continue;let s=await this.createGroupElement(e,a.id),r=s.querySelector(".item-grid"),o=i.filter((t=>t.group===("preview"===e)?null:e));for(const[e,r]of Object.entries(t.fields??{})){let t=s.querySelector(`input[name*="${e}"]`);t&&(t.value=r)}for(let e of o){let t=await this.createUpload(e.id,this.formatFile(e),a.id);r.append(t)}c.append(s)}t.querySelector(".wrap").append(s)}document.body.append(t),t=document.querySelector("dialog.restore-uploads"),this.restoreModal=new window.jvbModal(t),this.restoreSelection=new window.jvbHandleSelection({container:t,wrapper:".restore-uploads .wrap",bulkControls:".selection-actions",selectAll:"#select-all-restore",count:".selection-count"}),this.restoreModal.handleOpen()}async handleRestoreSelected(){if(!this.restoreSelection)return;let e=Array.from(this.restoreSelection.selectedItems);0!==e.length&&await this.restoreSelectedUploads(e)}async handleRestoreAll(){if(!this.restoreModal)return;const e=Array.from(this.restoreModal.modal.querySelectorAll(".item.upload")).map((e=>e.dataset.uploadId));await this.restoreSelectedUploads(e)}async restoreSelectedUploads(e){let t=window.location.href,s=Array.from(this.stores.uploads.data.values()).filter((s=>e.includes(s.id)&&s.src===t)),r=[...new Set(s.map((e=>e.group)))].filter(Boolean),i=s[0].field;if(!document.querySelector(`[data-uploader="${i}"]`))return void console.log("No field found for "+i);let o=this.fields.get(i);o.groupUI.container&&(o.groupUI.container.hidden=!1);let a=[];for(let e of r){let t=this.stores.groups.get(e);await this.createGroup(i,e);let r=this.groups.get(e),o=s.filter((t=>t.group===e));if(t&&this.groups.has(e)){let e=t.fields;for(const[t,s]of Object.entries(e)){let e=r.element.querySelector(`input[name*="${t}"]`);e&&(e.value=s)}}else e=null;for(let t of o){let s=await this.createUpload(t.id,this.formatFile(t),i);this.uploads.set(t.id,{element:s,ui:window.uiFromSelectors(this.selectors.items,s)}),await this.addToGroup(t.id,e),a.push(t.id)}}let l=s.filter((e=>!a.includes(e.id)));for(let e of l){let t=await this.createUpload(e.id,this.formatFile(e),i);this.uploads.set(e.id,{element:t,ui:window.uiFromSelectors(this.selectors.items,t)}),await this.addToGroup(e.id,null)}this.cleanupRestore()}cleanupRestore(){this.restoreModal.handleClose(),this.restoreSelection.destroy(),this.restoreSelection=null,this.restoreModal.destroy(),this.restoreModal.modal.remove(),this.restoreModal=null}getStatusText(e){return{received:"Image Received",local_processing:"Processing Image...",queued:"Waiting to upload...",uploading:"Uploading to Server",pending:"Successfully sent to server. In line for further processing.",processing:"Processing on server...",completed:"Upload complete!",failed:"Upload failed (will retry)",failed_permanent:"Upload failed permanently"}[e]||e}getStatusProgress(e){return{local_processing:28,queued:50,uploading:66,pending:75,processing:89,completed:100}[e]??0}async createUpload(e,t,s){let r=window.getTemplate("uploadItem");if(!r)return null;let i=this.fields.get(s);if(!i)return null;r.dataset.uploadId=e;let o=this.getSubtypeFromMime(t.type)||"image";r.dataset.subtype=o;let[a,l,n,d,u]=[r.querySelector('[name="featured"]'),r.querySelector("img"),r.querySelector("video"),r.querySelector("label > span"),r.querySelector("details")];switch(a&&(a.value=e),o){case"image":if(l){const e=this.createPreviewUrl(t);l.src=e,l.alt=t.name||"",l.dataset.previewUrl=e}n?.remove(),d?.remove();break;case"video":if(n){const e=this.createPreviewUrl(t);n.src=e,n.dataset.previewUrl=e}l?.remove(),d?.remove();break;case"document":let e=t.name.split(".").pop()?.toLowerCase()??"",s={pdf:"file-pdf",csv:"file-csv",doc:"file-doc",docx:"file-doc",txt:"file-txt",xls:"file-xls",xlsx:"file-xls"},r=window.getIcon(s[e]??"file");d&&(d.innerText=t.name,d.prepend(r)),l?.remove(),n?.remove()}if(u){let e=window.getTemplate("uploadMeta");e&&u.append(e)}return r.draggable="single"!==i.config.type??!1,r.querySelectorAll("input").forEach((t=>{let s=t.id;if(s){let r=s+e,i=t.parentNode.querySelector(`label[for="${s}"]`);t.id=r,i&&(i.htmlFor=r)}})),r}getSubtypeFromMime(e){return e.startsWith("image/")?"image":e.startsWith("video/")?"video":"document"}async handleRemoveItem(e){const t=e.closest(this.selectors.items.item);if(!t)return;const s=t.dataset.uploadId;confirm("Remove this item?")&&(await this.removeUpload(s),this.a11y.announce("Item removed"))}async setBulkUpload(e,t,s){const r=Array.from(e).map((async e=>("status"===t&&await this.setUploadStatus(e,s),e[t]=s,this.stores.uploads.save(e))));await Promise.all(r)}async setUploadStatus(e,t){e.progress&&window.showProgress(e.progress,this.getStatusProgress(t),100,this.getStatusText(t),this.queue.icons[t]??"")}async removeUpload(e){let t=this.stores.uploads.get(e);if(!t)return;if(t.group){let s=this.stores.groups.get(t.group);s.uploads=s.uploads.filter((t=>t!==e)),0===s.uploads.length&&await this.removeGroup(s.id,!1)}await this.clearUpload(e),this.maybeLockUploads(t.field);let s=this.selectionHandlers.get(t.field);s&&s.deselect(e),this.a11y.announce("Upload removed")}async clearUpload(e){const t=this.uploads.get(e);if(t&&(this.revokePreviewUrl(t.preview),t.element)){const e=t.element.dataset.previewUrl;this.revokePreviewUrl(e),t.element.remove()}this.uploads.delete(e),await this.stores.uploads.delete(e)}async handleAddToGroup(e){const t=this.selected.get(e);if(!t||0===t.size)return;let s=await this.createGroup(e);s&&(await Promise.all(Array.from(t).map((e=>this.addToGroup(e,s)))),this.selectionHandlers.get(e)?.clearSelection(),this.a11y.announce(`Created group with ${t.size} items`))}async createGroup(e,t=null){let s=this.fields.get(e);if(!s)return;t||(t=window.generateID("group"));const r=this.createGroupElement(t,e);if(!r)return null;s.groupUI.grid.append(r);const i=r.querySelector(".item-grid");i&&(i.dataset.groupId=t,this.createSortable(e,i,t));let o=this.stores.groups.data.has(t)?this.stores.groups.data.get(t):{};return await this.setGroup(t,{...o,id:t,field:e}),t}createGroupElement(e,t=null){let s=window.getTemplate("imageGroup");if(!s)return;s.dataset.groupId=e,t&&(s.dataset.fieldId=t);const r=s.querySelector("[data-select-all]");if(r){const t=`select-all-${e}`,i=s.querySelector(`label[for="${r.id}"]`);r.id=t,r.name=t,i&&(i.htmlFor=t)}let i=window.getTemplate("groupMetadata"),o=s.querySelector(".fields");if(i&&o){o.append(i);let t=o.querySelector('[name="post_title"]'),s=o.querySelector('[name="post_excerpt"]');t&&(t.id=`${e}_title`,t.name=`${e}[post_title]`),s&&(s.id=`${e}_excerpt`,s.name=`${e}[post_excerpt]`)}else s.querySelector("details")?.remove();const a=s.querySelector(".item-grid");return a&&(a.dataset.groupId=e),this.groups.set(e,{element:s,ui:window.uiFromSelectors(this.selectors.group,s)}),s}async setGroup(e,t){const s={...{id:e,src:window.location.href,uploads:[],operationId:null,field:null,fields:{}},...t};Object.preventExtensions(s),await this.stores.groups.save(s)}async setBulkGroup(e,t,s){let r=this.stores.groups.filterByIndex({field:e});if(0===r.length)return;let i=r.map((e=>{e[t]=s,this.stores.groups.save(e)}));await Promise.all(i)}async addToGroup(e,t=null){const s=this.stores.uploads.get(e),r=this.uploads.get(e);if(!s||!r)return;const i=this.fields.get(s.field);if(!i)return;if(null!==r.element?.parentElement&&(!t&&null===s.group||t===s.group))return void this.handleReorder(s.field,t);if(s.group){const t=this.stores.groups.get(s.group);t&&(t.uploads=t.uploads.filter((t=>t!==e)),0===t.uploads.length&&await this.removeGroup(t.id,!1))}if(r.ui.checkbox&&(r.ui.checkbox.checked=!1),this.selected.get(s.field)?.has(e)&&this.selected.get(s.field).delete(e),r.ui.featured&&(r.ui.featured.hidden=!t),t){r.ui.featured&&(r.ui.featured.name=`${t}_featured`);let i=this.stores.groups.get(t);i&&(i.uploads.push(e),s.group=t,this.stores.groups.save(i))}else s.group=null;let o=t?this.groups.get(t)?.ui.grid:i.ui.grid;o&&o.append(r.element),this.stores.uploads.save(s)}handleDeleteGroup(e){const t=e.closest(this.selectors.group.item);if(!t)return;let s=t.dataset.groupId;if(!confirm("Delete this group? Items will be moved back to the upload area."))return;let r=this.stores.uploads.filterByIndex({group:s});Promise.all(r.map((e=>this.addToGroup(e.id,null)))).then((()=>{this.removeGroup(s,!1).then((()=>{})),this.a11y.announce("Group deleted. Items returned to upload area")}))}async removeGroup(e,t=!0){let s=this.groups.get(e),r=this.stores.groups.get(e);if(!r)return;let i=!0;t&&r.uploads.length>0&&(i=window.confirm("Keep uploads in this group?")),await Promise.all(r.uploads.map((e=>i?this.addToGroup(e,null):this.removeUpload(e))));const o=this.getGroupKey(r.field,e),a=this.sortables.get(o);a?.destroy&&a.destroy(),this.sortables.delete(o),s?.element&&s.element.remove(),this.groups.delete(e),await this.stores.groups.delete(e),this.a11y.announce("Group removed")}maybeLockUploads(e){let t=this.fields.get(e);if(!t||!t.ui.dropZone)return;let s=this.stores.uploads.filterByIndex({field:e}).length,r=t.config.maxFiles??25;t.ui.dropZone.hidden=s>=r}async handleOperationCancelled(e){const t=this.stores.uploads.filterByIndex({field:e}),s=this.stores.groups.filterByIndex({field:e});await Promise.all([...t.map((e=>this.removeUpload(e.id))),...s.map((e=>this.removeGroup(e.id,!1)))]),this.a11y.announce("Upload Cancelled")}async handleOperationFailed(e,t){await this.setBulkUpload(this.stores.uploads.filterByIndex({field:t}),"status","failed")}async handleFieldStatus(e,t){let s=t.status,r=this.stores.uploads.filterByIndex({field:e});await this.setBulkUpload(r,"status",s)}getGroupKey(e,t=null){return t?`${e}_${t}`:`${e}`}getSelectionHandler(e){let t=this.getGroupKey(e);if(!this.selectionHandlers.has(t)){let s=this.fields.get(e);if(!s)return;let r=new window.jvbHandleSelection({container:s.element,item:this.selectors.items.item,count:this.selectors.fields.count,bulkControls:this.selectors.fields.actions,checkbox:this.selectors.items.checkbox,selectAll:this.selectors.fields.selectAll,wrapper:`${this.selectors.fields.preview}, ${this.selectors.group.item}`});r.subscribe(((t,s)=>{this.selected.set(e,s.selectedItems),console.log(Array.from(this.selected)),this.syncSortableSelection(e,s.selectedItems)})),this.selectionHandlers.set(t,r)}return this.selectionHandlers.get(t)}initSortable(e){if(!window.Sortable)return;const t=this.fields.get(e);t&&(!Sortable._multiDragMounted&&Sortable.MultiDrag&&(Sortable.mount(new Sortable.MultiDrag),Sortable._multiDragMounted=!0),this.createSortable(e,t.ui.grid,null),this.initEmptyGroupDropZone(e))}createSortable(e,t,s){if(!t)return null;const r=this.getGroupKey(e,s);if(this.sortables.has(r))return this.sortables.get(r);const i=new Sortable(t,{animation:150,draggable:".item",multiDrag:!0,selectedClass:"selected",avoidImplicitDeselect:!0,group:{name:e,pull:!0,put:!0},ghostClass:"ghost",chosenClass:"chosen",dragClass:"dragging",onStart:t=>{const s=t.item,r=s?.dataset.uploadId,i=this.selected.get(e);if(r&&(!i||!i.has(r))){const t=this.selectionHandlers.get(e);t&&t.select(r)}this.syncSortableSelection(e)},onEnd:t=>this.sortableDrop(t,e)});return this.sortables.set(r,i),i}initEmptyGroupDropZone(e){const t=this.fields.get(e),s=t?.groupUI?.empty;s&&(s.addEventListener("dragover",(e=>{e.preventDefault(),e.dataTransfer.dropEffect="move",s.classList.add("drag-over")})),s.addEventListener("dragleave",(e=>{s.contains(e.relatedTarget)||s.classList.remove("drag-over")})),s.addEventListener("drop",(async t=>{t.preventDefault(),s.classList.remove("drag-over");const r=this.selected.get(e);if(!r||0===r.size)return;const i=await this.createGroup(e);i&&(await Promise.all(Array.from(r).map((e=>this.addToGroup(e,i)))),this.selectionHandlers.get(e)?.clearSelection())})))}async sortableDrop(e,t){const s=e.to,r=(e.items?.length>0?Array.from(e.items):[e.item]).map((e=>e.dataset.uploadId)).filter(Boolean);if(0===r.length)return;const i=s.dataset.groupId||null;await Promise.all(r.map((e=>this.addToGroup(e,i)))),this.selectionHandlers.get(t)?.clearSelection()}syncSortableSelection(e){const t=this.selected.get(e)||new Set;for(const[s,r]of this.uploads){const i=this.stores.uploads.get(s);if(!i||i.field!==e)continue;const o=r.element;if(!o)continue;const a=t.has(s);a&&!o.classList.contains("selected")?Sortable.utils.select(o):!a&&o.classList.contains("selected")&&Sortable.utils.deselect(o)}}handleReorder(e,t=null){let s=t?this.groups.get(t)?.ui.grid:this.fields.get(e)?.ui.grid;if(!s)return void console.log("Couldn't Reorder items...");let r=Array.from(s.querySelectorAll(this.selectors.items.item+":not(.ghost)")).map((e=>e.dataset.uploadId)).filter((e=>e));if(t){let e=this.groups.get(t);e&&(e.uploads=r)}else{let t=this.fields.get(e)?.ui.hidden;t&&(t.value=r.join(","))}this.a11y.announce("Items reordered")}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}notify(e,t={}){this.subscribers.forEach((s=>{try{s(e,t)}catch(e){console.error("Subscriber error:",e)}}))}destroy(){this.subscribers.clear(),this.previewUrls.forEach((e=>{this.revokePreviewUrl(e)})),this.previewUrls.clear()}cleanupAllPreviewUrls(){this.previewUrls.forEach((e=>this.revokePreviewUrl(e))),this.previewUrls.clear()}async handleClearCache(){const e=window.location.href,t=this.stores.uploads.filterByIndex({src:e}),s=this.stores.groups.filterByIndex({src:e});await Promise.all([...t.map((e=>this.clearUpload(e.id))),...s.map((e=>(this.groups.get(e.id)?.element?.remove(),this.groups.delete(e.id),this.stores.groups.delete(e.id))))]),this.restoreModal&&this.cleanupRestore(),this.a11y.announce("Cache cleared for this page")}async getFilesForForm(e){const t=e.querySelectorAll(this.selectors.fields.field),s=[];for(const e of t){const t=this.determineFieldId(e),r=e.dataset.field,i=this.stores.uploads.filterByIndex({field:t});for(const e of i){const t=this.formatFile(e);t&&s.push({file:t,fieldName:r,uploadId:e.id,meta:e.fields||{}})}}return s}async clearFieldFromStores(e){const t=this.stores.uploads.filterByIndex({field:e}),s=this.stores.groups.filterByIndex({field:e});await Promise.all(t.map((e=>this.clearUpload(e.id)))),await Promise.all(s.map((e=>(this.groups.get(e.id)?.element?.remove(),this.groups.delete(e.id),this.stores.groups.delete(e.id)))))}}document.addEventListener("DOMContentLoaded",(async function(){window.auth.subscribe((t=>{"auth-loaded"===t&&(window.jvbUploads=new e)}))}))})();
\ No newline at end of file
diff --git a/assets/js/min/utility.min.js b/assets/js/min/utility.min.js
index 4f6e7b8..8263ddb 100644
--- a/assets/js/min/utility.min.js
+++ b/assets/js/min/utility.min.js
@@ -1 +1 @@
-(()=>{window.fade=function(t,e=!0){e?t.style.animation="fadeIn var(--transition-base)":(t.style.animation="fadeOut var(--transition-base)",window.debouncer.schedule(`remove-${t.dataset.id??t.id??t.className.replace(" ","-")}`,(()=>{t.remove()}),500))},window.formatTimeAgo=function(t,e="default"){const n=t instanceof Date?t:new Date(t),i=n-new Date,o=i<0,r=Math.floor(Math.abs(i)/1e3),a=Math.floor(r/60),s=Math.floor(a/60),c=Math.floor(s/24);if(0===a)return"Just now";let l="";if(r<10)l="a moment";else if(r<60)l="less than a minute";else if(a<5)l="a few minutes";else if(s<24)l=0===s?`${a} ${1===a?"minute":"minutes"}`:`about ${s} ${1===s?"hour":"hours"}`;else{if(!(c<7)){if("default"===e)return n.toLocaleDateString();const t={Y:n.getFullYear(),y:String(n.getFullYear()).slice(-2),F:n.toLocaleDateString("en-CA",{month:"long"}),M:n.toLocaleDateString("en-CA",{month:"short"}),m:String(n.getMonth()+1).padStart(2,"0"),n:n.getMonth()+1,d:String(n.getDate()).padStart(2,"0"),j:n.getDate(),D:n.toLocaleDateString("en-CA",{weekday:"short"}),l:n.toLocaleDateString("en-CA",{weekday:"long"}),H:String(n.getHours()).padStart(2,"0"),i:String(n.getMinutes()).padStart(2,"0"),s:String(n.getSeconds()).padStart(2,"0"),h:String(n.getHours()%12||12).padStart(2,"0"),g:n.getHours()%12||12,A:n.getHours()>=12?"PM":"AM",a:n.getHours()>=12?"pm":"am"};return e.replace(/[YyFMmnjDlHishgAa]/g,(e=>t[e]))}if(1===c)return o?"yesterday":"tomorrow";l=`about ${c} days`,l=`${c} ${1===c?"day":"days"}`}return o?`${l} ago`:`in ${l}`},window.uppercaseFirst=function(t){return t.charAt(0).toUpperCase()+t.slice(1)},window.templates=new Map,document.addEventListener("DOMContentLoaded",(()=>{window.loadTemplates()})),window.loadTemplates=function(){document.querySelectorAll("template").forEach((t=>{const e=Array.from(t.classList);if(e.length>0){const n=t.content.cloneNode(!0).firstElementChild;e.forEach((t=>{window.templates.has(t)||window.templates.set(t,n)}))}}))},window.getTemplate=function(t){return 0===window.templates.size&&window.loadTemplates(),!!window.templates.has(t)&&window.templates.get(t).cloneNode(!0)},window.icon=null,window.getIcon=function(t,e=""){if(void 0===t)return"";window.icon||(window.icon=document.createElement("i"),window.icon.className="icon",window.icon.ariaHidden=!0);let n=window.icon.cloneNode(!0);return e=""!==e&&["regular","bold","duotone","fill","light","thin"].includes("style")?`-${e.slice(0,2)}`:"",n.classList.add(`icon-${t}${e}`),n},window.formatNumber=function(t){return t.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")},window.formatPrice=function(t,e="CAD"){return new Intl.NumberFormat("en-CA",{style:"currency",currency:e}).format(t)},window.escapeHtml=function(t){return t?("string"==typeof t||t instanceof String||(t=String(t)),t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")):""},window.removeChildren=function(t){if(0!==t.children.length)for(;t.firstChild;)t.removeChild(t.firstChild)},window.formatDateRange=function(t,e){const n=new Date(t),i=new Date(e);return n.toDateString()===i.toDateString()?n.toLocaleDateString("en-CA",{year:"numeric",month:"short",day:"numeric"}):n.getMonth()===i.getMonth()&&n.getFullYear()===i.getFullYear()?`${n.toLocaleDateString("en-CA",{month:"short",day:"numeric"})} - ${i.getDate()}, ${i.getFullYear()}`:n.getFullYear()===i.getFullYear()?`${n.toLocaleDateString("en-CA",{month:"short",day:"numeric"})} - ${i.toLocaleDateString("en-CA",{month:"short",day:"numeric"})}, ${i.getFullYear()}`:`${n.toLocaleDateString("en-CA",{month:"short",day:"numeric",year:"numeric"})} - ${i.toLocaleDateString("en-CA",{month:"short",day:"numeric",year:"numeric"})}`},window.throttle=function(t,e=300){let n;return function(...i){n||(t.apply(this,i),n=!0,setTimeout((()=>n=!1),e))}},window.uppercaseFirst=function(t){return t.charAt(0).toUpperCase()+t.slice(1)},window.sanitizeHtml=function(t){const e=document.createElement("div");return e.textContent=t,e.innerHTML},window.generateID=function(t="jvb"){return`${t}_${Date.now()}_${Math.random().toString(36).slice(2,9)}`},window.showProgress=function(t,e,n,i="",o=""){const r=e<n;t.progress&&r&&window.fade(t.progress,!0);const a=n>0?e/n*100:0;t.fill&&(t.fill.style.width=`${a}%`),t.details&&(t.details.textContent=i),t.count&&(t.count.textContent=`${e}/${n}`),t.icon&&(t.icon.className=""===o?"icon":"icon icon-"+o),t.progress&&e===n&&window.fade(t.progress,!1)},window.formatDate=function(t){if(!t)return"";const e=new Date(t),n=new Date,i=Math.floor((n-e)/864e5);return i<1?"Today":i<2?"Yesterday":i<7?`${i} days ago`:e.toLocaleDateString()},window.getPluralContent=function(t){return"artwork"===t?"artwork":t+"s"},window.showToast=function(t,e="success",n={}){window.jvbNotifications.showToast(t,e,n)},window.dateFormatter=new Intl.DateTimeFormat("en-CA",{year:"numeric",month:"long",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:"short"}),window.formatDate=function(t){return t instanceof Date&&!isNaN(t)||(t=new Date(t)),window.dateFormatter.format(t)},window.typeText=function(t,e,n=50){return t.classList.add("typeText"),new Promise((i=>{let o=0;t.textContent="";const r=setInterval((()=>{o<e.length?(t.textContent+=e.charAt(o),o++):(clearInterval(r),i())}),n)}))},window.eraseText=function(t,e=10){return new Promise((n=>{let i=t.textContent,o=i.length;const r=setInterval((()=>{o>0?(o--,t.textContent=i.substring(0,o)):(clearInterval(r),n())}),e)}))},window.typeLoop=function(t,e,n=50,i=10,o=1e3,r=250){let a=!0;return async function(){for(;a;)await window.typeText(t,e,n),await new Promise((t=>setTimeout(t,o))),await window.eraseText(t,i),await new Promise((t=>setTimeout(t,r)))}(),function(){a=!1}},window.toCamelCase=function(t){return t.replace(/-([a-z])/g,(function(t){return t[1].toUpperCase()}))},window.targetCheck=function(t,e){return Array.isArray(e)&&(e=e.join(",")),"string"==typeof e&&(t.target.closest(e)??!1)},window.getDifferences={VALUE_CREATED:"created",VALUE_UPDATED:"updated",VALUE_DELETED:"deleted",VALUE_UNCHANGED:"unchanged",map:function(t,e){if(this.isFunction(t)||this.isFunction(e))throw"Invalid argument. Function given, object expected.";if(this.isFile(t)||this.isFile(e)){const n=this.compareFiles(t,e);return n===this.VALUE_UNCHANGED?null:{type:n,data:void 0===t?e:t}}if(this.isValue(t)||this.isValue(e)){const n=this.compareValues(t,e);if(n===this.VALUE_UNCHANGED)return null;let i;switch(n){case this.VALUE_CREATED:i=e;break;case this.VALUE_DELETED:i=this.getEmptyValue(t);break;case this.VALUE_UPDATED:default:i=e}return{type:n,data:i}}let n={},i=!1;for(let o in t)if(!this.isFunction(t[o])){let r;e&&void 0!==e[o]&&(r=e[o]);const a=this.map(t[o],r);null!==a&&(a.hasOwnProperty("type")&&a.hasOwnProperty("data")?n[o]=a.data:n[o]=a,i=!0)}if(e)for(let o in e)if(!this.isFunction(e[o])&&(void 0===t||void 0===t[o])){const t=this.map(void 0,e[o]);null!==t&&(t.hasOwnProperty("type")&&t.hasOwnProperty("data")?n[o]=t.data:n[o]=t,i=!0)}return i?n:null},getEmptyValue:function(t){return this.isArray(t)?[]:this.isObject(t)?{}:"number"==typeof t?0:"boolean"!=typeof t&&""},compareValues:function(t,e){return t===e||this.isDate(t)&&this.isDate(e)&&t.getTime()===e.getTime()?this.VALUE_UNCHANGED:void 0===t?this.VALUE_CREATED:void 0===e?this.VALUE_DELETED:this.VALUE_UPDATED},isFunction:function(t){return"[object Function]"===Object.prototype.toString.call(t)},isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},isDate:function(t){return"[object Date]"===Object.prototype.toString.call(t)},isObject:function(t){return"[object Object]"===Object.prototype.toString.call(t)},isFile:function(t){return t instanceof File},isValue:function(t){return!this.isObject(t)&&!this.isArray(t)},compareFiles:function(t,e){return!this.isFile(t)&&this.isFile(e)?this.VALUE_CREATED:this.isFile(t)&&!this.isFile(e)?this.VALUE_DELETED:this.isFile(t)&&this.isFile(e)?t.name===e.name&&t.size===e.size&&t.type===e.type&&t.lastModified===e.lastModified?this.VALUE_UNCHANGED:this.VALUE_UPDATED:this.VALUE_UNCHANGED},merge:function(t,e){if(null==t)return e;if(null==e)return t;if(this.isFunction(t)||this.isFunction(e))return e;if(this.isFile(t)||this.isFile(e))return e;if(this.isValue(t)||this.isValue(e)||this.isArray(t)||this.isArray(e))return e;if(this.isObject(t)&&this.isObject(e)){let n={};for(let e in t)this.isFunction(t[e])||(n[e]=t[e]);for(let i in e)this.isFunction(e[i])||(void 0!==t[i]?n[i]=this.merge(t[i],e[i]):n[i]=e[i]);return n}return e}},window.deepMerge=function(t,e){return window.getDifferences.merge(t,e)},window.isInt=function(t){return!isNaN(parseInt(t))&&isFinite(t)},window.isNumeric=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},window.uiFromSelectors=function(t,e=null){let n={};for(let[i,o]of Object.entries(t))n[i]="object"==typeof o?window.uiFromSelectors(o,e):e?e.querySelector(o):document.querySelector(o);return n};window.debouncer=new class{constructor(){this.timeouts=new Map,window.addEventListener("beforeunload",(()=>this.cleanup()))}schedule(t,e,n=1e3){this.cancel(t),this.timeouts.set(t,setTimeout((()=>{e(),this.timeouts.delete(t)}),n))}cancel(t){this.timeouts.has(t)&&(clearTimeout(this.timeouts.get(t)),this.timeouts.delete(t))}cleanup(){for(let t of this.timeouts.values())clearTimeout(t);this.timeouts.clear()}};document.body;const t=document.documentElement,e=document.querySelector(".scroll-progress .bar");let n=window.scrollY||t.scrollTop||0,i=-1,o=!1,r=0;function a(){r=Math.max(0,t.scrollHeight-window.innerHeight)}function s(t){if(!e)return;const n=r>0?t/r:0,i=Math.max(0,Math.min(1,n));e.style.transform=`scaleX(${i})`}function c(){const e=window.scrollY||t.scrollTop||0;e>n?i=1:e<n&&(i=-1),n=e,document.body.classList.toggle("scroll-up",i<0&&e>0),s(e),o=!1}window.addEventListener("scroll",(()=>{o||(o=!0,requestAnimationFrame(c))}),{passive:!0}),window.addEventListener("resize",(()=>{window.debouncer.schedule("recalc-max-scroll",(()=>{a(),s(window.scrollY||t.scrollTop||0)}),20)})),a(),s(n)})();
\ No newline at end of file
+(()=>{window.fade=function(t,e=!0){e?t.style.animation="fadeIn var(--transition-base)":(t.style.animation="fadeOut var(--transition-base)",window.debouncer.schedule(`remove-${t.dataset.id??t.id??t.className.replace(" ","-")}`,(()=>{t.remove()}),500))},window.formatTimeAgo=function(t,e="default"){const n=t instanceof Date?t:new Date(t),i=n-new Date,o=i<0,r=Math.floor(Math.abs(i)/1e3),a=Math.floor(r/60),s=Math.floor(a/60),l=Math.floor(s/24);if(0===a)return"Just now";let c="";if(r<10)c="a moment";else if(r<60)c="less than a minute";else if(a<5)c="a few minutes";else if(s<24)c=0===s?`${a} ${1===a?"minute":"minutes"}`:`about ${s} ${1===s?"hour":"hours"}`;else{if(!(l<7)){if("default"===e)return n.toLocaleDateString();const t={Y:n.getFullYear(),y:String(n.getFullYear()).slice(-2),F:n.toLocaleDateString("en-CA",{month:"long"}),M:n.toLocaleDateString("en-CA",{month:"short"}),m:String(n.getMonth()+1).padStart(2,"0"),n:n.getMonth()+1,d:String(n.getDate()).padStart(2,"0"),j:n.getDate(),D:n.toLocaleDateString("en-CA",{weekday:"short"}),l:n.toLocaleDateString("en-CA",{weekday:"long"}),H:String(n.getHours()).padStart(2,"0"),i:String(n.getMinutes()).padStart(2,"0"),s:String(n.getSeconds()).padStart(2,"0"),h:String(n.getHours()%12||12).padStart(2,"0"),g:n.getHours()%12||12,A:n.getHours()>=12?"PM":"AM",a:n.getHours()>=12?"pm":"am"};return e.replace(/[YyFMmnjDlHishgAa]/g,(e=>t[e]))}if(1===l)return o?"yesterday":"tomorrow";c=`about ${l} days`,c=`${l} ${1===l?"day":"days"}`}return o?`${c} ago`:`in ${c}`},window.uppercaseFirst=function(t){return t.charAt(0).toUpperCase()+t.slice(1)},window.templates=new Map,document.addEventListener("DOMContentLoaded",(()=>{window.loadTemplates()})),window.loadTemplates=function(){document.querySelectorAll("template").forEach((t=>{const e=Array.from(t.classList);if(e.length>0){const n=t.content.cloneNode(!0).firstElementChild;e.forEach((t=>{window.templates.has(t)||window.templates.set(t,n)}))}}))},window.getTemplate=function(t){return 0===window.templates.size&&window.loadTemplates(),!!window.templates.has(t)&&window.templates.get(t).cloneNode(!0)},window.icon=null,window.getIcon=function(t,e=""){if(void 0===t)return"";window.icon||(window.icon=document.createElement("i"),window.icon.className="icon",window.icon.ariaHidden=!0);let n=window.icon.cloneNode(!0);return e=""!==e&&["regular","bold","duotone","fill","light","thin"].includes("style")?`-${e.slice(0,2)}`:"",n.classList.add(`icon-${t}${e}`),n},window.formatNumber=function(t){return t.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")},window.formatPrice=function(t,e="CAD"){return new Intl.NumberFormat("en-CA",{style:"currency",currency:e}).format(t)},window.escapeHtml=function(t){return t?("string"==typeof t||t instanceof String||(t=String(t)),t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")):""},window.removeChildren=function(t){if(0!==t.children.length)for(;t.firstChild;)t.removeChild(t.firstChild)},window.formatDateRange=function(t,e){const n=new Date(t),i=new Date(e);return n.toDateString()===i.toDateString()?n.toLocaleDateString("en-CA",{year:"numeric",month:"short",day:"numeric"}):n.getMonth()===i.getMonth()&&n.getFullYear()===i.getFullYear()?`${n.toLocaleDateString("en-CA",{month:"short",day:"numeric"})} - ${i.getDate()}, ${i.getFullYear()}`:n.getFullYear()===i.getFullYear()?`${n.toLocaleDateString("en-CA",{month:"short",day:"numeric"})} - ${i.toLocaleDateString("en-CA",{month:"short",day:"numeric"})}, ${i.getFullYear()}`:`${n.toLocaleDateString("en-CA",{month:"short",day:"numeric",year:"numeric"})} - ${i.toLocaleDateString("en-CA",{month:"short",day:"numeric",year:"numeric"})}`},window.throttle=function(t,e=300){let n;return function(...i){n||(t.apply(this,i),n=!0,setTimeout((()=>n=!1),e))}},window.uppercaseFirst=function(t){return t.charAt(0).toUpperCase()+t.slice(1)},window.sanitizeHtml=function(t){const e=document.createElement("div");return e.textContent=t,e.innerHTML},window.generateID=function(t="jvb"){return`${t}_${Date.now()}_${Math.random().toString(36).slice(2,9)}`},window.showProgress=function(t,e,n,i="",o=""){const r=e<n;t.progress&&r&&window.fade(t.progress,!0);const a=n>0?e/n*100:0;t.fill&&(t.fill.style.width=`${a}%`),t.details&&(t.details.textContent=i),t.count&&(t.count.textContent=`${e}/${n}`),t.icon&&(t.icon.className=""===o?"icon":"icon icon-"+o),t.progress&&e===n&&window.fade(t.progress,!1)},window.formatDate=function(t){if(!t)return"";const e=new Date(t),n=new Date,i=Math.floor((n-e)/864e5);return i<1?"Today":i<2?"Yesterday":i<7?`${i} days ago`:e.toLocaleDateString()},window.getPluralContent=function(t){return"artwork"===t?"artwork":t+"s"},window.showToast=function(t,e="success",n={}){window.jvbNotifications.showToast(t,e,n)},window.dateFormatter=new Intl.DateTimeFormat("en-CA",{year:"numeric",month:"long",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:"short"}),window.formatDate=function(t){return t instanceof Date&&!isNaN(t)||(t=new Date(t)),window.dateFormatter.format(t)},window.typeText=function(t,e,n=50){return new Promise((i=>{t._typeInterval&&(clearInterval(t._typeInterval),delete t._typeInterval);let o=0;t.textContent="",t._typeInterval=setInterval((()=>{o<e.length?(t.textContent+=e.charAt(o),o++):(clearInterval(t._typeInterval),delete t._typeInterval,i())}),n)}))},window.eraseText=function(t,e=10){return new Promise((n=>{t._eraseInterval&&(clearInterval(t._eraseInterval),delete t._eraseInterval);let i=t.textContent,o=i.length;t._eraseInterval=setInterval((()=>{o>0?(o--,t.textContent=i.substring(0,o)):(clearInterval(t._eraseInterval),delete t._eraseInterval,n())}),e)}))},window.typeLoop=function(t,e,n=50,i=10,o=1e3,r=250){const a=t.id||t.dataset.typeKey||`type-${Date.now()}`;t.dataset.typeKey||(t.dataset.typeKey=a),t._stopTyping&&t._stopTyping();let s=!0;const l=function(){s=!1,t._typeInterval&&(clearInterval(t._typeInterval),delete t._typeInterval),t._eraseInterval&&(clearInterval(t._eraseInterval),delete t._eraseInterval)};return t._stopTyping=l,async function(){for(;s&&(await window.typeText(t,e,n),s)&&(await new Promise((t=>setTimeout(t,o))),s)&&(await window.eraseText(t,i),s);)await new Promise((t=>setTimeout(t,r)))}(),l},window.toCamelCase=function(t){return t.replace(/-([a-z])/g,(function(t){return t[1].toUpperCase()}))},window.targetCheck=function(t,e){return Array.isArray(e)&&(e=e.join(",")),"string"==typeof e&&(t.target.closest(e)??!1)},window.getDifferences={VALUE_CREATED:"created",VALUE_UPDATED:"updated",VALUE_DELETED:"deleted",VALUE_UNCHANGED:"unchanged",map:function(t,e){if(this.isFunction(t)||this.isFunction(e))throw"Invalid argument. Function given, object expected.";if(this.isFile(t)||this.isFile(e)){const n=this.compareFiles(t,e);return n===this.VALUE_UNCHANGED?null:{type:n,data:void 0===t?e:t}}if(this.isValue(t)||this.isValue(e)){const n=this.compareValues(t,e);if(n===this.VALUE_UNCHANGED)return null;let i;switch(n){case this.VALUE_CREATED:i=e;break;case this.VALUE_DELETED:i=this.getEmptyValue(t);break;case this.VALUE_UPDATED:default:i=e}return{type:n,data:i}}let n={},i=!1;for(let o in t)if(!this.isFunction(t[o])){let r;e&&void 0!==e[o]&&(r=e[o]);const a=this.map(t[o],r);null!==a&&(a.hasOwnProperty("type")&&a.hasOwnProperty("data")?n[o]=a.data:n[o]=a,i=!0)}if(e)for(let o in e)if(!this.isFunction(e[o])&&(void 0===t||void 0===t[o])){const t=this.map(void 0,e[o]);null!==t&&(t.hasOwnProperty("type")&&t.hasOwnProperty("data")?n[o]=t.data:n[o]=t,i=!0)}return i?n:null},getEmptyValue:function(t){return this.isArray(t)?[]:this.isObject(t)?{}:"number"==typeof t?0:"boolean"!=typeof t&&""},compareValues:function(t,e){return t===e||this.isDate(t)&&this.isDate(e)&&t.getTime()===e.getTime()?this.VALUE_UNCHANGED:void 0===t?this.VALUE_CREATED:void 0===e?this.VALUE_DELETED:this.VALUE_UPDATED},isFunction:function(t){return"[object Function]"===Object.prototype.toString.call(t)},isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},isDate:function(t){return"[object Date]"===Object.prototype.toString.call(t)},isObject:function(t){return"[object Object]"===Object.prototype.toString.call(t)},isFile:function(t){return t instanceof File},isValue:function(t){return!this.isObject(t)&&!this.isArray(t)},compareFiles:function(t,e){return!this.isFile(t)&&this.isFile(e)?this.VALUE_CREATED:this.isFile(t)&&!this.isFile(e)?this.VALUE_DELETED:this.isFile(t)&&this.isFile(e)?t.name===e.name&&t.size===e.size&&t.type===e.type&&t.lastModified===e.lastModified?this.VALUE_UNCHANGED:this.VALUE_UPDATED:this.VALUE_UNCHANGED},merge:function(t,e){if(null==t)return e;if(null==e)return t;if(this.isFunction(t)||this.isFunction(e))return e;if(this.isFile(t)||this.isFile(e))return e;if(this.isValue(t)||this.isValue(e)||this.isArray(t)||this.isArray(e))return e;if(this.isObject(t)&&this.isObject(e)){let n={};for(let e in t)this.isFunction(t[e])||(n[e]=t[e]);for(let i in e)this.isFunction(e[i])||(void 0!==t[i]?n[i]=this.merge(t[i],e[i]):n[i]=e[i]);return n}return e}},window.deepMerge=function(t,e){return window.getDifferences.merge(t,e)},window.isInt=function(t){return!isNaN(parseInt(t))&&isFinite(t)},window.isNumeric=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},window.uiFromSelectors=function(t,e=null){let n={};for(let[i,o]of Object.entries(t))n[i]="object"==typeof o?window.uiFromSelectors(o,e):e?e.querySelector(o):document.querySelector(o);return n};window.debouncer=new class{constructor(){this.timeouts=new Map,window.addEventListener("beforeunload",(()=>this.cleanup()))}schedule(t,e,n=1e3){this.cancel(t),this.timeouts.set(t,setTimeout((()=>{e(),this.timeouts.delete(t)}),n))}cancel(t){this.timeouts.has(t)&&(clearTimeout(this.timeouts.get(t)),this.timeouts.delete(t))}cleanup(){for(let t of this.timeouts.values())clearTimeout(t);this.timeouts.clear()}};document.body;const t=document.documentElement,e=document.querySelector(".scroll-progress .bar");let n=window.scrollY||t.scrollTop||0,i=-1,o=!1,r=0;function a(){r=Math.max(0,t.scrollHeight-window.innerHeight)}function s(t){if(!e)return;const n=r>0?t/r:0,i=Math.max(0,Math.min(1,n));e.style.transform=`scaleX(${i})`}function l(){const e=window.scrollY||t.scrollTop||0;e>n?i=1:e<n&&(i=-1),n=e,document.body.classList.toggle("scroll-up",i<0&&e>0),s(e),o=!1}window.addEventListener("scroll",(()=>{o||(o=!0,requestAnimationFrame(l))}),{passive:!0}),window.addEventListener("resize",(()=>{window.debouncer.schedule("recalc-max-scroll",(()=>{a(),s(window.scrollY||t.scrollTop||0)}),20)})),a(),s(n)})();
\ No newline at end of file
diff --git a/build/feed/style-index-rtl.css b/build/feed/style-index-rtl.css
index ba5c5ec..7a0ed7f 100644
--- a/build/feed/style-index-rtl.css
+++ b/build/feed/style-index-rtl.css
@@ -1 +1 @@
-.feed-block{grid-column:full}.feed-block .filters{margin:0 auto;max-width:var(--wide);padding:1rem 0}.feed-block .filter-group{padding:2rem 0;position:relative}.feed-block .filter-group .label{right:0;position:absolute}.feed-block .filter-group>.label{top:0}.feed-block .filter-group [type=radio]{right:var(--offScreen);position:absolute}.feed-block .filter-group button,.feed-block .filter-group label{height:-moz-max-content;height:max-content;padding:.5rem;position:relative}.feed-block .filter-group button:hover,.feed-block .filter-group label:hover{color:var(--action-contrast)}.feed-block .filter-group :checked+label .label,.feed-block .filter-group button:hover .label,.feed-block .filter-group label:hover .label{opacity:1;visibility:visible}.feed-block .filter-group button .label,.feed-block .filter-group label .label,.feed-block .filter-group:has(label:hover) :checked+label .label{--height:max-content;bottom:-2rem;font-weight:var(--fw-b);opacity:0;visibility:hidden;white-space:nowrap;width:-moz-max-content;width:max-content}.feed-block h3{font-size:var(--medium);margin:0 0 .25rem}.placeholder{align-items:center;aspect-ratio:1;background:var(--base);border:1rem solid var(--base-50);border-radius:1rem;display:flex;justify-content:center}.placeholder i.icon{--w:50%;animation:dance 2.5s ease-in-out infinite;color:var(--base-200)}.item-grid{max-width:none;padding:0 var(--chip)}.feed.item{background:var(--base-50);border-radius:.5rem;box-shadow:0 2px 4px rgba(0,0,0,.1);height:-moz-fit-content;height:fit-content;overflow:hidden;padding:0;position:relative}.feed.item details{padding:0;position:relative;width:100%;z-index:var(--z-2)}.feed.item details summary{backdrop-filter:blur(5px);background-color:rgba(var(--base-rgb),var(--op-2));right:0;position:absolute;top:-3rem;width:100%}.feed.item details summary:hover{background-color:rgba(var(--action-rgb),var(--op-45))}.feed.item details[open]{padding:.25rem .5rem}.feed.item details[open] summary .icon{opacity:0}.feed.item img{-o-object-fit:cover;object-fit:cover}.feed.item img:hover{opacity:.8}.feed.item[data-timeline] .images{aspect-ratio:3/2;padding:0 0 1rem}.feed.item[data-timeline] .images span{background-color:var(--action-0);color:var(--action-contrast);padding:.25rem .5rem;position:absolute;width:50%}.feed.item[data-timeline] .images span:first-of-type{bottom:0;left:50%;text-align:left}.feed.item[data-timeline] .images span:last-of-type{right:50%;top:0}.feed.item[data-timeline] .images>a{display:flex;flex-wrap:nowrap;height:100%;position:relative;width:100%}.feed.item[data-timeline] img{height:100%;-o-object-fit:cover;object-fit:cover;width:50%}.feed.item[data-timeline] img:first-of-type{border-left:1px solid var(--action-0)}.feed.item a:after,.feed.item a:before{display:none}.feed.item label{font-weight:400;text-transform:none}.feed.item label .icon{--w:1.5em}.item-grid:has([data-timeline]){grid-template-columns:repeat(1,1fr)}@media(min-width:768px){.item-grid:has([data-timeline]){grid-template-columns:repeat(2,1fr)}}
+.feed-block{grid-column:full}.feed-block .filters{margin:0 auto;max-width:var(--wide);padding:1rem 0}.feed-block .filters .remove-term.remove-term{height:-moz-max-content;height:max-content;width:-moz-max-content;width:max-content}.feed-block .filter-group{padding:2rem 0;position:relative}.feed-block .filter-group .label{right:0;position:absolute}.feed-block .filter-group>.label{top:0}.feed-block .filter-group [type=radio]{right:var(--offScreen);position:absolute}.feed-block .filter-group button,.feed-block .filter-group label{height:-moz-max-content;height:max-content;padding:.5rem;position:relative}.feed-block .filter-group button:hover,.feed-block .filter-group label:hover{color:var(--action-contrast)}.feed-block .filter-group :checked+label .label,.feed-block .filter-group button:hover .label,.feed-block .filter-group label:hover .label{opacity:1;visibility:visible}.feed-block .filter-group button .label,.feed-block .filter-group label .label,.feed-block .filter-group:has(label:hover) :checked+label .label{--height:max-content;bottom:-2rem;font-weight:var(--fw-b);opacity:0;visibility:hidden;white-space:nowrap;width:-moz-max-content;width:max-content}.feed-block h3{font-size:var(--medium);margin:0 0 .25rem}.placeholder{align-items:center;aspect-ratio:1;background:var(--base);border:1rem solid var(--base-50);border-radius:1rem;display:flex;justify-content:center}.placeholder i.icon{--w:50%;animation:dance 2.5s ease-in-out infinite;color:var(--base-200)}.item-grid{max-width:none;padding:0 var(--chip)}.feed.item{background:var(--base-50);border-radius:.5rem;box-shadow:0 2px 4px rgba(0,0,0,.1);height:-moz-fit-content;height:fit-content;overflow:hidden;padding:0;position:relative}.feed.item details{padding:0;position:relative;width:100%;z-index:var(--z-2)}.feed.item details summary{backdrop-filter:blur(5px);background-color:rgba(var(--base-rgb),var(--op-2));right:0;position:absolute;top:-3rem;width:100%}.feed.item details summary:hover{background-color:rgba(var(--action-rgb),var(--op-45))}.feed.item details[open]{padding:.25rem .5rem}.feed.item details[open] summary .icon{opacity:0}.feed.item img{height:100%;-o-object-fit:cover;object-fit:cover;width:100%}.feed.item img:hover{opacity:.8}.feed.item[data-timeline] .images{aspect-ratio:3/2;padding:0 0 1rem}.feed.item[data-timeline] .images span{background-color:var(--action-0);color:var(--action-contrast);padding:.25rem .5rem;position:absolute;width:50%}.feed.item[data-timeline] .images span:first-of-type{bottom:0;left:50%;text-align:left}.feed.item[data-timeline] .images span:last-of-type{right:50%;top:0}.feed.item[data-timeline] .images>a{display:flex;flex-wrap:nowrap;height:100%;position:relative;width:100%}.feed.item[data-timeline] img{height:100%;-o-object-fit:cover;object-fit:cover;width:50%}.feed.item[data-timeline] img:first-of-type{border-left:1px solid var(--action-0)}.feed.item a:after,.feed.item a:before{display:none}.feed.item label{font-weight:400;text-transform:none}.feed.item label .icon{--w:1.5em}.item-grid:has([data-timeline]){grid-template-columns:repeat(1,1fr)}@media(min-width:768px){.item-grid:has([data-timeline]){grid-template-columns:repeat(2,1fr)}}.items-wrap [type=checkbox],.items-wrap [type=radio]{right:-200vw;opacity:0;position:absolute}.items-wrap [type=checkbox]+label,.items-wrap [type=radio]+label{cursor:pointer;position:relative}.items-wrap [type=checkbox]+label:hover,.items-wrap [type=radio]+label:hover{color:var(--action-0)}.items-wrap [type=checkbox]+label:after,.items-wrap [type=checkbox]+label:before,.items-wrap [type=radio]+label:after,.items-wrap [type=radio]+label:before{content:"";position:absolute;top:50%}.items-wrap [type=checkbox]+label:after,.items-wrap [type=radio]+label:after{border:solid var(--light-0);border-width:0 0 2px 2px;display:none;height:10px;right:5px;transform:translateY(-70%) rotate(-45deg);width:5px}.items-wrap [type=checkbox]+label:before,.items-wrap [type=radio]+label:before{background-color:var(--base);border:2px solid var(--contrast-200);border-radius:var(--radius);height:1rem;right:0;transform:translateY(-50%);width:1rem}.items-wrap [type=checkbox]:hover+label:before,.items-wrap [type=radio]:hover+label:before{border-color:var(--action-200)}.items-wrap [type=checkbox]:checked+label:before,.items-wrap [type=radio]:checked+label:before{background-color:var(--action-0);border-color:var(--action-100)}.items-wrap [type=radio]:checked+label:before{border-radius:50%}.items-wrap [type=checkbox]:checked+label:after{border:solid var(--light-0);border-width:0 0 2px 2px;display:block;height:.66rem;right:5px;top:50%;transform:translateY(-70%) rotate(-45deg);width:.35rem}.items-wrap :disabled+label{cursor:not-allowed}.items-wrap :disabled+label,.items-wrap :disabled+label:hover{background-color:var(--base-50);border-color:var(--base-200);color:var(--base-200)}.items-wrap :disabled+label:before{border-color:var(--base-200)}#jvb-selector .items-wrap [type=checkbox]+label,#jvb-selector .items-wrap [type=radio]+label{flex:1;padding-right:2rem!important;transform-origin:top center;will-change:transform}
diff --git a/build/feed/style-index.css b/build/feed/style-index.css
index 7429b47..273f7f5 100644
--- a/build/feed/style-index.css
+++ b/build/feed/style-index.css
@@ -1 +1 @@
-.feed-block{grid-column:full}.feed-block .filters{margin:0 auto;max-width:var(--wide);padding:1rem 0}.feed-block .filter-group{padding:2rem 0;position:relative}.feed-block .filter-group .label{left:0;position:absolute}.feed-block .filter-group>.label{top:0}.feed-block .filter-group [type=radio]{left:var(--offScreen);position:absolute}.feed-block .filter-group button,.feed-block .filter-group label{height:-moz-max-content;height:max-content;padding:.5rem;position:relative}.feed-block .filter-group button:hover,.feed-block .filter-group label:hover{color:var(--action-contrast)}.feed-block .filter-group :checked+label .label,.feed-block .filter-group button:hover .label,.feed-block .filter-group label:hover .label{opacity:1;visibility:visible}.feed-block .filter-group button .label,.feed-block .filter-group label .label,.feed-block .filter-group:has(label:hover) :checked+label .label{--height:max-content;bottom:-2rem;font-weight:var(--fw-b);opacity:0;visibility:hidden;white-space:nowrap;width:-moz-max-content;width:max-content}.feed-block h3{font-size:var(--medium);margin:0 0 .25rem}.placeholder{align-items:center;aspect-ratio:1;background:var(--base);border:1rem solid var(--base-50);border-radius:1rem;display:flex;justify-content:center}.placeholder i.icon{--w:50%;animation:dance 2.5s ease-in-out infinite;color:var(--base-200)}.item-grid{max-width:none;padding:0 var(--chip)}.feed.item{background:var(--base-50);border-radius:.5rem;box-shadow:0 2px 4px rgba(0,0,0,.1);height:-moz-fit-content;height:fit-content;overflow:hidden;padding:0;position:relative}.feed.item details{padding:0;position:relative;width:100%;z-index:var(--z-2)}.feed.item details summary{backdrop-filter:blur(5px);background-color:rgba(var(--base-rgb),var(--op-2));left:0;position:absolute;top:-3rem;width:100%}.feed.item details summary:hover{background-color:rgba(var(--action-rgb),var(--op-45))}.feed.item details[open]{padding:.25rem .5rem}.feed.item details[open] summary .icon{opacity:0}.feed.item img{-o-object-fit:cover;object-fit:cover}.feed.item img:hover{opacity:.8}.feed.item[data-timeline] .images{aspect-ratio:3/2;padding:0 0 1rem}.feed.item[data-timeline] .images span{background-color:var(--action-0);color:var(--action-contrast);padding:.25rem .5rem;position:absolute;width:50%}.feed.item[data-timeline] .images span:first-of-type{bottom:0;right:50%;text-align:right}.feed.item[data-timeline] .images span:last-of-type{left:50%;top:0}.feed.item[data-timeline] .images>a{display:flex;flex-wrap:nowrap;height:100%;position:relative;width:100%}.feed.item[data-timeline] img{height:100%;-o-object-fit:cover;object-fit:cover;width:50%}.feed.item[data-timeline] img:first-of-type{border-right:1px solid var(--action-0)}.feed.item a:after,.feed.item a:before{display:none}.feed.item label{font-weight:400;text-transform:none}.feed.item label .icon{--w:1.5em}.item-grid:has([data-timeline]){grid-template-columns:repeat(1,1fr)}@media(min-width:768px){.item-grid:has([data-timeline]){grid-template-columns:repeat(2,1fr)}}
+.feed-block{grid-column:full}.feed-block .filters{margin:0 auto;max-width:var(--wide);padding:1rem 0}.feed-block .filters .remove-term.remove-term{height:-moz-max-content;height:max-content;width:-moz-max-content;width:max-content}.feed-block .filter-group{padding:2rem 0;position:relative}.feed-block .filter-group .label{left:0;position:absolute}.feed-block .filter-group>.label{top:0}.feed-block .filter-group [type=radio]{left:var(--offScreen);position:absolute}.feed-block .filter-group button,.feed-block .filter-group label{height:-moz-max-content;height:max-content;padding:.5rem;position:relative}.feed-block .filter-group button:hover,.feed-block .filter-group label:hover{color:var(--action-contrast)}.feed-block .filter-group :checked+label .label,.feed-block .filter-group button:hover .label,.feed-block .filter-group label:hover .label{opacity:1;visibility:visible}.feed-block .filter-group button .label,.feed-block .filter-group label .label,.feed-block .filter-group:has(label:hover) :checked+label .label{--height:max-content;bottom:-2rem;font-weight:var(--fw-b);opacity:0;visibility:hidden;white-space:nowrap;width:-moz-max-content;width:max-content}.feed-block h3{font-size:var(--medium);margin:0 0 .25rem}.placeholder{align-items:center;aspect-ratio:1;background:var(--base);border:1rem solid var(--base-50);border-radius:1rem;display:flex;justify-content:center}.placeholder i.icon{--w:50%;animation:dance 2.5s ease-in-out infinite;color:var(--base-200)}.item-grid{max-width:none;padding:0 var(--chip)}.feed.item{background:var(--base-50);border-radius:.5rem;box-shadow:0 2px 4px rgba(0,0,0,.1);height:-moz-fit-content;height:fit-content;overflow:hidden;padding:0;position:relative}.feed.item details{padding:0;position:relative;width:100%;z-index:var(--z-2)}.feed.item details summary{backdrop-filter:blur(5px);background-color:rgba(var(--base-rgb),var(--op-2));left:0;position:absolute;top:-3rem;width:100%}.feed.item details summary:hover{background-color:rgba(var(--action-rgb),var(--op-45))}.feed.item details[open]{padding:.25rem .5rem}.feed.item details[open] summary .icon{opacity:0}.feed.item img{height:100%;-o-object-fit:cover;object-fit:cover;width:100%}.feed.item img:hover{opacity:.8}.feed.item[data-timeline] .images{aspect-ratio:3/2;padding:0 0 1rem}.feed.item[data-timeline] .images span{background-color:var(--action-0);color:var(--action-contrast);padding:.25rem .5rem;position:absolute;width:50%}.feed.item[data-timeline] .images span:first-of-type{bottom:0;right:50%;text-align:right}.feed.item[data-timeline] .images span:last-of-type{left:50%;top:0}.feed.item[data-timeline] .images>a{display:flex;flex-wrap:nowrap;height:100%;position:relative;width:100%}.feed.item[data-timeline] img{height:100%;-o-object-fit:cover;object-fit:cover;width:50%}.feed.item[data-timeline] img:first-of-type{border-right:1px solid var(--action-0)}.feed.item a:after,.feed.item a:before{display:none}.feed.item label{font-weight:400;text-transform:none}.feed.item label .icon{--w:1.5em}.item-grid:has([data-timeline]){grid-template-columns:repeat(1,1fr)}@media(min-width:768px){.item-grid:has([data-timeline]){grid-template-columns:repeat(2,1fr)}}.items-wrap [type=checkbox],.items-wrap [type=radio]{left:-200vw;opacity:0;position:absolute}.items-wrap [type=checkbox]+label,.items-wrap [type=radio]+label{cursor:pointer;position:relative}.items-wrap [type=checkbox]+label:hover,.items-wrap [type=radio]+label:hover{color:var(--action-0)}.items-wrap [type=checkbox]+label:after,.items-wrap [type=checkbox]+label:before,.items-wrap [type=radio]+label:after,.items-wrap [type=radio]+label:before{content:"";position:absolute;top:50%}.items-wrap [type=checkbox]+label:after,.items-wrap [type=radio]+label:after{border:solid var(--light-0);border-width:0 2px 2px 0;display:none;height:10px;left:5px;transform:translateY(-70%) rotate(45deg);width:5px}.items-wrap [type=checkbox]+label:before,.items-wrap [type=radio]+label:before{background-color:var(--base);border:2px solid var(--contrast-200);border-radius:var(--radius);height:1rem;left:0;transform:translateY(-50%);width:1rem}.items-wrap [type=checkbox]:hover+label:before,.items-wrap [type=radio]:hover+label:before{border-color:var(--action-200)}.items-wrap [type=checkbox]:checked+label:before,.items-wrap [type=radio]:checked+label:before{background-color:var(--action-0);border-color:var(--action-100)}.items-wrap [type=radio]:checked+label:before{border-radius:50%}.items-wrap [type=checkbox]:checked+label:after{border:solid var(--light-0);border-width:0 2px 2px 0;display:block;height:.66rem;left:5px;top:50%;transform:translateY(-70%) rotate(45deg);width:.35rem}.items-wrap :disabled+label{cursor:not-allowed}.items-wrap :disabled+label,.items-wrap :disabled+label:hover{background-color:var(--base-50);border-color:var(--base-200);color:var(--base-200)}.items-wrap :disabled+label:before{border-color:var(--base-200)}#jvb-selector .items-wrap [type=checkbox]+label,#jvb-selector .items-wrap [type=radio]+label{flex:1;padding-left:2rem!important;transform-origin:top center;will-change:transform}
diff --git a/build/feed/view.asset.php b/build/feed/view.asset.php
index ef74b8c..45073e4 100644
--- a/build/feed/view.asset.php
+++ b/build/feed/view.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array(), 'version' => '1469437e42d138dbcd90');
+<?php return array('dependencies' => array(), 'version' => 'b17f126267647a51eaa7');
diff --git a/build/feed/view.js b/build/feed/view.js
index b4b82e2..09d0f45 100644
--- a/build/feed/view.js
+++ b/build/feed/view.js
@@ -1 +1 @@
-(()=>{class e{constructor(){this.container=document.querySelector("section.feed-block"),this.container&&(this.a11y=window.jvbA11y,this.cache=new window.jvbCache("feed"),this.error=window.jvbError,this.config={source:"",context:"",highlight:null,gallery:!1,view:this.cache.get("feedView")||"grid",...this.container.dataset},this.initElements(),this.initFilters(),this.loadWhenAble())}loadWhenAble(){"requestIdleCallback"in window?requestIdleCallback((()=>{this.initTaxonomies(),this.initStore(),this.initListeners(),this.initGallery()}),{timeout:2e3}):setTimeout((()=>{this.initTaxonomies(),this.initStore(),this.initListeners(),this.initGallery()}),100)}initElements(){var e;this.currentTaxonomies=new Set,this.taxonomyFilters={},this.elements={filterTrigger:"[data-filter]",filters:{content:'[data-filter="content"]',orderby:'[data-filter="orderby"]',order:'[data-filter="order"]',match:'[data-filter="match"]',favourites:'[data-filter="favourites"]',taxonomy:'[data-filter^="taxonomy"]'},selectedTax:".selected-items",clearFilter:"button.clear-filters",loadMore:"button.load-more",filterContainer:".filters",grid:".item-grid"},this.ui=window.uiFromSelectors(this.elements),this.ui.content=null!==(e=this.ui.filterContainer.querySelectorAll('[name="content"]'))&&void 0!==e&&e,this.ui.taxonomies=this.ui.filterContainer.querySelectorAll("[data-taxonomy]"),this.ui.content&&this.ui.content.length>0?this.contentTypes=Array.from(this.ui.content).map((e=>e.value)):this.contentTypes=[this.container.dataset.content],this.ui.taxonomies.length>0?this.taxonomies=Array.from(this.ui.taxonomies).map((e=>e.dataset.taxonomy)):this.taxonomies=[]}async initTaxonomies(){this.selector=window.jvbSelector;const e=document.querySelectorAll('[data-filter="taxonomy"]');this.selector.isInitializing=!0,e.forEach((e=>{const t=e.dataset.taxonomy;this.currentTaxonomies.add(t),this.selector.registerFilterButton(e,{button:e,buttonSelector:'[data-filter="taxonomy"]',selected:this.ui.selectedTax}),this.addTaxonomyPreloadListeners(e,t)})),this.selector.isInitializing=!1,this.selector.subscribe(((e,t)=>{"selected-terms"===e&&this.handleTaxonomyChange(t)}))}addTaxonomyPreloadListeners(e,t){const i=()=>{this.selector.preloadTaxonomy(t)};e.addEventListener("mouseenter",i,{once:!0}),e.addEventListener("pointerdown",i,{once:!0}),e.addEventListener("focus",i,{once:!0})}handleTaxonomyChange(e){const{terms:t,taxonomy:i}=e;t.size>0?this.taxonomyFilters[i]=Array.from(t.keys()):delete this.taxonomyFilters[i];let s={page:1};Object.keys(this.taxonomyFilters).length>0&&(s.taxonomy=this.taxonomyFilters),this.updateFilter(s)}clearAllTaxonomies(){this.taxonomyFilters={},window.removeChildren(this.ui.selectedTax),this.updateFilter({taxonomy:null,page:1})}initFilters(){this.filters={content:this.contentTypes[0],orderby:"date",order:"desc",page:1},this.config.context&&(this.filters.context=this.config.context),this.config.source&&(this.filters.source=this.config.source),this.processCachedFilters(),this.processURLFilters(),this.syncUIToFilters()}syncUIToFilters(){this.ui.filterContainer&&Object.entries(this.filters).forEach((([e,t])=>{const i=this.ui.filterContainer.querySelector(`[data-filter="${e}"][value="${t}"]`);i&&(i.checked=!0)})),this.updateContentFor(this.filters.content)}nextPage(){this.store.setFilter("page",this.store.filters.page++)}initStore(){const e=window.jvbStore.register("feed",{storeName:"feed",endpoint:"feed",keyPath:"id",indexes:[{name:"content",keyPath:"content"},{name:"taxonomy",keyPath:"taxonomy"},{name:"user",keyPath:"user"},{name:"date",keyPath:"modified"},{name:"title",keyPath:"title"}],filters:this.filters,TTL:216e5,showLoading:!0,required:"content",delayFetch:!0});this.store=e.feed,this.store.subscribe(((e,t)=>{"data-loaded"===e&&(this.renderItems(),this.ui.loadMore.hidden=!0,this.store.lastResponse&&this.store.lastResponse.has_more&&(this.ui.loadMore.hidden=!this.store.lastResponse.has_more))}))}initGallery(){this.gallery=!!this.config.gallery&&window.jvbGallery,this.gallery&&this.gallery.subscribe(((e,t)=>{"load-more"===e&&this.store.lastResponse&&this.store.lastResponse.has_more&&this.nextPage()}))}processCachedFilters(){Object.keys(this.filters).forEach((e=>{let t=this.cache.get(`${this.config.source}_${this.config.context}_${e}`);t&&t!==this.filters[e]&&(this.filters[e]=t)}))}processURLFilters(){if(this.filters.page>1)return!1;const e=new URLSearchParams(window.location.search);if(!e.toString())return!1;["content","order","orderby","favourites","match"].forEach((t=>{let i=e.get(`f_${t}`);if(i){this.filters[t]=i;let e=this.ui.filters[t];e&&(e.checked=!0)}}));let t=!1;if(e.forEach(((e,i)=>{if(i.startsWith("f_tax_")){t=!0;const s=i.replace("f_tax_","");this.taxonomyFilters[s]||(this.taxonomyFilters[s]=[]),this.taxonomyFilters[s]=e.split(",").map(Number)}})),this.ui.filterContainer&&t)for(let[e,t]in Object.entries(this.taxonomyFilters)){let i=this.ui.filterContainer.querySelector(`[data-taxonomy="${e}"]`);i&&(i.dataset.fieldId?(this.selector.get(i.dataset.fieldId).selectedTerms=new Set(t),this.selector.initFieldDisplay(i.dataset.fieldId)):this.selector.registerField(i,{button:i,buttonSelector:'[data-filter="taxonomy"]',selected:this.ui.selectedTax,selectedItems:t}))}return!0}updateURL(){const e=new URLSearchParams;["content","order","orderby","match"].forEach((t=>{this.filters[t]&&e.set(`f_${t}`,this.filters[t])})),Object.entries(this.taxonomyFilters).forEach((([t,i])=>{i.length>0&&e.set(`f_tax_${t}`,i.join(","))}));const t=`${window.location.pathname}${e.toString()?"?"+e.toString():""}`;window.history.pushState({filters:this.filters},"",t)}renderItems(){let e=this.store.getFiltered();if(1===this.store.filters.page&&window.removeChildren(this.ui.grid),0===e.length)return void this.a11y.announceItems(0,this.store.filters.page>0);const t=document.createDocumentFragment(),i=s=>{const r=Math.min(s+10,e.length);for(let i=s;i<r;i++){const s=e[i],r=this.createItemElement(s);t.appendChild(r)}r<e.length?requestAnimationFrame((()=>i(r))):(this.removePlaceholders(),this.ui.grid.append(t),this.config.gallery&&this.gallery.updateGalleryItems(this.gallery.getGalleryItems()),this.a11y.makeNavigable(this.ui.grid.querySelectorAll(".item:not([data-keyboard-nav])")),this.a11y.announceItems(e.length,this.store.filters.page>1,this.store.hasMore))};e.length>0?i(0):this.a11y.announceItems(0,this.store.filters.page>1,!1),this.ui.filters.match&&(this.ui.filters.match.hidden=0===Object.keys(this.taxonomyFilters).length),this.ui.clearFilter&&(this.ui.clearFilter.hidden=0===Object.keys(this.taxonomyFilters).length)}createItemElement(e){let t=window.getTemplate(`feedItem${window.uppercaseFirst(e.content)}`);const i=Object.hasOwn(t.dataset,"timeline");for(let[s,r]of Object.entries(e.fields)){if(i&&["timeline","number"].includes(s))continue;let o=t.querySelector(`[data-field="${s}"]`);o&&(""!==r?this.isImageField(e,r)?this.formatImageFields(o,r,e):this.isTaxonomyField(e,s)?this.formatTaxonomyField(o,e,s,r):this.isTimeField(o)?this.formatTimeField(o,r):this.formatField(o,r):o.remove())}let s=t.querySelector("a");var r;return s&&""!==e.url&&([s.href,s.title]=[e.url,`View ${null!==(r=e.fields.post_title)&&void 0!==r?r:"Item"}`]),i&&this.addTimelineElements(e,t),t}splitIDs(e){return String(e).split(",").map((e=>parseInt(e.trim()))).filter((e=>e))}isImageField(e,t){return!(!Object.hasOwn(e,"images")||0===Object.keys(e.images).length)&&this.splitIDs(t).some((t=>Object.keys(e.images).map((e=>parseInt(e))).includes(parseInt(t))))}formatImageFields(e,t,i){let s=this.splitIDs(t);if(0!==s.length)if(s.length>1){let t=e.querySelector("img");if(!t)return;s.forEach((s=>{let r=t.cloneNode(!0);this.formatImageField(r,s,i),e.append(r)})),t.remove()}else{if("IMG"!==e.tagName&&!(e=e.querySelector("img")))return;this.formatImageField(e,s[0],i)}}formatImageField(e,t,i){var s;let r=null!==(s=i.images[t])&&void 0!==s&&s;r&&([e.src,e.srcset,e.alt]=[r.tiny,`${r.tiny} 50w, ${r.small} 300w, ${r.medium} 1024w`,r["image-alt-text"]])}isTaxonomyField(e,t){return!(!Object.hasOwn(e,"taxonomies")||0===Object.keys(e.taxonomies).length)&&Object.keys(e.taxonomies).includes(t)}formatTaxonomyField(e,t,i,s){if("UL"!==e.tagName||!e.querySelector("li"))return;let r=this.splitIDs(s);0===r.length&&e.remove();let o=e.querySelector("li");for(let s of r){var n;let r=null!==(n=t.taxonomies[i][s])&&void 0!==n&&n;if(!r)continue;let a=o.cloneNode(!0),l=a.querySelector("a");l&&([l.href,l.title,l.textContent]=[r.url,`See more ${r.title}`,r.title],e.append(a))}o.remove()}isTimeField(e){return"TIME"===e.tagName||null!==e.querySelector("time")}formatTimeField(e,t){("TIME"===e.tagName||(e=e.querySelector("time")))&&(e.setAttribute("datetime",t),e.textContent=window.formatTimeAgo(t,"F Y"))}formatField(e,t){e.textContent=t}addTimelineElements(e,t){let[i,s,r,o]=[t.querySelector("span.after-text"),t.querySelector('[data-field="number"] b'),t.querySelector('[data-field="started"] time'),t.querySelector('[data-field="updated"] time')];i&&(i.textContent=`After ${e.fields.number} Tx`),s&&(s.textContent=e.fields.number),r&&this.formatTimeField(r,e.fields.timeline[0].post_date),o&&this.formatTimeField(o,e.fields.timeline[e.fields.timeline.length-1].post_date)}removePlaceholders(){const e=this.ui.grid.querySelectorAll(".placeholder");e.length>0&&e.forEach((e=>e.remove()))}addPlaceholders(){let e=this.contentTypes.length;const t=document.createDocumentFragment();for(let i=0;i<12;i++){let i,s=window.getTemplate("placeholderTemplate"),r=Math.floor(Math.random()*e);i=this.ui.content&&this.ui.content.length>0?this.ui.content.filter((e=>e.value===this.contentTypes[r])).querySelector(".icon").cloneNode(!0):window.getIcon(this.container.dataset.icon),s.append(i),t.append(s)}this.ui.grid.append(t)}updateFilter(e){let t=["taxonomy","favourites","match",...Object.keys(this.filters)];e=Object.keys(e).filter((e=>t.includes(e))).reduce(((t,i)=>(t[i]=e[i],t)),{}),window.getDifferences.map(this.filters,e)&&(this.filters={...this.filters,...e},this.updateURL(),this.store.setFilters(e))}updateContentFor(e){this.ui.filterContainer.querySelectorAll('[data-filter="taxonomy"]').forEach((t=>{const i=t.dataset.for?.split(",")||[];t.hidden=i.length>0&&!i.includes(e)})),this.ui.filterContainer.querySelectorAll("[data-for]").forEach((t=>{const i=t.dataset.for?.split(",")||[];i.length>0&&(t.hidden=!i.includes(e),t.hidden&&t.checked&&(t.checked=!1))}));const t=this.ui.filterContainer.querySelector('[name="orderby"]:checked');this.updateOrderDirectionVisibility(t?.value)}updateOrderDirectionVisibility(e){const t=this.ui.filterContainer.querySelector(".order-direction");if(t){const i=t.dataset.forOrder?.split(",")||[];t.hidden=i.length>0&&!i.includes(e)}}initListeners(){this.popStateHandler=this.handlePopState.bind(this),this.clickHandler=this.handleClick.bind(this),this.changeHandler=this.handleChange.bind(this),this.imageObserver=null,this.resizeObserver=null,"IntersectionObserver"in window&&(this.imageObserver=new IntersectionObserver((e=>{e.forEach((e=>{this.loadImage(e.target),this.imageObserver.unobserve(e.target)}))}),{rootMargin:"100px",threshold:.1})),"ResizeObserver"in window?this.resizeObserver=new ResizeObserver((()=>{window.debouncer.schedule("feed-update-images",(()=>this.updateImageSizes()),250)})):window.addEventListener("resize",(()=>{window.debouncer.schedule("feed-update-images",(()=>this.updateImageSizes()),250)})),window.addEventListener("popstate",this.popStateHandler),document.addEventListener("click",this.clickHandler),document.addEventListener("change",this.changeHandler)}handlePopState(e){e.state?.filters&&this.processURLFilters()&&(this.store.setFilters(this.filters),this.a11y.announce("Feed filters updated from browser history"))}handleClick(e){window.targetCheck(e,this.elements.loadMore)?this.nextPage():window.targetCheck(e,this.elements.clearFilter)?this.clearAllTaxonomies():window.targetCheck(e,".remove-item")&&this.handleRemoveSelectedTerm(e)}handleRemoveSelectedTerm(e){const t=e.target.closest(".selected-item");if(!t)return;const i=parseInt(t.dataset.id),s=t.dataset.taxonomy;this.taxonomyFilters[s]&&(this.taxonomyFilters[s]=this.taxonomyFilters[s].filter((e=>e!==i)),0===this.taxonomyFilters[s].length&&delete this.taxonomyFilters[s]),t.remove(),this.updateFilter({taxonomy:Object.keys(this.taxonomyFilters).length>0?this.taxonomyFilters:null,page:1})}handleChange(e){let t=e.target;Object.hasOwn(t.dataset,"filter")&&("content"===t.dataset.filter?(this.updateContentFor(t.value),this.updateFilter({content:t.value,page:1})):"orderby"===t.dataset.filter?(this.updateOrderDirectionVisibility(t.value),this.updateFilter({orderby:t.value,page:1})):"order"===t.dataset.filter?this.updateFilter({order:t.value,page:1}):"match"===t.dataset.filter?this.updateFilter({match:t.checked?"all":"any",page:1}):"favourites"===t.dataset.filter&&this.updateFilter({favourites:t.checked,page:1}))}}document.addEventListener("DOMContentLoaded",(async function(){window.auth.subscribe((t=>{"auth-loaded"===t&&(window.feedBlock=new e)}))}))})();
\ No newline at end of file
+(()=>{class e{constructor(){this.container=document.querySelector("section.feed-block"),this.container&&(this.a11y=window.jvbA11y,this.error=window.jvbError,this.cache=new window.jvbCache("feed"),this.config={source:"",context:"",highlight:null,gallery:!1,view:this.cache.get("feedView")||"grid",...this.container.dataset},this.init())}init(){this.initElements(),this.initListeners(),this.initFilters(),"requestIdleCallback"in window?requestIdleCallback((()=>{this.initStore(),this.initTaxonomies(),this.processCachedFilters(),this.processURLFilters(),this.updateFilterUI(),this.initGallery()}),{timeout:2e3}):setTimeout((()=>{this.initStore(),this.initTaxonomies(),this.processCachedFilters(),this.processURLFilters(),this.updateFilterUI(),this.initGallery()}),100)}initElements(){this.selectors={filterTrigger:"[data-filter]",filters:{actions:".filter-actions .toggle-text",container:".filters",content:'[data-filter="content"]',orderby:'[data-filter="orderby"]',order:'[data-filter="order"]',match:'[data-filter="match"]',favourites:'[data-filter="favourites"]',taxonomy:'[data-filter^="taxonomy"]'},grid:".item-grid",selected:".selected-items",buttons:{loadMore:"button.load-more",remove:".remove-term",clearFilters:"button.clear-filters"}},this.ui=window.uiFromSelectors(this.selectors,this.container),this.ui.content=this.ui.filters.container.querySelectorAll('[name="content"]'),0===this.ui.content.length&&(this.ui.content=!1),this.ui.taxonomies=this.ui.filters.container.querySelectorAll("[data-taxonomy]"),0===this.ui.taxonomies.length&&(this.ui.content=!1),this.ui.orderbyWrap=this.ui.filters.container.querySelector("[data-for-order]"),0===this.ui.orderbyWrap.length&&(this.ui.content=!1),this.ui.order=this.ui.filters.container.querySelectorAll('[data-filter="order"]'),0===this.ui.order.length&&(this.ui.content=!1),this.ui.orderby=this.ui.filters.container.querySelectorAll('[data-filter="orderby"]'),0===this.ui.orderby.length&&(this.ui.content=!1),this.contentTypes=this.ui.content?Array.from(this.ui.content).map((e=>e.value)):[this.container.dataset.content],this.taxonomies=this.ui.taxonomies?.length>0?Array.from(this.ui.taxonomies).map((e=>e.dataset.taxonomy)):[]}initListeners(){this.popStateHandler=this.handlePopState.bind(this),this.clickHandler=this.handleClick.bind(this),this.changeHandler=this.handleChange.bind(this),window.addEventListener("popstate",this.popStateHandler),document.addEventListener("click",this.clickHandler),document.addEventListener("change",this.changeHandler)}initFilters(){this.allowedFilters=["content","order","orderby","favourites","match"];let e={content:this.contentTypes[0],orderby:"date",order:"desc",page:1};this.config.context&&(e.context=this.config.context),this.config.source&&(e.source=this.config.source),this.filters=e,this.defaults={...e}}updateFilterUI(){if(this.ui.filters.container&&([this.ui.content,this.ui.orderby,this.ui.order].forEach((e=>{if(e)for(let t of e){let[e,i]=[t.dataset.filter,t.value];if(!Object.hasOwn(this.store.filters,e))break;let s=this.store.filters[e]===i;if(s){t.checked=s;break}}})),Object.hasOwn(this.store.filters,"taxonomy")))for(let[e,t]of Object.entries(this.store.filters.taxonomy))t.forEach((e=>{e=parseInt(e),this.selector.store.get(e)&&this.createTermElement(e)}))}handlePopState(e){e.state?.filters&&this.processURLFilters()&&(this.store.setFilters(this.filters),this.a11y.announce("Feed filters updated from browser history"))}handleClick(e){window.targetCheck(e,this.selectors.buttons.loadMore)?this.nextPage():window.targetCheck(e,this.selectors.buttons.clearFilters)&&this.clearFilters();let t=window.targetCheck(e,this.selectors.buttons.remove);t&&this.removeSelectedTerm(t)}nextPage(){const e=(this.store.filters.page||1)+1,t=this.store.lastResponse?.pages||e;this.store.setFilters({page:Math.min(e,t)})}handleChange(e){const t=e.target;if(Object.hasOwn(t.dataset,"filter")){if(this.allowedFilters.includes(t.dataset.filter)){let e={};e[t.dataset.filter]=t.value,this.resetFilters(e)}switch(t.dataset.filter){case"content":this.updateContentFor(t.value);break;case"orderby":this.updateOrderOptions(t.value)}}}clearFilters(){this.taxFilters={},window.removeChildren(this.ui.selected),this.taxonomies.forEach((e=>{let t=this.getFieldId(e);this.selector.selectedTerms.get(t)?.clear()})),this.store.setFilters({...this.defaults,taxonomy:null}),this.updateURL(),this.saveToCacheFilters()}resetFilters(e){e={...this.store.filters,page:1,...e},this.store.setFilters(e),this.updateURL(),this.saveToCacheFilters()}getFieldId(e){var t;return this.selector.getFieldId(null!==(t=Array.from(this.ui.taxonomies).filter((t=>t.dataset.taxonomy===e))[0])&&void 0!==t?t:null)}removeSelectedTerm(e){const t=parseInt(e.dataset.id),i=e.dataset.taxonomy;Object.hasOwn(this.taxFilters,i)&&(this.taxFilters[i]=this.taxFilters[i].filter((e=>e!==t)),0===this.taxFilters[i].length&&delete this.taxFilters[i]),e.remove();const s=this.getFieldId(i);s&&(this.selector.activeField=s,this.selector.removeSelected(t,s)),this.resetFilters({taxonomy:Object.keys(this.taxFilters).length>0?this.taxFilters:null})}updateContentFor(e){[this.ui.taxonomies,this.ui.orderby].forEach((t=>{t&&t.forEach((t=>{var i;const s=null!==(i=t.dataset.for?.split(","))&&void 0!==i?i:[];t.hidden=s.length>0&&!s.includes(e),t.hidden&&t.checked&&(t.checked=!1)}))}))}updateOrderOptions(e){if(this.ui.orderbyWrap){var t;let i=null!==(t=this.ui.orderbyWrap.dataset.forOrder.split(","))&&void 0!==t?t:[];this.ui.orderbyWrap.hidden=!i.includes(e)}}updateFilterControls(){const e=0===Object.keys(this.taxFilters).length;this.ui.buttons.clearFilters&&(this.ui.buttons.clearFilters.hidden=e),this.ui.filters.actions&&(this.ui.filters.actions.hidden=e)}async initTaxonomies(){this.taxFilters={},this.selector=window.jvbSelector,this.selector.subscribe(((e,t)=>{"selected-terms"===e&&this.handleTaxonomyChange(t)}))}handleTaxonomyChange(e){const{terms:t,taxonomy:i}=e;0!==t.size&&(this.taxFilters[i]=Array.from(t),this.resetFilters({taxonomy:this.taxFilters}),t.forEach((e=>{this.createTermElement(e)})),this.updateFilterControls())}getTaxonomyIcon(e){let t=Array.from(this.ui.taxonomies).find((t=>t.dataset.taxonomy===e));return t?.dataset.icon.trim()||"tag"}createTermElement(e){const t=this.selector.store.get(e);if(!t)return;if(this.ui.selected.querySelector(`[data-id="${e}"]`))return;let i=this.getTaxonomyIcon(t.taxonomy),s=window.getTemplate("feedTerm");if(!s)return;let[r,o]=[s.querySelector(".icon"),s.querySelector("span")];r&&o&&(s.dataset.id=t.id,s.dataset.taxonomy=t.taxonomy,r.className=`icon icon-${i}`,o.textContent=t.name,this.ui.selected.append(s))}processCachedFilters(){Object.keys(this.filters).forEach((e=>{let t=this.cache.get(`${this.config.source}_${this.config.context}_${e}`);t&&t!==this.filters[e]&&(this.filters[e]=t)}))}processURLFilters(){if(!this.isFirstPage())return!1;const e=new URLSearchParams(window.location.search);if(!e.toString())return!1;let t=!1;this.allowedFilters.forEach((i=>{let s=e.get(`f_${i}`);s&&(t=!0,this.filters[i]=s)}));let i=!1;return e.forEach(((e,s)=>{if(s.startsWith("f_tax_")){i=!0,t=!0;const r=s.replace("f_tax_","");this.taxFilters[r]=e.split(",").map(Number)}})),t&&(i&&(this.filters.taxonomy=this.taxFilters),this.resetFilters(this.filters)),!0}updateURL(){const e=new URLSearchParams;this.allowedFilters.forEach((t=>{Object.hasOwn(this.store.filters,t)&&this.store.filters[t]!==this.defaults[t]&&e.set(`f_${t}`,this.store.filters[t])}));for(let[t,i]of Object.entries(this.taxFilters))i.length>0&&e.set(`f_tax_${t}`,i.join(","));const t=`${window.location.pathname}${e.toString()?"?"+e.toString():""}`;t!==window.location.pathname+window.location.search&&window.history.pushState({filters:this.store.filters},"",t)}saveToCacheFilters(){Object.keys(this.store.filters).forEach((e=>{const t=`${this.config.source}_${this.config.context}_${e}`;this.store.filters[e]!==this.defaults[e]?this.cache.set(t,this.store.filters[e]):this.cache.remove(t)}));const e=`${this.config.source}_${this.config.context}_taxonomy`;Object.keys(this.taxFilters).length>0?this.cache.set(e,this.taxFilters):this.cache.remove(e)}initGallery(){this.gallery=!!this.config.gallery&&window.jvbGallery,this.gallery&&this.gallery.subscribe(((e,t)=>{"load-more"===e&&this.store.lastResponse?.has_more&&this.nextPage()}))}initStore(){const e=window.jvbStore.register("feed",{storeName:"feed",endpoint:"feed",keyPath:"id",indexes:[{name:"content",keyPath:"content"},{name:"taxonomy",keyPath:"taxonomy"},{name:"user",keyPath:"user"},{name:"date",keyPath:"modified"},{name:"title",keyPath:"title"}],filters:this.filters,TTL:216e5,showLoading:!0,required:"content"});this.store=e.feed,this.store.subscribe(((e,t)=>{var i;"data-loaded"===e&&(this.renderItems(),this.ui.buttons.loadMore.hidden=!0,this.store.lastResponse&&this.store.lastResponse?.has_more&&(this.ui.buttons.loadMore.hidden=null===(i=!this.store.lastResponse?.has_more)||void 0===i||i))}))}isFirstPage(){return 1===this.store.filters.page}renderItems(){let e=this.store.getFiltered();if(this.isFirstPage()&&window.removeChildren(this.ui.grid),0===e.length)this.showEmptyState(),this.a11y.announceItems(0,this.isFirstPage());else{const t=document.createDocumentFragment(),i=s=>{const r=Math.min(s+10,e.length);for(let i=s;i<r;i++){const s=e[i],r=this.createItemElement(s);t.append(r)}var o;r<e.length?requestAnimationFrame((()=>i(r))):(this.removePlaceholders(),this.ui.grid.append(t),this.config.gallery&&this.gallery.buildGalleryItems(".item img"),this.a11y.makeNavigable(this.ui.grid.querySelectorAll(".item:not([data-keyboard-nav])")),this.a11y.announceItems(e.length,!this.isFirstPage(),null!==(o=this.store.lastResponse?.has_more)&&void 0!==o&&o))};i(0)}this.updateFilterControls()}showEmptyState(){window.removeChildren(this.ui.grid);let e=window.getTemplate("emptyState");e&&this.ui.grid.append(e)}createItemElement(e){let t=window.getTemplate(`feedItem${window.uppercaseFirst(e.content)}`);const i=Object.hasOwn(t.dataset,"timeline");for(let[s,r]of Object.entries(e.fields)){if(i&&["timeline","number"].includes(s))continue;let o=t.querySelector(`[data-field="${s}"]`);o&&(""!==r?this.isImageField(e,r)?this.formatImageField(o,r,e):this.isTaxonomyField(e,s)?this.formatTaxonomyField(o,e,s,r):this.isTimeField(o)?this.formatTimeField(o,r):this.formatField(o,r):o.remove())}let s=t.querySelector("a");var r;return s&&""!==e.url&&([s.href,s.title]=[e.url,`View ${null!==(r=e.fields.post_title)&&void 0!==r?r:"Item"}`]),i&&this.addTimelineElements(e,t),t}splitIDs(e){return String(e).split(",").map((e=>parseInt(e.trim()))).filter((e=>e))}isImageField(e,t){return!(!Object.hasOwn(e,"images")||0===Object.keys(e.images).length)&&this.splitIDs(t).some((t=>Object.keys(e.images).map((e=>parseInt(e))).includes(parseInt(t))))}formatImageFields(e,t,i){let s=this.splitIDs(t);if(0!==s.length)if(s.length>1){let t=e.querySelector("img");if(!t)return;s.forEach((s=>{let r=t.cloneNode(!0);this.formatImageField(r,s,i),e.append(r)})),t.remove()}else{if("IMG"!==e.tagName&&!(e=e.querySelector("img")))return;this.formatImageField(e,s[0],i)}}formatImageField(e,t,i){var s;let r=null!==(s=i.images[t])&&void 0!==s&&s;r&&([e.src,e.srcset,e.alt]=[r.tiny,`${r.tiny} 50w, ${r.small} 300w, ${r.medium} 1024w`,r["image-alt-text"]])}isTaxonomyField(e,t){return!(!Object.hasOwn(e,"taxonomies")||0===Object.keys(e.taxonomies).length)&&Object.keys(e.taxonomies).includes(t)}formatTaxonomyField(e,t,i,s){if("UL"!==e.tagName||!e.querySelector("li"))return;let r=this.splitIDs(s);0===r.length&&e.remove();let o=e.querySelector("li");for(let s of r){var a;let r=null!==(a=t.taxonomies[i][s])&&void 0!==a&&a;if(!r)continue;let n=o.cloneNode(!0),l=n.querySelector("a");l&&([l.href,l.title,l.textContent]=[r.url,`See more ${r.title}`,r.title],e.append(n))}o.remove()}isTimeField(e){return"TIME"===e.tagName||null!==e.querySelector("time")}formatTimeField(e,t){("TIME"===e.tagName||(e=e.querySelector("time")))&&(e.setAttribute("datetime",t),e.textContent=window.formatTimeAgo(t,"F Y"))}formatField(e,t){e.textContent=t}addTimelineElements(e,t){let[i,s,r,o]=[t.querySelector("span.after-text"),t.querySelector('[data-field="number"] b'),t.querySelector('[data-field="started"] time'),t.querySelector('[data-field="updated"] time')];i&&(i.textContent=`After ${e.fields.number} Tx`),s&&(s.textContent=e.fields.number),r&&this.formatTimeField(r,e.fields.timeline[0].post_date),o&&this.formatTimeField(o,e.fields.timeline[e.fields.timeline.length-1].post_date)}removePlaceholders(){const e=this.ui.grid.querySelectorAll(".placeholder");e.length>0&&e.forEach((e=>e.remove()))}}document.addEventListener("DOMContentLoaded",(async function(){window.auth.subscribe((t=>{"auth-loaded"===t&&(window.feedBlock=new e)}))}))})();
\ No newline at end of file
diff --git a/checks.php b/checks.php
index 793b586..3c6ee74 100644
--- a/checks.php
+++ b/checks.php
@@ -1,5 +1,6 @@
 <?php
 
+use JVBase\managers\CacheManager;
 use JVBase\utility\Features;
 
 if (!defined('ABSPATH')) {
@@ -168,9 +169,7 @@
 
 function jvbUserIsVerified():bool
 {
-    return (Features::forMembership()->has('member_verified')) ?
-        current_user_can('skip_moderation') :
-        true;
+    return !(Features::forMembership()->has('member_verified')) || current_user_can('skip_moderation');
 }
 
 function jvbUserTypes():array
@@ -262,7 +261,7 @@
 
 function jvbTermHasPosts(int $termID, string $taxonomy):bool
 {
-	$cache = new \JVBase\managers\CacheManager('termCheck', 60*30);
+	$cache = CacheManager::for('terms', 30*60)->connectTo('taxonomy');
 	$key = $termID.$taxonomy;
 	$cached = $cache->get($key);
 	if ($cached) {
diff --git a/inc/blocks/FeedBlock.php b/inc/blocks/FeedBlock.php
index 8c630dd..71f30c9 100644
--- a/inc/blocks/FeedBlock.php
+++ b/inc/blocks/FeedBlock.php
@@ -292,8 +292,8 @@
 						<div class="selected-items-section">
 							<div class="selected-items row"></div>
 							<div class="filter-actions row">
-								<?= jvbRenderToggleTextField('match', 'Match', 'Filters', 'ALL', 'ANY', false, ['filter' => 'match']) ?>
-								<button type="button" class="clear-filters row">
+								<?= str_replace('class="toggle-text"', 'class="toggle-text" hidden', jvbRenderToggleTextField('match', 'Match', 'Filters', 'ALL', 'ANY', false, ['filter' => 'match'])) ?>
+								<button type="button" class="clear-filters row" hidden>
 									<?= jvbIcon('x') ?>
 									Clear All Filters
 								</button>
@@ -391,7 +391,7 @@
 			}
 		}
 
-
+		echo '<template class="feedTerm"><button class="remove-term">'.jvbIcon(jvbDefaultIcon()).'<span></span>'.jvbIcon('x').'</button></template>';
 		echo '<template class="emptyState">'.apply_filters('jvbFeedEmptyState', '<div class="empty-state">
                 <h3>'.jvbIcon($this->getIcon()).'NOTHING HERE'.jvbIcon($this->getIcon()).'</h3>
                 <p>Try tweaking those filters a bit.</p>
diff --git a/inc/forms/TaxonomySelector.php b/inc/forms/TaxonomySelector.php
index 8156ebb..eccabc2 100644
--- a/inc/forms/TaxonomySelector.php
+++ b/inc/forms/TaxonomySelector.php
@@ -35,7 +35,6 @@
 
 		$this->title = JVB_TAXONOMY[$this->name]['plural'];
 		$this->base = $config['base']??'';
-
 		$this->config = wp_parse_args($config, [
 			'types'		=> false, // for feed block implementation
 			'max'		=> 0,      // 0 = unlimited
@@ -99,11 +98,8 @@
 					<h3 id="modal-title">Select Taxonomy</h3>
 				</header>
 
-				<div class="selected-items-section">
-					<div class="selected-items row" role="region" aria-label="Selected items">
-						<!-- Selected items will be populated here -->
-					</div>
-				</div>
+
+				<div class="selected-items row" role="region" aria-label="Selected items"></div>
 
 				<div class="items-wrap">
 					<!-- Common/Favorite terms section -->
@@ -127,10 +123,10 @@
 						<!-- Terms will be populated here -->
 					</ul>
 
-					<!-- Loading indicator -->
-					<p class="loading" hidden aria-live="polite">
-						<span>loading items</span>
+					<p class="message" hidden aria-live="polite">
+						{ <span>loading items</span> }
 					</p>
+					<button class="submit-term" hidden data-ignore><strong>Create: </strong> "<span></span>"</button>
 
 					<!-- Infinite scroll sentinel -->
 					<div class="scroll-sentinel" aria-hidden="true"></div>
@@ -139,7 +135,7 @@
 				<!-- Search section -->
 				<div class="search-wrapper">
 					<div class="search-bar">
-						<?= jvbSearch('Search terms') ?>
+						<?= jvbSearch('Search terms', 'search-terms') ?>
 					</div>
 				</div>
 
@@ -159,14 +155,8 @@
 									<option value="0">None (Top Level)</option>
 								</select>
 							</div>
-
-							<button type="button" class="submit-term">Add Term</button>
 						</form>
-						<div class="term-suggestions" hidden><h4></h4><ul class="term-suggestion-list"></ul></div>
-						<div class="loading-message create-term" hidden>
-							<span id="typed-text"></span>
-							<span class="cursor">|</span>
-						</div>
+
 					</div>
 				</details>
 				<?= jvbModalActions(); ?>
@@ -175,18 +165,15 @@
 		<template class="loadingItems">
 			<p>{ <span>loading items</span> }</p>
 		</template>
-		<template class="autocompleteButton">
-			<button class="autocomplete submit-term" type="button"><strong>Create: </strong><span></span></button>
-		</template>
 		<template class="autocompleteItem">
-			<button class="autocomplete item" type="button" data-autocomplete-select></button>
+			<li class="autocomplete item btn"></li>
 		</template>
 		<template class="noTermResults">
 			<p>{ <span>nothing found</span> }</p>
 		</template>
 		<template class="termListItem">
 			<li>
-				<input type ="checkbox">
+				<input type="checkbox">
 				<label>
 					<span class="term-name"></span>
 				</label>
@@ -200,7 +187,7 @@
 		<template class="selectedTerm">
 			<div class="selected-item row">
 				<span class="item-name"></span>
-				<button type="button" class="remove-item row"><?=jvbIcon('x')?></button>
+				<button type="button" class="remove-term row"><?=jvbIcon('x')?></button>
 			</div>
 		</template>
 		<template class="termBreadcrumb">
@@ -252,19 +239,28 @@
 				</button>
 				<?php if ($hasAutocomplete !== '') { ?>
 					<input type="text" id="<?= $this->base ?><?= esc_attr($this->config['name']) ?>-autocomplete" autocomplete="off" data-ignore data-autocomplete>
-					<ul class="search-results" hidden>
-					</ul>
+					<div class="auto-wrapper" hidden>
+						<ul class="search-results">
+						</ul>
+						<p class="message" hidden aria-live="polite">
+							{ <span>loading items</span> }
+						</p>
+						<button class="submit-term" hidden data-ignore><strong>Create: </strong> "<span></span>"</button>
+					</div>
+
 				<?php } ?>
 			</div>
-
-			<div class="selected-items row" role="region" aria-label="Selected <?= esc_attr($this->plural) ?>">
-				<?php if (!empty($selected)): ?>
-					<?php foreach ($selected as $termId): ?>
-						<?php $this->renderSelectedTerm($termId); ?>
-					<?php endforeach; ?>
-				<?php endif; ?>
-			</div>
-
+			<?php
+			$selectedItems = '';
+			if (!empty($selected)):
+				ob_start();
+				foreach ($selected as $termId):
+					$this->renderSelectedTerm($termId);
+				endforeach;
+				$selectedItems = ob_get_clean();
+			endif;
+			?>
+			<div class="selected-items row" role="region" aria-label="Selected <?= esc_attr($this->plural) ?>"><?=$selectedItems?></div>
 			<?= $extra ?>
 		</div>
 		<?php
@@ -273,7 +269,16 @@
 
 	protected function renderTaxonomyToggle(array $selected = [], string $extra = ''): string
 	{
-		return '<button type="button" data-filter="taxonomy" data-taxonomy="'.$this->name.'" title="Filter by '.$this->singular.'">'.jvbIcon($this->config['icon']).'<span class="label">'.$this->singular.'</span></button>';
+		return sprintf(
+			'<button type="button" data-icon="%s" data-filter="taxonomy" data-taxonomy="%s" data-type="selector" data-single="%s" data-plural="%s" title="Filter by %s">%s<span class="label">%s</span></button>',
+			JVB_TAXONOMY[$this->name]['icon'],
+			$this->name,
+			$this->singular,
+			$this->plural,
+			$this->singular,
+			jvbIcon($this->config['icon']),
+			$this->singular
+		);
 	}
 
 	/**
@@ -335,7 +340,7 @@
 		<div class="selected-item row" data-id="<?= esc_attr($termId) ?>">
 			<span><?= esc_html($termPath) ?></span>
 			<button type="button"
-					class="remove-item row"
+					class="remove-term row"
 					aria-label="Remove <?= esc_attr($term->name) ?>">
 				<?= jvbIcon('x') ?>
 			</button>
diff --git a/inc/helpers/ui.php b/inc/helpers/ui.php
index bbd289a..5b0a616 100644
--- a/inc/helpers/ui.php
+++ b/inc/helpers/ui.php
@@ -17,7 +17,7 @@
     }
 
     ?>
-    <aside id="queue" class="left col start btw main" aria-expanded="false" hidden>
+    <aside id="queue" class="left col start btw main" aria-expanded="false" >
         <div class="status-actions row start nowrap">
 			<div class="refresh row btw">
                 <span class="countdown row" title="Will refresh again...">5</span>
@@ -46,7 +46,8 @@
 				foreach($filters as $filter => $title) {
 					$active = ($i === 0) ? ' active': '';
 					?>
-					<button class="filter<?=$active?>" data-filter="<?=$filter?>" data-count="0"><span class="count row"></span><?=$title?></button>
+					<input type="radio" id="qfilter-<?=$filter?>" name="qfilter" class="btn filter<?=$active?>" data-filter="<?=$filter?>">
+					<label for="qfilter-<?=$filter?>" data-count="0"><span class="count row"></span><?=$title?></label>
 					<?php
 					$i++;
 				}
@@ -61,7 +62,7 @@
 			<button class="retry-all">Retry Failed</button>
 		</div>
     </aside>
-	<button class="qtoggle row" title="Show Queue" aria-controls="queue" hidden>
+	<button class="qtoggle row" title="Show Queue" aria-controls="queue" >
 		<?= jvbIcon('floppy-disk') ?>
 		<span class="screen-reader-text"></span>
 		<span class="indicator"></span>
@@ -71,18 +72,22 @@
 		<div class="item">
 			<div class="header row btw">
 				<span class="type"></span>
-				<span class="status row"><span class="screen-reader-text"></span></span>
+				<span class="status row"><?= jvbIcon('arrows-clockwise') ?><span class="screen-reader-text"></span></span>
 			</div>
-			<?php jvbRenderProgressBar() ?>
+			<?php jvbRenderProgressBar('',false,false) ?>
 			<div class="info">
 				<div class="details"></div>
 				<div class="time row start">
 					<?= jvbIcon('clock') ?>
-					<span class="started">Started: <span class="time"></span>
-					<span class="completed"></span>
+					<span class="started">Started: <time></time></span>
+					<span class="completed" hidden><span>Completed: </span><time></time></span>
 				</div>
 			</div>
 			<div class="actions row end">
+				<button class="retry" data-action="retry"><span>Retry</span><?= jvbIcon('arrows-clockwise')?></button>
+				<button class="cancel" data-action="cancel"><span>Cancel</span><?= jvbIcon('x-square')?></button>
+				<button class="dismiss" data-action="dismiss"><span>Dismiss</span><?= jvbIcon('eye-closed')?></button>
+
 			</div>
 		</div>
 	</template>
@@ -205,19 +210,26 @@
  * Outputs the search bar (likely don't need anymore)
  * @return string
  */
-function jvbSearch(string $placeholder = 'Search...'):string
+function jvbSearch(string $placeholder = 'Search...', string $id = 'search'):string
 {
-    return '<div class="search-container row start nowrap">
-  <input type="search" id="search" placeholder="'.$placeholder.'">
-  <button
-    title="Clear Search"
-    type="button"
-    class="clear-search"
-    aria-label="Clear search"
-    onclick="this.previousElementSibling.value = \'\'; this.previousElementSibling.focus();"
-  >'.jvbIcon('x', ['title'=> 'Clear Search']).'</button>
-  <button type="button" title="Search" class="toggle search" aria-label="Toggles search input visually" onclick="this.parentNode.classList.toggle(\'open\');this.previousElementSibling.previousElementSibling.focus();">'.jvbIcon('magnifying-glass').'</button>
-</div>';
+	$id = sanitize_title($id);
+	return sprintf(
+		'<div class="search-container row start nowrap">
+		  <input type="search" id="%s" placeholder="%s">
+		  <button
+			title="Clear Search"
+			type="button"
+			class="clear-search"
+			aria-label="Clear search"
+			onclick="this.previousElementSibling.value = \'\'; this.previousElementSibling.focus();"
+		  >%s</button>
+		  <button type="button" title="Search" class="toggle search" aria-label="Toggles search input visually" onclick="this.parentNode.classList.toggle(\'open\');this.previousElementSibling.previousElementSibling.focus();">%s</button>
+		</div>',
+		$id,
+		$placeholder,
+		jvbIcon('x', ['title'=> 'Clear Search']),
+		jvbIcon('magnifying-glass')
+	);
 }
 
 
@@ -424,7 +436,7 @@
 	return $out;
 }
 
-function jvbRenderProgressBar(string $inside ='', $top = false)
+function jvbRenderProgressBar(string $inside ='', $top = false, $icon = true)
 {
 	$top = $top ? ' abs top' : '';
 	?>
@@ -433,7 +445,9 @@
 			<div class="fill"></div>
 		</div>
 		<div class="row btw">
-			<i class="icon"></i>
+			<?php if ($icon) { ?>
+				<i class="icon"></i>
+			<?php } ?>
 			<div class="details">
 				<?=$inside?>
 			</div>
diff --git a/inc/managers/CRUDManager.php b/inc/managers/CRUDManager.php
index b129c15..d425070 100644
--- a/inc/managers/CRUDManager.php
+++ b/inc/managers/CRUDManager.php
@@ -40,6 +40,7 @@
 		$this->config = $this->constant[$content];
 		$this->content = $content;
 		$this->cache = CacheManager::for($content);
+
 		// Create and configure skeleton
 		$this->skeleton = new CRUDSkeleton();
 		$this->configure();
@@ -60,7 +61,7 @@
 		// Initialize meta
 		$this->skeleton->initMeta($this->type, $this->content);
 
-
+		$this->skeleton->addSearch();
 
 		// Timeline if applicable
 		if (Features::forContent($this->content)->has('is_timeline')) {
diff --git a/inc/managers/OperationQueue.php b/inc/managers/OperationQueue.php
index 182ca97..040447d 100644
--- a/inc/managers/OperationQueue.php
+++ b/inc/managers/OperationQueue.php
@@ -136,7 +136,6 @@
     {
         switch ($action) {
             case 'unlock-operation-queue':
-				error_log('Unlocking Queue from admin action');
                 $this->unlockQueue();
                 return new WP_REST_Response([
                     'success'   => true,
@@ -203,7 +202,6 @@
 			return;
 		}
 
-		error_log('[queue] Checking queue...');
 
 		// Peek at what operations we might process
 		$batch_size = $this->getAdaptiveBatchSize();
@@ -433,12 +431,7 @@
 	{
 		try {
 			$table = $this->wpdb->prefix . $this->table;
-			error_log('QUEUING OPERATION: '.print_r([
-				'type' => $type,
-					'user_id' => $user_id,
-					'data' => $data,
-					'options' => $options,
-				],true));
+
 			// Extract options
 			$priority = (array_key_exists('priority', $options) && in_array($options['priority'], ['low', 'normal', 'high'])) ? $options['priority'] : 'normal';
 			$delay = (array_key_exists('delay', $options)) ? (int) $options['delay'] : 0;
@@ -469,10 +462,8 @@
 			// Generate operation ID
 			$operation_id = $this->checkOperationId($operation_id, $type, $merge, $user_id);
 
-			error_log('Checked OperationId: '.print_r($operation_id, true));
 			// Check for existing operation
 			$existing = $this->getOperation($operation_id);
-			error_log('Existing: '.print_r($existing, true));
 
 			$dependencies = $options['depends_on'] ?? [];
 			if (is_string($dependencies)) {
@@ -491,10 +482,9 @@
 			}
 
 			if ($existing) {
-				error_log('[queue]:queueOperation - Already Existing operation... updating');
 
 				if ($merge !== 'append' && ($existing->status === 'pending' || $existing->status === 'scheduled')) {
-					error_log('Not appending operation, checking for merge');
+
 					if ($merge === 'merge') {
 						$existing_data = json_decode($existing->request_data ?? '{}', true);
 						$data = $this->deepMerge($existing_data, $data);
@@ -542,14 +532,12 @@
 					}
 
 				} else if ($merge === 'append') {
-					error_log('Append operation, creating a new one');
 					$operation_id = $operation_id . '_' . time() . '_' . substr(uniqid(), -4);
 					$existing = null;
 				}
 			}
 
 			if (!$existing) {
-				error_log('Inserting new operation into table');
 				// Prepare metadata with chunk config
 				$metadata = $chunk_config ? ['chunk_config' => $chunk_config] : [];
 
@@ -592,7 +580,6 @@
 			];
 
 		} catch (Exception $e) {
-			error_log("Error queueing operation: " . $e->getMessage());
 			JVB()->error()->log('queue', $e->getMessage(), $data, 'high');
 			return new WP_Error('queue_failed', $e->getMessage());
 		}
@@ -607,10 +594,8 @@
 		$merged = $existing;
 
 		if (!$this->isAssociativeArray($existing) && !$this->isAssociativeArray($new)) {
-			error_log('It is an associative array!');
 			return array_merge($existing, $new);
 		}
-		error_log('Not an associative array... moving on!');
 		foreach ($new as $key => $newValue) {
 			if (!array_key_exists($key, $existing)) {
 				$merged[$key] = $newValue;
@@ -722,19 +707,16 @@
 					'limit' => 1
 				]);
 			if ($existing) {
-				error_log('Found existing User operations: '.print_r($existing, true));
 				$operation_id = $existing[0]->id;
 			}
 		}
 
 		if (!$operation_id) {
 			$operation_id = uniqid('op_');
-			error_log('Generated operation ID: '.print_r($operation_id, true));
 		}
 
 		if (!str_starts_with($operation_id, 'u')) {
 			$operation_id = 'u' . $user_id . '_' . $operation_id;
-			error_log('Added user ID to operation ID: '.print_r($operation_id, true));
 		}
 
 		return $operation_id;
@@ -745,7 +727,6 @@
 	{
 		// Only add if not already scheduled AND if operation is high priority or small
 		if (!has_action('shutdown', [$this, 'processQueueOnShutdown'])) {
-			error_log('Adding shutdown call');
 			add_action('shutdown', [$this, 'processQueueOnShutdown'], 100);
 		}
 	}
@@ -910,7 +891,6 @@
 	protected function canProcessOperation(object $operation): bool
 	{
 		if ($operation->retries >= $this->max_attempts) {
-			error_log("Operation {$operation->id} exceeded retry limit: {$operation->retries} >= {$this->max_attempts}");
 			$this->markAsPermanentlyFailed($operation->id, 'Exceeded maximum retry attempts');
 			return false;
 		}
@@ -943,7 +923,6 @@
 
 		if ($result) {
 			$this->invalidateQueueCache('status');
-			error_log("Marked operation {$operation_id} as permanently failed: {$final_error_message}");
 		}
 	}
 
@@ -1143,14 +1122,6 @@
 			['%s']
 		);
 
-		// Log retry schedule
-		error_log(sprintf(
-			"Operation %s scheduled for retry #%d at %s (delay: %ds)",
-			$operation_id,
-			$attempt,
-			$scheduled_at,
-			$delay
-		));
 	}
 
     /**
@@ -1277,8 +1248,6 @@
 				];
 			}
 
-			error_log('Filtered Result: '.print_r($filterResult, true));
-
 			$newCount = $progress_count + $chunk['progress'];
 
 			if ($filterResult['success']) {
@@ -1292,12 +1261,7 @@
 					$filterResult['result'] = [$filterResult['result']];
 				}
 				// Store the result data
-				error_log('Merging Old Result: '. print_r($oldResult, true));
-				error_log('With Newer Result: '. print_r($filterResult['result'], true));
 				$resultToStore = $this->deepMerge($oldResult, $filterResult['result']);
-
-				error_log('Merged Result: '.print_r($resultToStore, true));
-
 				$resultToStore['processed_at'] = current_time('mysql');
 
 				// Check if operation is complete
@@ -1318,10 +1282,6 @@
 						['%s']
 					);
 
-
-
-
-					error_log('Completion result: '.print_r($result, true));
 					// Now do post-completion tasks
 					$this->invalidateQueueCache('status');
 					$this->updateLastModified($operation->user_id);
@@ -2073,8 +2033,6 @@
         ", $this->max_attempts));
 
 		if (!empty($stuck_operations)) {
-			error_log("Found " . count($stuck_operations) . " stuck operations to clean up");
-
 			foreach ($stuck_operations as $operation) {
 				$this->markAsPermanentlyFailed(
 					$operation->id,
@@ -2091,8 +2049,6 @@
         ", date('Y-m-d H:i:s', strtotime('-1 hour'))));
 
 		if (!empty($long_processing)) {
-			error_log("Found " . count($long_processing) . " long-running operations to reset");
-
 			foreach ($long_processing as $operation) {
 				$this->wpdb->update($table, [
 					'status' => 'pending',
diff --git a/inc/meta/MetaForm.php b/inc/meta/MetaForm.php
index 51959aa..afaf791 100644
--- a/inc/meta/MetaForm.php
+++ b/inc/meta/MetaForm.php
@@ -1351,13 +1351,12 @@
 	 * Generic selector field renderer
 	 * Handles both taxonomy and post selectors with consistent structure
 	 */
-	private function renderSelectorField(string $name, mixed $value, array $field, string $type): void
+	public function renderSelectorField(string $name, mixed $value, array $field, string $type): void
 	{
 		$conditional = $this->handleConditionalField($field);
 		$validationAttrs = $this->buildValidationAttributes($field);
 		$describedBy = (!empty($field['description'])) ? ' aria-describedby="' . $name . '-help"' : '';
 
-		$isSimple = (array_key_exists('mode', $field) && $field['mode']==='simple');
 		// Parse selected values
 		$value = (is_array($value)) ? array_filter(array_map('absint', $value)): $value;
 		$selected = ($value === '') ? [] : (is_array($value) ? $value : explode(',', $value));
diff --git a/inc/rest/routes/QueueRoutes.php b/inc/rest/routes/QueueRoutes.php
index 8ea77cd..21bce8f 100644
--- a/inc/rest/routes/QueueRoutes.php
+++ b/inc/rest/routes/QueueRoutes.php
@@ -372,7 +372,7 @@
 					case 'cancel':
 						// Can only cancel pending/queued operations
 						if (!in_array($operation_status, ['pending', 'queued'])) {
-							$errors[] = "Operation {$operation_id} cannot be cancelled (status: {$operation_status})";
+//							$errors[] = "Operation {$operation_id} cannot be cancelled (status: {$operation_status})";
 							continue 2;
 						}
 
diff --git a/inc/rest/routes/TermRoutes.php b/inc/rest/routes/TermRoutes.php
index fe5de06..ec029c8 100644
--- a/inc/rest/routes/TermRoutes.php
+++ b/inc/rest/routes/TermRoutes.php
@@ -24,7 +24,7 @@
         parent::__construct();
 //		$this->cache->invalidateGroup('terms');
         $this->per_page = 20;
-		$this->cache->clear();
+
         add_action('edited_term', [$this, 'deleteTermPath']);
         add_action('wp_login', [$this, 'clearUserTaxonomyCache'], 10, 2);
     }
@@ -182,8 +182,7 @@
     public function handleTermSelectionRequest(WP_REST_Request $request):WP_REST_Response
     {
 		$data = $request->get_params();
-		$taxonomy = jvbCheckBase($data['taxonomy'])??'';
-
+		$taxonomy = sanitize_text_field($data['taxonomy'])??'';
 		// Check HTTP cache headers
 		$cache_check = $this->checkHeaders($request, $taxonomy);
 		if ($cache_check) {
@@ -195,6 +194,7 @@
 		if (str_contains($taxonomy, ',')) {
 			return $this->handleBatchTermRequest($taxonomy, $data, $request);
 		}
+		$taxonomy = jvbCheckBase($taxonomy);
 
 		if (array_key_exists('termIDs', $data)) {
 			$args = [
diff --git a/inc/rest/routes/UploadRoutes.php b/inc/rest/routes/UploadRoutes.php
index 6052ab5..614e74c 100644
--- a/inc/rest/routes/UploadRoutes.php
+++ b/inc/rest/routes/UploadRoutes.php
@@ -277,7 +277,6 @@
 		unset($context['upload_ids']);
 
 		$config = $this->getFieldConfig($args);
-		error_log('secureFiles: '.print_r($files, true));
 		$file_array = $files['files'] ?? $files;
 		$tmp_names = isset($file_array['tmp_name'][0]) && is_array($file_array['tmp_name'][0])
 			? $file_array['tmp_name'][0]
@@ -1092,9 +1091,7 @@
 			$args = $this->buildUploadArgs($request);
 			$data = $request->get_params();
 
-			error_log('get_file_params: '.print_r($files, true));
 			global $_FILES;
-			error_log('Global Files: '.print_r($_FILES, true));
 
 			if (!$args['content'] || !$args['user'] || !$args['posts']) {
 
@@ -1226,7 +1223,6 @@
 			$created_posts = [];
 			$used_upload_ids = [];
 
-			error_log('Processing Group Data: '.print_r($data, true));
 			// Create posts from groups
 			foreach ($data['posts'] as $index => $post) {
 				$post_title = !empty($post['fields']['post_title'])
@@ -1251,7 +1247,9 @@
 					$created_posts[] = $new_post_id;
 
 					// Get featured image upload_id
-					$featured_upload_id = (int)$post['fields']['featured'] ?? null;
+
+
+					$featured_upload_id = array_key_exists('featured', $post['fields']) ? (int)$post['fields']['featured'] : null;
 					$featured_attachment_id = null;
 					$gallery_attachment_ids = [];
 
@@ -1279,7 +1277,7 @@
 						set_post_thumbnail($new_post_id, (int)$gallery_attachment_ids[0]);
 						array_shift($gallery_attachment_ids);
 					}
-					error_log('Remaining Gallery images: '.print_r($gallery_attachment_ids, true));
+
 					// Set gallery images
 					if (!empty($gallery_attachment_ids)) {
 						$meta = new MetaManager($new_post_id, 'post');
@@ -1330,9 +1328,9 @@
 			$used_upload_ids = [];
 
 			$content = jvbCheckBase($data['content']);
-			error_log('[processTimelineUploads]Got content: '.print_r($content, true));
+
 			$config = Features::getConfig($content);
-			error_log('[processTimelineUploads]Got config: '.print_r($config, true));
+
 			$defaultTitle = 'New '.$config['singular']. ' ';
 			foreach ($data['posts'] as $index=> $post) {
 				$title = !empty($post['fields']['post_title'])
diff --git a/inc/ui/CRUDSkeleton.php b/inc/ui/CRUDSkeleton.php
index 7347c63..1268132 100644
--- a/inc/ui/CRUDSkeleton.php
+++ b/inc/ui/CRUDSkeleton.php
@@ -230,6 +230,20 @@
 		return $this;
 	}
 
+	protected function taxConfig(string $taxonomy, string $label = ''):array
+	{
+		$isVerified = jvbUserIsVerified();
+		$label = ($label === '') ? JVB_TAXONOMY[$taxonomy]['plural'] : $label;
+		return [
+			'type'		=> 'taxonomy',
+			'label'		=> $label,
+			'taxonomy'	=> $taxonomy,
+			'createNew' => $isVerified,
+			'multiple'	=> true,
+			'mode'		=> 'append',
+		];
+	}
+
 	public function addSearch():self
 	{
 		$this->hasSearch = true;
@@ -1585,7 +1599,6 @@
 					$temp = array_filter($fields, function ($field) {
 						return in_array($field, $this->timelineUniqueFields);
 					}, ARRAY_FILTER_USE_KEY);
-
 					$config = [
 						'type'		=> 'gallery',
 						'subtype'	=> 'timeline',
@@ -1596,6 +1609,9 @@
 					$content = '';
 					foreach ($fields as $slug=> $field) {
 						if (in_array($slug, $this->timelineSharedFields)) {
+							if (in_array($field['type'], ['taxonomy', 'selector'])) {
+								$field = array_merge($field, $this->taxConfig($field['taxonomy'], $field['label']));
+							}
 							$content .= $this->form->render($slug, null, $field, false, true);
 						}
 					}
@@ -1611,6 +1627,9 @@
 						$section = (array_key_exists('section', $config)) ? $config['section'] : 'basic';
 						$tabs[$section]['content'] .= $this->meta->render('form', $n, $config, false, true);
 					} else {
+						if (in_array($config['type'], ['taxonomy', 'selector'])) {
+							$config = array_merge($config, $this->taxConfig($config['taxonomy'], $config['label']));
+						}
 						$this->meta->render('form', $n, $config);
 					}
 				}
@@ -1656,17 +1675,11 @@
 					<div class="taxonomies">
 						<?php
 						foreach ($this->taxonomies as $taxonomy => $config) {
-							$this->meta->render(
-								'form',
+							$this->form->renderSelectorField(
 								'bulk-edit-'.$taxonomy,
-								[
-									'type'		=> 'taxonomy',
-									'label'		=> $config['label'],
-									'taxonomy'	=> $taxonomy,
-									'createNew'	=> jvbUserIsVerified(),
-									'multiple'	=> true,
-									'mode'		=> 'append'
-								]
+								'',
+								$this->taxConfig($taxonomy, $config['label']),
+								'taxonomy'
 							);
 						}
 						?>
diff --git a/inc/ui/Navigation.php b/inc/ui/Navigation.php
index 16a7e66..2fc120d 100644
--- a/inc/ui/Navigation.php
+++ b/inc/ui/Navigation.php
@@ -23,7 +23,7 @@
  */
 class Navigation {
 	private string $id;
-	private array $items = [];
+	public array $items = [];
 	private array $classes = [];
 	protected array $defaultMenuClasses = [];
 	private bool $isNav = true;
@@ -230,6 +230,7 @@
 				$menuItem->url($item['url']);
 			}
 
+
 			if (!empty($item['submenu'])) {
 				$submenu = $menuItem->submenu();
 				$submenu->populateFromArray($item['submenu']);
@@ -375,6 +376,9 @@
 	 * @return string
 	 */
 	public function render(): string {
+		if (!$this->url && (!$this->submenu || empty($this->submenu->items))) {
+			return '';
+		}
 		$classes = $this->classes;
 		if ($this->submenu) {
 			$classes[] = 'has-submenu';
diff --git a/src/feed/style.scss b/src/feed/style.scss
index b126889..937092f 100644
--- a/src/feed/style.scss
+++ b/src/feed/style.scss
@@ -647,6 +647,11 @@
 		padding: 1rem 0;
 		max-width:var(--wide);
 		margin: 0 auto;
+
+		.remove-term.remove-term {
+			width: max-content;
+			height: max-content
+		}
 	}
 	.filter-group {
 		position: relative;
@@ -752,6 +757,8 @@
 
 	img {
 		object-fit: cover;
+		width: 100%;
+		height: 100%;
 		//opacity: .7;
 		//filter: grayscale(.5) sepia(.3);
 		&:hover {
@@ -824,3 +831,103 @@
 		grid-template-columns: repeat(2, 1fr);
 	}
 }
+
+.items-wrap [type=radio],
+.items-wrap [type=checkbox] {
+	position: absolute;
+	opacity: 0;
+	left: -200vw;
+}
+
+.items-wrap [type=radio] + label,
+.items-wrap [type=checkbox] + label {
+	position: relative;
+	cursor: pointer;
+}
+
+.items-wrap [type=radio] + label:hover,
+.items-wrap [type=checkbox] + label:hover {
+	color: var(--action-0);
+}
+
+.items-wrap [type=radio] + label::before,
+.items-wrap [type=checkbox] + label::before,
+.items-wrap [type=radio] + label::after,
+.items-wrap [type=checkbox] + label::after {
+	content: '';
+	position: absolute;
+	top: 50%;
+}
+
+.items-wrap [type=radio] + label::after,
+.items-wrap [type=checkbox] + label::after {
+	left: 5px;
+	transform: translateY(-70%) rotate(45deg);
+	width: 5px;
+	height: 10px;
+	border: solid var(--light-0);
+	border-width: 0 2px 2px 0;
+	display: none;
+}
+
+.items-wrap [type=radio] + label::before,
+.items-wrap [type=checkbox] + label::before {
+	left: 0;
+	transform: translateY(-50%);
+	width: 1rem;
+	height: 1rem;
+	border: 2px solid var(--contrast-200);
+	background-color: var(--base);
+	border-radius: var(--radius);
+}
+
+.items-wrap [type=radio]:hover + label::before,
+.items-wrap [type=checkbox]:hover + label::before {
+	border-color: var(--action-200);
+}
+
+.items-wrap [type=radio]:checked + label::before,
+.items-wrap [type=checkbox]:checked + label::before{
+	background-color: var(--action-0);
+	border-color: var(--action-100);
+}
+
+.items-wrap [type=radio]:checked + label::before {
+	border-radius: 50%;
+}
+
+.items-wrap [type=checkbox]:checked + label::after {
+	display: block;
+	left: 5px;
+	top: 50%;
+	transform: translateY(-70%) rotate(45deg);
+	width: .35rem;
+	height: .66rem;
+	border: solid var(--light-0);
+	border-width: 0 2px 2px 0;
+}
+
+.items-wrap :disabled + label {
+	cursor: not-allowed;
+	background-color: var(--base-50);
+	color: var(--base-200);
+	border-color: var(--base-200);
+}
+
+.items-wrap :disabled + label:hover {
+	background-color: var(--base-50);
+	color: var(--base-200);
+	border-color: var(--base-200);
+}
+
+.items-wrap :disabled + label::before {
+	border-color: var(--base-200);
+}
+
+#jvb-selector .items-wrap [type=radio] + label,
+#jvb-selector .items-wrap [type=checkbox] + label{
+	flex: 1;
+	padding-left: 2rem!important;
+	transform-origin: top center;
+	will-change: transform;
+}
diff --git a/src/feed/view.js b/src/feed/view.js
index 94da05e..8066082 100644
--- a/src/feed/view.js
+++ b/src/feed/view.js
@@ -1,13 +1,11 @@
 class FeedBlock {
 	constructor() {
 		this.container = document.querySelector('section.feed-block');
-		if (!this.container) {
-			return;
-		}
+		if(!this.container) return;
 
 		this.a11y = window.jvbA11y;
-		this.cache = new window.jvbCache('feed');
 		this.error = window.jvbError;
+		this.cache = new window.jvbCache('feed');
 
 		this.config = {
 			source: '',
@@ -17,186 +15,421 @@
 			view: this.cache.get('feedView') || 'grid',
 			... this.container.dataset
 		};
+
+		this.init();
+	}
+	init() {
 		this.initElements();
+		this.initListeners();
 		this.initFilters();
 
-
-		this.loadWhenAble();
-	}
-
-	loadWhenAble() {
 		if ('requestIdleCallback' in window) {
 			requestIdleCallback(() => {
-				this.initTaxonomies();
 				this.initStore();
-				this.initListeners();
+				this.initTaxonomies();
+
+				this.processCachedFilters();
+				this.processURLFilters();
+				this.updateFilterUI();
 				this.initGallery();
 			}, { timeout: 2000 });
 		} else {
 			setTimeout(() => {
-				this.initTaxonomies();
 				this.initStore();
-				this.initListeners();
+				this.initTaxonomies();
+
+				this.processCachedFilters();
+				this.processURLFilters();
+				this.updateFilterUI();
 				this.initGallery();
 			}, 100);
 		}
 	}
 
 	initElements() {
-		this.currentTaxonomies = new Set();			// Allowed Taxonomies, grabbed from active buttons
-		this.taxonomyFilters = {};
-		this.elements = {
+		this.selectors = {
 			filterTrigger: '[data-filter]',
 			filters: {
-				content: '[data-filter="content"]',
-				orderby: '[data-filter="orderby"]',
-				order: '[data-filter="order"]',
-				match: '[data-filter="match"]',
+				actions: 	'.filter-actions .toggle-text',
+				container:	'.filters',
+				content: 	'[data-filter="content"]',
+				orderby: 	'[data-filter="orderby"]',
+				order: 		'[data-filter="order"]',
+				match: 		'[data-filter="match"]',
 				favourites: '[data-filter="favourites"]',
-				taxonomy: '[data-filter^="taxonomy"]'
+				taxonomy: 	'[data-filter^="taxonomy"]',
 			},
-			selectedTax: '.selected-items',
-			clearFilter: 'button.clear-filters',
-			loadMore: 'button.load-more',
-			filterContainer: '.filters',
-			grid: '.item-grid',
+			grid: 		'.item-grid',
+			selected: 	'.selected-items',
+			buttons: {
+				loadMore: 		'button.load-more',
+				remove:			'.remove-term',
+				clearFilters: 	'button.clear-filters'
+			}
 		};
-		this.ui = window.uiFromSelectors(this.elements);
+		this.ui = window.uiFromSelectors(this.selectors, this.container);
 
+		//Add content and taxonomies
+		this.ui.content = this.ui.filters.container.querySelectorAll('[name="content"]');
+		if (this.ui.content.length === 0) this.ui.content = false;
+		this.ui.taxonomies = this.ui.filters.container.querySelectorAll('[data-taxonomy]');
+		if (this.ui.taxonomies.length === 0) this.ui.content = false;
+		this.ui.orderbyWrap = this.ui.filters.container.querySelector('[data-for-order]');
+		if (this.ui.orderbyWrap.length === 0) this.ui.content = false;
+		this.ui.order = this.ui.filters.container.querySelectorAll('[data-filter="order"]');
+		if (this.ui.order.length === 0) this.ui.content = false;
+		this.ui.orderby = this.ui.filters.container.querySelectorAll('[data-filter="orderby"]');
+		if (this.ui.orderby.length === 0) this.ui.content = false;
 
-		this.ui.content = this.ui.filterContainer.querySelectorAll('[name="content"]')??false;
-		this.ui.taxonomies = this.ui.filterContainer.querySelectorAll('[data-taxonomy]');
-		if (this.ui.content && this.ui.content.length > 0) {
-			this.contentTypes = Array.from(
-				this.ui.content
-			).map(content => content.value);
-		} else {
-			this.contentTypes = [this.container.dataset['content']];
-		}
-
-		if (this.ui.taxonomies.length>0) {
-			this.taxonomies = Array.from(
-				this.ui.taxonomies,
-			).map(content => content.dataset.taxonomy);
-		} else {
-			this.taxonomies = [];
-		}
-
-
+		this.contentTypes = (this.ui.content)
+			? Array.from(this.ui.content).map(c => c.value)
+			: [this.container.dataset.content];
+		this.taxonomies = (this.ui.taxonomies?.length > 0)
+			? Array.from(this.ui.taxonomies).map(t => t.dataset.taxonomy)
+			: [];
 	}
 
-	async initTaxonomies() {
-		this.selector = window.jvbSelector;
-		const buttons = document.querySelectorAll('[data-filter="taxonomy"]');
+	initListeners() {
+		this.popStateHandler	= this.handlePopState.bind(this);
+		this.clickHandler		= this.handleClick.bind(this);
+		this.changeHandler		= this.handleChange.bind(this);
 
-		this.selector.isInitializing = true;
-		buttons.forEach((button) => {
-			const taxonomy = button.dataset.taxonomy;
-			this.currentTaxonomies.add(taxonomy);
-
-			this.selector.registerFilterButton(button, {
-				button: button,
-				buttonSelector: '[data-filter="taxonomy"]',
-				selected: this.ui.selectedTax
-			});
-
-			// Add preload listeners
-			this.addTaxonomyPreloadListeners(button, taxonomy);
-		});
-
-		this.selector.isInitializing = false;
-
-		this.selector.subscribe((event, data) => {
-			if (event === 'selected-terms') this.handleTaxonomyChange(data);
-		});
-	}
-
-	addTaxonomyPreloadListeners(button, taxonomy) {
-		const preload = () => {
-			this.selector.preloadTaxonomy(taxonomy);
-		};
-
-		// Desktop hover
-		button.addEventListener('mouseenter', preload, { once: true });
-
-		// Touch/keyboard (fires before click)
-		button.addEventListener('pointerdown', preload, { once: true });
-
-		// Keyboard focus
-		button.addEventListener('focus', preload, { once: true });
-	}
-
-	handleTaxonomyChange(data) {
-		const { terms, taxonomy } = data;
-
-		// Update only the current taxonomy's terms
-		if (terms.size > 0) {
-			this.taxonomyFilters[taxonomy] = Array.from(terms.keys());
-		} else {
-			// Remove taxonomy if no terms selected
-			delete this.taxonomyFilters[taxonomy];
-		}
-
-		// Build filters object with all taxonomies
-		let filters = {
-			page: 1
-		};
-
-		// Add taxonomy filters if any exist
-		if (Object.keys(this.taxonomyFilters).length > 0) {
-			filters.taxonomy = this.taxonomyFilters;
-		}
-
-		this.updateFilter(filters);
-	}
-
-	clearAllTaxonomies() {
-		this.taxonomyFilters = {};
-		window.removeChildren(this.ui.selectedTax);
-
-		this.updateFilter({
-			taxonomy: null,
-			page: 1
-		});
+		window.addEventListener('popstate', this.popStateHandler);
+		document.addEventListener('click', this.clickHandler);
+		document.addEventListener('change', this.changeHandler);
 	}
 
 	initFilters() {
-		//defaults
-		this.filters = {
-			content: 	this.contentTypes[0],
-			orderby: 	'date',
-			order: 		'desc',
-			page: 		1
+		this.allowedFilters = ['content', 'order', 'orderby', 'favourites', 'match'];
+		let defaults = {
+			content:	this.contentTypes[0],
+			orderby:	'date',
+			order:		'desc',
+			page:		1,
 		};
-		if (this.config.context) this.filters.context = this.config.context;
-		if (this.config.source) this.filters.source = this.config.source;
+		if (this.config.context) defaults.context = this.config.context;
+		if (this.config.source) defaults.source = this.config.source;
 
-		//check the cache
-		this.processCachedFilters();
-		//check url
-		this.processURLFilters();
-
-		// Set initial UI state
-		this.syncUIToFilters();
+		this.filters = defaults;
+		this.defaults = {...defaults};
 	}
-	syncUIToFilters() {
-		if (this.ui.filterContainer) {
-			// Check radio buttons
-			Object.entries(this.filters).forEach(([key, value]) => {
-				const input = this.ui.filterContainer.querySelector(`[data-filter="${key}"][value="${value}"]`);
-				if (input) {
-					input.checked = true;
+	updateFilterUI() {
+		if (this.ui.filters.container) {
+			//Get cached inputs
+			let groups = [
+				this.ui.content,
+				this.ui.orderby,
+				this.ui.order
+			];
+
+			groups.forEach(group => {
+				if(group) {
+					for (let input of group) {
+						let [filter, value] = [input.dataset.filter, input.value];
+						if (!Object.hasOwn(this.store.filters, filter)) break;
+						let doit = this.store.filters[filter] === value;
+						if (doit) {
+							input.checked = doit;
+							break;
+						}
+					}
+				}
+			});
+
+			if (Object.hasOwn(this.store.filters, 'taxonomy')) {
+				for (let [taxonomy, terms] of Object.entries(this.store.filters.taxonomy)) {
+					terms.forEach(termId => {
+						termId = parseInt(termId);
+						const term = this.selector.store.get(termId);
+						if (term) {
+							this.createTermElement(termId);
+						}
+					});
+				}
+			}
+		}
+	}
+
+	handlePopState(e) {
+		if (e.state?.filters) {
+			if (this.processURLFilters()) {
+				this.store.setFilters(this.filters);
+				this.a11y.announce('Feed filters updated from browser history');
+			}
+		}
+	}
+
+	handleClick(e) {
+		if (window.targetCheck(e, this.selectors.buttons.loadMore)) {
+			this.nextPage();
+		} else if (window.targetCheck(e, this.selectors.buttons.clearFilters)) {
+			this.clearFilters();
+		}
+		let remove = window.targetCheck(e, this.selectors.buttons.remove);
+		if (remove) {
+			this.removeSelectedTerm(remove);
+		}
+	}
+
+	nextPage() {
+		const nextPage = (this.store.filters.page || 1) + 1;
+		const maxPage = this.store.lastResponse?.pages || nextPage;
+		this.store.setFilters({ page: Math.min(nextPage, maxPage) });
+	}
+
+	handleChange(e) {
+		const target = e.target;
+		if (Object.hasOwn(target.dataset, 'filter')) {
+			if (this.allowedFilters.includes(target.dataset.filter)) {
+				let filters = {};
+				filters[target.dataset.filter] = target.value;
+				this.resetFilters(filters);
+			}
+			switch (target.dataset.filter) {
+				case 'content':
+					this.updateContentFor(target.value);
+					break;
+				case 'orderby':
+					this.updateOrderOptions(target.value);
+					break;
+			}
+		}
+	}
+
+	clearFilters() {
+		this.taxFilters = {};
+		window.removeChildren(this.ui.selected);
+
+		this.taxonomies.forEach(tax => {
+			let fieldId = this.getFieldId(tax);
+			this.selector.selectedTerms.get(fieldId)?.clear();
+		});
+
+		this.store.setFilters({
+			...this.defaults,
+			taxonomy: null
+		});
+
+		this.updateURL();
+		this.saveToCacheFilters();
+	}
+
+	resetFilters(filters) {
+		filters = {
+			...this.store.filters,
+			page: 1,
+			... filters
+		}
+		this.store.setFilters(filters);
+
+		this.updateURL();
+		this.saveToCacheFilters();
+	}
+
+	getFieldId(taxonomy) {
+		return this.selector.getFieldId(Array.from(this.ui.taxonomies).filter(tax => tax.dataset.taxonomy === taxonomy)[0]??null);
+	}
+	removeSelectedTerm(button) {
+		const termId = parseInt(button.dataset.id);
+		const taxonomy = button.dataset.taxonomy;
+
+		if (Object.hasOwn(this.taxFilters, taxonomy)){
+			this.taxFilters[taxonomy] = this.taxFilters[taxonomy]
+				.filter(id => id !== termId);
+			if (this.taxFilters[taxonomy].length === 0) {
+				delete this.taxFilters[taxonomy];
+			}
+		}
+		button.remove();
+
+		// Find the fieldId for this taxonomy
+		const field = this.getFieldId(taxonomy);
+		if (field) {
+			this.selector.activeField = field;
+			// Notify selector to remove from its selectedTerms
+			this.selector.removeSelected(termId, field);
+		}
+
+		this.resetFilters({
+			taxonomy: Object.keys(this.taxFilters).length > 0
+				? this.taxFilters
+				: null
+		});
+	}
+
+	updateContentFor(content) {
+		let checkIt = [
+			this.ui.taxonomies,
+			this.ui.orderby
+		];
+		checkIt.forEach(check => {
+			if (!check) return;
+			check.forEach(button => {
+				const forTypes = button.dataset.for?.split(',')??[];
+				button.hidden = forTypes.length > 0 && !forTypes.includes(content);
+				if (button.hidden && button.checked) {
+					button.checked = false;
+				}
+			});
+		});
+	}
+	updateOrderOptions(order) {
+		if (this.ui.orderbyWrap) {
+			let options = this.ui.orderbyWrap.dataset.forOrder.split(',')??[];
+			this.ui.orderbyWrap.hidden = !options.includes(order);
+		}
+	}
+
+	updateFilterControls() {
+		const isHidden = Object.keys(this.taxFilters).length === 0;
+		if (this.ui.buttons.clearFilters) {
+			this.ui.buttons.clearFilters.hidden = isHidden;
+		}
+		if (this.ui.filters.actions) {
+			this.ui.filters.actions.hidden = isHidden;
+		}
+	}
+
+	async initTaxonomies() {
+		this.taxFilters = {};
+		this.selector = window.jvbSelector;
+		// this.selector.scanExistingFields(this.ui.filters.container);
+		// this.taxonomies.map(tax => this.selector.batchFetch.add(tax));
+		// this.selector.batchFetchTaxonomies();
+		this.selector.subscribe((event, data) => {
+			switch (event) {
+				case 'selected-terms':
+
+					this.handleTaxonomyChange(data);
+					break;
+
+			}
+		});
+	}
+	handleTaxonomyChange(data) {
+		const {terms, taxonomy } = data;
+		if (terms.size === 0) return;
+		this.taxFilters[taxonomy] = Array.from(terms);
+		this.resetFilters({ taxonomy: this.taxFilters });
+
+		terms.forEach(t => {
+			this.createTermElement(t);
+		});
+		this.updateFilterControls();
+	}
+	getTaxonomyIcon(taxonomy) {
+		let iconButton = Array.from(this.ui.taxonomies)
+			.find(t => t.dataset.taxonomy === taxonomy);
+		return iconButton?.dataset.icon.trim() || 'tag';
+	}
+	createTermElement(termId) {
+		const term = this.selector.store.get(termId);
+		if (!term) return;
+		if (this.ui.selected.querySelector(`[data-id="${termId}"]`)) return;
+		let icon = this.getTaxonomyIcon(term.taxonomy);
+		let template = window.getTemplate('feedTerm');
+		if (!template) return;
+		let [iconEl,span] = [template.querySelector('.icon'), template.querySelector('span')];
+		if (!iconEl || !span) return;
+		template.dataset.id = term.id;
+		template.dataset.taxonomy = term.taxonomy;
+		iconEl.className = `icon icon-${icon}`;
+		span.textContent = term.name;
+
+		this.ui.selected.append(template);
+	}
+
+	processCachedFilters() {
+		Object.keys(this.filters).forEach(filter => {
+			let cached = this.cache.get(`${this.config.source}_${this.config.context}_${filter}`);
+			if (cached && cached !== this.filters[filter]) {
+				this.filters[filter] = cached;
+			}
+		});
+	}
+
+	processURLFilters() {
+		if (!this.isFirstPage()) return false;
+		const params = new URLSearchParams(window.location.search);
+		if (!params.toString()) return false;
+		let shouldUpdate = false;
+		this.allowedFilters.forEach(filter => {
+			let value = params.get(`f_${filter}`);
+			if (value) {
+				shouldUpdate = true;
+				this.filters[filter] = value;
+			}
+		});
+
+		let hasTax = false;
+		params.forEach((value, key) => {
+			if (key.startsWith('f_tax_')) {
+				hasTax = true;
+				shouldUpdate = true;
+				const taxonomy = key.replace('f_tax_','');
+				this.taxFilters[taxonomy] = value.split(',').map(Number);
+			}
+		});
+		if (shouldUpdate) {
+			if (hasTax) {
+				this.filters.taxonomy = this.taxFilters;
+			}
+			this.resetFilters(this.filters);
+		}
+		return true;
+	}
+
+	updateURL() {
+		const params = new URLSearchParams();
+		this.allowedFilters.forEach(key => {
+			if (Object.hasOwn(this.store.filters, key) && this.store.filters[key] !== this.defaults[key]) {
+				params.set(`f_${key}`, this.store.filters[key]);
+			}
+		});
+
+		for (let [tax, terms] of Object.entries(this.taxFilters)) {
+			if (terms.length > 0) {
+				params.set(`f_tax_${tax}`, terms.join(','));
+			}
+		}
+
+		const newURL = `${window.location.pathname}${params.toString() ? '?' + params.toString() : ''}`;
+		const currentURL = window.location.pathname + window.location.search;  // Change this line
+
+		if (newURL !== currentURL) {
+			window.history.pushState({filters:this.store.filters}, '', newURL);
+		}
+	}
+
+	saveToCacheFilters() {
+		Object.keys(this.store.filters).forEach(filter => {
+			const cacheKey = `${this.config.source}_${this.config.context}_${filter}`;
+
+			if (this.store.filters[filter] !== this.defaults[filter]) {
+				this.cache.set(cacheKey, this.store.filters[filter]);
+			} else {
+				this.cache.remove(cacheKey);
+			}
+		});
+
+		const taxCacheKey = `${this.config.source}_${this.config.context}_taxonomy`;
+		if (Object.keys(this.taxFilters).length > 0) {
+			this.cache.set(taxCacheKey, this.taxFilters);
+		} else {
+			this.cache.remove(taxCacheKey);
+		}
+	}
+
+	initGallery() {
+		this.gallery = (this.config.gallery) ? window.jvbGallery : false;
+		if (this.gallery) {
+			this.gallery.subscribe((event, data) => {
+				if (event === 'load-more' && this.store.lastResponse?.has_more) {
+					this.nextPage();
 				}
 			});
 		}
-
-		// Update content-specific visibility
-		this.updateContentFor(this.filters.content);
 	}
-	nextPage() {
-		this.store.setFilter('page', this.store.filters.page++);
-	}
-
 	initStore() {
 		const store = window.jvbStore.register(
 			'feed',
@@ -212,10 +445,9 @@
 					{ name: 'title', keyPath: 'title'}
 				],
 				filters: this.filters,
-				TTL: 6 * 60 * 60 * 1000,
+				TTL: 6 * 60 * 60 * 1000, //6 hours
 				showLoading: true,
 				required: 'content',
-				delayFetch: true
 			}
 		);
 		this.store = store.feed;
@@ -224,192 +456,77 @@
 			switch (event) {
 				case 'data-loaded':
 					this.renderItems();
-					this.ui.loadMore.hidden = true;
-					if (this.store.lastResponse && this.store.lastResponse['has_more']) {
-						this.ui.loadMore.hidden = !this.store.lastResponse['has_more'];
+					this.ui.buttons.loadMore.hidden = true;
+					if (this.store.lastResponse && this.store.lastResponse?.has_more) {
+						this.ui.buttons.loadMore.hidden = !this.store.lastResponse?.has_more??true;
 					}
 					break;
 			}
 		});
 	}
 
-	initGallery() {
-		this.gallery = (this.config.gallery) ? window.jvbGallery : false;
-		if (this.gallery) {
-			this.gallery.subscribe((event, data) => {
-				if (event === 'load-more' && this.store.lastResponse) {
-					if (this.store.lastResponse['has_more']) {
-						this.nextPage();
-					}
-				}
-			});
-		}
-	}
-
-	processCachedFilters() {
-		Object.keys(this.filters).forEach(filter => {
-			let cached = this.cache.get(`${this.config.source}_${this.config.context}_${filter}`);
-			if (cached && cached !== this.filters[filter]){
-				this.filters[filter] = cached;
-			}
-		});
-	}
-
-	processURLFilters() {
-		if (this.filters.page > 1) {
-			return false;
-		}
-		const params = new URLSearchParams(window.location.search);
-
-		if (!params.toString()) {
-			return false;
-		}
-		let filters = ['content', 'order', 'orderby', 'favourites', 'match'];
-		filters.forEach(filter => {
-			let value = params.get(`f_${filter}`);
-			if (value) {
-				this.filters[filter] = value;
-				let input = this.ui.filters[filter];
-				if (input) {
-					input.checked = true;
-				}
-			}
-		});
-
-		let hasTaxonomy = false;
-		// Load taxonomy filters from URL
-		params.forEach((value, key) => {
-			if (key.startsWith('f_tax_')) {
-				hasTaxonomy = true;
-				const taxonomy = key.replace('f_tax_', '');
-				if (!this.taxonomyFilters[taxonomy]) {
-					this.taxonomyFilters[taxonomy] = [];
-				}
-				this.taxonomyFilters[taxonomy] = value.split(',').map(Number);
-			}
-		});
-		if (this.ui.filterContainer && hasTaxonomy) {
-			for (let [tax, ids] in Object.entries(this.taxonomyFilters)) {
-				let button = this.ui.filterContainer.querySelector(`[data-taxonomy="${tax}"]`);
-				if (button) {
-					if (button.dataset.fieldId) {
-						let field = this.selector.get(button.dataset.fieldId);
-						field.selectedTerms = new Set(ids);
-						this.selector.initFieldDisplay(button.dataset.fieldId);
-					} else {
-						this.selector.registerField(button, {
-							button: button,
-							buttonSelector: '[data-filter="taxonomy"]',
-							selected: this.ui.selectedTax,
-							selectedItems: ids
-						});
-					}
-				}
-			}
-		}
-		return true;
-	}
-
-	/**
-	 * Update URL with current filters (for sharing/bookmarking)
-	 */
-	updateURL() {
-		const params = new URLSearchParams();
-
-		// Add simple filters
-		['content', 'order', 'orderby', 'match'].forEach(key => {
-			if (this.filters[key]) {
-				params.set(`f_${key}`, this.filters[key]);
-			}
-		});
-
-		// Add taxonomy filters
-		Object.entries(this.taxonomyFilters).forEach(([taxonomy, terms]) => {
-			if (terms.length > 0) {
-				params.set(`f_tax_${taxonomy}`, terms.join(','));
-			}
-		});
-
-		// Update URL without reload
-		const newURL = `${window.location.pathname}${params.toString() ? '?' + params.toString() : ''}`;
-		window.history.pushState({ filters: this.filters }, '', newURL);
+	isFirstPage() {
+		return this.store.filters.page === 1;
 	}
 
 	renderItems() {
 		let items = this.store.getFiltered();
-		if (this.store.filters['page'] === 1) {
+		if (this.isFirstPage()) {
 			window.removeChildren(this.ui.grid);
 		}
-
 		if (items.length === 0) {
-			this.a11y.announceItems(0, this.store.filters['page'] > 0);
-			return;
-		}
-
-		const fragment = document.createDocumentFragment();
-		const batchSize = 10;
-
-		const processBatch = (startIndex) => {
-			const endIndex = Math.min(startIndex + batchSize, items.length);
-
-			for (let i = startIndex; i < endIndex; i++) {
-				const item = items[i];
-				const element = this.createItemElement(item);
-
-				fragment.appendChild(element);
-			}
-
-			if (endIndex < items.length) {
-				requestAnimationFrame(() => processBatch(endIndex));
-			} else {
-				this.removePlaceholders();
-				this.ui.grid.append(fragment);
-
-				if (this.config.gallery) {
-					this.gallery.updateGalleryItems(this.gallery.getGalleryItems());
-				}
-
-				this.a11y.makeNavigable(this.ui.grid.querySelectorAll('.item:not([data-keyboard-nav])'));
-				this.a11y.announceItems(items.length, this.store.filters['page'] > 1, this.store.hasMore);
-			}
-		};
-
-		if (items.length > 0) {
-			processBatch(0);
+			this.showEmptyState();
+			this.a11y.announceItems(0, this.isFirstPage());
 		} else {
-			this.a11y.announceItems(0, this.store.filters['page'] >1, false);
+			const fragment = document.createDocumentFragment();
+			const processBatch = (startIndex) => {
+				const endIndex = Math.min(startIndex + 10, items.length);
+				for (let i = startIndex; i < endIndex; i++) {
+					const item = items[i];
+					const element = this.createItemElement(item);
+					fragment.append(element);
+				}
+				if (endIndex < items.length) {
+					requestAnimationFrame(() => processBatch(endIndex));
+				} else {
+					this.removePlaceholders();
+					this.ui.grid.append(fragment);
+
+					if (this.config.gallery) this.gallery.buildGalleryItems('.item img');
+					this.a11y.makeNavigable(this.ui.grid.querySelectorAll('.item:not([data-keyboard-nav])'));
+					this.a11y.announceItems(items.length, !this.isFirstPage(), this.store.lastResponse?.has_more??false);
+				}
+			};
+			processBatch(0);
 		}
 
-		if (this.ui.filters.match) {
-			this.ui.filters.match.hidden = Object.keys(this.taxonomyFilters).length === 0;
-		}
-		if (this.ui.clearFilter) {
-			this.ui.clearFilter.hidden = Object.keys(this.taxonomyFilters).length === 0;
-		}
+		this.updateFilterControls();
 	}
 
-	/**
-	 *
-	 * @param {object} item
-	 */
+	showEmptyState() {
+		window.removeChildren(this.ui.grid);
+		let template = window.getTemplate('emptyState');
+		if (!template) return;
+		this.ui.grid.append(template);
+
+	}
+
 	createItemElement(item) {
 		let template = window.getTemplate(`feedItem${window.uppercaseFirst(item.content)}`);
-
 		const isTimeline = Object.hasOwn(template.dataset, 'timeline');
 
-		// Format fields using helpers
 		for (let [fieldName, value] of Object.entries(item.fields)) {
 			if (isTimeline && ['timeline', 'number'].includes(fieldName)) continue;
+
 			let el = template.querySelector(`[data-field="${fieldName}"]`);
 			if (!el) continue;
-
 			if (value === '') {
 				el.remove();
 				continue;
 			}
 
 			if (this.isImageField(item, value)) {
-				this.formatImageFields(el, value, item);
+				this.formatImageField(el, value, item);
 			} else if (this.isTaxonomyField(item, fieldName)) {
 				this.formatTaxonomyField(el, item, fieldName, value);
 			} else if (this.isTimeField(el)) {
@@ -419,16 +536,10 @@
 			}
 		}
 
-		// Handle link
 		let link = template.querySelector('a');
 		if (link && item.url !== '') {
-			[
-				link.href,
-				link.title
-			] = [
-				item.url,
-				`View ${item.fields['post_title']??'Item'}`
-			];
+			[link.href, link.title] =
+				[item.url, `View ${item.fields['post_title']??'Item'}`];
 		}
 
 		if (isTimeline) {
@@ -440,6 +551,7 @@
 	splitIDs(value) {
 		return String(value).split(',').map((value) => parseInt(value.trim())).filter(value=>value);
 	}
+
 	isImageField(item, value) {
 		if (!Object.hasOwn(item, 'images') || Object.keys(item.images).length === 0) {
 			return false;
@@ -471,19 +583,19 @@
 			this.formatImageField(element, values[0], item);
 		}
 	}
-		formatImageField(element, value, item) {
-			let imgData = item.images[value]??false;
-			if (!imgData) return;
-				[
-					element.src,
-					element.srcset,
-					element.alt
-				] = [
-					imgData.tiny,
-					`${imgData.tiny} 50w, ${imgData.small} 300w, ${imgData.medium} 1024w`,
-					imgData['image-alt-text']
-				]
-		}
+	formatImageField(element, value, item) {
+		let imgData = item.images[value]??false;
+		if (!imgData) return;
+		[
+			element.src,
+			element.srcset,
+			element.alt
+		] = [
+			imgData.tiny,
+			`${imgData.tiny} 50w, ${imgData.small} 300w, ${imgData.medium} 1024w`,
+			imgData['image-alt-text']
+		]
+	}
 	isTaxonomyField(item, field) {
 		if (!Object.hasOwn(item, 'taxonomies') || Object.keys(item.taxonomies).length === 0) {
 			return false;
@@ -567,198 +679,24 @@
 		}
 	}
 
-
-	addPlaceholders() {
-		let total = this.contentTypes.length;
-		const fragment = document.createDocumentFragment();
-		for (let i = 0; i < 12; i++) {
-			let template = window.getTemplate('placeholderTemplate');
-
-			let rand = Math.floor(Math.random() * total);
-			let icon;
-			if (this.ui.content && this.ui.content.length > 0) {
-				icon = this.ui.content.filter((content) => { return content.value === this.contentTypes[rand]}).querySelector('.icon').cloneNode(true);
-			} else {
-				icon = window.getIcon(this.container.dataset.icon);
-			}
-			template.append(icon);
-			fragment.append(template);
-		}
-		this.ui.grid.append(fragment);
-	}
-
-
-
-	/**
-	 *
-	 * @param {object} filters {name: value}
-	 */
-	updateFilter(filters) {
-		//double check filters are what we're expecting
-		let allowed = ['taxonomy','favourites','match', ... Object.keys(this.filters)];
-
-		filters = Object.keys(filters)
-			.filter(key => allowed.includes(key))
-			.reduce((obj, key) => {
-				obj[key] = filters[key];
-				return obj;
-			}, {});
-
-		if (window.getDifferences.map(this.filters, filters)) {
-			this.filters = { ...this.filters, ...filters };  // Merge instead of replace
-			this.updateURL();
-			this.store.setFilters(filters);
-		}
-	}
-	/**
-	 * Update visible filters based on selected content type
-	 */
-	updateContentFor(contentType) {
-		// Update taxonomy filter visibility
-		const taxonomyButtons = this.ui.filterContainer.querySelectorAll('[data-filter="taxonomy"]');
-		taxonomyButtons.forEach(button => {
-			const forTypes = button.dataset.for?.split(',') || [];
-			button.hidden = forTypes.length > 0 && !forTypes.includes(contentType);
-		});
-
-		// Update ordering options
-		const orderButtons = this.ui.filterContainer.querySelectorAll('[data-for]');
-		orderButtons.forEach(button => {
-			const forTypes = button.dataset.for?.split(',') || [];
-			if (forTypes.length > 0) {
-				button.hidden = !forTypes.includes(contentType);
-				// Uncheck if hiding
-				if (button.hidden && button.checked) {
-					button.checked = false;
-				}
-			}
-		});
-
-		// Update order direction visibility based on selected orderby
-		const orderBy = this.ui.filterContainer.querySelector('[name="orderby"]:checked');
-		this.updateOrderDirectionVisibility(orderBy?.value);
-	}
-
-	/**
-	 * Show/hide order direction based on orderby selection
-	 */
-	updateOrderDirectionVisibility(orderBy) {
-		const orderDirection = this.ui.filterContainer.querySelector('.order-direction');
-		if (orderDirection) {
-			const forOrders = orderDirection.dataset.forOrder?.split(',') || [];
-			orderDirection.hidden = forOrders.length > 0 && !forOrders.includes(orderBy);
-		}
-	}
-	/*********************************************************************
-	LISTENERS
-	 *********************************************************************/
-	initListeners() {
-		this.popStateHandler 	= this.handlePopState.bind(this);
-		this.clickHandler		= this.handleClick.bind(this);
-		this.changeHandler		= this.handleChange.bind(this);
-		this.imageObserver = null;
-		this.resizeObserver = null;
-		if ('IntersectionObserver' in window) {
-			this.imageObserver = new IntersectionObserver(entries => {
-				entries.forEach(entry => {
-					this.loadImage(entry.target);
-					this.imageObserver.unobserve(entry.target);
-				});
-			}, {
-				rootMargin: '100px',
-				threshold: .1
-			});
-		}
-
-		if ('ResizeObserver' in window) {
-			this.resizeObserver = new ResizeObserver(() => {
-				window.debouncer.schedule(
-					'feed-update-images',
-					() => this.updateImageSizes(),
-					250
-				);
-			});
-		} else {
-			window.addEventListener('resize', () => {
-				window.debouncer.schedule(
-					'feed-update-images',
-					() => this.updateImageSizes(),
-					250
-				);
-			});
-		}
-
-		window.addEventListener('popstate', this.popStateHandler);
-		document.addEventListener('click', this.clickHandler);
-		document.addEventListener('change', this.changeHandler);
-	}
-
-	handlePopState(e) {
-		if (e.state?.filters) {
-			if (this.processURLFilters()) {
-				this.store.setFilters(this.filters);
-				this.a11y.announce('Feed filters updated from browser history');
-			}
-		}
-	}
-
-	handleClick(e) {
-		if (window.targetCheck(e, this.elements.loadMore)) {
-			this.nextPage();
-		} else if (window.targetCheck(e, this.elements.clearFilter)) {
-			this.clearAllTaxonomies();
-		} else if (window.targetCheck(e, '.remove-item')) {
-			this.handleRemoveSelectedTerm(e);
-		}
-	}
-
-	handleRemoveSelectedTerm(e) {
-		const selectedItem = e.target.closest('.selected-item');
-		if (!selectedItem) return;
-
-		const termId = parseInt(selectedItem.dataset.id);
-		const taxonomy = selectedItem.dataset.taxonomy;
-
-		// Remove from filters
-		if (this.taxonomyFilters[taxonomy]) {
-			this.taxonomyFilters[taxonomy] = this.taxonomyFilters[taxonomy]
-				.filter(id => id !== termId);
-
-			if (this.taxonomyFilters[taxonomy].length === 0) {
-				delete this.taxonomyFilters[taxonomy];
-			}
-		}
-
-		// Remove from UI
-		selectedItem.remove();
-
-		// Update filters
-		this.updateFilter({
-			taxonomy: Object.keys(this.taxonomyFilters).length > 0
-				? this.taxonomyFilters
-				: null,
-			page: 1
-		});
-	}
-
-	handleChange(e) {
-		let target = e.target;
-		if (Object.hasOwn(target.dataset, 'filter')) {
-			if (target.dataset.filter === 'content') {
-				this.updateContentFor(target.value);
-				this.updateFilter({ content: target.value, page: 1 });
-			} else if (target.dataset.filter === 'orderby') {
-				this.updateOrderDirectionVisibility(target.value);
-				this.updateFilter({ orderby: target.value, page: 1 });
-			} else if (target.dataset.filter === 'order') {
-				this.updateFilter({ order: target.value, page: 1 });
-			} else if (target.dataset.filter === 'match') {
-				this.updateFilter({ match: target.checked ? 'all' : 'any', page: 1 });
-			} else if (target.dataset.filter === 'favourites') {
-				this.updateFilter({ favourites: target.checked, page: 1 });
-			}
-		}
-	}
+	// addPlaceholders() {
+	// 	let total = this.contentTypes.length;
+	// 	const fragment = document.createDocumentFragment();
+	// 	for (let i = 0; i < 12; i++) {
+	// 		let template = window.getTemplate('placeholderTemplate');
+	//
+	// 		let rand = Math.floor(Math.random() * total);
+	// 		let icon;
+	// 		if (this.ui.content && this.ui.content.length > 0) {
+	// 			icon = this.ui.content.filter((content) => { return content.value === this.contentTypes[rand]}).querySelector('.icon').cloneNode(true);
+	// 		} else {
+	// 			icon = window.getIcon(this.container.dataset.icon);
+	// 		}
+	// 		template.append(icon);
+	// 		fragment.append(template);
+	// 	}
+	// 	this.ui.grid.append(fragment);
+	// }
 }
 
 document.addEventListener('DOMContentLoaded', async function() {
@@ -768,5 +706,3 @@
 		}
 	});
 });
-
-
diff --git a/src/feed/viewOld.js b/src/feed/viewOld.js
index 29859f9..c65be60 100644
--- a/src/feed/viewOld.js
+++ b/src/feed/viewOld.js
@@ -1,745 +1,770 @@
-class FeedBlock {
+class FeedBlockOld {
 	constructor() {
-		this.cache = window.jvbCache;
-		this.a11y = window.jvbA11y;
-		this.loading = window.jvbLoading;
-		this.error = window.jvbError;
-
-
 		this.container = document.querySelector('section.feed-block');
 		if (!this.container) {
 			return;
 		}
 
-		this.openGallery = false;
+		this.a11y = window.jvbA11y;
+		this.cache = new window.jvbCache('feed');
+		this.error = window.jvbError;
 
-		this.initElements();
-		this.addPlaceholders();
 		this.config = {
-			api: feedSettings.apiUrl,
-			nonce: feedSettings.nonce,
-			user: jvbSettings.currentUser || null,
 			source: '',
 			context: '',
 			highlight: null,
 			gallery: false,
-			showAuthor: true,
-			showDate: false,
-			view: localStorage.getItem('feedViewMode') || 'grid',
+			view: this.cache.get('feedView') || 'grid',
 			... this.container.dataset
 		};
-		this.taxonomies = {};
-		this.rendered = {};
+		this.initElements();
+		this.initFilters();
 
-		this.feed = {
-			imageLoadThreshold: 5,
-			lazyLoadOffset: '100px',
-			gallery: [],
-			loaded: 0,
-			intsersectionObserver: null,
-			templates: new Map()
-		};
 
-		this.isLoading = false;
-		this.hasMore = true;
-		this.retries = {
-			count: 0,
-			max: 3,
-			delay: 1000
-		};
-		this.page = 1;
-		this.order = 'DESC';
-		this.orderby = 'date';
-
-		this.gallery = (this.config.gallery) ? new window.jvbGallery(document.querySelector('dialog.gallery'), {
-			imageWrapper: '.item',
-			loadMore: ()=>this.fetchFeed.bind(this)
-		}) : false;
-		this.initListeners();
-		if (this.page === 1) {
-			this.processURLFilters();
-		} else {
-			this.updateFilters();
-		}
-
+		this.loadWhenAble();
 	}
+
+	loadWhenAble() {
+		if ('requestIdleCallback' in window) {
+			requestIdleCallback(() => {
+				this.initTaxonomies();
+				this.initStore();
+				this.initListeners();
+				this.initGallery();
+			}, { timeout: 2000 });
+		} else {
+			setTimeout(() => {
+				this.initTaxonomies();
+				this.initStore();
+				this.initListeners();
+				this.initGallery();
+			}, 100);
+		}
+	}
+
 	initElements() {
-		this.filterSelector = 'form.feed-filters';
-		this.filterForm = this.container.querySelector(this.filterSelector);
-		this.grid = this.container.querySelector('.item-grid');
-		this.loadMore = this.container.querySelector('.load-more');
-		this.filterControls = this.container.querySelector('.filter-actions');
-		this.contentTypes = Array.from(this.filterForm.querySelectorAll('input[name="content"]')).map(
-			content => {
-				return content.value;
-			});
-		this.selectedTerms = this.container.querySelector('.selected-items-section .selected-items');
+		this.currentTaxonomies = new Set();			// Allowed Taxonomies, grabbed from active buttons
+		this.taxonomyFilters = {};
+		this.elements = {
+			filterTrigger: '[data-filter]',
+			filters: {
+				content: '[data-filter="content"]',
+				orderby: '[data-filter="orderby"]',
+				order: '[data-filter="order"]',
+				match: '[data-filter="match"]',
+				favourites: '[data-filter="favourites"]',
+				taxonomy: '[data-filter^="taxonomy"]'
+			},
+			selectedTax: '.selected-items',
+			clearFilter: 'button.clear-filters',
+			loadMore: 'button.load-more',
+			filterContainer: '.filters',
+			grid: '.item-grid',
+		};
+		this.ui = window.uiFromSelectors(this.elements);
+
+
+		this.ui.content = this.ui.filterContainer.querySelectorAll('[name="content"]')??false;
+		this.ui.taxonomies = this.ui.filterContainer.querySelectorAll('[data-taxonomy]');
+		if (this.ui.content && this.ui.content.length > 0) {
+			this.contentTypes = Array.from(
+				this.ui.content
+			).map(content => content.value);
+		} else {
+			this.contentTypes = [this.container.dataset['content']];
+		}
+
+		if (this.ui.taxonomies.length>0) {
+			this.taxonomies = Array.from(
+				this.ui.taxonomies,
+			).map(content => content.dataset.taxonomy);
+		} else {
+			this.taxonomies = [];
+		}
+
+
 	}
 
-	initListeners() {
-		window.addEventListener('popstate', this.handlePopState.bind(this));
-		document.addEventListener('click', this.handleClick.bind(this));
-		document.addEventListener('change', this.handleChange.bind(this));
+	async initTaxonomies() {
+		this.selector = window.jvbSelector;
+		const buttons = document.querySelectorAll('[data-filter="taxonomy"]');
 
+		this.selector.isInitializing = true;
+		buttons.forEach((button) => {
+			const taxonomy = button.dataset.taxonomy;
+			this.currentTaxonomies.add(taxonomy);
 
-		// Intersection observer for lazy loading
-		if ('IntersectionObserver' in window) {
-			this.imageObserver = new IntersectionObserver(entries => {
-				entries.forEach(entry => {
-					if (entry.isIntersecting) {
-						this.loadImage(entry.target);
-						this.imageObserver.unobserve(entry.target);
-					}
-				});
-			}, {
-				rootMargin: '100px',
-				threshold: 0.1
+			this.selector.registerFilterButton(button, {
+				button: button,
+				buttonSelector: '[data-filter="taxonomy"]',
+				selected: this.ui.selectedTax
+			});
+
+			// Add preload listeners
+			this.addTaxonomyPreloadListeners(button, taxonomy);
+		});
+
+		this.selector.isInitializing = false;
+
+		this.selector.subscribe((event, data) => {
+			if (event === 'selected-terms') this.handleTaxonomyChange(data);
+		});
+	}
+
+	addTaxonomyPreloadListeners(button, taxonomy) {
+		const preload = () => {
+			this.selector.preloadTaxonomy(taxonomy);
+		};
+
+		// Desktop hover
+		button.addEventListener('mouseenter', preload, { once: true });
+
+		// Touch/keyboard (fires before click)
+		button.addEventListener('pointerdown', preload, { once: true });
+
+		// Keyboard focus
+		button.addEventListener('focus', preload, { once: true });
+	}
+
+	handleTaxonomyChange(data) {
+		const { terms, taxonomy } = data;
+
+		// Update only the current taxonomy's terms
+		if (terms.size > 0) {
+			this.taxonomyFilters[taxonomy] = Array.from(terms.keys());
+		} else {
+			// Remove taxonomy if no terms selected
+			delete this.taxonomyFilters[taxonomy];
+		}
+
+		// Build filters object with all taxonomies
+		let filters = {
+			page: 1
+		};
+
+		// Add taxonomy filters if any exist
+		if (Object.keys(this.taxonomyFilters).length > 0) {
+			filters.taxonomy = this.taxonomyFilters;
+		}
+
+		this.updateFilter(filters);
+	}
+
+	clearAllTaxonomies() {
+		this.taxonomyFilters = {};
+		window.removeChildren(this.ui.selectedTax);
+
+		this.updateFilter({
+			taxonomy: null,
+			page: 1
+		});
+	}
+
+	initFilters() {
+		//defaults
+		this.filters = {
+			content: 	this.contentTypes[0],
+			orderby: 	'date',
+			order: 		'desc',
+			page: 		1
+		};
+		if (this.config.context) this.filters.context = this.config.context;
+		if (this.config.source) this.filters.source = this.config.source;
+
+		//check the cache
+		this.processCachedFilters();
+		//check url
+		this.processURLFilters();
+
+		// Set initial UI state
+		this.syncUIToFilters();
+	}
+	syncUIToFilters() {
+		if (this.ui.filterContainer) {
+			// Check radio buttons
+			Object.entries(this.filters).forEach(([key, value]) => {
+				const input = this.ui.filterContainer.querySelector(`[data-filter="${key}"][value="${value}"]`);
+				if (input) {
+					input.checked = true;
+				}
 			});
 		}
-		// Resize observer for responsive images
-		if ('ResizeObserver' in window) {
-			this.resizeObserver = new ResizeObserver(window.debounce(() => {
-				this.updateImageSizes();
-			}, 250));
 
-			// Observe the container
-			this.resizeObserver.observe(this.container);
-		} else {
-			// Fallback to window resize
-			window.addEventListener('resize', window.debounce(() => {
-				this.updateImageSizes();
-			}, 250));
-		}
+		// Update content-specific visibility
+		this.updateContentFor(this.filters.content);
+	}
+	nextPage() {
+		this.store.setFilter('page', this.store.filters.page++);
+	}
 
-		this.taxonomies = {};
-		this.container.querySelectorAll('.jvb-selector:not([hidden])').forEach(selector => {
-			let taxonomy = selector.dataset.taxonomy;
-			if (!Object.hasOwn(this.taxonomies, taxonomy)) {
-				this.taxonomies[taxonomy] = new window.jvbTaxonomySelector(
-					selector,
-					{
-						multiple: true,
-						feed: true,
-						selected: {},
-						onClose: () => this.setSelectedTerms(taxonomy),
+	initStore() {
+		const store = window.jvbStore.register(
+			'feed',
+			{
+				storeName: 'feed',
+				endpoint: 'feed',
+				keyPath: 'id',
+				indexes: [
+					{ name: 'content', keyPath: 'content'},
+					{ name: 'taxonomy', keyPath: 'taxonomy'},
+					{ name: 'user', keyPath: 'user'},
+					{ name: 'date', keyPath: 'modified'},
+					{ name: 'title', keyPath: 'title'}
+				],
+				filters: this.filters,
+				TTL: 6 * 60 * 60 * 1000,
+				showLoading: true,
+				required: 'content',
+				delayFetch: true
+			}
+		);
+		this.store = store.feed;
+
+		this.store.subscribe((event, data) => {
+			switch (event) {
+				case 'data-loaded':
+					this.renderItems();
+					this.ui.loadMore.hidden = true;
+					if (this.store.lastResponse && this.store.lastResponse['has_more']) {
+						this.ui.loadMore.hidden = !this.store.lastResponse['has_more'];
 					}
-				);
+					break;
 			}
 		});
 	}
 
-
-	/**
-	 * Handle browser history navigation
-	 */
-	handlePopState(e) {
-		if (e.state && e.state.filters) {
-			if(this.processURLFilters()){
-				// Load items with updated filters
-				this.resetPage();
-				this.fetchFeed();
-
-				// Announce to screen readers
-				this.a11y.announce('Feed filters updated from browser history.');
-			}
+	initGallery() {
+		this.gallery = (this.config.gallery) ? window.jvbGallery : false;
+		if (this.gallery) {
+			this.gallery.subscribe((event, data) => {
+				if (event === 'load-more' && this.store.lastResponse) {
+					if (this.store.lastResponse['has_more']) {
+						this.nextPage();
+					}
+				}
+			});
 		}
 	}
 
+	processCachedFilters() {
+		Object.keys(this.filters).forEach(filter => {
+			let cached = this.cache.get(`${this.config.source}_${this.config.context}_${filter}`);
+			if (cached && cached !== this.filters[filter]){
+				this.filters[filter] = cached;
+			}
+		});
+	}
+
 	processURLFilters() {
-		const params = new URLSearchParams(window.location.search);
-		//No parameters to process
-		if (!params.toString()) {
-			this.updateFilters();
-			return;
+		if (this.filters.page > 1) {
+			return false;
 		}
+		const params = new URLSearchParams(window.location.search);
 
-		let filters = ['content', 'order', 'orderby', 'favourites','match'];
-
+		if (!params.toString()) {
+			return false;
+		}
+		let filters = ['content', 'order', 'orderby', 'favourites', 'match'];
 		filters.forEach(filter => {
-			let value = params.get('f_'+filter);
-			params.delete('f_'+filter);
-			if (value && this.filterForm.querySelector(`input[name="${filter}"][value="${value}"]`)) {
-				this.filterForm.querySelector(`input[name="${filter}"][value="${value}"]`).checked = true;
+			let value = params.get(`f_${filter}`);
+			if (value) {
+				this.filters[filter] = value;
+				let input = this.ui.filters[filter];
+				if (input) {
+					input.checked = true;
+				}
 			}
 		});
 
-		let unprocessed = {};
-		for (var [key, value] of Object.entries(Object.fromEntries(params))) {
-
-			key = key.replace('f_','');
-			if (this.contentTypes.includes(key)) {
-				this.openGallery = value;
-			} else {
-				this.taxonomies[key].addTermsFromURL(value);
-				this.setSelectedTerms(key);
+		let hasTaxonomy = false;
+		// Load taxonomy filters from URL
+		params.forEach((value, key) => {
+			if (key.startsWith('f_tax_')) {
+				hasTaxonomy = true;
+				const taxonomy = key.replace('f_tax_', '');
+				if (!this.taxonomyFilters[taxonomy]) {
+					this.taxonomyFilters[taxonomy] = [];
+				}
+				this.taxonomyFilters[taxonomy] = value.split(',').map(Number);
 			}
-		}
-
-		this.updateFilters();
-	}
-
-	handleClick(e) {
-		if (e.target.classList.contains('load-more') || e.target.closest('.load-more')) {
-			this.fetchFeed(false);
-			e.target.disabled = true;
-		} else if (e.target.classList.contains('clear-filters') || e.target.closest('.clear-filters')) {
-			this.resetFilters();
-		} else if (this.config.gallery && e.target.closest('.feed-image')) {
-			this.gallery.handleGalleryOpen(e);
-		} else if (e.target.classList.contains('.remove-item') || e.target.closest('.remove-item')) {
-			let tag = e.target.closest('.selected-item');
-			let taxonomy = tag.dataset.taxonomy;
-			this.taxonomies[taxonomy].removeSelectedTerm(tag.dataset.id);
-			this.setSelectedTerms(taxonomy);
-			this.updateFilters();
-		}
-	}
-	handleChange(e) {
-		if (e.target.closest(this.filterSelector)) {
-			this.resetPage();
-			window.removeChildren(this.grid);
-			this.addPlaceholders();
-			//update filters
-			this.updateFilters();
-		}
-	}
-
-	updateFilters() {
-		this.page = 1;
-		const params = new URLSearchParams(window.location.search);
-
-		let filters = Object.fromEntries(new FormData(this.filterForm));
-
-		let contents = [];
-		for (let [key, value] of Object.entries(filters)) {
-			let set = false;
-			switch (key) {
-				case 'content':
-					if (value !== this.contentTypes[0]) {
-						set = true;
+		});
+		if (this.ui.filterContainer && hasTaxonomy) {
+			for (let [tax, ids] in Object.entries(this.taxonomyFilters)) {
+				let button = this.ui.filterContainer.querySelector(`[data-taxonomy="${tax}"]`);
+				if (button) {
+					if (button.dataset.fieldId) {
+						let field = this.selector.get(button.dataset.fieldId);
+						field.selectedTerms = new Set(ids);
+						this.selector.initFieldDisplay(button.dataset.fieldId);
 					} else {
-						params.delete('f_'+key);
+						this.selector.registerField(button, {
+							button: button,
+							buttonSelector: '[data-filter="taxonomy"]',
+							selected: this.ui.selectedTax,
+							selectedItems: ids
+						});
 					}
-					break;
-				case 'orderby':
-					if (value !== 'date') {
-						set = true;
-					}
-					break;
-				case 'order':
-					if (value !== 'desc') {
-						set = true;
-					}
-					break;
-				default:
-					set = true;
+				}
 			}
-			if (!set) {
-				params.delete('f_'+key);
-			}
-
-
-			if (set && value !== false && value !== '') {
-				params.set('f_'+key, value);
-			}
-			if (value !== '') {
-				contents.push(value);
-			}
-
-			const newURL = `${window.location.pathname}?${params.toString()}`;
-			history.pushState(filters, '', newURL);
-
 		}
-
-		this.filters = filters;
-		this.updateContentFor(filters.content);
-
-		this.updateFilterControls();
-
-		this.loading.setContent(contents);
-		this.fetchFeed(true);
-	}
-
-	updateFilterControls() {
-		this.filterControls.hidden = this.selectedTerms.children.length < 2;
+		return true;
 	}
 
 	/**
-	 * Toggles taxonomy selectors and certain order/orderby options
-	 *  depending on current content
-	 * @param content
+	 * Update URL with current filters (for sharing/bookmarking)
 	 */
-	updateContentFor(content) {
-		this.filterForm.querySelectorAll('.jvb-selector').forEach(tax => {
-			let hasContent = tax.dataset.for.includes(content);
-			tax.hidden = !hasContent;
-			if (!hasContent) {
-				let t = tax.dataset.taxonomy;
-				this.clearSelectedTerms(t);
+	updateURL() {
+		const params = new URLSearchParams();
+
+		// Add simple filters
+		['content', 'order', 'orderby', 'match'].forEach(key => {
+			if (this.filters[key]) {
+				params.set(`f_${key}`, this.filters[key]);
 			}
 		});
-		this.filterForm.querySelectorAll('input[data-for]').forEach(toggle => {
-			toggle.hidden = !toggle.dataset.for.includes(content);
+
+		// Add taxonomy filters
+		Object.entries(this.taxonomyFilters).forEach(([taxonomy, terms]) => {
+			if (terms.length > 0) {
+				params.set(`f_tax_${taxonomy}`, terms.join(','));
+			}
 		});
-		this.filterForm.querySelectorAll('input[name="order"]').forEach(order => {
-			order.hidden = this.filters.order === 'random';
-		});
+
+		// Update URL without reload
+		const newURL = `${window.location.pathname}${params.toString() ? '?' + params.toString() : ''}`;
+		window.history.pushState({ filters: this.filters }, '', newURL);
 	}
 
-	clearSelectedTerms(taxonomy) {
-		this.filterForm.querySelector(`input[name="${taxonomy}"]`).value = '';
-		if (Object.hasOwn(this.taxonomies, taxonomy)) {
-			this.taxonomies[taxonomy].selectedItems = {};
-		}
-	}
-
-	setSelectedTerms(taxonomy) {
-		let input = this.filterForm.querySelector(`input[name="${taxonomy}"]`);
-		input.value = '';
-		let selected = this.taxonomies[taxonomy].selectedTerms;
-		if (!window.isEmptyObject(selected)) {
-			let ids = Object.keys(selected);
-			input.value = ids.join(',');
-		}
-		this.updateFilters();
-	}
-
-
-	nextPage() {
-		if (this.hasMore) {
-			this.page++;
-		}
-	}
-	resetPage() {
-		this.page = 1;
-		this.hasMore = true;
-	}
-	resetState() {
-		this.resetPage(true);
-		this.isLoading = false;
-		this.retries = {
-			count: 0,
-			max: 3,
-			delay: 1000
-		};
-	}
-
-	resetFilters() {
-		this.filterForm.reset();
-		//check the first content
-		this.filterForm.querySelector('input[name="content"]').checked = true;
-		this.filterForm.querySelector('input[name="orderby"][value="date"]').checked = true;
-		this.page = 1;
-		this.updateFilters();
-	}
-
-
-	buildFilterRequest() {
-
-		let filters = {};
-
-		for (let [filter, value] of Object.entries(this.filters)) {
-			if (value !== false && value !== '') {
-				filters[filter] = value;
-			}
-		}
-		filters.page = parseInt(this.page);
-		if (this.container.dataset.context) {
-			filters.context = this.container.dataset.context;
-		}
-		if (this.container.dataset.source) {
-			filters.source = this.container.dataset.source;
-		}
-		return new URLSearchParams(filters).toString();
-	}
-
-	async fetchFeed(reset = false, force = false) {
-		if (this.isLoading) {
-			return false;
-		}
-		this.loading.showLoading(this.filters);
-		try {
-			if (this.page === 1) {
-				window.removeChildren(this.grid);
-				this.addPlaceholders();
-			}
-
-			const data = await this.cache.fetchWithCache(
-				`${this.config.api}feed?${this.buildFilterRequest()}`,
-				{
-					method: 'GET',
-				},
-				{
-					context: 'feed',
-					forceRefresh: true
-					// forceRefresh: force
-				}
-			);
-
-			//Handle empty results
-			if (!data || !data.items || data.items.length === 0) {
-				if (this.page === 1) {
-					this.showEmptyState();
-				}
-				this.hasMore = false;
-				return false;
-			} else {
-				this.hasMore = data['has_more'];
-
-				this.renderItems(data.items, this.page > 1);
-
-				if (this.hasMore) {
-					this.nextPage();
-				}
-				return true;
-			}
-		} catch (error) {
-			this.handleError(error);
-		} finally {
-			this.loading.hideLoading();
-			if (this.openGallery !== false) {
-				this.gallery.openWhenReady = this.openGallery;
-				this.openGallery = false;
-			}
-			this.loadMore.disabled = false;
-			this.loadMore.hidden = !this.hasMore;
-		}
-	}
-
-	removePlaceholders() {
-		if (this.grid.querySelector('.placeholder')) {
-			window.removeChildren(this.grid);
-		}
-	}
-	showEmptyState() {
-		window.removeChildren(this.grid);
-		let template = window.getTemplate('emptyState');
-		let isFavourite = Object.hasOwn(this.filters, 'favourites') && this.filters.favourites === true;
-		if (isFavourite) {
-			[
-				template.querySelector('h3').textContent,
-				template.querySelector('p:first-of-type').textContent,
-				template.querySelector('p:last-of-type').textContent,
-			] = [
-				'♡ BLANK CANVAS ♡',
-				'You haven\'t fallen in love with any pieces... yet!',
-				'Hit that heart icon when something stops your scroll — your dream collection is waiting to start.'
-			];
-		}
-		this.grid.append(template);
-		this.a11y.announceEmpty(isFavourite);
-
-	}
-	handleError(error){
-		return this.error.handleApiError(
-			error,
-			{
-				component: 'Feed Block',
-				action: 'loaditems'
-			},
-			() => this.fetchFeed()
-		);
-	}
-
-	addPlaceholders() {
-		let total = this.contentTypes.length - 1;
-		for (let i = 0; i < 9; i++) {
-			let template = window.getTemplate('placeholderTemplate');
-			let rand =  Math.floor(Math.random()*total+1);
-			let icon = window.getIcon(this.contentTypes[rand]).cloneNode(true);
-
-			template.append(icon);
-			this.grid.append(template);
-		}
-	}
-	renderItems(items, append = false) {
-		//Clear the grid if we aren't appending
-		if (!append) {
-			window.removeChildren(this.grid);
-			this.addPlaceholders();
+	renderItems() {
+		let items = this.store.getFiltered();
+		if (this.store.filters['page'] === 1) {
+			window.removeChildren(this.ui.grid);
 		}
 
-
-		//Bail early if no items
 		if (items.length === 0) {
-			this.a11y.announceUpdate(0, append);
+			this.a11y.announceItems(0, this.store.filters['page'] > 0);
 			return;
 		}
 
-		//Use DocumentFragment for better performance
 		const fragment = document.createDocumentFragment();
-
 		const batchSize = 10;
+
 		const processBatch = (startIndex) => {
 			const endIndex = Math.min(startIndex + batchSize, items.length);
 
 			for (let i = startIndex; i < endIndex; i++) {
 				const item = items[i];
 				const element = this.createItemElement(item);
-				fragment.appendChild(element);
 
-				this.imageObserver.observe(element);
+				fragment.appendChild(element);
 			}
 
 			if (endIndex < items.length) {
-				requestAnimationFrame(() => {
-					processBatch(endIndex);
-				});
+				requestAnimationFrame(() => processBatch(endIndex));
 			} else {
 				this.removePlaceholders();
-				//all batches are processed, append fragment
-				this.grid.appendChild(fragment);
+				this.ui.grid.append(fragment);
+
 				if (this.config.gallery) {
 					this.gallery.updateGalleryItems(this.gallery.getGalleryItems());
 				}
-				this.a11y.makeNavigable(this.grid.querySelectorAll('.item:not([data-keyboard-nav])'));
-				this.a11y.announceItems(items.length, append, this.hasMore);
+
+				this.a11y.makeNavigable(this.ui.grid.querySelectorAll('.item:not([data-keyboard-nav])'));
+				this.a11y.announceItems(items.length, this.store.filters['page'] > 1, this.store.hasMore);
 			}
 		};
 
 		if (items.length > 0) {
 			processBatch(0);
 		} else {
-			this.a11y.announceUpdate(0, append);
+			this.a11y.announceItems(0, this.store.filters['page'] >1, false);
+		}
+
+		if (this.ui.filters.match) {
+			this.ui.filters.match.hidden = Object.keys(this.taxonomyFilters).length === 0;
+		}
+		if (this.ui.clearFilter) {
+			this.ui.clearFilter.hidden = Object.keys(this.taxonomyFilters).length === 0;
 		}
 	}
 
 	/**
-	 * Creates a feed-item. Used by RenderItems
+	 *
+	 * @param {object} item
 	 */
 	createItemElement(item) {
-		if(!this.rendered[item.icon]) {
-			this.rendered[item.icon] = new Map();
-		}
-		if (this.rendered[item.icon].has(item.id)) {
-			return this.rendered[item.icon].get(item.id);
-		}
+		let template = window.getTemplate(`feedItem${window.uppercaseFirst(item.content)}`);
 
-		const favourited = window.isFavourited(item.icon, item.id)??false;
-		const template = window.getTemplate('feed-item');
+		const isTimeline = Object.hasOwn(template.dataset, 'timeline');
 
-		template.id = `${item.icon}-${item.id}`;
-		template.dataset.id = item.id;
-		template.classList.add(item.icon);
+		// Format fields using helpers
+		for (let [fieldName, value] of Object.entries(item.fields)) {
+			if (isTimeline && ['timeline', 'number'].includes(fieldName)) continue;
+			let el = template.querySelector(`[data-field="${fieldName}"]`);
+			if (!el) continue;
 
-		if (item['umami_view']) {
-			this.buildUmamiData(template, item['umami_view']);
-		}
+			if (value === '') {
+				el.remove();
+				continue;
+			}
 
-		let favouriteButton = template.querySelector('button.favourite');
-		[
-			favouriteButton.dataset.id,
-			favouriteButton.dataset.type,
-			favouriteButton.dataset.artist,
-			favouriteButton.title
-		] = [
-			item.id,
-			item.icon,
-			item['user_id'],
-			(favourited) ? 'Remove from Favourites' : 'Add to Favourites'
-		];
-
-		let order = item.order;
-		let single = template.querySelector('.item');
-		let list = template.querySelector('.item-list');
-		let img = template.querySelector('.feed-images');
-		let summary = template.querySelector('summary');
-		let info = template.querySelector('.item-info');
-
-		for (let [index, id] of Object.entries(order)) {
-			let target;
-			let config = item[id];
-			if (id === 'title') {
-				target = template.querySelector('h3 a');
-				if (item.title !== '') {
-					[
-						target.textContent,
-						target.href,
-						target.url
-					] = [
-						item.title,
-						item.url,
-						`Learn more about this ${item.icon}`
-					];
-					if (item.icon !== '') {
-						target.closest('h3').prepend(window.getIcon(item.icon));
-					}
-					if (item.umami_click) {
-						this.buildUmamiData(target, item.umami_click);
-					}
-				} else {
-					target.remove();
-				}
-			}  else if (Object.hasOwn(config, 'terms')) {
-				//Taxonomy list
-				if (config.terms.length === 0) {
-					continue;
-				}
-				let taxonomy = list.cloneNode(true);
-				let label = taxonomy.querySelector('.label');
-				let termList = taxonomy.querySelector('ul');
-				let listItem = taxonomy.querySelector('li');
-
-				if (config.label) {
-					label.textContent = config.label;
-				}
-				if (config.icon) {
-					label.prepend(window.getIcon(config.icon));
-				}
-				if (!config.label && !config.icon){
-					label.remove();
-				}
-
-				config.terms.forEach(term => {
-					let termItem = listItem.cloneNode(true);
-					let link = termItem.querySelector('a');
-					[
-						link.href,
-						link.title,
-						link.textContent
-					] = [
-						term.url,
-						`Learn more about ${term.title}`,
-						term.title
-					];
-					if (term.umami_click.length > 0) {
-						this.buildUmamiData(link, term.umami_click);
-					}
-					termList.append(termItem);
-				});
-
-				listItem.remove();
-				info.appendChild(taxonomy);
-			} else if (Object.hasOwn(config, 'value') && config.value !== '') {
-				let itemInfo = single.cloneNode(true);
-				let label = itemInfo.querySelector('.label');
-				let link = itemInfo.querySelector('a');
-				let p = itemInfo.querySelector('p');
-				if (Object.hasOwn(config, 'label')) {
-					label.textContent = config.label;
-				}
-				if (Object.hasOwn(config, 'icon')) {
-					label.prepend(window.getIcon(config.icon));
-				}
-				if (!Object.hasOwn(config, 'icon') && !Object.hasOwn(config, 'label')) {
-					label.remove();
-				}
-				if (Object.hasOwn(config, 'url')) {
-					p.remove();
-					[
-						link.textContent,
-						link.href,
-						link.title
-					] = [
-						config.value,
-						config.url,
-						`Learn more about ${config.value}`
-					];
-				} else {
-					link.remove();
-					p.textContent = config.value;
-				}
-				info.appendChild(itemInfo);
-			} else if (id === 'image') {
-				let images = summary.querySelector('.feed-images');
-				let img = images.querySelector('a');
-
-				let main = img.cloneNode(true);
-				if (!this.config.gallery) {
-					main.href = item.url;
-				}
-
-				main.classList.add('feed-image');
-				this.buildImageData(main.querySelector('img'), item.image);
-				images.append(main);
-
-				if (item.content?.length > 0) {
-					images.classList.add('multi');
-					item.content.forEach(c => {
-						let image = img.cloneNode(true);
-						if (!this.config.gallery) {
-							image.href = c.url;
-						}
-						let itemImg = image.querySelector('img');
-						itemImg.src = c.image.small;
-						itemImg.alt = c.image.alt;
-						images.append(image);
-					});
-				}
-				img.remove();
+			if (this.isImageField(item, value)) {
+				this.formatImageFields(el, value, item);
+			} else if (this.isTaxonomyField(item, fieldName)) {
+				this.formatTaxonomyField(el, item, fieldName, value);
+			} else if (this.isTimeField(el)) {
+				this.formatTimeField(el, value);
+			} else {
+				this.formatField(el, value);
 			}
 		}
-		single.remove();
-		list.remove();
 
-		this.rendered[item.icon].set(item.id, template);
+		// Handle link
+		let link = template.querySelector('a');
+		if (link && item.url !== '') {
+			[
+				link.href,
+				link.title
+			] = [
+				item.url,
+				`View ${item.fields['post_title']??'Item'}`
+			];
+		}
+
+		if (isTimeline) {
+			this.addTimelineElements(item, template);
+		}
 
 		return template;
 	}
-
-	buildImageData(img, data){
-		if (typeof data.tiny !== 'string') {
-			return;
+	splitIDs(value) {
+		return String(value).split(',').map((value) => parseInt(value.trim())).filter(value=>value);
+	}
+	isImageField(item, value) {
+		if (!Object.hasOwn(item, 'images') || Object.keys(item.images).length === 0) {
+			return false;
 		}
+		let values = this.splitIDs(value);
+
+		return values.some(v =>
+			Object.keys(item.images).map(k => parseInt(k)).includes(parseInt(v))
+		);
+	}
+	formatImageFields(element, value, item) {
+		let values = this.splitIDs(value); // Convert string to array first
+		if (values.length === 0) return;
+
+		if (values.length > 1) {
+			let image = element.querySelector('img');
+			if (!image) return;
+			values.forEach(imgID => {
+				let img = image.cloneNode(true);
+				this.formatImageField(img, imgID, item);
+				element.append(img);
+			});
+			image.remove();
+		} else {
+			if (element.tagName !== 'IMG') {
+				element = element.querySelector('img');
+				if (!element) return;
+			}
+			this.formatImageField(element, values[0], item);
+		}
+	}
+	formatImageField(element, value, item) {
+		let imgData = item.images[value]??false;
+		if (!imgData) return;
 		[
-			img.src,
-			img.dataset.small,
-			img.dataset.medium,
-			img.dataset.large,
-			img.alt
-		] =
+			element.src,
+			element.srcset,
+			element.alt
+		] = [
+			imgData.tiny,
+			`${imgData.tiny} 50w, ${imgData.small} 300w, ${imgData.medium} 1024w`,
+			imgData['image-alt-text']
+		]
+	}
+	isTaxonomyField(item, field) {
+		if (!Object.hasOwn(item, 'taxonomies') || Object.keys(item.taxonomies).length === 0) {
+			return false;
+		}
+
+		return Object.keys(item.taxonomies).includes(field);
+	}
+	formatTaxonomyField(element, item, field, value) {
+		if (element.tagName !== 'UL' || !element.querySelector('li')) return;
+		let values = this.splitIDs(value);
+		if (values.length === 0) {
+			element.remove();
+		}
+		let listItem = element.querySelector('li');
+		for (let termID of values) {
+			let term = item.taxonomies[field][termID]??false;
+			if (!term) continue;
+			let termItem = listItem.cloneNode(true);
+			let link = termItem.querySelector('a');
+			if (!link) continue;
+
 			[
-				data.tiny,
-				data.small,
-				data.medium,
-				data.large,
-				data.alt
+				link.href,
+				link.title,
+				link.textContent
+			] = [
+				term.url,
+				`See more ${term.title}`,
+				term.title
 			];
+			element.append(termItem);
+		}
+		listItem.remove();
+	}
+	isTimeField(el) {
+		return el.tagName === 'TIME' || el.querySelector('time') !== null;
+	}
+	formatTimeField(element, value) {
+		if (element.tagName !== 'TIME') {
+			element = element.querySelector('time');
+			if (!element) return;
+		}
+		element.setAttribute('datetime', value);
+		element.textContent = window.formatTimeAgo(value, 'F Y');
+	}
+	formatField(element, value) {
+		element.textContent = value;
 	}
 
-	buildUmamiData(item, data){
-		for(let [key, value] of Object.entries(data)){
-			item.dataset[key] = value;
+	addTimelineElements(item, template) {
+		let [
+			afterEl,
+			number,
+			started,
+			last
+		] = [
+			template.querySelector('span.after-text'),
+			template.querySelector('[data-field="number"] b'),
+			template.querySelector('[data-field="started"] time'),
+			template.querySelector('[data-field="updated"] time')
+		];
+
+		if (afterEl) {
+			afterEl.textContent = `After ${item.fields.number} Tx`;
+		}
+		if (number) {
+			number.textContent = item.fields.number;
+		}
+		if (started) {
+			this.formatTimeField(started, item.fields.timeline[0]['post_date']);
+		}
+		if (last) {
+			this.formatTimeField(last, item.fields.timeline[item.fields.timeline.length - 1]['post_date']);
 		}
 	}
 
-	/**
-	 * Load Image, used by renderItems
-	 * @param element
-	 */
-	loadImage(element) {
-		const img = element.querySelector('img');
-		if (!img) return;
-		const size = this.getImageSize();
-
-		img.src = img.dataset[size] || img.dataset.src;
-		element.setAttribute('data-loaded', 'true');
+	removePlaceholders() {
+		const placeholders = this.ui.grid.querySelectorAll('.placeholder');
+		if (placeholders.length > 0) {
+			placeholders.forEach(p => p.remove());
+		}
 	}
 
+
+	addPlaceholders() {
+		let total = this.contentTypes.length;
+		const fragment = document.createDocumentFragment();
+		for (let i = 0; i < 12; i++) {
+			let template = window.getTemplate('placeholderTemplate');
+
+			let rand = Math.floor(Math.random() * total);
+			let icon;
+			if (this.ui.content && this.ui.content.length > 0) {
+				icon = this.ui.content.filter((content) => { return content.value === this.contentTypes[rand]}).querySelector('.icon').cloneNode(true);
+			} else {
+				icon = window.getIcon(this.container.dataset.icon);
+			}
+			template.append(icon);
+			fragment.append(template);
+		}
+		this.ui.grid.append(fragment);
+	}
+
+
+
 	/**
-	 * Updates the image size according to screen size
+	 *
+	 * @param {object} filters {name: value}
 	 */
-	updateImageSizes() {
-		const size = this.getImageSize();
-		const items = this.grid.querySelectorAll('.item');
-		items.forEach(item => {
-			const img = item.querySelector('img');
-			if (img && img.dataset[size] && img.src !== img.dataset[size]) {
-				img.src = img.dataset[size];
+	updateFilter(filters) {
+		//double check filters are what we're expecting
+		let allowed = ['taxonomy','favourites','match', ... Object.keys(this.filters)];
+
+		filters = Object.keys(filters)
+			.filter(key => allowed.includes(key))
+			.reduce((obj, key) => {
+				obj[key] = filters[key];
+				return obj;
+			}, {});
+
+		if (window.getDifferences.map(this.filters, filters)) {
+			this.filters = { ...this.filters, ...filters };  // Merge instead of replace
+			this.updateURL();
+			this.store.setFilters(filters);
+		}
+	}
+	/**
+	 * Update visible filters based on selected content type
+	 */
+	updateContentFor(contentType) {
+		// Update taxonomy filter visibility
+		const taxonomyButtons = this.ui.filterContainer.querySelectorAll('[data-filter="taxonomy"]');
+		taxonomyButtons.forEach(button => {
+			const forTypes = button.dataset.for?.split(',') || [];
+			button.hidden = forTypes.length > 0 && !forTypes.includes(contentType);
+		});
+
+		// Update ordering options
+		const orderButtons = this.ui.filterContainer.querySelectorAll('[data-for]');
+		orderButtons.forEach(button => {
+			const forTypes = button.dataset.for?.split(',') || [];
+			if (forTypes.length > 0) {
+				button.hidden = !forTypes.includes(contentType);
+				// Uncheck if hiding
+				if (button.hidden && button.checked) {
+					button.checked = false;
+				}
 			}
 		});
-	}
-	/**
-	 * Get image size based on screen width
-	 */
-	getImageSize() {
-		const width = window.innerWidth;
-		if (width > 1024) return 'medium';
-		if (width > 500) return 'medium';
-		return 'small';
+
+		// Update order direction visibility based on selected orderby
+		const orderBy = this.ui.filterContainer.querySelector('[name="orderby"]:checked');
+		this.updateOrderDirectionVisibility(orderBy?.value);
 	}
 
+	/**
+	 * Show/hide order direction based on orderby selection
+	 */
+	updateOrderDirectionVisibility(orderBy) {
+		const orderDirection = this.ui.filterContainer.querySelector('.order-direction');
+		if (orderDirection) {
+			const forOrders = orderDirection.dataset.forOrder?.split(',') || [];
+			orderDirection.hidden = forOrders.length > 0 && !forOrders.includes(orderBy);
+		}
+	}
+	/*********************************************************************
+	LISTENERS
+	 *********************************************************************/
+	initListeners() {
+		this.popStateHandler 	= this.handlePopState.bind(this);
+		this.clickHandler		= this.handleClick.bind(this);
+		this.changeHandler		= this.handleChange.bind(this);
+		this.imageObserver = null;
+		this.resizeObserver = null;
+		if ('IntersectionObserver' in window) {
+			this.imageObserver = new IntersectionObserver(entries => {
+				entries.forEach(entry => {
+					this.loadImage(entry.target);
+					this.imageObserver.unobserve(entry.target);
+				});
+			}, {
+				rootMargin: '100px',
+				threshold: .1
+			});
+		}
+
+		if ('ResizeObserver' in window) {
+			this.resizeObserver = new ResizeObserver(() => {
+				window.debouncer.schedule(
+					'feed-update-images',
+					() => this.updateImageSizes(),
+					250
+				);
+			});
+		} else {
+			window.addEventListener('resize', () => {
+				window.debouncer.schedule(
+					'feed-update-images',
+					() => this.updateImageSizes(),
+					250
+				);
+			});
+		}
+
+		window.addEventListener('popstate', this.popStateHandler);
+		document.addEventListener('click', this.clickHandler);
+		document.addEventListener('change', this.changeHandler);
+	}
+
+	handlePopState(e) {
+		if (e.state?.filters) {
+			if (this.processURLFilters()) {
+				this.store.setFilters(this.filters);
+				this.a11y.announce('Feed filters updated from browser history');
+			}
+		}
+	}
+
+	handleClick(e) {
+		if (window.targetCheck(e, this.elements.loadMore)) {
+			this.nextPage();
+		} else if (window.targetCheck(e, this.elements.clearFilter)) {
+			this.clearAllTaxonomies();
+		} else if (window.targetCheck(e, '.remove-item')) {
+			this.handleRemoveSelectedTerm(e);
+		}
+	}
+
+	handleRemoveSelectedTerm(e) {
+		const selectedItem = e.target.closest('.selected-item');
+		if (!selectedItem) return;
+
+		const termId = parseInt(selectedItem.dataset.id);
+		const taxonomy = selectedItem.dataset.taxonomy;
+
+		// Remove from filters
+		if (this.taxonomyFilters[taxonomy]) {
+			this.taxonomyFilters[taxonomy] = this.taxonomyFilters[taxonomy]
+				.filter(id => id !== termId);
+
+			if (this.taxonomyFilters[taxonomy].length === 0) {
+				delete this.taxonomyFilters[taxonomy];
+			}
+		}
+
+		// Remove from UI
+		selectedItem.remove();
+
+		// Update filters
+		this.updateFilter({
+			taxonomy: Object.keys(this.taxonomyFilters).length > 0
+				? this.taxonomyFilters
+				: null,
+			page: 1
+		});
+	}
+
+	handleChange(e) {
+		let target = e.target;
+		if (Object.hasOwn(target.dataset, 'filter')) {
+			if (target.dataset.filter === 'content') {
+				this.updateContentFor(target.value);
+				this.updateFilter({ content: target.value, page: 1 });
+			} else if (target.dataset.filter === 'orderby') {
+				this.updateOrderDirectionVisibility(target.value);
+				this.updateFilter({ orderby: target.value, page: 1 });
+			} else if (target.dataset.filter === 'order') {
+				this.updateFilter({ order: target.value, page: 1 });
+			} else if (target.dataset.filter === 'match') {
+				this.updateFilter({ match: target.checked ? 'all' : 'any', page: 1 });
+			} else if (target.dataset.filter === 'favourites') {
+				this.updateFilter({ favourites: target.checked, page: 1 });
+			}
+		}
+	}
 }
-document.addEventListener('DOMContentLoaded', () => {
-	window.feedBlock = new FeedBlock();
+
+document.addEventListener('DOMContentLoaded', async function() {
+	window.auth.subscribe(event => {
+		if (event === 'auth-loaded') {
+			window.feedBlock = new FeedBlock();
+		}
+	});
 });

--
Gitblit v1.10.0