From f8ffc3dc1748b9af63123eb281696c0c30448715 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sun, 30 Aug 2026 03:43:48 +0000
Subject: [PATCH] =Meta overhaul, attempting to simplify. Maybe it did?

---
 assets/css/icons.css     |    2 
 inc/meta/Group.php       |   13 
 inc/meta/MetaOld.php     |  744 ++++++++++++++++++++++
 inc/meta/Meta.php        | 1145 +++++++++++++++-------------------
 inc/blocks/MenuBlock.php |   28 
 inc/meta/Repeater.php    |   12 
 6 files changed, 1,291 insertions(+), 653 deletions(-)

diff --git a/assets/css/icons.css b/assets/css/icons.css
index 834f0ae..998ce35 100644
--- a/assets/css/icons.css
+++ b/assets/css/icons.css
@@ -1 +1 @@
-.icon-google-logo{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjQsMTI4YTk2LDk2LDAsMSwxLTIxLjk1LTYxLjA5LDgsOCwwLDEsMS0xMi4zMywxMC4xOEE4MCw4MCwwLDEsMCwyMDcuNiwxMzZIMTI4YTgsOCwwLDAsMSwwLTE2aDg4QTgsOCwwLDAsMSwyMjQsMTI4WiIvPjwvc3ZnPg==');}.icon-apple-logo{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjMuMywxNjkuNTlhOC4wNyw4LjA3LDAsMCwwLTIuOC0zLjRDMjAzLjUzLDE1NC41MywyMDAsMTM0LjY0LDIwMCwxMjBjMC0xNy42NywxMy40Ny0zMy4wNiwyMS41LTQwLjY3YTgsOCwwLDAsMCwwLTExLjYyQzIwOC44Miw1NS43NCwxODcuODIsNDgsMTY4LDQ4YTcyLjIsNzIuMiwwLDAsMC00MCwxMi4xMyw3MS41Niw3MS41NiwwLDAsMC05MC43MSw5LjA5QTc0LjYzLDc0LjYzLDAsMCwwLDE2LDEyMy40YTEyNy4wNiwxMjcuMDYsMCwwLDAsNDAuMTQsODkuNzNBMzkuOCwzOS44LDAsMCwwLDgzLjU5LDIyNGg4Ny42OGEzOS44NCwzOS44NCwwLDAsMCwyOS4xMi0xMi41NywxMjUsMTI1LDAsMCwwLDE3LjgyLTI0LjZDMjI1LjIzLDE3NCwyMjQuMzMsMTcyLDIyMy4zLDE2OS41OVptLTM0LjYzLDMwLjk0YTIzLjc2LDIzLjc2LDAsMCwxLTE3LjQsNy40N0g4My41OWEyMy44MiwyMy44MiwwLDAsMS0xNi40NC02LjUxQTExMS4xNCwxMTEuMTQsMCwwLDEsMzIsMTIzLDU4LjUsNTguNSwwLDAsMSw0OC42NSw4MC40Nyw1NC44MSw1NC44MSwwLDAsMSw4OCw2NGguNzhBNTUuNDUsNTUuNDUsMCwwLDEsMTIzLDc2LjI4YTgsOCwwLDAsMCwxMCwwQTU1LjQ0LDU1LjQ0LDAsMCwxLDE2OCw2NGE3MC42NCw3MC42NCwwLDAsMSwzNiwxMC4zNWMtMTMsMTQuNTItMjAsMzAuNDctMjAsNDUuNjUsMCwyMy43Nyw3LjY0LDQyLjczLDIyLjE4LDU1LjNBMTA1LjgyLDEwNS44MiwwLDAsMSwxODguNjcsMjAwLjUzWk0xMjguMjMsMzBBNDAsNDAsMCwwLDEsMTY3LDBoMWE4LDgsMCwwLDEsMCwxNmgtMWEyNCwyNCwwLDAsMC0yMy4yNCwxOCw4LDgsMCwxLDEtMTUuNS00WiIvPjwvc3ZnPg==');}.icon-check-circle{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNzMuNjYsOTguMzRhOCw4LDAsMCwxLDAsMTEuMzJsLTU2LDU2YTgsOCwwLDAsMS0xMS4zMiwwbC0yNC0yNGE4LDgsMCwwLDEsMTEuMzItMTEuMzJMMTEyLDE0OC42OWw1MC4zNC01MC4zNUE4LDgsMCwwLDEsMTczLjY2LDk4LjM0Wk0yMzIsMTI4QTEwNCwxMDQsMCwxLDEsMTI4LDI0LDEwNC4xMSwxMDQuMTEsMCwwLDEsMjMyLDEyOFptLTE2LDBhODgsODgsMCwxLDAtODgsODhBODguMSw4OC4xLDAsMCwwLDIxNiwxMjhaIi8+PC9zdmc+');}details.all-filters summary::after,.icon-faders-horizontal{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNzYsODBhOCw4LDAsMCwxLDgtOGgzMmE4LDgsMCwwLDEsMCwxNkgxODRBOCw4LDAsMCwxLDE3Niw4MFpNNDAsODhIMTQ0djE2YTgsOCwwLDAsMCwxNiwwVjU2YTgsOCwwLDAsMC0xNiwwVjcySDQwYTgsOCwwLDAsMCwwLDE2Wm0xNzYsODBIMTIwYTgsOCwwLDAsMCwwLDE2aDk2YTgsOCwwLDAsMCwwLTE2Wk04OCwxNDRhOCw4LDAsMCwwLTgsOHYxNkg0MGE4LDgsMCwwLDAsMCwxNkg4MHYxNmE4LDgsMCwwLDAsMTYsMFYxNTJBOCw4LDAsMCwwLDg4LDE0NFoiLz48L3N2Zz4=');}.icon-cloud-slash{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik01My45MiwzNC42MkE4LDgsMCwxLDAsNDIuMDgsNDUuMzhMODEuMzIsODguNTVsLS4wNi4xMkE2NSw2NSwwLDAsMCw3Miw4OGE2NCw2NCwwLDAsMCwwLDEyOGg4OGE4Ny4zNCw4Ny4zNCwwLDAsMCwzMS44LTUuOTNsMTAuMjgsMTEuMzFhOCw4LDAsMSwwLDExLjg0LTEwLjc2Wk0xNjAsMjAwSDcyYTQ4LDQ4LDAsMCwxLDAtOTZjMS4xLDAsMi4yLDAsMy4zLjEyQTg4LjQsODguNCwwLDAsMCw3MiwxMjhhOCw4LDAsMCwwLDE2LDAsNzIuMjUsNzIuMjUsMCwwLDEsNS4wNi0yNi41NGw4Nyw5NS43QTcxLjY2LDcxLjY2LDAsMCwxLDE2MCwyMDBabTg4LTcyYTg3Ljg5LDg3Ljg5LDAsMCwxLTIyLjM1LDU4LjYxQTgsOCwwLDAsMSwyMTMuNzEsMTc2LDcyLDcyLDAsMCwwLDExNy4zNyw3MGE4LDgsMCwwLDEtOS40OC0xMi44OUE4OCw4OCwwLDAsMSwyNDgsMTI4WiIvPjwvc3ZnPg==');}.icon-exclamation-mark{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNDQsMjAwYTE2LDE2LDAsMSwxLTE2LTE2QTE2LDE2LDAsMCwxLDE0NCwyMDBabS0xNi00MGE4LDgsMCwwLDAsOC04VjQ4YTgsOCwwLDAsMC0xNiwwVjE1MkE4LDgsMCwwLDAsMTI4LDE2MFoiLz48L3N2Zz4=');}.icon-cloud-arrow-down{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yNDgsMTI4YTg3LjM0LDg3LjM0LDAsMCwxLTE3LjYsNTIuODEsOCw4LDAsMSwxLTEyLjgtOS42MkE3MS4zNCw3MS4zNCwwLDAsMCwyMzIsMTI4YTcyLDcyLDAsMCwwLTE0NCwwLDgsOCwwLDAsMS0xNiwwLDg4LDg4LDAsMCwxLDMuMjktMjMuODhDNzQuMiwxMDQsNzMuMSwxMDQsNzIsMTA0YTQ4LDQ4LDAsMCwwLDAsOTZIOTZhOCw4LDAsMCwxLDAsMTZINzJBNjQsNjQsMCwxLDEsODEuMjksODguNjgsODgsODgsMCwwLDEsMjQ4LDEyOFptLTY5LjY2LDQyLjM0TDE2MCwxODguNjlWMTI4YTgsOCwwLDAsMC0xNiwwdjYwLjY5bC0xOC4zNC0xOC4zNWE4LDgsMCwwLDAtMTEuMzIsMTEuMzJsMzIsMzJhOCw4LDAsMCwwLDExLjMyLDBsMzItMzJhOCw4LDAsMCwwLTExLjMyLTExLjMyWiIvPjwvc3ZnPg==');}details summary::after,.icon-caret-down{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTMuNjYsMTAxLjY2bC04MCw4MGE4LDgsMCwwLDEtMTEuMzIsMGwtODAtODBBOCw4LDAsMCwxLDUzLjY2LDkwLjM0TDEyOCwxNjQuNjlsNzQuMzQtNzQuMzVhOCw4LDAsMCwxLDExLjMyLDExLjMyWiIvPjwvc3ZnPg==');}.icon-cloud-arrow-up{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNzguMzQsMTY1LjY2LDE2MCwxNDcuMzFWMjA4YTgsOCwwLDAsMS0xNiwwVjE0Ny4zMWwtMTguMzQsMTguMzVhOCw4LDAsMCwxLTExLjMyLTExLjMybDMyLTMyYTgsOCwwLDAsMSwxMS4zMiwwbDMyLDMyYTgsOCwwLDAsMS0xMS4zMiwxMS4zMlpNMTYwLDQwQTg4LjA4LDg4LjA4LDAsMCwwLDgxLjI5LDg4LjY4LDY0LDY0LDAsMSwwLDcyLDIxNmg0MGE4LDgsMCwwLDAsMC0xNkg3MmE0OCw0OCwwLDAsMSwwLTk2YzEuMSwwLDIuMiwwLDMuMjkuMTJBODgsODgsMCwwLDAsNzIsMTI4YTgsOCwwLDAsMCwxNiwwLDcyLDcyLDAsMSwxLDEwMC44LDY2LDgsOCwwLDAsMCwzLjIsMTUuMzQsNy45LDcuOSwwLDAsMCwzLjItLjY4QTg4LDg4LDAsMCwwLDE2MCw0MFoiLz48L3N2Zz4=');}.icon-cloud-check{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjAsNDBBODguMDksODguMDksMCwwLDAsODEuMjksODguNjcsNjQsNjQsMCwxLDAsNzIsMjE2aDg4YTg4LDg4LDAsMCwwLDAtMTc2Wm0wLDE2MEg3MmE0OCw0OCwwLDAsMSwwLTk2YzEuMSwwLDIuMiwwLDMuMjkuMTFBODgsODgsMCwwLDAsNzIsMTI4YTgsOCwwLDAsMCwxNiwwLDcyLDcyLDAsMSwxLDcyLDcyWm0zNy42Ni05My42NmE4LDgsMCwwLDEsMCwxMS4zMmwtNDgsNDhhOCw4LDAsMCwxLTExLjMyLDBsLTI0LTI0YTgsOCwwLDAsMSwxMS4zMi0xMS4zMkwxNDQsMTQ4LjY5bDQyLjM0LTQyLjM1QTgsOCwwLDAsMSwxOTcuNjYsMTA2LjM0WiIvPjwvc3ZnPg==');}.icon-cloud-warning{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjAsNDBBODguMDksODguMDksMCwwLDAsODEuMjksODguNjcsNjQsNjQsMCwxLDAsNzIsMjE2aDg4YTg4LDg4LDAsMCwwLDAtMTc2Wm0wLDE2MEg3MmE0OCw0OCwwLDAsMSwwLTk2YzEuMSwwLDIuMiwwLDMuMjkuMTFBODgsODgsMCwwLDAsNzIsMTI4YTgsOCwwLDAsMCwxNiwwLDcyLDcyLDAsMSwxLDcyLDcyWm0tOC03MlY4OGE4LDgsMCwwLDEsMTYsMHY0MGE4LDgsMCwwLDEtMTYsMFptMjAsMzZhMTIsMTIsMCwxLDEtMTItMTJBMTIsMTIsMCwwLDEsMTcyLDE2NFoiLz48L3N2Zz4=');}.icon-syncing{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0iY3VycmVudENvbG9yIiB2aWV3Qm94PSIwIDAgMjU2IDI1NiI+PHBhdGggaWQ9InJlZnJlc2giIGQ9Ik0xNjAuMDQ3IDEyMi44NzVhMzAuNzg0IDMwLjc4NCAwIDAgMC0yMS43NSA4Ljc5N2MtMi44NDIgMy4wMDMtLjQ2NyA0Ljk3MSAxLjMxMiAzLjE1NiAxMS4wNDMtMTAuNzg2IDI4LjcxLTEwLjY4IDM5LjYyNS4yMzRsNy4yMDMgNy4yMDRoLTEyLjg3NWMtMy4zNDcuMDA4LTMuMTY1IDMuODc1IDAgMy44NzVoMTYuMTFjMi4wNjIgMCAyLjU0LTEuNDE4IDIuNTYyLTQuOTdsLjA5NC0xNC45MjFjLjAyLTMuMjktMy40MzctMy4xNjUtMy40MzcgMHYxMi44NmwtNy4yMDMtNy4xODhhMzAuNzY4IDMwLjc2OCAwIDAgMC0yMS42NDEtOS4wNDd6bS0yOS41OTQgMzkuNzk3Yy0yLjA2MiAwLTIuNTI0IDEuNDAyLTIuNTQ3IDQuOTUzbC0uMDk0IDE0LjkyMmMtLjAyIDMuMjkgMy40MjIgMy4xNjQgMy40MjIgMHYtMTIuODZsNy4yMDMgNy4yMDRjMTEuOTU2IDExLjk1NSAzMS4zMTIgMTIuMDY0IDQzLjQwNy4yNSAyLjg0Mi0zLjAwMy40NTEtNC45ODgtMS4zMjgtMy4xNzItMTEuMDQzIDEwLjc4Ni0yOC43MSAxMC42OC0zOS42MjUtLjIzNWwtNy4xODgtNy4yMDNoMTIuODZjMy4zNDctLjAwOCAzLjE2NS0zLjg2IDAtMy44NmgtMTYuMTF6Ii8+PHBhdGggZD0iTTE2MCA0NGE4NC4xMSA4NC4xMSAwIDAgMC03Ni40MSA0OS4xMkE2MC43MSA2MC43MSAwIDAgMCA3MiA5MmE2MCA2MCAwIDAgMCAwIDEyMGg4OGE4NCA4NCAwIDAgMCAwLTE2OFptMCAxNjBINzJhNTIgNTIgMCAxIDEgOC41NS0xMDMuM0E4My42NiA4My42NiAwIDAgMCA3NiAxMjhhNCA0IDAgMCAwIDggMCA3NiA3NiAwIDEgMSA3NiA3NloiLz48L3N2Zz4=');}.icon-cloud-x{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjAsNDBBODguMDksODguMDksMCwwLDAsODEuMjksODguNjcsNjQsNjQsMCwxLDAsNzIsMjE2aDg4YTg4LDg4LDAsMCwwLDAtMTc2Wm0wLDE2MEg3MmE0OCw0OCwwLDAsMSwwLTk2YzEuMSwwLDIuMiwwLDMuMjkuMTFBODgsODgsMCwwLDAsNzIsMTI4YTgsOCwwLDAsMCwxNiwwLDcyLDcyLDAsMSwxLDcyLDcyWm0yOS42Ni04Mi4zNEwxNzEuMzEsMTM2bDE4LjM1LDE4LjM0YTgsOCwwLDAsMS0xMS4zMiwxMS4zMkwxNjAsMTQ3LjMxbC0xOC4zNCwxOC4zNWE4LDgsMCwwLDEtMTEuMzItMTEuMzJMMTQ4LjY5LDEzNmwtMTguMzUtMTguMzRhOCw4LDAsMCwxLDExLjMyLTExLjMyTDE2MCwxMjQuNjlsMTguMzQtMTguMzVhOCw4LDAsMCwxLDExLjMyLDExLjMyWiIvPjwvc3ZnPg==');}.icon-arrows-clockwise{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjQsNDhWOTZhOCw4LDAsMCwxLTgsOEgxNjhhOCw4LDAsMCwxLDAtMTZoMjguNjlMMTgyLjA2LDczLjM3YTc5LjU2LDc5LjU2LDAsMCwwLTU2LjEzLTIzLjQzaC0uNDVBNzkuNTIsNzkuNTIsMCwwLDAsNjkuNTksNzIuNzEsOCw4LDAsMCwxLDU4LjQxLDYxLjI3YTk2LDk2LDAsMCwxLDEzNSwuNzlMMjA4LDc2LjY5VjQ4YTgsOCwwLDAsMSwxNiwwWk0xODYuNDEsMTgzLjI5YTgwLDgwLDAsMCwxLTExMi40Ny0uNjZMNTkuMzEsMTY4SDg4YTgsOCwwLDAsMCwwLTE2SDQwYTgsOCwwLDAsMC04LDh2NDhhOCw4LDAsMCwwLDE2LDBWMTc5LjMxbDE0LjYzLDE0LjYzQTk1LjQzLDk1LjQzLDAsMCwwLDEzMCwyMjIuMDZoLjUzYTk1LjM2LDk1LjM2LDAsMCwwLDY3LjA3LTI3LjMzLDgsOCwwLDAsMC0xMS4xOC0xMS40NFoiLz48L3N2Zz4=');}.icon-share-fat{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzcuNjYsMTA2LjM1bC04MC04MEE4LDgsMCwwLDAsMTQ0LDMyVjcyLjM1Yy0yNS45NCwyLjIyLTU0LjU5LDE0LjkyLTc4LjE2LDM0LjkxLTI4LjM4LDI0LjA4LTQ2LjA1LDU1LjExLTQ5Ljc2LDg3LjM3YTEyLDEyLDAsMCwwLDIwLjY4LDkuNThoMGMxMS0xMS43MSw1MC4xNC00OC43NCwxMDcuMjQtNTJWMTkyYTgsOCwwLDAsMCwxMy42Niw1LjY1bDgwLTgwQTgsOCwwLDAsMCwyMzcuNjYsMTA2LjM1Wk0xNjAsMTcyLjY5VjE0NGE4LDgsMCwwLDAtOC04Yy0yOC4wOCwwLTU1LjQzLDcuMzMtODEuMjksMjEuOGExOTYuMTcsMTk2LjE3LDAsMCwwLTM2LjU3LDI2LjUyYzUuOC0yMy44NCwyMC40Mi00Ni41MSw0Mi4wNS02NC44NkM5OS40MSw5OS43NywxMjcuNzUsODgsMTUyLDg4YTgsOCwwLDAsMCw4LThWNTEuMzJMMjIwLjY5LDExMloiLz48L3N2Zz4=');}.icon-trash{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTYsNDhIMTc2VjQwYTI0LDI0LDAsMCwwLTI0LTI0SDEwNEEyNCwyNCwwLDAsMCw4MCw0MHY4SDQwYTgsOCwwLDAsMCwwLDE2aDhWMjA4YTE2LDE2LDAsMCwwLDE2LDE2SDE5MmExNiwxNiwwLDAsMCwxNi0xNlY2NGg4YTgsOCwwLDAsMCwwLTE2Wk05Niw0MGE4LDgsMCwwLDEsOC04aDQ4YTgsOCwwLDAsMSw4LDh2OEg5NlptOTYsMTY4SDY0VjY0SDE5MlpNMTEyLDEwNHY2NGE4LDgsMCwwLDEtMTYsMFYxMDRhOCw4LDAsMCwxLDE2LDBabTQ4LDB2NjRhOCw4LDAsMCwxLTE2LDBWMTA0YTgsOCwwLDAsMSwxNiwwWiIvPjwvc3ZnPg==');}.icon-star{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzkuMTgsOTcuMjZBMTYuMzgsMTYuMzgsMCwwLDAsMjI0LjkyLDg2bC01OS00Ljc2TDE0My4xNCwyNi4xNWExNi4zNiwxNi4zNiwwLDAsMC0zMC4yNywwTDkwLjExLDgxLjIzLDMxLjA4LDg2YTE2LjQ2LDE2LjQ2LDAsMCwwLTkuMzcsMjguODZsNDUsMzguODNMNTMsMjExLjc1YTE2LjM4LDE2LjM4LDAsMCwwLDI0LjUsMTcuODJMMTI4LDE5OC40OWw1MC41MywzMS4wOEExNi40LDE2LjQsMCwwLDAsMjAzLDIxMS43NWwtMTMuNzYtNTguMDcsNDUtMzguODNBMTYuNDMsMTYuNDMsMCwwLDAsMjM5LjE4LDk3LjI2Wm0tMTUuMzQsNS40Ny00OC43LDQyYTgsOCwwLDAsMC0yLjU2LDcuOTFsMTQuODgsNjIuOGEuMzcuMzcsMCwwLDEtLjE3LjQ4Yy0uMTguMTQtLjIzLjExLS4zOCwwbC01NC43Mi0zMy42NWE4LDgsMCwwLDAtOC4zOCwwTDY5LjA5LDIxNS45NGMtLjE1LjA5LS4xOS4xMi0uMzgsMGEuMzcuMzcsMCwwLDEtLjE3LS40OGwxNC44OC02Mi44YTgsOCwwLDAsMC0yLjU2LTcuOTFsLTQ4LjctNDJjLS4xMi0uMS0uMjMtLjE5LS4xMy0uNXMuMTgtLjI3LjMzLS4yOWw2My45Mi01LjE2QTgsOCwwLDAsMCwxMDMsOTEuODZsMjQuNjItNTkuNjFjLjA4LS4xNy4xMS0uMjUuMzUtLjI1cy4yNy4wOC4zNS4yNUwxNTMsOTEuODZhOCw4LDAsMCwwLDYuNzUsNC45Mmw2My45Miw1LjE2Yy4xNSwwLC4yNCwwLC4zMy4yOVMyMjQsMTAyLjYzLDIyMy44NCwxMDIuNzNaIi8+PC9zdmc+');}.icon-alphabetical{--icon:url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIGZpbGw9ImN1cnJlbnRDb2xvciIgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSIwIDAgMTgzLjc4IDE4NC4wNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNTkuNTg2IDY5Ljc0MmMtMC44NTEzIDAtMS40NjEgMC4xOTY1Ni0xLjgzNjYgMC41OTcxOC0wLjM1MDU0IDAuMzc1NTgtMC41Mjk1OCAxLjAyMjktMC41Mjk1OCAxLjk0OTNzMC4xNzkwMyAxLjU5MzcgMC41Mjk1OCAxLjk5NDRjMC4zNzU1OCAwLjM3NTU4IDAuOTg1MjkgMC41NjMzOCAxLjgzNjYgMC41NjMzOGg3LjAxOTdsLTEyLjQyOCAzNC4zNjZoLTIuMTA3Yy0wLjg1MTMgMC0xLjQ2MSAwLjE5NjU2LTEuODM2NiAwLjU5NzE4LTAuMzUwNTQgMC4zNzU1OC0wLjUyOTU3IDEuMDM0MS0wLjUyOTU3IDEuOTYwNiAwIDAuOTI2NDQgMC4xNzkwMyAxLjU4MjUgMC41Mjk1NyAxLjk4MyAwLjM3NTU4IDAuMzc1NTkgMC45ODUyOSAwLjU2MzM4IDEuODM2NiAwLjU2MzM4aDEyLjU1MmMwLjg1MTMgMCAxLjQ1MjItMC4xODc3OSAxLjgwMjgtMC41NjMzOCAwLjM3NTU4LTAuNDAwNjIgMC41NjMzNy0xLjA1NjYgMC41NjMzNy0xLjk4MyAwLTAuOTI2NDUtMC4xODc3OS0xLjU4NS0wLjU2MzM3LTEuOTYwNi0wLjM1MDU0LTAuNDAwNjItMC45NTE0Ny0wLjU5NzE4LTEuODAyOC0wLjU5NzE4aC00LjU1MjFsMy4xMjExLTguOTM0OWgxOC4yMmwzLjA3NiA4LjkzNDloLTUuMDcwNGMtMC44NTEzIDAtMS40NjEgMC4xOTY1Ni0xLjgzNjYgMC41OTcxOC0wLjM1MDU0IDAuMzc1NTgtMC41Mjk1OCAxLjAzNDEtMC41Mjk1OCAxLjk2MDYgMCAwLjkyNjQ0IDAuMTc5MDMgMS41ODI1IDAuNTI5NTggMS45ODMgMC4zNzU1OCAwLjM3NTU5IDAuOTg1MjkgMC41NjMzOCAxLjgzNjYgMC41NjMzOGgxMy4yOTZjMC44NTEzIDAgMS40NTIyLTAuMTg3NzkgMS44MDI4LTAuNTYzMzggMC4zNzU1OC0wLjQwMDYyIDAuNTYzMzctMS4wNTY2IDAuNTYzMzctMS45ODMgMC0wLjkyNjQ1LTAuMTg3NzktMS41ODUtMC41NjMzNy0xLjk2MDYtMC4zNTA1NC0wLjQwMDYyLTAuOTUxNDctMC41OTcxOC0xLjgwMjgtMC41OTcxOGgtMi4yODczbC0xMy4yNjItMzcuMDM2Yy0wLjMwMDQ3LTAuODUxMy0wLjc1OTk0LTEuNDYxLTEuMzg1OS0xLjgzNjYtMC42MDA5My0wLjQwMDYyLTEuNDA5Ny0wLjU5NzE4LTIuNDExMy0wLjU5NzE4em00NC4xNDYgMGMtMC44NTEzIDAtMS40NzIzIDAuMTk2NTYtMS44NDc4IDAuNTk3MTgtMC4zNTA1NSAwLjM3NTU4LTAuNTE4MyAxLjAyMjktMC41MTgzIDEuOTQ5M3YxMS45MWMwIDAuODc2MzMgMC4yMDUzMiAxLjUwNjEgMC42MzA5OCAxLjg4MTcgMC40MjU2NiAwLjM3NTU4IDEuMTU5MyAwLjU2MzM3IDIuMTg1OSAwLjU2MzM3czEuNzQ5LTAuMTg3NzkgMi4xNzQ3LTAuNTYzMzdjMC40MjU2OS0wLjM3NTU4IDAuNjQyMjYtMS4wMDUzIDAuNjQyMjYtMS44ODE3di05LjM1MTdoMTguODUxbC0yNC43NTQgMzUuMzAxYy0wLjM1MDU0IDAuNTI1ODItMC41MTgzMSAxLjA3MTctMC41MTgzMSAxLjYyMjYgMCAwLjkyNjQ1IDAuMTY3NzcgMS41ODI1IDAuNTE4MzEgMS45ODMxIDAuMzc1NTggMC4zNzU1OCAwLjk5NjU0IDAuNTYzMzggMS44NDc4IDAuNTYzMzhoMjguNzY2YzAuODUxMyAwIDEuNDUyMi0wLjE4NzggMS44MDI4LTAuNTYzMzggMC4zNzU1OC0wLjQwMDYyIDAuNTYzMzgtMS4wNTY2IDAuNTYzMzgtMS45ODMxdi0xMi42NjVjMC0wLjg3NjMzLTAuMjE2NTgtMS40OTQ4LTAuNjQyMjUtMS44NzA0LTAuNDI1NjYtMC4zNzU1OC0xLjE0OC0wLjU2MzM4LTIuMTc0Ny0wLjU2MzM4LTEuMDI2NiAwLTEuNzQ5IDAuMTg3NzktMi4xNzQ3IDAuNTYzMzgtMC40MjU2NiAwLjM3NTU4LTAuNjQyMjQgMC45OTQwMi0wLjY0MjI0IDEuODcwNHYxMC4xMDdoLTE5Ljk3OGwyNC45MDEtMzUuNDU5YzAuMjUwMzktMC4zNTA1NCAwLjM3MTgzLTAuODM4ODMgMC4zNzE4My0xLjQ2NDggMC0wLjkyNjQ1LTAuMTg3OC0xLjU3MzctMC41NjMzOC0xLjk0OTMtMC4zNTA1NS0wLjQwMDYyLTAuOTUxNDctMC41OTcxOC0xLjgwMjgtMC41OTcxOHptLTMxLjc1MiA1LjEwNDJoMC43MDk4NWw2Ljk4NTkgMjAuMzE1aC0xNC43MTZ6bS0zNy43MjMtNDkuMTgzYy00LjczNDIgMC04LjYzMTMgMy44OTctOC42MzEzIDguNjMxM3YxMTUuNDdjMCA0LjczNDIgMy44OTcgOC42MzEzIDguNjMxMyA4LjYzMTNoMTE1LjI2YzQuNzM0MiAwIDguNjQyMS0zLjg5NyA4LjY0MjEtOC42MzEzdi0xMTUuNDdjMC00LjczNDItMy45MDgyLTguNjMxMy04LjY0MjEtOC42MzEzem0wIDUuNzI0aDExNS4yNmMxLjY1OCAwIDIuOTA3IDEuMjQ5MSAyLjkwNyAyLjkwNzF2MTE1LjQ3YzAgMS42NTgtMS4yNDkxIDIuOTA3LTIuOTA3IDIuOTA3aC0xMTUuMjZjLTEuNjU4IDAtMi44OTU4LTEuMjQ5MS0yLjg5NTgtMi45MDd2LTExNS40N2MwLTEuNjU4IDEuMjM3OC0yLjkwNzEgMi44OTU4LTIuOTA3MXoiIGZpbGw9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIuNzIxMTQiLz48L3N2Zz4=');}.icon-star-half-fi{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzkuMTgsOTcuMjZBMTYuMzgsMTYuMzgsMCwwLDAsMjI0LjkyLDg2bC01OS00Ljc2TDE0My4xNCwyNi4xNWExNi4zNiwxNi4zNiwwLDAsMC0zMC4yNywwTDkwLjExLDgxLjIzLDMxLjA4LDg2YTE2LjQ2LDE2LjQ2LDAsMCwwLTkuMzcsMjguODZsNDUsMzguODNMNTMsMjExLjc1YTE2LjQsMTYuNCwwLDAsMCwyNC41LDE3LjgyTDEyOCwxOTguNDlsNTAuNTMsMzEuMDhBMTYuNCwxNi40LDAsMCwwLDIwMywyMTEuNzVsLTEzLjc2LTU4LjA3LDQ1LTM4LjgzQTE2LjQzLDE2LjQzLDAsMCwwLDIzOS4xOCw5Ny4yNlptLTE1LjM0LDUuNDctNDguNyw0MmE4LDgsMCwwLDAtMi41Niw3LjkxbDE0Ljg4LDYyLjhhLjM3LjM3LDAsMCwxLS4xNy40OGMtLjE4LjE0LS4yMy4xMS0uMzgsMGwtNTQuNzItMzMuNjVBOCw4LDAsMCwwLDEyOCwxODEuMVYzMmMuMjQsMCwuMjcuMDguMzUuMjZMMTUzLDkxLjg2YTgsOCwwLDAsMCw2Ljc1LDQuOTJsNjMuOTEsNS4xNmMuMTYsMCwuMjUsMCwuMzQuMjlTMjI0LDEwMi42MywyMjMuODQsMTAyLjczWiIvPjwvc3ZnPg==');}.icon-star-fi{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzQuMjksMTE0Ljg1bC00NSwzOC44M0wyMDMsMjExLjc1YTE2LjQsMTYuNCwwLDAsMS0yNC41LDE3LjgyTDEyOCwxOTguNDksNzcuNDcsMjI5LjU3QTE2LjQsMTYuNCwwLDAsMSw1MywyMTEuNzVsMTMuNzYtNTguMDctNDUtMzguODNBMTYuNDYsMTYuNDYsMCwwLDEsMzEuMDgsODZsNTktNC43NiwyMi43Ni01NS4wOGExNi4zNiwxNi4zNiwwLDAsMSwzMC4yNywwbDIyLjc1LDU1LjA4LDU5LDQuNzZhMTYuNDYsMTYuNDYsMCwwLDEsOS4zNywyOC44NloiLz48L3N2Zz4=');}
\ No newline at end of file
+.icon-google-logo{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjQsMTI4YTk2LDk2LDAsMSwxLTIxLjk1LTYxLjA5LDgsOCwwLDEsMS0xMi4zMywxMC4xOEE4MCw4MCwwLDEsMCwyMDcuNiwxMzZIMTI4YTgsOCwwLDAsMSwwLTE2aDg4QTgsOCwwLDAsMSwyMjQsMTI4WiIvPjwvc3ZnPg==');}.icon-apple-logo{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjMuMywxNjkuNTlhOC4wNyw4LjA3LDAsMCwwLTIuOC0zLjRDMjAzLjUzLDE1NC41MywyMDAsMTM0LjY0LDIwMCwxMjBjMC0xNy42NywxMy40Ny0zMy4wNiwyMS41LTQwLjY3YTgsOCwwLDAsMCwwLTExLjYyQzIwOC44Miw1NS43NCwxODcuODIsNDgsMTY4LDQ4YTcyLjIsNzIuMiwwLDAsMC00MCwxMi4xMyw3MS41Niw3MS41NiwwLDAsMC05MC43MSw5LjA5QTc0LjYzLDc0LjYzLDAsMCwwLDE2LDEyMy40YTEyNy4wNiwxMjcuMDYsMCwwLDAsNDAuMTQsODkuNzNBMzkuOCwzOS44LDAsMCwwLDgzLjU5LDIyNGg4Ny42OGEzOS44NCwzOS44NCwwLDAsMCwyOS4xMi0xMi41NywxMjUsMTI1LDAsMCwwLDE3LjgyLTI0LjZDMjI1LjIzLDE3NCwyMjQuMzMsMTcyLDIyMy4zLDE2OS41OVptLTM0LjYzLDMwLjk0YTIzLjc2LDIzLjc2LDAsMCwxLTE3LjQsNy40N0g4My41OWEyMy44MiwyMy44MiwwLDAsMS0xNi40NC02LjUxQTExMS4xNCwxMTEuMTQsMCwwLDEsMzIsMTIzLDU4LjUsNTguNSwwLDAsMSw0OC42NSw4MC40Nyw1NC44MSw1NC44MSwwLDAsMSw4OCw2NGguNzhBNTUuNDUsNTUuNDUsMCwwLDEsMTIzLDc2LjI4YTgsOCwwLDAsMCwxMCwwQTU1LjQ0LDU1LjQ0LDAsMCwxLDE2OCw2NGE3MC42NCw3MC42NCwwLDAsMSwzNiwxMC4zNWMtMTMsMTQuNTItMjAsMzAuNDctMjAsNDUuNjUsMCwyMy43Nyw3LjY0LDQyLjczLDIyLjE4LDU1LjNBMTA1LjgyLDEwNS44MiwwLDAsMSwxODguNjcsMjAwLjUzWk0xMjguMjMsMzBBNDAsNDAsMCwwLDEsMTY3LDBoMWE4LDgsMCwwLDEsMCwxNmgtMWEyNCwyNCwwLDAsMC0yMy4yNCwxOCw4LDgsMCwxLDEtMTUuNS00WiIvPjwvc3ZnPg==');}.icon-check-circle{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNzMuNjYsOTguMzRhOCw4LDAsMCwxLDAsMTEuMzJsLTU2LDU2YTgsOCwwLDAsMS0xMS4zMiwwbC0yNC0yNGE4LDgsMCwwLDEsMTEuMzItMTEuMzJMMTEyLDE0OC42OWw1MC4zNC01MC4zNUE4LDgsMCwwLDEsMTczLjY2LDk4LjM0Wk0yMzIsMTI4QTEwNCwxMDQsMCwxLDEsMTI4LDI0LDEwNC4xMSwxMDQuMTEsMCwwLDEsMjMyLDEyOFptLTE2LDBhODgsODgsMCwxLDAtODgsODhBODguMSw4OC4xLDAsMCwwLDIxNiwxMjhaIi8+PC9zdmc+');}details.all-filters summary::after,.icon-faders-horizontal{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNzYsODBhOCw4LDAsMCwxLDgtOGgzMmE4LDgsMCwwLDEsMCwxNkgxODRBOCw4LDAsMCwxLDE3Niw4MFpNNDAsODhIMTQ0djE2YTgsOCwwLDAsMCwxNiwwVjU2YTgsOCwwLDAsMC0xNiwwVjcySDQwYTgsOCwwLDAsMCwwLDE2Wm0xNzYsODBIMTIwYTgsOCwwLDAsMCwwLDE2aDk2YTgsOCwwLDAsMCwwLTE2Wk04OCwxNDRhOCw4LDAsMCwwLTgsOHYxNkg0MGE4LDgsMCwwLDAsMCwxNkg4MHYxNmE4LDgsMCwwLDAsMTYsMFYxNTJBOCw4LDAsMCwwLDg4LDE0NFoiLz48L3N2Zz4=');}.icon-cloud-slash{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik01My45MiwzNC42MkE4LDgsMCwxLDAsNDIuMDgsNDUuMzhMODEuMzIsODguNTVsLS4wNi4xMkE2NSw2NSwwLDAsMCw3Miw4OGE2NCw2NCwwLDAsMCwwLDEyOGg4OGE4Ny4zNCw4Ny4zNCwwLDAsMCwzMS44LTUuOTNsMTAuMjgsMTEuMzFhOCw4LDAsMSwwLDExLjg0LTEwLjc2Wk0xNjAsMjAwSDcyYTQ4LDQ4LDAsMCwxLDAtOTZjMS4xLDAsMi4yLDAsMy4zLjEyQTg4LjQsODguNCwwLDAsMCw3MiwxMjhhOCw4LDAsMCwwLDE2LDAsNzIuMjUsNzIuMjUsMCwwLDEsNS4wNi0yNi41NGw4Nyw5NS43QTcxLjY2LDcxLjY2LDAsMCwxLDE2MCwyMDBabTg4LTcyYTg3Ljg5LDg3Ljg5LDAsMCwxLTIyLjM1LDU4LjYxQTgsOCwwLDAsMSwyMTMuNzEsMTc2LDcyLDcyLDAsMCwwLDExNy4zNyw3MGE4LDgsMCwwLDEtOS40OC0xMi44OUE4OCw4OCwwLDAsMSwyNDgsMTI4WiIvPjwvc3ZnPg==');}.icon-exclamation-mark{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNDQsMjAwYTE2LDE2LDAsMSwxLTE2LTE2QTE2LDE2LDAsMCwxLDE0NCwyMDBabS0xNi00MGE4LDgsMCwwLDAsOC04VjQ4YTgsOCwwLDAsMC0xNiwwVjE1MkE4LDgsMCwwLDAsMTI4LDE2MFoiLz48L3N2Zz4=');}.icon-cloud-arrow-down{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yNDgsMTI4YTg3LjM0LDg3LjM0LDAsMCwxLTE3LjYsNTIuODEsOCw4LDAsMSwxLTEyLjgtOS42MkE3MS4zNCw3MS4zNCwwLDAsMCwyMzIsMTI4YTcyLDcyLDAsMCwwLTE0NCwwLDgsOCwwLDAsMS0xNiwwLDg4LDg4LDAsMCwxLDMuMjktMjMuODhDNzQuMiwxMDQsNzMuMSwxMDQsNzIsMTA0YTQ4LDQ4LDAsMCwwLDAsOTZIOTZhOCw4LDAsMCwxLDAsMTZINzJBNjQsNjQsMCwxLDEsODEuMjksODguNjgsODgsODgsMCwwLDEsMjQ4LDEyOFptLTY5LjY2LDQyLjM0TDE2MCwxODguNjlWMTI4YTgsOCwwLDAsMC0xNiwwdjYwLjY5bC0xOC4zNC0xOC4zNWE4LDgsMCwwLDAtMTEuMzIsMTEuMzJsMzIsMzJhOCw4LDAsMCwwLDExLjMyLDBsMzItMzJhOCw4LDAsMCwwLTExLjMyLTExLjMyWiIvPjwvc3ZnPg==');}details summary::after,.icon-caret-down{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTMuNjYsMTAxLjY2bC04MCw4MGE4LDgsMCwwLDEtMTEuMzIsMGwtODAtODBBOCw4LDAsMCwxLDUzLjY2LDkwLjM0TDEyOCwxNjQuNjlsNzQuMzQtNzQuMzVhOCw4LDAsMCwxLDExLjMyLDExLjMyWiIvPjwvc3ZnPg==');}.icon-cloud-arrow-up{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNzguMzQsMTY1LjY2LDE2MCwxNDcuMzFWMjA4YTgsOCwwLDAsMS0xNiwwVjE0Ny4zMWwtMTguMzQsMTguMzVhOCw4LDAsMCwxLTExLjMyLTExLjMybDMyLTMyYTgsOCwwLDAsMSwxMS4zMiwwbDMyLDMyYTgsOCwwLDAsMS0xMS4zMiwxMS4zMlpNMTYwLDQwQTg4LjA4LDg4LjA4LDAsMCwwLDgxLjI5LDg4LjY4LDY0LDY0LDAsMSwwLDcyLDIxNmg0MGE4LDgsMCwwLDAsMC0xNkg3MmE0OCw0OCwwLDAsMSwwLTk2YzEuMSwwLDIuMiwwLDMuMjkuMTJBODgsODgsMCwwLDAsNzIsMTI4YTgsOCwwLDAsMCwxNiwwLDcyLDcyLDAsMSwxLDEwMC44LDY2LDgsOCwwLDAsMCwzLjIsMTUuMzQsNy45LDcuOSwwLDAsMCwzLjItLjY4QTg4LDg4LDAsMCwwLDE2MCw0MFoiLz48L3N2Zz4=');}.icon-cloud-check{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjAsNDBBODguMDksODguMDksMCwwLDAsODEuMjksODguNjcsNjQsNjQsMCwxLDAsNzIsMjE2aDg4YTg4LDg4LDAsMCwwLDAtMTc2Wm0wLDE2MEg3MmE0OCw0OCwwLDAsMSwwLTk2YzEuMSwwLDIuMiwwLDMuMjkuMTFBODgsODgsMCwwLDAsNzIsMTI4YTgsOCwwLDAsMCwxNiwwLDcyLDcyLDAsMSwxLDcyLDcyWm0zNy42Ni05My42NmE4LDgsMCwwLDEsMCwxMS4zMmwtNDgsNDhhOCw4LDAsMCwxLTExLjMyLDBsLTI0LTI0YTgsOCwwLDAsMSwxMS4zMi0xMS4zMkwxNDQsMTQ4LjY5bDQyLjM0LTQyLjM1QTgsOCwwLDAsMSwxOTcuNjYsMTA2LjM0WiIvPjwvc3ZnPg==');}.icon-cloud-warning{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjAsNDBBODguMDksODguMDksMCwwLDAsODEuMjksODguNjcsNjQsNjQsMCwxLDAsNzIsMjE2aDg4YTg4LDg4LDAsMCwwLDAtMTc2Wm0wLDE2MEg3MmE0OCw0OCwwLDAsMSwwLTk2YzEuMSwwLDIuMiwwLDMuMjkuMTFBODgsODgsMCwwLDAsNzIsMTI4YTgsOCwwLDAsMCwxNiwwLDcyLDcyLDAsMSwxLDcyLDcyWm0tOC03MlY4OGE4LDgsMCwwLDEsMTYsMHY0MGE4LDgsMCwwLDEtMTYsMFptMjAsMzZhMTIsMTIsMCwxLDEtMTItMTJBMTIsMTIsMCwwLDEsMTcyLDE2NFoiLz48L3N2Zz4=');}.icon-syncing{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0iY3VycmVudENvbG9yIiB2aWV3Qm94PSIwIDAgMjU2IDI1NiI+PHBhdGggaWQ9InJlZnJlc2giIGQ9Ik0xNjAuMDQ3IDEyMi44NzVhMzAuNzg0IDMwLjc4NCAwIDAgMC0yMS43NSA4Ljc5N2MtMi44NDIgMy4wMDMtLjQ2NyA0Ljk3MSAxLjMxMiAzLjE1NiAxMS4wNDMtMTAuNzg2IDI4LjcxLTEwLjY4IDM5LjYyNS4yMzRsNy4yMDMgNy4yMDRoLTEyLjg3NWMtMy4zNDcuMDA4LTMuMTY1IDMuODc1IDAgMy44NzVoMTYuMTFjMi4wNjIgMCAyLjU0LTEuNDE4IDIuNTYyLTQuOTdsLjA5NC0xNC45MjFjLjAyLTMuMjktMy40MzctMy4xNjUtMy40MzcgMHYxMi44NmwtNy4yMDMtNy4xODhhMzAuNzY4IDMwLjc2OCAwIDAgMC0yMS42NDEtOS4wNDd6bS0yOS41OTQgMzkuNzk3Yy0yLjA2MiAwLTIuNTI0IDEuNDAyLTIuNTQ3IDQuOTUzbC0uMDk0IDE0LjkyMmMtLjAyIDMuMjkgMy40MjIgMy4xNjQgMy40MjIgMHYtMTIuODZsNy4yMDMgNy4yMDRjMTEuOTU2IDExLjk1NSAzMS4zMTIgMTIuMDY0IDQzLjQwNy4yNSAyLjg0Mi0zLjAwMy40NTEtNC45ODgtMS4zMjgtMy4xNzItMTEuMDQzIDEwLjc4Ni0yOC43MSAxMC42OC0zOS42MjUtLjIzNWwtNy4xODgtNy4yMDNoMTIuODZjMy4zNDctLjAwOCAzLjE2NS0zLjg2IDAtMy44NmgtMTYuMTF6Ii8+PHBhdGggZD0iTTE2MCA0NGE4NC4xMSA4NC4xMSAwIDAgMC03Ni40MSA0OS4xMkE2MC43MSA2MC43MSAwIDAgMCA3MiA5MmE2MCA2MCAwIDAgMCAwIDEyMGg4OGE4NCA4NCAwIDAgMCAwLTE2OFptMCAxNjBINzJhNTIgNTIgMCAxIDEgOC41NS0xMDMuM0E4My42NiA4My42NiAwIDAgMCA3NiAxMjhhNCA0IDAgMCAwIDggMCA3NiA3NiAwIDEgMSA3NiA3NloiLz48L3N2Zz4=');}.icon-cloud-x{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xNjAsNDBBODguMDksODguMDksMCwwLDAsODEuMjksODguNjcsNjQsNjQsMCwxLDAsNzIsMjE2aDg4YTg4LDg4LDAsMCwwLDAtMTc2Wm0wLDE2MEg3MmE0OCw0OCwwLDAsMSwwLTk2YzEuMSwwLDIuMiwwLDMuMjkuMTFBODgsODgsMCwwLDAsNzIsMTI4YTgsOCwwLDAsMCwxNiwwLDcyLDcyLDAsMSwxLDcyLDcyWm0yOS42Ni04Mi4zNEwxNzEuMzEsMTM2bDE4LjM1LDE4LjM0YTgsOCwwLDAsMS0xMS4zMiwxMS4zMkwxNjAsMTQ3LjMxbC0xOC4zNCwxOC4zNWE4LDgsMCwwLDEtMTEuMzItMTEuMzJMMTQ4LjY5LDEzNmwtMTguMzUtMTguMzRhOCw4LDAsMCwxLDExLjMyLTExLjMyTDE2MCwxMjQuNjlsMTguMzQtMTguMzVhOCw4LDAsMCwxLDExLjMyLDExLjMyWiIvPjwvc3ZnPg==');}.icon-arrows-clockwise{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjQsNDhWOTZhOCw4LDAsMCwxLTgsOEgxNjhhOCw4LDAsMCwxLDAtMTZoMjguNjlMMTgyLjA2LDczLjM3YTc5LjU2LDc5LjU2LDAsMCwwLTU2LjEzLTIzLjQzaC0uNDVBNzkuNTIsNzkuNTIsMCwwLDAsNjkuNTksNzIuNzEsOCw4LDAsMCwxLDU4LjQxLDYxLjI3YTk2LDk2LDAsMCwxLDEzNSwuNzlMMjA4LDc2LjY5VjQ4YTgsOCwwLDAsMSwxNiwwWk0xODYuNDEsMTgzLjI5YTgwLDgwLDAsMCwxLTExMi40Ny0uNjZMNTkuMzEsMTY4SDg4YTgsOCwwLDAsMCwwLTE2SDQwYTgsOCwwLDAsMC04LDh2NDhhOCw4LDAsMCwwLDE2LDBWMTc5LjMxbDE0LjYzLDE0LjYzQTk1LjQzLDk1LjQzLDAsMCwwLDEzMCwyMjIuMDZoLjUzYTk1LjM2LDk1LjM2LDAsMCwwLDY3LjA3LTI3LjMzLDgsOCwwLDAsMC0xMS4xOC0xMS40NFoiLz48L3N2Zz4=');}.icon-share-fat{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzcuNjYsMTA2LjM1bC04MC04MEE4LDgsMCwwLDAsMTQ0LDMyVjcyLjM1Yy0yNS45NCwyLjIyLTU0LjU5LDE0LjkyLTc4LjE2LDM0LjkxLTI4LjM4LDI0LjA4LTQ2LjA1LDU1LjExLTQ5Ljc2LDg3LjM3YTEyLDEyLDAsMCwwLDIwLjY4LDkuNThoMGMxMS0xMS43MSw1MC4xNC00OC43NCwxMDcuMjQtNTJWMTkyYTgsOCwwLDAsMCwxMy42Niw1LjY1bDgwLTgwQTgsOCwwLDAsMCwyMzcuNjYsMTA2LjM1Wk0xNjAsMTcyLjY5VjE0NGE4LDgsMCwwLDAtOC04Yy0yOC4wOCwwLTU1LjQzLDcuMzMtODEuMjksMjEuOGExOTYuMTcsMTk2LjE3LDAsMCwwLTM2LjU3LDI2LjUyYzUuOC0yMy44NCwyMC40Mi00Ni41MSw0Mi4wNS02NC44NkM5OS40MSw5OS43NywxMjcuNzUsODgsMTUyLDg4YTgsOCwwLDAsMCw4LThWNTEuMzJMMjIwLjY5LDExMloiLz48L3N2Zz4=');}.icon-trash{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTYsNDhIMTc2VjQwYTI0LDI0LDAsMCwwLTI0LTI0SDEwNEEyNCwyNCwwLDAsMCw4MCw0MHY4SDQwYTgsOCwwLDAsMCwwLDE2aDhWMjA4YTE2LDE2LDAsMCwwLDE2LDE2SDE5MmExNiwxNiwwLDAsMCwxNi0xNlY2NGg4YTgsOCwwLDAsMCwwLTE2Wk05Niw0MGE4LDgsMCwwLDEsOC04aDQ4YTgsOCwwLDAsMSw4LDh2OEg5NlptOTYsMTY4SDY0VjY0SDE5MlpNMTEyLDEwNHY2NGE4LDgsMCwwLDEtMTYsMFYxMDRhOCw4LDAsMCwxLDE2LDBabTQ4LDB2NjRhOCw4LDAsMCwxLTE2LDBWMTA0YTgsOCwwLDAsMSwxNiwwWiIvPjwvc3ZnPg==');}.icon-star{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzkuMTgsOTcuMjZBMTYuMzgsMTYuMzgsMCwwLDAsMjI0LjkyLDg2bC01OS00Ljc2TDE0My4xNCwyNi4xNWExNi4zNiwxNi4zNiwwLDAsMC0zMC4yNywwTDkwLjExLDgxLjIzLDMxLjA4LDg2YTE2LjQ2LDE2LjQ2LDAsMCwwLTkuMzcsMjguODZsNDUsMzguODNMNTMsMjExLjc1YTE2LjM4LDE2LjM4LDAsMCwwLDI0LjUsMTcuODJMMTI4LDE5OC40OWw1MC41MywzMS4wOEExNi40LDE2LjQsMCwwLDAsMjAzLDIxMS43NWwtMTMuNzYtNTguMDcsNDUtMzguODNBMTYuNDMsMTYuNDMsMCwwLDAsMjM5LjE4LDk3LjI2Wm0tMTUuMzQsNS40Ny00OC43LDQyYTgsOCwwLDAsMC0yLjU2LDcuOTFsMTQuODgsNjIuOGEuMzcuMzcsMCwwLDEtLjE3LjQ4Yy0uMTguMTQtLjIzLjExLS4zOCwwbC01NC43Mi0zMy42NWE4LDgsMCwwLDAtOC4zOCwwTDY5LjA5LDIxNS45NGMtLjE1LjA5LS4xOS4xMi0uMzgsMGEuMzcuMzcsMCwwLDEtLjE3LS40OGwxNC44OC02Mi44YTgsOCwwLDAsMC0yLjU2LTcuOTFsLTQ4LjctNDJjLS4xMi0uMS0uMjMtLjE5LS4xMy0uNXMuMTgtLjI3LjMzLS4yOWw2My45Mi01LjE2QTgsOCwwLDAsMCwxMDMsOTEuODZsMjQuNjItNTkuNjFjLjA4LS4xNy4xMS0uMjUuMzUtLjI1cy4yNy4wOC4zNS4yNUwxNTMsOTEuODZhOCw4LDAsMCwwLDYuNzUsNC45Mmw2My45Miw1LjE2Yy4xNSwwLC4yNCwwLC4zMy4yOVMyMjQsMTAyLjYzLDIyMy44NCwxMDIuNzNaIi8+PC9zdmc+');}.icon-alphabetical{--icon:url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIGZpbGw9ImN1cnJlbnRDb2xvciIgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSIwIDAgMTgzLjc4IDE4NC4wNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNTkuNTg2IDY5Ljc0MmMtMC44NTEzIDAtMS40NjEgMC4xOTY1Ni0xLjgzNjYgMC41OTcxOC0wLjM1MDU0IDAuMzc1NTgtMC41Mjk1OCAxLjAyMjktMC41Mjk1OCAxLjk0OTNzMC4xNzkwMyAxLjU5MzcgMC41Mjk1OCAxLjk5NDRjMC4zNzU1OCAwLjM3NTU4IDAuOTg1MjkgMC41NjMzOCAxLjgzNjYgMC41NjMzOGg3LjAxOTdsLTEyLjQyOCAzNC4zNjZoLTIuMTA3Yy0wLjg1MTMgMC0xLjQ2MSAwLjE5NjU2LTEuODM2NiAwLjU5NzE4LTAuMzUwNTQgMC4zNzU1OC0wLjUyOTU3IDEuMDM0MS0wLjUyOTU3IDEuOTYwNiAwIDAuOTI2NDQgMC4xNzkwMyAxLjU4MjUgMC41Mjk1NyAxLjk4MyAwLjM3NTU4IDAuMzc1NTkgMC45ODUyOSAwLjU2MzM4IDEuODM2NiAwLjU2MzM4aDEyLjU1MmMwLjg1MTMgMCAxLjQ1MjItMC4xODc3OSAxLjgwMjgtMC41NjMzOCAwLjM3NTU4LTAuNDAwNjIgMC41NjMzNy0xLjA1NjYgMC41NjMzNy0xLjk4MyAwLTAuOTI2NDUtMC4xODc3OS0xLjU4NS0wLjU2MzM3LTEuOTYwNi0wLjM1MDU0LTAuNDAwNjItMC45NTE0Ny0wLjU5NzE4LTEuODAyOC0wLjU5NzE4aC00LjU1MjFsMy4xMjExLTguOTM0OWgxOC4yMmwzLjA3NiA4LjkzNDloLTUuMDcwNGMtMC44NTEzIDAtMS40NjEgMC4xOTY1Ni0xLjgzNjYgMC41OTcxOC0wLjM1MDU0IDAuMzc1NTgtMC41Mjk1OCAxLjAzNDEtMC41Mjk1OCAxLjk2MDYgMCAwLjkyNjQ0IDAuMTc5MDMgMS41ODI1IDAuNTI5NTggMS45ODMgMC4zNzU1OCAwLjM3NTU5IDAuOTg1MjkgMC41NjMzOCAxLjgzNjYgMC41NjMzOGgxMy4yOTZjMC44NTEzIDAgMS40NTIyLTAuMTg3NzkgMS44MDI4LTAuNTYzMzggMC4zNzU1OC0wLjQwMDYyIDAuNTYzMzctMS4wNTY2IDAuNTYzMzctMS45ODMgMC0wLjkyNjQ1LTAuMTg3NzktMS41ODUtMC41NjMzNy0xLjk2MDYtMC4zNTA1NC0wLjQwMDYyLTAuOTUxNDctMC41OTcxOC0xLjgwMjgtMC41OTcxOGgtMi4yODczbC0xMy4yNjItMzcuMDM2Yy0wLjMwMDQ3LTAuODUxMy0wLjc1OTk0LTEuNDYxLTEuMzg1OS0xLjgzNjYtMC42MDA5My0wLjQwMDYyLTEuNDA5Ny0wLjU5NzE4LTIuNDExMy0wLjU5NzE4em00NC4xNDYgMGMtMC44NTEzIDAtMS40NzIzIDAuMTk2NTYtMS44NDc4IDAuNTk3MTgtMC4zNTA1NSAwLjM3NTU4LTAuNTE4MyAxLjAyMjktMC41MTgzIDEuOTQ5M3YxMS45MWMwIDAuODc2MzMgMC4yMDUzMiAxLjUwNjEgMC42MzA5OCAxLjg4MTcgMC40MjU2NiAwLjM3NTU4IDEuMTU5MyAwLjU2MzM3IDIuMTg1OSAwLjU2MzM3czEuNzQ5LTAuMTg3NzkgMi4xNzQ3LTAuNTYzMzdjMC40MjU2OS0wLjM3NTU4IDAuNjQyMjYtMS4wMDUzIDAuNjQyMjYtMS44ODE3di05LjM1MTdoMTguODUxbC0yNC43NTQgMzUuMzAxYy0wLjM1MDU0IDAuNTI1ODItMC41MTgzMSAxLjA3MTctMC41MTgzMSAxLjYyMjYgMCAwLjkyNjQ1IDAuMTY3NzcgMS41ODI1IDAuNTE4MzEgMS45ODMxIDAuMzc1NTggMC4zNzU1OCAwLjk5NjU0IDAuNTYzMzggMS44NDc4IDAuNTYzMzhoMjguNzY2YzAuODUxMyAwIDEuNDUyMi0wLjE4NzggMS44MDI4LTAuNTYzMzggMC4zNzU1OC0wLjQwMDYyIDAuNTYzMzgtMS4wNTY2IDAuNTYzMzgtMS45ODMxdi0xMi42NjVjMC0wLjg3NjMzLTAuMjE2NTgtMS40OTQ4LTAuNjQyMjUtMS44NzA0LTAuNDI1NjYtMC4zNzU1OC0xLjE0OC0wLjU2MzM4LTIuMTc0Ny0wLjU2MzM4LTEuMDI2NiAwLTEuNzQ5IDAuMTg3NzktMi4xNzQ3IDAuNTYzMzgtMC40MjU2NiAwLjM3NTU4LTAuNjQyMjQgMC45OTQwMi0wLjY0MjI0IDEuODcwNHYxMC4xMDdoLTE5Ljk3OGwyNC45MDEtMzUuNDU5YzAuMjUwMzktMC4zNTA1NCAwLjM3MTgzLTAuODM4ODMgMC4zNzE4My0xLjQ2NDggMC0wLjkyNjQ1LTAuMTg3OC0xLjU3MzctMC41NjMzOC0xLjk0OTMtMC4zNTA1NS0wLjQwMDYyLTAuOTUxNDctMC41OTcxOC0xLjgwMjgtMC41OTcxOHptLTMxLjc1MiA1LjEwNDJoMC43MDk4NWw2Ljk4NTkgMjAuMzE1aC0xNC43MTZ6bS0zNy43MjMtNDkuMTgzYy00LjczNDIgMC04LjYzMTMgMy44OTctOC42MzEzIDguNjMxM3YxMTUuNDdjMCA0LjczNDIgMy44OTcgOC42MzEzIDguNjMxMyA4LjYzMTNoMTE1LjI2YzQuNzM0MiAwIDguNjQyMS0zLjg5NyA4LjY0MjEtOC42MzEzdi0xMTUuNDdjMC00LjczNDItMy45MDgyLTguNjMxMy04LjY0MjEtOC42MzEzem0wIDUuNzI0aDExNS4yNmMxLjY1OCAwIDIuOTA3IDEuMjQ5MSAyLjkwNyAyLjkwNzF2MTE1LjQ3YzAgMS42NTgtMS4yNDkxIDIuOTA3LTIuOTA3IDIuOTA3aC0xMTUuMjZjLTEuNjU4IDAtMi44OTU4LTEuMjQ5MS0yLjg5NTgtMi45MDd2LTExNS40N2MwLTEuNjU4IDEuMjM3OC0yLjkwNzEgMi44OTU4LTIuOTA3MXoiIGZpbGw9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIuNzIxMTQiLz48L3N2Zz4=');}.icon-list{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMjQsMTI4YTgsOCwwLDAsMS04LDhINDBhOCw4LDAsMCwxLDAtMTZIMjE2QTgsOCwwLDAsMSwyMjQsMTI4Wk00MCw3MkgyMTZhOCw4LDAsMCwwLDAtMTZINDBhOCw4LDAsMCwwLDAsMTZaTTIxNiwxODRINDBhOCw4LDAsMCwwLDAsMTZIMjE2YTgsOCwwLDAsMCwwLTE2WiIvPjwvc3ZnPg==');}.icon-x{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMDUuNjYsMTk0LjM0YTgsOCwwLDAsMS0xMS4zMiwxMS4zMkwxMjgsMTM5LjMxLDYxLjY2LDIwNS42NmE4LDgsMCwwLDEtMTEuMzItMTEuMzJMMTE2LjY5LDEyOCw1MC4zNCw2MS42NkE4LDgsMCwwLDEsNjEuNjYsNTAuMzRMMTI4LDExNi42OWw2Ni4zNC02Ni4zNWE4LDgsMCwwLDEsMTEuMzIsMTEuMzJMMTM5LjMxLDEyOFoiLz48L3N2Zz4=');}.icon-arrow-circle-right{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0xMjgsMjRBMTA0LDEwNCwwLDEsMCwyMzIsMTI4LDEwNC4xMSwxMDQuMTEsMCwwLDAsMTI4LDI0Wm0wLDE5MmE4OCw4OCwwLDEsMSw4OC04OEE4OC4xLDg4LjEsMCwwLDEsMTI4LDIxNlptNDUuNjYtOTMuNjZhOCw4LDAsMCwxLDAsMTEuMzJsLTMyLDMyYTgsOCwwLDAsMS0xMS4zMi0xMS4zMkwxNDguNjksMTM2SDg4YTgsOCwwLDAsMSwwLTE2aDYwLjY5bC0xOC4zNS0xOC4zNGE4LDgsMCwwLDEsMTEuMzItMTEuMzJaIi8+PC9zdmc+');}.icon-house{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMTkuMzEsMTA4LjY4bC04MC04MGExNiwxNiwwLDAsMC0yMi42MiwwbC04MCw4MEExNS44NywxNS44NywwLDAsMCwzMiwxMjB2OTZhOCw4LDAsMCwwLDgsOGg2NGE4LDgsMCwwLDAsOC04VjE2MGgzMnY1NmE4LDgsMCwwLDAsOCw4aDY0YTgsOCwwLDAsMCw4LThWMTIwQTE1Ljg3LDE1Ljg3LDAsMCwwLDIxOS4zMSwxMDguNjhaTTIwOCwyMDhIMTYwVjE1MmE4LDgsMCwwLDAtOC04SDEwNGE4LDgsMCwwLDAtOCw4djU2SDQ4VjEyMGw4MC04MCw4MCw4MFoiLz48L3N2Zz4=');}.icon-star-half-fi{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzkuMTgsOTcuMjZBMTYuMzgsMTYuMzgsMCwwLDAsMjI0LjkyLDg2bC01OS00Ljc2TDE0My4xNCwyNi4xNWExNi4zNiwxNi4zNiwwLDAsMC0zMC4yNywwTDkwLjExLDgxLjIzLDMxLjA4LDg2YTE2LjQ2LDE2LjQ2LDAsMCwwLTkuMzcsMjguODZsNDUsMzguODNMNTMsMjExLjc1YTE2LjQsMTYuNCwwLDAsMCwyNC41LDE3LjgyTDEyOCwxOTguNDlsNTAuNTMsMzEuMDhBMTYuNCwxNi40LDAsMCwwLDIwMywyMTEuNzVsLTEzLjc2LTU4LjA3LDQ1LTM4LjgzQTE2LjQzLDE2LjQzLDAsMCwwLDIzOS4xOCw5Ny4yNlptLTE1LjM0LDUuNDctNDguNyw0MmE4LDgsMCwwLDAtMi41Niw3LjkxbDE0Ljg4LDYyLjhhLjM3LjM3LDAsMCwxLS4xNy40OGMtLjE4LjE0LS4yMy4xMS0uMzgsMGwtNTQuNzItMzMuNjVBOCw4LDAsMCwwLDEyOCwxODEuMVYzMmMuMjQsMCwuMjcuMDguMzUuMjZMMTUzLDkxLjg2YTgsOCwwLDAsMCw2Ljc1LDQuOTJsNjMuOTEsNS4xNmMuMTYsMCwuMjUsMCwuMzQuMjlTMjI0LDEwMi42MywyMjMuODQsMTAyLjczWiIvPjwvc3ZnPg==');}.icon-star-fi{--icon:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBmaWxsPSJjdXJyZW50Q29sb3IiPjxwYXRoIGQ9Ik0yMzQuMjksMTE0Ljg1bC00NSwzOC44M0wyMDMsMjExLjc1YTE2LjQsMTYuNCwwLDAsMS0yNC41LDE3LjgyTDEyOCwxOTguNDksNzcuNDcsMjI5LjU3QTE2LjQsMTYuNCwwLDAsMSw1MywyMTEuNzVsMTMuNzYtNTguMDctNDUtMzguODNBMTYuNDYsMTYuNDYsMCwwLDEsMzEuMDgsODZsNTktNC43NiwyMi43Ni01NS4wOGExNi4zNiwxNi4zNiwwLDAsMSwzMC4yNywwbDIyLjc1LDU1LjA4LDU5LDQuNzZhMTYuNDYsMTYuNDYsMCwwLDEsOS4zNywyOC44NloiLz48L3N2Zz4=');}
\ No newline at end of file
diff --git a/inc/blocks/MenuBlock.php b/inc/blocks/MenuBlock.php
index dd69c46..66edde2 100644
--- a/inc/blocks/MenuBlock.php
+++ b/inc/blocks/MenuBlock.php
@@ -147,11 +147,7 @@
 	protected function getSections():array
 	{
 		if (!$this->sections) {
-			$sections = Options::get('menu_section_order');
-			if (!is_array($sections)) {
-				$sections = [];
-			}
-			$this->sections = $sections;
+			$this->sections = aneb_menu_sections();
 		}
 
 		return $this->sections;
@@ -215,13 +211,27 @@
 
 		$excerpt = get_the_excerpt($ID);
 		$isVariable = !empty($fields['variations']??[]);
-		$variations = $isVariable ? array_map('floatval', array_column($fields['variations'], 'price')) : [];
-		$priceRange = $isVariable ?
-			(jvbCurrency(min($variations)).' - '.jvbCurrency(max($variations))) :
-			jvbCurrency($fields['_price']??'');
+
+		$priceRange = $fields['price'];
+		if ($isVariable) {
+			$prices = array_map('floatval', array_column($fields['variations'], 'price'));
+			$min = min($prices);
+			$max = max($prices);
+			$priceRange = $min===$max ? jvbCurrency($min) : jvbCurrency($min) .' - '.jvbCurrency($max);
+
+		}
+
 //		if (!$isVariable) {
 //			jvbDump($fields, 'Fields');
 //		}
+//		jvbDump(get_post_thumbnail_id($ID), 'thumbnail');
+//		$product = wc_get_product($ID);
+//		jvbDump($product->get_image_id(), 'product image');
+//		jvbDump($product->get_gallery_image_ids(), 'Gallery images');
+		if ($fields['post_title'] === 'Breakfast Poutine') {
+			jvbDump($ID);
+			jvbDump($fields);
+		}
 
 		$out = sprintf(
 	'<div id="%s" class="menu-item%s" data-section="%s" data-label="%s" data-id="%s">
diff --git a/inc/meta/Group.php b/inc/meta/Group.php
index 38a8d5c..9d77b6d 100644
--- a/inc/meta/Group.php
+++ b/inc/meta/Group.php
@@ -16,7 +16,7 @@
 	{
 		$this->meta = $meta;
 		$this->name = $name;
-		$this->config = $meta->config($name) ?? [];
+		$this->config = $meta->getFieldConfig($name) ?? [];
 
 		$data = $meta->get($name);
 		$this->data = is_array($data) ? $data : [];
@@ -44,12 +44,11 @@
 		return $this->getPath($nested, $fieldConfig['fields'] ?? [], $parts);
 	}
 
-	public function set(string $path, mixed $value, bool $autosave = true): self
+	public function set(string $path, mixed $value, bool $autosave = true): bool
 	{
-		$parts = explode('|', $path);
+		$parts = explode('|', $path, 2);
 		$this->setPath($this->data, $this->config['fields'] ?? [], $parts, $value);
-		$this->sync($autosave);
-		return $this;
+		return $this->sync($autosave);
 	}
 
 	protected function setPath(array &$data, array $fieldsConfig, array $parts, mixed $value): void
@@ -97,8 +96,8 @@
 		return isset($this->config['fields'][$field]);
 	}
 
-	protected function sync(bool $autosave = true): void
+	protected function sync(bool $autosave = true): bool
 	{
-		$this->meta->set($this->name, $this->data, $autosave);
+		return $this->meta->set($this->name, $this->data);
 	}
 }
diff --git a/inc/meta/Meta.php b/inc/meta/Meta.php
index d929089..0482cbc 100644
--- a/inc/meta/Meta.php
+++ b/inc/meta/Meta.php
@@ -1,596 +1,521 @@
 <?php
 namespace JVBase\meta;
 
-use JVBase\base\Options;
+use JVBase\managers\Cache;
 use JVBase\registrar\Registrar;
-use WP_Post;
-use WP_Term;
-use WP_User;
 
 if (!defined('ABSPATH')) {
 	exit;
 }
 
-class Meta
-{
+class Meta {
 	/**
 	 * @var string post, term, user, or options
 	 */
-	protected string $type;
+	protected string $objectType;
 	/**
-	 * @var ?string the full slug, with BASE
+	 * @var string|null post type, user role, or taxonomy
 	 */
-	protected ?string $slug;
-
-	protected string $contentType;
-	protected Item $item;
-	protected Storage $storage;
-	protected Validator $validator;
-	protected Sanitizer $sanitizer;
-	protected array $fields;
-	protected WP_Post|WP_Term|WP_User|false|null $wpObject;
+	protected ?string $content;
+	/**
+	 * @var int|string <int>post, term, or user ID OR {string} option key base
+	 */
 	protected int|string $ID;
-	protected MetaTypeManager $typeManager;
-	protected static array $instances = ['post' => [],'term' => [], 'user'=>[],'option'=>[]];
-
-	protected array $defaults = ['post_thumbnail'];
 	/**
-	 * Create Meta instance for a post
+	 * @var array of Registrar's defined fields, if any
 	 */
-	public static function forPost(int $id): self
-	{
-		if (array_key_exists($id, self::$instances['post'])) {
-			return self::$instances['post'][$id];
-		}
-		$new = new self($id, 'post');
-		self::$instances['post'][$id] = $new;
-		return $new;
-	}
-
+	protected static array $registrars = [];
 	/**
-	 * Create Meta instance for a term
+	 * @var array Field values, stored in memory
 	 */
-	public static function forTerm(int $id): self
-	{
-		if (array_key_exists($id, self::$instances['term'])) {
-			return self::$instances['term'][$id];
+	protected array $fields;
+
+	protected ?\WC_Product $product = null;
+
+	protected static Validator $validator;
+	protected static Sanitizer $sanitizer;
+
+	protected static array $coreFields = [
+		'post' => ['post_title', 'post_content', 'post_excerpt', 'post_status', 'post_date', 'post_modified', 'post_thumbnail', 'post_name'],
+		'term' => ['name', 'description', 'parent'],
+		'user' => ['first_name', 'last_name', 'user_email', 'display_name', 'user_login'],
+		'options' => []
+	];
+
+	protected static array $instances = [
+		'post'	=> [],
+		'term'	=> [],
+		'user'	=> [],
+		'options'=> [],
+	];
+
+	private function __construct(string $objectType, int|string $ID) {
+		$this->objectType = $objectType;
+		$this->ID = $ID;
+		$this->content = $this->resolveBasedType();
+
+		if ($this->content && !array_key_exists($this->content, self::$registrars)) {
+			$registrar = Registrar::getInstance($this->content);
+			if ($registrar) {
+				self::$registrars[$this->content] = $registrar->getFields();
+			}
 		}
-		$new = new self($id, 'term');
-		self::$instances['term'][$id] = $new;
-		return $new;
-	}
 
-	/**
-	 * Create Meta instance for a user
-	 */
-	public static function forUser(int $id): self
-	{
-		if (array_key_exists($id, self::$instances['user'])) {
-			return self::$instances['user'][$id];
+		if ($this->objectType === 'post' && function_exists('wc_get_product') && in_array($this->content, ['product', 'product_variation'], true)) {
+			$this->product = wc_get_product($this->ID) ?: null;
 		}
-		$new = new self($id, 'user');
-		self::$instances['user'][$id] = $new;
-		return $new;
-	}
-
-	/**
-	 * Create Meta instance for options
-	 */
-	public static function forOptions(?string $baseKey = BASE): self
-	{
-		if (array_key_exists($baseKey, self::$instances['option'])) {
-			return self::$instances['option'][$baseKey];
+		$this->buildData();
+		if (!isset(self::$sanitizer)) {
+			self::$sanitizer = new Sanitizer();
 		}
-		$new = new self($baseKey, 'option');
-		self::$instances['option'][$baseKey] = $new;
-		return $new;
+		if (!isset(self::$validator)) {
+			self::$validator = new Validator();
+		}
 	}
-	/***************************************************************
-	 * Constructor
-	***************************************************************/
+		protected function buildData():void
+		{
+			//Get all Item meta
+			$this->fields = match ($this->objectType) {
+				'post'	=> get_post_meta($this->ID),
+				'term'	=> get_term_meta($this->ID),
+				'user'	=> get_user_meta($this->ID),
+				default	=> []
+			};
+			$this->fields = array_combine(
+				array_map('jvbNoBase', array_keys($this->fields)),
+				$this->fields
+			);
 
-	public function __construct(int|string|null $id, string $type, array $fields = [])
+			//Add in core fields
+			$obj = match ($this->objectType) {
+				'post'	=> get_post($this->ID),
+				'term'	=> get_term($this->ID, $this->content),
+				'user'	=> get_userdata($this->ID),
+				default => false
+			};
+			if ($obj) {
+				foreach (self::$coreFields[$this->objectType] as $name) {
+					$value =  match ($name) {
+						'post_thumbnail'	=> get_post_thumbnail_id($this->ID),
+						default	=> $obj->$name??false
+					};
+//					if (!$value) {
+//						$this->log('Could not find value for '.$name.', of '.$this->content);
+//					}
+					$this->fields[$name] = $value??'';
+				}
+			}
+		}
+
+	public static function forPost(int $ID):self
 	{
-		$this->validator = new Validator();
-		$this->sanitizer = new Sanitizer();
-		$this->typeManager = new MetaTypeManager();
-		$this->type = $type;
-		$this->ID = $id;
-		$this->buildData($id, $type, $fields);
+		if (array_key_exists($ID, self::$instances['post'])) {
+			return self::$instances['post'][$ID];
+		}
+		self::$instances['post'][$ID] = new self('post', $ID);
+		return self::$instances['post'][$ID];
 	}
 
-	protected function buildData(int|string|null $id, string $type, array $fields):void
+	public static function forTerm(int $ID):self
 	{
-		$this->wpObject = match($type) {
-			'post' 	=> get_post($id),
-			'term'	=> get_term($id),
-			'user', 'integrations' => get_userdata($id),
-			default => false
-		};
+		if (array_key_exists($ID, self::$instances['term'])) {
+			return self::$instances['term'][$ID];
+		}
+		self::$instances['term'][$ID] = new self('term', $ID);
+		return self::$instances['term'][$ID];
+	}
 
-		$this->slug = match($type) {
-			'post'	=> $this->wpObject->post_type,
-			'term'	=> $this->wpObject->taxonomy,
-			'user'	=> jvbUserRole($id),
+	public static function forUser(int $ID):self
+	{
+		if (array_key_exists($ID, self::$instances['user'])) {
+			return self::$instances['user'][$ID];
+		}
+		self::$instances['user'][$ID] = new self('user', $ID);
+		return self::$instances['user'][$ID];
+	}
+
+	public static function forOptions(string $base = 'default'):self
+	{
+		if (array_key_exists($base, self::$instances['options'])) {
+			return self::$instances['options'][$base];
+		}
+		self::$instances['options'][$base] = new self('options', $base);
+		return self::$instances['options'][$base];
+	}
+
+	protected function resolveBasedType(): ?string {
+		return match ($this->objectType) {
+			'post' => get_post_type($this->ID) ?: null,
+			'term' => ($term = get_term($this->ID)) && !is_wp_error($term) ? $term->taxonomy : null,
+			'user' => jvbUserRole($this->ID),
 			default => null
 		};
+	}
 
-		$registrar = !is_null($this->slug) ? Registrar::getInstance($this->slug) : false;
-		$fields = $registrar ? $registrar->getFields() : $fields;
 
-		if ($this->type == 'option') {
-			$options = Options::getInstance();
-			$fields = $options->getFields();
+
+
+
+	/***************************************************************************
+	 * GETTING FIELDS
+	***************************************************************************/
+	public function get(string $name): mixed {
+		if (array_key_exists($name, $this->fields)) {
+			return $this->fields[$name];
 		}
-		$meta = match($type) {
-			'post'	=> get_post_meta($id),
-			'term'	=> get_term_meta($id),
-			'user'	=> get_user_meta($id),
-			default => []
+
+		if ($this->product && $this->isProductField($name)) {
+			$value = $this->getProductField($name);
+		} else if (in_array($name, static::$coreFields[$this->objectType], true)) {
+			$value = $this->getCoreField($name);
+		} else {
+			$value = $this->getMetaField($name);
+		}
+		$this->fields[$name] = $value;
+		return $value;
+	}
+
+	public function getAll(?array $names = null): array {
+		$names = $names ?? $this->getAllFieldNames();
+		$out = [];
+		foreach ($names as $name) {
+			$out[$name] = $this->get($name);
+		}
+		return $out;
+	}
+
+	protected function getCoreField(string $name): mixed {
+		return match ($this->objectType) {
+			'post' => $name === 'post_thumbnail'
+				? get_post_thumbnail_id($this->ID)
+				: (($p = get_post($this->ID)) ? ($p->$name ?? null) : null),
+			'term' => ($t = get_term($this->ID, $this->content)) && !is_wp_error($t) ? ($t->$name ?? null) : null,
+			'user' => ($u = get_userdata($this->ID)) ? ($u->$name ?? null) : null,
 		};
-		if (!$meta) {
-			$meta = [];
-		}
-		$meta = array_map(fn($value) => maybe_unserialize($value[0]), $meta);
+	}
 
+	protected function getMetaField(string $name): mixed {
+		$key = $this->metaKey($name);
+		return match ($this->objectType) {
+			'post' => get_post_meta($this->ID, $key, true),
+			'term' => get_term_meta($this->ID, $key, true),
+			'user' => get_user_meta($this->ID, $key, true),
+			'options' => get_option($key)
+		};
+	}
 
-		$this->fields = [];
-
-		if (class_exists('WooCommerce') && $this->type === 'post' && $this->wpObject->post_type??'' === 'product') {
-			$fields['post_title'] = [
-				'type'	=> 'text',
-				'label'	=> 'Title',
-			];
-			$fields['post_content'] = [
-				'type'	=> 'text',
-				'label'	=> 'Content',
-			];
-			$fields['post_excerpt'] = [
-				'type'	=> 'text',
-				'label'	=> 'Short Description',
-			];
-			$fields['ID'] = [
-				'type'	=> 'text',
-				'label'	=> 'ID',
-			];
-
-
-			$fields['_stock'] = [
-				'type' => 'number',
-				'label' => 'Stock',
-				'default'	=> null
-			];
-			$fields['_stock_status'] = [
-				'type'	=> 'select',
-				'label'	=> 'Stock Status',
-				'default'	=> 'instock',
-				'options'	=> [
-					'instock'	=> 'In Stock',
-					'outofstock'	=> 'Out of Stock',
-					'onbackorder'		=> 'On Backorder'
-				]
-			];
-			$fields['_price'] = [
-				'type'		=> 'text',
-				'subtype'	=> 'number',
-				'label'		=>	'Price'
-			];
-
-
-			$product = wc_get_product($id);
-
-			$fields['sku'] = [
-				'type'	=> 'text',
-				'label'	=> 'SKU',
-			];
-
-			$out = [];
-			if ($product && $product->is_type('variable')) {
-				$var = $product->get_children();
-				$var = array_filter(array_map(function($v) {
-					return wc_get_product($v);
-				}, $var));
-
-				$title= $product->get_title();
-				foreach ($var as $variation) {
-					$out[] = [
-						'id'	=> $variation->get_id(),
-						'sku'	=> $variation->get_sku(),
-						'title'	=> str_replace($title.' - ', '', $variation->get_name()),
-						'price'	=> $variation->get_price(),
-						'description'=> $variation->get_short_description(),
-						'sale'	=> $variation->get_sale_price(),
-						'img'	=> $variation->get_image_id(),
-						'stock'	=> $variation->get_stock_quantity(),
-						'stock_status'	=> $variation->get_stock_status()
-					];
-				}
-			}
-			if (!empty($out)) {
-				$this->fields['variations'] = new Field('variations', $out, [
-					'type'	=> 'repeater',
-					'label'	=> 'Variations',
-					'fields'	=> [
-						'id'	=> [
-							'type'	=> 'text',
-							'subtype'	=> 'number',
-							'label'	=> 'Variation ID',
-						],
-						'sku'	=> [
-							'type'	=> 'text',
-							'label'	=> 'Stock Keeping Unit (SKU)'
-						],
-						'title'	=> [
-							'type'	=> 'text',
-							'label'	=> 'Variation Title'
-						],
-						'price'	=> [
-							'type'	=> 'text',
-							'subtype'	=> 'number',
-							'label'	=> 'Variation Price'
-						],
-						'sale'	=> [
-							'type'	=> 'text',
-							'subtype'	=> 'number',
-							'label'	=> 'Sale Price',
-						],
-						'image'	=> [
-							'type'	=> 'text',
-							'subtype'	=> 'number',
-							'label'	=> 'Variation Image ID'
-						],
-						'stock'	=> [
-							'type'	=> 'text',
-							'label'	=> 'Stock Quantity'
-						],
-						'stock_status'	=> [
-							'type'	=> 'text',
-							'label'	=> 'Stock Status'
-						]
-					]
-				]);
+	/***************************************************************************
+	 * SETTING FIELDS
+	***************************************************************************/
+	public function set(string $name, mixed $value): bool {
+		$field = $this->getFieldConfig($name);
+		if ($field) {
+			if ($field['type']??'' === 'repeater' && str_contains($name, ':')) {
+				return $this->setByPath($name, $value);
+			} elseif ($field['type']??'' === 'group' && str_contains($name, '|')) {
+				return $this->setGroup($name, $value);
 			}
 
-
-		}
-		foreach ($fields as $fieldName => $config) {
-			$fieldName = jvbNoBase($fieldName);
-			$value = '';
-			if ($this->type === 'option') {
-				$value = get_option(BASE . $fieldName, $config['default'] ?? '');
-			} else if ($this->wpObject && $this->wpObject->post_type === 'product') {
-				if (property_exists($this->wpObject, $fieldName)) {
-					$value = $this->wpObject->$fieldName;
-				} else {
-					$product = wc_get_product($this->wpObject->ID);
-					$value = match ($fieldName) {
-						'sku'	=> $product->get_sku(),
-						'_price'	=> $product->get_price(),
-						'description'=> $product->get_short_description(),
-						'sale'	=> $product->get_sale_price(),
-						'img'	=> $product->get_image_id(),
-						'_stock'	=> $product->get_stock_quantity(),
-						'_stock_status'	=> $product->get_stock_status(),
-						default => '',
-					};
-				}
-
-			} else if (
-				($this->wpObject && property_exists($this->wpObject, $fieldName))
-				|| ($type === 'user' && $this->wpObject && property_exists($this->wpObject->data, $fieldName))) {
-				$config['wp'] = true;
-				$value = $this->wpObject->$fieldName;
-
-			}  else if (in_array($fieldName, $this->defaults)) {
-				$config['wp'] = true;
-				switch ($fieldName) {
-					case 'post_thumbnail':
-						$value = get_post_thumbnail_id($this->ID);
-						break;
-				}
-			} else {
-				$value = array_key_exists(BASE.$fieldName, $meta) ? $meta[BASE.$fieldName] : $config['default']??'';
-				switch ($config['type']) {
-					case 'taxonomy':
-						if (!$config['isReference']??true) {
-							$config['wp'] = true;
-							$value = implode(',', wp_get_post_terms($this->ID, jvbCheckBase($config['taxonomy']), ['fields' => 'ids']));
-						}
-						break;
-					case 'selector':
-						if (array_key_exists('subtype', $config) && $config['subtype'] === 'taxonomy' && !$config['isReference']??true) {
-							$config['wp'] = true;
-							$value = implode(',',wp_get_post_terms($this->ID, jvbCheckBase($config['taxonomy']), ['fields' => 'ids']));
-						}
-						break;
-				}
-
-			}
-			$this->fields[$fieldName] = new Field($fieldName, $value, $config);
-		}
-	}
-
-	// ─────────────────────────────────────────────────────────────
-	// Magic Methods for Fluent Access
-	// ─────────────────────────────────────────────────────────────
-
-	public function __get(string $name): mixed
-	{
-		return $this->get($name);
-	}
-
-	public function __set(string $name, mixed $value): void
-	{
-		$this->set($name, $value);
-	}
-
-	public function __isset(string $name): bool
-	{
-		return $this->item->hasField($name);
-	}
-
-	// ─────────────────────────────────────────────────────────────
-	// Core API
-	// ─────────────────────────────────────────────────────────────
-
-	/**
-	 * Get a field value
-	 */
-	public function get(string $name): mixed
-	{
-		// Handle repeater subfield path
-		if (str_contains($name, ':')) {
-			return $this->getByPath($name);
-		}
-		// Group shortcut path
-		if (str_contains($name, '|')) {
-			[$parent, $child] = explode('|', $name, 2);
-			return $this->group($parent)->get($child);
-		}
-		if (!array_key_exists($name, $this->fields)) {
-			error_log('[Meta]::get Attempted to get unregistered field: '.$name);
-			return '';
-		}
-		if (is_null($this->fields[$name])) {
-			error_log('[Meta]::get Field does not seem to be setup yet: '.$name);
-			return '';
-		}
-		return $this->fields[$name]->get()??'';
-	}
-
-	/**
-	 * Set a field value (validates & sanitizes by default)
-	 */
-	public function set(string $name, mixed $value, $autosave = true): self
-	{
-		// Handle repeater subfield path (e.g., "services:2:image")
-		if (str_contains($name, ':')) {
-			return $this->setByPath($name, $value);
-		}
-
-		// Group shortcut
-		if (str_contains($name, '|')) {
-			return $this->setGroup($name, $value, $autosave);
-		}
-
-		$field = $this->fields[$name]??false;
-		if (!$field) {
-			error_log('No config found for field: '.$name);
-			return $this;
-		}
-
-		// Validate
-		if (!$this->validator->validate($value, $field->config)) {
-			$field->addError("Validation failed for {$name}");
-			return $this;
-		}
-
-		// Sanitize
-		$value = $this->sanitizer->sanitize($value, $field->config);
-		$field->set($value);
-		if ($autosave && $field->isDirty) {
-			$this->save();
-		}
-
-		return $this;
-	}
-
-	/**
-	 * Get multiple fields
-	 */
-	public function getAll(array $fields = []): array
-	{
-		if (empty($fields) || $fields === ['all']) {
-			$fields = array_keys($this->fields);
-		}
-		$fields = array_filter($this->fields, function ($field) use ($fields) {
-			return in_array($field, $fields);
-		}, ARRAY_FILTER_USE_KEY);
-
-		return array_map(function ($field) {
-			return $field->value;
-		}, $fields);
-	}
-
-	/**
-	 * Set multiple fields
-	 */
-	public function setAll(array $data):bool
-	{
-		foreach ($data as $name => $value) {
-			$this->set($name, $value, false);
-		}
-		return $this->save();
-	}
-
-	/**
-	 * Save all dirty fields to database
-	 */
-	public function save(): bool
-	{
-		$dirtyFields = array_filter($this->fields, function ($field) {
-			return $field->isDirty;
-		});
-		$defaults = array_filter($dirtyFields, function ($field) {
-			return $field->isDefault;
-		});
-		$custom = array_filter($dirtyFields, function($field) {
-			return !$field->isDefault;
-		});
-
-		$success = true;
-
-		if (!empty($defaults)) {
-			$result = false;
-			switch ($this->type) {
-				case 'post':
-					//Deal with field exceptions, first, that cannot be set via wp_update_post
-					foreach ($defaults as $fieldName => $field) {
-						switch ($fieldName) {
-							case 'post_thumbnail':
-								$result = set_post_thumbnail($this->ID, $field->value);
-								unset($defaults[$fieldName]);
-								break;
-						}
-						//If it's a taxonomy, we use wp_set_object_terms
-						if (
-							($field->config['type'] === 'selector' && $field->config['subtype'] === 'taxonomy')
-							|| $field->config['type'] === 'taxonomy') {
-
-							$result = wp_set_object_terms($this->ID, array_map('absint', explode(',', $field->value)), jvbCheckBase($field->config['taxonomy']));
-							unset($defaults[$fieldName]);
-						}
-					}
-
-
-
-					if (!empty($defaults)) {
-						error_log('Remaining fields: '.print_r($defaults, true));
-						$defaults = array_map(function ($field) {
-							return $field->value;
-						}, $defaults);
-						error_log('Remaining values to save: '.print_r($defaults, true));
-						$data = array_merge([
-							'post_type'	=> $this->slug,
-							'ID'		=> $this->ID
-						], $defaults);
-						error_log('Updating post: '.print_r($data, true));
-						$result = wp_update_post($data);
-					}
-					break;
-				case 'term':
-					$termDefaults = array_map(fn($field) => $field->value, $defaults);
-					$result = wp_update_term($this->ID, $this->slug, $termDefaults);
-					break;
-				case 'user':
-					$userDefaults = array_map(fn($field) => $field->value, $defaults);
-					$data = array_merge(['ID' => $this->ID], $userDefaults);
-					$result = wp_update_user($data);
-					break;
-			}
-			if (!$result || is_wp_error($result)) {
-				$success = false;
-			}
-		}
-		if (!empty($custom)) {
-			$function = match ($this->type) {
-				'post' => 'update_post_meta',
-				'term' => 'update_term_meta',
-				'user' => 'update_user_meta',
-				'option' => 'update_option',
-				default => false,
-			};
-			if (!$function) {
-				error_log('[Meta]::save() Invalid type, cannot save: '.$this->type);
+			if (!self::$validator->validate($value, $field)) {
 				return false;
 			}
-			foreach ($custom as $field) {
-				if ($this->type === 'option') {
-					$result = update_option(BASE.$field->name, $field->value);
-				} else {
-					$result = $function($this->ID, BASE.$field->name, $field->value);
-				}
 
-				if (!$result) {
-					error_log('Problem saving field: '.$field->name.' with value: '.print_r($field->value, true));
-				}
-			}
-			//Now handled directly from Registrar
-//			if ($this->type === 'term' && Registrar::getInstance($this->slug)->hasFeature('is_content')) {
-//				update_term_meta($this->ID, BASE.'date_modified', date('Y-m-d H:i:s'));
-//			}
+			$value = self::$sanitizer->sanitize($value, $field);
 		}
 
-
-		return $success;
+		if ($this->product && $this->isProductField($name)) {
+			return $this->setProductField($name, $value);
+		}
+		if (in_array($name, static::$coreFields[$this->objectType], true)) {
+			return $this->setCoreField($name, $value);
+		}
+		return $this->setMetaField($name, $value);
 	}
 
-	/**
-	 * Delete a field value
-	 */
-	public function delete(string $name): bool
-	{
-		$field = $this->fields[$name]??false;
-		if (!$field) {
-			error_log('[Meta]::delete Could not delete field '.$name.': not registered');
-			return true;
-		}
-
-		if ($field->isTaxonomy()) {
-			wp_set_object_terms($this->ID, [], $this->slug);
-			return true;
-		}
-
-		return match ($this->type) {
-			'post'	=> delete_post_meta($this->ID, BASE.$name),
-			'term'	=> delete_term_meta($this->ID, BASE.$name),
-			'user', 'integrations' => delete_user_meta($this->ID, BASE.$name),
-			'option'	=> delete_option(BASE.$name),
-			default => false
-		};
-	}
-
-
-
-	/**
-	 * Delete multiple field values
-	 */
-	public function deleteAll(array $names): array
-	{
+	public function setAll(array $data): array {
+		$core = array_filter($data, function ($name) {
+			return in_array($name, self::$coreFields[$this->objectType]);
+		}, ARRAY_FILTER_USE_KEY);
 		$results = [];
-		foreach ($names as $name) {
-			$results[$name] = $this->delete($name);
+		if (!empty($core)) {
+			$data = array_filter($data, function ($name) {
+				return !in_array($name, self::$coreFields[$this->objectType]);
+			}, ARRAY_FILTER_USE_KEY);
+			$results = $this->setAllCoreFields($core);
+		}
+
+		foreach ($data as $name => $value) {
+			$results[$name] = $this->set($name, $value);
 		}
 		return $results;
 	}
 
-	/*****************************************************************
-	 * Repeater Access
-	*****************************************************************/
+	protected function setAllCoreFields(array $data):array
+	{
+		$results = [];
 
-	/**
-	 * Get repeater accessor for fluent repeater operations
-	 */
-	public function repeater(string $name): Repeater
+		$core = array_filter($data, function ($name) {
+			return in_array($name, self::$coreFields[$this->objectType]);
+		}, ARRAY_FILTER_USE_KEY);
+
+
+		if (count($core) !== count($data)) {
+			$notCore = array_filter($data, function ($name) {
+				return !in_array($name, self::$coreFields[$this->objectType]);
+			}, ARRAY_FILTER_USE_KEY);
+			$results = $this->setAll($notCore);
+		}
+
+		if (array_key_exists('post_thumbnail', $core)) {
+			$results['post_thumbnail'] = $this->setCoreField('post_thumbnail', $core['post_thumbnail']);
+			unset ($core['post_thumbnail']);
+		}
+
+		$return = match ($this->objectType) {
+			'post'	=> !is_wp_error(wp_update_post(array_merge(['ID' => $this->ID], $core))),
+			'term'	=> !is_wp_error(wp_update_term($this->ID, $this->content, $core)),
+			'user'	=> !is_wp_error(wp_update_user(array_merge(['ID' => $this->ID], $core))),
+		};
+		foreach ($core as $name => $value) {
+			$results[$name] = $return;
+		}
+		return $results;
+	}
+
+	protected function setCoreField(string $name, mixed $value): bool {
+		$success = match ($this->objectType) {
+			'post' => $name === 'post_thumbnail'
+				? (!empty($value) ? set_post_thumbnail($this->ID, (int)$value) : delete_post_thumbnail($this->ID))
+				: !is_wp_error(wp_update_post(['ID' => $this->ID, $name => $value])),
+			'term' => !is_wp_error(wp_update_term($this->ID, $this->content, [$name => $value])),
+			'user' => !is_wp_error(wp_update_user(['ID' => $this->ID, $name => $value])),
+			default => false
+		};
+		if ($success) {
+			$this->clearCache();
+			$this->fields[$name] = $value;
+		}
+		return $success;
+	}
+
+	protected function setMetaField(string $name, mixed $value): bool {
+		$key = $this->metaKey($name);
+		$result = match ($this->objectType) {
+			'post' => update_post_meta($this->ID, $key, $value),
+			'term' => update_term_meta($this->ID, $key, $value),
+			'user' => update_user_meta($this->ID, $key, $value),
+			'options' => update_option($key, $value)
+		};
+		if ($result) {
+			$this->fields[$name] = $value;
+			$this->clearCache();
+		}
+		return $result !== false;
+	}
+	/********************************************************************************
+	 * DELETING FIELDS
+	********************************************************************************/
+	public function delete(string $name):bool
+	{
+		if (in_array($name, static::$coreFields[$this->objectType])) {
+			return $this->deleteCoreField($name);
+		}
+
+		$field = $this->getFieldConfig($name);
+		if ($field) {
+			if ($this->isTaxonomy($field)) {
+				return !is_wp_error(wp_set_object_terms($this->ID, [], $this->content));
+			}
+		}
+		$key = $this->metaKey($name);
+		return match ($this->objectType) {
+			'post'	=> delete_post_meta($this->ID, $key),
+			'term'	=> delete_term_meta($this->ID, $key),
+			'user'	=> delete_user_meta($this->ID, $key),
+			'option'=> delete_option($key)
+		};
+	}
+	public function deleteAll(array $fieldNames):array
+	{
+		$core = array_filter($fieldNames, function ($name) {
+			return in_array($name, self::$coreFields[$this->objectType]);
+		}, ARRAY_FILTER_USE_KEY);
+
+		$results = [];
+		if (!empty($core)) {
+			$fieldNames = array_filter($fieldNames, function ($name) {
+				return !in_array($name, self::$coreFields[$this->objectType]);
+			});
+			$results = $this->deleteAllCoreFields($core);
+		}
+
+		foreach ($fieldNames as $name) {
+			$results[$name] = $this->delete($name);
+		}
+
+		return $results;
+	}
+	protected function deleteAllCoreFields(array $fieldNames):array
+	{
+		$results = [];
+		$core = array_filter($fieldNames, function ($name) {
+			return in_array($name, self::$coreFields[$this->objectType]);
+		}, ARRAY_FILTER_USE_KEY);
+
+
+		if (count($core) !== count($fieldNames)) {
+			$notCore = array_filter($fieldNames, function ($name) {
+				return !in_array($name, self::$coreFields[$this->objectType]);
+			}, ARRAY_FILTER_USE_KEY);
+			$results = $this->deleteAll($notCore);
+		}
+
+		if (array_key_exists('post_thumbnail', $fieldNames)) {
+			$results['post_thumbnail'] = delete_post_thumbnail($this->ID);
+			unset($fieldNames['post_thumbnail']);
+			unset($core['post_thumbnail']);
+		}
+
+		$updated = [];
+		foreach ($core as $name) {
+			$updated[$name] = $this->getCoreDefault($name);
+		}
+
+		$success = match ($this->objectType) {
+			'post'	=> !is_wp_error(wp_update_post(array_merge(['ID' => $this->ID], $updated))),
+			'term'	=> !is_wp_error(wp_update_term($this->ID, $this->content, $updated)),
+			'user'	=> !is_wp_error(wp_update_user(array_merge(['ID' => $this->ID], $updated)))
+		};
+
+		foreach ($core as $name) {
+			$results[$name] = $success;
+		}
+		return $results;
+	}
+
+	protected function deleteCoreField(string $name):bool
+	{
+		if ($name === 'post_thumbnail') {
+			return delete_post_thumbnail($this->ID);
+		}
+		$default = $this->getCoreDefault($name);
+		return $this->setCoreField($name, $default);
+	}
+
+
+	/**************************************************************
+	 * WOOCOMMERCE PRODUCT SPECIFIC
+	**************************************************************/
+	protected function isProductField(string $name): bool {
+		return method_exists($this->product, 'get_'.$name) || method_exists($this->product, 'set_'.$name);
+	}
+
+	protected function getProductField(string $name): mixed {
+		$method = 'get_'.$name;
+		if ($name === 'variations') {
+			return $this->getVariations();
+		}
+		return method_exists($this->product, $method) ? $this->product->$method() : null;
+	}
+		protected function getVariations():array
+		{
+			$variations = $this->product->get_children();
+			$out = [];
+			foreach ($variations as $v) {
+				$out[] = self::forPost($v)->getAll();
+			}
+			return $out;
+		}
+
+	protected function setProductField(string $name, mixed $value): bool {
+		$method = 'set_'.$name;
+		if (!method_exists($this->product, $method)) return false;
+		$this->product->$method($value);
+		$this->product->save();
+		$this->fields[$name] = $value;
+		$this->clearCache();
+		return true;
+	}
+
+	protected function getAllProductFieldNames(): array
+	{
+		return [
+			'price',
+			'sku',
+			'sale',
+			'short_description',
+			'image_id',
+			'gallery_image_ids',
+			'stock',
+			'stock_quantity',
+			'stock_status',
+			'variations'
+		];
+	}
+
+	/*** Sanitization & Validation ***/
+//	protected function sanitize(mixed $value, array $field): mixed {
+//		return match ($field['type']) {
+//			'text', 'tel' => sanitize_text_field($value),
+//			'email' => sanitize_email($value),
+//			'url' => esc_url_raw($value),
+//			'textarea' => !empty($field['quill']) ? wp_kses_post($value) : sanitize_textarea_field($value),
+//			'number' => is_numeric($value) ? $value + 0 : 0,
+//			'true_false' => (bool)$value,
+//			'datetime' => sanitize_text_field($value),
+//			'upload', 'image', 'gallery' => !empty($field['multiple']) ? array_map('intval', (array)$value) : (int)$value,
+//			'checkbox', 'set' => array_map('sanitize_text_field', (array)$value),
+//			'radio', 'select' => sanitize_text_field($value),
+//			'selector', 'taxonomy', 'user', 'post' => array_map('intval', (array)$value),
+//			'repeater', 'tagList' => $this->sanitizeRepeater($value, $field),
+//			'group' => $this->sanitizeGroup($value, $field),
+//			default => is_array($value) ? array_map('sanitize_text_field', $value) : sanitize_text_field($value),
+//		};
+//	}
+
+//	protected function validate(string $name, mixed $value, array $field): bool|string {
+//		if (!empty($field['required']) && ($value === '' || $value === null)) {
+//			return $name.' is required';
+//		}
+//		if (isset($field['maxLength']) && is_string($value) && strlen($value) > $field['maxLength']) {
+//			return $name.' exceeds max length of '.$field['maxLength'];
+//		}
+//		if (isset($field['min']) && is_numeric($value) && $value < $field['min']) {
+//			return $name.' is below minimum of '.$field['min'];
+//		}
+//		if (isset($field['max']) && is_numeric($value) && $value > $field['max']) {
+//			return $name.' exceeds maximum of '.$field['max'];
+//		}
+//		if (in_array($field['type'], ['checkbox', 'set', 'radio', 'select'], true) && !empty($field['options'])) {
+//			foreach ((array)$value as $v) {
+//				if (!array_key_exists($v, $field['options'])) {
+//					return $name.': invalid option '.$v;
+//				}
+//			}
+//		}
+//		return true;
+//	}
+
+	/************************************************************************
+	 * REPEATER Helpers
+	************************************************************************/
+	public function repeater(string $name):Repeater
 	{
 		return new Repeater($this, $name);
 	}
-
-
-	protected function setByPath(string $path, mixed $value): self
+	protected function setByPath(string $path, mixed $value):bool
 	{
 		$parts = explode(':', $path, 3);
 		if (count($parts) !== 3) {
-			return $this;
+			$this->log('Could not set value by path');
+			return false;
 		}
-
 		[$repeaterName, $rowIndex, $subField] = $parts;
-		$this->repeater($repeaterName)->setField((int) $rowIndex, $subField, $value);
-
-		return $this;
+		$this->clearCache();
+		return $this->repeater($repeaterName)->setField((int) $rowIndex, $subField, $value);
 	}
 
-	protected function getByPath(string $path): mixed
+	protected function getByPath(string $path):mixed
 	{
 		$parts = explode(':', $path, 3);
 		if (count($parts) !== 3) {
@@ -600,123 +525,85 @@
 		[$repeaterName, $rowIndex, $subField] = $parts;
 		return $this->repeater($repeaterName)->field((int) $rowIndex, $subField);
 	}
-
-
+	/****************************************************************************************
+	 * GROUP helpers
+	****************************************************************************************/
 
 	public function group(string $name): Group
 	{
 		return new Group($this, $name);
 	}
 
-	protected function setGroup(string $name, mixed $value, bool $autosave = true): self
+	protected function setGroup(string $name, mixed $value):bool
 	{
-		$parent = strtok($name, '|');
-		$child = str_replace($parent . '|', '', $name);
-
-		$this->group($parent)->set($child, $value, $autosave);
-		return $this;
+		[$parent, $child] = explode('|', $name, 2);
+		$this->clearCache();
+		return $this->group($parent)->set($child, $value);
 	}
 
-	// ─────────────────────────────────────────────────────────────
-	// Utility Methods
-	// ─────────────────────────────────────────────────────────────
-
-
-	/**
-	 * Discard all unsaved changes
-	 */
-	public function reset(): self
+	/***************************************************************************************
+	 * UTILITY
+	***************************************************************************************/
+	protected function clearCache():void
 	{
-		$this->item->resetAll();
-		return $this;
+		match ($this->objectType) {
+			'post'	=> Cache::clearPost($this->ID),
+			'term'	=> Cache::clearTerm($this->ID),
+			'user'	=> Cache::clearUser($this->ID),
+		};
+	}
+	protected function isTaxonomy(array $field):bool
+	{
+		$type = $field['type']??'';
+		return $type === 'taxonomy' || ($type === 'selector' &&$field['subtype']??'' === 'taxonomy');
 	}
 
-
-	/**
-	 * Get field configuration
-	 */
-	public function config(string $name): ?array
-	{
-		return $this->fields[$name]->config??null;
-	}
-
-
-	/**
-	 * Get item ID
-	 */
-	public function id(): int|string|null
-	{
-		return $this->ID;
-	}
-
-	/**
-	 * Get object type (post, term, user, options)
-	 */
-	public function objectType(): string
-	{
-		return $this->type;
-	}
-
-	/**
-	 * Get content type (tattoo, artist, etc)
-	 */
-	public function contentType(): ?string
-	{
-		return $this->contentType;
-	}
-
-	public function item():Item
-	{
-		return $this->item;
-	}
-
-
-	// ─────────────────────────────────────────────────────────────
-	// Protected Helpers
-	// ─────────────────────────────────────────────────────────────
-
-	/**
-	 * Check for field update overrides
-	 */
-	public function checkOverrides(Field $field): bool
-	{
-		$name = $field->name;
-		$type = $field->type();
-		$value = $field->value;
-
-		do_action('jvb_meta_update', $name, $value, $this->item->objectType);
-
-		$overrides = [
-			BASE . 'update_' . $name,
-			BASE . 'update_' . $type,
-			'jvb_update_' . $name,
-			'jvb_update_' . $type,
-		];
-
-		foreach ($overrides as $override) {
-			if (function_exists($override)) {
-				$override($this->item->id, $value);
-				return true;
-			}
+	protected function getAllFieldNames(): array {
+		$names = static::$coreFields[$this->objectType];
+		if ($this->hasRegistrar()) {
+			$names = array_merge($names, array_keys(self::$registrars[$this->content]));
 		}
-
-		return false;
+		if ($this->product) {
+			$names = array_merge($names, $this->getAllProductFieldNames());
+		}
+		return array_unique($names);
 	}
 
-	/**
-	 * Get default value for a field type
-	 */
-	protected function getDefaultValue(string $name): string|int|bool|array
+	protected function hasRegistrar():bool
 	{
-		$config = $this->item->getFieldConfig($name);
-		$type = $config['type'] ?? 'text';
+		return array_key_exists($this->content, self::$registrars);
+	}
 
-		return match ($this->typeManager->getMetaType($type)) {
-			'object', 'array' => [],
-			'boolean' => false,
-			'integer' => 0,
-			default => '',
+	public function getFieldConfig(string $name): ?array {
+		if (!$this->hasRegistrar()) return null;
+		return self::$registrars[$this->content][$name] ?? null;
+	}
+
+	protected function getCoreDefault(string $name):string
+	{
+		return match($name) {
+			'post_status'				=> 'draft',
+			'post_date','post_modified'	=> date('mysql'),
+			'post_name'	=> sanitize_title($this->get('post_title')),
+			default => ''
 		};
 	}
 
+	protected function metaKey(string $name): string {
+		if ($this->product) {
+			if (in_array($name, $this->getAllProductFieldNames())) {
+				return $name;
+			}
+		}
+		return jvbCheckBase($name);
+	}
+
+	protected function log(string $message, array $context = []):void
+	{
+		$caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['function'] ?? '';
+		error_log('[Meta] '.$caller.' '.$message);
+		if (!empty($context)) {
+			error_log('    CONTEXT: '.print_r($context, true));
+		}
+	}
 }
diff --git a/inc/meta/MetaOld.php b/inc/meta/MetaOld.php
new file mode 100644
index 0000000..02c5f31
--- /dev/null
+++ b/inc/meta/MetaOld.php
@@ -0,0 +1,744 @@
+<?php
+namespace JVBase\meta;
+
+use JVBase\base\Options;
+use JVBase\registrar\Registrar;
+use WP_Post;
+use WP_Term;
+use WP_User;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+
+class MetaOld
+{
+	/**
+	 * @var string post, term, user, or options
+	 */
+	protected string $type;
+	/**
+	 * @var ?string the full slug, with BASE
+	 */
+	protected ?string $slug;
+
+	protected string $contentType;
+	protected Item $item;
+	protected Storage $storage;
+	protected Validator $validator;
+	protected Sanitizer $sanitizer;
+	protected array $fields;
+	protected WP_Post|WP_Term|WP_User|false|null $wpObject;
+	protected int|string $ID;
+	protected MetaTypeManager $typeManager;
+	protected static array $instances = ['post' => [],'term' => [], 'user'=>[],'option'=>[]];
+
+	protected array $defaults = ['post_thumbnail'];
+	/**
+	 * Create Meta instance for a post
+	 */
+	public static function forPost(int $id): self
+	{
+		if (array_key_exists($id, self::$instances['post'])) {
+			return self::$instances['post'][$id];
+		}
+		$new = new self($id, 'post');
+		self::$instances['post'][$id] = $new;
+		return $new;
+	}
+
+	/**
+	 * Create Meta instance for a term
+	 */
+	public static function forTerm(int $id): self
+	{
+		if (array_key_exists($id, self::$instances['term'])) {
+			return self::$instances['term'][$id];
+		}
+		$new = new self($id, 'term');
+		self::$instances['term'][$id] = $new;
+		return $new;
+	}
+
+	/**
+	 * Create Meta instance for a user
+	 */
+	public static function forUser(int $id): self
+	{
+		if (array_key_exists($id, self::$instances['user'])) {
+			return self::$instances['user'][$id];
+		}
+		$new = new self($id, 'user');
+		self::$instances['user'][$id] = $new;
+		return $new;
+	}
+
+	/**
+	 * Create Meta instance for options
+	 */
+	public static function forOptions(?string $baseKey = BASE): self
+	{
+		if (array_key_exists($baseKey, self::$instances['option'])) {
+			return self::$instances['option'][$baseKey];
+		}
+		$new = new self($baseKey, 'option');
+		self::$instances['option'][$baseKey] = $new;
+		return $new;
+	}
+	/***************************************************************
+	 * Constructor
+	***************************************************************/
+
+	public function __construct(int|string|null $id, string $type, array $fields = [])
+	{
+		$this->validator = new Validator();
+		$this->sanitizer = new Sanitizer();
+		$this->typeManager = new MetaTypeManager();
+		$this->type = $type;
+		$this->ID = $id;
+		$this->buildData($id, $type, $fields);
+	}
+
+	protected function buildData(int|string|null $id, string $type, array $fields):void
+	{
+		$this->wpObject = match($type) {
+			'post' 	=> get_post($id),
+			'term'	=> get_term($id),
+			'user', 'integrations' => get_userdata($id),
+			default => false
+		};
+
+		$this->slug = match($type) {
+			'post'	=> $this->wpObject->post_type,
+			'term'	=> $this->wpObject->taxonomy,
+			'user'	=> jvbUserRole($id),
+			default => null
+		};
+
+		$registrar = !is_null($this->slug) ? Registrar::getInstance($this->slug) : false;
+		$fields = $registrar ? $registrar->getFields() : $fields;
+		if ($this->type === 'post' && $this->wpObject && $this->wpObject->post_type === 'product') {
+			$fields = $this->getProductFields();
+		}
+
+		if ($this->type == 'option') {
+			$options = Options::getInstance();
+			$fields = $options->getFields();
+		}
+		$meta = match($type) {
+			'post'	=> get_post_meta($id),
+			'term'	=> get_term_meta($id),
+			'user'	=> get_user_meta($id),
+			default => []
+		};
+		if (!$meta) {
+			$meta = [];
+		}
+		$meta = array_map(fn($value) => maybe_unserialize($value[0]), $meta);
+
+
+		$this->fields = [];
+
+
+
+		foreach ($fields as $fieldName => $config) {
+			$fieldName = jvbNoBase($fieldName);
+			$value = '';
+			if ($this->type === 'option') {
+				$value = get_option(BASE . $fieldName, $config['default'] ?? '');
+			} else if ($this->wpObject && $this->wpObject->post_type === 'product') {
+				if (property_exists($this->wpObject, $fieldName)) {
+					if ($fieldName === 'post_thumbnail') {
+						$value = get_post_thumbnail_id($this->ID);
+					} else {
+						$value = $this->wpObject->$fieldName;
+					}
+				} else {
+					$product = wc_get_product($this->wpObject->ID);
+
+					$value = match ($fieldName) {
+						'sku'	=> $product->get_sku(),
+						'_price'	=> $product->get_price(),
+						'description'=> $product->get_short_description(),
+						'sale'	=> $product->get_sale_price(),
+						'post_thumbnail'	=> $product->get_image_id(),
+						'_product_images'	=> $product->get_gallery_image_ids(),
+						'_stock'	=> $product->get_stock_quantity(),
+						'_stock_status'	=> $product->get_stock_status(),
+						default => '',
+					};
+				}
+
+			} else if (
+				($this->wpObject && property_exists($this->wpObject, $fieldName))
+				|| ($type === 'user' && $this->wpObject && property_exists($this->wpObject->data, $fieldName))) {
+				$config['wp'] = true;
+				$value = $this->wpObject->$fieldName;
+
+			}  else if (in_array($fieldName, $this->defaults)) {
+				$config['wp'] = true;
+				switch ($fieldName) {
+					case 'post_thumbnail':
+						$value = get_post_thumbnail_id($this->ID);
+						break;
+				}
+			} else {
+				$value = array_key_exists(BASE.$fieldName, $meta) ? $meta[BASE.$fieldName] : $config['default']??'';
+				switch ($config['type']) {
+					case 'taxonomy':
+						if (!$config['isReference']??true) {
+							$config['wp'] = true;
+							$value = implode(',', wp_get_post_terms($this->ID, jvbCheckBase($config['taxonomy']), ['fields' => 'ids']));
+						}
+						break;
+					case 'selector':
+						if (array_key_exists('subtype', $config) && $config['subtype'] === 'taxonomy' && !$config['isReference']??true) {
+							$config['wp'] = true;
+							$value = implode(',',wp_get_post_terms($this->ID, jvbCheckBase($config['taxonomy']), ['fields' => 'ids']));
+						}
+						break;
+				}
+
+			}
+			$this->fields[$fieldName] = new Field($fieldName, $value, $config);
+		}
+	}
+
+		protected function getProductFields():array
+		{
+			$fields = [];
+			if (class_exists('WooCommerce') && $this->type === 'post' && $this->wpObject->post_type??'' === 'product') {
+				$fields['post_title'] = [
+					'type'	=> 'text',
+					'label'	=> 'Title',
+				];
+				$fields['post_content'] = [
+					'type'	=> 'text',
+					'label'	=> 'Content',
+				];
+				$fields['post_excerpt'] = [
+					'type'	=> 'text',
+					'label'	=> 'Short Description',
+				];
+				$fields['post_thumbnail'] = [
+					'type'	=> 'upload',
+					'multiple'	=> false,
+					'label'	=> 'Image',
+				];
+				$fields['_product_images'] = [
+					'type'	=> 'upload',
+					'label'	=> 'Gallery'
+				];
+				$fields['ID'] = [
+					'type'	=> 'text',
+					'label'	=> 'ID',
+				];
+
+
+				$fields['_stock'] = [
+					'type' => 'number',
+					'label' => 'Stock',
+					'default'	=> null
+				];
+				$fields['_stock_status'] = [
+					'type'	=> 'select',
+					'label'	=> 'Stock Status',
+					'default'	=> 'instock',
+					'options'	=> [
+						'instock'	=> 'In Stock',
+						'outofstock'	=> 'Out of Stock',
+						'onbackorder'		=> 'On Backorder'
+					]
+				];
+				$fields['_price'] = [
+					'type'		=> 'text',
+					'subtype'	=> 'number',
+					'label'		=>	'Price'
+				];
+
+
+				$product = wc_get_product($this->ID);
+
+				$fields['sku'] = [
+					'type'	=> 'text',
+					'label'	=> 'SKU',
+				];
+
+				$out = [];
+				if ($product && $product->is_type('variable')) {
+					$var = $product->get_children();
+					$var = array_filter(array_map(function($v) {
+						return wc_get_product($v);
+					}, $var));
+
+					$title= $product->get_title();
+					foreach ($var as $variation) {
+						$out[] = [
+							'id'	=> $variation->get_id(),
+							'sku'	=> $variation->get_sku(),
+							'title'	=> str_replace($title.' - ', '', $variation->get_name()),
+							'price'	=> $variation->get_price(),
+							'description'=> $variation->get_short_description(),
+							'sale'	=> $variation->get_sale_price(),
+							'image'	=> $variation->get_image_id(),
+							'stock'	=> $variation->get_stock_quantity(),
+							'stock_status'	=> $variation->get_stock_status()
+						];
+					}
+				}
+				if (!empty($out)) {
+					$this->fields['variations'] = new Field('variations', $out, [
+						'type'	=> 'repeater',
+						'label'	=> 'Variations',
+						'fields'	=> [
+							'id'	=> [
+								'type'	=> 'text',
+								'subtype'	=> 'number',
+								'label'	=> 'Variation ID',
+							],
+							'sku'	=> [
+								'type'	=> 'text',
+								'label'	=> 'Stock Keeping Unit (SKU)'
+							],
+							'title'	=> [
+								'type'	=> 'text',
+								'label'	=> 'Variation Title'
+							],
+							'price'	=> [
+								'type'	=> 'text',
+								'subtype'	=> 'number',
+								'label'	=> 'Variation Price'
+							],
+							'sale'	=> [
+								'type'	=> 'text',
+								'subtype'	=> 'number',
+								'label'	=> 'Sale Price',
+							],
+							'image'	=> [
+								'type'	=> 'text',
+								'subtype'	=> 'number',
+								'label'	=> 'Variation Image ID'
+							],
+							'stock'	=> [
+								'type'	=> 'text',
+								'label'	=> 'Stock Quantity'
+							],
+							'stock_status'	=> [
+								'type'	=> 'text',
+								'label'	=> 'Stock Status'
+							]
+						]
+					]);
+				}
+
+
+			}
+
+			return $fields;
+		}
+
+	// ─────────────────────────────────────────────────────────────
+	// Magic Methods for Fluent Access
+	// ─────────────────────────────────────────────────────────────
+
+	public function __get(string $name): mixed
+	{
+		return $this->get($name);
+	}
+
+	public function __set(string $name, mixed $value): void
+	{
+		$this->set($name, $value);
+	}
+
+	public function __isset(string $name): bool
+	{
+		return $this->item->hasField($name);
+	}
+
+	// ─────────────────────────────────────────────────────────────
+	// Core API
+	// ─────────────────────────────────────────────────────────────
+
+	/**
+	 * Get a field value
+	 */
+	public function get(string $name): mixed
+	{
+		// Handle repeater subfield path
+		if (str_contains($name, ':')) {
+			return $this->getByPath($name);
+		}
+		// Group shortcut path
+		if (str_contains($name, '|')) {
+			[$parent, $child] = explode('|', $name, 2);
+			return $this->group($parent)->get($child);
+		}
+		if (!array_key_exists($name, $this->fields)) {
+			error_log('[Meta]::get Attempted to get unregistered field: '.$name);
+			return '';
+		}
+		if (is_null($this->fields[$name])) {
+			error_log('[Meta]::get Field does not seem to be setup yet: '.$name);
+			return '';
+		}
+		return $this->fields[$name]->get()??'';
+	}
+
+	/**
+	 * Set a field value (validates & sanitizes by default)
+	 */
+	public function set(string $name, mixed $value, $autosave = true): self
+	{
+		// Handle repeater subfield path (e.g., "services:2:image")
+		if (str_contains($name, ':')) {
+			return $this->setByPath($name, $value);
+		}
+
+		// Group shortcut
+		if (str_contains($name, '|')) {
+			return $this->setGroup($name, $value, $autosave);
+		}
+
+		$field = $this->fields[$name]??false;
+		if (!$field) {
+			error_log('No config found for field: '.$name);
+			return $this;
+		}
+
+		// Validate
+		if (!$this->validator->validate($value, $field->config)) {
+			$field->addError("Validation failed for {$name}");
+			return $this;
+		}
+
+		// Sanitize
+		$value = $this->sanitizer->sanitize($value, $field->config);
+		$field->set($value);
+		if ($autosave && $field->isDirty) {
+			$this->save();
+		}
+
+		return $this;
+	}
+
+	/**
+	 * Get multiple fields
+	 */
+	public function getAll(array $fields = []): array
+	{
+		if (empty($fields) || $fields === ['all']) {
+			$fields = array_keys($this->fields);
+		}
+		$fields = array_filter($this->fields, function ($field) use ($fields) {
+			return in_array($field, $fields);
+		}, ARRAY_FILTER_USE_KEY);
+
+		return array_map(function ($field) {
+			return $field->value;
+		}, $fields);
+	}
+
+	/**
+	 * Set multiple fields
+	 */
+	public function setAll(array $data):bool
+	{
+		foreach ($data as $name => $value) {
+			$this->set($name, $value, false);
+		}
+		return $this->save();
+	}
+
+	/**
+	 * Save all dirty fields to database
+	 */
+	public function save(): bool
+	{
+		$dirtyFields = array_filter($this->fields, function ($field) {
+			return $field->isDirty;
+		});
+		$defaults = array_filter($dirtyFields, function ($field) {
+			return $field->isDefault;
+		});
+		$custom = array_filter($dirtyFields, function($field) {
+			return !$field->isDefault;
+		});
+
+		$success = true;
+
+		if (!empty($defaults)) {
+			$result = false;
+			switch ($this->type) {
+				case 'post':
+					//Deal with field exceptions, first, that cannot be set via wp_update_post
+					foreach ($defaults as $fieldName => $field) {
+						switch ($fieldName) {
+							case 'post_thumbnail':
+								$result = set_post_thumbnail($this->ID, $field->value);
+								unset($defaults[$fieldName]);
+								break;
+						}
+						//If it's a taxonomy, we use wp_set_object_terms
+						if (
+							($field->config['type'] === 'selector' && $field->config['subtype'] === 'taxonomy')
+							|| $field->config['type'] === 'taxonomy') {
+
+							$result = wp_set_object_terms($this->ID, array_map('absint', explode(',', $field->value)), jvbCheckBase($field->config['taxonomy']));
+							unset($defaults[$fieldName]);
+						}
+					}
+
+
+
+					if (!empty($defaults)) {
+						error_log('Remaining fields: '.print_r($defaults, true));
+						$defaults = array_map(function ($field) {
+							return $field->value;
+						}, $defaults);
+						error_log('Remaining values to save: '.print_r($defaults, true));
+						$data = array_merge([
+							'post_type'	=> $this->slug,
+							'ID'		=> $this->ID
+						], $defaults);
+						error_log('Updating post: '.print_r($data, true));
+						$result = wp_update_post($data);
+					}
+					break;
+				case 'term':
+					$termDefaults = array_map(fn($field) => $field->value, $defaults);
+					$result = wp_update_term($this->ID, $this->slug, $termDefaults);
+					break;
+				case 'user':
+					$userDefaults = array_map(fn($field) => $field->value, $defaults);
+					$data = array_merge(['ID' => $this->ID], $userDefaults);
+					$result = wp_update_user($data);
+					break;
+			}
+			if (!$result || is_wp_error($result)) {
+				$success = false;
+			}
+		}
+		if (!empty($custom)) {
+			$function = match ($this->type) {
+				'post' => 'update_post_meta',
+				'term' => 'update_term_meta',
+				'user' => 'update_user_meta',
+				'option' => 'update_option',
+				default => false,
+			};
+			if (!$function) {
+				error_log('[Meta]::save() Invalid type, cannot save: '.$this->type);
+				return false;
+			}
+			foreach ($custom as $field) {
+				if ($this->type === 'option') {
+					$result = update_option(BASE.$field->name, $field->value);
+				} else {
+					$result = $function($this->ID, BASE.$field->name, $field->value);
+				}
+
+				if (!$result) {
+					error_log('Problem saving field: '.$field->name.' with value: '.print_r($field->value, true));
+				}
+			}
+			//Now handled directly from Registrar
+//			if ($this->type === 'term' && Registrar::getInstance($this->slug)->hasFeature('is_content')) {
+//				update_term_meta($this->ID, BASE.'date_modified', date('Y-m-d H:i:s'));
+//			}
+		}
+
+
+		return $success;
+	}
+
+	/**
+	 * Delete a field value
+	 */
+	public function delete(string $name): bool
+	{
+		$field = $this->fields[$name]??false;
+		if (!$field) {
+			error_log('[Meta]::delete Could not delete field '.$name.': not registered');
+			return true;
+		}
+
+		if ($field->isTaxonomy()) {
+			wp_set_object_terms($this->ID, [], $this->slug);
+			return true;
+		}
+
+		return match ($this->type) {
+			'post'	=> delete_post_meta($this->ID, BASE.$name),
+			'term'	=> delete_term_meta($this->ID, BASE.$name),
+			'user', 'integrations' => delete_user_meta($this->ID, BASE.$name),
+			'option'	=> delete_option(BASE.$name),
+			default => false
+		};
+	}
+
+
+
+	/**
+	 * Delete multiple field values
+	 */
+	public function deleteAll(array $names): array
+	{
+		$results = [];
+		foreach ($names as $name) {
+			$results[$name] = $this->delete($name);
+		}
+		return $results;
+	}
+
+	/*****************************************************************
+	 * Repeater Access
+	*****************************************************************/
+
+	/**
+	 * Get repeater accessor for fluent repeater operations
+	 */
+	public function repeater(string $name): Repeater
+	{
+		return new Repeater($this, $name);
+	}
+
+
+	protected function setByPath(string $path, mixed $value): self
+	{
+		$parts = explode(':', $path, 3);
+		if (count($parts) !== 3) {
+			return $this;
+		}
+
+		[$repeaterName, $rowIndex, $subField] = $parts;
+		$this->repeater($repeaterName)->setField((int) $rowIndex, $subField, $value);
+
+		return $this;
+	}
+
+	protected function getByPath(string $path): mixed
+	{
+		$parts = explode(':', $path, 3);
+		if (count($parts) !== 3) {
+			return null;
+		}
+
+		[$repeaterName, $rowIndex, $subField] = $parts;
+		return $this->repeater($repeaterName)->field((int) $rowIndex, $subField);
+	}
+
+
+
+	public function group(string $name): Group
+	{
+		return new Group($this, $name);
+	}
+
+	protected function setGroup(string $name, mixed $value, bool $autosave = true): self
+	{
+		$parent = strtok($name, '|');
+		$child = str_replace($parent . '|', '', $name);
+
+		$this->group($parent)->set($child, $value, $autosave);
+		return $this;
+	}
+
+	// ─────────────────────────────────────────────────────────────
+	// Utility Methods
+	// ─────────────────────────────────────────────────────────────
+
+
+	/**
+	 * Discard all unsaved changes
+	 */
+	public function reset(): self
+	{
+		$this->item->resetAll();
+		return $this;
+	}
+
+
+	/**
+	 * Get field configuration
+	 */
+	public function config(string $name): ?array
+	{
+		return $this->fields[$name]->config??null;
+	}
+
+
+	/**
+	 * Get item ID
+	 */
+	public function id(): int|string|null
+	{
+		return $this->ID;
+	}
+
+	/**
+	 * Get object type (post, term, user, options)
+	 */
+	public function objectType(): string
+	{
+		return $this->type;
+	}
+
+	/**
+	 * Get content type (tattoo, artist, etc)
+	 */
+	public function contentType(): ?string
+	{
+		return $this->contentType;
+	}
+
+	public function item():Item
+	{
+		return $this->item;
+	}
+
+	/**
+	 * Check for field update overrides
+	 */
+	public function checkOverrides(Field $field): bool
+	{
+		$name = $field->name;
+		$type = $field->type();
+		$value = $field->value;
+
+		do_action('jvb_meta_update', $name, $value, $this->item->objectType);
+
+		$overrides = [
+			BASE . 'update_' . $name,
+			BASE . 'update_' . $type,
+			'jvb_update_' . $name,
+			'jvb_update_' . $type,
+		];
+
+		foreach ($overrides as $override) {
+			if (function_exists($override)) {
+				$override($this->item->id, $value);
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * Get default value for a field type
+	 */
+	protected function getDefaultValue(string $name): string|int|bool|array
+	{
+		$config = $this->item->getFieldConfig($name);
+		$type = $config['type'] ?? 'text';
+
+		return match ($this->typeManager->getMetaType($type)) {
+			'object', 'array' => [],
+			'boolean' => false,
+			'integer' => 0,
+			default => '',
+		};
+	}
+
+}
diff --git a/inc/meta/Repeater.php b/inc/meta/Repeater.php
index ae1622e..a387296 100644
--- a/inc/meta/Repeater.php
+++ b/inc/meta/Repeater.php
@@ -25,7 +25,7 @@
 		$this->meta = $meta;
 		$this->name = $name;
 		$this->data = $meta->get($name) ?: [];
-		$this->config = $meta->config($name) ?? [];
+		$this->config = $meta->getFieldConfig($name) ?? [];
 
 		// Ensure data is array
 		if (!is_array($this->data)) {
@@ -111,16 +111,14 @@
 	/**
 	 * Set field value in specific row
 	 */
-	public function setField(int $index, string $field, mixed $value): self
+	public function setField(int $index, string $field, mixed $value):bool
 	{
 		if (!isset($this->data[$index])) {
 			$this->data[$index] = [];
 		}
 
 		$this->data[$index][$field] = $value;
-		$this->sync();
-
-		return $this;
+		return $this->sync();
 	}
 
 	/**
@@ -374,9 +372,9 @@
 	/**
 	 * Sync data back to Meta instance
 	 */
-	protected function sync(): void
+	protected function sync(): bool
 	{
-		$this->meta->set($this->name, $this->data);
+		return $this->meta->set($this->name, $this->data);
 	}
 
 	/**

--
Gitblit v1.10.0