@fayz-ai/storefront 0.82.0 → 0.83.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analytics/meta-pixel.d.ts.map +1 -1
- package/dist/analytics/posthog.d.ts +3 -0
- package/dist/analytics/posthog.d.ts.map +1 -1
- package/dist/app/router.d.ts +2 -2
- package/dist/chunk-4REZOGGW.js +153 -0
- package/dist/chunk-4REZOGGW.js.map +1 -0
- package/dist/{chunk-UJHCVRK3.js → chunk-7N5HKQBM.js} +2 -2
- package/dist/{chunk-UJHCVRK3.js.map → chunk-7N5HKQBM.js.map} +1 -1
- package/dist/{chunk-GI5BTJK6.js → chunk-G2R6OJQA.js} +4 -4
- package/dist/{chunk-GI5BTJK6.js.map → chunk-G2R6OJQA.js.map} +1 -1
- package/dist/{chunk-RYWQGQ4M.js → chunk-OV6DVQMB.js} +128 -115
- package/dist/chunk-OV6DVQMB.js.map +1 -0
- package/dist/components/delivery/StoreCover.d.ts +0 -17
- package/dist/components/delivery/StoreCover.d.ts.map +1 -1
- package/dist/document/config.d.ts +7 -5
- package/dist/document/config.d.ts.map +1 -1
- package/dist/edge.d.ts +1 -1
- package/dist/edge.d.ts.map +1 -1
- package/dist/edge.js +16 -26
- package/dist/edge.js.map +1 -1
- package/dist/experiments/assign.d.ts +41 -53
- package/dist/experiments/assign.d.ts.map +1 -1
- package/dist/experiments/react.d.ts +4 -3
- package/dist/experiments/react.d.ts.map +1 -1
- package/dist/host/edge-handler.d.ts +15 -12
- package/dist/host/edge-handler.d.ts.map +1 -1
- package/dist/host.js +4 -4
- package/dist/index.js +7 -7
- package/dist/lib/theme.d.ts +2 -0
- package/dist/lib/theme.d.ts.map +1 -1
- package/dist/render.js +4 -4
- package/dist/tanstack.js +3 -3
- package/package.json +4 -4
- package/dist/chunk-746BEU7H.js +0 -160
- package/dist/chunk-746BEU7H.js.map +0 -1
- package/dist/chunk-RYWQGQ4M.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/locales/messages.ts","../src/document/config.ts","../src/app/router.ts","../src/app/static-render.ts","../src/blocks/page-data.tsx","../src/blocks/page-blocks.ts","../src/lib/seo.ts","../src/app/serving.ts","../src/data/menu-needs.ts"],"names":["createContext","useContext","React","useEffect","entry","getBlockMeta","dataNeedKey"],"mappings":";;;;;;;AAWO,IAAM,IAAA,GAAO;AAAA;AAAA,EAElB,gBAAA,EAAkB,2BAAA;AAAA,EAClB,sBAAA,EAAwB,kBAAA;AAAA,EACxB,iBAAA,EAAmB,iBAAA;AAAA,EACnB,eAAA,EAAiB,OAAA;AAAA,EACjB,sBAAA,EAAwB,oBAAA;AAAA,EACxB,kBAAA,EAAoB,OAAA;AAAA,EACpB,kBAAA,EAAoB,SAAA;AAAA,EACpB,kBAAA,EAAoB,WAAA;AAAA,EACpB,kBAAA,EAAoB,QAAA;AAAA;AAAA,EAEpB,wBAAA,EAA0B,8BAAA;AAAA,EAC1B,6BAAA,EAA+B,0BAAA;AAAA,EAC/B,uBAAA,EAAyB,SAAA;AAAA,EACzB,yBAAA,EAA2B,sBAAA;AAAA,EAC3B,0BAAA,EAA4B,MAAA;AAAA,EAC5B,8BAAA,EAAgC,+BAAA;AAAA,EAChC,8BAAA,EAAgC,yBAAA;AAAA,EAChC,wBAAA,EAA0B,QAAA;AAAA,EAC1B,uBAAA,EAAyB,eAAA;AAAA,EACzB,wBAAA,EAA0B,UAAA;AAAA,EAC1B,gCAAA,EAAkC,qBAAA;AAAA,EAClC,2BAAA,EAA6B,aAAA;AAAA,EAC7B,mCAAA,EAAqC,wBAAA;AAAA,EACrC,kCAAA,EAAoC,mDAAA;AAAA,EACpC,iCAAA,EAAmC,uBAAA;AAAA;AAAA,EAEnC,wBAAA,EAA0B,wBAAA;AAAA,EAC1B,+BAAA,EAAiC,mCAAA;AAAA,EACjC,2BAAA,EAA6B,aAAA;AAAA,EAC7B,yBAAA,EAA2B,8BAAA;AAAA,EAC3B,wBAAA,EAA0B,kCAAA;AAAA,EAC1B,4BAAA,EAA8B,8CAAA;AAAA,EAC9B,4BAAA,EAA8B,kCAAA;AAAA,EAC9B,2BAAA,EAA6B,kEAAA;AAAA,EAC7B,yBAAA,EAA2B,yCAAA;AAAA,EAC3B,mCAAA,EAAqC,gDAAA;AAAA,EACrC,2BAAA,EAA6B,sBAAA;AAAA,EAC7B,yBAAA,EAA2B,WAAA;AAAA,EAC3B,yBAAA,EAA2B,aAAA;AAAA;AAAA,EAE3B,2BAAA,EAA6B,wBAAA;AAAA,EAC7B,2BAAA,EAA6B,oBAAA;AAAA,EAC7B,8BAAA,EAAgC,4EAAA;AAAA,EAChC,wBAAA,EAA0B,WAAA;AAAA,EAC1B,wBAAA,EAA0B,oBAAA;AAAA,EAC1B,6BAAA,EAA+B,kEAAA;AAAA,EAC/B,6BAAA,EAA+B,0BAAA;AAAA,EAC/B,8BAAA,EAAgC,6DAAA;AAAA,EAChC,qCAAA,EAAuC,wEAAA;AAAA,EACvC,mBAAA,EAAqB,KAAA;AAAA,EACrB,kBAAA,EAAoB,8DAAA;AAAA,EACpB,2BAAA,EAA6B,yBAAA;AAAA,EAC7B,0BAAA,EAA4B,uBAAA;AAAA,EAC5B,0BAAA,EAA4B,wBAAA;AAAA,EAC5B,yBAAA,EAA2B,uBAAA;AAAA,EAC3B,sBAAA,EAAwB,QAAA;AAAA,EACxB,qBAAA,EAAuB,gDAAA;AAAA,EACvB,oBAAA,EAAsB,UAAA;AAAA,EACtB,mBAAA,EAAqB,sBAAA;AAAA,EACrB,qBAAA,EAAuB,qBAAA;AAAA,EACvB,oBAAA,EAAsB,kDAAA;AAAA;AAAA,EAEtB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,oBAAA,EAAsB,mDAAA;AAAA,EACtB,yBAAA,EAA2B,gBAAA;AAAA;AAAA,EAE3B,6BAAA,EAA+B,0BAAA;AAAA,EAC/B,sBAAA,EAAwB,iCAAA;AAAA,EACxB,wBAAA,EAA0B,kBAAA;AAAA,EAC1B,qBAAA,EAAuB,oBAAA;AAAA;AAAA,EAEvB,eAAA,EAAiB,kBAAA;AAAA,EACjB,kBAAA,EAAoB,UAAA;AAAA,EACpB,kBAAA,EAAoB,UAAA;AAAA,EACpB,kBAAA,EAAoB,SAAA;AAAA,EACpB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,eAAA,EAAiB,UAAA;AAAA,EACjB,cAAA,EAAgB,WAAA;AAAA,EAChB,eAAA,EAAiB,OAAA;AAAA,EACjB,mBAAA,EAAqB,0CAAA;AAAA,EACrB,kBAAA,EAAoB,OAAA;AAAA;AAAA,EAEpB,sBAAA,EAAwB,mBAAA;AAAA,EACxB,gBAAA,EAAkB,SAAA;AAAA,EAClB,uBAAA,EAAyB,iBAAA;AAAA,EACzB,qBAAA,EAAuB,0BAAA;AAAA,EACvB,kBAAA,EAAoB,gCAAA;AAAA,EACpB,uBAAA,EAAyB,iBAAA;AAAA,EACzB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,uBAAA,EAAyB,mBAAA;AAAA,EACzB,oBAAA,EAAsB,0CAAA;AAAA,EACtB,yBAAA,EAA2B,8CAAA;AAAA,EAC3B,8BAAA,EAAgC,oCAAA;AAAA,EAChC,mBAAA,EAAqB,oCAAA;AAAA;AAAA,EAErB,eAAA,EAAiB,aAAA;AAAA,EACjB,aAAA,EAAe,QAAA;AAAA,EACf,eAAA,EAAiB,2BAAA;AAAA;AAAA,EAEjB,uBAAA,EAAyB,wEAAA;AAAA,EACzB,aAAA,EAAe,8BAAA;AAAA,EACf,YAAA,EAAc,4BAAA;AAAA,EACd,aAAA,EAAe,iCAAA;AAAA,EACf,uBAAA,EAAyB,uDAAA;AAAA,EACzB,uBAAA,EAAyB,qCAAA;AAAA,EACzB,oBAAA,EAAsB,iDAAA;AAAA,EACtB,eAAA,EAAiB,iDAAA;AAAA,EACjB,cAAA,EAAgB,mCAAA;AAAA,EAChB,kBAAA,EAAoB,sCAAA;AAAA,EACpB,aAAA,EAAe,yCAAA;AAAA,EACf,qBAAA,EAAuB,gDAAA;AAAA,EACvB,cAAA,EAAgB,wBAAA;AAAA,EAChB,mBAAA,EAAqB,0DAAA;AAAA,EACrB,gBAAA,EAAkB,6DAAA;AAAA,EAClB,uBAAA,EAAyB,qFAAA;AAAA,EACzB,kBAAA,EAAoB,2EAAA;AAAA,EACpB,kBAAA,EAAoB,2CAAA;AAAA;AAAA,EAEpB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,oBAAA,EAAsB,UAAA;AAAA,EACtB,sBAAA,EAAwB,KAAA;AAAA,EACxB,iBAAA,EAAmB,YAAA;AAAA,EACnB,mBAAA,EAAqB,oCAAA;AAAA,EACrB,kBAAA,EAAoB,6CAAA;AAAA,EACpB,iBAAA,EAAmB,wEAAA;AAAA,EACnB,kBAAA,EAAoB,mBAAA;AAAA,EACpB,mBAAA,EAAqB,iCAAA;AAAA,EACrB,kBAAA,EAAoB,8BAAA;AAAA,EACpB,mBAAA,EAAqB,qCAAA;AAAA,EACrB,uBAAA,EAAyB,gCAAA;AAAA,EACzB,uBAAA,EAAyB,gDAAA;AAAA,EACzB,sBAAA,EAAwB,+DAAA;AAAA,EACxB,yBAAA,EAA2B,+CAAA;AAAA;AAAA,EAE3B,YAAA,EAAc,UAAA;AAAA,EACd,YAAA,EAAc,iBAAA;AAAA,EACd,YAAA,EAAc,6BAAA;AAAA,EACd,aAAA,EAAe,kBAAA;AAAA,EACf,eAAA,EAAiB,kBAAA;AAAA,EACjB,qBAAA,EAAuB,wCAAA;AAAA,EACvB,cAAA,EAAgB,iCAAA;AAAA,EAChB,mBAAA,EAAqB,gEAAA;AAAA,EACrB,cAAA,EAAgB,0BAAA;AAAA,EAChB,kBAAA,EAAoB,gCAAA;AAAA,EACpB,iBAAA,EAAmB,6BAAA;AAAA,EACnB,qBAAA,EAAuB,yEAAA;AAAA;AAAA,EAEvB,mBAAA,EAAqB,aAAA;AAAA,EACrB,gBAAA,EAAkB,gBAAA;AAAA,EAClB,eAAA,EAAiB;AACnB,CAAA;AAKA,IAAM,EAAA,GAAwB;AAAA,EAC5B,sBAAA,EAAwB,eAAA;AAAA,EACxB,iBAAA,EAAmB,iBAAA;AAAA,EACnB,eAAA,EAAiB,MAAA;AAAA,EACjB,sBAAA,EAAwB,gBAAA;AAAA,EACxB,kBAAA,EAAoB,SAAA;AAAA,EACpB,kBAAA,EAAoB,UAAA;AAAA,EACpB,kBAAA,EAAoB,SAAA;AAAA,EACpB,kBAAA,EAAoB,MAAA;AAAA,EACpB,wBAAA,EAA0B,qBAAA;AAAA,EAC1B,6BAAA,EAA+B,wBAAA;AAAA,EAC/B,uBAAA,EAAyB,QAAA;AAAA,EACzB,yBAAA,EAA2B,UAAA;AAAA,EAC3B,0BAAA,EAA4B,UAAA;AAAA,EAC5B,8BAAA,EAAgC,8BAAA;AAAA,EAChC,8BAAA,EAAgC,0BAAA;AAAA,EAChC,wBAAA,EAA0B,OAAA;AAAA,EAC1B,uBAAA,EAAyB,WAAA;AAAA,EACzB,wBAAA,EAA0B,OAAA;AAAA,EAC1B,gCAAA,EAAkC,kBAAA;AAAA,EAClC,2BAAA,EAA6B,QAAA;AAAA,EAC7B,mCAAA,EAAqC,mBAAA;AAAA,EACrC,kCAAA,EAAoC,uDAAA;AAAA,EACpC,iCAAA,EAAmC,8BAAA;AAAA,EACnC,wBAAA,EAA0B,kBAAA;AAAA,EAC1B,+BAAA,EAAiC,8BAAA;AAAA,EACjC,2BAAA,EAA6B,UAAA;AAAA,EAC7B,yBAAA,EAA2B,qBAAA;AAAA,EAC3B,wBAAA,EAA0B,4BAAA;AAAA,EAC1B,4BAAA,EAA8B,wCAAA;AAAA,EAC9B,4BAAA,EAA8B,6BAAA;AAAA,EAC9B,2BAAA,EAA6B,2DAAA;AAAA,EAC7B,yBAAA,EAA2B,mCAAA;AAAA,EAC3B,mCAAA,EAAqC,uCAAA;AAAA,EACrC,2BAAA,EAA6B,sBAAA;AAAA,EAC7B,yBAAA,EAA2B,QAAA;AAAA,EAC3B,yBAAA,EAA2B,SAAA;AAAA,EAC3B,2BAAA,EAA6B,uBAAA;AAAA,EAC7B,2BAAA,EAA6B,qBAAA;AAAA,EAC7B,8BAAA,EAAgC,qFAAA;AAAA,EAChC,wBAAA,EAA0B,SAAA;AAAA,EAC1B,wBAAA,EAA0B,gBAAA;AAAA,EAC1B,6BAAA,EAA+B,uEAAA;AAAA,EAC/B,6BAAA,EAA+B,yBAAA;AAAA,EAC/B,8BAAA,EAAgC,uDAAA;AAAA,EAChC,qCAAA,EAAuC,2DAAA;AAAA,EACvC,kBAAA,EAAoB,mDAAA;AAAA,EACpB,2BAAA,EAA6B,aAAA;AAAA,EAC7B,0BAAA,EAA4B,0BAAA;AAAA,EAC5B,0BAAA,EAA4B,YAAA;AAAA,EAC5B,yBAAA,EAA2B,0BAAA;AAAA,EAC3B,qBAAA,EAAuB,kCAAA;AAAA,EACvB,oBAAA,EAAsB,MAAA;AAAA,EACtB,mBAAA,EAAqB,iBAAA;AAAA,EACrB,qBAAA,EAAuB,wBAAA;AAAA,EACvB,oBAAA,EAAsB,+CAAA;AAAA,EACtB,qBAAA,EAAuB,oBAAA;AAAA,EACvB,oBAAA,EAAsB,yDAAA;AAAA,EACtB,yBAAA,EAA2B,eAAA;AAAA,EAC3B,6BAAA,EAA+B,sBAAA;AAAA,EAC/B,sBAAA,EAAwB,2BAAA;AAAA,EACxB,wBAAA,EAA0B,iBAAA;AAAA,EAC1B,qBAAA,EAAuB,cAAA;AAAA,EACvB,eAAA,EAAiB,eAAA;AAAA,EACjB,kBAAA,EAAoB,UAAA;AAAA,EACpB,kBAAA,EAAoB,UAAA;AAAA,EACpB,gBAAA,EAAkB,cAAA;AAAA,EAClB,eAAA,EAAiB,QAAA;AAAA,EACjB,cAAA,EAAgB,MAAA;AAAA,EAChB,mBAAA,EAAqB,qCAAA;AAAA,EACrB,kBAAA,EAAoB,UAAA;AAAA,EACpB,sBAAA,EAAwB,eAAA;AAAA,EACxB,gBAAA,EAAkB,OAAA;AAAA,EAClB,uBAAA,EAAyB,eAAA;AAAA,EACzB,qBAAA,EAAuB,kBAAA;AAAA,EACvB,kBAAA,EAAoB,+BAAA;AAAA,EACpB,uBAAA,EAAyB,eAAA;AAAA,EACzB,kBAAA,EAAoB,eAAA;AAAA,EACpB,uBAAA,EAAyB,cAAA;AAAA,EACzB,oBAAA,EAAsB,+BAAA;AAAA,EACtB,yBAAA,EAA2B,6CAAA;AAAA,EAC3B,8BAAA,EAAgC,iCAAA;AAAA,EAChC,mBAAA,EAAqB,wBAAA;AAAA,EACrB,eAAA,EAAiB,SAAA;AAAA,EACjB,aAAA,EAAe,OAAA;AAAA,EACf,eAAA,EAAiB,SAAA;AAAA,EACjB,uBAAA,EAAyB,8EAAA;AAAA,EACzB,aAAA,EAAe,sBAAA;AAAA,EACf,YAAA,EAAc,uBAAA;AAAA,EACd,aAAA,EAAe,+BAAA;AAAA,EACf,uBAAA,EAAyB,0CAAA;AAAA,EACzB,uBAAA,EAAyB,gCAAA;AAAA,EACzB,oBAAA,EAAsB,0CAAA;AAAA,EACtB,eAAA,EAAiB,yCAAA;AAAA,EACjB,cAAA,EAAgB,+BAAA;AAAA,EAChB,kBAAA,EAAoB,8BAAA;AAAA,EACpB,aAAA,EAAe,4CAAA;AAAA,EACf,qBAAA,EAAuB,2CAAA;AAAA,EACvB,cAAA,EAAgB,uBAAA;AAAA,EAChB,mBAAA,EAAqB,+DAAA;AAAA,EACrB,gBAAA,EAAkB,qEAAA;AAAA,EAClB,uBAAA,EAAyB,8EAAA;AAAA,EACzB,kBAAA,EAAoB,sEAAA;AAAA,EACpB,kBAAA,EAAoB,sCAAA;AAAA,EACpB,gBAAA,EAAkB,mBAAA;AAAA,EAClB,oBAAA,EAAsB,UAAA;AAAA,EACtB,sBAAA,EAAwB,aAAA;AAAA,EACxB,iBAAA,EAAmB,oBAAA;AAAA,EACnB,mBAAA,EAAqB,gDAAA;AAAA,EACrB,kBAAA,EAAoB,kDAAA;AAAA,EACpB,iBAAA,EAAmB,2EAAA;AAAA,EACnB,kBAAA,EAAoB,mBAAA;AAAA,EACpB,mBAAA,EAAqB,kCAAA;AAAA,EACrB,kBAAA,EAAoB,0BAAA;AAAA,EACpB,mBAAA,EAAqB,qCAAA;AAAA,EACrB,uBAAA,EAAyB,gCAAA;AAAA,EACzB,uBAAA,EAAyB,2CAAA;AAAA,EACzB,sBAAA,EAAwB,2DAAA;AAAA,EACxB,yBAAA,EAA2B,2CAAA;AAAA,EAC3B,YAAA,EAAc,MAAA;AAAA,EACd,YAAA,EAAc,YAAA;AAAA,EACd,YAAA,EAAc,qBAAA;AAAA,EACd,aAAA,EAAe,iBAAA;AAAA,EACf,eAAA,EAAiB,UAAA;AAAA,EACjB,qBAAA,EAAuB,oCAAA;AAAA,EACvB,cAAA,EAAgB,wBAAA;AAAA,EAChB,mBAAA,EAAqB,4DAAA;AAAA,EACrB,cAAA,EAAgB,2BAAA;AAAA,EAChB,kBAAA,EAAoB,8BAAA;AAAA,EACpB,iBAAA,EAAmB,2BAAA;AAAA,EACnB,qBAAA,EAAuB,6DAAA;AAAA,EACvB,mBAAA,EAAqB,YAAA;AAAA,EACrB,gBAAA,EAAkB,gBAAA;AAAA,EAClB,eAAA,EAAiB;AACnB,CAAA;AAEA,IAAM,EAAA,GAAwB;AAAA,EAC5B,sBAAA,EAAwB,oBAAA;AAAA,EACxB,iBAAA,EAAmB,aAAA;AAAA,EACnB,eAAA,EAAiB,OAAA;AAAA,EACjB,sBAAA,EAAwB,gBAAA;AAAA,EACxB,kBAAA,EAAoB,OAAA;AAAA,EACpB,kBAAA,EAAoB,UAAA;AAAA,EACpB,kBAAA,EAAoB,MAAA;AAAA,EACpB,kBAAA,EAAoB,OAAA;AAAA,EACpB,wBAAA,EAA0B,mBAAA;AAAA,EAC1B,6BAAA,EAA+B,uCAAA;AAAA,EAC/B,uBAAA,EAAyB,SAAA;AAAA,EACzB,yBAAA,EAA2B,oBAAA;AAAA,EAC3B,0BAAA,EAA4B,OAAA;AAAA,EAC5B,8BAAA,EAAgC,4BAAA;AAAA,EAChC,8BAAA,EAAgC,8BAAA;AAAA,EAChC,wBAAA,EAA0B,OAAA;AAAA,EAC1B,uBAAA,EAAyB,iBAAA;AAAA,EACzB,wBAAA,EAA0B,aAAA;AAAA,EAC1B,gCAAA,EAAkC,wBAAA;AAAA,EAClC,2BAAA,EAA6B,SAAA;AAAA,EAC7B,mCAAA,EAAqC,oBAAA;AAAA,EACrC,kCAAA,EAAoC,uDAAA;AAAA,EACpC,iCAAA,EAAmC,uBAAA;AAAA,EACnC,wBAAA,EAA0B,0BAAA;AAAA,EAC1B,+BAAA,EAAiC,oCAAA;AAAA,EACjC,2BAAA,EAA6B,cAAA;AAAA,EAC7B,yBAAA,EAA2B,oCAAA;AAAA,EAC3B,wBAAA,EAA0B,oCAAA;AAAA,EAC1B,4BAAA,EAA8B,yCAAA;AAAA,EAC9B,4BAAA,EAA8B,gCAAA;AAAA,EAC9B,2BAAA,EAA6B,iEAAA;AAAA,EAC7B,yBAAA,EAA2B,yCAAA;AAAA,EAC3B,mCAAA,EAAqC,oDAAA;AAAA,EACrC,2BAAA,EAA6B,sBAAA;AAAA,EAC7B,yBAAA,EAA2B,YAAA;AAAA,EAC3B,yBAAA,EAA2B,UAAA;AAAA,EAC3B,2BAAA,EAA6B,uBAAA;AAAA,EAC7B,2BAAA,EAA6B,mBAAA;AAAA,EAC7B,8BAAA,EAAgC,wEAAA;AAAA,EAChC,wBAAA,EAA0B,MAAA;AAAA,EAC1B,wBAAA,EAA0B,eAAA;AAAA,EAC1B,6BAAA,EAA+B,kEAAA;AAAA,EAC/B,6BAAA,EAA+B,0BAAA;AAAA,EAC/B,8BAAA,EAAgC,oEAAA;AAAA,EAChC,qCAAA,EAAuC,4DAAA;AAAA,EACvC,kBAAA,EAAoB,oDAAA;AAAA,EACpB,2BAAA,EAA6B,uBAAA;AAAA,EAC7B,0BAAA,EAA4B,2BAAA;AAAA,EAC5B,0BAAA,EAA4B,sBAAA;AAAA,EAC5B,yBAAA,EAA2B,2BAAA;AAAA,EAC3B,qBAAA,EAAuB,2CAAA;AAAA,EACvB,oBAAA,EAAsB,UAAA;AAAA,EACtB,mBAAA,EAAqB,oBAAA;AAAA,EACrB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,oBAAA,EAAsB,iDAAA;AAAA,EACtB,qBAAA,EAAuB,sBAAA;AAAA,EACvB,oBAAA,EAAsB,wDAAA;AAAA,EACtB,yBAAA,EAA2B,eAAA;AAAA,EAC3B,6BAAA,EAA+B,uBAAA;AAAA,EAC/B,sBAAA,EAAwB,wBAAA;AAAA,EACxB,wBAAA,EAA0B,oBAAA;AAAA,EAC1B,qBAAA,EAAuB,mBAAA;AAAA,EACvB,eAAA,EAAiB,oBAAA;AAAA,EACjB,kBAAA,EAAoB,WAAA;AAAA,EACpB,kBAAA,EAAoB,UAAA;AAAA,EACpB,gBAAA,EAAkB,oBAAA;AAAA,EAClB,eAAA,EAAiB,WAAA;AAAA,EACjB,cAAA,EAAgB,QAAA;AAAA,EAChB,mBAAA,EAAqB,oCAAA;AAAA,EACrB,kBAAA,EAAoB,UAAA;AAAA,EACpB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,gBAAA,EAAkB,SAAA;AAAA,EAClB,uBAAA,EAAyB,iBAAA;AAAA,EACzB,qBAAA,EAAuB,2BAAA;AAAA,EACvB,kBAAA,EAAoB,gCAAA;AAAA,EACpB,uBAAA,EAAyB,yBAAA;AAAA,EACzB,kBAAA,EAAoB,yBAAA;AAAA,EACpB,uBAAA,EAAyB,wBAAA;AAAA,EACzB,oBAAA,EAAsB,8CAAA;AAAA,EACtB,yBAAA,EAA2B,+CAAA;AAAA,EAC3B,8BAAA,EAAgC,sCAAA;AAAA,EAChC,mBAAA,EAAqB,0CAAA;AAAA,EACrB,eAAA,EAAiB,YAAA;AAAA,EACjB,aAAA,EAAe,aAAA;AAAA,EACf,eAAA,EAAiB,cAAA;AAAA,EACjB,uBAAA,EAAyB,6EAAA;AAAA,EACzB,aAAA,EAAe,4BAAA;AAAA,EACf,YAAA,EAAc,4BAAA;AAAA,EACd,aAAA,EAAe,oCAAA;AAAA,EACf,uBAAA,EAAyB,gDAAA;AAAA,EACzB,uBAAA,EAAyB,oCAAA;AAAA,EACzB,oBAAA,EAAsB,4CAAA;AAAA,EACtB,eAAA,EAAiB,mDAAA;AAAA,EACjB,cAAA,EAAgB,wCAAA;AAAA,EAChB,kBAAA,EAAoB,6BAAA;AAAA,EACpB,aAAA,EAAe,4CAAA;AAAA,EACf,qBAAA,EAAuB,gDAAA;AAAA,EACvB,cAAA,EAAgB,0BAAA;AAAA,EAChB,mBAAA,EAAqB,+DAAA;AAAA,EACrB,gBAAA,EAAkB,+EAAA;AAAA,EAClB,uBAAA,EAAyB,8FAAA;AAAA,EACzB,kBAAA,EAAoB,mFAAA;AAAA,EACpB,kBAAA,EAAoB,sCAAA;AAAA,EACpB,gBAAA,EAAkB,mBAAA;AAAA,EAClB,oBAAA,EAAsB,UAAA;AAAA,EACtB,sBAAA,EAAwB,kBAAA;AAAA,EACxB,iBAAA,EAAmB,0BAAA;AAAA,EACnB,mBAAA,EAAqB,iDAAA;AAAA,EACrB,kBAAA,EAAoB,8CAAA;AAAA,EACpB,iBAAA,EAAmB,mEAAA;AAAA,EACnB,kBAAA,EAAoB,iBAAA;AAAA,EACpB,mBAAA,EAAqB,yCAAA;AAAA,EACrB,kBAAA,EAAoB,iCAAA;AAAA,EACpB,mBAAA,EAAqB,oCAAA;AAAA,EACrB,uBAAA,EAAyB,mCAAA;AAAA,EACzB,uBAAA,EAAyB,gDAAA;AAAA,EACzB,sBAAA,EAAwB,oEAAA;AAAA,EACxB,yBAAA,EAA2B,wDAAA;AAAA,EAC3B,YAAA,EAAc,SAAA;AAAA,EACd,YAAA,EAAc,gBAAA;AAAA,EACd,YAAA,EAAc,8BAAA;AAAA,EACd,aAAA,EAAe,iBAAA;AAAA,EACf,eAAA,EAAiB,kBAAA;AAAA,EACjB,qBAAA,EAAuB,8CAAA;AAAA,EACvB,cAAA,EAAgB,6BAAA;AAAA,EAChB,mBAAA,EAAqB,mEAAA;AAAA,EACrB,cAAA,EAAgB,6BAAA;AAAA,EAChB,mBAAA,EAAqB,UAAA;AAAA,EACrB,gBAAA,EAAkB,iBAAA;AAAA,EAClB,eAAA,EAAiB;AACnB,CAAA;AAEO,IAAM,QAAA,GAA0D,EAAE,OAAA,EAAS,IAAA,EAAM,IAAI,EAAA;AAGrF,SAAS,kBAAkB,KAAA,EAAkD;AAClF,EAAA,MAAM,IAAA,GAAA,CAAQ,SAAS,EAAA,EAAI,WAAA,GAAc,KAAA,CAAM,MAAM,EAAE,CAAC,CAAA;AACxD,EAAA,IAAI,IAAA,KAAS,MAAM,OAAO,OAAA;AAC1B,EAAA,IAAI,IAAA,KAAS,MAAM,OAAO,IAAA;AAC1B,EAAA,IAAI,IAAA,KAAS,MAAM,OAAO,IAAA;AAC1B,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,SAAA,CACd,QAAA,EACA,GAAA,EACA,IAAA,EACA,SAAA,EACQ;AACR,EAAA,IAAI,OAAO,SAAA,GAAY,QAAQ,CAAA,GAAI,GAAG,KAAK,QAAA,CAAS,QAAQ,CAAA,GAAI,GAAG,KAAK,SAAA,GAAY,OAAO,IAAI,GAAG,CAAA,IAAK,KAAK,GAAG,CAAA;AAC/G,EAAA,IAAI,IAAA,aAAiB,CAAC,IAAA,EAAM,KAAK,CAAA,IAAK,MAAA,CAAO,QAAQ,IAAI,CAAA,SAAU,IAAA,CAAK,KAAA,CAAM,KAAK,IAAI,CAAA,EAAA,CAAI,EAAE,IAAA,CAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAC/G,EAAA,OAAO,IAAA;AACT;ACmBA,SAAS,iBAAiB,MAAA,EAA2E;AACnG,EAAA,MAAM,SAAA,GAAY,CAAC,GAAG,IAAI,KAAK,MAAA,CAAO,SAAA,IAAa,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,MAAK,CAAE,WAAA,EAAa,CAAA,CAAE,MAAA,CAAO,OAAO,CAAC,CAAC,CAAA;AAC1G,EAAA,IAAI,SAAA,CAAU,MAAA,KAAW,CAAA,EAAG,SAAA,CAAU,KAAK,IAAI,CAAA;AAC/C,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,cAAA,EAAgB,IAAA,GAAO,WAAA,EAAY;AACzD,EAAA,OAAO,EAAE,SAAA,EAAW,cAAA,EAAgB,MAAA,IAAU,SAAA,CAAU,QAAA,CAAS,MAAM,CAAA,GAAI,MAAA,GAAS,SAAA,CAAU,CAAC,CAAA,EAAG;AACpG;AAEO,SAAS,cAAc,MAAA,EAAoD;AAIhF,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,KAAA,EAAO,IAAA,KAAS,MAAA,CAAO,IAAA,GAAO,EAAE,MAAA,EAAQ,MAAA,CAAO,IAAA,CAAK,QAAA,EAAS,GAAI,MAAA,CAAA;AACzF,EAAA,MAAM,YAAA,GAAe,OAAO,YAAA,IAAgB,UAAA;AAI5C,EAAA,MAAM,WAAA,GAAc,iBAAiB,UAAA,GAChC,MAAA,CAAO,UAAU,QAAA,IAAY,OAAA,GAC9B,WAAW,UAAA,GAAa,GAAA;AAI5B,EAAA,MAAM,eAAA,GAAkB,YAAA,KAAiB,UAAA,IAAc,YAAA,KAAiB,UAAA;AACxE,EAAA,OAAO;AAAA,IACL,GAAG,MAAA;AAAA,IACH,KAAA,EAAO,EAAE,GAAG,MAAA,CAAO,KAAA,EAAO,GAAI,QAAA,GAAW,EAAE,IAAA,EAAM,QAAA,EAAS,GAAI,EAAC,EAAG;AAAA,IAClE,QAAA,EAAU,OAAO,QAAA,IAAY,KAAA;AAAA,IAC7B,MAAA,EAAQ,OAAO,MAAA,IAAU,OAAA;AAAA,IACzB,QAAA,EAAU,iBAAA,CAAkB,MAAA,CAAO,QAAQ,CAAA,IAAK,OAAA;AAAA,IAChD,GAAG,iBAAiB,MAAM,CAAA;AAAA,IAC1B,QAAA,EAAU,EAAE,QAAA,EAAU,MAAA,CAAO,QAAA,EAAU,YAAY,CAAA,EAAG,SAAA,EAAW,MAAA,CAAO,QAAA,EAAU,SAAA,EAAU;AAAA,IAC5F,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,MAAA,CAAO,QAAA,EAAU,IAAA,IAAQ,MAAA;AAAA,MAC/B,OAAA,EAAS,MAAA,CAAO,QAAA,EAAU,OAAA,EAAS,MAAA,GAAS,MAAA,CAAO,QAAA,CAAS,OAAA,GAAU,CAAC,KAAA,EAAO,aAAA,EAAe,MAAM,CAAA;AAAA;AAAA;AAAA;AAAA,MAInG,KAAA,EAAO,OAAO,QAAA,EAAU;AAAA,KAC1B;AAAA,IACA,YAAA;AAAA;AAAA;AAAA,IAGA,QAAA,EAAU,iBAAiB,UAAA,GACvB;AAAA,MACE,QAAA,EAAU,MAAA,CAAO,QAAA,EAAU,QAAA,IAAY,OAAA;AAAA,MACvC,UAAA,EAAY,OAAO,QAAA,EAAU,UAAA;AAAA,MAC7B,SAAA,EAAW,OAAO,QAAA,EAAU,SAAA;AAAA,MAC5B,SAAA,EAAW,OAAO,QAAA,EAAU,SAAA;AAAA,MAC5B,QAAA,EAAU,OAAO,QAAA,EAAU,QAAA;AAAA,MAC3B,cAAA,EAAgB,OAAO,QAAA,EAAU,cAAA;AAAA;AAAA,MAEjC,gBAAA,EAAkB,MAAA,CAAO,QAAA,EAAU,gBAAA,EAAkB,MAAA,GACjD,MAAA,CAAO,QAAA,CAAS,gBAAA,GACf,CAAC,UAAU,CAAA,CAAiD,KAAA,EAAM;AAAA;AAAA;AAAA;AAAA,MAIvE,UAAA,EAAY,MAAA,CAAO,QAAA,EAAU,UAAA,IAAc,KAAA;AAAA,MAC3C,aAAA,EAAe,OAAO,QAAA,EAAU;AAAA,KAClC,GACA,MAAA;AAAA,IACJ,OAAA,EAAS;AAAA,MACP,KAAA,EAAO,MAAA,CAAO,OAAA,EAAS,KAAA,IAAS,YAAA;AAAA,MAChC,cAAA,EAAgB,MAAA,CAAO,OAAA,EAAS,cAAA,IAAkB,mCAAA;AAAA,MAClD,aAAA,EAAe,MAAA,CAAO,OAAA,EAAS,aAAA,IAAiB,iBAAA;AAAA,MAChD,KAAA,EAAO,OAAO,OAAA,EAAS,KAAA;AAAA,MACvB,WAAA,EAAa,OAAO,OAAA,EAAS,WAAA;AAAA,MAC7B,YAAA,EAAc,OAAO,OAAA,EAAS;AAAA,KAChC;AAAA,IACA,QAAA,EAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMR,SAAA,EACE,MAAA,CAAO,QAAA,EAAU,SAAA,IACjB,OAAA;AAAA,QACE,MAAA,CAAO,WAAW,MAAA,IAClB,MAAA,CAAO,SAAS,SAAA,EAAW,MAAA,IAC3B,MAAA,CAAO,UAAA,EAAY,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAI,KACrC,MAAA,CAAO,OAAA,EAAS,YAAY,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI;AAAA,OAChD;AAAA,MACF,QAAA,EAAU,MAAA,CAAO,QAAA,EAAU,QAAA,IAAY,eAAA;AAAA,MACvC,IAAA,EAAM,MAAA,CAAO,QAAA,EAAU,IAAA,IAAQ,eAAA;AAAA,MAC/B,QAAA,EAAU,MAAA,CAAO,QAAA,EAAU,QAAA,IAAY;AAAA,KACzC;AAAA,IACA,YAAA,EAAc;AAAA,MACZ,IAAA,EAAM,MAAA,CAAO,YAAA,EAAc,IAAA,IAAQ,MAAA;AAAA,MACnC,UAAA,EAAY,MAAA,CAAO,YAAA,EAAc,UAAA,IAAc,GAAA;AAAA,MAC/C,MAAA,EAAQ,MAAA,CAAO,YAAA,EAAc,MAAA,IAAU,gCAAA;AAAA,MACvC,IAAA,EAAM,MAAA,CAAO,YAAA,EAAc,IAAA,IAAQ,IAAA;AAAA,MACnC,SAAA,EAAW,MAAA,CAAO,YAAA,EAAc,SAAA,IAAa;AAAA,KAC/C;AAAA,IACA,WAAA;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,IAAA,EAAM,MAAA,CAAO,MAAA,EAAQ,IAAA,IAAQ,QAAA;AAAA,MAC7B,WAAA,EAAa,MAAA,CAAO,MAAA,EAAQ,WAAA,IAAe,oBAAA;AAAA,MAC3C,WAAA,EAAa,MAAA,CAAO,MAAA,EAAQ,WAAA,IAAe,SAAA;AAAA,MAC3C,gBAAA,EAAkB,MAAA,CAAO,MAAA,EAAQ,gBAAA,IAAoB,CAAA;AAAA,MACrD,QAAA,EAAU,MAAA,CAAO,MAAA,EAAQ,QAAA,IAAY,CAAA;AAAA,MACrC,QAAA,EAAU,MAAA,CAAO,MAAA,EAAQ,QAAA,IAAY,sBAAA;AAAA,MACrC,UAAA,EAAY,MAAA,CAAO,MAAA,EAAQ,UAAA,IAAc,sBAAA;AAAA,MACzC,gBAAA,EAAkB,OAAO,MAAA,EAAQ;AAAA,KACnC;AAAA,IACA,GAAA,EACE,MAAA,CAAO,GAAA,KACN,QAAA,GACG;AAAA,MACE,EAAE,KAAA,EAAO,WAAA,EAAU,EAAA,EAAI,GAAA,EAAI;AAAA,MAC3B,EAAE,KAAA,EAAO,MAAA,EAAQ,EAAA,EAAI,UAAA;AAAW,QAElC,CAAC,EAAE,OAAO,MAAA,EAAQ,EAAA,EAAI,KAAK,CAAA;AAAA,GACnC;AACF;AAEA,IAAM,uBAAA,GAA0B,cAA+C,IAAI,CAAA;AAE5E,IAAM,2BAA2B,uBAAA,CAAwB;AAEzD,SAAS,mBAAA,GAAgD;AAC9D,EAAA,MAAM,GAAA,GAAM,WAAW,uBAAuB,CAAA;AAC9C,EAAA,IAAI,CAAC,GAAA,EAAK,MAAM,IAAI,MAAM,6DAA6D,CAAA;AACvF,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,2BAAA,GAA+D;AAC7E,EAAA,OAAO,WAAW,uBAAuB,CAAA;AAC3C;AAEO,SAAS,wBAAwB,MAAA,EAAwD;AAC9F,EAAA,OAAO,MAAA,CAAO,cAAc,EAAC;AAC/B;AC1kBA,IAAM,oBAAA,GAAuBA,cAAoC,IAAI,CAAA;AAE9D,IAAM,2BAA2B,oBAAA,CAAqB;AAS7D,IAAI,cAAA,GAAuC,IAAA;AAC3C,IAAI,SAAA,GAAkC,IAAA;AAQtC,SAAS,eAAA,GAAiC;AACxC,EAAA,IAAI,CAAC,SAAA,EAAW,SAAA,GAAY,oBAAA,CAAqB,MAAM,CAAA;AACvD,EAAA,OAAO,SAAA;AACT;AAEO,SAAS,gBAAA,GAAkC;AAChD,EAAA,MAAM,QAAA,GAAWC,WAAW,oBAAoB,CAAA;AAChD,EAAA,MAAM,OAAA,GAAU,YAAY,eAAA,EAAgB;AAC5C,EAAA,SAAA,CAAU,MAAM;AASd,IAAA,IAAI,UAAU,cAAA,GAAiB,QAAA;AAAA,EACjC,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AACb,EAAA,OAAO,OAAA;AACT;AAGO,SAAS,YAAA,GAAuB;AACrC,EAAA,MAAM,UAAU,gBAAA,EAAiB;AACjC,EAAA,OAAO,oBAAA;AAAA,IACL,CAAC,QAAA,KAAa,OAAA,CAAQ,YAAA,CAAa,QAAQ,CAAA;AAAA,IAC3C,MAAM,OAAA,CAAQ,cAAA,EAAe,IAAK,GAAA;AAAA,IAClC,MAAM,OAAA,CAAQ,cAAA,EAAe,IAAK;AAAA,GACpC;AACF;AAIO,SAAS,yBAAyB,IAAA,EAAoB;AAC3D,EAAA,MAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAC5B,EAAA,SAAA,CAAU,MAAM;AAMd,IAAA,IAAI,CAAC,QAAQ,OAAA,EAAS;AACpB,MAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,MAAA;AAAA,IACF;AACA,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,MAAA,CAAO,QAAA,CAAS,GAAG,CAAC,CAAA;AAAA,EACzD,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AACX;AAEO,SAAS,WAAA,GAAoC;AAClD,EAAA,MAAM,UAAU,gBAAA,EAAiB;AACjC,EAAA,OAAO,OAAA,CAAQ,QAAA,CAAS,IAAA,CAAK,OAAO,CAAA;AACtC;AAGO,IAAM,WAAA,GAAc;AAGpB,SAAS,WAAW,EAAA,EAAkB;AAC1C,EAAA,CAAC,cAAA,IAAkB,eAAA,EAAgB,EAAG,QAAA,CAAS,EAAE,CAAA;AACpD;AASO,SAAS,kBAAA,CAAmB,cAAkC,IAAA,EAAoC;AACvG,EAAA,IAAI,YAAA,IAAgB,MAAM,OAAO,IAAA;AAKjC,EAAA,OAAO,mBAAA,CAAoB,YAAA,EAAc,EAAE,IAAA,EAAM,CAAC,OAAO,IAAA,CAAK,IAAA,CAAK,EAAE,CAAA,EAAG,CAAA;AAC1E;AAGO,SAAS,SAAA,CAAU,SAAiB,IAAA,EAA6C;AACtF,EAAA,MAAM,SAAA,GAAA,CAAa,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA,EAAI,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,IAAK,GAAA;AACpE,EAAA,MAAM,eAAe,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAA,CAAE,OAAO,OAAO,CAAA;AACtD,EAAA,MAAM,YAAY,SAAA,CAAU,KAAA,CAAM,GAAG,CAAA,CAAE,OAAO,OAAO,CAAA;AACrD,EAAA,IAAI,YAAA,CAAa,MAAA,KAAW,SAAA,CAAU,MAAA,EAAQ,OAAO,IAAA;AACrD,EAAA,MAAM,SAAiC,EAAC;AACxC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,YAAA,CAAa,QAAQ,CAAA,EAAA,EAAK;AAC5C,IAAA,MAAM,GAAA,GAAM,aAAa,CAAC,CAAA;AAC1B,IAAA,MAAM,IAAA,GAAO,UAAU,CAAC,CAAA;AACxB,IAAA,IAAI,GAAA,CAAI,UAAA,CAAW,GAAG,CAAA,EAAG,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA,GAAI,kBAAA,CAAmB,IAAI,CAAA;AAAA,SAAA,IAC9D,GAAA,KAAQ,MAAM,OAAO,IAAA;AAAA,EAChC;AACA,EAAA,OAAO,MAAA;AACT;AAeO,SAAS,IAAA,CAAK,EAAE,EAAA,EAAI,QAAA,EAAU,SAAS,MAAA,EAAQ,GAAG,MAAK,EAAc;AAC1E,EAAA,MAAM,UAAU,gBAAA,EAAiB;AAEjC,EAAA,MAAM,WAAA,GAAc,CAAC,KAAA,KAA+C;AAClE,IAAA,OAAA,GAAU,KAAK,CAAA;AACf,IAAA,IAAI,CAAC,QAAQ,oBAAA,EAAsB;AACnC,IAAA,IAAI,MAAM,gBAAA,EAAkB;AAC5B,IAAA,IAAI,MAAA,IAAU,WAAW,OAAA,EAAS;AAClC,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACxB,IAAA,IAAI,MAAM,OAAA,IAAW,KAAA,CAAM,WAAW,KAAA,CAAM,QAAA,IAAY,MAAM,MAAA,EAAQ;AACtE,IAAA,KAAA,CAAM,cAAA,EAAe;AACrB,IAAA,OAAA,CAAQ,SAAS,EAAE,CAAA;AAAA,EACrB,CAAA;AAEA,EAAA,OAAOC,MAAAA,CAAM,aAAA;AAAA,IACX,GAAA;AAAA,IACA,EAAE,IAAA,EAAM,OAAA,CAAQ,IAAA,CAAK,EAAE,GAAG,OAAA,EAAS,WAAA,EAAa,MAAA,EAAQ,GAAG,IAAA,EAAK;AAAA,IAChE;AAAA,GACF;AACF;;;ACrHA,IAAI,MAAA,GAAkC,IAAA;AAG/B,SAAS,uBAAA,GAAmD;AACjE,EAAA,OAAO,MAAA;AACT;AAIO,SAAS,oBAAA,CAAwB,MAAwB,MAAA,EAAoB;AAClF,EAAA,MAAM,QAAA,GAAW,MAAA;AACjB,EAAA,MAAA,GAAS,IAAA;AACT,EAAA,IAAI;AACF,IAAA,OAAO,MAAA,EAAO;AAAA,EAChB,CAAA,SAAE;AACA,IAAA,MAAA,GAAS,QAAA;AAAA,EACX;AACF;ACdO,SAAS,iBAAA,CACd,MACA,OAAA,EACyB;AACzB,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,KAAK,CAAA,IAAK,MAAA,CAAO,QAAQ,IAAA,CAAK,MAAA,IAAU,EAAE,CAAA,EAAG;AAC7D,IAAA,IAAI,QAAA,GAAoB,KAAA;AACxB,IAAA,IAAI,iBAAiB,KAAK,CAAA,aAAc,OAAA,CAAQ,MAAA,CAAO,MAAM,MAAM,CAAA;AAAA,SAAA,IAC1D,gBAAgB,KAAK,CAAA,aAAc,OAAA,CAAQ,KAAA,CAAM,MAAM,KAAK,CAAA;AACrE,IAAA,IAAI,QAAA,KAAa,MAAA,EAAW,GAAA,CAAI,IAAI,CAAA,GAAI,QAAA;AAAA,EAC1C;AACA,EAAA,OAAO,GAAA;AACT;AAIA,SAAS,aAAa,IAAA,EAAgD;AACpE,EAAA,MAAM,IAAA,GAAO,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA;AACnC,EAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,GAAG,KAAK,IAAA,EAAK;AACvC;AAMO,SAAS,gBAAA,CACd,KAAA,EACA,WAAA,GAAsC,EAAC,EACvB;AAChB,EAAA,MAAM,KAAA,uBAAY,GAAA,EAA0B;AAC5C,EAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,KAA0B;AACvC,IAAA,MAAM,IAAA,GAAO,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA;AACnC,IAAA,MAAM,KAAA,GAAQ,aAAa,IAAI,CAAA;AAC/B,IAAA,IAAI,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,CAAA,EAAG;AACjC,MAAA,MAAM,KAAA,GAAQ,EAAE,GAAG,wBAAA,CAAyB,MAAM,QAAQ,CAAA,EAAG,GAAG,IAAA,CAAK,KAAA,EAAM;AAC3E,MAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA,EAAG;AACvC,QAAA,IAAI,CAAC,QAAQ,OAAO,IAAA,CAAK,WAAW,QAAA,IAAY,CAAC,KAAK,MAAA,EAAQ;AAC9D,QAAA,MAAM,SAAS,iBAAA,CAAkB,IAAA,EAAM,EAAE,MAAA,EAAQ,WAAA,EAAa,OAAO,CAAA;AACrE,QAAA,MAAM,GAAA,GAAM,WAAA,CAAY,IAAA,CAAK,MAAA,EAAQ,MAAM,CAAA;AAC3C,QAAA,IAAI,CAAC,KAAA,CAAM,GAAA,CAAI,GAAG,GAAG,KAAA,CAAM,GAAA,CAAI,GAAA,EAAK,EAAE,GAAA,EAAK,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,QAAQ,CAAA;AAAA,MAC1E;AAAA,IACF;AACA,IAAA,KAAA,MAAW,SAAS,IAAA,CAAK,QAAA,IAAY,EAAC,QAAS,KAAK,CAAA;AAAA,EACtD,CAAA;AACA,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,EAAO,KAAA,CAAM,IAAI,CAAA;AACpC,EAAA,OAAO,CAAC,GAAG,KAAA,CAAM,MAAA,EAAQ,CAAA;AAC3B;AAMA,eAAsB,oBAAoB,IAAA,EAAuE;AAC/G,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,aAAA,CAAc,IAAA,CAAK,MAAM,CAAA;AACtC,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,IAAA,CAAK,QAAQ,EAAE,IAAA,EAAM,eAAA,EAAgB,EAAG,CAAA;AAChE,IAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAK;AAAA,EACjC,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,OAAA,GAAU,aAAa,GAAG,CAAA;AAGhC,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,qBAAA,EAAwB,IAAA,CAAK,MAAM,aAAa,GAAG,CAAA;AACjE,IAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAO,OAAA,EAAQ;AAAA,EAC3C;AACF;AAIA,eAAsB,gBACpB,KAAA,EACwC;AACxC,EAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,GAAA;AAAA,IAC5B,KAAA,CAAM,GAAA,CAAI,OAAO,IAAA,KAAS,CAAC,IAAA,CAAK,GAAA,EAAK,MAAM,mBAAA,CAAoB,IAAI,CAAC,CAAU;AAAA,GAChF;AACA,EAAA,OAAO,MAAA,CAAO,YAAY,OAAO,CAAA;AACnC;AAWA,IAAM,eAAA,GAAkBF,cAA2C,IAAI,CAAA;AA4BhE,SAAS,cAAc,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAA,EAAS,UAAS,EAAuB;AACtF,EAAA,MAAM,MAAA,GAASC,WAAW,eAAe,CAAA;AACzC,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,MAAM,MAAA,IAAU,MAAA,EAAQ,MAAA,IAAU,EAAC,EAAG,CAAC,MAAA,EAAQ,MAAM,CAAC,CAAA;AAClF,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,MAAM,gBAAA,CAAiB,KAAA,EAAO,WAAW,CAAA,EAAG,CAAC,KAAA,EAAO,WAAW,CAAC,CAAA;AACtF,EAAA,MAAM,GAAA,GAAM,OAAA;AAAA,IACV,MAAM,KAAA,CAAM,MAAA,CAAO,CAAC,IAAA,KAAS,CAAC,MAAA,IAAU,EAAE,IAAA,CAAK,GAAA,IAAO,MAAA,CAAO,OAAA,CAAQ,CAAA;AAAA,IACrE,CAAC,OAAO,MAAM;AAAA,GAChB;AAIA,EAAA,MAAM,aAAa,uBAAA,EAAwB;AAC3C,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,UAAA,CAAW,KAAK,KAAK,CAAA;AACrB,IAAA,UAAA,CAAW,MAAM,GAAG,CAAA;AAAA,EACtB;AAKA,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAwC,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO3E,GAAG,OAAA;AAAA,IACH,GAAG,MAAA,CAAO,WAAA;AAAA,MACR,GAAA,CAAI,GAAA,CAAI,CAAC,IAAA,KAAS;AAAA,QAChB,IAAA,CAAK,GAAA;AAAA,QACL,OAAA,GAAU,IAAA,CAAK,GAAG,CAAA,IAAK,UAAA,EAAY,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA,IAAM,EAAE,MAAA,EAAQ,SAAA;AAAU,OAC9E;AAAA;AACH,GACF,CAAE,CAAA;AAEF,EAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,CAAC,SAAS,IAAA,CAAK,GAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AACvD,EAAAE,UAAU,MAAM;AAEd,IAAA,MAAM,OAAA,GAAU,GAAA,CAAI,MAAA,CAAO,CAAC,IAAA,KAAS,UAAU,IAAA,CAAK,GAAG,CAAA,EAAG,MAAA,KAAW,OAAO,CAAA;AAC5E,IAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AAC1B,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,UAAA,CAAW,CAAC,IAAA,KAAS;AACnB,MAAA,MAAM,IAAA,GAAO,EAAE,GAAG,IAAA,EAAK;AACvB,MAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAC1B,QAAA,IAAI,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA,EAAG,MAAA,KAAW,OAAA,EAAS,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA,GAAI,EAAE,MAAA,EAAQ,SAAA,EAAU;AAAA,MAC/E;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AACD,IAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAC1B,MAAA,KAAK,mBAAA,CAAoB,IAAI,CAAA,CAAE,IAAA,CAAK,CAAC,KAAA,KAAU;AAC7C,QAAA,IAAI,CAAC,SAAA,EAAW,UAAA,CAAW,CAAC,IAAA,MAAU,EAAE,GAAG,IAAA,EAAM,CAAC,IAAA,CAAK,GAAG,GAAG,OAAM,CAAE,CAAA;AAAA,MACvE,CAAC,CAAA;AAAA,IACH;AACA,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EAGF,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAWd,EAAA,MAAM,KAAA,GAAQ,OAAA;AAAA,IACZ,OAAO,EAAE,OAAA,EAAS,EAAE,GAAG,MAAA,EAAQ,OAAA,EAAS,GAAG,OAAA,EAAS,GAAG,OAAA,EAAQ,EAAG,QAAQ,WAAA,EAAY,CAAA;AAAA,IACtF,CAAC,MAAA,EAAQ,OAAA,EAAS,OAAA,EAAS,WAAW;AAAA,GACxC;AACA,EAAA,uBAAO,GAAA,CAAC,eAAA,CAAgB,QAAA,EAAhB,EAAyB,OAAe,QAAA,EAAS,CAAA;AAC3D;AAsBO,SAAS,SAAA,CACd,QACA,MAAA,EACoB;AACpB,EAAA,MAAM,KAAA,GAAQF,WAAW,eAAe,CAAA;AACxC,EAAA,MAAM,MAAM,MAAA,KAAW,IAAA,GAAO,IAAA,GAAO,WAAA,CAAY,QAAQ,MAAM,CAAA;AAC/D,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,CAAC,CAAA;AACpC,EAAA,MAAM,MAAA,GAAS,UAAU,CAAA,IAAK,GAAA,KAAQ,QAAQ,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GAAI,MAAA;AAC3E,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuD,IAAI,CAAA;AAMrF,EAAA,MAAM,aAAa,uBAAA,EAAwB;AAC3C,EAAA,MAAM,WAAA,GAAc,cAAc,GAAA,KAAQ,IAAA,IAAQ,WAAW,MAAA,GAAY,UAAA,CAAW,OAAA,CAAQ,GAAG,CAAA,GAAI,MAAA;AACnG,EAAA,IAAI,cAAc,GAAA,KAAQ,IAAA,IAAQ,MAAA,KAAW,MAAA,IAAa,gBAAgB,MAAA,EAAW;AACnF,IAAA,UAAA,CAAW,MAAM,CAAC,EAAE,KAAK,MAAA,EAAQ,MAAA,EAAiB,CAAC,CAAA;AAAA,EACrD;AAEA,EAAA,MAAM,YAAY,MAAA,KAAW,IAAA,GAAO,IAAA,GAAO,IAAA,CAAK,UAAU,MAAM,CAAA;AAChE,EAAAE,UAAU,MAAM;AACd,IAAA,IAAI,GAAA,KAAQ,IAAA,IAAQ,MAAA,KAAW,MAAA,EAAW;AAC1C,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,QAAA,CAAS,EAAE,GAAA,EAAK,KAAA,EAAO,EAAE,MAAA,EAAQ,SAAA,IAAa,CAAA;AAC9C,IAAA,KAAK,mBAAA,CAAoB,EAAE,MAAA,EAAQ,MAAA,EAAiB,CAAA,CAAE,IAAA,CAAK,CAACC,MAAAA,KAAU;AACpE,MAAA,IAAI,CAAC,SAAA,EAAW,QAAA,CAAS,EAAE,GAAA,EAAK,KAAA,EAAAA,QAAO,CAAA;AAAA,IACzC,CAAC,CAAA;AACD,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EAGF,GAAG,CAAC,MAAA,EAAQ,WAAW,KAAA,EAAO,MAAA,KAAW,MAAS,CAAC,CAAA;AAEnD,EAAA,MAAM,KAAA,GACJ,MAAA,IACA,WAAA,KACC,KAAA,IAAS,MAAM,GAAA,KAAQ,GAAA,GAAM,KAAA,CAAM,KAAA,GAAQ,GAAA,KAAQ,IAAA,GAAO,EAAE,MAAA,EAAQ,WAAmB,GAAI,IAAA,CAAA;AAE9F,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,OAAO,MAAA,IAAU,MAAA;AAAA,IACzB,IAAA,EAAM,KAAA,EAAO,MAAA,KAAW,OAAA,GAAW,MAAM,IAAA,GAAa,IAAA;AAAA,IACtD,OAAO,KAAA,EAAO,MAAA,KAAW,OAAA,GAAU,KAAA,CAAM,SAAS,eAAA,GAAkB,IAAA;AAAA,IACpE,QAAQ,MAAM,QAAA,CAAS,CAAC,CAAA,KAAM,IAAI,CAAC;AAAA,GACrC;AACF;AAgBO,SAAS,YAAA,CACd,IAAA,EACA,IAAA,EACA,QAAA,EACyC;AACzC,EAAA,MAAM,KAAA,GAAQH,WAAW,eAAe,CAAA;AACxC,EAAA,IAAI,SAAS,QAAA,CAAS,MAAA;AACtB,EAAA,IAAI,SAAS,QAAA,CAAS,MAAA;AACtB,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,MAAM,IAAA,GAAO,YAAA,CAAa,IAAI,CAAA,CAAE,IAAI,CAAA;AACpC,IAAA,IAAI,QAAQ,OAAO,IAAA,CAAK,MAAA,KAAW,QAAA,IAAY,KAAK,MAAA,EAAQ;AAC1D,MAAA,MAAM,IAAA,GAAO,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA;AACnC,MAAA,MAAA,GAAS,IAAA,CAAK,MAAA;AACd,MAAA,MAAA,GAAS,kBAAkB,IAAA,EAAM;AAAA,QAC/B,MAAA,EAAQ,KAAA,EAAO,MAAA,IAAU,EAAC;AAAA,QAC1B,KAAA,EAAO,EAAE,GAAG,wBAAA,CAAyB,MAAM,QAAQ,CAAA,EAAG,GAAG,IAAA,CAAK,KAAA;AAAM,OACrE,CAAA;AAAA,IACH;AAAA,EACF;AACA,EAAA,MAAM,MAAA,GAAS,SAAA,CAAa,MAAA,EAAQ,MAAM,CAAA;AAC1C,EAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,MAAA,EAAO;AAC7B;AAUO,SAAS,cAAA,CAAe,EAAE,MAAA,EAAQ,OAAA,EAAQ,EAAgD;AAC/F,EAAA,IAAI,uBAAA,EAAwB,KAAM,QAAA,EAAU,OAAO,IAAA;AACnD,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,kBAAA,EAAkB,UAAU,MAAM,CAAA,CAAA;AAAA,MAClC,KAAA,EAAO;AAAA,QACL,MAAA,EAAQ,oBAAA;AAAA,QACR,KAAA,EAAO,SAAA;AAAA,QACP,OAAA,EAAS,UAAA;AAAA,QACT,IAAA,EAAM,8BAAA;AAAA,QACN,YAAA,EAAc;AAAA,OAChB;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,CAAA,oCAAA,EAAuC,MAAM,CAAA,EAAA,CAAA;AAAA,QAC7C,OAAA,mBAAU,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,GAAA,EAAK,SAAA,EAAW,CAAA,EAAE,EAAI,QAAA,EAAA,OAAA,EAAQ,CAAA,GAAS;AAAA;AAAA;AAAA,GAC3E;AAEJ;ACnQO,SAAS,cAAA,CACd,MACA,OAAA,EAC6B;AAC7B,EAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,OAAA,EAAS,OAAO,MAAA;AAC9B,EAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AACrB,EAAA,MAAM,OAAO,OAAA,CAAQ,IAAA,KAAS,OAAO,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,KAAA,CAAA,GAAU,MAAA,CAAA;AAC3D,EAAA,MAAM,IAAA,GAAO,IAAA,EAAM,IAAA,GAAO,EAAE,GAAG,IAAA,CAAK,IAAA,EAAM,GAAG,OAAA,CAAQ,IAAA,EAAK,GAAK,OAAA,CAAQ,IAAA;AACvE,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,GAAG,OAAA;AAAA,IACH,IAAA;AAAA,IACA,QAAQ,EAAE,GAAG,MAAM,MAAA,EAAQ,GAAG,QAAQ,MAAA,EAAO;AAAA,IAC7C,IAAA;AAAA,IACA,QAAQ,EAAE,GAAG,MAAM,MAAA,EAAQ,GAAG,QAAQ,MAAA,EAAO;AAAA,IAC7C,QAAQ,EAAE,GAAG,MAAM,MAAA,EAAQ,GAAG,QAAQ,MAAA,EAAO;AAAA,IAC7C,aAAa,EAAE,GAAG,MAAM,WAAA,EAAa,GAAG,QAAQ,WAAA;AAAY,GAC9D;AACF;AAGO,SAAS,kBAAkB,IAAA,EAAsB;AACtD,EAAA,OAAO,eAAe,IAAI,CAAA,EAAA,CAAA;AAC5B;AAGO,SAAS,gBAAgB,IAAA,EAAwB;AACtD,EAAA,OAAO,KACJ,KAAA,CAAM,GAAG,EACT,MAAA,CAAO,CAAC,YAAY,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAC,EAC3C,GAAA,CAAI,CAAC,YAAY,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAC,CAAA;AACtC;AAYO,SAAS,eAAA,CAAgB,MAAc,IAAA,EAA2C;AACvF,EAAA,OAAO,IAAA,CAAK,IAAA,IAAQ,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AAC9B;AAYO,SAAS,gBAAA,CACd,OACA,IAAA,EACyB;AACzB,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,CAAA,IAAK,MAAA,CAAO,QAAQ,KAAA,EAAO,OAAA,IAAW,EAAE,CAAA,EAAG;AAC/D,IAAA,MAAM,SAAS,SAAA,CAAU,eAAA,CAAgB,IAAA,EAAM,IAAI,GAAG,IAAI,CAAA;AAC1D,IAAA,IAAI,MAAA,EAAQ,OAAO,EAAE,IAAA,EAAM,MAAM,MAAA,EAAO;AAAA,EAC1C;AACA,EAAA,OAAO,IAAA;AACT;AAGO,IAAM,kBAAA,GAAqB;AAC3B,IAAM,kBAAA,GAAqB;AAGlC,IAAM,kBAAA,GAAkE;AAAA,EACtE,OAAA,EAAS,kBAAA;AAAA,EACT,OAAA,EAAS;AACX,CAAA;AAUO,IAAM,qBAAA,uBAAiD,GAAA,CAAI;AAAA,EAChE,MAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAC;AAED,IAAM,eAAA,GAAkB,qBAAA;AAUjB,SAAS,iBAAiB,KAAA,EAAyB;AACxD,EAAA,OAAO,YAAY,KAA4B,CAAA;AACjD;AAEA,SAAS,YAAY,KAAA,EAAqC;AACxD,EAAA,MAAM,MAAA,GAAS,KAAA;AAIf,EAAA,IAAI,OAAA,IAAW,QAAQ,OAAO,IAAA;AAC9B,EAAA,OAAO,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAAE,KAAA,CAAM,CAAC,GAAA,KAAQ,eAAA,CAAgB,GAAA,CAAI,GAAG,CAAC,CAAA;AACpE;AAaO,SAAS,eAAA,CAAgB,OAAgB,KAAA,EAAuB;AACrE,EAAA,MAAM,MAAA,GAAS,KAAA;AACf,EAAA,IAAI,MAAA,IAAU,OAAO,MAAA,CAAO,EAAA,KAAO,YAAY,MAAA,CAAO,EAAA,SAAW,MAAA,CAAO,EAAA;AACxE,EAAA,OAAO,GAAG,MAAA,CAAO,MAAA,EAAQ,IAAI,CAAC,IAAI,KAAK,CAAA,CAAA;AACzC;AAQA,SAAS,WAAA,CAAY,OAA4B,KAAA,EAA0B;AACzE,EAAA,MAAM,MAAA,GAAS,KAAA;AACf,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA;AAC/B,EAAA,MAAM,EAAA,GAAK,eAAA,CAAgB,KAAA,EAAO,KAAK,CAAA;AAEvC,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AAEpB,EAAA,IAAI,WAAA,CAAY,KAAK,CAAA,EAAG;AACtB,IAAA,MAAM,QAAA,GAAY,MAAA,CAAO,QAAA,IAA0D,EAAC;AACpF,IAAA,OAAO;AAAA,MACL,IAAA;AAAA,MACA,EAAA;AAAA,MACA,KAAA,EAAQ,MAAA,CAAO,KAAA,IAAiD,EAAC;AAAA,MACjE,GAAI,QAAA,CAAS,MAAA,GAAS,EAAE,QAAA,EAAU,SAAS,GAAA,CAAI,CAAC,KAAA,EAAO,CAAA,KAAM,YAAY,KAAA,EAAO,CAAC,CAAC,CAAA,KAAM,EAAC;AAAA,MACzF,GAAI,IAAA,GAAO,EAAE,IAAA,KAAS;AAAC,KACzB;AAAA,EACF;AAGA,EAAA,MAAM,QAAiC,EAAC;AACxC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACjD,IAAA,IAAI,CAAC,eAAA,CAAgB,GAAA,CAAI,GAAG,CAAA,EAAG,KAAA,CAAM,GAAG,CAAA,GAAI,KAAA;AAAA,EAC9C;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,EAAA,EAAI,KAAA,EAAO,GAAI,OAAO,EAAE,IAAA,EAAK,GAAI,EAAC,EAAG;AACtD;AAGO,SAAS,aAAa,MAAA,EAAqD;AAChF,EAAA,OAAO,MAAA,CAAO,IAAI,WAAW,CAAA;AAC/B;AAOO,SAAS,kBAAkB,IAAA,EAAuC;AACvE,EAAA,MAAM,IAAA,GAAO,mBAAmB,IAAI,CAAA;AACpC,EAAA,OAAO,IAAA,GAAO,CAAC,EAAE,IAAA,EAAM,IAAA,EAAM,EAAA,EAAI,IAAA,EAAM,KAAA,EAAO,EAAC,EAAG,CAAA,GAAI,EAAC;AACzD;AAgBO,SAAS,eAAA,CAAgB,MAA0B,KAAA,EAAoD;AAC5G,EAAA,MAAM,QAA+B,EAAC;AACtC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,EAAA,MAAM,YAAA,GAAe,mBAAmB,IAAI,CAAA;AAC5C,EAAA,IAAI,OAAA,GAAU,KAAA;AAEd,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,IAAA,CAAK,IAAA,KAAS,YAAA,EAAc,OAAA,GAAU,IAAA;AAE1C,IAAA,IAAI,KAAK,EAAA,EAAI;AACX,MAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG;AACxB,QAAA,KAAA,CAAM,IAAA,CAAK;AAAA,UACT,KAAA,EAAO,SAAA;AAAA,UACP,IAAA,EAAM,oBAAA;AAAA,UACN,MAAA,EAAQ,CAAA,kBAAA,EAAqB,IAAI,CAAA,oBAAA,EAAuB,KAAK,EAAE,CAAA,6DAAA;AAAA,SAChE,CAAA;AAAA,MACH;AACA,MAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,EAAE,CAAA;AAAA,IACrB;AAEA,IAAA,MAAM,IAAA,GAAOI,YAAAA,CAAa,IAAA,CAAK,IAAI,CAAA;AACnC,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,KAAA,EAAO,OAAA;AAAA,QACP,IAAA,EAAM,eAAA;AAAA,QACN,MAAA,EAAQ,CAAA,IAAA,EAAO,IAAI,CAAA,wBAAA,EAA2B,KAAK,IAAI,CAAA,0EAAA;AAAA,OACxD,CAAA;AACD,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,gBAAA,CAAiB,EAAE,SAAA,EAAW,IAAA,CAAK,aAAa,EAAC,EAAE,EAAG,IAAI,CAAA,EAAG;AAChE,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,KAAA,EAAO,SAAA;AAAA,QACP,IAAA,EAAM,2BAAA;AAAA,QACN,MAAA,EAAQ,CAAA,OAAA,EAAU,IAAA,CAAK,IAAI,CAAA,sBAAA,EAAA,CAA0B,IAAA,CAAK,SAAA,IAAa,EAAC,EAAG,IAAA,CAAK,IAAI,CAAC,0BAA0B,IAAI,CAAA,KAAA;AAAA,OACpH,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,IAAI,YAAA,IAAgB,CAAC,OAAA,EAAS;AAK5B,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,KAAA,EAAO,SAAA;AAAA,MACP,IAAA,EAAM,mBAAA;AAAA,MACN,MAAA,EAAQ,OAAO,IAAI,CAAA,kBAAA,EAAqB,YAAY,CAAA,0BAAA,EAA6B,IAAA,KAAS,SAAA,GAAY,gBAAA,GAAmB,cAAc,CAAA,wDAAA;AAAA,KACxI,CAAA;AAAA,EACH;AAMA,EAAA,KAAA,MAAW,SAAA,IAAa,qBAAA,CAAsB,KAAK,CAAA,EAAG;AACpD,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,KAAA,EAAO,OAAA;AAAA,MACP,MAAM,SAAA,CAAU,IAAA;AAAA,MAChB,MAAA,EAAQ,GAAG,IAAI,CAAA,MAAA,EAAS,UAAU,IAAI,CAAA,EAAA,EAAK,UAAU,MAAM,CAAA;AAAA,KAC5D,CAAA;AAAA,EACH;AAKA,EAAA,KAAA,MAAW,OAAA,IAAW,iBAAA,CAAkB,KAAK,CAAA,EAAG;AAC9C,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,KAAA,EAAO,SAAA;AAAA,MACP,IAAA,EAAM,sBAAA;AAAA,MACN,MAAA,EAAQ,CAAA,OAAA,EAAU,OAAA,CAAQ,IAAI,QAAQ,IAAI,CAAA,MAAA,EAAS,OAAA,CAAQ,IAAI,CAAA,eAAA,EAAkB,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAC,CAAA,2BAAA;AAAA,KAC5G,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,KAAA;AACT;ACrWA,SAAS,QAAA,CAAS,GAAA,EAA2B,IAAA,GAAO,GAAA,CAAI,IAAA,EAA0B;AAGhF,EAAA,MAAM,MAAA,GAAA,CAAU,GAAA,CAAI,MAAA,IAAU,uBAAA,EAAwB,EAAG,UAAU,SAAA,EAAU,EAAG,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AACjG,EAAA,IAAI,CAAC,QAAQ,OAAO,MAAA;AACpB,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,EAAG,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,GAAI,IAAA,GAAO,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAA,CAAA;AAC7D;AAGO,SAAS,gBAAgB,OAAA,EAAsC;AACpE,EAAA,OAAA,CAAQ,OAAA,CAAQ,MAAA,EAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,CAAA,IAAK,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA,GAAI,GAAA;AAC5E;AAOA,SAAS,aAAA,CAAc,SAAkB,GAAA,EAA+C;AACtF,EAAA,MAAM,GAAA,GAAM,gBAAgB,OAAO,CAAA;AACnC,EAAA,IAAI,CAAC,KAAK,OAAO,MAAA;AACjB,EAAA,OAAO,GAAA,CAAI,MAAA,CAAO,YAAA,CAAa,SAAA,KAAc,UAAA,GAAa,eAAA,CAAgB,GAAA,EAAK,EAAE,KAAA,EAAO,IAAA,EAAM,OAAA,EAAS,EAAA,EAAI,CAAA,GAAI,GAAA;AACjH;AAOO,SAAS,aAAA,CACd,SACA,GAAA,EACyB;AACzB,EAAA,MAAM,GAAA,GAAM,SAAS,GAAG,CAAA;AACxB,EAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,OAAA,EAAS,GAAG,CAAA;AACxC,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,oBAAA;AAAA,IACZ,OAAA,EAAS,SAAA;AAAA,IACT,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,GAAI,QAAQ,WAAA,GAAc,EAAE,aAAa,OAAA,CAAQ,WAAA,KAAgB,EAAC;AAAA,IAClE,GAAI,QAAQ,GAAA,GAAM,EAAE,KAAK,OAAA,CAAQ,GAAA,KAAQ,EAAC;AAAA,IAC1C,GAAI,QAAQ,EAAE,KAAA,EAAO,CAAC,KAAK,CAAA,KAAM,EAAC;AAAA,IAClC,MAAA,EAAQ;AAAA,MACN,OAAA,EAAS,OAAA;AAAA,MACT,GAAI,GAAA,GAAM,EAAE,GAAA,KAAQ,EAAC;AAAA,MACrB,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,aAAA,EAAe,OAAA,CAAQ,QAAA,IAAY,GAAA,CAAI,MAAA,CAAO,QAAA;AAAA,MAC9C,YAAA,EAAA,CACG,OAAA,CAAQ,cAAA,IAAkB,CAAA,IAAK,IAC5B,4BAAA,GACA;AAAA;AACR,GACF;AACF;AAGO,SAAS,UAAA,CAAW,SAAkB,GAAA,EAA4C;AACvF,EAAA,MAAM,GAAA,GAAM,SAAS,GAAG,CAAA;AACxB,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,GAAA,EAAK,GAAG,CAAA;AAC9B,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,GAAA,EAAK,GAAA,CAAI,OAAO,WAAW,CAAA;AACpD,EAAA,OAAO;AAAA,IACL,OAAO,CAAA,EAAG,OAAA,CAAQ,IAAI,CAAA,QAAA,EAAM,GAAA,CAAI,OAAO,IAAI,CAAA,CAAA;AAAA,IAC3C,WAAA,EAAa,OAAA,CAAQ,WAAA,EAAa,KAAA,CAAM,GAAG,GAAG,CAAA;AAAA,IAC9C,SAAA,EAAW,GAAA;AAAA,IACX,KAAA,EAAO,aAAA,CAAc,OAAA,EAAS,GAAG,CAAA;AAAA,IACjC,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,aAAA,CAAc,SAAS,GAAG,CAAA;AAAA,MAC1B,GAAI,IAAA,IAAQ,OAAA,IAAW,GAAA,GACnB;AAAA,QACE,gBAAA,CAAiB;AAAA,UACf,EAAE,IAAA,EAAM,GAAA,CAAI,MAAA,CAAO,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,UACnC,EAAE,IAAA,EAAM,MAAA,EAAQ,GAAA,EAAK,OAAA,EAAQ;AAAA,UAC7B,EAAE,IAAA,EAAM,OAAA,CAAQ,IAAA,EAAM,GAAA;AAAI,SAC3B;AAAA,UAEH;AAAC;AACP,GACF;AACF;AAGO,SAAS,OAAA,CACd,KACA,KAAA,EACiB;AACjB,EAAA,OAAO,EAAE,GAAG,KAAA,EAAO,SAAA,EAAW,SAAS,GAAG,CAAA,EAAG,MAAM,SAAA,EAAU;AAC/D;AA8BA,SAAS,YAAA,CAAa,UAAqB,UAAA,EAAwB;AACjE,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAuB;AAC9C,EAAA,MAAM,QAAmB,EAAC;AAC1B,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,MAAM,GAAA,GAAM,CAAA,CAAE,UAAA,IAAc,CAAA,CAAE,YAAA,IAAgB,EAAA;AAC9C,IAAA,IAAI,CAAC,GAAA,EAAK;AAAE,MAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AAAG,MAAA;AAAA,IAAS;AACpC,IAAA,UAAA,CAAW,GAAA,CAAI,GAAA,EAAK,CAAC,GAAI,UAAA,CAAW,GAAA,CAAI,GAAG,CAAA,IAAK,EAAC,EAAI,CAAC,CAAC,CAAA;AAAA,EACzD;AACA,EAAA,MAAM,QAAA,GAAW,UAAA,CACd,GAAA,CAAI,CAAC,OAAO,EAAE,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,WAAA,EAAa,CAAA,CAAE,WAAA,EAAa,QAAA,EAAU,WAAW,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,IAAK,UAAA,CAAW,GAAA,CAAI,CAAA,CAAE,IAAI,KAAK,EAAC,EAAE,CAAE,CAAA,CACzH,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,CAAS,SAAS,CAAC,CAAA;AACtC,EAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,QAAA,CAAS,IAAA,CAAK,EAAE,IAAA,EAAM,QAAA,EAAU,WAAA,EAAa,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,CAAA;AACtF,EAAA,IAAI,CAAC,QAAA,CAAS,MAAA,IAAU,QAAA,CAAS,MAAA,EAAQ,OAAO,CAAC,EAAE,IAAA,EAAM,aAAA,EAAY,WAAA,EAAa,IAAA,EAAM,UAAU,CAAA;AAClG,EAAA,OAAO,QAAA;AACT;AAUO,SAAS,UAAA,CACd,OACA,GAAA,EACyB;AACzB,EAAA,MAAM,GAAA,GAAM,SAAS,GAAG,CAAA;AACxB,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,GAAA,EAAK,GAAG,CAAA;AAC9B,EAAA,MAAM,CAAA,GAAI,KAAA,CAAM,QAAA,IAAY,EAAC;AAC7B,EAAA,MAAM,QAAA,GAAW,IAAI,MAAA,CAAO,QAAA;AAC5B,EAAA,MAAM,OAAA,GAAU,EAAE,OAAA,GACd;AAAA,IACE,OAAA,EAAS,eAAA;AAAA,IACT,GAAI,CAAA,CAAE,OAAA,CAAQ,aAAA,GAAgB,EAAE,eAAe,CAAA,CAAE,OAAA,CAAQ,aAAA,EAAc,GAAI,EAAC;AAAA,IAC5E,GAAI,CAAA,CAAE,OAAA,CAAQ,QAAA,GAAW,EAAE,iBAAiB,CAAA,CAAE,OAAA,CAAQ,QAAA,EAAS,GAAI,EAAC;AAAA,IACpE,GAAI,CAAA,CAAE,OAAA,CAAQ,MAAA,GAAS,EAAE,eAAe,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAO,GAAI,EAAC;AAAA,IAC9D,GAAI,CAAA,CAAE,OAAA,CAAQ,UAAA,GAAa,EAAE,YAAY,CAAA,CAAE,OAAA,CAAQ,UAAA,EAAW,GAAI,EAAC;AAAA,IACnE,cAAA,EAAgB,CAAA,CAAE,OAAA,CAAQ,OAAA,IAAW;AAAA,GACvC,GACA,MAAA;AACJ,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,oBAAA;AAAA,IACZ,OAAA,EAAS,EAAE,IAAA,IAAQ,YAAA;AAAA,IACnB,GAAI,IAAA,GAAO,EAAE,KAAA,EAAO,CAAA,EAAG,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAC,CAAA,UAAA,CAAA,EAAa,GAAI,EAAC;AAAA,IAChE,IAAA,EAAM,IAAI,MAAA,CAAO,IAAA;AAAA,IACjB,GAAI,IAAA,GAAO,EAAE,GAAA,EAAK,IAAA,KAAS,EAAC;AAAA,IAC5B,GAAI,EAAE,WAAA,GAAc,EAAE,aAAa,CAAA,CAAE,WAAA,KAAgB,EAAC;AAAA,IACtD,GAAI,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAA,EAAO,CAAC,CAAA,CAAE,KAAK,CAAA,EAAE,GAAI,EAAC;AAAA,IACtC,GAAI,EAAE,IAAA,GAAO,EAAE,MAAM,CAAA,CAAE,IAAA,KAAS,EAAC;AAAA,IACjC,GAAI,EAAE,SAAA,GAAY,EAAE,WAAW,CAAA,CAAE,SAAA,KAAc,EAAC;AAAA,IAChD,GAAI,EAAE,KAAA,GAAQ,EAAE,OAAO,CAAA,CAAE,KAAA,KAAU,EAAC;AAAA,IACpC,GAAI,EAAE,aAAA,GAAgB,EAAE,eAAe,CAAA,CAAE,aAAA,KAAkB,EAAC;AAAA,IAC5D,GAAI,EAAE,UAAA,GAAa,EAAE,YAAY,CAAA,CAAE,UAAA,KAAe,EAAC;AAAA,IACnD,GAAI,OAAA,GAAU,EAAE,OAAA,KAAY,EAAC;AAAA,IAC7B,GAAI,CAAA,CAAE,UAAA,EAAY,SAAS,EAAE,UAAA,EAAY,EAAE,UAAA,CAAW,GAAA,CAAI,CAAC,IAAA,MAAU,EAAE,OAAA,EAAS,OAAA,EAAS,MAAK,CAAE,CAAA,KAAM,EAAC;AAAA,IACvG,GAAI,EAAE,YAAA,EAAc,MAAA,GAAS,EAAE,YAAA,EAAc,CAAA,CAAE,YAAA,EAAa,GAAI,EAAC;AAAA,IACjE,GAAI,EAAE,MAAA,EAAQ,MAAA,GAAS,EAAE,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAO,GAAI,EAAC;AAAA,IAC/C,GAAI,GAAA,GAAM,EAAE,OAAA,EAAS,GAAA,KAAQ,EAAC;AAAA,IAC9B,GAAI,GAAA,GACA;AAAA,MACE,eAAA,EAAiB;AAAA,QACf,OAAA,EAAS,aAAA;AAAA,QACT,MAAA,EAAQ,EAAE,OAAA,EAAS,YAAA,EAAc,WAAA,EAAa,KAAK,cAAA,EAAgB,CAAC,uCAAA,EAAyC,sCAAsC,CAAA,EAAE;AAAA,QACrJ,cAAA,EAAgB;AAAA;AAClB,QAEF,EAAC;AAAA,IACL,IAAA,EAAM;AAAA,MACJ,OAAA,EAAS,MAAA;AAAA,MACT,IAAA,EAAM,CAAA,mBAAA,EAAc,GAAA,CAAI,MAAA,CAAO,IAAI,CAAA,CAAA;AAAA,MACnC,GAAI,GAAA,GAAM,EAAE,GAAA,KAAQ,EAAC;AAAA,MACrB,UAAA,EAAY,OAAA;AAAA,MACZ,cAAA,EAAgB,aAAa,KAAA,CAAM,QAAA,EAAU,MAAM,UAAU,CAAA,CAAE,GAAA,CAAI,CAAC,OAAA,MAAa;AAAA,QAC/E,OAAA,EAAS,aAAA;AAAA,QACT,MAAM,OAAA,CAAQ,IAAA;AAAA,QACd,GAAI,QAAQ,WAAA,GAAc,EAAE,aAAa,OAAA,CAAQ,WAAA,KAAgB,EAAC;AAAA,QAClE,WAAA,EAAa,OAAA,CAAQ,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM;AACvC,UAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,CAAA,EAAG,GAAG,CAAA;AAClC,UAAA,MAAM,UAAU,QAAA,CAAS,GAAA,EAAK,CAAA,SAAA,EAAY,CAAA,CAAE,IAAI,CAAA,CAAE,CAAA;AAClD,UAAA,OAAO;AAAA,YACL,OAAA,EAAS,UAAA;AAAA,YACT,MAAM,CAAA,CAAE,IAAA;AAAA,YACR,GAAI,CAAA,CAAE,WAAA,GAAc,EAAE,WAAA,EAAa,CAAA,CAAE,WAAA,CAAY,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,EAAE,GAAI,EAAC;AAAA,YACpE,GAAI,KAAA,GAAQ,EAAE,KAAA,KAAU,EAAC;AAAA,YACzB,GAAI,OAAA,GAAU,EAAE,GAAA,EAAK,OAAA,KAAY,EAAC;AAAA,YAClC,MAAA,EAAQ;AAAA,cACN,OAAA,EAAS,OAAA;AAAA,cACT,OAAO,CAAA,CAAE,KAAA;AAAA,cACT,aAAA,EAAe,EAAE,QAAA,IAAY,QAAA;AAAA,cAC7B,YAAA,EAAA,CAAe,CAAA,CAAE,cAAA,IAAkB,CAAA,IAAK,IAAI,4BAAA,GAA+B;AAAA;AAC7E,WACF;AAAA,QACF,CAAC;AAAA,OACH,CAAE;AAAA;AACJ,GACF;AACF;AAOO,SAAS,OAAA,CACd,OAOA,GAAA,EACiB;AACjB,EAAA,MAAM,GAAA,GAAM,SAAS,GAAG,CAAA;AACxB,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,GAAA,EAAK,GAAG,CAAA;AAC9B,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,QAAA,CAAS,KAAA,CAAM,GAAG,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAA,CAAE,KAAK,IAAI,CAAA;AACrE,EAAA,OAAO;AAAA,IACL,OAAO,KAAA,CAAM,KAAA,IAAS,CAAA,SAAA,EAAY,GAAA,CAAI,OAAO,IAAI,CAAA,sBAAA,CAAA;AAAA,IACjD,WAAA,EAAA,CACG,KAAA,CAAM,WAAA,KAAgB,KAAA,GAAQ,CAAA,gBAAA,EAAgB,KAAK,CAAA,4CAAA,CAAA,GAA2C,MAAA,CAAA,GAAa,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA;AAAA,IAC1H,SAAA,EAAW,GAAA;AAAA,IACX,KAAA,EAAO,MAAM,QAAA,EAAU,KAAA;AAAA,IACvB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,UAAA,CAAW,OAAO,GAAG,CAAA;AAAA,MACrB,GAAI,QAAQ,GAAA,GACR,CAAC,iBAAiB,CAAC,EAAE,IAAA,EAAM,GAAA,CAAI,MAAA,CAAO,IAAA,EAAM,KAAK,IAAA,EAAK,EAAG,EAAE,IAAA,EAAM,UAAA,EAAY,KAAK,CAAC,CAAC,CAAA,GACpF;AAAC;AACP,GACF;AACF;;;AC3OO,SAAS,sBAAA,CACd,QACA,OAAA,EACsB;AACtB,EAAA,MAAM,QAAA,GAAW,eAAe,MAAM,CAAA;AACtC,EAAA,MAAM,OAAO,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,GAAA;AAEtC,EAAA,KAAA,MAAW,KAAA,IAAS,QAAA,CAAS,MAAA,IAAU,EAAC,EAAG;AACzC,IAAA,MAAM,MAAA,GAAS,SAAA,CAAU,KAAA,CAAM,IAAA,EAAM,IAAI,CAAA;AACzC,IAAA,IAAI,QAAQ,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,OAAO,MAAA,EAAO;AAAA,EACrD;AAEA,EAAA,MAAM,OAAA,GAAU,SAAA,CAAU,gBAAA,EAAkB,IAAI,CAAA;AAChD,EAAA,IAAI,SAAS,IAAA,EAAM,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,QAAQ,OAAA,EAAQ;AAE7D,EAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,YAAA,EAAc,IAAI,CAAA;AAC1C,EAAA,IAAI,OAAO,EAAA,EAAI,OAAO,EAAE,IAAA,EAAM,OAAA,EAAS,QAAQ,KAAA,EAAM;AAIrD,EAAA,IAAI,UAAU,WAAA,EAAa,IAAI,GAAG,OAAO,EAAE,MAAM,UAAA,EAAW;AAC5D,EAAA,IAAI,UAAU,UAAA,EAAY,IAAI,GAAG,OAAO,EAAE,MAAM,SAAA,EAAU;AAC1D,EAAA,IAAI,UAAU,UAAA,EAAY,IAAI,GAAG,OAAO,EAAE,MAAM,SAAA,EAAU;AAK1D,EAAA,IAAI,QAAA,CAAS,QAAA,IAAY,SAAA,CAAU,QAAA,CAAS,QAAA,CAAS,QAAA,EAAU,IAAI,CAAA,EAAG,OAAO,EAAE,IAAA,EAAM,MAAA,EAAO;AAC5F,EAAA,IAAI,QAAA,CAAS,OAAO,IAAA,KAAS,SAAA,IAAa,UAAU,QAAA,CAAS,MAAA,CAAO,WAAA,EAAa,IAAI,CAAA,EAAG;AACtF,IAAA,OAAO,EAAE,MAAM,eAAA,EAAgB;AAAA,EACjC;AACA,EAAA,IAAI,SAAA,CAAU,YAAY,IAAI,CAAA,SAAU,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,SAAA,EAAU;AAC5E,EAAA,IAAI,SAAA,CAAU,UAAU,IAAI,CAAA,SAAU,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,OAAA,EAAQ;AACxE,EAAA,IAAI,SAAA,CAAU,YAAY,IAAI,CAAA,SAAU,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,SAAA,EAAU;AAE5E,EAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,QAAA,CAAS,KAAA,EAAO,IAAI,CAAA;AACrD,EAAA,IAAI,OAAA,EAAS,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,MAAM,OAAA,CAAQ,IAAA,EAAM,MAAA,EAAQ,OAAA,CAAQ,MAAA,EAAO;AAElF,EAAA,IAAI,SAAS,GAAA,IAAO,IAAA,KAAS,IAAI,OAAO,EAAE,MAAM,MAAA,EAAO;AACvD,EAAA,OAAO,EAAE,MAAM,UAAA,EAAW;AAC5B;AAGO,SAAS,WAAA,CACd,QACA,IAAA,EACS;AACT,EAAA,OAAO,sBAAA,CAAuB,MAAA,EAAQ,IAAI,CAAA,CAAE,IAAA,KAAS,UAAA;AACvD;AAOA,IAAM,kBAAkB,CAAC,GAAA,EAAK,UAAA,EAAY,UAAA,EAAY,UAAU,UAAU,CAAA;AAE1E,SAAS,eAAe,MAAA,EAA+E;AACrG,EAAA,OAAO,cAAc,MAAA,IAAU,OAAA,IAAW,MAAA,GACrC,MAAA,GACD,cAAc,MAAM,CAAA;AAC1B;AASO,SAAS,YAAA,CACd,QACA,IAAA,EACS;AACT,EAAA,MAAM,KAAA,GAAQ,sBAAA,CAAuB,MAAA,EAAQ,IAAI,CAAA;AACjD,EAAA,QAAQ,MAAM,IAAA;AAAM,IAClB,KAAK,UAAA;AAAA,IACL,KAAK,SAAA;AAAA,IACL,KAAK,OAAA;AACH,MAAA,OAAO,KAAA;AAAA,IACT,KAAK,QAAA;AACH,MAAA,OACE,KAAA,CAAM,KAAA,CAAM,IAAA,KAAS,UAAA,IACrB,KAAA,CAAM,MAAM,IAAA,KAAS,SAAA,IACrB,KAAA,CAAM,KAAA,CAAM,MAAA,KAAW,SAAA;AAAA,IAE3B;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;AAUA,eAAsB,gBAAgB,KAAA,EAKhB;AACpB,EAAA,MAAM,QAAA,GAAW,cAAA,CAAe,KAAA,CAAM,MAAM,CAAA;AAC5C,EAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,eAAe,CAAA;AAKjC,EAAA,IAAI,SAAS,QAAA,EAAU,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,SAAS,QAAQ,CAAA;AAE5D,EAAA,KAAA,MAAW,KAAA,IAAS,QAAA,CAAS,MAAA,IAAU,EAAC,EAAG;AACzC,IAAA,IAAI,CAAC,MAAM,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAAA,EACtD;AAEA,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,QAAA,CAAS,aAAa,EAAE,MAAA,EAAQ,UAAU,CAAA;AACvE,EAAA,KAAA,MAAW,WAAW,QAAA,EAAU,KAAA,CAAM,KAAK,CAAA,SAAA,EAAY,OAAA,CAAQ,IAAI,CAAA,CAAE,CAAA;AAErE,EAAA,MAAM,SAAS,KAAA,CAAM,IAAA,CAAK,IAAI,GAAA,CAAI,KAAK,CAAC,CAAA;AACxC,EAAA,OAAO,KAAA,CAAM,cAAA,GAAiB,MAAA,GAAS,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,YAAA,CAAa,QAAA,EAAU,CAAC,CAAC,CAAA;AACvF;AC3JO,IAAM,eAAA,GAAkB;AAAA,EAC7B,UAAU,EAAE,MAAA,EAAQ,eAAA,EAAiB,MAAA,EAAQ,EAAC,EAAE;AAAA,EAChD,YAAY,EAAE,MAAA,EAAQ,iBAAA,EAAmB,MAAA,EAAQ,EAAC,EAAE;AAAA,EACpD,UAAU,EAAE,MAAA,EAAQ,mBAAA,EAAqB,MAAA,EAAQ,EAAC;AACpD;AAGO,SAAS,aAAA,GAAyF;AACvG,EAAA,OAAO,OAAO,MAAA,CAAO,eAAe,EAAE,GAAA,CAAI,CAAC,EAAE,MAAA,EAAQ,MAAA,EAAO,MAAO,EAAE,KAAKC,WAAAA,CAAY,MAAA,EAAQ,MAAM,CAAA,EAAG,MAAA,EAAQ,QAAO,CAAE,CAAA;AAC1H","file":"chunk-UJHCVRK3.js","sourcesContent":["// ---------------------------------------------------------------------------\n// The storefront's own words (cart, checkout, delivery), per language.\n//\n// pt-BR is the source: copied verbatim from the screens as they were, so a\n// store that sets no language reads exactly what it always read. en and es\n// translate it; a key missing from either falls back to pt-BR, never to the\n// key itself. `{{name}}` marks a value filled in at the call site.\n// ---------------------------------------------------------------------------\n\nexport type StorefrontLanguage = 'pt-BR' | 'en' | 'es'\n\nexport const ptBR = {\n // Checkout shell\n 'checkout.title': 'Checkout — {{store}}',\n 'checkout.backToStore': 'Voltar à loja',\n 'checkout.secure': 'Checkout seguro',\n 'checkout.help': 'Ajuda',\n 'checkout.steps.label': 'Etapas do checkout',\n 'checkout.steps.1': 'Dados',\n 'checkout.steps.2': 'Entrega',\n 'checkout.steps.3': 'Pagamento',\n 'checkout.steps.4': 'Pronto',\n // Step 1 — contact\n 'checkout.contact.title': 'Informações de contato',\n 'checkout.contact.signedInAs': 'Conectado como {{email}}',\n 'checkout.contact.edit': 'Alterar',\n 'checkout.contact.notYou': 'Não é você?',\n 'checkout.contact.signOut': 'Sair',\n 'checkout.contact.emailLocked': 'O e-mail é o da sua conta.',\n 'checkout.contact.haveAccount': 'Já tem conta? Entrar',\n 'checkout.contact.email': 'E-mail',\n 'checkout.contact.name': 'Nome completo',\n 'checkout.contact.phone': 'Telefone',\n 'checkout.contact.phoneOptional': 'Telefone (opcional)',\n 'checkout.contact.document': 'CPF ou CNPJ',\n 'checkout.contact.documentOptional': 'CPF ou CNPJ (opcional)',\n 'checkout.contact.requiresAccount': 'Esta loja pede uma conta para finalizar a compra.',\n 'checkout.contact.signInOrCreate': 'Entrar ou criar conta',\n // Step 2 — address\n 'checkout.address.title': 'Endereço de entrega',\n 'checkout.address.loadingSaved': 'Buscando seus endereços salvos',\n 'checkout.address.selected': 'Selecionado',\n 'checkout.address.addNew': '+ Adicionar novo endereço',\n 'checkout.address.enter': 'Informe o endereço de entrega',\n 'checkout.address.enterHint': 'Preencher outro endereço para esta compra',\n 'checkout.address.lookingUp': 'Buscando o endereço deste CEP',\n 'checkout.address.notFound': 'CEP não encontrado — preencha o endereço à mão.',\n 'checkout.address.filled': 'Preenchemos o endereço para você.',\n 'checkout.address.regionFromPostal': 'Província preenchida pelo código postal.',\n 'checkout.address.optional': '{{label}} (opcional)',\n 'checkout.address.choose': 'Selecione',\n 'checkout.address.shipTo': 'Enviar para',\n // Step 3 — payment\n 'checkout.confirming.title': 'Confirmando seu pedido',\n 'checkout.confirming.label': 'Criando seu pedido',\n 'checkout.confirming.keepOpen': 'Não feche esta página — estamos registrando seu pedido na loja.',\n 'checkout.payment.title': 'Pagamento',\n 'checkout.payment.label': 'Forma de pagamento',\n 'checkout.payment.cardOnline': 'Você paga na página segura do provedor e volta para a loja',\n 'checkout.payment.placeOrder': 'Fazer pedido - {{total}}',\n 'checkout.payment.pendingNote': 'O pedido fica aguardando pagamento até a loja confirmar.',\n 'checkout.payment.unavailableCountry': 'Esta forma de pagamento não está disponível para {{country}}.',\n 'payment.pix.label': 'Pix',\n 'payment.pix.hint': 'Você recebe a chave para pagar após confirmar o pedido',\n 'payment.credit_card.label': 'Cartão de crédito',\n 'payment.credit_card.hint': 'Maquininha na entrega',\n 'payment.debit_card.label': 'Cartão de débito',\n 'payment.debit_card.hint': 'Maquininha na entrega',\n 'payment.boleto.label': 'Boleto',\n 'payment.boleto.hint': 'Enviado por e-mail após a confirmação',\n 'payment.cash.label': 'Dinheiro',\n 'payment.cash.hint': 'Pagamento na entrega',\n 'payment.other.label': 'Combinar com a loja',\n 'payment.other.hint': 'A loja entra em contato para acertar o pagamento',\n // Step 4\n 'checkout.done.title': 'Pagamento confirmado!',\n 'checkout.done.text': 'Seu pedido foi criado e a loja já foi avisada.',\n 'checkout.done.viewOrder': 'Ver meu pedido',\n // Navigation\n 'checkout.continueToDelivery': 'Continuar para a entrega',\n 'checkout.goToPayment': 'Ir para o pagamento - {{total}}',\n 'checkout.backToContact': 'Voltar aos dados',\n 'checkout.backToCart': 'Voltar ao carrinho',\n // Summary\n 'summary.title': 'Resumo do pedido',\n 'summary.subtotal': 'Subtotal',\n 'summary.discount': 'Desconto',\n 'summary.delivery': 'Entrega',\n 'summary.pickup': 'Retirada na loja',\n 'summary.noFee': 'Sem taxa',\n 'summary.free': 'Grátis',\n 'summary.total': 'Total',\n 'summary.protected': 'Compra protegida e dados criptografados.',\n 'summary.shipping': 'Frete',\n // Discount\n 'discount.placeholder': 'Cupom de desconto',\n 'discount.apply': 'Aplicar',\n 'discount.freeShipping': 'frete grátis',\n 'discount.percentOff': '{{percent}}% de desconto',\n 'discount.applied': '{{code}} aplicado: {{effect}}.',\n 'discount.appliedToast': 'Cupom aplicado!',\n 'discount.invalid': 'Cupom inválido.',\n 'discount.invalidToast': 'Cupom inválido',\n 'discount.checkCode': 'Verifique o código e tente novamente.',\n 'discount.cannotValidate': 'Não conseguimos validar esse cupom agora.',\n 'discount.cannotValidateToast': 'Não conseguimos validar o cupom',\n 'discount.tryLater': 'Tente de novo em alguns instantes.',\n // Legal\n 'legal.privacy': 'Privacidade',\n 'legal.terms': 'Termos',\n 'legal.refunds': 'Trocas e devoluções',\n // Validation\n 'error.requiresAccount': 'Esta loja pede uma conta para finalizar a compra. Entre ou crie a sua.',\n 'error.email': 'Informe um e-mail válido.',\n 'error.name': 'Informe seu nome completo.',\n 'error.phone': 'Informe um telefone de contato.',\n 'error.documentInvalid': 'CPF ou CNPJ inválido — confira os números.',\n 'error.documentMissing': 'Informe o CPF ou CNPJ do comprador.',\n 'error.taxIdInvalid': 'NIF/NIE inválido — confira o número.',\n 'error.address': 'Preencha ou selecione o endereço de entrega.',\n 'error.number': 'Falta o número do endereço.',\n 'error.complement': 'Informe o complemento (apto, bloco).',\n 'error.state': 'Informe a UF com duas letras (ex.: RJ).',\n 'error.postalInvalid': 'Confira o código postal (ex.: {{example}}).',\n 'error.region': 'Selecione a {{label}}.',\n 'error.refusedZone': 'Esta loja não entrega nesse endereço. Tente outro.',\n 'error.unserved': 'Ainda não entregamos nesse CEP. Tente outro endereço.',\n 'error.sessionMismatch': 'Sua sessão ficou presa a outro cadastro. Recarregue a página e tente de novo.',\n 'error.outOfStock': 'Um item do carrinho ficou sem estoque. Revise o carrinho e tente de novo.',\n 'error.placeOrder': 'Não foi possível concluir o pedido.',\n // Delivery estimator\n 'delivery.title': 'Calcular entrega',\n 'delivery.calculate': 'Calcular',\n 'delivery.postalLabel': 'CEP',\n 'delivery.change': 'Trocar CEP',\n 'delivery.unserved': 'Ainda não entregamos nesse CEP.',\n 'delivery.refused': 'Esta loja não entrega nesse endereço.',\n 'delivery.review': 'Entregamos nessa região, mas confirmamos com você antes de sair.',\n 'delivery.etaSoon': 'hoje ou amanhã',\n 'delivery.etaRange': '{{min}} a {{max}} dias úteis',\n 'delivery.etaDays': '{{days}} dia(s) útil(eis)',\n 'delivery.flatRate': 'O frete é calculado no checkout.',\n 'delivery.error.digits': 'Digite os 8 dígitos do CEP.',\n 'delivery.error.postal': 'Confira o código postal (ex.: {{example}}).',\n 'delivery.error.quote': 'Não foi possível calcular o frete agora. Tente de novo.',\n 'delivery.error.notFound': 'CEP não encontrado. Confira os números.',\n // Cart\n 'cart.title': 'Carrinho',\n 'cart.close': 'Fechar carrinho',\n 'cart.empty': 'Seu carrinho está vazio.',\n 'cart.remove': 'Remover {{name}}',\n 'cart.checkout': 'Finalizar compra',\n 'cart.missingForFree': 'Faltam {{amount}} para frete grátis',\n 'cart.wonFree': 'Você ganhou frete grátis!',\n 'cart.minimumOrder': 'Pedido mínimo para entrega: {{amount}}. Faltam {{missing}}.',\n 'delivery.eta': 'Entrega em ~{{duration}}',\n 'delivery.etaUpTo': 'Entrega em até {{duration}}',\n 'delivery.paused': 'Delivery fechado no momento',\n 'cart.deliveryPaused': 'O delivery está fechado no momento. Volte mais tarde para finalizar.',\n // Deliver to\n 'country.deliverTo': 'Enviar para',\n 'country.change': 'Trocar país',\n 'country.label': 'País de entrega',\n}\n\nexport type MessageKey = keyof typeof ptBR\nexport type Messages = Record<MessageKey, string>\n\nconst en: Partial<Messages> = {\n 'checkout.backToStore': 'Back to store',\n 'checkout.secure': 'Secure checkout',\n 'checkout.help': 'Help',\n 'checkout.steps.label': 'Checkout steps',\n 'checkout.steps.1': 'Details',\n 'checkout.steps.2': 'Delivery',\n 'checkout.steps.3': 'Payment',\n 'checkout.steps.4': 'Done',\n 'checkout.contact.title': 'Contact information',\n 'checkout.contact.signedInAs': 'Signed in as {{email}}',\n 'checkout.contact.edit': 'Change',\n 'checkout.contact.notYou': 'Not you?',\n 'checkout.contact.signOut': 'Sign out',\n 'checkout.contact.emailLocked': 'This is your account e-mail.',\n 'checkout.contact.haveAccount': 'Have an account? Sign in',\n 'checkout.contact.email': 'Email',\n 'checkout.contact.name': 'Full name',\n 'checkout.contact.phone': 'Phone',\n 'checkout.contact.phoneOptional': 'Phone (optional)',\n 'checkout.contact.document': 'Tax ID',\n 'checkout.contact.documentOptional': 'Tax ID (optional)',\n 'checkout.contact.requiresAccount': 'This store needs an account to complete the purchase.',\n 'checkout.contact.signInOrCreate': 'Sign in or create an account',\n 'checkout.address.title': 'Delivery address',\n 'checkout.address.loadingSaved': 'Loading your saved addresses',\n 'checkout.address.selected': 'Selected',\n 'checkout.address.addNew': '+ Add a new address',\n 'checkout.address.enter': 'Enter the delivery address',\n 'checkout.address.enterHint': 'Use a different address for this order',\n 'checkout.address.lookingUp': 'Looking up this postal code',\n 'checkout.address.notFound': 'Postal code not found — fill in the address by hand.',\n 'checkout.address.filled': 'We filled in the address for you.',\n 'checkout.address.regionFromPostal': 'Province filled in from the postcode.',\n 'checkout.address.optional': '{{label}} (optional)',\n 'checkout.address.choose': 'Select',\n 'checkout.address.shipTo': 'Ship to',\n 'checkout.confirming.title': 'Confirming your order',\n 'checkout.confirming.label': 'Creating your order',\n 'checkout.confirming.keepOpen': 'Don’t close this page — we’re registering your order with the store.',\n 'checkout.payment.title': 'Payment',\n 'checkout.payment.label': 'Payment method',\n 'checkout.payment.cardOnline': 'You pay on the provider’s secure page and come back to the store',\n 'checkout.payment.placeOrder': 'Place order - {{total}}',\n 'checkout.payment.pendingNote': 'The order awaits payment until the store confirms it.',\n 'checkout.payment.unavailableCountry': 'This payment method isn’t available for {{country}}.',\n 'payment.pix.hint': 'You get the key to pay after confirming the order',\n 'payment.credit_card.label': 'Credit card',\n 'payment.credit_card.hint': 'Card machine on delivery',\n 'payment.debit_card.label': 'Debit card',\n 'payment.debit_card.hint': 'Card machine on delivery',\n 'payment.boleto.hint': 'Sent by email after confirmation',\n 'payment.cash.label': 'Cash',\n 'payment.cash.hint': 'Pay on delivery',\n 'payment.other.label': 'Arrange with the store',\n 'payment.other.hint': 'The store will contact you to arrange payment',\n 'checkout.done.title': 'Payment confirmed!',\n 'checkout.done.text': 'Your order was created and the store has been notified.',\n 'checkout.done.viewOrder': 'View my order',\n 'checkout.continueToDelivery': 'Continue to delivery',\n 'checkout.goToPayment': 'Go to payment - {{total}}',\n 'checkout.backToContact': 'Back to details',\n 'checkout.backToCart': 'Back to cart',\n 'summary.title': 'Order summary',\n 'summary.discount': 'Discount',\n 'summary.delivery': 'Delivery',\n 'summary.pickup': 'Store pickup',\n 'summary.noFee': 'No fee',\n 'summary.free': 'Free',\n 'summary.protected': 'Protected purchase, encrypted data.',\n 'summary.shipping': 'Shipping',\n 'discount.placeholder': 'Discount code',\n 'discount.apply': 'Apply',\n 'discount.freeShipping': 'free shipping',\n 'discount.percentOff': '{{percent}}% off',\n 'discount.applied': '{{code}} applied: {{effect}}.',\n 'discount.appliedToast': 'Code applied!',\n 'discount.invalid': 'Invalid code.',\n 'discount.invalidToast': 'Invalid code',\n 'discount.checkCode': 'Check the code and try again.',\n 'discount.cannotValidate': 'We couldn’t check this code right now.',\n 'discount.cannotValidateToast': 'We couldn’t check the code',\n 'discount.tryLater': 'Try again in a moment.',\n 'legal.privacy': 'Privacy',\n 'legal.terms': 'Terms',\n 'legal.refunds': 'Returns',\n 'error.requiresAccount': 'This store needs an account to complete the purchase. Sign in or create one.',\n 'error.email': 'Enter a valid email.',\n 'error.name': 'Enter your full name.',\n 'error.phone': 'Enter a contact phone number.',\n 'error.documentInvalid': 'Invalid tax ID — check the numbers.',\n 'error.documentMissing': 'Enter the buyer’s tax ID.',\n 'error.taxIdInvalid': 'Invalid NIF/NIE — check the number.',\n 'error.address': 'Fill in or select the delivery address.',\n 'error.number': 'The street number is missing.',\n 'error.complement': 'Enter the apartment or unit.',\n 'error.state': 'Enter the two-letter state code (e.g. RJ).',\n 'error.postalInvalid': 'Check the postal code (e.g. {{example}}).',\n 'error.region': 'Select the {{label}}.',\n 'error.refusedZone': 'This store doesn’t deliver to this address. Try another.',\n 'error.unserved': 'We don’t deliver to this postal code yet. Try another address.',\n 'error.sessionMismatch': 'Your session got attached to another account. Reload the page and try again.',\n 'error.outOfStock': 'An item in your cart is out of stock. Review the cart and try again.',\n 'error.placeOrder': 'We couldn’t complete the order.',\n 'delivery.title': 'Estimate delivery',\n 'delivery.calculate': 'Estimate',\n 'delivery.postalLabel': 'Postal code',\n 'delivery.change': 'Change postal code',\n 'delivery.unserved': 'We don’t deliver to this postal code yet.',\n 'delivery.refused': 'This store doesn’t deliver to this address.',\n 'delivery.review': 'We deliver to this area, but we’ll confirm with you before shipping.',\n 'delivery.etaSoon': 'today or tomorrow',\n 'delivery.etaRange': '{{min}} to {{max}} business days',\n 'delivery.etaDays': '{{days}} business day(s)',\n 'delivery.flatRate': 'Shipping is calculated at checkout.',\n 'delivery.error.digits': 'Enter all 8 digits of the CEP.',\n 'delivery.error.postal': 'Check the postal code (e.g. {{example}}).',\n 'delivery.error.quote': 'We couldn’t calculate shipping right now. Try again.',\n 'delivery.error.notFound': 'Postal code not found. Check the numbers.',\n 'cart.title': 'Cart',\n 'cart.close': 'Close cart',\n 'cart.empty': 'Your cart is empty.',\n 'cart.remove': 'Remove {{name}}',\n 'cart.checkout': 'Checkout',\n 'cart.missingForFree': '{{amount}} away from free shipping',\n 'cart.wonFree': 'You got free shipping!',\n 'cart.minimumOrder': 'Minimum order for delivery: {{amount}}. {{missing}} to go.',\n 'delivery.eta': 'Delivery in ~{{duration}}',\n 'delivery.etaUpTo': 'Delivery within {{duration}}',\n 'delivery.paused': 'Delivery closed right now',\n 'cart.deliveryPaused': 'Delivery is closed right now. Come back later to check out.',\n 'country.deliverTo': 'Deliver to',\n 'country.change': 'Change country',\n 'country.label': 'Delivery country',\n}\n\nconst es: Partial<Messages> = {\n 'checkout.backToStore': 'Volver a la tienda',\n 'checkout.secure': 'Pago seguro',\n 'checkout.help': 'Ayuda',\n 'checkout.steps.label': 'Pasos del pago',\n 'checkout.steps.1': 'Datos',\n 'checkout.steps.2': 'Envío',\n 'checkout.steps.3': 'Pago',\n 'checkout.steps.4': 'Listo',\n 'checkout.contact.title': 'Datos de contacto',\n 'checkout.contact.signedInAs': 'Has iniciado sesión como {{email}}',\n 'checkout.contact.edit': 'Cambiar',\n 'checkout.contact.notYou': '¿No eres tú?',\n 'checkout.contact.signOut': 'Salir',\n 'checkout.contact.emailLocked': 'Es el correo de tu cuenta.',\n 'checkout.contact.haveAccount': '¿Ya tienes cuenta? Entrar',\n 'checkout.contact.email': 'Email',\n 'checkout.contact.name': 'Nombre completo',\n 'checkout.contact.phone': 'Teléfono',\n 'checkout.contact.phoneOptional': 'Teléfono (opcional)',\n 'checkout.contact.document': 'NIF/NIE',\n 'checkout.contact.documentOptional': 'NIF/NIE (opcional)',\n 'checkout.contact.requiresAccount': 'Esta tienda pide una cuenta para finalizar la compra.',\n 'checkout.contact.signInOrCreate': 'Entrar o crear cuenta',\n 'checkout.address.title': 'Dirección de envío',\n 'checkout.address.loadingSaved': 'Buscando tus direcciones guardadas',\n 'checkout.address.selected': 'Seleccionada',\n 'checkout.address.addNew': '+ Añadir una dirección nueva',\n 'checkout.address.enter': 'Indica la dirección de envío',\n 'checkout.address.enterHint': 'Usar otra dirección para este pedido',\n 'checkout.address.lookingUp': 'Buscando este código postal',\n 'checkout.address.notFound': 'Código postal no encontrado: rellena la dirección a mano.',\n 'checkout.address.filled': 'Hemos rellenado la dirección por ti.',\n 'checkout.address.regionFromPostal': 'Provincia rellenada a partir del código postal.',\n 'checkout.address.optional': '{{label}} (opcional)',\n 'checkout.address.choose': 'Selecciona',\n 'checkout.address.shipTo': 'Enviar a',\n 'checkout.confirming.title': 'Confirmando tu pedido',\n 'checkout.confirming.label': 'Creando tu pedido',\n 'checkout.confirming.keepOpen': 'No cierres esta página: estamos registrando tu pedido en la tienda.',\n 'checkout.payment.title': 'Pago',\n 'checkout.payment.label': 'Forma de pago',\n 'checkout.payment.cardOnline': 'Pagas en la página segura del proveedor y vuelves a la tienda',\n 'checkout.payment.placeOrder': 'Hacer pedido - {{total}}',\n 'checkout.payment.pendingNote': 'El pedido queda pendiente de pago hasta que la tienda lo confirme.',\n 'checkout.payment.unavailableCountry': 'Esta forma de pago no está disponible para {{country}}.',\n 'payment.pix.hint': 'Recibes la clave para pagar al confirmar el pedido',\n 'payment.credit_card.label': 'Tarjeta de crédito',\n 'payment.credit_card.hint': 'Datáfono en la entrega',\n 'payment.debit_card.label': 'Tarjeta de débito',\n 'payment.debit_card.hint': 'Datáfono en la entrega',\n 'payment.boleto.hint': 'Enviado por email tras la confirmación',\n 'payment.cash.label': 'Efectivo',\n 'payment.cash.hint': 'Pago en la entrega',\n 'payment.other.label': 'Acordar con la tienda',\n 'payment.other.hint': 'La tienda te contactará para acordar el pago',\n 'checkout.done.title': '¡Pago confirmado!',\n 'checkout.done.text': 'Tu pedido se ha creado y la tienda ya ha sido avisada.',\n 'checkout.done.viewOrder': 'Ver mi pedido',\n 'checkout.continueToDelivery': 'Continuar al envío',\n 'checkout.goToPayment': 'Ir al pago - {{total}}',\n 'checkout.backToContact': 'Volver a los datos',\n 'checkout.backToCart': 'Volver al carrito',\n 'summary.title': 'Resumen del pedido',\n 'summary.discount': 'Descuento',\n 'summary.delivery': 'Envío',\n 'summary.pickup': 'Recogida en tienda',\n 'summary.noFee': 'Sin coste',\n 'summary.free': 'Gratis',\n 'summary.protected': 'Compra protegida y datos cifrados.',\n 'summary.shipping': 'Envío',\n 'discount.placeholder': 'Código de descuento',\n 'discount.apply': 'Aplicar',\n 'discount.freeShipping': 'envío gratis',\n 'discount.percentOff': '{{percent}}% de descuento',\n 'discount.applied': '{{code}} aplicado: {{effect}}.',\n 'discount.appliedToast': '¡Código aplicado!',\n 'discount.invalid': 'Código no válido.',\n 'discount.invalidToast': 'Código no válido',\n 'discount.checkCode': 'Revisa el código e inténtalo de nuevo.',\n 'discount.cannotValidate': 'No hemos podido validar este código ahora.',\n 'discount.cannotValidateToast': 'No hemos podido validar el código',\n 'discount.tryLater': 'Inténtalo de nuevo en unos instantes.',\n 'legal.privacy': 'Privacidad',\n 'legal.terms': 'Términos',\n 'legal.refunds': 'Devoluciones',\n 'error.requiresAccount': 'Esta tienda pide una cuenta para finalizar la compra. Entra o crea la tuya.',\n 'error.email': 'Indica un email válido.',\n 'error.name': 'Indica tu nombre completo.',\n 'error.phone': 'Indica un teléfono de contacto.',\n 'error.documentInvalid': 'Documento no válido: revisa los números.',\n 'error.documentMissing': 'Indica el documento del comprador.',\n 'error.taxIdInvalid': 'NIF/NIE no válido: revisa el número.',\n 'error.address': 'Rellena o selecciona la dirección de envío.',\n 'error.number': 'Falta el número de la dirección.',\n 'error.complement': 'Indica el piso o la puerta.',\n 'error.state': 'Indica el estado con dos letras (ej.: RJ).',\n 'error.postalInvalid': 'Revisa el código postal (ej.: {{example}}).',\n 'error.region': 'Selecciona la {{label}}.',\n 'error.refusedZone': 'Esta tienda no envía a esta dirección. Prueba con otra.',\n 'error.unserved': 'Todavía no enviamos a este código postal. Prueba con otra dirección.',\n 'error.sessionMismatch': 'Tu sesión quedó vinculada a otra cuenta. Recarga la página e inténtalo de nuevo.',\n 'error.outOfStock': 'Un producto del carrito se ha agotado. Revisa el carrito e inténtalo de nuevo.',\n 'error.placeOrder': 'No se ha podido completar el pedido.',\n 'delivery.title': 'Calcular envío',\n 'delivery.calculate': 'Calcular',\n 'delivery.postalLabel': 'Código postal',\n 'delivery.change': 'Cambiar código postal',\n 'delivery.unserved': 'Todavía no enviamos a este código postal.',\n 'delivery.refused': 'Esta tienda no envía a esta dirección.',\n 'delivery.review': 'Enviamos a esta zona, pero lo confirmamos contigo antes de salir.',\n 'delivery.etaSoon': 'hoy o mañana',\n 'delivery.etaRange': 'de {{min}} a {{max}} días laborables',\n 'delivery.etaDays': '{{days}} día(s) laborable(s)',\n 'delivery.flatRate': 'El envío se calcula en el pago.',\n 'delivery.error.digits': 'Escribe los 8 dígitos del CEP.',\n 'delivery.error.postal': 'Revisa el código postal (ej.: {{example}}).',\n 'delivery.error.quote': 'No hemos podido calcular el envío ahora. Inténtalo de nuevo.',\n 'delivery.error.notFound': 'Código postal no encontrado. Revisa los números.',\n 'cart.title': 'Carrito',\n 'cart.close': 'Cerrar carrito',\n 'cart.empty': 'Tu carrito está vacío.',\n 'cart.remove': 'Quitar {{name}}',\n 'cart.checkout': 'Finalizar compra',\n 'cart.missingForFree': 'Te faltan {{amount}} para el envío gratis',\n 'cart.wonFree': '¡Tienes envío gratis!',\n 'cart.minimumOrder': 'Pedido mínimo para entrega: {{amount}}. Te faltan {{missing}}.',\n 'delivery.eta': 'Entrega en ~{{minutes}} min',\n 'country.deliverTo': 'Enviar a',\n 'country.change': 'Cambiar país',\n 'country.label': 'País de envío',\n}\n\nexport const MESSAGES: Record<StorefrontLanguage, Partial<Messages>> = { 'pt-BR': ptBR, en, es }\n\n/** 'pt', 'pt-PT', 'PT-br' → 'pt-BR'; 'en-GB' → 'en'; 'es-MX' → 'es'; anything else → null. */\nexport function normalizeLanguage(value?: string | null): StorefrontLanguage | null {\n const base = (value || '').toLowerCase().split(/[-_]/)[0]\n if (base === 'pt') return 'pt-BR'\n if (base === 'en') return 'en'\n if (base === 'es') return 'es'\n return null\n}\n\n/** Look a key up: the store's override, the language, then pt-BR. */\nexport function translate(\n language: StorefrontLanguage,\n key: MessageKey,\n vars?: Record<string, string | number>,\n overrides?: Partial<Record<StorefrontLanguage, Partial<Messages>>>,\n): string {\n let text = overrides?.[language]?.[key] ?? MESSAGES[language]?.[key] ?? overrides?.['pt-BR']?.[key] ?? ptBR[key]\n if (vars) for (const [name, value] of Object.entries(vars)) text = text.split(`{{${name}}}`).join(String(value))\n return text\n}\n","import React, { createContext, useContext, type ReactNode } from 'react'\nimport type { StorefrontAnalyticsConfig } from '../analytics/posthog'\nimport type { StorefrontExperiment } from '../experiments/assign'\nimport type { Experimental } from '../experiments/react'\nimport type { EntityDeclarationInput } from '@fayz-ai/core'\nimport type { ShopProvider } from '@fayz-ai/shop/provider'\nimport type { MockShopSeed } from '@fayz-ai/shop/mock'\nimport type { PaymentMethodKind, Product, ShopMarket, StoreSettings } from '@fayz-ai/shop/types'\nimport type { Promotion } from '@fayz-ai/shop/rules'\nimport type { StorefrontTheme } from '../lib/theme'\nimport type { HomeConfig, NavLink, FooterConfig } from '../blocks/sections'\nimport type { StorefrontPagesConfig } from '../blocks/page-blocks'\nimport { normalizeLanguage, type Messages, type StorefrontLanguage } from '../locales/messages'\n// Type-only: slots.tsx imports the config hook at runtime, so a value import\n// here would close the cycle.\nimport type { StorefrontSlots } from '../extend/slots'\nimport type { StorefrontAuthConfig } from '../data/auth'\nimport type { StorefrontComponents } from '../extend/component-contracts'\nimport type { StorefrontReviewsConfig } from '../components/product/ProductReviews'\nimport type { CatalogFacetConfig } from '../components/collection/FiltersPanel'\n\nexport type StorefrontRouteKind =\n | 'home'\n | 'catalog'\n | 'product'\n | 'checkout'\n | 'account'\n | 'order'\n | 'custom'\n\nexport type StorefrontRouteParams = Record<string, string>\n\nexport interface StorefrontRouteComponentProps {\n path: string\n params: StorefrontRouteParams\n config: ResolvedStorefrontConfig\n}\n\n/**\n * Quanta moldura o fluxo aguenta.\n *\n * default a vitrine inteira — nav de marketing, rodapé, tudo.\n * minimal marca + busca + carrinho, e o resto da navegação recolhida no\n * menu. É o cabeçalho de um app de pedido: o cardápio JÁ é a tarefa,\n * e cinco links concorrendo com ela no topo são cinco saídas.\n * focused sem moldura nenhuma. Para o checkout, onde qualquer link é fuga.\n *\n * `minimal` existe porque os dois extremos estavam errados para o cardápio:\n * `default` compete com o pedido e `focused` levaria junto o carrinho e a busca\n * — e esconder a navegação INTEIRA num fluxo é o oposto do que a regra de\n * navegação persistente pede. Recolher não é esconder.\n */\nexport type StorefrontRouteChrome = 'default' | 'minimal' | 'focused'\n/**\n * 'delivery' (0094) é 'checkout' com a ordem das perguntas invertida: a loja\n * responde \"estou aberta?\" e \"onde você está?\" ANTES do carrinho, e só pergunta\n * quem é o comprador no fim. Herda tudo que 'checkout' liga — carrinho, contas,\n * pagamento — e acrescenta a rota /menu, o seletor entrega × retirada e o\n * agendamento.\n *\n * Um modo e não uma flag solta porque as quatro coisas andam juntas: uma loja\n * com horário mas sem cardápio, ou com retirada mas sem horário, não é um\n * estado que alguém queira operar.\n */\nexport type StorefrontCommerceMode = 'checkout' | 'catalog' | 'enquiry' | 'delivery'\nexport type StorefrontImageLoadingMode = 'fade' | 'none'\n\nexport interface StorefrontImageLoadingConfig {\n mode?: StorefrontImageLoadingMode\n durationMs?: number\n easing?: string\n blur?: boolean\n /**\n * Where the browser gets a photo at the size it draws it.\n *\n * 'supabase' — images in the store's own storage are served as\n * delivery-time variants (`…/render/image/public/…?width=…`): resized once\n * per size, cached at the CDN, WebP for browsers that take it, and offered\n * as a `srcset` so a card never downloads the gallery's 4000 px original.\n * Requires the storage project to have image transformations enabled (a\n * plan feature); an image hotlinked from anywhere else is left untouched.\n * 'none' (default) — every image is loaded as it was stored.\n */\n transform?: 'supabase' | 'none'\n}\n\nexport interface StorefrontRouteDefinition {\n /**\n * Stable identifier for generated-code diffs, QA reports, and route ownership.\n */\n id: string\n /**\n * Hash route pattern. Supports the same params as matchPath, e.g. '/checkout'\n * or '/collections/:slug'. Custom routes are matched before SDK defaults.\n */\n path: string\n /**\n * Intent label for agents and manifests. It does not change matching behavior.\n */\n kind?: StorefrontRouteKind\n /**\n * Shell chrome for the route. `focused` hides storefront nav/footer/cart\n * around high-intent flows such as checkout.\n */\n chrome?: StorefrontRouteChrome\n /**\n * App-owned screen/workflow that can still use storefront/shop primitives.\n */\n component: React.ComponentType<StorefrontRouteComponentProps>\n}\n\nexport interface StorefrontDiscountConfig {\n code: string\n percent: number\n title?: string\n}\n\nexport interface StorefrontEnquiryConfig {\n label?: string\n successMessage?: string\n subjectPrefix?: string\n email?: string\n whatsappUrl?: string\n requirePhone?: boolean\n}\n\nexport interface StorefrontConfig {\n /** Store display name (header, page title) */\n name: string\n /** Optional logo node; defaults to the store name */\n logo?: React.ReactNode\n /** ISO 4217 — default 'BRL' */\n currency?: string\n /** Intl locale for money/date formatting — default 'pt-BR' */\n locale?: string\n /**\n * Language of the SDK's own screens (cart, checkout, delivery): 'pt-BR',\n * 'en' or 'es'. Default 'pt-BR'. Separate from `locale`, which formats money.\n * A host that knows the visitor's language per request passes it to\n * StorefrontConfigHost as `buyer.language` instead.\n */\n language?: string\n /** Per-store copy overrides, by language and message key. */\n messages?: Partial<Record<StorefrontLanguage, Partial<Messages>>>\n /**\n * ISO2 countries the store ships to. Default ['BR']. With more than one, the\n * buyer picks (or is detected into) one, and the address form, validation\n * and payment methods follow that country.\n */\n countries?: readonly string[]\n /** The country assumed before the buyer says otherwise. Default: countries[0]. */\n defaultCountry?: string\n /** Visual identity: colors, fonts, radius, header/card personality */\n theme?: StorefrontTheme\n /** Checkout-first default, catalog-only browsing, or product enquiry flow. */\n commerceMode?: StorefrontCommerceMode\n /** Promo message above the header (e.g. 'FRETE GRÁTIS ACIMA DE R$ 300') */\n announcement?: string\n /**\n * How pages are addressed when this store is served.\n *\n * `'hash'` (the default) needs no server configuration and is how every\n * shipped store works today. `'history'` gives each page a real URL, which is\n * what makes it indexable, shareable with its own link preview, and\n * prerenderable — and requires the host to serve the app shell for unknown\n * paths, or a deep link 404s before the app ever runs.\n */\n routing?: 'hash' | 'history'\n /**\n * Home page blueprint. When set, `/` renders it and the catalog moves to /catalog.\n *\n * Still fully supported — five of seven live stores write it. `pages.home` is\n * the same thing with room for the other routes; this stays as the short form.\n */\n home?: HomeConfig\n /**\n * Pages composed from blocks.\n *\n * `catalog` and `product` compose AROUND the native body block rather than\n * replacing it, so a store adds content to those pages without taking over\n * their maintenance. Omitting a page renders the SDK default — adopting this\n * field changes nothing until something is added.\n */\n pages?: StorefrontPagesConfig\n /**\n * Blocks grafted into named positions inside SDK pages.\n *\n * This is the rung between \"configure a section\" and \"rewrite the page\". If\n * you are about to reimplement an SDK page to add one thing to it, look for\n * the slot first — and if the position you need is missing, that is a gap in\n * this list rather than a reason to fork. `listSlots()` enumerates them.\n */\n slots?: StorefrontSlots\n /** Header nav links — defaults derived from home/catalog routing */\n nav?: NavLink[]\n /** Footer content (about text, contact, social) */\n footer?: FooterConfig\n /** Preferred backend descriptor for manifest/scaffold metadata. */\n backend?: { provider?: 'mock' | 'fayz-api' | 'fayz-shop' | 'custom'; url?: string }\n /** @deprecated Use backend/provider adapters. Storefront no longer creates Supabase clients. */\n supabaseUrl?: string\n /** @deprecated Use backend/provider adapters. Storefront no longer creates Supabase clients. */\n supabaseAnonKey?: string\n /** Explicit provider override (tests, custom backends) */\n provider?: ShopProvider\n /**\n * Product analytics. With `posthog` set, every page view, click, cart change\n * and checkout step is reported to that project, grouped under `storeId`.\n */\n analytics?: StorefrontAnalyticsConfig\n /** Per-store mock catalog (products/categories/discounts) for mock mode */\n catalog?: MockShopSeed\n /**\n * Custom entity declarations (spine M4), keyed by entity key. Registered\n * through defineEntity at runtime init, so one config field yields the\n * record schema, the storage descriptor, the generated RLS, the entity.*\n * loaders and the admin form.\n */\n entities?: Record<string, EntityDeclarationInput>\n /** Store-level discount codes available regardless of provider backend. */\n discounts?: StorefrontDiscountConfig[]\n /**\n * Rule-engine promotions (spine M6) — the serializable Promotion shape:\n * eligibility rules + application method, pure data. Rides in the Store\n * Document's `promotions` section; the mock provider evaluates them with\n * the reference evaluator, a live backend re-evaluates server-side. A\n * `{code, percent}` entry in `discounts` is the same thing in shorthand.\n */\n promotions?: Promotion[]\n /**\n * Institutional/legal page content (privacy, terms, returns). Plain text —\n * blank lines separate paragraphs. Unset pages render a placeholder so the\n * routes (and footer links) exist even before the store writes its policy.\n */\n legal?: { privacy?: string; terms?: string; returns?: string }\n /** Customer auth — same AuthAdapter contract as createSaasApp. Default: mock. */\n auth?: StorefrontAuthConfig\n /** Shipping pricing — default { flatRate: 0 } */\n shipping?: { flatRate?: number; freeAbove?: number }\n /**\n * Modo delivery (0094). Ignorado fora de `commerceMode: 'delivery'`.\n *\n * O que NÃO mora aqui, de propósito: horário de funcionamento, endereço de\n * retirada e prazo de preparo. Esses vêm do banco, porque uma lojista precisa\n * mudar o horário num feriado sem esperar um deploy — e um horário em arquivo\n * de configuração é exatamente isso.\n */\n delivery?: StorefrontDeliveryConfig\n /**\n * The A/B tests this store runs, by PostHog flag key. Each one is a\n * multivariate flag (and a PostHog Experiment over it); the edge assigns the\n * variant before render, and any setting typed `Experimental<…>`, any\n * `experiment` block or any `useExperiment(key)` call reads it. A key not\n * declared here is always 'control'. See docs/storefront/EXPERIMENTS.md.\n */\n experiments?: Record<string, StorefrontExperiment>\n /**\n * Payment behavior. v1 default 'mock' instantly marks orders paid with NO\n * real charge (demo). M4 sets 'pix-mercadopago' so orders stay pending until\n * a real payment webhook confirms settlement.\n */\n payments?: {\n /**\n * 'gateway' means a real PSP is connected: the checkout opens a charge and\n * the order waits for it. WHICH provider is deliberately not spelled here —\n * that lives in the store's connection row, server side. A storefront that\n * named the acquirer would need a redeploy to change acquirer.\n */\n mode?: 'mock' | 'pix-mercadopago' | 'gateway'\n /**\n * Which methods the checkout offers. Declaring them is what lets the order\n * record how the buyer intends to pay instead of assuming 'credit_card',\n * which is what it did while the card form was a simulation.\n */\n methods?: readonly PaymentMethodKind[]\n /**\n * Published payment terms, shown on the card and the PDP. These are the two\n * lines every Brazilian storefront carries and the SDK had no model for:\n * the Pix discount and the interest-free instalment.\n *\n * Display only — they describe what the merchant advertises, not a charge\n * the checkout computes. A product may override the Pix price per SKU via\n * `metadata.pixPrice`.\n */\n terms?: {\n /** e.g. 5 → \"5% de desconto no Pix\". */\n pixDiscountPercent?: number\n /** Longest interest-free plan offered. */\n maxInstallments?: number\n /** Don't split below this per-instalment value. Default 10. */\n minInstallmentValue?: number\n }\n }\n /**\n * The PDP specification table renders scalar `product.metadata` alongside\n * SKU/category/weight. Stores also keep bookkeeping in metadata; `exclude`\n * hides those keys and `labels` names the rest, so a store doesn't have to\n * fork ProductSpecs to stop showing an internal field.\n */\n productSpecs?: { exclude?: readonly string[]; labels?: Readonly<Record<string, string>> }\n /** Product reviews shown on the PDP. See ./components/product/ProductReviews. */\n reviews?: StorefrontReviewsConfig\n /**\n * Extra catalog refinements over `product.metadata`, rendered in the filters\n * panel and reflected in `?<key>=<value>`. This is how a store adds its own\n * discovery axis — colour, purpose, brand — without forking FiltersPanel.\n */\n catalogFacets?: readonly CatalogFacetConfig[]\n /** Product enquiry behavior for catalog/enquiry stores. */\n enquiry?: StorefrontEnquiryConfig\n /** Feature toggles — defaults depend on commerceMode. */\n features?: { discounts?: boolean; accounts?: boolean; cart?: boolean; checkout?: boolean }\n /** Global storefront image reveal behavior. Default is a soft fade. */\n imageLoading?: StorefrontImageLoadingConfig\n /** Header search behaviour. Omit for the inline live-filter. */\n search?: StorefrontSearchConfig\n /**\n * The merchant's own commercial policy, read from the store's settings row at\n * boot (see ./store-policy). NOT authored here: an app declares its defaults\n * through the fields above, and this arrives from the database to override the\n * ones the merchant actually decided.\n *\n * Present so components can read the decisions that have no equivalent\n * config field — whether an account is required, which optional checkout\n * fields to show. The ones that DO have a field (currency, payment methods)\n * are folded into those fields instead, so nothing has to read both.\n */\n policy?: StoreSettings\n /** Code-level component replacements. Kept out of serialized manifests. */\n components?: StorefrontComponents\n /** Code-level route overrides/custom routes. Kept out of serialized manifests. */\n routes?: readonly StorefrontRouteDefinition[]\n}\n\n/** See `StorefrontDeliveryConfig.coverSize`. */\nexport type StorefrontCoverSize = 'full' | 'compact'\n\n/** Entrega ou retirada, do ponto de vista da vitrine. */\nexport type FulfillmentMode = 'delivery' | 'pickup'\n\nexport interface StorefrontDeliveryConfig {\n /** Onde o cardápio mora. Default '/menu'. */\n menuPath?: string\n /**\n * A capa da loja — a foto que ocupa o topo do cardápio.\n *\n * É a única imagem do modo que NÃO vem do catálogo: capa é identidade da\n * loja, não de um produto. Sem ela o cabeçalho continua existindo, só que\n * sobre a cor da marca — o cardápio nunca depende de haver foto.\n */\n coverImage?: string\n /** O logo, no quadrado sobre a capa. Cai para a inicial do nome. */\n logoImage?: string\n /**\n * How much of the first screen the cover takes. 'full' (default) is the\n * cover as a store styles it; 'compact' shrinks it to a band so the first\n * dishes — photo, price, add button — are visible without scrolling on a\n * phone. The cover carries `data-cover-size`, so a store's own cover CSS can\n * follow it. Bindable to an experiment:\n * `{ experiment: 'menu-cover-compact', variants: { control: 'full', compact: 'compact' } }`.\n */\n coverSize?: Experimental<StorefrontCoverSize>\n /** \"Rio de Janeiro, RJ\" — a linha sob o nome. */\n locality?: string\n /**\n * Os slugs que sobem para \"Destaques\", NA ORDEM em que a lojista os quer.\n *\n * Curadoria é decisão de quem vende, e não há dado na vitrine que a\n * substitua: \"mais pedido\" precisaria de contagem de pedidos por produto,\n * que não existe aqui. Sem esta lista o cardápio cai para o que está em\n * promoção — um fato cadastrado, não um palpite — e, sem promoções, a seção\n * simplesmente não aparece.\n */\n highlightSlugs?: readonly string[]\n /** Modos oferecidos, NA ORDEM em que o seletor os mostra. Default ['delivery']. */\n fulfillmentModes?: readonly FulfillmentMode[]\n /** Oferecer \"Agendar\". Default false — e a loja ainda precisa concordar. */\n scheduling?: boolean\n /**\n * O balcão, para os pedidos de retirada.\n *\n * ESTÁ AQUI POR UMA LIMITAÇÃO CONHECIDA, e não porque este seja o lugar certo.\n * O lugar certo é `plg_shop_settings.pickup_address` (0094), para a lojista\n * mudar o endereço sem deploy — mas a vitrine lê configuração por\n * `shop_store_settings()`, uma RPC que devolve um SUBCONJUNTO fixo de colunas\n * e não inclui esta. Estender a RPC é uma migration, e a 0094 já está fechada.\n *\n * Então: a vitrine PREFERE o que vier do banco e cai para cá quando não vier.\n * No dia em que a RPC ganhar a coluna, esta chave para de ser lida sozinha,\n * sem tocar em app nenhum.\n */\n pickupAddress?: {\n postalCode: string\n street: string\n number?: string\n complement?: string\n district?: string\n city: string\n state: string\n }\n}\n\nexport interface ResolvedStorefrontConfig extends StorefrontConfig {\n currency: string\n locale: string\n language: StorefrontLanguage\n countries: readonly string[]\n defaultCountry: string\n /** The host's per-request country hint (e.g. the CDN's geo header), if any. */\n countryHint?: string\n /** The market the buyer is in (0116), when the store has markets. Its\n * currency, locale and shipping are already applied to this config. */\n market?: ShopMarket\n shipping: { flatRate: number; freeAbove?: number }\n payments: {\n mode: NonNullable<NonNullable<StorefrontConfig['payments']>['mode']>\n methods: readonly PaymentMethodKind[]\n terms?: NonNullable<StorefrontConfig['payments']>['terms']\n }\n commerceMode: StorefrontCommerceMode\n /** Presente somente no modo delivery — a rota /menu testa por este objeto. */\n delivery?: {\n menuPath: string\n coverImage?: string\n logoImage?: string\n coverSize?: StorefrontDeliveryConfig['coverSize']\n locality?: string\n highlightSlugs?: readonly string[]\n fulfillmentModes: readonly FulfillmentMode[]\n scheduling: boolean\n pickupAddress?: StorefrontDeliveryConfig['pickupAddress']\n /** From the store's Delivery settings (shop 0130), when it set them. */\n etaMinutes?: number\n /** The minimum order on the items' subtotal; the server refuses below it. */\n minOrderTotal?: number\n /** The house switched its delivery off (shop 0131): no order until it is back. */\n paused?: boolean\n }\n enquiry: Required<Pick<StorefrontEnquiryConfig, 'label' | 'successMessage' | 'subjectPrefix'>> &\n Omit<StorefrontEnquiryConfig, 'label' | 'successMessage' | 'subjectPrefix'>\n features: { discounts: boolean; accounts: boolean; cart: boolean; checkout: boolean }\n imageLoading: Required<StorefrontImageLoadingConfig>\n /** Where the full product list lives ('/' without a home page, '/catalog' with one, the menu in delivery mode) */\n catalogPath: string\n nav: NavLink[]\n /** `pages` with the legacy `home` short form folded in — always read this one. */\n pages: StorefrontPagesConfig\n search: Required<Omit<StorefrontSearchConfig, 'renderSuggestion'>> &\n Pick<StorefrontSearchConfig, 'renderSuggestion'>\n}\n\n/**\n * Header search. Defaults reproduce the inline live-filter the storefront has\n * always had, so turning this on is opt-in; every label and limit is a knob\n * because \"what a search feels like\" is a per-store decision, not the SDK's.\n */\nexport interface StorefrontSearchConfig {\n /**\n * 'inline' filters the catalogue as you type (the original behaviour).\n * 'overlay' dims the page and shows suggestions under the field, with a\n * link through to the full result page.\n */\n mode?: 'inline' | 'overlay'\n placeholder?: string\n /** Where \"see all results\" lands, carrying `?q=`. */\n resultsPath?: string\n /** Suggestions shown under the field before the shopper commits. */\n suggestionsLimit?: number\n /** Characters before anything is queried — 1 matches everything, which is noise. */\n minChars?: number\n ctaLabel?: string\n emptyLabel?: string\n /** Full control of a suggestion row when the default card is wrong for the store. */\n renderSuggestion?: (product: Product) => ReactNode\n}\n\n/** Upper-cased, de-duplicated, never empty; the default is always one of them. */\nfunction resolveCountries(config: StorefrontConfig): { countries: string[]; defaultCountry: string } {\n const countries = [...new Set((config.countries ?? []).map((c) => c.trim().toUpperCase()).filter(Boolean))]\n if (countries.length === 0) countries.push('BR')\n const wanted = config.defaultCountry?.trim().toUpperCase()\n return { countries, defaultCountry: wanted && countries.includes(wanted) ? wanted : countries[0]! }\n}\n\nexport function resolveConfig(config: StorefrontConfig): ResolvedStorefrontConfig {\n // `home` and `pages.home` are the same page written two ways. Collapse them\n // here so nothing downstream has to check both, and so the legacy short form\n // keeps deciding where the catalog lives exactly as it did before.\n const homePage = config.pages?.home ?? (config.home ? { blocks: config.home.sections } : undefined)\n const commerceMode = config.commerceMode ?? 'checkout'\n // In a delivery store the menu IS the catalogue: «Continuar comprando» and\n // «Voltar ao catálogo» on a product page sent buyers to the old e-commerce\n // shelf at /catalog instead of the menu they order from.\n const catalogPath = commerceMode === 'delivery'\n ? (config.delivery?.menuPath ?? '/menu')\n : homePage ? '/catalog' : '/'\n // 'delivery' compra tudo que 'checkout' liga. Escrever `=== 'checkout'` em\n // cada feature abaixo teria desligado carrinho e conta no modo novo — o modo\n // que mais precisa dos dois.\n const checkoutEnabled = commerceMode === 'checkout' || commerceMode === 'delivery'\n return {\n ...config,\n pages: { ...config.pages, ...(homePage ? { home: homePage } : {}) },\n currency: config.currency ?? 'BRL',\n locale: config.locale ?? 'pt-BR',\n language: normalizeLanguage(config.language) ?? 'pt-BR',\n ...resolveCountries(config),\n shipping: { flatRate: config.shipping?.flatRate ?? 0, freeAbove: config.shipping?.freeAbove },\n payments: {\n mode: config.payments?.mode ?? 'mock',\n methods: config.payments?.methods?.length ? config.payments.methods : ['pix', 'credit_card', 'cash'],\n // Rebuilding `payments` key by key silently dropped `terms`, so the Pix\n // price and the instalment line never reached a component even when the\n // store had configured them.\n terms: config.payments?.terms,\n },\n commerceMode,\n // Só existe no modo delivery. Fora dele o objeto inteiro é undefined, e é\n // isso que a rota /menu consulta para decidir se existe.\n delivery: commerceMode === 'delivery'\n ? {\n menuPath: config.delivery?.menuPath ?? '/menu',\n coverImage: config.delivery?.coverImage,\n logoImage: config.delivery?.logoImage,\n coverSize: config.delivery?.coverSize,\n locality: config.delivery?.locality,\n highlightSlugs: config.delivery?.highlightSlugs,\n // A ORDEM é a do seletor na tela. Um Set aqui perderia isso.\n fulfillmentModes: config.delivery?.fulfillmentModes?.length\n ? config.delivery.fulfillmentModes\n : (['delivery'] as const satisfies readonly FulfillmentMode[]).slice(),\n // Agendamento é opt-in duas vezes: aqui e na loja (0094 devolve zero\n // slots quando scheduling_enabled é falso). A tela só oferece quando\n // as duas concordam.\n scheduling: config.delivery?.scheduling ?? false,\n pickupAddress: config.delivery?.pickupAddress,\n }\n : undefined,\n enquiry: {\n label: config.enquiry?.label ?? 'Contact me',\n successMessage: config.enquiry?.successMessage ?? 'Thanks. We received your enquiry.',\n subjectPrefix: config.enquiry?.subjectPrefix ?? 'Product enquiry',\n email: config.enquiry?.email,\n whatsappUrl: config.enquiry?.whatsappUrl,\n requirePhone: config.enquiry?.requirePhone,\n },\n features: {\n // Auto-enable the coupon UI when the store actually ships discount codes\n // (config.discounts, a seeded catalog, or a rule-engine promotion with a\n // code — M6), unless explicitly overridden — otherwise a store can\n // advertise a coupon with no field to enter it, which is exactly the\n // figurinhas pilot failure this milestone exists to end.\n discounts:\n config.features?.discounts ??\n Boolean(\n config.discounts?.length ||\n config.catalog?.discounts?.length ||\n config.promotions?.some((p) => p.code) ||\n config.catalog?.promotions?.some((p) => p.code),\n ),\n accounts: config.features?.accounts ?? checkoutEnabled,\n cart: config.features?.cart ?? checkoutEnabled,\n checkout: config.features?.checkout ?? checkoutEnabled,\n },\n imageLoading: {\n mode: config.imageLoading?.mode ?? 'fade',\n durationMs: config.imageLoading?.durationMs ?? 420,\n easing: config.imageLoading?.easing ?? 'cubic-bezier(0.22, 1, 0.36, 1)',\n blur: config.imageLoading?.blur ?? true,\n transform: config.imageLoading?.transform ?? 'none',\n },\n catalogPath,\n search: {\n mode: config.search?.mode ?? 'inline',\n placeholder: config.search?.placeholder ?? 'Buscar produtos...',\n resultsPath: config.search?.resultsPath ?? '/search',\n suggestionsLimit: config.search?.suggestionsLimit ?? 4,\n minChars: config.search?.minChars ?? 2,\n ctaLabel: config.search?.ctaLabel ?? 'Ver todos resultados',\n emptyLabel: config.search?.emptyLabel ?? 'Nada encontrado para',\n renderSuggestion: config.search?.renderSuggestion,\n },\n nav:\n config.nav ??\n (homePage\n ? [\n { label: 'Início', to: '/' },\n { label: 'Loja', to: '/catalog' },\n ]\n : [{ label: 'Loja', to: '/' }]),\n }\n}\n\nconst StorefrontConfigContext = createContext<ResolvedStorefrontConfig | null>(null)\n\nexport const StorefrontConfigProvider = StorefrontConfigContext.Provider\n\nexport function useStorefrontConfig(): ResolvedStorefrontConfig {\n const ctx = useContext(StorefrontConfigContext)\n if (!ctx) throw new Error('useStorefrontConfig must be used inside createStorefrontApp')\n return ctx\n}\n\nexport function useStorefrontConfigOptional(): ResolvedStorefrontConfig | null {\n return useContext(StorefrontConfigContext)\n}\n\nexport function getStorefrontComponents(config: ResolvedStorefrontConfig): StorefrontComponents {\n return config.components ?? {}\n}\n","import React, { createContext, useContext, useEffect, useRef, useSyncExternalStore } from 'react'\nimport { defaultRouterAdapter, staticRouterAdapter, type RouterAdapter } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Storefront routing.\n//\n// The storefront owns a handful of flat routes, so it resolves them itself\n// rather than depending on a router package — that dependency is what created\n// the duplicate-singleton hazards under source-alias dev. What it does NOT own\n// is the *addressing scheme*: whether a page lives at `#/product/x` or at\n// `/product/x`, and who controls history.\n//\n// That is injected as a RouterAdapter, which is what lets the same components\n// render under a hash SPA, a real-URL SPA, and a static render. It matters\n// beyond convenience: a fragment is never sent to the server, so a\n// hash-addressed page has no URL of its own to index, share or prerender —\n// `renderStore` can produce perfect HTML for a page that no crawler can reach\n// as a distinct address.\n//\n// Hash remains the default, so an app that never mentions routing behaves\n// exactly as it does today.\n// ---------------------------------------------------------------------------\n\nconst RouterAdapterContext = createContext<RouterAdapter | null>(null)\n\nexport const StorefrontRouterProvider = RouterAdapterContext.Provider\n\n/**\n * `navigateTo` is a module function called from event handlers. Handlers only\n * run in a browser, after the provider has mounted, so a module-level reference\n * to the active adapter is safe here in a way it would not be during render.\n * Render paths use `useNavigate()` / `useRouterAdapter()` so a static render\n * reads the adapter for the path it is rendering, not this process-wide one.\n */\nlet _activeAdapter: RouterAdapter | null = null\nlet _fallback: RouterAdapter | null = null\n\n/**\n * One shared fallback instance, not one per component: an adapter owns its\n * subscriber list, so N instances would mean N event bindings and — for history\n * addressing — navigations that only notify their own subscribers. Constructing\n * one touches no browser API; only its methods do.\n */\nfunction fallbackAdapter(): RouterAdapter {\n if (!_fallback) _fallback = defaultRouterAdapter('hash')\n return _fallback\n}\n\nexport function useRouterAdapter(): RouterAdapter {\n const injected = useContext(RouterAdapterContext)\n const adapter = injected ?? fallbackAdapter()\n useEffect(() => {\n // Only an INJECTED adapter becomes the active one. The fallback is what a\n // read outside any provider gets — and `StorefrontShell` itself makes such\n // a read, for the ambient adapter, before installing the router it was\n // given. Being the parent, its effect runs after every child's; if it\n // wrote the fallback here, a store served by a host router (TanStack,\n // history) would have every Link go through the host and every\n // `navigateTo` from an event handler go through hash addressing. That is\n // exactly what a header search did on the first SSR store: /#/catalog.\n if (injected) _activeAdapter = injected\n }, [injected])\n return adapter\n}\n\n/** The current in-app path, re-rendering on every navigation. */\nexport function useRoutePath(): string {\n const adapter = useRouterAdapter()\n return useSyncExternalStore(\n (onChange) => adapter.onPathChange(onChange),\n () => adapter.getCurrentPath() || '/',\n () => adapter.getCurrentPath() || '/',\n )\n}\n\n/** Scroll to top on route change. Separate from path tracking so a host that\n * manages its own scroll restoration can simply not call it. */\nexport function useScrollToTopOnNavigate(path: string): void {\n const mounted = useRef(false)\n useEffect(() => {\n // Not on the first pass. That one is not a navigation — it is the store\n // arriving, either as the server's HTML being hydrated or as a reload the\n // browser has already positioned. Scrolling there takes the page away from\n // a shopper who started reading during hydration, and on a host with its\n // own scroll restoration it races that host's restore.\n if (!mounted.current) {\n mounted.current = true\n return\n }\n if (typeof window !== 'undefined') window.scrollTo(0, 0)\n }, [path])\n}\n\nexport function useNavigate(): (to: string) => void {\n const adapter = useRouterAdapter()\n return adapter.navigate.bind(adapter)\n}\n\n/** @deprecated Use `useRoutePath()`. Kept so existing imports keep compiling. */\nexport const useHashPath = useRoutePath\n\n/** Imperative navigation from an event handler. See `_activeAdapter` above. */\nexport function navigateTo(to: string): void {\n ;(_activeAdapter ?? fallbackAdapter()).navigate(to)\n}\n\n/**\n * The adapter a shell should install for a given render.\n *\n * A `path` override means a static render (`renderStore`, the preview server, a\n * node test): there is no history to own, but anchors must still carry real,\n * crawlable hrefs — which is the whole point of rendering headlessly.\n */\nexport function shellRouterAdapter(pathOverride: string | undefined, live: RouterAdapter): RouterAdapter {\n if (pathOverride == null) return live\n // Inherit the ambient scheme's href writer: a store served as a hash SPA must\n // still emit `#/…` links when rendered headlessly, or `renderStore` would\n // describe a page whose links do not exist. Pass an explicit `router` to the\n // shell to render a store served at real URLs.\n return staticRouterAdapter(pathOverride, { href: (to) => live.href(to) })\n}\n\n/** Match '/product/:slug' against '/product/leather-backpack' → { slug: 'leather-backpack' } */\nexport function matchPath(pattern: string, path: string): Record<string, string> | null {\n const cleanPath = (path.split('?')[0] ?? '').replace(/\\/+$/, '') || '/'\n const patternParts = pattern.split('/').filter(Boolean)\n const pathParts = cleanPath.split('/').filter(Boolean)\n if (patternParts.length !== pathParts.length) return null\n const params: Record<string, string> = {}\n for (let i = 0; i < patternParts.length; i++) {\n const pat = patternParts[i]!\n const part = pathParts[i]!\n if (pat.startsWith(':')) params[pat.slice(1)] = decodeURIComponent(part)\n else if (pat !== part) return null\n }\n return params\n}\n\nexport interface LinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\n to: string\n}\n\n/**\n * A real anchor, always — middle-click, cmd-click, \"copy link address\" and\n * Playwright all keep working, and a crawler sees a real href.\n *\n * Under hash addressing the browser handles the fragment itself, so the click\n * is left alone. Under real-URL addressing a plain left-click must be\n * intercepted or the browser would do a full document load; modified clicks and\n * explicit targets are still handed to the browser.\n */\nexport function Link({ to, children, onClick, target, ...rest }: LinkProps) {\n const adapter = useRouterAdapter()\n\n const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {\n onClick?.(event)\n if (!adapter.interceptsLinkClicks) return\n if (event.defaultPrevented) return\n if (target && target !== '_self') return\n if (event.button !== 0) return\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return\n event.preventDefault()\n adapter.navigate(to)\n }\n\n return React.createElement(\n 'a',\n { href: adapter.href(to), onClick: handleClick, target, ...rest },\n children,\n )\n}\n","import type { BlockNode } from '@fayz-ai/core'\nimport type { PageDataEntry, PageDataNeed } from '../blocks/page-data'\n\n// Effects do not run under `renderToStaticMarkup`, so a headless render would\n// produce loading states with no title. Instead of reimplementing routing on the\n// server — a second mechanism to keep in sync — components REPORT to the pass\n// rendering them, and the renderer re-renders with the answers seeded.\n//\n// Module-scoped rather than a React context because `renderToStaticMarkup` is\n// synchronous: there is exactly one pass in flight, and a context would force\n// every reporting call site to be a hook (`PageDataScope`'s useState initialiser\n// cannot be one). Null in every browser render.\n\n/**\n * What a route declared for the document head during a static render.\n *\n * Title and description are the client-rendered baseline. The rest is what a\n * page needs to be worth anything once it HAS its own URL: a canonical so the\n * engine knows which address is authoritative, an image and type so a share in\n * a messaging app is not a grey rectangle, and JSON-LD so a product is eligible\n * for a rich result instead of a plain blue link.\n */\nexport interface StaticHeadInput {\n title?: string\n description?: string | null\n /** Absolute URL. A relative canonical is ignored by search engines. */\n canonical?: string\n /** Absolute URL of the image a share should show. */\n image?: string\n /** OpenGraph type — 'website', 'article', 'product'. */\n type?: string\n /** schema.org objects, emitted as <script type=\"application/ld+json\">. */\n jsonLd?: Array<Record<string, unknown>>\n}\n\nexport interface StaticRenderPass {\n /** Called once per scope, so a page plus its slots report the whole rendered\n * composition — including forced-layout repairs (I7). */\n tree(nodes: readonly BlockNode[]): void\n needs(needs: readonly PageDataNeed[]): void\n head(input: StaticHeadInput): void\n /** Resolved by an earlier pass, keyed by `dataNeedKey`. A key present here is\n * served instead of being fetched. */\n entries: Readonly<Record<string, PageDataEntry>>\n /**\n * Absolute origin the rendered page will be served from, when the caller\n * knows it. Pages need it to declare a canonical or an og:image, and a static\n * render has no `window.location` to infer one from — so it travels with the\n * pass rather than being guessed per page.\n */\n origin?: string\n}\n\nlet active: StaticRenderPass | null = null\n\n/** The pass currently rendering, or null — which is every browser render. */\nexport function currentStaticRenderPass(): StaticRenderPass | null {\n return active\n}\n\n/** Run one synchronous render with `pass` installed. Nesting restores the\n * previous pass, so a renderer inside a renderer cannot strand the global. */\nexport function withStaticRenderPass<T>(pass: StaticRenderPass, render: () => T): T {\n const previous = active\n active = pass\n try {\n return render()\n } finally {\n active = previous\n }\n}\n","import { errorMessage } from '@fayz-ai/core'\nimport React, { createContext, useContext, useEffect, useMemo, useState } from 'react'\nimport {\n dataNeedKey,\n defaultPropsFromSettings,\n getBlockErrorVisibility,\n getBlockMeta,\n isLoaderParamRef,\n isLoaderPropRef,\n resolveLoader,\n} from '@fayz-ai/core'\nimport type { BlockDataNeed, BlockNode } from '@fayz-ai/core'\nimport { getShopProvider } from '@fayz-ai/shop/runtime'\nimport { currentStaticRenderPass } from '../app/static-render'\n\n// ---------------------------------------------------------------------------\n// Page data — declared needs, resolved once per page (spine M3, I11).\n//\n// A block never fetches for itself. Its meta (or its document instance)\n// declares named needs against registered loaders; the page walks its repaired\n// tree, collects them, DEDUPES identical (loader, params) pairs, resolves them\n// concurrently through the ShopProvider port, and hands the results down by\n// context. Two product rails asking the same question cost one provider call —\n// and, because the needs are known before render, a server can resolve the\n// same set ahead of time, which is the SSR prerequisite L4 calls out.\n//\n// Failure semantics follow the M2 error-boundary contract (I7): one failing\n// loader marks ONE entry as errored and never touches the rest of the page.\n// A block whose data errored renders null for shoppers and an error card in\n// dev/admin (BlockDataError), exactly like a block that crashed.\n// ---------------------------------------------------------------------------\n\nexport type PageDataStatus = 'idle' | 'loading' | 'ready' | 'error'\n\nexport interface PageDataEntry {\n status: 'loading' | 'ready' | 'error'\n data?: unknown\n error?: string\n}\n\n/** One collected, binding-resolved, deduped need. */\nexport interface PageDataNeed {\n key: string\n loader: string\n params: Record<string, unknown>\n}\n\n// --- Binding resolution -------------------------------------------------------\n\n/**\n * Resolve a declared need's param bindings against the page's route params and\n * the declaring block's props (setting defaults filled in, so the declaration\n * and the rendered block agree on unset props). A binding that resolves to\n * `undefined` drops its param — dataNeedKey drops undefined anyway, so the\n * declared need and a hook asking with explicit `undefined`s share a key.\n */\nexport function resolveDataParams(\n need: BlockDataNeed,\n context: { params: Record<string, string>; props: Record<string, unknown> },\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [name, value] of Object.entries(need.params ?? {})) {\n let resolved: unknown = value\n if (isLoaderParamRef(value)) resolved = context.params[value.$param]\n else if (isLoaderPropRef(value)) resolved = context.props[value.$prop]\n if (resolved !== undefined) out[name] = resolved\n }\n return out\n}\n\n/** A block's effective needs: the meta declaration with the document\n * instance's `data` merged over it by need name. */\nfunction needsForNode(node: BlockNode): Record<string, BlockDataNeed> {\n const meta = getBlockMeta(node.type)\n return { ...meta?.data, ...node.data }\n}\n\n/**\n * Walk a block tree (children included) and collect every declared need,\n * bindings resolved, deduped by canonical (loader, params) key.\n */\nexport function collectDataNeeds(\n nodes: readonly BlockNode[],\n routeParams: Record<string, string> = {},\n): PageDataNeed[] {\n const found = new Map<string, PageDataNeed>()\n const visit = (node: BlockNode): void => {\n const meta = getBlockMeta(node.type)\n const needs = needsForNode(node)\n if (Object.keys(needs).length > 0) {\n const props = { ...defaultPropsFromSettings(meta?.settings), ...node.props }\n for (const need of Object.values(needs)) {\n if (!need || typeof need.loader !== 'string' || !need.loader) continue\n const params = resolveDataParams(need, { params: routeParams, props })\n const key = dataNeedKey(need.loader, params)\n if (!found.has(key)) found.set(key, { key, loader: need.loader, params })\n }\n }\n for (const child of node.children ?? []) visit(child)\n }\n for (const node of nodes) visit(node)\n return [...found.values()]\n}\n\n// --- Resolution ---------------------------------------------------------------\n\n/** Resolve ONE need through the provider port. Never throws: an unknown\n * loader or a failing read becomes an 'error' entry for that need alone. */\nexport async function resolvePageDataNeed(need: Pick<PageDataNeed, 'loader' | 'params'>): Promise<PageDataEntry> {\n try {\n const impl = resolveLoader(need.loader)\n const data = await impl(need.params, { shop: getShopProvider() })\n return { status: 'ready', data }\n } catch (err) {\n const message = errorMessage(err)\n // Always log — a store hitting this in production is better off with the\n // reason in the console than without it (same policy as BlockErrorBoundary).\n console.error(`[storefront] loader \"${need.loader}\" failed:`, err)\n return { status: 'error', error: message }\n }\n}\n\n/** Resolve a set of needs concurrently, isolated per need. Test seam and the\n * future server-side entry point — the scope component uses the same calls. */\nexport async function resolvePageData(\n needs: readonly PageDataNeed[],\n): Promise<Record<string, PageDataEntry>> {\n const settled = await Promise.all(\n needs.map(async (need) => [need.key, await resolvePageDataNeed(need)] as const),\n )\n return Object.fromEntries(settled)\n}\n\n// --- The scope ----------------------------------------------------------------\n\ninterface PageDataContextValue {\n entries: Record<string, PageDataEntry>\n /** The route params this scope resolved `$param` bindings against — the same\n * ones a consuming block must use, or its key would diverge. */\n params: Record<string, string>\n}\n\nconst PageDataContext = createContext<PageDataContextValue | null>(null)\n\nexport interface PageDataScopeProps {\n nodes: readonly BlockNode[]\n /** Route params the tree's `$param` bindings resolve against. */\n params?: Record<string, string>\n /**\n * Pre-resolved entries, keyed by dataNeedKey — the server-side/static-render\n * seam (L4): `resolvePageData(collectDataNeeds(nodes))` ahead of render,\n * then hand the results in. Keys already 'ready' here are never re-fetched;\n * anything missing resolves client-side as usual.\n *\n * Live, not mount-only: a host whose shell outlives the page (every real\n * one — the shell must not remount on navigation) hands in a NEW object\n * for each page it loads, and a child scope mounting in that same commit\n * sees it. Pass a stable reference per page (the loader's result), not a\n * literal built in render.\n */\n initial?: Record<string, PageDataEntry>\n children: React.ReactNode\n}\n\n/**\n * Collects and resolves the data needs of one block tree, and provides the\n * results. Scopes nest (a slot inside a page): a child scope reuses every\n * entry an ancestor already resolved and only fetches its own remainder, so\n * dedupe holds across the whole rendered page, not per tree.\n */\nexport function PageDataScope({ nodes, params, initial, children }: PageDataScopeProps) {\n const parent = useContext(PageDataContext)\n const routeParams = useMemo(() => params ?? parent?.params ?? {}, [params, parent])\n const needs = useMemo(() => collectDataNeeds(nodes, routeParams), [nodes, routeParams])\n const own = useMemo(\n () => needs.filter((need) => !parent || !(need.key in parent.entries)),\n [needs, parent],\n )\n // A static render (renderStore) has no effects, so this scope reports what it\n // renders and what it would fetch, and reads back anything an earlier pass\n // already resolved. Null in the browser.\n const staticPass = currentStaticRenderPass()\n if (staticPass) {\n staticPass.tree(nodes)\n staticPass.needs(own)\n }\n\n // Seeded synchronously so the first render already shows 'loading' (or the\n // pre-resolved entry) for every owned key — a consuming block must never see\n // a gap and start its own fetch.\n const [entries, setEntries] = useState<Record<string, PageDataEntry>>(() => ({\n // Everything handed in is published, not only the needs THIS scope\n // collected. That is what lets a host framework resolve a page's data in\n // its own loader and wrap the shell in a seeding scope: the page's own\n // scope then finds those keys already answered on its parent and fetches\n // nothing. Without it, seeding only works when the seeding scope happens to\n // render the same block tree.\n ...initial,\n ...Object.fromEntries(\n own.map((need) => [\n need.key,\n initial?.[need.key] ?? staticPass?.entries[need.key] ?? ({ status: 'loading' } as PageDataEntry),\n ]),\n ),\n }))\n\n const signature = own.map((need) => need.key).join('\\n')\n useEffect(() => {\n // A key handed in ready stays authoritative; everything else resolves here.\n const pending = own.filter((need) => initial?.[need.key]?.status !== 'ready')\n if (pending.length === 0) return\n let cancelled = false\n setEntries((prev) => {\n const next = { ...prev }\n for (const need of pending) {\n if (next[need.key]?.status !== 'ready') next[need.key] = { status: 'loading' }\n }\n return next\n })\n for (const need of pending) {\n void resolvePageDataNeed(need).then((entry) => {\n if (!cancelled) setEntries((prev) => ({ ...prev, [need.key]: entry }))\n })\n }\n return () => {\n cancelled = true\n }\n // `own` is captured by its key signature: same keys = same needs.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [signature])\n\n // `initial` is overlaid at RENDER time, on top of what this scope resolved,\n // rather than folded into state once at mount. The difference is one\n // commit, and it is the whole point: after a client-side navigation the\n // host hands in the next page's entries and the next page's own scope\n // mounts in the same commit — it decides which needs are unanswered by\n // reading this value as it mounts. State would only carry the new entries\n // from the following commit, by which time the child has already started\n // fetching everything the host had just resolved, and the shopper watches\n // content that was ready pop in a second time.\n const value = useMemo<PageDataContextValue>(\n () => ({ entries: { ...parent?.entries, ...entries, ...initial }, params: routeParams }),\n [parent, entries, initial, routeParams],\n )\n return <PageDataContext.Provider value={value}>{children}</PageDataContext.Provider>\n}\n\n// --- Consumption --------------------------------------------------------------\n\nexport interface UseLoaderResult<T> {\n status: PageDataStatus\n data: T | null\n error: string | null\n /** Re-run the read (bypasses the page-resolved entry from then on). */\n reload: () => void\n}\n\n/**\n * A block's (or page's) read: `useLoader('products.list', { filter, limit })`.\n *\n * When a PageDataScope above already resolved the same (loader, params) pair —\n * because this block, or ANY block on the page, declared it — the resolved\n * entry is returned and no request is made. Otherwise the hook resolves the\n * loader itself, through the same provider port, so a component used outside a\n * composed page (a store's hand-written route) keeps working identically.\n * Pass `null` params to disable the read.\n */\nexport function useLoader<T>(\n loader: string,\n params: Record<string, unknown> | null,\n): UseLoaderResult<T> {\n const scope = useContext(PageDataContext)\n const key = params === null ? null : dataNeedKey(loader, params)\n const [nonce, setNonce] = useState(0)\n const scoped = nonce === 0 && key !== null && scope ? scope.entries[key] : undefined\n const [local, setLocal] = useState<{ key: string; entry: PageDataEntry } | null>(null)\n\n // Undeclared reads — a hand-written route calling the hook directly — still\n // resolve under a static render: the pass collects the key on the first pass\n // and serves it on the next. Without this, exactly the reads that no block\n // declared would be the ones missing from a headless render.\n const staticPass = currentStaticRenderPass()\n const staticEntry = staticPass && key !== null && scoped === undefined ? staticPass.entries[key] : undefined\n if (staticPass && key !== null && scoped === undefined && staticEntry === undefined) {\n staticPass.needs([{ key, loader, params: params! }])\n }\n\n const paramsKey = params === null ? null : JSON.stringify(params)\n useEffect(() => {\n if (key === null || scoped !== undefined) return\n let cancelled = false\n setLocal({ key, entry: { status: 'loading' } })\n void resolvePageDataNeed({ loader, params: params! }).then((entry) => {\n if (!cancelled) setLocal({ key, entry })\n })\n return () => {\n cancelled = true\n }\n // params identity travels through paramsKey; scoped presence through a boolean.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [loader, paramsKey, nonce, scoped !== undefined])\n\n const entry =\n scoped ??\n staticEntry ??\n (local && local.key === key ? local.entry : key !== null ? { status: 'loading' as const } : null)\n\n return {\n status: entry?.status ?? 'idle',\n data: entry?.status === 'ready' ? (entry.data as T) : null,\n error: entry?.status === 'error' ? entry.error ?? 'unknown error' : null,\n reload: () => setNonce((n) => n + 1),\n }\n}\n\n/**\n * A BLOCK's named data need: `useBlockData(node, 'products', fallback)`.\n *\n * Reads the block's effective declaration — meta `data` with the document\n * instance's `data` merged over it — and resolves its bindings with the SAME\n * inputs the page resolver used (scope route params, node props over setting\n * defaults), so the two always compute the same key. That is what makes a\n * document able to rebind a param (`category: { $param: 'slug' }`) and have\n * the rendered block follow: the block asks for its declared need, not for a\n * hardcoded one.\n *\n * `fallback` covers the component being used directly as JSX (a store's\n * hand-written route), where there is no node and no declaration to read.\n */\nexport function useBlockData<T>(\n node: BlockNode | undefined,\n name: string,\n fallback: { loader: string; params: Record<string, unknown> },\n): UseLoaderResult<T> & { loader: string } {\n const scope = useContext(PageDataContext)\n let loader = fallback.loader\n let params = fallback.params\n if (node) {\n const need = needsForNode(node)[name]\n if (need && typeof need.loader === 'string' && need.loader) {\n const meta = getBlockMeta(node.type)\n loader = need.loader\n params = resolveDataParams(need, {\n params: scope?.params ?? {},\n props: { ...defaultPropsFromSettings(meta?.settings), ...node.props },\n })\n }\n }\n const result = useLoader<T>(loader, params)\n return { ...result, loader }\n}\n\n// --- Error surface ------------------------------------------------------------\n\n/**\n * What a block renders when its declared data failed: nothing for shoppers, a\n * visible card for builders — the same visibility rule as a crashed block\n * (M2's per-block error boundary, WooCommerce's `CURRENT_USER_IS_ADMIN ?\n * onError : () => null`).\n */\nexport function BlockDataError({ loader, message }: { loader: string; message?: string | null }) {\n if (getBlockErrorVisibility() === 'silent') return null\n return (\n <div\n data-block-error={`loader:${loader}`}\n style={{\n border: '1px dashed #dc2626',\n color: '#b91c1c',\n padding: '8px 12px',\n font: '12px ui-monospace, monospace',\n borderRadius: 6,\n }}\n >\n {`Data for this block failed (loader \"${loader}\")`}\n {message ? <div style={{ opacity: 0.8, marginTop: 4 }}>{message}</div> : null}\n </div>\n )\n}\n","import { checkBlockConstraints, checkBlockContext, getBlockMeta, isBlockEnabledOn } from '@fayz-ai/core'\nimport type { BlockDataNeeds, BlockNode } from '@fayz-ai/core'\nimport type { StorefrontSection } from './sections'\nimport type { StorefrontTheme } from '../lib/theme'\nimport { matchPath } from '../app/router'\n\n// ---------------------------------------------------------------------------\n// Pages as block trees.\n//\n// The home page has been a block tree since the registry landed. Every other\n// route was hand-written JSX, which is why a store that wanted a banner above\n// the catalog grid had only one move available: reimplement the catalog page.\n// One store did exactly that for three routes and stopped receiving SDK updates\n// for all three.\n//\n// What the benchmarks do, and what this adopts:\n//\n// Shopify templates/product.json lists sections, one of which is `main` —\n// the product form itself. A theme adds sections around `main`\n// without owning it.\n// VTEX IO store.product is a block array containing `product-details`.\n// Same idea, same reason.\n//\n// So the native page body becomes a block (`catalogBody`, `productBody`), and a\n// store composes around it. The body keeps being maintained by the SDK.\n//\n// One deliberate shape change: the general block form nests its props under\n// `props`, matching Shopify's `settings` and VTEX's `props`. The flat\n// StorefrontSection form stays supported — five of seven live stores write it —\n// but it is the outlier, and it is the reason the two stores with custom blocks\n// both had to write `sections: mySections as never`: a closed union cannot\n// describe a block the SDK has never heard of. Nesting fixes that without a cast.\n// ---------------------------------------------------------------------------\n\n/** Pages that are composed from blocks, and the `enabledOn` vocabulary.\n * `content` is the editorial kind: a titled page that is nothing but blocks —\n * no commerce body, no catalog assumptions. */\nexport type StorefrontPageKind = 'home' | 'catalog' | 'product' | 'collection' | 'content'\n\n/**\n * A block instance in a page tree — the general form.\n *\n * `id` matters more than it looks: two product rails on one page are\n * indistinguishable without it, so an external editor cannot target one of them\n * and an AI-generated diff cannot say which it changed. VTEX solved the same\n * problem with `rich-text#hero`; this is the same idea spelled as a field.\n */\nexport interface StorefrontBlockRef {\n /** Registered block id — an SDK section, a plugin block, or an app's own. */\n type: string\n id?: string\n props?: Record<string, unknown>\n children?: readonly StorefrontBlockRef[]\n /**\n * Instance-level data needs, merged over the block meta's `data` declaration\n * by need name — how a document points a block's loader at a route param\n * (`{ products: { loader: 'products.list', params: { category: { $param:\n * 'slug' } } } }`). Resolved once per page by the page-data scope.\n */\n data?: BlockDataNeeds\n}\n\n/**\n * What a page's block list accepts.\n *\n * The typed union keeps checking SDK sections (a bad `variant` is still a type\n * error); the open ref form is what lets an app place its own registered block\n * without casting.\n */\nexport type StorefrontBlockLike = StorefrontSection | StorefrontBlockRef\n\nexport interface StorefrontPageConfig {\n blocks: readonly StorefrontBlockLike[]\n}\n\n/**\n * An editorial page, expressible entirely in the document: a slug, a title, a\n * route, and blocks. This is the page kind that absorbs the \"brand site half\"\n * of a store — biography, philosophy, press, collections — which today lives\n * as hand-written custom routes (cristinarotondaro carries ~240 lines of them).\n *\n * The store chrome (header, footer, cart) still frames the page; what a\n * content page does NOT get is a commerce body block or any catalog\n * assumption. It is blocks all the way down.\n */\nexport interface StorefrontContentPageConfig extends StorefrontPageConfig {\n /** Document/page title (`<title>` gets \"<title> — <store>\"). Defaults to the slug. */\n title?: string\n /**\n * Route path. Defaults to `/<slug>`. May declare params (`/categoria/:slug`)\n * — one page then serves every match, and its blocks read the params through\n * `$param` loader bindings (M3). validateStore checks that every binding\n * names a param the path declares.\n */\n path?: string\n /**\n * Theme overlay applied ONLY inside this page, merged over the store theme.\n *\n * This is what makes a campaign page — a licensed line, a seasonal drop, a\n * collab — expressible as a content page instead of a microsite. Stores\n * routinely build those elsewhere and lose the funnel with them: the \"buy\"\n * CTA leaves for another domain and the cart, the session and the\n * attribution go with it.\n *\n * The overlay is emitted scoped to `[data-page=\"<slug>\"]`, so a hot-pink\n * summer drop cannot repaint the header, the cart drawer or any other route.\n * It merges key by key, so a page that sets only `colors.primary` keeps the\n * store's typography and every other token.\n */\n theme?: Partial<StorefrontTheme>\n}\n\n/**\n * Merge a page's theme overlay over the store theme.\n *\n * Nested groups merge rather than replace: a page declaring one colour must not\n * silently drop the store's fonts, radii and brand tokens back to SDK defaults.\n */\nexport function mergePageTheme(\n base: StorefrontTheme | undefined,\n overlay: Partial<StorefrontTheme> | undefined,\n): StorefrontTheme | undefined {\n if (!base && !overlay) return undefined\n if (!overlay) return base\n const name = overlay.name ?? (base ? `${base.name}-page` : 'page')\n const font = base?.font ? { ...base.font, ...overlay.font } : (overlay.font as StorefrontTheme['font'])\n return {\n ...base,\n ...overlay,\n name,\n colors: { ...base?.colors, ...overlay.colors },\n font,\n tokens: { ...base?.tokens, ...overlay.tokens },\n header: { ...base?.header, ...overlay.header },\n productCard: { ...base?.productCard, ...overlay.productCard },\n }\n}\n\n/** The wrapper attribute + selector a page's scoped theme is emitted under. */\nexport function pageThemeSelector(slug: string): string {\n return `[data-page=\"${slug}\"]`\n}\n\n/** The params a route path pattern declares ('/categoria/:slug' → ['slug']). */\nexport function routePathParams(path: string): string[] {\n return path\n .split('/')\n .filter((segment) => segment.startsWith(':'))\n .map((segment) => segment.slice(1))\n}\n\nexport interface StorefrontPagesConfig {\n home?: StorefrontPageConfig\n catalog?: StorefrontPageConfig\n product?: StorefrontPageConfig\n collection?: StorefrontPageConfig\n /** Editorial pages, keyed by slug. */\n content?: Record<string, StorefrontContentPageConfig>\n}\n\n/** Route path of one content page (explicit `path`, or `/<slug>`). */\nexport function contentPagePath(slug: string, page: StorefrontContentPageConfig): string {\n return page.path ?? `/${slug}`\n}\n\nexport interface ContentPageMatch {\n slug: string\n page: StorefrontContentPageConfig\n /** Params extracted from the page's path pattern, when it declares any. */\n params: Record<string, string>\n}\n\n/** The content page a path resolves to, if the store declared one. Paths are\n * patterns (`/categoria/:slug`), so one declared page can serve a family of\n * URLs and hand the matched params to its blocks' `$param` bindings. */\nexport function matchContentPage(\n pages: StorefrontPagesConfig | undefined,\n path: string,\n): ContentPageMatch | null {\n for (const [slug, page] of Object.entries(pages?.content ?? {})) {\n const params = matchPath(contentPagePath(slug, page), path)\n if (params) return { slug, page, params }\n }\n return null\n}\n\n/** Block ids for the native page bodies — Shopify's `main` section, by another name. */\nexport const CATALOG_BODY_BLOCK = 'catalogBody'\nexport const PRODUCT_BODY_BLOCK = 'productBody'\n\n/** The block that renders the page's own reason for existing, per page kind. */\nconst BODY_BLOCK_BY_KIND: Partial<Record<StorefrontPageKind, string>> = {\n catalog: CATALOG_BODY_BLOCK,\n product: PRODUCT_BODY_BLOCK,\n}\n\n/**\n * Keys that are block identity rather than props, in the nested form.\n *\n * Exported for the same reason `blockInstanceId` is: it must be ONE rule.\n * Whoever asks \"where do this block's settings live\" — the renderer here, the\n * editor via `blockAtPath`, the overlay's settings/structure guard — has to get\n * the same answer, or an edit an editor accepts is one the renderer ignores.\n */\nexport const BLOCK_STRUCTURAL_KEYS: ReadonlySet<string> = new Set([\n 'type',\n 'id',\n 'props',\n 'children',\n 'data',\n])\n\nconst STRUCTURAL_KEYS = BLOCK_STRUCTURAL_KEYS\n\n/**\n * Does this entry keep its settings under `props` (nested form) or inline on\n * the entry itself (flat form)?\n *\n * Both forms are first-class and they MIX inside one array — artorious's home\n * page is 3 nested and 5 flat — so nothing may assume the shape from the path\n * it took to get here.\n */\nexport function isNestedBlockRef(entry: unknown): boolean {\n return isNestedRef(entry as StorefrontBlockLike)\n}\n\nfunction isNestedRef(entry: StorefrontBlockLike): boolean {\n const record = entry as Record<string, unknown>\n // An explicit `props` settles it. Otherwise: an entry carrying nothing but\n // structural keys is a ref with no props (`{ type: 'seals' }`), which the flat\n // reading would also produce — so either branch is correct for that case.\n if ('props' in record) return true\n return Object.keys(record).every((key) => STRUCTURAL_KEYS.has(key))\n}\n\n/**\n * The id a block instance is known by: the authored `id`, or `<type>-<index>`\n * when it has none.\n *\n * Exported because it must be ONE rule. A block with no authored id still\n * reaches the outside world under its synthesized id — `renderStore` reports\n * it, an editor targets it, a generated diff names it — so `applyChange` has\n * to resolve `blocks[#banner-0]` to the same entry the renderer called\n * `banner-0`. Two implementations of this rule would make the id an agent is\n * handed by one ability unusable by another.\n */\nexport function blockInstanceId(entry: unknown, index: number): string {\n const record = entry as Record<string, unknown> | null\n if (record && typeof record.id === 'string' && record.id) return record.id\n return `${String(record?.type)}-${index}`\n}\n\n/**\n * Normalize one authored entry into a `BlockNode`.\n *\n * Both authoring forms collapse to the same node, so everything downstream —\n * the renderer, the editor, `describeBlocks` — sees one shape.\n */\nfunction toBlockNode(entry: StorefrontBlockLike, index: number): BlockNode {\n const record = entry as Record<string, unknown>\n const type = String(record.type)\n const id = blockInstanceId(entry, index)\n\n const data = record.data as BlockDataNeeds | undefined\n\n if (isNestedRef(entry)) {\n const children = (record.children as readonly StorefrontBlockRef[] | undefined) ?? []\n return {\n type,\n id,\n props: (record.props as Record<string, unknown> | undefined) ?? {},\n ...(children.length ? { children: children.map((child, i) => toBlockNode(child, i)) } : {}),\n ...(data ? { data } : {}),\n }\n }\n\n // Flat form: everything that is not identity is a prop.\n const props: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(record)) {\n if (!STRUCTURAL_KEYS.has(key)) props[key] = value\n }\n return { type, id, props, ...(data ? { data } : {}) }\n}\n\n/** Normalize an authored block list into the block tree the renderer consumes. */\nexport function toBlockNodes(blocks: readonly StorefrontBlockLike[]): BlockNode[] {\n return blocks.map(toBlockNode)\n}\n\n/**\n * The default tree for a page kind — what the SDK renders when a store has not\n * composed the page. For catalog and product that is the native body alone,\n * which is why adopting `pages` is a no-op until a store adds something.\n */\nexport function defaultPageBlocks(kind: StorefrontPageKind): BlockNode[] {\n const body = BODY_BLOCK_BY_KIND[kind]\n return body ? [{ type: body, id: body, props: {} }] : []\n}\n\nexport interface PageBlockDiagnostic {\n level: 'error' | 'warning'\n rule: string\n detail: string\n}\n\n/**\n * Diagnostics for one composed page.\n *\n * These are reported, not enforced. A store in production must not go blank\n * because a block was placed on a page its author did not anticipate — so the\n * hard stop belongs in the editor (which reads the same `enabledOn` through\n * `describeBlocks`), and this is the development-time equivalent.\n */\nexport function checkPageBlocks(kind: StorefrontPageKind, nodes: readonly BlockNode[]): PageBlockDiagnostic[] {\n const found: PageBlockDiagnostic[] = []\n const seenIds = new Set<string>()\n const expectedBody = BODY_BLOCK_BY_KIND[kind]\n let hasBody = false\n\n for (const node of nodes) {\n if (node.type === expectedBody) hasBody = true\n\n if (node.id) {\n if (seenIds.has(node.id)) {\n found.push({\n level: 'warning',\n rule: 'duplicate-block-id',\n detail: `two blocks on the ${kind} page share the id \"${node.id}\" — an editor or a generated diff cannot tell them apart`,\n })\n }\n seenIds.add(node.id)\n }\n\n const meta = getBlockMeta(node.type)\n if (!meta) {\n found.push({\n level: 'error',\n rule: 'unknown-block',\n detail: `the ${kind} page references block \"${node.type}\", which is not registered — register it before the storefront mounts`,\n })\n continue\n }\n if (!isBlockEnabledOn({ enabledOn: meta.enabledOn ?? [] }, kind)) {\n found.push({\n level: 'warning',\n rule: 'block-not-enabled-on-page',\n detail: `block \"${node.type}\" declares enabledOn [${(meta.enabledOn ?? []).join(', ')}] and is placed on the ${kind} page`,\n })\n }\n }\n\n if (expectedBody && !hasBody) {\n // Shopify hard-requires the `main` section in a template for this reason. We\n // warn instead of inserting it, because silently adding a block the config\n // does not mention makes the config a lie — and a fully bespoke catalog is a\n // legitimate thing to build.\n found.push({\n level: 'warning',\n rule: 'missing-page-body',\n detail: `the ${kind} page tree omits \"${expectedBody}\", so the page renders no ${kind === 'product' ? 'product detail' : 'product list'} — add it back unless the replacement is deliberate`,\n })\n }\n\n // Composition constraints, for pages composed in code: a document goes\n // through validateStore, but a TS config never does, so the same structural\n // rules are reported here. Errors, because the renderer will keep these\n // blocks off the shopper's page (I7) — the composition already lies.\n for (const violation of checkBlockConstraints(nodes)) {\n found.push({\n level: 'error',\n rule: violation.rule,\n detail: `${kind} page ${violation.path}: ${violation.detail}`,\n })\n }\n\n // Context is advisory: the key may arrive through a runtime channel a static\n // tree cannot see (a slot area, a future loader), so the honest verdict is\n // \"nothing declares this\", not \"this is broken\".\n for (const finding of checkBlockContext(nodes)) {\n found.push({\n level: 'warning',\n rule: 'context-not-provided',\n detail: `block \"${finding.type}\" at ${kind} page ${finding.path} uses context [${finding.missing.join(', ')}] that no ancestor provides`,\n })\n }\n\n return found\n}\n","import { breadcrumbJsonLd, seoOrigin } from '@fayz-ai/core'\nimport { currentStaticRenderPass } from '../app/static-render'\nimport type { Category, Product } from '@fayz-ai/shop/types'\nimport { imageVariantUrl } from '@fayz-ai/shop'\nimport type { ResolvedStorefrontConfig } from '../document/config'\nimport type { StaticHeadInput } from '../app/static-render'\n\n// ---------------------------------------------------------------------------\n// What a storefront route should tell a crawler about itself.\n//\n// Pure builders returning a head declaration, so the page that knows what it is\n// rendering also declares its own SEO — rather than a renderer re-deriving the\n// routing table on the server to guess. Same reason `useStorefrontHead` reports\n// the title instead of letting `renderStore` infer it.\n//\n// Absolute URLs need an origin the store does not know at build time. Callers\n// pass one explicitly (a server render knows the request host); in a browser it\n// falls back to the live origin. Without either, canonical and OG URLs are\n// omitted rather than emitted relative, because a relative canonical is ignored\n// by search engines and a relative og:image renders as a broken share.\n// ---------------------------------------------------------------------------\n\nexport interface StorefrontSeoContext {\n config: ResolvedStorefrontConfig\n /** In-app path, e.g. '/product/pork-ribs'. */\n path: string\n /** Absolute origin, e.g. 'https://loja.example.com'. */\n origin?: string\n}\n\nfunction absolute(ctx: StorefrontSeoContext, path = ctx.path): string | undefined {\n // Explicit wins, then the origin the static render was told about, then the\n // live browser origin. A page never has to know which of the three it is in.\n const origin = (ctx.origin ?? currentStaticRenderPass()?.origin ?? seoOrigin()).replace(/\\/$/, '')\n if (!origin) return undefined\n return `${origin}${path.startsWith('/') ? path : `/${path}`}`\n}\n\n/** Primary image, falling back to the first — how product cards pick one. */\nexport function primaryImageUrl(product: Product): string | undefined {\n return (product.images?.find((i) => i.isPrimary) ?? product.images?.[0])?.url\n}\n\n/**\n * The primary image as a share card wants it: 1200 px wide when the store\n * serves variants, so a WhatsApp/OG scraper does not pull the 4000 px\n * original — and the same URL for every scraper, so it is cached once.\n */\nfunction shareImageUrl(product: Product, ctx: StorefrontSeoContext): string | undefined {\n const url = primaryImageUrl(product)\n if (!url) return undefined\n return ctx.config.imageLoading.transform === 'supabase' ? imageVariantUrl(url, { width: 1200, quality: 82 }) : url\n}\n\n/**\n * schema.org Product. Availability is derived from inventory rather than\n * declared, because a rich result advertising an in-stock product that is not\n * is worse than no rich result.\n */\nexport function productJsonLd(\n product: Product,\n ctx: StorefrontSeoContext,\n): Record<string, unknown> {\n const url = absolute(ctx)\n const image = shareImageUrl(product, ctx)\n return {\n '@context': 'https://schema.org',\n '@type': 'Product',\n name: product.name,\n ...(product.description ? { description: product.description } : {}),\n ...(product.sku ? { sku: product.sku } : {}),\n ...(image ? { image: [image] } : {}),\n offers: {\n '@type': 'Offer',\n ...(url ? { url } : {}),\n price: product.price,\n priceCurrency: product.currency ?? ctx.config.currency,\n availability:\n (product.inventoryCount ?? 0) > 0\n ? 'https://schema.org/InStock'\n : 'https://schema.org/OutOfStock',\n },\n }\n}\n\n/** The head declaration for a product page. */\nexport function productSeo(product: Product, ctx: StorefrontSeoContext): StaticHeadInput {\n const url = absolute(ctx)\n const home = absolute(ctx, '/')\n const catalog = absolute(ctx, ctx.config.catalogPath)\n return {\n title: `${product.name} — ${ctx.config.name}`,\n description: product.description?.slice(0, 160),\n canonical: url,\n image: shareImageUrl(product, ctx),\n type: 'product',\n jsonLd: [\n productJsonLd(product, ctx),\n ...(home && catalog && url\n ? [\n breadcrumbJsonLd([\n { name: ctx.config.name, url: home },\n { name: 'Loja', url: catalog },\n { name: product.name, url },\n ]),\n ]\n : []),\n ],\n }\n}\n\n/** The head declaration for any non-product route: canonical only. */\nexport function pageSeo(\n ctx: StorefrontSeoContext,\n input: { title: string; description?: string | null },\n): StaticHeadInput {\n return { ...input, canonical: absolute(ctx), type: 'website' }\n}\n\n/**\n * Who serves the menu, as the store knows itself. Everything optional: a\n * field the store has not filled is left out of the JSON-LD rather than\n * guessed, because a wrong phone number in a rich result is worse than none.\n */\nexport interface MenuBusiness {\n /** schema.org type. 'Restaurant' unless the house is better described by\n * another FoodEstablishment subtype (e.g. 'FastFoodRestaurant', 'Bakery'). */\n type?: string\n description?: string\n telephone?: string\n email?: string\n /** Absolute URL. */\n logo?: string\n /** Absolute URL; the cover photo. */\n image?: string\n servesCuisine?: string | string[]\n priceRange?: string\n address?: { streetAddress?: string; locality?: string; region?: string; postalCode?: string; country?: string }\n /** Cities or neighbourhoods delivered to, by name. */\n areaServed?: string[]\n /** schema.org openingHours, e.g. ['Mo-Fr 11:00-22:00']. */\n openingHours?: string[]\n sameAs?: string[]\n}\n\n/** The menu as the shopper sees it: category order, each dish under its\n * category, the uncategorised ones last (same grouping as `MenuPage`). */\nfunction menuSections(products: Product[], categories: Category[]) {\n const byCategory = new Map<string, Product[]>()\n const loose: Product[] = []\n for (const p of products) {\n const key = p.categoryId ?? p.categoryName ?? ''\n if (!key) { loose.push(p); continue }\n byCategory.set(key, [...(byCategory.get(key) ?? []), p])\n }\n const sections = categories\n .map((c) => ({ name: c.name, description: c.description, products: byCategory.get(c.id) ?? byCategory.get(c.name) ?? [] }))\n .filter((s) => s.products.length > 0)\n if (loose.length) sections.push({ name: 'Outros', description: null, products: loose })\n if (!sections.length && products.length) return [{ name: 'Cardápio', description: null, products }]\n return sections\n}\n\n/**\n * schema.org Restaurant with its Menu — what lets a search engine answer\n * \"delivery de costela defumada\" with this house, and read every dish and\n * price without running the page's JavaScript.\n *\n * Each dish links to its own product page, where the full Product entity\n * lives; here it is a MenuItem, which is what a dish on a menu is.\n */\nexport function menuJsonLd(\n input: { products: Product[]; categories: Category[]; business?: MenuBusiness },\n ctx: StorefrontSeoContext,\n): Record<string, unknown> {\n const url = absolute(ctx)\n const home = absolute(ctx, '/')\n const b = input.business ?? {}\n const currency = ctx.config.currency\n const address = b.address\n ? {\n '@type': 'PostalAddress',\n ...(b.address.streetAddress ? { streetAddress: b.address.streetAddress } : {}),\n ...(b.address.locality ? { addressLocality: b.address.locality } : {}),\n ...(b.address.region ? { addressRegion: b.address.region } : {}),\n ...(b.address.postalCode ? { postalCode: b.address.postalCode } : {}),\n addressCountry: b.address.country ?? 'BR',\n }\n : undefined\n return {\n '@context': 'https://schema.org',\n '@type': b.type ?? 'Restaurant',\n ...(home ? { '@id': `${home.replace(/\\/$/, '')}/#business` } : {}),\n name: ctx.config.name,\n ...(home ? { url: home } : {}),\n ...(b.description ? { description: b.description } : {}),\n ...(b.image ? { image: [b.image] } : {}),\n ...(b.logo ? { logo: b.logo } : {}),\n ...(b.telephone ? { telephone: b.telephone } : {}),\n ...(b.email ? { email: b.email } : {}),\n ...(b.servesCuisine ? { servesCuisine: b.servesCuisine } : {}),\n ...(b.priceRange ? { priceRange: b.priceRange } : {}),\n ...(address ? { address } : {}),\n ...(b.areaServed?.length ? { areaServed: b.areaServed.map((name) => ({ '@type': 'Place', name })) } : {}),\n ...(b.openingHours?.length ? { openingHours: b.openingHours } : {}),\n ...(b.sameAs?.length ? { sameAs: b.sameAs } : {}),\n ...(url ? { hasMenu: url } : {}),\n ...(url\n ? {\n potentialAction: {\n '@type': 'OrderAction',\n target: { '@type': 'EntryPoint', urlTemplate: url, actionPlatform: ['https://schema.org/DesktopWebPlatform', 'https://schema.org/MobileWebPlatform'] },\n deliveryMethod: 'http://purl.org/goodrelations/v1#DeliveryModeOwnFleet',\n },\n }\n : {}),\n menu: {\n '@type': 'Menu',\n name: `Cardápio — ${ctx.config.name}`,\n ...(url ? { url } : {}),\n inLanguage: 'pt-BR',\n hasMenuSection: menuSections(input.products, input.categories).map((section) => ({\n '@type': 'MenuSection',\n name: section.name,\n ...(section.description ? { description: section.description } : {}),\n hasMenuItem: section.products.map((p) => {\n const image = shareImageUrl(p, ctx)\n const itemUrl = absolute(ctx, `/product/${p.slug}`)\n return {\n '@type': 'MenuItem',\n name: p.name,\n ...(p.description ? { description: p.description.slice(0, 300) } : {}),\n ...(image ? { image } : {}),\n ...(itemUrl ? { url: itemUrl } : {}),\n offers: {\n '@type': 'Offer',\n price: p.price,\n priceCurrency: p.currency ?? currency,\n availability: (p.inventoryCount ?? 0) > 0 ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock',\n },\n }\n }),\n })),\n },\n }\n}\n\n/**\n * The head declaration for the delivery menu: its own title and description\n * (the store passes copy written for the query it should answer), the\n * Restaurant + Menu entity, and a breadcrumb back to the home page.\n */\nexport function menuSeo(\n input: {\n products: Product[]\n categories: Category[]\n title?: string\n description?: string | null\n business?: MenuBusiness\n },\n ctx: StorefrontSeoContext,\n): StaticHeadInput {\n const url = absolute(ctx)\n const home = absolute(ctx, '/')\n const names = input.products.slice(0, 4).map((p) => p.name).join(', ')\n return {\n title: input.title ?? `Delivery ${ctx.config.name} — peça online`,\n description:\n (input.description ?? (names ? `Peça online: ${names} e mais. Cardápio completo com preços.` : undefined))?.slice(0, 160),\n canonical: url,\n image: input.business?.image,\n type: 'website',\n jsonLd: [\n menuJsonLd(input, ctx),\n ...(home && url\n ? [breadcrumbJsonLd([{ name: ctx.config.name, url: home }, { name: 'Delivery', url }])]\n : []),\n ],\n }\n}\n","import type { ShopProvider } from '@fayz-ai/shop/provider'\nimport { matchPath } from './router'\nimport { matchContentPage } from '../blocks/page-blocks'\nimport { resolveConfig } from '../document/config'\nimport type { StorefrontConfig, ResolvedStorefrontConfig } from '../document/config'\n\n// ---------------------------------------------------------------------------\n// How a store is served, once its pages have URLs of their own.\n//\n// Two questions a host has to answer that the shell cannot: which paths exist\n// at all (what to prerender, what to put in a sitemap), and which of them are\n// the same for every visitor (what a shared cache may hold). Both are\n// properties of the route, so they are decided here rather than by each host\n// re-deriving them — and the second one has a failure mode a CDN makes\n// invisible: cache a cart or an order confirmation once and it is served to the\n// next shopper.\n// ---------------------------------------------------------------------------\n\nexport type StorefrontRouteMatch =\n | { kind: 'custom'; route: NonNullable<ResolvedStorefrontConfig['routes']>[number]; params: Record<string, string> }\n | { kind: 'product'; params: Record<string, string> }\n | { kind: 'order'; params: Record<string, string> }\n | { kind: 'checkout' }\n | { kind: 'account' }\n | { kind: 'catalog' }\n | { kind: 'menu' }\n | { kind: 'searchResults' }\n | { kind: 'policy'; policy: 'privacy' | 'terms' | 'returns' }\n | { kind: 'content'; slug: string; params: Record<string, string> }\n | { kind: 'home' }\n | { kind: 'notFound' }\n\n/**\n * What a path means, resolved once.\n *\n * The shell renders from this, cacheability is derived from it, and a host\n * framework asks it whether a URL exists at all before choosing a status code.\n * Those three answering separately is how a page ends up rendered as one thing\n * and cached or statused as another.\n *\n * The query string is stripped first: it addresses state WITHIN a page, so\n * `/?utm_source=instagram` is the home page — the single most common shape of\n * inbound marketing link, and a 404 for it is a silent, expensive bug.\n */\nexport function resolveStorefrontRoute(\n config: StorefrontConfig | ResolvedStorefrontConfig,\n rawPath: string,\n): StorefrontRouteMatch {\n const resolved = ensureResolved(config)\n const path = rawPath.split('?')[0] || '/'\n\n for (const route of resolved.routes ?? []) {\n const params = matchPath(route.path, path)\n if (params) return { kind: 'custom', route, params }\n }\n\n const product = matchPath('/product/:slug', path)\n if (product?.slug) return { kind: 'product', params: product }\n\n const order = matchPath('/order/:id', path)\n if (order?.id) return { kind: 'order', params: order }\n\n // Matched regardless of the feature flag: a disabled checkout still owns its\n // URL rather than falling through to an unrelated page.\n if (matchPath('/checkout', path)) return { kind: 'checkout' }\n if (matchPath('/account', path)) return { kind: 'account' }\n if (matchPath('/catalog', path)) return { kind: 'catalog' }\n // Só existe no modo delivery, e por isso é testado contra `resolved.delivery`\n // e não contra o literal '/menu': fora do modo, /menu é um 404 de verdade em\n // vez de uma página vazia — que é a diferença entre uma rota que não existe e\n // uma rota quebrada.\n if (resolved.delivery && matchPath(resolved.delivery.menuPath, path)) return { kind: 'menu' }\n if (resolved.search.mode === 'overlay' && matchPath(resolved.search.resultsPath, path)) {\n return { kind: 'searchResults' }\n }\n if (matchPath('/privacy', path)) return { kind: 'policy', policy: 'privacy' }\n if (matchPath('/terms', path)) return { kind: 'policy', policy: 'terms' }\n if (matchPath('/refunds', path)) return { kind: 'policy', policy: 'returns' }\n\n const content = matchContentPage(resolved.pages, path)\n if (content) return { kind: 'content', slug: content.slug, params: content.params }\n\n if (path === '/' || path === '') return { kind: 'home' }\n return { kind: 'notFound' }\n}\n\n/** Whether a URL exists at all — what a host needs before choosing a status. */\nexport function isKnownPath(\n config: StorefrontConfig | ResolvedStorefrontConfig,\n path: string,\n): boolean {\n return resolveStorefrontRoute(config, path).kind !== 'notFound'\n}\n\n/** Paths whose HTML is per-shopper and must never enter a shared cache. */\nconst PRIVATE_PATTERNS = ['/checkout', '/account', '/order/:id'] as const\n\n/** Paths the SDK serves that exist without knowing any product. The delivery\n * menu is added from the store's own `delivery.menuPath` — see `storefrontPaths`. */\nconst STATIC_PATTERNS = ['/', '/catalog', '/privacy', '/terms', '/refunds'] as const\n\nfunction ensureResolved(config: StorefrontConfig | ResolvedStorefrontConfig): ResolvedStorefrontConfig {\n return 'features' in config && 'pages' in config\n ? (config as ResolvedStorefrontConfig)\n : resolveConfig(config)\n}\n\n/**\n * Whether `path`'s HTML is identical for every visitor.\n *\n * Conservative by construction: a store's own route is private unless it says\n * otherwise, because guessing \"public\" is the direction that leaks one\n * shopper's page to another.\n */\nexport function isPublicPath(\n config: StorefrontConfig | ResolvedStorefrontConfig,\n path: string,\n): boolean {\n const match = resolveStorefrontRoute(config, path)\n switch (match.kind) {\n case 'checkout':\n case 'account':\n case 'order':\n return false\n case 'custom':\n return (\n match.route.kind !== 'checkout' &&\n match.route.kind !== 'account' &&\n match.route.chrome !== 'focused'\n )\n default:\n return true\n }\n}\n\n/**\n * Every path worth prerendering, and the same list a sitemap should carry.\n *\n * Product URLs come from the catalogue rather than the route table, so the\n * provider is asked rather than guessed at. Custom routes with parameters are\n * skipped: the SDK cannot know what values a store's own route accepts, and\n * emitting `/colecao/:slug` into a sitemap is worse than omitting it.\n */\nexport async function storefrontPaths(input: {\n config: StorefrontConfig | ResolvedStorefrontConfig\n provider: ShopProvider\n /** Include per-shopper routes. Off by default — they are not prerenderable. */\n includePrivate?: boolean\n}): Promise<string[]> {\n const resolved = ensureResolved(input.config)\n const paths = [...STATIC_PATTERNS] as string[]\n // The menu is the same for every visitor — what changes per shopper (address,\n // cart, open right now) resolves in the browser after hydration. It is listed\n // at the store's own path: a store whose menu lives at /delivery had /menu in\n // its sitemap and its real ordering page in none.\n if (resolved.delivery) paths.push(resolved.delivery.menuPath)\n\n for (const route of resolved.routes ?? []) {\n if (!route.path.includes(':')) paths.push(route.path)\n }\n\n const products = await input.provider.listProducts({ status: 'active' })\n for (const product of products) paths.push(`/product/${product.slug}`)\n\n const unique = Array.from(new Set(paths))\n return input.includePrivate ? unique : unique.filter((p) => isPublicPath(resolved, p))\n}\n","import { dataNeedKey } from '@fayz-ai/core'\n\n/**\n * The reads the delivery menu makes, named once so a server host can resolve\n * them before render. The menu is not a block tree, so nothing collects these\n * for it — a host that does not seed them sends a menu with no dishes in the\n * HTML, which is the page a crawler indexes.\n *\n * Its own module, free of React, because a host's route loader imports it on\n * every request.\n */\nexport const MENU_DATA_NEEDS = {\n products: { loader: 'products.list', params: {} },\n categories: { loader: 'categories.list', params: {} },\n featured: { loader: 'products.featured', params: {} },\n} as const\n\n/** The menu's data needs, keyed exactly as its `useLoader` calls will ask. */\nexport function menuDataNeeds(): Array<{ key: string; loader: string; params: Record<string, unknown> }> {\n return Object.values(MENU_DATA_NEEDS).map(({ loader, params }) => ({ key: dataNeedKey(loader, params), loader, params }))\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/locales/messages.ts","../src/document/config.ts","../src/app/router.ts","../src/app/static-render.ts","../src/blocks/page-data.tsx","../src/blocks/page-blocks.ts","../src/lib/seo.ts","../src/app/serving.ts","../src/data/menu-needs.ts"],"names":["createContext","useContext","React","useEffect","entry","getBlockMeta","dataNeedKey"],"mappings":"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","file":"chunk-7N5HKQBM.js","sourcesContent":["// ---------------------------------------------------------------------------\n// The storefront's own words (cart, checkout, delivery), per language.\n//\n// pt-BR is the source: copied verbatim from the screens as they were, so a\n// store that sets no language reads exactly what it always read. en and es\n// translate it; a key missing from either falls back to pt-BR, never to the\n// key itself. `{{name}}` marks a value filled in at the call site.\n// ---------------------------------------------------------------------------\n\nexport type StorefrontLanguage = 'pt-BR' | 'en' | 'es'\n\nexport const ptBR = {\n // Checkout shell\n 'checkout.title': 'Checkout — {{store}}',\n 'checkout.backToStore': 'Voltar à loja',\n 'checkout.secure': 'Checkout seguro',\n 'checkout.help': 'Ajuda',\n 'checkout.steps.label': 'Etapas do checkout',\n 'checkout.steps.1': 'Dados',\n 'checkout.steps.2': 'Entrega',\n 'checkout.steps.3': 'Pagamento',\n 'checkout.steps.4': 'Pronto',\n // Step 1 — contact\n 'checkout.contact.title': 'Informações de contato',\n 'checkout.contact.signedInAs': 'Conectado como {{email}}',\n 'checkout.contact.edit': 'Alterar',\n 'checkout.contact.notYou': 'Não é você?',\n 'checkout.contact.signOut': 'Sair',\n 'checkout.contact.emailLocked': 'O e-mail é o da sua conta.',\n 'checkout.contact.haveAccount': 'Já tem conta? Entrar',\n 'checkout.contact.email': 'E-mail',\n 'checkout.contact.name': 'Nome completo',\n 'checkout.contact.phone': 'Telefone',\n 'checkout.contact.phoneOptional': 'Telefone (opcional)',\n 'checkout.contact.document': 'CPF ou CNPJ',\n 'checkout.contact.documentOptional': 'CPF ou CNPJ (opcional)',\n 'checkout.contact.requiresAccount': 'Esta loja pede uma conta para finalizar a compra.',\n 'checkout.contact.signInOrCreate': 'Entrar ou criar conta',\n // Step 2 — address\n 'checkout.address.title': 'Endereço de entrega',\n 'checkout.address.loadingSaved': 'Buscando seus endereços salvos',\n 'checkout.address.selected': 'Selecionado',\n 'checkout.address.addNew': '+ Adicionar novo endereço',\n 'checkout.address.enter': 'Informe o endereço de entrega',\n 'checkout.address.enterHint': 'Preencher outro endereço para esta compra',\n 'checkout.address.lookingUp': 'Buscando o endereço deste CEP',\n 'checkout.address.notFound': 'CEP não encontrado — preencha o endereço à mão.',\n 'checkout.address.filled': 'Preenchemos o endereço para você.',\n 'checkout.address.regionFromPostal': 'Província preenchida pelo código postal.',\n 'checkout.address.optional': '{{label}} (opcional)',\n 'checkout.address.choose': 'Selecione',\n 'checkout.address.shipTo': 'Enviar para',\n // Step 3 — payment\n 'checkout.confirming.title': 'Confirmando seu pedido',\n 'checkout.confirming.label': 'Criando seu pedido',\n 'checkout.confirming.keepOpen': 'Não feche esta página — estamos registrando seu pedido na loja.',\n 'checkout.payment.title': 'Pagamento',\n 'checkout.payment.label': 'Forma de pagamento',\n 'checkout.payment.cardOnline': 'Você paga na página segura do provedor e volta para a loja',\n 'checkout.payment.placeOrder': 'Fazer pedido - {{total}}',\n 'checkout.payment.pendingNote': 'O pedido fica aguardando pagamento até a loja confirmar.',\n 'checkout.payment.unavailableCountry': 'Esta forma de pagamento não está disponível para {{country}}.',\n 'payment.pix.label': 'Pix',\n 'payment.pix.hint': 'Você recebe a chave para pagar após confirmar o pedido',\n 'payment.credit_card.label': 'Cartão de crédito',\n 'payment.credit_card.hint': 'Maquininha na entrega',\n 'payment.debit_card.label': 'Cartão de débito',\n 'payment.debit_card.hint': 'Maquininha na entrega',\n 'payment.boleto.label': 'Boleto',\n 'payment.boleto.hint': 'Enviado por e-mail após a confirmação',\n 'payment.cash.label': 'Dinheiro',\n 'payment.cash.hint': 'Pagamento na entrega',\n 'payment.other.label': 'Combinar com a loja',\n 'payment.other.hint': 'A loja entra em contato para acertar o pagamento',\n // Step 4\n 'checkout.done.title': 'Pagamento confirmado!',\n 'checkout.done.text': 'Seu pedido foi criado e a loja já foi avisada.',\n 'checkout.done.viewOrder': 'Ver meu pedido',\n // Navigation\n 'checkout.continueToDelivery': 'Continuar para a entrega',\n 'checkout.goToPayment': 'Ir para o pagamento - {{total}}',\n 'checkout.backToContact': 'Voltar aos dados',\n 'checkout.backToCart': 'Voltar ao carrinho',\n // Summary\n 'summary.title': 'Resumo do pedido',\n 'summary.subtotal': 'Subtotal',\n 'summary.discount': 'Desconto',\n 'summary.delivery': 'Entrega',\n 'summary.pickup': 'Retirada na loja',\n 'summary.noFee': 'Sem taxa',\n 'summary.free': 'Grátis',\n 'summary.total': 'Total',\n 'summary.protected': 'Compra protegida e dados criptografados.',\n 'summary.shipping': 'Frete',\n // Discount\n 'discount.placeholder': 'Cupom de desconto',\n 'discount.apply': 'Aplicar',\n 'discount.freeShipping': 'frete grátis',\n 'discount.percentOff': '{{percent}}% de desconto',\n 'discount.applied': '{{code}} aplicado: {{effect}}.',\n 'discount.appliedToast': 'Cupom aplicado!',\n 'discount.invalid': 'Cupom inválido.',\n 'discount.invalidToast': 'Cupom inválido',\n 'discount.checkCode': 'Verifique o código e tente novamente.',\n 'discount.cannotValidate': 'Não conseguimos validar esse cupom agora.',\n 'discount.cannotValidateToast': 'Não conseguimos validar o cupom',\n 'discount.tryLater': 'Tente de novo em alguns instantes.',\n // Legal\n 'legal.privacy': 'Privacidade',\n 'legal.terms': 'Termos',\n 'legal.refunds': 'Trocas e devoluções',\n // Validation\n 'error.requiresAccount': 'Esta loja pede uma conta para finalizar a compra. Entre ou crie a sua.',\n 'error.email': 'Informe um e-mail válido.',\n 'error.name': 'Informe seu nome completo.',\n 'error.phone': 'Informe um telefone de contato.',\n 'error.documentInvalid': 'CPF ou CNPJ inválido — confira os números.',\n 'error.documentMissing': 'Informe o CPF ou CNPJ do comprador.',\n 'error.taxIdInvalid': 'NIF/NIE inválido — confira o número.',\n 'error.address': 'Preencha ou selecione o endereço de entrega.',\n 'error.number': 'Falta o número do endereço.',\n 'error.complement': 'Informe o complemento (apto, bloco).',\n 'error.state': 'Informe a UF com duas letras (ex.: RJ).',\n 'error.postalInvalid': 'Confira o código postal (ex.: {{example}}).',\n 'error.region': 'Selecione a {{label}}.',\n 'error.refusedZone': 'Esta loja não entrega nesse endereço. Tente outro.',\n 'error.unserved': 'Ainda não entregamos nesse CEP. Tente outro endereço.',\n 'error.sessionMismatch': 'Sua sessão ficou presa a outro cadastro. Recarregue a página e tente de novo.',\n 'error.outOfStock': 'Um item do carrinho ficou sem estoque. Revise o carrinho e tente de novo.',\n 'error.placeOrder': 'Não foi possível concluir o pedido.',\n // Delivery estimator\n 'delivery.title': 'Calcular entrega',\n 'delivery.calculate': 'Calcular',\n 'delivery.postalLabel': 'CEP',\n 'delivery.change': 'Trocar CEP',\n 'delivery.unserved': 'Ainda não entregamos nesse CEP.',\n 'delivery.refused': 'Esta loja não entrega nesse endereço.',\n 'delivery.review': 'Entregamos nessa região, mas confirmamos com você antes de sair.',\n 'delivery.etaSoon': 'hoje ou amanhã',\n 'delivery.etaRange': '{{min}} a {{max}} dias úteis',\n 'delivery.etaDays': '{{days}} dia(s) útil(eis)',\n 'delivery.flatRate': 'O frete é calculado no checkout.',\n 'delivery.error.digits': 'Digite os 8 dígitos do CEP.',\n 'delivery.error.postal': 'Confira o código postal (ex.: {{example}}).',\n 'delivery.error.quote': 'Não foi possível calcular o frete agora. Tente de novo.',\n 'delivery.error.notFound': 'CEP não encontrado. Confira os números.',\n // Cart\n 'cart.title': 'Carrinho',\n 'cart.close': 'Fechar carrinho',\n 'cart.empty': 'Seu carrinho está vazio.',\n 'cart.remove': 'Remover {{name}}',\n 'cart.checkout': 'Finalizar compra',\n 'cart.missingForFree': 'Faltam {{amount}} para frete grátis',\n 'cart.wonFree': 'Você ganhou frete grátis!',\n 'cart.minimumOrder': 'Pedido mínimo para entrega: {{amount}}. Faltam {{missing}}.',\n 'delivery.eta': 'Entrega em ~{{duration}}',\n 'delivery.etaUpTo': 'Entrega em até {{duration}}',\n 'delivery.paused': 'Delivery fechado no momento',\n 'cart.deliveryPaused': 'O delivery está fechado no momento. Volte mais tarde para finalizar.',\n // Deliver to\n 'country.deliverTo': 'Enviar para',\n 'country.change': 'Trocar país',\n 'country.label': 'País de entrega',\n}\n\nexport type MessageKey = keyof typeof ptBR\nexport type Messages = Record<MessageKey, string>\n\nconst en: Partial<Messages> = {\n 'checkout.backToStore': 'Back to store',\n 'checkout.secure': 'Secure checkout',\n 'checkout.help': 'Help',\n 'checkout.steps.label': 'Checkout steps',\n 'checkout.steps.1': 'Details',\n 'checkout.steps.2': 'Delivery',\n 'checkout.steps.3': 'Payment',\n 'checkout.steps.4': 'Done',\n 'checkout.contact.title': 'Contact information',\n 'checkout.contact.signedInAs': 'Signed in as {{email}}',\n 'checkout.contact.edit': 'Change',\n 'checkout.contact.notYou': 'Not you?',\n 'checkout.contact.signOut': 'Sign out',\n 'checkout.contact.emailLocked': 'This is your account e-mail.',\n 'checkout.contact.haveAccount': 'Have an account? Sign in',\n 'checkout.contact.email': 'Email',\n 'checkout.contact.name': 'Full name',\n 'checkout.contact.phone': 'Phone',\n 'checkout.contact.phoneOptional': 'Phone (optional)',\n 'checkout.contact.document': 'Tax ID',\n 'checkout.contact.documentOptional': 'Tax ID (optional)',\n 'checkout.contact.requiresAccount': 'This store needs an account to complete the purchase.',\n 'checkout.contact.signInOrCreate': 'Sign in or create an account',\n 'checkout.address.title': 'Delivery address',\n 'checkout.address.loadingSaved': 'Loading your saved addresses',\n 'checkout.address.selected': 'Selected',\n 'checkout.address.addNew': '+ Add a new address',\n 'checkout.address.enter': 'Enter the delivery address',\n 'checkout.address.enterHint': 'Use a different address for this order',\n 'checkout.address.lookingUp': 'Looking up this postal code',\n 'checkout.address.notFound': 'Postal code not found — fill in the address by hand.',\n 'checkout.address.filled': 'We filled in the address for you.',\n 'checkout.address.regionFromPostal': 'Province filled in from the postcode.',\n 'checkout.address.optional': '{{label}} (optional)',\n 'checkout.address.choose': 'Select',\n 'checkout.address.shipTo': 'Ship to',\n 'checkout.confirming.title': 'Confirming your order',\n 'checkout.confirming.label': 'Creating your order',\n 'checkout.confirming.keepOpen': 'Don’t close this page — we’re registering your order with the store.',\n 'checkout.payment.title': 'Payment',\n 'checkout.payment.label': 'Payment method',\n 'checkout.payment.cardOnline': 'You pay on the provider’s secure page and come back to the store',\n 'checkout.payment.placeOrder': 'Place order - {{total}}',\n 'checkout.payment.pendingNote': 'The order awaits payment until the store confirms it.',\n 'checkout.payment.unavailableCountry': 'This payment method isn’t available for {{country}}.',\n 'payment.pix.hint': 'You get the key to pay after confirming the order',\n 'payment.credit_card.label': 'Credit card',\n 'payment.credit_card.hint': 'Card machine on delivery',\n 'payment.debit_card.label': 'Debit card',\n 'payment.debit_card.hint': 'Card machine on delivery',\n 'payment.boleto.hint': 'Sent by email after confirmation',\n 'payment.cash.label': 'Cash',\n 'payment.cash.hint': 'Pay on delivery',\n 'payment.other.label': 'Arrange with the store',\n 'payment.other.hint': 'The store will contact you to arrange payment',\n 'checkout.done.title': 'Payment confirmed!',\n 'checkout.done.text': 'Your order was created and the store has been notified.',\n 'checkout.done.viewOrder': 'View my order',\n 'checkout.continueToDelivery': 'Continue to delivery',\n 'checkout.goToPayment': 'Go to payment - {{total}}',\n 'checkout.backToContact': 'Back to details',\n 'checkout.backToCart': 'Back to cart',\n 'summary.title': 'Order summary',\n 'summary.discount': 'Discount',\n 'summary.delivery': 'Delivery',\n 'summary.pickup': 'Store pickup',\n 'summary.noFee': 'No fee',\n 'summary.free': 'Free',\n 'summary.protected': 'Protected purchase, encrypted data.',\n 'summary.shipping': 'Shipping',\n 'discount.placeholder': 'Discount code',\n 'discount.apply': 'Apply',\n 'discount.freeShipping': 'free shipping',\n 'discount.percentOff': '{{percent}}% off',\n 'discount.applied': '{{code}} applied: {{effect}}.',\n 'discount.appliedToast': 'Code applied!',\n 'discount.invalid': 'Invalid code.',\n 'discount.invalidToast': 'Invalid code',\n 'discount.checkCode': 'Check the code and try again.',\n 'discount.cannotValidate': 'We couldn’t check this code right now.',\n 'discount.cannotValidateToast': 'We couldn’t check the code',\n 'discount.tryLater': 'Try again in a moment.',\n 'legal.privacy': 'Privacy',\n 'legal.terms': 'Terms',\n 'legal.refunds': 'Returns',\n 'error.requiresAccount': 'This store needs an account to complete the purchase. Sign in or create one.',\n 'error.email': 'Enter a valid email.',\n 'error.name': 'Enter your full name.',\n 'error.phone': 'Enter a contact phone number.',\n 'error.documentInvalid': 'Invalid tax ID — check the numbers.',\n 'error.documentMissing': 'Enter the buyer’s tax ID.',\n 'error.taxIdInvalid': 'Invalid NIF/NIE — check the number.',\n 'error.address': 'Fill in or select the delivery address.',\n 'error.number': 'The street number is missing.',\n 'error.complement': 'Enter the apartment or unit.',\n 'error.state': 'Enter the two-letter state code (e.g. RJ).',\n 'error.postalInvalid': 'Check the postal code (e.g. {{example}}).',\n 'error.region': 'Select the {{label}}.',\n 'error.refusedZone': 'This store doesn’t deliver to this address. Try another.',\n 'error.unserved': 'We don’t deliver to this postal code yet. Try another address.',\n 'error.sessionMismatch': 'Your session got attached to another account. Reload the page and try again.',\n 'error.outOfStock': 'An item in your cart is out of stock. Review the cart and try again.',\n 'error.placeOrder': 'We couldn’t complete the order.',\n 'delivery.title': 'Estimate delivery',\n 'delivery.calculate': 'Estimate',\n 'delivery.postalLabel': 'Postal code',\n 'delivery.change': 'Change postal code',\n 'delivery.unserved': 'We don’t deliver to this postal code yet.',\n 'delivery.refused': 'This store doesn’t deliver to this address.',\n 'delivery.review': 'We deliver to this area, but we’ll confirm with you before shipping.',\n 'delivery.etaSoon': 'today or tomorrow',\n 'delivery.etaRange': '{{min}} to {{max}} business days',\n 'delivery.etaDays': '{{days}} business day(s)',\n 'delivery.flatRate': 'Shipping is calculated at checkout.',\n 'delivery.error.digits': 'Enter all 8 digits of the CEP.',\n 'delivery.error.postal': 'Check the postal code (e.g. {{example}}).',\n 'delivery.error.quote': 'We couldn’t calculate shipping right now. Try again.',\n 'delivery.error.notFound': 'Postal code not found. Check the numbers.',\n 'cart.title': 'Cart',\n 'cart.close': 'Close cart',\n 'cart.empty': 'Your cart is empty.',\n 'cart.remove': 'Remove {{name}}',\n 'cart.checkout': 'Checkout',\n 'cart.missingForFree': '{{amount}} away from free shipping',\n 'cart.wonFree': 'You got free shipping!',\n 'cart.minimumOrder': 'Minimum order for delivery: {{amount}}. {{missing}} to go.',\n 'delivery.eta': 'Delivery in ~{{duration}}',\n 'delivery.etaUpTo': 'Delivery within {{duration}}',\n 'delivery.paused': 'Delivery closed right now',\n 'cart.deliveryPaused': 'Delivery is closed right now. Come back later to check out.',\n 'country.deliverTo': 'Deliver to',\n 'country.change': 'Change country',\n 'country.label': 'Delivery country',\n}\n\nconst es: Partial<Messages> = {\n 'checkout.backToStore': 'Volver a la tienda',\n 'checkout.secure': 'Pago seguro',\n 'checkout.help': 'Ayuda',\n 'checkout.steps.label': 'Pasos del pago',\n 'checkout.steps.1': 'Datos',\n 'checkout.steps.2': 'Envío',\n 'checkout.steps.3': 'Pago',\n 'checkout.steps.4': 'Listo',\n 'checkout.contact.title': 'Datos de contacto',\n 'checkout.contact.signedInAs': 'Has iniciado sesión como {{email}}',\n 'checkout.contact.edit': 'Cambiar',\n 'checkout.contact.notYou': '¿No eres tú?',\n 'checkout.contact.signOut': 'Salir',\n 'checkout.contact.emailLocked': 'Es el correo de tu cuenta.',\n 'checkout.contact.haveAccount': '¿Ya tienes cuenta? Entrar',\n 'checkout.contact.email': 'Email',\n 'checkout.contact.name': 'Nombre completo',\n 'checkout.contact.phone': 'Teléfono',\n 'checkout.contact.phoneOptional': 'Teléfono (opcional)',\n 'checkout.contact.document': 'NIF/NIE',\n 'checkout.contact.documentOptional': 'NIF/NIE (opcional)',\n 'checkout.contact.requiresAccount': 'Esta tienda pide una cuenta para finalizar la compra.',\n 'checkout.contact.signInOrCreate': 'Entrar o crear cuenta',\n 'checkout.address.title': 'Dirección de envío',\n 'checkout.address.loadingSaved': 'Buscando tus direcciones guardadas',\n 'checkout.address.selected': 'Seleccionada',\n 'checkout.address.addNew': '+ Añadir una dirección nueva',\n 'checkout.address.enter': 'Indica la dirección de envío',\n 'checkout.address.enterHint': 'Usar otra dirección para este pedido',\n 'checkout.address.lookingUp': 'Buscando este código postal',\n 'checkout.address.notFound': 'Código postal no encontrado: rellena la dirección a mano.',\n 'checkout.address.filled': 'Hemos rellenado la dirección por ti.',\n 'checkout.address.regionFromPostal': 'Provincia rellenada a partir del código postal.',\n 'checkout.address.optional': '{{label}} (opcional)',\n 'checkout.address.choose': 'Selecciona',\n 'checkout.address.shipTo': 'Enviar a',\n 'checkout.confirming.title': 'Confirmando tu pedido',\n 'checkout.confirming.label': 'Creando tu pedido',\n 'checkout.confirming.keepOpen': 'No cierres esta página: estamos registrando tu pedido en la tienda.',\n 'checkout.payment.title': 'Pago',\n 'checkout.payment.label': 'Forma de pago',\n 'checkout.payment.cardOnline': 'Pagas en la página segura del proveedor y vuelves a la tienda',\n 'checkout.payment.placeOrder': 'Hacer pedido - {{total}}',\n 'checkout.payment.pendingNote': 'El pedido queda pendiente de pago hasta que la tienda lo confirme.',\n 'checkout.payment.unavailableCountry': 'Esta forma de pago no está disponible para {{country}}.',\n 'payment.pix.hint': 'Recibes la clave para pagar al confirmar el pedido',\n 'payment.credit_card.label': 'Tarjeta de crédito',\n 'payment.credit_card.hint': 'Datáfono en la entrega',\n 'payment.debit_card.label': 'Tarjeta de débito',\n 'payment.debit_card.hint': 'Datáfono en la entrega',\n 'payment.boleto.hint': 'Enviado por email tras la confirmación',\n 'payment.cash.label': 'Efectivo',\n 'payment.cash.hint': 'Pago en la entrega',\n 'payment.other.label': 'Acordar con la tienda',\n 'payment.other.hint': 'La tienda te contactará para acordar el pago',\n 'checkout.done.title': '¡Pago confirmado!',\n 'checkout.done.text': 'Tu pedido se ha creado y la tienda ya ha sido avisada.',\n 'checkout.done.viewOrder': 'Ver mi pedido',\n 'checkout.continueToDelivery': 'Continuar al envío',\n 'checkout.goToPayment': 'Ir al pago - {{total}}',\n 'checkout.backToContact': 'Volver a los datos',\n 'checkout.backToCart': 'Volver al carrito',\n 'summary.title': 'Resumen del pedido',\n 'summary.discount': 'Descuento',\n 'summary.delivery': 'Envío',\n 'summary.pickup': 'Recogida en tienda',\n 'summary.noFee': 'Sin coste',\n 'summary.free': 'Gratis',\n 'summary.protected': 'Compra protegida y datos cifrados.',\n 'summary.shipping': 'Envío',\n 'discount.placeholder': 'Código de descuento',\n 'discount.apply': 'Aplicar',\n 'discount.freeShipping': 'envío gratis',\n 'discount.percentOff': '{{percent}}% de descuento',\n 'discount.applied': '{{code}} aplicado: {{effect}}.',\n 'discount.appliedToast': '¡Código aplicado!',\n 'discount.invalid': 'Código no válido.',\n 'discount.invalidToast': 'Código no válido',\n 'discount.checkCode': 'Revisa el código e inténtalo de nuevo.',\n 'discount.cannotValidate': 'No hemos podido validar este código ahora.',\n 'discount.cannotValidateToast': 'No hemos podido validar el código',\n 'discount.tryLater': 'Inténtalo de nuevo en unos instantes.',\n 'legal.privacy': 'Privacidad',\n 'legal.terms': 'Términos',\n 'legal.refunds': 'Devoluciones',\n 'error.requiresAccount': 'Esta tienda pide una cuenta para finalizar la compra. Entra o crea la tuya.',\n 'error.email': 'Indica un email válido.',\n 'error.name': 'Indica tu nombre completo.',\n 'error.phone': 'Indica un teléfono de contacto.',\n 'error.documentInvalid': 'Documento no válido: revisa los números.',\n 'error.documentMissing': 'Indica el documento del comprador.',\n 'error.taxIdInvalid': 'NIF/NIE no válido: revisa el número.',\n 'error.address': 'Rellena o selecciona la dirección de envío.',\n 'error.number': 'Falta el número de la dirección.',\n 'error.complement': 'Indica el piso o la puerta.',\n 'error.state': 'Indica el estado con dos letras (ej.: RJ).',\n 'error.postalInvalid': 'Revisa el código postal (ej.: {{example}}).',\n 'error.region': 'Selecciona la {{label}}.',\n 'error.refusedZone': 'Esta tienda no envía a esta dirección. Prueba con otra.',\n 'error.unserved': 'Todavía no enviamos a este código postal. Prueba con otra dirección.',\n 'error.sessionMismatch': 'Tu sesión quedó vinculada a otra cuenta. Recarga la página e inténtalo de nuevo.',\n 'error.outOfStock': 'Un producto del carrito se ha agotado. Revisa el carrito e inténtalo de nuevo.',\n 'error.placeOrder': 'No se ha podido completar el pedido.',\n 'delivery.title': 'Calcular envío',\n 'delivery.calculate': 'Calcular',\n 'delivery.postalLabel': 'Código postal',\n 'delivery.change': 'Cambiar código postal',\n 'delivery.unserved': 'Todavía no enviamos a este código postal.',\n 'delivery.refused': 'Esta tienda no envía a esta dirección.',\n 'delivery.review': 'Enviamos a esta zona, pero lo confirmamos contigo antes de salir.',\n 'delivery.etaSoon': 'hoy o mañana',\n 'delivery.etaRange': 'de {{min}} a {{max}} días laborables',\n 'delivery.etaDays': '{{days}} día(s) laborable(s)',\n 'delivery.flatRate': 'El envío se calcula en el pago.',\n 'delivery.error.digits': 'Escribe los 8 dígitos del CEP.',\n 'delivery.error.postal': 'Revisa el código postal (ej.: {{example}}).',\n 'delivery.error.quote': 'No hemos podido calcular el envío ahora. Inténtalo de nuevo.',\n 'delivery.error.notFound': 'Código postal no encontrado. Revisa los números.',\n 'cart.title': 'Carrito',\n 'cart.close': 'Cerrar carrito',\n 'cart.empty': 'Tu carrito está vacío.',\n 'cart.remove': 'Quitar {{name}}',\n 'cart.checkout': 'Finalizar compra',\n 'cart.missingForFree': 'Te faltan {{amount}} para el envío gratis',\n 'cart.wonFree': '¡Tienes envío gratis!',\n 'cart.minimumOrder': 'Pedido mínimo para entrega: {{amount}}. Te faltan {{missing}}.',\n 'delivery.eta': 'Entrega en ~{{minutes}} min',\n 'country.deliverTo': 'Enviar a',\n 'country.change': 'Cambiar país',\n 'country.label': 'País de envío',\n}\n\nexport const MESSAGES: Record<StorefrontLanguage, Partial<Messages>> = { 'pt-BR': ptBR, en, es }\n\n/** 'pt', 'pt-PT', 'PT-br' → 'pt-BR'; 'en-GB' → 'en'; 'es-MX' → 'es'; anything else → null. */\nexport function normalizeLanguage(value?: string | null): StorefrontLanguage | null {\n const base = (value || '').toLowerCase().split(/[-_]/)[0]\n if (base === 'pt') return 'pt-BR'\n if (base === 'en') return 'en'\n if (base === 'es') return 'es'\n return null\n}\n\n/** Look a key up: the store's override, the language, then pt-BR. */\nexport function translate(\n language: StorefrontLanguage,\n key: MessageKey,\n vars?: Record<string, string | number>,\n overrides?: Partial<Record<StorefrontLanguage, Partial<Messages>>>,\n): string {\n let text = overrides?.[language]?.[key] ?? MESSAGES[language]?.[key] ?? overrides?.['pt-BR']?.[key] ?? ptBR[key]\n if (vars) for (const [name, value] of Object.entries(vars)) text = text.split(`{{${name}}}`).join(String(value))\n return text\n}\n","import React, { createContext, useContext, type ReactNode } from 'react'\nimport type { StorefrontAnalyticsConfig } from '../analytics/posthog'\nimport type { StorefrontExperiment } from '../experiments/assign'\nimport type { Experimental } from '../experiments/react'\nimport type { EntityDeclarationInput } from '@fayz-ai/core'\nimport type { ShopProvider } from '@fayz-ai/shop/provider'\nimport type { MockShopSeed } from '@fayz-ai/shop/mock'\nimport type { PaymentMethodKind, Product, ShopMarket, StoreSettings } from '@fayz-ai/shop/types'\nimport type { Promotion } from '@fayz-ai/shop/rules'\nimport type { StorefrontTheme } from '../lib/theme'\nimport type { HomeConfig, NavLink, FooterConfig } from '../blocks/sections'\nimport type { StorefrontPagesConfig } from '../blocks/page-blocks'\nimport { normalizeLanguage, type Messages, type StorefrontLanguage } from '../locales/messages'\n// Type-only: slots.tsx imports the config hook at runtime, so a value import\n// here would close the cycle.\nimport type { StorefrontSlots } from '../extend/slots'\nimport type { StorefrontAuthConfig } from '../data/auth'\nimport type { StorefrontComponents } from '../extend/component-contracts'\nimport type { StorefrontReviewsConfig } from '../components/product/ProductReviews'\nimport type { CatalogFacetConfig } from '../components/collection/FiltersPanel'\n\nexport type StorefrontRouteKind =\n | 'home'\n | 'catalog'\n | 'product'\n | 'checkout'\n | 'account'\n | 'order'\n | 'custom'\n\nexport type StorefrontRouteParams = Record<string, string>\n\nexport interface StorefrontRouteComponentProps {\n path: string\n params: StorefrontRouteParams\n config: ResolvedStorefrontConfig\n}\n\n/**\n * Quanta moldura o fluxo aguenta.\n *\n * default a vitrine inteira — nav de marketing, rodapé, tudo.\n * minimal marca + busca + carrinho, e o resto da navegação recolhida no\n * menu. É o cabeçalho de um app de pedido: o cardápio JÁ é a tarefa,\n * e cinco links concorrendo com ela no topo são cinco saídas.\n * focused sem moldura nenhuma. Para o checkout, onde qualquer link é fuga.\n *\n * `minimal` existe porque os dois extremos estavam errados para o cardápio:\n * `default` compete com o pedido e `focused` levaria junto o carrinho e a busca\n * — e esconder a navegação INTEIRA num fluxo é o oposto do que a regra de\n * navegação persistente pede. Recolher não é esconder.\n */\nexport type StorefrontRouteChrome = 'default' | 'minimal' | 'focused'\n/**\n * 'delivery' (0094) é 'checkout' com a ordem das perguntas invertida: a loja\n * responde \"estou aberta?\" e \"onde você está?\" ANTES do carrinho, e só pergunta\n * quem é o comprador no fim. Herda tudo que 'checkout' liga — carrinho, contas,\n * pagamento — e acrescenta a rota /menu, o seletor entrega × retirada e o\n * agendamento.\n *\n * Um modo e não uma flag solta porque as quatro coisas andam juntas: uma loja\n * com horário mas sem cardápio, ou com retirada mas sem horário, não é um\n * estado que alguém queira operar.\n */\nexport type StorefrontCommerceMode = 'checkout' | 'catalog' | 'enquiry' | 'delivery'\nexport type StorefrontImageLoadingMode = 'fade' | 'none'\n\nexport interface StorefrontImageLoadingConfig {\n mode?: StorefrontImageLoadingMode\n durationMs?: number\n easing?: string\n blur?: boolean\n /**\n * Where the browser gets a photo at the size it draws it.\n *\n * 'supabase' — images in the store's own storage are served as\n * delivery-time variants (`…/render/image/public/…?width=…`): resized once\n * per size, cached at the CDN, WebP for browsers that take it, and offered\n * as a `srcset` so a card never downloads the gallery's 4000 px original.\n * Requires the storage project to have image transformations enabled (a\n * plan feature); an image hotlinked from anywhere else is left untouched.\n * 'none' (default) — every image is loaded as it was stored.\n */\n transform?: 'supabase' | 'none'\n}\n\nexport interface StorefrontRouteDefinition {\n /**\n * Stable identifier for generated-code diffs, QA reports, and route ownership.\n */\n id: string\n /**\n * Hash route pattern. Supports the same params as matchPath, e.g. '/checkout'\n * or '/collections/:slug'. Custom routes are matched before SDK defaults.\n */\n path: string\n /**\n * Intent label for agents and manifests. It does not change matching behavior.\n */\n kind?: StorefrontRouteKind\n /**\n * Shell chrome for the route. `focused` hides storefront nav/footer/cart\n * around high-intent flows such as checkout.\n */\n chrome?: StorefrontRouteChrome\n /**\n * App-owned screen/workflow that can still use storefront/shop primitives.\n */\n component: React.ComponentType<StorefrontRouteComponentProps>\n}\n\nexport interface StorefrontDiscountConfig {\n code: string\n percent: number\n title?: string\n}\n\nexport interface StorefrontEnquiryConfig {\n label?: string\n successMessage?: string\n subjectPrefix?: string\n email?: string\n whatsappUrl?: string\n requirePhone?: boolean\n}\n\nexport interface StorefrontConfig {\n /** Store display name (header, page title) */\n name: string\n /** Optional logo node; defaults to the store name */\n logo?: React.ReactNode\n /** ISO 4217 — default 'BRL' */\n currency?: string\n /** Intl locale for money/date formatting — default 'pt-BR' */\n locale?: string\n /**\n * Language of the SDK's own screens (cart, checkout, delivery): 'pt-BR',\n * 'en' or 'es'. Default 'pt-BR'. Separate from `locale`, which formats money.\n * A host that knows the visitor's language per request passes it to\n * StorefrontConfigHost as `buyer.language` instead.\n */\n language?: string\n /** Per-store copy overrides, by language and message key. */\n messages?: Partial<Record<StorefrontLanguage, Partial<Messages>>>\n /**\n * ISO2 countries the store ships to. Default ['BR']. With more than one, the\n * buyer picks (or is detected into) one, and the address form, validation\n * and payment methods follow that country.\n */\n countries?: readonly string[]\n /** The country assumed before the buyer says otherwise. Default: countries[0]. */\n defaultCountry?: string\n /** Visual identity: colors, fonts, radius, header/card personality */\n theme?: StorefrontTheme\n /** Checkout-first default, catalog-only browsing, or product enquiry flow. */\n commerceMode?: StorefrontCommerceMode\n /** Promo message above the header (e.g. 'FRETE GRÁTIS ACIMA DE R$ 300') */\n announcement?: string\n /**\n * How pages are addressed when this store is served.\n *\n * `'hash'` (the default) needs no server configuration and is how every\n * shipped store works today. `'history'` gives each page a real URL, which is\n * what makes it indexable, shareable with its own link preview, and\n * prerenderable — and requires the host to serve the app shell for unknown\n * paths, or a deep link 404s before the app ever runs.\n */\n routing?: 'hash' | 'history'\n /**\n * Home page blueprint. When set, `/` renders it and the catalog moves to /catalog.\n *\n * Still fully supported — five of seven live stores write it. `pages.home` is\n * the same thing with room for the other routes; this stays as the short form.\n */\n home?: HomeConfig\n /**\n * Pages composed from blocks.\n *\n * `catalog` and `product` compose AROUND the native body block rather than\n * replacing it, so a store adds content to those pages without taking over\n * their maintenance. Omitting a page renders the SDK default — adopting this\n * field changes nothing until something is added.\n */\n pages?: StorefrontPagesConfig\n /**\n * Blocks grafted into named positions inside SDK pages.\n *\n * This is the rung between \"configure a section\" and \"rewrite the page\". If\n * you are about to reimplement an SDK page to add one thing to it, look for\n * the slot first — and if the position you need is missing, that is a gap in\n * this list rather than a reason to fork. `listSlots()` enumerates them.\n */\n slots?: StorefrontSlots\n /** Header nav links — defaults derived from home/catalog routing */\n nav?: NavLink[]\n /** Footer content (about text, contact, social) */\n footer?: FooterConfig\n /** Preferred backend descriptor for manifest/scaffold metadata. */\n backend?: { provider?: 'mock' | 'fayz-api' | 'fayz-shop' | 'custom'; url?: string }\n /** @deprecated Use backend/provider adapters. Storefront no longer creates Supabase clients. */\n supabaseUrl?: string\n /** @deprecated Use backend/provider adapters. Storefront no longer creates Supabase clients. */\n supabaseAnonKey?: string\n /** Explicit provider override (tests, custom backends) */\n provider?: ShopProvider\n /**\n * Product analytics. With `posthog` set, every page view, click, cart change\n * and checkout step is reported to that project, grouped under `storeId`.\n */\n analytics?: StorefrontAnalyticsConfig\n /** Per-store mock catalog (products/categories/discounts) for mock mode */\n catalog?: MockShopSeed\n /**\n * Custom entity declarations (spine M4), keyed by entity key. Registered\n * through defineEntity at runtime init, so one config field yields the\n * record schema, the storage descriptor, the generated RLS, the entity.*\n * loaders and the admin form.\n */\n entities?: Record<string, EntityDeclarationInput>\n /** Store-level discount codes available regardless of provider backend. */\n discounts?: StorefrontDiscountConfig[]\n /**\n * Rule-engine promotions (spine M6) — the serializable Promotion shape:\n * eligibility rules + application method, pure data. Rides in the Store\n * Document's `promotions` section; the mock provider evaluates them with\n * the reference evaluator, a live backend re-evaluates server-side. A\n * `{code, percent}` entry in `discounts` is the same thing in shorthand.\n */\n promotions?: Promotion[]\n /**\n * Institutional/legal page content (privacy, terms, returns). Plain text —\n * blank lines separate paragraphs. Unset pages render a placeholder so the\n * routes (and footer links) exist even before the store writes its policy.\n */\n legal?: { privacy?: string; terms?: string; returns?: string }\n /** Customer auth — same AuthAdapter contract as createSaasApp. Default: mock. */\n auth?: StorefrontAuthConfig\n /** Shipping pricing — default { flatRate: 0 } */\n shipping?: { flatRate?: number; freeAbove?: number }\n /**\n * Modo delivery (0094). Ignorado fora de `commerceMode: 'delivery'`.\n *\n * O que NÃO mora aqui, de propósito: horário de funcionamento, endereço de\n * retirada e prazo de preparo. Esses vêm do banco, porque uma lojista precisa\n * mudar o horário num feriado sem esperar um deploy — e um horário em arquivo\n * de configuração é exatamente isso.\n */\n delivery?: StorefrontDeliveryConfig\n /**\n * The A/B tests this store runs, by PostHog flag key. This is the source of\n * truth for who sees what: the edge buckets each visitor locally with\n * PostHog's hashing, before render, and any setting typed `Experimental<…>`,\n * any `experiment` block or any `useExperiment(key)` call reads it. The\n * PostHog Experiment on the same key reads the results. A key not declared,\n * or not `status: 'running'`, is always 'control'. See\n * docs/storefront/EXPERIMENTS.md.\n */\n experiments?: Record<string, StorefrontExperiment>\n /**\n * Payment behavior. v1 default 'mock' instantly marks orders paid with NO\n * real charge (demo). M4 sets 'pix-mercadopago' so orders stay pending until\n * a real payment webhook confirms settlement.\n */\n payments?: {\n /**\n * 'gateway' means a real PSP is connected: the checkout opens a charge and\n * the order waits for it. WHICH provider is deliberately not spelled here —\n * that lives in the store's connection row, server side. A storefront that\n * named the acquirer would need a redeploy to change acquirer.\n */\n mode?: 'mock' | 'pix-mercadopago' | 'gateway'\n /**\n * Which methods the checkout offers. Declaring them is what lets the order\n * record how the buyer intends to pay instead of assuming 'credit_card',\n * which is what it did while the card form was a simulation.\n */\n methods?: readonly PaymentMethodKind[]\n /**\n * Published payment terms, shown on the card and the PDP. These are the two\n * lines every Brazilian storefront carries and the SDK had no model for:\n * the Pix discount and the interest-free instalment.\n *\n * Display only — they describe what the merchant advertises, not a charge\n * the checkout computes. A product may override the Pix price per SKU via\n * `metadata.pixPrice`.\n */\n terms?: {\n /** e.g. 5 → \"5% de desconto no Pix\". */\n pixDiscountPercent?: number\n /** Longest interest-free plan offered. */\n maxInstallments?: number\n /** Don't split below this per-instalment value. Default 10. */\n minInstallmentValue?: number\n }\n }\n /**\n * The PDP specification table renders scalar `product.metadata` alongside\n * SKU/category/weight. Stores also keep bookkeeping in metadata; `exclude`\n * hides those keys and `labels` names the rest, so a store doesn't have to\n * fork ProductSpecs to stop showing an internal field.\n */\n productSpecs?: { exclude?: readonly string[]; labels?: Readonly<Record<string, string>> }\n /** Product reviews shown on the PDP. See ./components/product/ProductReviews. */\n reviews?: StorefrontReviewsConfig\n /**\n * Extra catalog refinements over `product.metadata`, rendered in the filters\n * panel and reflected in `?<key>=<value>`. This is how a store adds its own\n * discovery axis — colour, purpose, brand — without forking FiltersPanel.\n */\n catalogFacets?: readonly CatalogFacetConfig[]\n /** Product enquiry behavior for catalog/enquiry stores. */\n enquiry?: StorefrontEnquiryConfig\n /** Feature toggles — defaults depend on commerceMode. */\n features?: { discounts?: boolean; accounts?: boolean; cart?: boolean; checkout?: boolean }\n /** Global storefront image reveal behavior. Default is a soft fade. */\n imageLoading?: StorefrontImageLoadingConfig\n /** Header search behaviour. Omit for the inline live-filter. */\n search?: StorefrontSearchConfig\n /**\n * The merchant's own commercial policy, read from the store's settings row at\n * boot (see ./store-policy). NOT authored here: an app declares its defaults\n * through the fields above, and this arrives from the database to override the\n * ones the merchant actually decided.\n *\n * Present so components can read the decisions that have no equivalent\n * config field — whether an account is required, which optional checkout\n * fields to show. The ones that DO have a field (currency, payment methods)\n * are folded into those fields instead, so nothing has to read both.\n */\n policy?: StoreSettings\n /** Code-level component replacements. Kept out of serialized manifests. */\n components?: StorefrontComponents\n /** Code-level route overrides/custom routes. Kept out of serialized manifests. */\n routes?: readonly StorefrontRouteDefinition[]\n}\n\n/** See `StorefrontDeliveryConfig.coverSize`. */\nexport type StorefrontCoverSize = 'full' | 'compact'\n\n/** Entrega ou retirada, do ponto de vista da vitrine. */\nexport type FulfillmentMode = 'delivery' | 'pickup'\n\nexport interface StorefrontDeliveryConfig {\n /** Onde o cardápio mora. Default '/menu'. */\n menuPath?: string\n /**\n * A capa da loja — a foto que ocupa o topo do cardápio.\n *\n * É a única imagem do modo que NÃO vem do catálogo: capa é identidade da\n * loja, não de um produto. Sem ela o cabeçalho continua existindo, só que\n * sobre a cor da marca — o cardápio nunca depende de haver foto.\n */\n coverImage?: string\n /** O logo, no quadrado sobre a capa. Cai para a inicial do nome. */\n logoImage?: string\n /**\n * How much of the first screen the cover takes. 'full' (default) is the\n * cover as a store styles it; 'compact' shrinks it to a band so the first\n * dishes — photo, price, add button — are visible without scrolling on a\n * phone. The cover carries `data-cover-size`, so a store's own cover CSS can\n * follow it. Bindable to an experiment:\n * `{ experiment: 'menu-cover-compact', variants: { control: 'full', compact: 'compact' } }`.\n */\n coverSize?: Experimental<StorefrontCoverSize>\n /** \"Rio de Janeiro, RJ\" — a linha sob o nome. */\n locality?: string\n /**\n * Os slugs que sobem para \"Destaques\", NA ORDEM em que a lojista os quer.\n *\n * Curadoria é decisão de quem vende, e não há dado na vitrine que a\n * substitua: \"mais pedido\" precisaria de contagem de pedidos por produto,\n * que não existe aqui. Sem esta lista o cardápio cai para o que está em\n * promoção — um fato cadastrado, não um palpite — e, sem promoções, a seção\n * simplesmente não aparece.\n */\n highlightSlugs?: readonly string[]\n /** Modos oferecidos, NA ORDEM em que o seletor os mostra. Default ['delivery']. */\n fulfillmentModes?: readonly FulfillmentMode[]\n /** Oferecer \"Agendar\". Default false — e a loja ainda precisa concordar. */\n scheduling?: boolean\n /**\n * O balcão, para os pedidos de retirada.\n *\n * ESTÁ AQUI POR UMA LIMITAÇÃO CONHECIDA, e não porque este seja o lugar certo.\n * O lugar certo é `plg_shop_settings.pickup_address` (0094), para a lojista\n * mudar o endereço sem deploy — mas a vitrine lê configuração por\n * `shop_store_settings()`, uma RPC que devolve um SUBCONJUNTO fixo de colunas\n * e não inclui esta. Estender a RPC é uma migration, e a 0094 já está fechada.\n *\n * Então: a vitrine PREFERE o que vier do banco e cai para cá quando não vier.\n * No dia em que a RPC ganhar a coluna, esta chave para de ser lida sozinha,\n * sem tocar em app nenhum.\n */\n pickupAddress?: {\n postalCode: string\n street: string\n number?: string\n complement?: string\n district?: string\n city: string\n state: string\n }\n}\n\nexport interface ResolvedStorefrontConfig extends StorefrontConfig {\n currency: string\n locale: string\n language: StorefrontLanguage\n countries: readonly string[]\n defaultCountry: string\n /** The host's per-request country hint (e.g. the CDN's geo header), if any. */\n countryHint?: string\n /** The market the buyer is in (0116), when the store has markets. Its\n * currency, locale and shipping are already applied to this config. */\n market?: ShopMarket\n shipping: { flatRate: number; freeAbove?: number }\n payments: {\n mode: NonNullable<NonNullable<StorefrontConfig['payments']>['mode']>\n methods: readonly PaymentMethodKind[]\n terms?: NonNullable<StorefrontConfig['payments']>['terms']\n }\n commerceMode: StorefrontCommerceMode\n /** Presente somente no modo delivery — a rota /menu testa por este objeto. */\n delivery?: {\n menuPath: string\n coverImage?: string\n logoImage?: string\n coverSize?: StorefrontDeliveryConfig['coverSize']\n locality?: string\n highlightSlugs?: readonly string[]\n fulfillmentModes: readonly FulfillmentMode[]\n scheduling: boolean\n pickupAddress?: StorefrontDeliveryConfig['pickupAddress']\n /** From the store's Delivery settings (shop 0130), when it set them. */\n etaMinutes?: number\n /** The minimum order on the items' subtotal; the server refuses below it. */\n minOrderTotal?: number\n /** The house switched its delivery off (shop 0131): no order until it is back. */\n paused?: boolean\n }\n enquiry: Required<Pick<StorefrontEnquiryConfig, 'label' | 'successMessage' | 'subjectPrefix'>> &\n Omit<StorefrontEnquiryConfig, 'label' | 'successMessage' | 'subjectPrefix'>\n features: { discounts: boolean; accounts: boolean; cart: boolean; checkout: boolean }\n imageLoading: Required<StorefrontImageLoadingConfig>\n /** Where the full product list lives ('/' without a home page, '/catalog' with one, the menu in delivery mode) */\n catalogPath: string\n nav: NavLink[]\n /** `pages` with the legacy `home` short form folded in — always read this one. */\n pages: StorefrontPagesConfig\n search: Required<Omit<StorefrontSearchConfig, 'renderSuggestion'>> &\n Pick<StorefrontSearchConfig, 'renderSuggestion'>\n}\n\n/**\n * Header search. Defaults reproduce the inline live-filter the storefront has\n * always had, so turning this on is opt-in; every label and limit is a knob\n * because \"what a search feels like\" is a per-store decision, not the SDK's.\n */\nexport interface StorefrontSearchConfig {\n /**\n * 'inline' filters the catalogue as you type (the original behaviour).\n * 'overlay' dims the page and shows suggestions under the field, with a\n * link through to the full result page.\n */\n mode?: 'inline' | 'overlay'\n placeholder?: string\n /** Where \"see all results\" lands, carrying `?q=`. */\n resultsPath?: string\n /** Suggestions shown under the field before the shopper commits. */\n suggestionsLimit?: number\n /** Characters before anything is queried — 1 matches everything, which is noise. */\n minChars?: number\n ctaLabel?: string\n emptyLabel?: string\n /** Full control of a suggestion row when the default card is wrong for the store. */\n renderSuggestion?: (product: Product) => ReactNode\n}\n\n/** Upper-cased, de-duplicated, never empty; the default is always one of them. */\nfunction resolveCountries(config: StorefrontConfig): { countries: string[]; defaultCountry: string } {\n const countries = [...new Set((config.countries ?? []).map((c) => c.trim().toUpperCase()).filter(Boolean))]\n if (countries.length === 0) countries.push('BR')\n const wanted = config.defaultCountry?.trim().toUpperCase()\n return { countries, defaultCountry: wanted && countries.includes(wanted) ? wanted : countries[0]! }\n}\n\nexport function resolveConfig(config: StorefrontConfig): ResolvedStorefrontConfig {\n // `home` and `pages.home` are the same page written two ways. Collapse them\n // here so nothing downstream has to check both, and so the legacy short form\n // keeps deciding where the catalog lives exactly as it did before.\n const homePage = config.pages?.home ?? (config.home ? { blocks: config.home.sections } : undefined)\n const commerceMode = config.commerceMode ?? 'checkout'\n // In a delivery store the menu IS the catalogue: «Continuar comprando» and\n // «Voltar ao catálogo» on a product page sent buyers to the old e-commerce\n // shelf at /catalog instead of the menu they order from.\n const catalogPath = commerceMode === 'delivery'\n ? (config.delivery?.menuPath ?? '/menu')\n : homePage ? '/catalog' : '/'\n // 'delivery' compra tudo que 'checkout' liga. Escrever `=== 'checkout'` em\n // cada feature abaixo teria desligado carrinho e conta no modo novo — o modo\n // que mais precisa dos dois.\n const checkoutEnabled = commerceMode === 'checkout' || commerceMode === 'delivery'\n return {\n ...config,\n pages: { ...config.pages, ...(homePage ? { home: homePage } : {}) },\n currency: config.currency ?? 'BRL',\n locale: config.locale ?? 'pt-BR',\n language: normalizeLanguage(config.language) ?? 'pt-BR',\n ...resolveCountries(config),\n shipping: { flatRate: config.shipping?.flatRate ?? 0, freeAbove: config.shipping?.freeAbove },\n payments: {\n mode: config.payments?.mode ?? 'mock',\n methods: config.payments?.methods?.length ? config.payments.methods : ['pix', 'credit_card', 'cash'],\n // Rebuilding `payments` key by key silently dropped `terms`, so the Pix\n // price and the instalment line never reached a component even when the\n // store had configured them.\n terms: config.payments?.terms,\n },\n commerceMode,\n // Só existe no modo delivery. Fora dele o objeto inteiro é undefined, e é\n // isso que a rota /menu consulta para decidir se existe.\n delivery: commerceMode === 'delivery'\n ? {\n menuPath: config.delivery?.menuPath ?? '/menu',\n coverImage: config.delivery?.coverImage,\n logoImage: config.delivery?.logoImage,\n coverSize: config.delivery?.coverSize,\n locality: config.delivery?.locality,\n highlightSlugs: config.delivery?.highlightSlugs,\n // A ORDEM é a do seletor na tela. Um Set aqui perderia isso.\n fulfillmentModes: config.delivery?.fulfillmentModes?.length\n ? config.delivery.fulfillmentModes\n : (['delivery'] as const satisfies readonly FulfillmentMode[]).slice(),\n // Agendamento é opt-in duas vezes: aqui e na loja (0094 devolve zero\n // slots quando scheduling_enabled é falso). A tela só oferece quando\n // as duas concordam.\n scheduling: config.delivery?.scheduling ?? false,\n pickupAddress: config.delivery?.pickupAddress,\n }\n : undefined,\n enquiry: {\n label: config.enquiry?.label ?? 'Contact me',\n successMessage: config.enquiry?.successMessage ?? 'Thanks. We received your enquiry.',\n subjectPrefix: config.enquiry?.subjectPrefix ?? 'Product enquiry',\n email: config.enquiry?.email,\n whatsappUrl: config.enquiry?.whatsappUrl,\n requirePhone: config.enquiry?.requirePhone,\n },\n features: {\n // Auto-enable the coupon UI when the store actually ships discount codes\n // (config.discounts, a seeded catalog, or a rule-engine promotion with a\n // code — M6), unless explicitly overridden — otherwise a store can\n // advertise a coupon with no field to enter it, which is exactly the\n // figurinhas pilot failure this milestone exists to end.\n discounts:\n config.features?.discounts ??\n Boolean(\n config.discounts?.length ||\n config.catalog?.discounts?.length ||\n config.promotions?.some((p) => p.code) ||\n config.catalog?.promotions?.some((p) => p.code),\n ),\n accounts: config.features?.accounts ?? checkoutEnabled,\n cart: config.features?.cart ?? checkoutEnabled,\n checkout: config.features?.checkout ?? checkoutEnabled,\n },\n imageLoading: {\n mode: config.imageLoading?.mode ?? 'fade',\n durationMs: config.imageLoading?.durationMs ?? 420,\n easing: config.imageLoading?.easing ?? 'cubic-bezier(0.22, 1, 0.36, 1)',\n blur: config.imageLoading?.blur ?? true,\n transform: config.imageLoading?.transform ?? 'none',\n },\n catalogPath,\n search: {\n mode: config.search?.mode ?? 'inline',\n placeholder: config.search?.placeholder ?? 'Buscar produtos...',\n resultsPath: config.search?.resultsPath ?? '/search',\n suggestionsLimit: config.search?.suggestionsLimit ?? 4,\n minChars: config.search?.minChars ?? 2,\n ctaLabel: config.search?.ctaLabel ?? 'Ver todos resultados',\n emptyLabel: config.search?.emptyLabel ?? 'Nada encontrado para',\n renderSuggestion: config.search?.renderSuggestion,\n },\n nav:\n config.nav ??\n (homePage\n ? [\n { label: 'Início', to: '/' },\n { label: 'Loja', to: '/catalog' },\n ]\n : [{ label: 'Loja', to: '/' }]),\n }\n}\n\nconst StorefrontConfigContext = createContext<ResolvedStorefrontConfig | null>(null)\n\nexport const StorefrontConfigProvider = StorefrontConfigContext.Provider\n\nexport function useStorefrontConfig(): ResolvedStorefrontConfig {\n const ctx = useContext(StorefrontConfigContext)\n if (!ctx) throw new Error('useStorefrontConfig must be used inside createStorefrontApp')\n return ctx\n}\n\nexport function useStorefrontConfigOptional(): ResolvedStorefrontConfig | null {\n return useContext(StorefrontConfigContext)\n}\n\nexport function getStorefrontComponents(config: ResolvedStorefrontConfig): StorefrontComponents {\n return config.components ?? {}\n}\n","import React, { createContext, useContext, useEffect, useRef, useSyncExternalStore } from 'react'\nimport { defaultRouterAdapter, staticRouterAdapter, type RouterAdapter } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Storefront routing.\n//\n// The storefront owns a handful of flat routes, so it resolves them itself\n// rather than depending on a router package — that dependency is what created\n// the duplicate-singleton hazards under source-alias dev. What it does NOT own\n// is the *addressing scheme*: whether a page lives at `#/product/x` or at\n// `/product/x`, and who controls history.\n//\n// That is injected as a RouterAdapter, which is what lets the same components\n// render under a hash SPA, a real-URL SPA, and a static render. It matters\n// beyond convenience: a fragment is never sent to the server, so a\n// hash-addressed page has no URL of its own to index, share or prerender —\n// `renderStore` can produce perfect HTML for a page that no crawler can reach\n// as a distinct address.\n//\n// Hash remains the default, so an app that never mentions routing behaves\n// exactly as it does today.\n// ---------------------------------------------------------------------------\n\nconst RouterAdapterContext = createContext<RouterAdapter | null>(null)\n\nexport const StorefrontRouterProvider = RouterAdapterContext.Provider\n\n/**\n * `navigateTo` is a module function called from event handlers. Handlers only\n * run in a browser, after the provider has mounted, so a module-level reference\n * to the active adapter is safe here in a way it would not be during render.\n * Render paths use `useNavigate()` / `useRouterAdapter()` so a static render\n * reads the adapter for the path it is rendering, not this process-wide one.\n */\nlet _activeAdapter: RouterAdapter | null = null\nlet _fallback: RouterAdapter | null = null\n\n/**\n * One shared fallback instance, not one per component: an adapter owns its\n * subscriber list, so N instances would mean N event bindings and — for history\n * addressing — navigations that only notify their own subscribers. Constructing\n * one touches no browser API; only its methods do.\n */\nfunction fallbackAdapter(): RouterAdapter {\n if (!_fallback) _fallback = defaultRouterAdapter('hash')\n return _fallback\n}\n\nexport function useRouterAdapter(): RouterAdapter {\n const injected = useContext(RouterAdapterContext)\n const adapter = injected ?? fallbackAdapter()\n useEffect(() => {\n // Only an INJECTED adapter becomes the active one. The fallback is what a\n // read outside any provider gets — and `StorefrontShell` itself makes such\n // a read, for the ambient adapter, before installing the router it was\n // given. Being the parent, its effect runs after every child's; if it\n // wrote the fallback here, a store served by a host router (TanStack,\n // history) would have every Link go through the host and every\n // `navigateTo` from an event handler go through hash addressing. That is\n // exactly what a header search did on the first SSR store: /#/catalog.\n if (injected) _activeAdapter = injected\n }, [injected])\n return adapter\n}\n\n/** The current in-app path, re-rendering on every navigation. */\nexport function useRoutePath(): string {\n const adapter = useRouterAdapter()\n return useSyncExternalStore(\n (onChange) => adapter.onPathChange(onChange),\n () => adapter.getCurrentPath() || '/',\n () => adapter.getCurrentPath() || '/',\n )\n}\n\n/** Scroll to top on route change. Separate from path tracking so a host that\n * manages its own scroll restoration can simply not call it. */\nexport function useScrollToTopOnNavigate(path: string): void {\n const mounted = useRef(false)\n useEffect(() => {\n // Not on the first pass. That one is not a navigation — it is the store\n // arriving, either as the server's HTML being hydrated or as a reload the\n // browser has already positioned. Scrolling there takes the page away from\n // a shopper who started reading during hydration, and on a host with its\n // own scroll restoration it races that host's restore.\n if (!mounted.current) {\n mounted.current = true\n return\n }\n if (typeof window !== 'undefined') window.scrollTo(0, 0)\n }, [path])\n}\n\nexport function useNavigate(): (to: string) => void {\n const adapter = useRouterAdapter()\n return adapter.navigate.bind(adapter)\n}\n\n/** @deprecated Use `useRoutePath()`. Kept so existing imports keep compiling. */\nexport const useHashPath = useRoutePath\n\n/** Imperative navigation from an event handler. See `_activeAdapter` above. */\nexport function navigateTo(to: string): void {\n ;(_activeAdapter ?? fallbackAdapter()).navigate(to)\n}\n\n/**\n * The adapter a shell should install for a given render.\n *\n * A `path` override means a static render (`renderStore`, the preview server, a\n * node test): there is no history to own, but anchors must still carry real,\n * crawlable hrefs — which is the whole point of rendering headlessly.\n */\nexport function shellRouterAdapter(pathOverride: string | undefined, live: RouterAdapter): RouterAdapter {\n if (pathOverride == null) return live\n // Inherit the ambient scheme's href writer: a store served as a hash SPA must\n // still emit `#/…` links when rendered headlessly, or `renderStore` would\n // describe a page whose links do not exist. Pass an explicit `router` to the\n // shell to render a store served at real URLs.\n return staticRouterAdapter(pathOverride, { href: (to) => live.href(to) })\n}\n\n/** Match '/product/:slug' against '/product/leather-backpack' → { slug: 'leather-backpack' } */\nexport function matchPath(pattern: string, path: string): Record<string, string> | null {\n const cleanPath = (path.split('?')[0] ?? '').replace(/\\/+$/, '') || '/'\n const patternParts = pattern.split('/').filter(Boolean)\n const pathParts = cleanPath.split('/').filter(Boolean)\n if (patternParts.length !== pathParts.length) return null\n const params: Record<string, string> = {}\n for (let i = 0; i < patternParts.length; i++) {\n const pat = patternParts[i]!\n const part = pathParts[i]!\n if (pat.startsWith(':')) params[pat.slice(1)] = decodeURIComponent(part)\n else if (pat !== part) return null\n }\n return params\n}\n\nexport interface LinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\n to: string\n}\n\n/**\n * A real anchor, always — middle-click, cmd-click, \"copy link address\" and\n * Playwright all keep working, and a crawler sees a real href.\n *\n * Under hash addressing the browser handles the fragment itself, so the click\n * is left alone. Under real-URL addressing a plain left-click must be\n * intercepted or the browser would do a full document load; modified clicks and\n * explicit targets are still handed to the browser.\n */\nexport function Link({ to, children, onClick, target, ...rest }: LinkProps) {\n const adapter = useRouterAdapter()\n\n const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {\n onClick?.(event)\n if (!adapter.interceptsLinkClicks) return\n if (event.defaultPrevented) return\n if (target && target !== '_self') return\n if (event.button !== 0) return\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return\n event.preventDefault()\n adapter.navigate(to)\n }\n\n return React.createElement(\n 'a',\n { href: adapter.href(to), onClick: handleClick, target, ...rest },\n children,\n )\n}\n","import type { BlockNode } from '@fayz-ai/core'\nimport type { PageDataEntry, PageDataNeed } from '../blocks/page-data'\n\n// Effects do not run under `renderToStaticMarkup`, so a headless render would\n// produce loading states with no title. Instead of reimplementing routing on the\n// server — a second mechanism to keep in sync — components REPORT to the pass\n// rendering them, and the renderer re-renders with the answers seeded.\n//\n// Module-scoped rather than a React context because `renderToStaticMarkup` is\n// synchronous: there is exactly one pass in flight, and a context would force\n// every reporting call site to be a hook (`PageDataScope`'s useState initialiser\n// cannot be one). Null in every browser render.\n\n/**\n * What a route declared for the document head during a static render.\n *\n * Title and description are the client-rendered baseline. The rest is what a\n * page needs to be worth anything once it HAS its own URL: a canonical so the\n * engine knows which address is authoritative, an image and type so a share in\n * a messaging app is not a grey rectangle, and JSON-LD so a product is eligible\n * for a rich result instead of a plain blue link.\n */\nexport interface StaticHeadInput {\n title?: string\n description?: string | null\n /** Absolute URL. A relative canonical is ignored by search engines. */\n canonical?: string\n /** Absolute URL of the image a share should show. */\n image?: string\n /** OpenGraph type — 'website', 'article', 'product'. */\n type?: string\n /** schema.org objects, emitted as <script type=\"application/ld+json\">. */\n jsonLd?: Array<Record<string, unknown>>\n}\n\nexport interface StaticRenderPass {\n /** Called once per scope, so a page plus its slots report the whole rendered\n * composition — including forced-layout repairs (I7). */\n tree(nodes: readonly BlockNode[]): void\n needs(needs: readonly PageDataNeed[]): void\n head(input: StaticHeadInput): void\n /** Resolved by an earlier pass, keyed by `dataNeedKey`. A key present here is\n * served instead of being fetched. */\n entries: Readonly<Record<string, PageDataEntry>>\n /**\n * Absolute origin the rendered page will be served from, when the caller\n * knows it. Pages need it to declare a canonical or an og:image, and a static\n * render has no `window.location` to infer one from — so it travels with the\n * pass rather than being guessed per page.\n */\n origin?: string\n}\n\nlet active: StaticRenderPass | null = null\n\n/** The pass currently rendering, or null — which is every browser render. */\nexport function currentStaticRenderPass(): StaticRenderPass | null {\n return active\n}\n\n/** Run one synchronous render with `pass` installed. Nesting restores the\n * previous pass, so a renderer inside a renderer cannot strand the global. */\nexport function withStaticRenderPass<T>(pass: StaticRenderPass, render: () => T): T {\n const previous = active\n active = pass\n try {\n return render()\n } finally {\n active = previous\n }\n}\n","import { errorMessage } from '@fayz-ai/core'\nimport React, { createContext, useContext, useEffect, useMemo, useState } from 'react'\nimport {\n dataNeedKey,\n defaultPropsFromSettings,\n getBlockErrorVisibility,\n getBlockMeta,\n isLoaderParamRef,\n isLoaderPropRef,\n resolveLoader,\n} from '@fayz-ai/core'\nimport type { BlockDataNeed, BlockNode } from '@fayz-ai/core'\nimport { getShopProvider } from '@fayz-ai/shop/runtime'\nimport { currentStaticRenderPass } from '../app/static-render'\n\n// ---------------------------------------------------------------------------\n// Page data — declared needs, resolved once per page (spine M3, I11).\n//\n// A block never fetches for itself. Its meta (or its document instance)\n// declares named needs against registered loaders; the page walks its repaired\n// tree, collects them, DEDUPES identical (loader, params) pairs, resolves them\n// concurrently through the ShopProvider port, and hands the results down by\n// context. Two product rails asking the same question cost one provider call —\n// and, because the needs are known before render, a server can resolve the\n// same set ahead of time, which is the SSR prerequisite L4 calls out.\n//\n// Failure semantics follow the M2 error-boundary contract (I7): one failing\n// loader marks ONE entry as errored and never touches the rest of the page.\n// A block whose data errored renders null for shoppers and an error card in\n// dev/admin (BlockDataError), exactly like a block that crashed.\n// ---------------------------------------------------------------------------\n\nexport type PageDataStatus = 'idle' | 'loading' | 'ready' | 'error'\n\nexport interface PageDataEntry {\n status: 'loading' | 'ready' | 'error'\n data?: unknown\n error?: string\n}\n\n/** One collected, binding-resolved, deduped need. */\nexport interface PageDataNeed {\n key: string\n loader: string\n params: Record<string, unknown>\n}\n\n// --- Binding resolution -------------------------------------------------------\n\n/**\n * Resolve a declared need's param bindings against the page's route params and\n * the declaring block's props (setting defaults filled in, so the declaration\n * and the rendered block agree on unset props). A binding that resolves to\n * `undefined` drops its param — dataNeedKey drops undefined anyway, so the\n * declared need and a hook asking with explicit `undefined`s share a key.\n */\nexport function resolveDataParams(\n need: BlockDataNeed,\n context: { params: Record<string, string>; props: Record<string, unknown> },\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [name, value] of Object.entries(need.params ?? {})) {\n let resolved: unknown = value\n if (isLoaderParamRef(value)) resolved = context.params[value.$param]\n else if (isLoaderPropRef(value)) resolved = context.props[value.$prop]\n if (resolved !== undefined) out[name] = resolved\n }\n return out\n}\n\n/** A block's effective needs: the meta declaration with the document\n * instance's `data` merged over it by need name. */\nfunction needsForNode(node: BlockNode): Record<string, BlockDataNeed> {\n const meta = getBlockMeta(node.type)\n return { ...meta?.data, ...node.data }\n}\n\n/**\n * Walk a block tree (children included) and collect every declared need,\n * bindings resolved, deduped by canonical (loader, params) key.\n */\nexport function collectDataNeeds(\n nodes: readonly BlockNode[],\n routeParams: Record<string, string> = {},\n): PageDataNeed[] {\n const found = new Map<string, PageDataNeed>()\n const visit = (node: BlockNode): void => {\n const meta = getBlockMeta(node.type)\n const needs = needsForNode(node)\n if (Object.keys(needs).length > 0) {\n const props = { ...defaultPropsFromSettings(meta?.settings), ...node.props }\n for (const need of Object.values(needs)) {\n if (!need || typeof need.loader !== 'string' || !need.loader) continue\n const params = resolveDataParams(need, { params: routeParams, props })\n const key = dataNeedKey(need.loader, params)\n if (!found.has(key)) found.set(key, { key, loader: need.loader, params })\n }\n }\n for (const child of node.children ?? []) visit(child)\n }\n for (const node of nodes) visit(node)\n return [...found.values()]\n}\n\n// --- Resolution ---------------------------------------------------------------\n\n/** Resolve ONE need through the provider port. Never throws: an unknown\n * loader or a failing read becomes an 'error' entry for that need alone. */\nexport async function resolvePageDataNeed(need: Pick<PageDataNeed, 'loader' | 'params'>): Promise<PageDataEntry> {\n try {\n const impl = resolveLoader(need.loader)\n const data = await impl(need.params, { shop: getShopProvider() })\n return { status: 'ready', data }\n } catch (err) {\n const message = errorMessage(err)\n // Always log — a store hitting this in production is better off with the\n // reason in the console than without it (same policy as BlockErrorBoundary).\n console.error(`[storefront] loader \"${need.loader}\" failed:`, err)\n return { status: 'error', error: message }\n }\n}\n\n/** Resolve a set of needs concurrently, isolated per need. Test seam and the\n * future server-side entry point — the scope component uses the same calls. */\nexport async function resolvePageData(\n needs: readonly PageDataNeed[],\n): Promise<Record<string, PageDataEntry>> {\n const settled = await Promise.all(\n needs.map(async (need) => [need.key, await resolvePageDataNeed(need)] as const),\n )\n return Object.fromEntries(settled)\n}\n\n// --- The scope ----------------------------------------------------------------\n\ninterface PageDataContextValue {\n entries: Record<string, PageDataEntry>\n /** The route params this scope resolved `$param` bindings against — the same\n * ones a consuming block must use, or its key would diverge. */\n params: Record<string, string>\n}\n\nconst PageDataContext = createContext<PageDataContextValue | null>(null)\n\nexport interface PageDataScopeProps {\n nodes: readonly BlockNode[]\n /** Route params the tree's `$param` bindings resolve against. */\n params?: Record<string, string>\n /**\n * Pre-resolved entries, keyed by dataNeedKey — the server-side/static-render\n * seam (L4): `resolvePageData(collectDataNeeds(nodes))` ahead of render,\n * then hand the results in. Keys already 'ready' here are never re-fetched;\n * anything missing resolves client-side as usual.\n *\n * Live, not mount-only: a host whose shell outlives the page (every real\n * one — the shell must not remount on navigation) hands in a NEW object\n * for each page it loads, and a child scope mounting in that same commit\n * sees it. Pass a stable reference per page (the loader's result), not a\n * literal built in render.\n */\n initial?: Record<string, PageDataEntry>\n children: React.ReactNode\n}\n\n/**\n * Collects and resolves the data needs of one block tree, and provides the\n * results. Scopes nest (a slot inside a page): a child scope reuses every\n * entry an ancestor already resolved and only fetches its own remainder, so\n * dedupe holds across the whole rendered page, not per tree.\n */\nexport function PageDataScope({ nodes, params, initial, children }: PageDataScopeProps) {\n const parent = useContext(PageDataContext)\n const routeParams = useMemo(() => params ?? parent?.params ?? {}, [params, parent])\n const needs = useMemo(() => collectDataNeeds(nodes, routeParams), [nodes, routeParams])\n const own = useMemo(\n () => needs.filter((need) => !parent || !(need.key in parent.entries)),\n [needs, parent],\n )\n // A static render (renderStore) has no effects, so this scope reports what it\n // renders and what it would fetch, and reads back anything an earlier pass\n // already resolved. Null in the browser.\n const staticPass = currentStaticRenderPass()\n if (staticPass) {\n staticPass.tree(nodes)\n staticPass.needs(own)\n }\n\n // Seeded synchronously so the first render already shows 'loading' (or the\n // pre-resolved entry) for every owned key — a consuming block must never see\n // a gap and start its own fetch.\n const [entries, setEntries] = useState<Record<string, PageDataEntry>>(() => ({\n // Everything handed in is published, not only the needs THIS scope\n // collected. That is what lets a host framework resolve a page's data in\n // its own loader and wrap the shell in a seeding scope: the page's own\n // scope then finds those keys already answered on its parent and fetches\n // nothing. Without it, seeding only works when the seeding scope happens to\n // render the same block tree.\n ...initial,\n ...Object.fromEntries(\n own.map((need) => [\n need.key,\n initial?.[need.key] ?? staticPass?.entries[need.key] ?? ({ status: 'loading' } as PageDataEntry),\n ]),\n ),\n }))\n\n const signature = own.map((need) => need.key).join('\\n')\n useEffect(() => {\n // A key handed in ready stays authoritative; everything else resolves here.\n const pending = own.filter((need) => initial?.[need.key]?.status !== 'ready')\n if (pending.length === 0) return\n let cancelled = false\n setEntries((prev) => {\n const next = { ...prev }\n for (const need of pending) {\n if (next[need.key]?.status !== 'ready') next[need.key] = { status: 'loading' }\n }\n return next\n })\n for (const need of pending) {\n void resolvePageDataNeed(need).then((entry) => {\n if (!cancelled) setEntries((prev) => ({ ...prev, [need.key]: entry }))\n })\n }\n return () => {\n cancelled = true\n }\n // `own` is captured by its key signature: same keys = same needs.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [signature])\n\n // `initial` is overlaid at RENDER time, on top of what this scope resolved,\n // rather than folded into state once at mount. The difference is one\n // commit, and it is the whole point: after a client-side navigation the\n // host hands in the next page's entries and the next page's own scope\n // mounts in the same commit — it decides which needs are unanswered by\n // reading this value as it mounts. State would only carry the new entries\n // from the following commit, by which time the child has already started\n // fetching everything the host had just resolved, and the shopper watches\n // content that was ready pop in a second time.\n const value = useMemo<PageDataContextValue>(\n () => ({ entries: { ...parent?.entries, ...entries, ...initial }, params: routeParams }),\n [parent, entries, initial, routeParams],\n )\n return <PageDataContext.Provider value={value}>{children}</PageDataContext.Provider>\n}\n\n// --- Consumption --------------------------------------------------------------\n\nexport interface UseLoaderResult<T> {\n status: PageDataStatus\n data: T | null\n error: string | null\n /** Re-run the read (bypasses the page-resolved entry from then on). */\n reload: () => void\n}\n\n/**\n * A block's (or page's) read: `useLoader('products.list', { filter, limit })`.\n *\n * When a PageDataScope above already resolved the same (loader, params) pair —\n * because this block, or ANY block on the page, declared it — the resolved\n * entry is returned and no request is made. Otherwise the hook resolves the\n * loader itself, through the same provider port, so a component used outside a\n * composed page (a store's hand-written route) keeps working identically.\n * Pass `null` params to disable the read.\n */\nexport function useLoader<T>(\n loader: string,\n params: Record<string, unknown> | null,\n): UseLoaderResult<T> {\n const scope = useContext(PageDataContext)\n const key = params === null ? null : dataNeedKey(loader, params)\n const [nonce, setNonce] = useState(0)\n const scoped = nonce === 0 && key !== null && scope ? scope.entries[key] : undefined\n const [local, setLocal] = useState<{ key: string; entry: PageDataEntry } | null>(null)\n\n // Undeclared reads — a hand-written route calling the hook directly — still\n // resolve under a static render: the pass collects the key on the first pass\n // and serves it on the next. Without this, exactly the reads that no block\n // declared would be the ones missing from a headless render.\n const staticPass = currentStaticRenderPass()\n const staticEntry = staticPass && key !== null && scoped === undefined ? staticPass.entries[key] : undefined\n if (staticPass && key !== null && scoped === undefined && staticEntry === undefined) {\n staticPass.needs([{ key, loader, params: params! }])\n }\n\n const paramsKey = params === null ? null : JSON.stringify(params)\n useEffect(() => {\n if (key === null || scoped !== undefined) return\n let cancelled = false\n setLocal({ key, entry: { status: 'loading' } })\n void resolvePageDataNeed({ loader, params: params! }).then((entry) => {\n if (!cancelled) setLocal({ key, entry })\n })\n return () => {\n cancelled = true\n }\n // params identity travels through paramsKey; scoped presence through a boolean.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [loader, paramsKey, nonce, scoped !== undefined])\n\n const entry =\n scoped ??\n staticEntry ??\n (local && local.key === key ? local.entry : key !== null ? { status: 'loading' as const } : null)\n\n return {\n status: entry?.status ?? 'idle',\n data: entry?.status === 'ready' ? (entry.data as T) : null,\n error: entry?.status === 'error' ? entry.error ?? 'unknown error' : null,\n reload: () => setNonce((n) => n + 1),\n }\n}\n\n/**\n * A BLOCK's named data need: `useBlockData(node, 'products', fallback)`.\n *\n * Reads the block's effective declaration — meta `data` with the document\n * instance's `data` merged over it — and resolves its bindings with the SAME\n * inputs the page resolver used (scope route params, node props over setting\n * defaults), so the two always compute the same key. That is what makes a\n * document able to rebind a param (`category: { $param: 'slug' }`) and have\n * the rendered block follow: the block asks for its declared need, not for a\n * hardcoded one.\n *\n * `fallback` covers the component being used directly as JSX (a store's\n * hand-written route), where there is no node and no declaration to read.\n */\nexport function useBlockData<T>(\n node: BlockNode | undefined,\n name: string,\n fallback: { loader: string; params: Record<string, unknown> },\n): UseLoaderResult<T> & { loader: string } {\n const scope = useContext(PageDataContext)\n let loader = fallback.loader\n let params = fallback.params\n if (node) {\n const need = needsForNode(node)[name]\n if (need && typeof need.loader === 'string' && need.loader) {\n const meta = getBlockMeta(node.type)\n loader = need.loader\n params = resolveDataParams(need, {\n params: scope?.params ?? {},\n props: { ...defaultPropsFromSettings(meta?.settings), ...node.props },\n })\n }\n }\n const result = useLoader<T>(loader, params)\n return { ...result, loader }\n}\n\n// --- Error surface ------------------------------------------------------------\n\n/**\n * What a block renders when its declared data failed: nothing for shoppers, a\n * visible card for builders — the same visibility rule as a crashed block\n * (M2's per-block error boundary, WooCommerce's `CURRENT_USER_IS_ADMIN ?\n * onError : () => null`).\n */\nexport function BlockDataError({ loader, message }: { loader: string; message?: string | null }) {\n if (getBlockErrorVisibility() === 'silent') return null\n return (\n <div\n data-block-error={`loader:${loader}`}\n style={{\n border: '1px dashed #dc2626',\n color: '#b91c1c',\n padding: '8px 12px',\n font: '12px ui-monospace, monospace',\n borderRadius: 6,\n }}\n >\n {`Data for this block failed (loader \"${loader}\")`}\n {message ? <div style={{ opacity: 0.8, marginTop: 4 }}>{message}</div> : null}\n </div>\n )\n}\n","import { checkBlockConstraints, checkBlockContext, getBlockMeta, isBlockEnabledOn } from '@fayz-ai/core'\nimport type { BlockDataNeeds, BlockNode } from '@fayz-ai/core'\nimport type { StorefrontSection } from './sections'\nimport type { StorefrontTheme } from '../lib/theme'\nimport { matchPath } from '../app/router'\n\n// ---------------------------------------------------------------------------\n// Pages as block trees.\n//\n// The home page has been a block tree since the registry landed. Every other\n// route was hand-written JSX, which is why a store that wanted a banner above\n// the catalog grid had only one move available: reimplement the catalog page.\n// One store did exactly that for three routes and stopped receiving SDK updates\n// for all three.\n//\n// What the benchmarks do, and what this adopts:\n//\n// Shopify templates/product.json lists sections, one of which is `main` —\n// the product form itself. A theme adds sections around `main`\n// without owning it.\n// VTEX IO store.product is a block array containing `product-details`.\n// Same idea, same reason.\n//\n// So the native page body becomes a block (`catalogBody`, `productBody`), and a\n// store composes around it. The body keeps being maintained by the SDK.\n//\n// One deliberate shape change: the general block form nests its props under\n// `props`, matching Shopify's `settings` and VTEX's `props`. The flat\n// StorefrontSection form stays supported — five of seven live stores write it —\n// but it is the outlier, and it is the reason the two stores with custom blocks\n// both had to write `sections: mySections as never`: a closed union cannot\n// describe a block the SDK has never heard of. Nesting fixes that without a cast.\n// ---------------------------------------------------------------------------\n\n/** Pages that are composed from blocks, and the `enabledOn` vocabulary.\n * `content` is the editorial kind: a titled page that is nothing but blocks —\n * no commerce body, no catalog assumptions. */\nexport type StorefrontPageKind = 'home' | 'catalog' | 'product' | 'collection' | 'content'\n\n/**\n * A block instance in a page tree — the general form.\n *\n * `id` matters more than it looks: two product rails on one page are\n * indistinguishable without it, so an external editor cannot target one of them\n * and an AI-generated diff cannot say which it changed. VTEX solved the same\n * problem with `rich-text#hero`; this is the same idea spelled as a field.\n */\nexport interface StorefrontBlockRef {\n /** Registered block id — an SDK section, a plugin block, or an app's own. */\n type: string\n id?: string\n props?: Record<string, unknown>\n children?: readonly StorefrontBlockRef[]\n /**\n * Instance-level data needs, merged over the block meta's `data` declaration\n * by need name — how a document points a block's loader at a route param\n * (`{ products: { loader: 'products.list', params: { category: { $param:\n * 'slug' } } } }`). Resolved once per page by the page-data scope.\n */\n data?: BlockDataNeeds\n}\n\n/**\n * What a page's block list accepts.\n *\n * The typed union keeps checking SDK sections (a bad `variant` is still a type\n * error); the open ref form is what lets an app place its own registered block\n * without casting.\n */\nexport type StorefrontBlockLike = StorefrontSection | StorefrontBlockRef\n\nexport interface StorefrontPageConfig {\n blocks: readonly StorefrontBlockLike[]\n}\n\n/**\n * An editorial page, expressible entirely in the document: a slug, a title, a\n * route, and blocks. This is the page kind that absorbs the \"brand site half\"\n * of a store — biography, philosophy, press, collections — which today lives\n * as hand-written custom routes (cristinarotondaro carries ~240 lines of them).\n *\n * The store chrome (header, footer, cart) still frames the page; what a\n * content page does NOT get is a commerce body block or any catalog\n * assumption. It is blocks all the way down.\n */\nexport interface StorefrontContentPageConfig extends StorefrontPageConfig {\n /** Document/page title (`<title>` gets \"<title> — <store>\"). Defaults to the slug. */\n title?: string\n /**\n * Route path. Defaults to `/<slug>`. May declare params (`/categoria/:slug`)\n * — one page then serves every match, and its blocks read the params through\n * `$param` loader bindings (M3). validateStore checks that every binding\n * names a param the path declares.\n */\n path?: string\n /**\n * Theme overlay applied ONLY inside this page, merged over the store theme.\n *\n * This is what makes a campaign page — a licensed line, a seasonal drop, a\n * collab — expressible as a content page instead of a microsite. Stores\n * routinely build those elsewhere and lose the funnel with them: the \"buy\"\n * CTA leaves for another domain and the cart, the session and the\n * attribution go with it.\n *\n * The overlay is emitted scoped to `[data-page=\"<slug>\"]`, so a hot-pink\n * summer drop cannot repaint the header, the cart drawer or any other route.\n * It merges key by key, so a page that sets only `colors.primary` keeps the\n * store's typography and every other token.\n */\n theme?: Partial<StorefrontTheme>\n}\n\n/**\n * Merge a page's theme overlay over the store theme.\n *\n * Nested groups merge rather than replace: a page declaring one colour must not\n * silently drop the store's fonts, radii and brand tokens back to SDK defaults.\n */\nexport function mergePageTheme(\n base: StorefrontTheme | undefined,\n overlay: Partial<StorefrontTheme> | undefined,\n): StorefrontTheme | undefined {\n if (!base && !overlay) return undefined\n if (!overlay) return base\n const name = overlay.name ?? (base ? `${base.name}-page` : 'page')\n const font = base?.font ? { ...base.font, ...overlay.font } : (overlay.font as StorefrontTheme['font'])\n return {\n ...base,\n ...overlay,\n name,\n colors: { ...base?.colors, ...overlay.colors },\n font,\n tokens: { ...base?.tokens, ...overlay.tokens },\n header: { ...base?.header, ...overlay.header },\n productCard: { ...base?.productCard, ...overlay.productCard },\n }\n}\n\n/** The wrapper attribute + selector a page's scoped theme is emitted under. */\nexport function pageThemeSelector(slug: string): string {\n return `[data-page=\"${slug}\"]`\n}\n\n/** The params a route path pattern declares ('/categoria/:slug' → ['slug']). */\nexport function routePathParams(path: string): string[] {\n return path\n .split('/')\n .filter((segment) => segment.startsWith(':'))\n .map((segment) => segment.slice(1))\n}\n\nexport interface StorefrontPagesConfig {\n home?: StorefrontPageConfig\n catalog?: StorefrontPageConfig\n product?: StorefrontPageConfig\n collection?: StorefrontPageConfig\n /** Editorial pages, keyed by slug. */\n content?: Record<string, StorefrontContentPageConfig>\n}\n\n/** Route path of one content page (explicit `path`, or `/<slug>`). */\nexport function contentPagePath(slug: string, page: StorefrontContentPageConfig): string {\n return page.path ?? `/${slug}`\n}\n\nexport interface ContentPageMatch {\n slug: string\n page: StorefrontContentPageConfig\n /** Params extracted from the page's path pattern, when it declares any. */\n params: Record<string, string>\n}\n\n/** The content page a path resolves to, if the store declared one. Paths are\n * patterns (`/categoria/:slug`), so one declared page can serve a family of\n * URLs and hand the matched params to its blocks' `$param` bindings. */\nexport function matchContentPage(\n pages: StorefrontPagesConfig | undefined,\n path: string,\n): ContentPageMatch | null {\n for (const [slug, page] of Object.entries(pages?.content ?? {})) {\n const params = matchPath(contentPagePath(slug, page), path)\n if (params) return { slug, page, params }\n }\n return null\n}\n\n/** Block ids for the native page bodies — Shopify's `main` section, by another name. */\nexport const CATALOG_BODY_BLOCK = 'catalogBody'\nexport const PRODUCT_BODY_BLOCK = 'productBody'\n\n/** The block that renders the page's own reason for existing, per page kind. */\nconst BODY_BLOCK_BY_KIND: Partial<Record<StorefrontPageKind, string>> = {\n catalog: CATALOG_BODY_BLOCK,\n product: PRODUCT_BODY_BLOCK,\n}\n\n/**\n * Keys that are block identity rather than props, in the nested form.\n *\n * Exported for the same reason `blockInstanceId` is: it must be ONE rule.\n * Whoever asks \"where do this block's settings live\" — the renderer here, the\n * editor via `blockAtPath`, the overlay's settings/structure guard — has to get\n * the same answer, or an edit an editor accepts is one the renderer ignores.\n */\nexport const BLOCK_STRUCTURAL_KEYS: ReadonlySet<string> = new Set([\n 'type',\n 'id',\n 'props',\n 'children',\n 'data',\n])\n\nconst STRUCTURAL_KEYS = BLOCK_STRUCTURAL_KEYS\n\n/**\n * Does this entry keep its settings under `props` (nested form) or inline on\n * the entry itself (flat form)?\n *\n * Both forms are first-class and they MIX inside one array — artorious's home\n * page is 3 nested and 5 flat — so nothing may assume the shape from the path\n * it took to get here.\n */\nexport function isNestedBlockRef(entry: unknown): boolean {\n return isNestedRef(entry as StorefrontBlockLike)\n}\n\nfunction isNestedRef(entry: StorefrontBlockLike): boolean {\n const record = entry as Record<string, unknown>\n // An explicit `props` settles it. Otherwise: an entry carrying nothing but\n // structural keys is a ref with no props (`{ type: 'seals' }`), which the flat\n // reading would also produce — so either branch is correct for that case.\n if ('props' in record) return true\n return Object.keys(record).every((key) => STRUCTURAL_KEYS.has(key))\n}\n\n/**\n * The id a block instance is known by: the authored `id`, or `<type>-<index>`\n * when it has none.\n *\n * Exported because it must be ONE rule. A block with no authored id still\n * reaches the outside world under its synthesized id — `renderStore` reports\n * it, an editor targets it, a generated diff names it — so `applyChange` has\n * to resolve `blocks[#banner-0]` to the same entry the renderer called\n * `banner-0`. Two implementations of this rule would make the id an agent is\n * handed by one ability unusable by another.\n */\nexport function blockInstanceId(entry: unknown, index: number): string {\n const record = entry as Record<string, unknown> | null\n if (record && typeof record.id === 'string' && record.id) return record.id\n return `${String(record?.type)}-${index}`\n}\n\n/**\n * Normalize one authored entry into a `BlockNode`.\n *\n * Both authoring forms collapse to the same node, so everything downstream —\n * the renderer, the editor, `describeBlocks` — sees one shape.\n */\nfunction toBlockNode(entry: StorefrontBlockLike, index: number): BlockNode {\n const record = entry as Record<string, unknown>\n const type = String(record.type)\n const id = blockInstanceId(entry, index)\n\n const data = record.data as BlockDataNeeds | undefined\n\n if (isNestedRef(entry)) {\n const children = (record.children as readonly StorefrontBlockRef[] | undefined) ?? []\n return {\n type,\n id,\n props: (record.props as Record<string, unknown> | undefined) ?? {},\n ...(children.length ? { children: children.map((child, i) => toBlockNode(child, i)) } : {}),\n ...(data ? { data } : {}),\n }\n }\n\n // Flat form: everything that is not identity is a prop.\n const props: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(record)) {\n if (!STRUCTURAL_KEYS.has(key)) props[key] = value\n }\n return { type, id, props, ...(data ? { data } : {}) }\n}\n\n/** Normalize an authored block list into the block tree the renderer consumes. */\nexport function toBlockNodes(blocks: readonly StorefrontBlockLike[]): BlockNode[] {\n return blocks.map(toBlockNode)\n}\n\n/**\n * The default tree for a page kind — what the SDK renders when a store has not\n * composed the page. For catalog and product that is the native body alone,\n * which is why adopting `pages` is a no-op until a store adds something.\n */\nexport function defaultPageBlocks(kind: StorefrontPageKind): BlockNode[] {\n const body = BODY_BLOCK_BY_KIND[kind]\n return body ? [{ type: body, id: body, props: {} }] : []\n}\n\nexport interface PageBlockDiagnostic {\n level: 'error' | 'warning'\n rule: string\n detail: string\n}\n\n/**\n * Diagnostics for one composed page.\n *\n * These are reported, not enforced. A store in production must not go blank\n * because a block was placed on a page its author did not anticipate — so the\n * hard stop belongs in the editor (which reads the same `enabledOn` through\n * `describeBlocks`), and this is the development-time equivalent.\n */\nexport function checkPageBlocks(kind: StorefrontPageKind, nodes: readonly BlockNode[]): PageBlockDiagnostic[] {\n const found: PageBlockDiagnostic[] = []\n const seenIds = new Set<string>()\n const expectedBody = BODY_BLOCK_BY_KIND[kind]\n let hasBody = false\n\n for (const node of nodes) {\n if (node.type === expectedBody) hasBody = true\n\n if (node.id) {\n if (seenIds.has(node.id)) {\n found.push({\n level: 'warning',\n rule: 'duplicate-block-id',\n detail: `two blocks on the ${kind} page share the id \"${node.id}\" — an editor or a generated diff cannot tell them apart`,\n })\n }\n seenIds.add(node.id)\n }\n\n const meta = getBlockMeta(node.type)\n if (!meta) {\n found.push({\n level: 'error',\n rule: 'unknown-block',\n detail: `the ${kind} page references block \"${node.type}\", which is not registered — register it before the storefront mounts`,\n })\n continue\n }\n if (!isBlockEnabledOn({ enabledOn: meta.enabledOn ?? [] }, kind)) {\n found.push({\n level: 'warning',\n rule: 'block-not-enabled-on-page',\n detail: `block \"${node.type}\" declares enabledOn [${(meta.enabledOn ?? []).join(', ')}] and is placed on the ${kind} page`,\n })\n }\n }\n\n if (expectedBody && !hasBody) {\n // Shopify hard-requires the `main` section in a template for this reason. We\n // warn instead of inserting it, because silently adding a block the config\n // does not mention makes the config a lie — and a fully bespoke catalog is a\n // legitimate thing to build.\n found.push({\n level: 'warning',\n rule: 'missing-page-body',\n detail: `the ${kind} page tree omits \"${expectedBody}\", so the page renders no ${kind === 'product' ? 'product detail' : 'product list'} — add it back unless the replacement is deliberate`,\n })\n }\n\n // Composition constraints, for pages composed in code: a document goes\n // through validateStore, but a TS config never does, so the same structural\n // rules are reported here. Errors, because the renderer will keep these\n // blocks off the shopper's page (I7) — the composition already lies.\n for (const violation of checkBlockConstraints(nodes)) {\n found.push({\n level: 'error',\n rule: violation.rule,\n detail: `${kind} page ${violation.path}: ${violation.detail}`,\n })\n }\n\n // Context is advisory: the key may arrive through a runtime channel a static\n // tree cannot see (a slot area, a future loader), so the honest verdict is\n // \"nothing declares this\", not \"this is broken\".\n for (const finding of checkBlockContext(nodes)) {\n found.push({\n level: 'warning',\n rule: 'context-not-provided',\n detail: `block \"${finding.type}\" at ${kind} page ${finding.path} uses context [${finding.missing.join(', ')}] that no ancestor provides`,\n })\n }\n\n return found\n}\n","import { breadcrumbJsonLd, seoOrigin } from '@fayz-ai/core'\nimport { currentStaticRenderPass } from '../app/static-render'\nimport type { Category, Product } from '@fayz-ai/shop/types'\nimport { imageVariantUrl } from '@fayz-ai/shop'\nimport type { ResolvedStorefrontConfig } from '../document/config'\nimport type { StaticHeadInput } from '../app/static-render'\n\n// ---------------------------------------------------------------------------\n// What a storefront route should tell a crawler about itself.\n//\n// Pure builders returning a head declaration, so the page that knows what it is\n// rendering also declares its own SEO — rather than a renderer re-deriving the\n// routing table on the server to guess. Same reason `useStorefrontHead` reports\n// the title instead of letting `renderStore` infer it.\n//\n// Absolute URLs need an origin the store does not know at build time. Callers\n// pass one explicitly (a server render knows the request host); in a browser it\n// falls back to the live origin. Without either, canonical and OG URLs are\n// omitted rather than emitted relative, because a relative canonical is ignored\n// by search engines and a relative og:image renders as a broken share.\n// ---------------------------------------------------------------------------\n\nexport interface StorefrontSeoContext {\n config: ResolvedStorefrontConfig\n /** In-app path, e.g. '/product/pork-ribs'. */\n path: string\n /** Absolute origin, e.g. 'https://loja.example.com'. */\n origin?: string\n}\n\nfunction absolute(ctx: StorefrontSeoContext, path = ctx.path): string | undefined {\n // Explicit wins, then the origin the static render was told about, then the\n // live browser origin. A page never has to know which of the three it is in.\n const origin = (ctx.origin ?? currentStaticRenderPass()?.origin ?? seoOrigin()).replace(/\\/$/, '')\n if (!origin) return undefined\n return `${origin}${path.startsWith('/') ? path : `/${path}`}`\n}\n\n/** Primary image, falling back to the first — how product cards pick one. */\nexport function primaryImageUrl(product: Product): string | undefined {\n return (product.images?.find((i) => i.isPrimary) ?? product.images?.[0])?.url\n}\n\n/**\n * The primary image as a share card wants it: 1200 px wide when the store\n * serves variants, so a WhatsApp/OG scraper does not pull the 4000 px\n * original — and the same URL for every scraper, so it is cached once.\n */\nfunction shareImageUrl(product: Product, ctx: StorefrontSeoContext): string | undefined {\n const url = primaryImageUrl(product)\n if (!url) return undefined\n return ctx.config.imageLoading.transform === 'supabase' ? imageVariantUrl(url, { width: 1200, quality: 82 }) : url\n}\n\n/**\n * schema.org Product. Availability is derived from inventory rather than\n * declared, because a rich result advertising an in-stock product that is not\n * is worse than no rich result.\n */\nexport function productJsonLd(\n product: Product,\n ctx: StorefrontSeoContext,\n): Record<string, unknown> {\n const url = absolute(ctx)\n const image = shareImageUrl(product, ctx)\n return {\n '@context': 'https://schema.org',\n '@type': 'Product',\n name: product.name,\n ...(product.description ? { description: product.description } : {}),\n ...(product.sku ? { sku: product.sku } : {}),\n ...(image ? { image: [image] } : {}),\n offers: {\n '@type': 'Offer',\n ...(url ? { url } : {}),\n price: product.price,\n priceCurrency: product.currency ?? ctx.config.currency,\n availability:\n (product.inventoryCount ?? 0) > 0\n ? 'https://schema.org/InStock'\n : 'https://schema.org/OutOfStock',\n },\n }\n}\n\n/** The head declaration for a product page. */\nexport function productSeo(product: Product, ctx: StorefrontSeoContext): StaticHeadInput {\n const url = absolute(ctx)\n const home = absolute(ctx, '/')\n const catalog = absolute(ctx, ctx.config.catalogPath)\n return {\n title: `${product.name} — ${ctx.config.name}`,\n description: product.description?.slice(0, 160),\n canonical: url,\n image: shareImageUrl(product, ctx),\n type: 'product',\n jsonLd: [\n productJsonLd(product, ctx),\n ...(home && catalog && url\n ? [\n breadcrumbJsonLd([\n { name: ctx.config.name, url: home },\n { name: 'Loja', url: catalog },\n { name: product.name, url },\n ]),\n ]\n : []),\n ],\n }\n}\n\n/** The head declaration for any non-product route: canonical only. */\nexport function pageSeo(\n ctx: StorefrontSeoContext,\n input: { title: string; description?: string | null },\n): StaticHeadInput {\n return { ...input, canonical: absolute(ctx), type: 'website' }\n}\n\n/**\n * Who serves the menu, as the store knows itself. Everything optional: a\n * field the store has not filled is left out of the JSON-LD rather than\n * guessed, because a wrong phone number in a rich result is worse than none.\n */\nexport interface MenuBusiness {\n /** schema.org type. 'Restaurant' unless the house is better described by\n * another FoodEstablishment subtype (e.g. 'FastFoodRestaurant', 'Bakery'). */\n type?: string\n description?: string\n telephone?: string\n email?: string\n /** Absolute URL. */\n logo?: string\n /** Absolute URL; the cover photo. */\n image?: string\n servesCuisine?: string | string[]\n priceRange?: string\n address?: { streetAddress?: string; locality?: string; region?: string; postalCode?: string; country?: string }\n /** Cities or neighbourhoods delivered to, by name. */\n areaServed?: string[]\n /** schema.org openingHours, e.g. ['Mo-Fr 11:00-22:00']. */\n openingHours?: string[]\n sameAs?: string[]\n}\n\n/** The menu as the shopper sees it: category order, each dish under its\n * category, the uncategorised ones last (same grouping as `MenuPage`). */\nfunction menuSections(products: Product[], categories: Category[]) {\n const byCategory = new Map<string, Product[]>()\n const loose: Product[] = []\n for (const p of products) {\n const key = p.categoryId ?? p.categoryName ?? ''\n if (!key) { loose.push(p); continue }\n byCategory.set(key, [...(byCategory.get(key) ?? []), p])\n }\n const sections = categories\n .map((c) => ({ name: c.name, description: c.description, products: byCategory.get(c.id) ?? byCategory.get(c.name) ?? [] }))\n .filter((s) => s.products.length > 0)\n if (loose.length) sections.push({ name: 'Outros', description: null, products: loose })\n if (!sections.length && products.length) return [{ name: 'Cardápio', description: null, products }]\n return sections\n}\n\n/**\n * schema.org Restaurant with its Menu — what lets a search engine answer\n * \"delivery de costela defumada\" with this house, and read every dish and\n * price without running the page's JavaScript.\n *\n * Each dish links to its own product page, where the full Product entity\n * lives; here it is a MenuItem, which is what a dish on a menu is.\n */\nexport function menuJsonLd(\n input: { products: Product[]; categories: Category[]; business?: MenuBusiness },\n ctx: StorefrontSeoContext,\n): Record<string, unknown> {\n const url = absolute(ctx)\n const home = absolute(ctx, '/')\n const b = input.business ?? {}\n const currency = ctx.config.currency\n const address = b.address\n ? {\n '@type': 'PostalAddress',\n ...(b.address.streetAddress ? { streetAddress: b.address.streetAddress } : {}),\n ...(b.address.locality ? { addressLocality: b.address.locality } : {}),\n ...(b.address.region ? { addressRegion: b.address.region } : {}),\n ...(b.address.postalCode ? { postalCode: b.address.postalCode } : {}),\n addressCountry: b.address.country ?? 'BR',\n }\n : undefined\n return {\n '@context': 'https://schema.org',\n '@type': b.type ?? 'Restaurant',\n ...(home ? { '@id': `${home.replace(/\\/$/, '')}/#business` } : {}),\n name: ctx.config.name,\n ...(home ? { url: home } : {}),\n ...(b.description ? { description: b.description } : {}),\n ...(b.image ? { image: [b.image] } : {}),\n ...(b.logo ? { logo: b.logo } : {}),\n ...(b.telephone ? { telephone: b.telephone } : {}),\n ...(b.email ? { email: b.email } : {}),\n ...(b.servesCuisine ? { servesCuisine: b.servesCuisine } : {}),\n ...(b.priceRange ? { priceRange: b.priceRange } : {}),\n ...(address ? { address } : {}),\n ...(b.areaServed?.length ? { areaServed: b.areaServed.map((name) => ({ '@type': 'Place', name })) } : {}),\n ...(b.openingHours?.length ? { openingHours: b.openingHours } : {}),\n ...(b.sameAs?.length ? { sameAs: b.sameAs } : {}),\n ...(url ? { hasMenu: url } : {}),\n ...(url\n ? {\n potentialAction: {\n '@type': 'OrderAction',\n target: { '@type': 'EntryPoint', urlTemplate: url, actionPlatform: ['https://schema.org/DesktopWebPlatform', 'https://schema.org/MobileWebPlatform'] },\n deliveryMethod: 'http://purl.org/goodrelations/v1#DeliveryModeOwnFleet',\n },\n }\n : {}),\n menu: {\n '@type': 'Menu',\n name: `Cardápio — ${ctx.config.name}`,\n ...(url ? { url } : {}),\n inLanguage: 'pt-BR',\n hasMenuSection: menuSections(input.products, input.categories).map((section) => ({\n '@type': 'MenuSection',\n name: section.name,\n ...(section.description ? { description: section.description } : {}),\n hasMenuItem: section.products.map((p) => {\n const image = shareImageUrl(p, ctx)\n const itemUrl = absolute(ctx, `/product/${p.slug}`)\n return {\n '@type': 'MenuItem',\n name: p.name,\n ...(p.description ? { description: p.description.slice(0, 300) } : {}),\n ...(image ? { image } : {}),\n ...(itemUrl ? { url: itemUrl } : {}),\n offers: {\n '@type': 'Offer',\n price: p.price,\n priceCurrency: p.currency ?? currency,\n availability: (p.inventoryCount ?? 0) > 0 ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock',\n },\n }\n }),\n })),\n },\n }\n}\n\n/**\n * The head declaration for the delivery menu: its own title and description\n * (the store passes copy written for the query it should answer), the\n * Restaurant + Menu entity, and a breadcrumb back to the home page.\n */\nexport function menuSeo(\n input: {\n products: Product[]\n categories: Category[]\n title?: string\n description?: string | null\n business?: MenuBusiness\n },\n ctx: StorefrontSeoContext,\n): StaticHeadInput {\n const url = absolute(ctx)\n const home = absolute(ctx, '/')\n const names = input.products.slice(0, 4).map((p) => p.name).join(', ')\n return {\n title: input.title ?? `Delivery ${ctx.config.name} — peça online`,\n description:\n (input.description ?? (names ? `Peça online: ${names} e mais. Cardápio completo com preços.` : undefined))?.slice(0, 160),\n canonical: url,\n image: input.business?.image,\n type: 'website',\n jsonLd: [\n menuJsonLd(input, ctx),\n ...(home && url\n ? [breadcrumbJsonLd([{ name: ctx.config.name, url: home }, { name: 'Delivery', url }])]\n : []),\n ],\n }\n}\n","import type { ShopProvider } from '@fayz-ai/shop/provider'\nimport { matchPath } from './router'\nimport { matchContentPage } from '../blocks/page-blocks'\nimport { resolveConfig } from '../document/config'\nimport type { StorefrontConfig, ResolvedStorefrontConfig } from '../document/config'\n\n// ---------------------------------------------------------------------------\n// How a store is served, once its pages have URLs of their own.\n//\n// Two questions a host has to answer that the shell cannot: which paths exist\n// at all (what to prerender, what to put in a sitemap), and which of them are\n// the same for every visitor (what a shared cache may hold). Both are\n// properties of the route, so they are decided here rather than by each host\n// re-deriving them — and the second one has a failure mode a CDN makes\n// invisible: cache a cart or an order confirmation once and it is served to the\n// next shopper.\n// ---------------------------------------------------------------------------\n\nexport type StorefrontRouteMatch =\n | { kind: 'custom'; route: NonNullable<ResolvedStorefrontConfig['routes']>[number]; params: Record<string, string> }\n | { kind: 'product'; params: Record<string, string> }\n | { kind: 'order'; params: Record<string, string> }\n | { kind: 'checkout' }\n | { kind: 'account' }\n | { kind: 'catalog' }\n | { kind: 'menu' }\n | { kind: 'searchResults' }\n | { kind: 'policy'; policy: 'privacy' | 'terms' | 'returns' }\n | { kind: 'content'; slug: string; params: Record<string, string> }\n | { kind: 'home' }\n | { kind: 'notFound' }\n\n/**\n * What a path means, resolved once.\n *\n * The shell renders from this, cacheability is derived from it, and a host\n * framework asks it whether a URL exists at all before choosing a status code.\n * Those three answering separately is how a page ends up rendered as one thing\n * and cached or statused as another.\n *\n * The query string is stripped first: it addresses state WITHIN a page, so\n * `/?utm_source=instagram` is the home page — the single most common shape of\n * inbound marketing link, and a 404 for it is a silent, expensive bug.\n */\nexport function resolveStorefrontRoute(\n config: StorefrontConfig | ResolvedStorefrontConfig,\n rawPath: string,\n): StorefrontRouteMatch {\n const resolved = ensureResolved(config)\n const path = rawPath.split('?')[0] || '/'\n\n for (const route of resolved.routes ?? []) {\n const params = matchPath(route.path, path)\n if (params) return { kind: 'custom', route, params }\n }\n\n const product = matchPath('/product/:slug', path)\n if (product?.slug) return { kind: 'product', params: product }\n\n const order = matchPath('/order/:id', path)\n if (order?.id) return { kind: 'order', params: order }\n\n // Matched regardless of the feature flag: a disabled checkout still owns its\n // URL rather than falling through to an unrelated page.\n if (matchPath('/checkout', path)) return { kind: 'checkout' }\n if (matchPath('/account', path)) return { kind: 'account' }\n if (matchPath('/catalog', path)) return { kind: 'catalog' }\n // Só existe no modo delivery, e por isso é testado contra `resolved.delivery`\n // e não contra o literal '/menu': fora do modo, /menu é um 404 de verdade em\n // vez de uma página vazia — que é a diferença entre uma rota que não existe e\n // uma rota quebrada.\n if (resolved.delivery && matchPath(resolved.delivery.menuPath, path)) return { kind: 'menu' }\n if (resolved.search.mode === 'overlay' && matchPath(resolved.search.resultsPath, path)) {\n return { kind: 'searchResults' }\n }\n if (matchPath('/privacy', path)) return { kind: 'policy', policy: 'privacy' }\n if (matchPath('/terms', path)) return { kind: 'policy', policy: 'terms' }\n if (matchPath('/refunds', path)) return { kind: 'policy', policy: 'returns' }\n\n const content = matchContentPage(resolved.pages, path)\n if (content) return { kind: 'content', slug: content.slug, params: content.params }\n\n if (path === '/' || path === '') return { kind: 'home' }\n return { kind: 'notFound' }\n}\n\n/** Whether a URL exists at all — what a host needs before choosing a status. */\nexport function isKnownPath(\n config: StorefrontConfig | ResolvedStorefrontConfig,\n path: string,\n): boolean {\n return resolveStorefrontRoute(config, path).kind !== 'notFound'\n}\n\n/** Paths whose HTML is per-shopper and must never enter a shared cache. */\nconst PRIVATE_PATTERNS = ['/checkout', '/account', '/order/:id'] as const\n\n/** Paths the SDK serves that exist without knowing any product. The delivery\n * menu is added from the store's own `delivery.menuPath` — see `storefrontPaths`. */\nconst STATIC_PATTERNS = ['/', '/catalog', '/privacy', '/terms', '/refunds'] as const\n\nfunction ensureResolved(config: StorefrontConfig | ResolvedStorefrontConfig): ResolvedStorefrontConfig {\n return 'features' in config && 'pages' in config\n ? (config as ResolvedStorefrontConfig)\n : resolveConfig(config)\n}\n\n/**\n * Whether `path`'s HTML is identical for every visitor.\n *\n * Conservative by construction: a store's own route is private unless it says\n * otherwise, because guessing \"public\" is the direction that leaks one\n * shopper's page to another.\n */\nexport function isPublicPath(\n config: StorefrontConfig | ResolvedStorefrontConfig,\n path: string,\n): boolean {\n const match = resolveStorefrontRoute(config, path)\n switch (match.kind) {\n case 'checkout':\n case 'account':\n case 'order':\n return false\n case 'custom':\n return (\n match.route.kind !== 'checkout' &&\n match.route.kind !== 'account' &&\n match.route.chrome !== 'focused'\n )\n default:\n return true\n }\n}\n\n/**\n * Every path worth prerendering, and the same list a sitemap should carry.\n *\n * Product URLs come from the catalogue rather than the route table, so the\n * provider is asked rather than guessed at. Custom routes with parameters are\n * skipped: the SDK cannot know what values a store's own route accepts, and\n * emitting `/colecao/:slug` into a sitemap is worse than omitting it.\n */\nexport async function storefrontPaths(input: {\n config: StorefrontConfig | ResolvedStorefrontConfig\n provider: ShopProvider\n /** Include per-shopper routes. Off by default — they are not prerenderable. */\n includePrivate?: boolean\n}): Promise<string[]> {\n const resolved = ensureResolved(input.config)\n const paths = [...STATIC_PATTERNS] as string[]\n // The menu is the same for every visitor — what changes per shopper (address,\n // cart, open right now) resolves in the browser after hydration. It is listed\n // at the store's own path: a store whose menu lives at /delivery had /menu in\n // its sitemap and its real ordering page in none.\n if (resolved.delivery) paths.push(resolved.delivery.menuPath)\n\n for (const route of resolved.routes ?? []) {\n if (!route.path.includes(':')) paths.push(route.path)\n }\n\n const products = await input.provider.listProducts({ status: 'active' })\n for (const product of products) paths.push(`/product/${product.slug}`)\n\n const unique = Array.from(new Set(paths))\n return input.includePrivate ? unique : unique.filter((p) => isPublicPath(resolved, p))\n}\n","import { dataNeedKey } from '@fayz-ai/core'\n\n/**\n * The reads the delivery menu makes, named once so a server host can resolve\n * them before render. The menu is not a block tree, so nothing collects these\n * for it — a host that does not seed them sends a menu with no dishes in the\n * HTML, which is the page a crawler indexes.\n *\n * Its own module, free of React, because a host's route loader imports it on\n * every request.\n */\nexport const MENU_DATA_NEEDS = {\n products: { loader: 'products.list', params: {} },\n categories: { loader: 'categories.list', params: {} },\n featured: { loader: 'products.featured', params: {} },\n} as const\n\n/** The menu's data needs, keyed exactly as its `useLoader` calls will ask. */\nexport function menuDataNeeds(): Array<{ key: string; loader: string; params: Record<string, unknown> }> {\n return Object.values(MENU_DATA_NEEDS).map(({ loader, params }) => ({ key: dataNeedKey(loader, params), loader, params }))\n}\n"]}
|