@burdenoff/microfe-store 2026.625.5 → 2026.626.2

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.
Files changed (189) hide show
  1. package/dist/StoreRoot.js +47 -90
  2. package/dist/StoreRoot.js.map +1 -1
  3. package/dist/StoreRoutes.js +93 -158
  4. package/dist/StoreRoutes.js.map +1 -1
  5. package/dist/components/AccessDenied.js +3 -3
  6. package/dist/components/AccessDenied.js.map +1 -1
  7. package/dist/components/InstallAppModal.js +175 -255
  8. package/dist/components/InstallAppModal.js.map +1 -1
  9. package/dist/components/cart/CartDrawer.js +10 -10
  10. package/dist/components/cart/CartDrawer.js.map +1 -1
  11. package/dist/hooks/useStoreGraphQL.js +107 -177
  12. package/dist/hooks/useStoreGraphQL.js.map +1 -1
  13. package/dist/index.js +3 -3
  14. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/errors/CombinedGraphQLErrors.js +1 -1
  15. package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +1 -0
  16. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/errors/utils.js +1 -1
  17. package/dist/node_modules/@apollo/client/errors/utils.js.map +1 -0
  18. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/link/core/ApolloLink.js +2 -2
  19. package/dist/node_modules/@apollo/client/link/core/ApolloLink.js.map +1 -0
  20. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/link/subscriptions/index.js +2 -2
  21. package/dist/node_modules/@apollo/client/link/subscriptions/index.js.map +1 -0
  22. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/link/utils/createOperation.js +1 -1
  23. package/dist/node_modules/@apollo/client/link/utils/createOperation.js.map +1 -0
  24. package/dist/node_modules/@apollo/client/utilities/caching/sizes.js.map +1 -0
  25. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/graphql/print.js +1 -1
  26. package/dist/node_modules/@apollo/client/utilities/graphql/print.js.map +1 -0
  27. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/caches.js +2 -2
  28. package/dist/node_modules/@apollo/client/utilities/internal/caches.js.map +1 -0
  29. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/checkDocument.js +1 -1
  30. package/dist/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +1 -0
  31. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/getMainDefinition.js +1 -1
  32. package/dist/node_modules/@apollo/client/utilities/internal/getMainDefinition.js.map +1 -0
  33. package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +9 -0
  34. package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +1 -0
  35. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/getOperationDefinition.js +1 -1
  36. package/dist/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +1 -0
  37. package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js +8 -0
  38. package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +1 -0
  39. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/globals/global.js +1 -1
  40. package/dist/node_modules/@apollo/client/utilities/internal/globals/global.js.map +1 -0
  41. package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js +10 -0
  42. package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +1 -0
  43. package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js +8 -0
  44. package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js.map +1 -0
  45. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/makeUniqueId.js +1 -1
  46. package/dist/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +1 -0
  47. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/memoize.js +2 -2
  48. package/dist/node_modules/@apollo/client/utilities/internal/memoize.js.map +1 -0
  49. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/internal/stringifyForDisplay.js +1 -1
  50. package/dist/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +1 -0
  51. package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/invariant/index.js +1 -1
  52. package/dist/node_modules/@apollo/client/utilities/invariant/index.js.map +1 -0
  53. package/dist/node_modules/@apollo/client/version.js +6 -0
  54. package/dist/node_modules/@apollo/client/version.js.map +1 -0
  55. package/dist/node_modules/{.bun/@wry_caches@1.0.1/node_modules/@wry → @wry}/caches/lib/weak.js +1 -1
  56. package/dist/node_modules/@wry/caches/lib/weak.js.map +1 -0
  57. package/dist/node_modules/{.bun/@wry_trie@0.5.0/node_modules/@wry → @wry}/trie/lib/index.js +1 -1
  58. package/dist/node_modules/@wry/trie/lib/index.js.map +1 -0
  59. package/dist/node_modules/{.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws → graphql-ws}/dist/client.js +1 -1
  60. package/dist/node_modules/graphql-ws/dist/client.js.map +1 -0
  61. package/dist/node_modules/{.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws → graphql-ws}/dist/common-CGW11Fyb.js +1 -1
  62. package/dist/node_modules/graphql-ws/dist/common-CGW11Fyb.js.map +1 -0
  63. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/NotificationFactories.js +1 -1
  64. package/dist/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +1 -0
  65. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/Observable.js +1 -1
  66. package/dist/node_modules/rxjs/dist/esm5/internal/Observable.js.map +1 -0
  67. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/Subscriber.js +2 -2
  68. package/dist/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +1 -0
  69. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/Subscription.js +2 -2
  70. package/dist/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +1 -0
  71. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/config.js +1 -1
  72. package/dist/node_modules/rxjs/dist/esm5/internal/config.js.map +1 -0
  73. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/observable/empty.js +1 -1
  74. package/dist/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +1 -0
  75. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/scheduler/timeoutProvider.js +2 -2
  76. package/dist/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +1 -0
  77. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/symbol/observable.js +1 -1
  78. package/dist/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +1 -0
  79. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/util/UnsubscriptionError.js +1 -1
  80. package/dist/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +1 -0
  81. package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +11 -0
  82. package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +1 -0
  83. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/util/createErrorClass.js +1 -1
  84. package/dist/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +1 -0
  85. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/util/errorContext.js +1 -1
  86. package/dist/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +1 -0
  87. package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js +8 -0
  88. package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +1 -0
  89. package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +8 -0
  90. package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +1 -0
  91. package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js +6 -0
  92. package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +1 -0
  93. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/util/pipe.js +1 -1
  94. package/dist/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +1 -0
  95. package/dist/node_modules/{.bun/rxjs@7.8.2/node_modules/rxjs → rxjs}/dist/esm5/internal/util/reportUnhandledError.js +1 -1
  96. package/dist/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +1 -0
  97. package/dist/node_modules/{.bun/tslib@2.8.1 → rxjs}/node_modules/tslib/tslib.es6.js +1 -1
  98. package/dist/node_modules/rxjs/node_modules/tslib/tslib.es6.js.map +1 -0
  99. package/dist/pages/AdminDashboardPage.js +118 -91
  100. package/dist/pages/AdminDashboardPage.js.map +1 -1
  101. package/dist/pages/AdminReviewModerationPage.js +67 -61
  102. package/dist/pages/AdminReviewModerationPage.js.map +1 -1
  103. package/dist/pages/AdminStoresPage.js +424 -371
  104. package/dist/pages/AdminStoresPage.js.map +1 -1
  105. package/dist/pages/AdminSubmissionsQueuePage.js +303 -286
  106. package/dist/pages/AdminSubmissionsQueuePage.js.map +1 -1
  107. package/dist/pages/AppDetailPage.js +172 -135
  108. package/dist/pages/AppDetailPage.js.map +1 -1
  109. package/dist/pages/AppSettingsPage.js +83 -300
  110. package/dist/pages/AppSettingsPage.js.map +1 -1
  111. package/dist/pages/CartPage.js +71 -79
  112. package/dist/pages/CartPage.js.map +1 -1
  113. package/dist/pages/InstalledAppsPage.js +120 -337
  114. package/dist/pages/InstalledAppsPage.js.map +1 -1
  115. package/dist/pages/MarketplaceHomePage.js +196 -205
  116. package/dist/pages/MarketplaceHomePage.js.map +1 -1
  117. package/dist/pages/MyLicensesPage.js +70 -75
  118. package/dist/pages/MyLicensesPage.js.map +1 -1
  119. package/dist/pages/OrderConfirmationPage.js +70 -37
  120. package/dist/pages/OrderConfirmationPage.js.map +1 -1
  121. package/dist/pages/OrdersPage.js +60 -68
  122. package/dist/pages/OrdersPage.js.map +1 -1
  123. package/dist/pages/ProductDetailPage.js +794 -752
  124. package/dist/pages/ProductDetailPage.js.map +1 -1
  125. package/dist/providers/StoreProvider.js +3 -3
  126. package/package.json +2 -2
  127. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +0 -1
  128. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/errors/utils.js.map +0 -1
  129. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/core/ApolloLink.js.map +0 -1
  130. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/subscriptions/index.js.map +0 -1
  131. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/utils/createOperation.js.map +0 -1
  132. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/caching/sizes.js.map +0 -1
  133. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/graphql/print.js.map +0 -1
  134. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/caches.js.map +0 -1
  135. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +0 -1
  136. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMainDefinition.js.map +0 -1
  137. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +0 -9
  138. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +0 -1
  139. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +0 -1
  140. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationName.js +0 -8
  141. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +0 -1
  142. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/global.js.map +0 -1
  143. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/maybe.js +0 -10
  144. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +0 -1
  145. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/isNonNullObject.js +0 -8
  146. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/isNonNullObject.js.map +0 -1
  147. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +0 -1
  148. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/memoize.js.map +0 -1
  149. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +0 -1
  150. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/invariant/index.js.map +0 -1
  151. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/version.js +0 -6
  152. package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/version.js.map +0 -1
  153. package/dist/node_modules/.bun/@wry_caches@1.0.1/node_modules/@wry/caches/lib/weak.js.map +0 -1
  154. package/dist/node_modules/.bun/@wry_trie@0.5.0/node_modules/@wry/trie/lib/index.js.map +0 -1
  155. package/dist/node_modules/.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws/dist/client.js.map +0 -1
  156. package/dist/node_modules/.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws/dist/common-CGW11Fyb.js.map +0 -1
  157. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +0 -1
  158. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Observable.js.map +0 -1
  159. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +0 -1
  160. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +0 -1
  161. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/config.js.map +0 -1
  162. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +0 -1
  163. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +0 -1
  164. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +0 -1
  165. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +0 -1
  166. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +0 -11
  167. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +0 -1
  168. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +0 -1
  169. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +0 -1
  170. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/identity.js +0 -8
  171. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +0 -1
  172. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +0 -8
  173. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +0 -1
  174. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/noop.js +0 -6
  175. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +0 -1
  176. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +0 -1
  177. package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +0 -1
  178. package/dist/node_modules/.bun/tslib@2.8.1/node_modules/tslib/tslib.es6.js.map +0 -1
  179. package/dist/pages/ProductReviewsPage.js +0 -87
  180. package/dist/pages/ProductReviewsPage.js.map +0 -1
  181. package/dist/pages/PublisherDashboardPage.js +0 -160
  182. package/dist/pages/PublisherDashboardPage.js.map +0 -1
  183. package/dist/pages/PublisherRevenuePage.js +0 -140
  184. package/dist/pages/PublisherRevenuePage.js.map +0 -1
  185. package/dist/pages/PublisherSubmissionsPage.js +0 -179
  186. package/dist/pages/PublisherSubmissionsPage.js.map +0 -1
  187. package/dist/pages/PublisherSubmitPage.js +0 -230
  188. package/dist/pages/PublisherSubmitPage.js.map +0 -1
  189. /package/dist/node_modules/{.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo → @apollo}/client/utilities/caching/sizes.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ProductDetailPage.js","names":[],"sources":["../../src/pages/ProductDetailPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport { useParams, useNavigate, useLocation } from 'react-router-dom';\nimport { useEventBus } from '@burdenoff/fe-libs/shared/events';\nimport {\n ArrowLeft,\n Star,\n ShieldCheck,\n Check,\n ThumbsUp,\n Package,\n AlertCircle,\n ShoppingCart,\n Loader2,\n} from 'lucide-react';\nimport { useStore } from '../providers/StoreProvider';\nimport { nativeConfirm, nativeImpact, nativeNotify } from '../utils/nativeBridge';\nimport {\n useCreateReview,\n useDeleteReview,\n useMarkReviewHelpful,\n useStoreProductDetails,\n useUpdateReview,\n} from '../hooks/useStoreGraphQL';\nimport { useCart } from '../hooks/useCart';\nimport { useInstallations } from '../hooks/useInstallations';\nimport { formatNumber, formatPrice } from '../utils';\nimport { InstallAppModal } from '../components/InstallAppModal';\nimport type {\n Product,\n ItemType,\n ProductType,\n PricingModel as CartPricingModel,\n ProductStatus,\n} from '../types';\n\n// ============================================================================\n// Type Definitions for GraphQL Response\n// ============================================================================\n\ninterface Publisher {\n id: string;\n userId?: string;\n name: string;\n email?: string;\n websiteUrl?: string;\n logoUrl?: string;\n bio?: string;\n isVerified: boolean;\n totalSales?: number;\n totalEarnings?: number;\n createdAt?: string;\n}\n\ninterface ProductReview {\n id: string;\n productId: string;\n userId: string;\n rating: number;\n title?: string;\n comment?: string;\n status: string;\n helpful: number;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface RelatedProduct {\n id: string;\n name: string;\n slug?: string;\n icon?: string;\n type: string;\n price: number;\n pricingModel: string;\n rating?: number;\n reviewCount?: number;\n downloads: number;\n publisher?: {\n id: string;\n name: string;\n isVerified: boolean;\n };\n}\n\ninterface RatingDistribution {\n fiveStars: number;\n fourStars: number;\n threeStars: number;\n twoStars: number;\n oneStar: number;\n}\n\ninterface UserEntitlement {\n id: string;\n status: string;\n licenseKey?: string;\n expiresAt?: string;\n}\n\ninterface StoreProduct {\n id: string;\n name: string;\n slug?: string;\n type: string;\n nature: string;\n status: string;\n description?: string;\n longDescription?: string;\n pricingModel: string;\n price: number;\n currency: string;\n icon?: string;\n screenshots: string[];\n videoUrls?: string[];\n documentationUrl?: string;\n repositoryUrl?: string;\n category?: string;\n tags?: string[];\n featured: boolean;\n zipFileUrl?: string;\n downloads: number;\n viewCount?: number;\n rating?: number;\n reviewCount: number;\n publishedAt?: string;\n createdAt: string;\n updatedAt: string;\n // Manifest fields\n subType?: string;\n manifestVersion?: string;\n authorName?: string;\n license?: string;\n minPlatformVersion?: string;\n compatibleProducts?: string[];\n requiredPermissions?: string[];\n integrationDeps?: string[];\n // Physical product fields\n sku?: string;\n stockQuantity?: number;\n trackInventory?: boolean;\n requiresShipping?: boolean;\n weight?: number;\n weightUnit?: string;\n brand?: string;\n manifest?: Record<string, unknown>;\n publisher?: Publisher;\n}\n\ninterface StoreProductDetailsResponse {\n product: StoreProduct;\n publisher: Publisher;\n reviews: ProductReview[];\n reviewsCount: number;\n relatedProducts: RelatedProduct[];\n userReview?: ProductReview;\n isPurchased: boolean;\n userEntitlement?: UserEntitlement;\n ratingDistribution?: RatingDistribution;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Convert StoreProduct (GraphQL) to Product (Cart) type\n */\nconst convertToCartProduct = (storeProduct: StoreProduct, publisher?: Publisher): Product => {\n // Map GraphQL pricing model to cart pricing model\n const mapPricingModel = (model: string): CartPricingModel => {\n const mapping: Record<string, CartPricingModel> = {\n FREE: 'FREE',\n PAID_ONETIME: 'ONE_TIME',\n SUBSCRIPTION: 'SUBSCRIPTION',\n USAGE_BASED: 'USAGE_BASED',\n FREEMIUM: 'FREEMIUM',\n };\n return mapping[model] || 'ONE_TIME';\n };\n\n // Map product type\n const mapProductType = (type: string): ProductType => {\n const mapping: Record<string, ProductType> = {\n APP: 'STANDALONE_APP',\n BOTAPP: 'STANDALONE_APP',\n AGENT: 'STANDALONE_APP',\n WORKFLOW: 'WORKFLOW_TEMPLATE',\n TEMPLATE: 'WORKFLOW_TEMPLATE',\n INTEGRATION: 'API_INTEGRATION',\n EXTENSION: 'BROWSER_EXTENSION',\n THEME: 'UI_THEME',\n PLUGIN: 'WORKSPACE_MODULE',\n COMPONENT: 'WORKSPACE_MODULE',\n WIDGET: 'WORKSPACE_MODULE',\n VIBEMODULE: 'WORKSPACE_MODULE',\n CONSOLE: 'STANDALONE_APP',\n NODE: 'WORKSPACE_MODULE',\n };\n return mapping[type] || 'STANDALONE_APP';\n };\n\n // Map item type\n const mapItemType = (nature: string, type: string): ItemType => {\n if (nature === 'PHYSICAL') return 'PHYSICAL';\n const typeMapping: Record<string, ItemType> = {\n APP: 'APP',\n BOTAPP: 'APP',\n AGENT: 'APP',\n WORKFLOW: 'WORKFLOW',\n TEMPLATE: 'TEMPLATE',\n INTEGRATION: 'INTEGRATION',\n EXTENSION: 'EXTENSION',\n THEME: 'THEME',\n };\n return typeMapping[type] || 'APP';\n };\n\n return {\n id: storeProduct.id,\n publisherId: publisher?.id || '',\n publisher: {\n id: publisher?.id || '',\n name: publisher?.name || storeProduct.authorName || 'Unknown',\n displayName: publisher?.name || storeProduct.authorName || 'Unknown',\n email: publisher?.email || '',\n verified: publisher?.isVerified || false,\n totalProducts: 0,\n totalDownloads: 0,\n averageRating: 0,\n joinedAt: publisher?.createdAt || storeProduct.createdAt,\n website: publisher?.websiteUrl,\n logoUrl: publisher?.logoUrl,\n },\n name: storeProduct.name,\n slug: storeProduct.slug || storeProduct.id,\n displayName: storeProduct.name,\n description: storeProduct.longDescription || storeProduct.description || '',\n shortDescription: storeProduct.description || '',\n iconUrl: storeProduct.icon,\n screenshotUrls: storeProduct.screenshots || [],\n videoUrls: storeProduct.videoUrls || [],\n itemType: mapItemType(storeProduct.nature, storeProduct.type),\n type: mapProductType(storeProduct.type),\n tags: storeProduct.tags || [],\n pricingModel: mapPricingModel(storeProduct.pricingModel),\n basePrice: storeProduct.price,\n currency: storeProduct.currency || 'USD',\n variants: [],\n status: (storeProduct.status as ProductStatus) || 'PUBLISHED',\n featured: storeProduct.featured,\n verified: publisher?.isVerified || false,\n downloadCount: storeProduct.downloads,\n installCount: storeProduct.downloads,\n orderCount: 0,\n averageRating: storeProduct.rating || 0,\n reviewCount: storeProduct.reviewCount,\n createdAt: storeProduct.createdAt,\n updatedAt: storeProduct.updatedAt,\n publishedAt: storeProduct.publishedAt,\n };\n};\n\n// ============================================================================\n// Helper Components\n// ============================================================================\n\n/**\n * Rating bar component for rating distribution\n */\nconst RatingBar: FC<{ stars: number; percentage: number; count: number }> = ({\n stars,\n percentage,\n count,\n}) => (\n <div className=\"flex items-center gap-2\">\n <span className=\"w-3 text-xs text-text-muted\">{stars}</span>\n <div className=\"h-2 flex-1 overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-full rounded-full bg-status-warning-bg-subtle\"\n style={{ width: `${percentage}%` }}\n />\n </div>\n <span className=\"w-12 text-right text-xs text-text-muted\">{formatNumber(count)}</span>\n </div>\n);\n\n/**\n * Review card component\n */\nconst ReviewCard: FC<{\n review: ProductReview;\n onMarkHelpful: (reviewId: string) => void;\n markingHelpful: boolean;\n}> = ({ review, onMarkHelpful, markingHelpful }) => {\n const formatDate = (dateString: string) => {\n try {\n return new Date(dateString).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n } catch {\n return dateString;\n }\n };\n\n return (\n <div className=\"rounded-lg border border-border-default bg-bg-surface p-4\">\n <div className=\"mb-3 flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex size-10 items-center justify-center rounded-full bg-bg-sunken text-text-muted\">\n {review.userId.charAt(0).toUpperCase()}\n </div>\n <div>\n <p className=\"font-medium text-text-primary\">User {review.userId.slice(0, 8)}</p>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex gap-0.5\">\n {[1, 2, 3, 4, 5].map((star) => (\n <Star\n key={star}\n className={`size-3 ${\n star <= review.rating\n ? 'fill-current text-status-warning-text'\n : 'text-text-muted'\n }`}\n />\n ))}\n </div>\n <span className=\"text-xs text-text-muted\">{formatDate(review.createdAt)}</span>\n </div>\n </div>\n </div>\n </div>\n {review.title && <h4 className=\"mb-2 font-medium text-text-primary\">{review.title}</h4>}\n {review.comment && <p className=\"mb-3 text-sm text-text-muted\">{review.comment}</p>}\n <div className=\"flex items-center justify-between\">\n <button\n type=\"button\"\n onClick={() => onMarkHelpful(review.id)}\n disabled={markingHelpful}\n aria-label={`Mark review from ${review.userId} as helpful`}\n className=\"flex items-center gap-1 text-xs text-text-muted transition-colors hover:text-text-primary disabled:cursor-not-allowed disabled:opacity-60\"\n >\n <ThumbsUp className=\"size-3.5\" />\n <span>{markingHelpful ? 'Updating…' : `Helpful (${review.helpful})`}</span>\n </button>\n </div>\n </div>\n );\n};\n\n/**\n * Loading skeleton component - comprehensive skeleton matching full page layout\n */\nconst LoadingSkeleton: FC = () => (\n <div className=\"h-full overflow-y-auto\">\n {/* Header Skeleton */}\n <div className=\"sticky top-0 z-10 border-b border-border-default bg-bg-surface px-6 py-4\">\n <div className=\"flex items-center gap-4\">\n <div className=\"size-10 animate-pulse rounded-lg bg-bg-sunken\" />\n <div className=\"h-6 w-48 flex-1 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"flex gap-2\">\n <div className=\"size-10 animate-pulse rounded-lg bg-bg-sunken\" />\n <div className=\"size-10 animate-pulse rounded-lg bg-bg-sunken\" />\n </div>\n </div>\n </div>\n\n <div className=\"mx-auto max-w-6xl p-6\">\n {/* App Header Section Skeleton */}\n <div className=\"mb-8 flex flex-col gap-6 md:flex-row\">\n {/* App Icon & Basic Info */}\n <div className=\"flex gap-4 md:w-1/2\">\n <div className=\"size-28 animate-pulse rounded-2xl bg-bg-sunken\" />\n <div className=\"flex flex-1 flex-col justify-center gap-2\">\n <div className=\"h-8 w-3/4 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"flex items-center gap-2\">\n <div className=\"h-4 w-32 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"size-4 animate-pulse rounded-full bg-bg-sunken\" />\n </div>\n <div className=\"flex gap-3\">\n <div className=\"h-5 w-16 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"h-5 w-24 animate-pulse rounded bg-bg-sunken\" />\n </div>\n </div>\n </div>\n\n {/* Rating & Install Skeleton */}\n <div className=\"flex flex-col gap-4 md:w-1/2 md:items-end\">\n <div className=\"flex items-center gap-4\">\n <div className=\"text-center\">\n <div className=\"h-10 w-16 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"mt-1 h-3 w-20 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"h-12 w-px bg-border-default\" />\n <div className=\"text-center\">\n <div className=\"h-8 w-16 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"mt-1 h-3 w-16 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"h-12 w-px bg-border-default\" />\n <div className=\"text-center\">\n <div className=\"h-8 w-20 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"mt-1 h-3 w-12 animate-pulse rounded bg-bg-sunken\" />\n </div>\n </div>\n <div className=\"flex gap-3\">\n <div className=\"h-12 w-40 animate-pulse rounded-lg bg-bg-sunken\" />\n <div className=\"size-12 animate-pulse rounded-lg bg-bg-sunken\" />\n </div>\n </div>\n </div>\n\n {/* Screenshots Skeleton */}\n <section className=\"mb-8\">\n <div className=\"aspect-video animate-pulse rounded-lg bg-bg-sunken\" />\n <div className=\"mt-4 flex gap-4\">\n {[...Array(4)].map((_, i) => (\n <div key={i} className=\"h-20 w-36 animate-pulse rounded-lg bg-bg-sunken\" />\n ))}\n </div>\n </section>\n\n {/* About Section Skeleton */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center gap-2\">\n <div className=\"size-5 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"h-6 w-32 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"animate-pulse rounded-lg border border-border-default bg-bg-surface p-4\">\n <div className=\"space-y-2\">\n <div className=\"h-4 w-full rounded bg-bg-sunken\" />\n <div className=\"h-4 w-full rounded bg-bg-sunken\" />\n <div className=\"h-4 w-3/4 rounded bg-bg-sunken\" />\n <div className=\"h-4 w-5/6 rounded bg-bg-sunken\" />\n </div>\n <div className=\"mt-4 flex gap-2\">\n {[...Array(4)].map((_, i) => (\n <div key={i} className=\"h-6 w-16 rounded-full bg-bg-sunken\" />\n ))}\n </div>\n </div>\n </section>\n\n {/* Ratings & Reviews Skeleton */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <div className=\"size-5 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"h-6 w-40 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"h-4 w-16 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"mb-6 flex flex-col gap-6 md:flex-row\">\n <div className=\"animate-pulse rounded-lg border border-border-default bg-bg-surface p-4 md:w-64\">\n <div className=\"flex items-center gap-6\">\n <div className=\"text-center\">\n <div className=\"h-12 w-16 rounded bg-bg-sunken\" />\n <div className=\"my-1 flex justify-center gap-0.5\">\n {[...Array(5)].map((_, i) => (\n <div key={i} className=\"size-4 rounded bg-bg-sunken\" />\n ))}\n </div>\n <div className=\"h-3 w-20 rounded bg-bg-sunken\" />\n </div>\n <div className=\"flex-1 space-y-1\">\n {[...Array(5)].map((_, i) => (\n <div key={i} className=\"flex items-center gap-2\">\n <div className=\"h-2 w-3 rounded bg-bg-sunken\" />\n <div className=\"h-2 flex-1 rounded-full bg-bg-sunken\" />\n <div className=\"h-2 w-8 rounded bg-bg-sunken\" />\n </div>\n ))}\n </div>\n </div>\n </div>\n <div className=\"h-12 w-32 animate-pulse rounded-lg bg-bg-sunken\" />\n </div>\n {/* Review Cards Skeleton */}\n <div className=\"space-y-4\">\n {[...Array(2)].map((_, i) => (\n <div\n key={i}\n className=\"animate-pulse rounded-lg border border-border-default bg-bg-surface p-4\"\n >\n <div className=\"mb-3 flex items-start gap-3\">\n <div className=\"size-10 rounded-full bg-bg-sunken\" />\n <div className=\"flex-1\">\n <div className=\"h-4 w-32 rounded bg-bg-sunken\" />\n <div className=\"mt-1 flex items-center gap-2\">\n <div className=\"flex gap-0.5\">\n {[...Array(5)].map((_, j) => (\n <div key={j} className=\"size-3 rounded bg-bg-sunken\" />\n ))}\n </div>\n <div className=\"h-3 w-20 rounded bg-bg-sunken\" />\n </div>\n </div>\n </div>\n <div className=\"space-y-2\">\n <div className=\"h-4 w-full rounded bg-bg-sunken\" />\n <div className=\"h-4 w-2/3 rounded bg-bg-sunken\" />\n </div>\n </div>\n ))}\n </div>\n </section>\n\n {/* Additional Info Skeleton */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center gap-2\">\n <div className=\"size-5 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"h-6 w-48 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"animate-pulse rounded-lg border border-border-default bg-bg-surface p-4\">\n <div className=\"grid gap-4 md:grid-cols-2\">\n {[...Array(6)].map((_, i) => (\n <div key={i}>\n <div className=\"h-3 w-16 rounded bg-bg-sunken\" />\n <div className=\"mt-1 h-5 w-24 rounded bg-bg-sunken\" />\n </div>\n ))}\n </div>\n </div>\n </section>\n\n {/* Related Products Skeleton */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <div className=\"size-5 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"h-6 w-40 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"h-4 w-16 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"grid gap-4 md:grid-cols-4\">\n {[...Array(4)].map((_, i) => (\n <div\n key={i}\n className=\"animate-pulse rounded-lg border border-border-default bg-bg-surface p-3\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"size-14 rounded-xl bg-bg-sunken\" />\n <div className=\"flex-1\">\n <div className=\"h-4 w-24 rounded bg-bg-sunken\" />\n <div className=\"mt-1 h-3 w-16 rounded bg-bg-sunken\" />\n <div className=\"mt-1 flex items-center gap-2\">\n <div className=\"h-3 w-8 rounded bg-bg-sunken\" />\n <div className=\"h-3 w-12 rounded bg-bg-sunken\" />\n </div>\n </div>\n </div>\n </div>\n ))}\n </div>\n </section>\n\n {/* Publisher Skeleton */}\n <section className=\"mb-8\">\n <div className=\"mb-4 h-6 w-36 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"animate-pulse rounded-lg border border-border-default bg-bg-surface p-4\">\n <div className=\"flex items-center gap-4\">\n <div className=\"size-12 rounded-lg bg-bg-sunken\" />\n <div>\n <div className=\"flex items-center gap-2\">\n <div className=\"h-5 w-32 rounded bg-bg-sunken\" />\n <div className=\"size-4 rounded-full bg-bg-sunken\" />\n </div>\n <div className=\"mt-1 h-4 w-40 rounded bg-bg-sunken\" />\n </div>\n </div>\n <div className=\"mt-3 space-y-2\">\n <div className=\"h-4 w-full rounded bg-bg-sunken\" />\n <div className=\"h-4 w-2/3 rounded bg-bg-sunken\" />\n </div>\n </div>\n </section>\n </div>\n </div>\n);\n\n/**\n * Error display component\n */\nconst ErrorDisplay: FC<{ error: Error; onRetry: () => void; onBack: () => void }> = ({\n error,\n onRetry,\n onBack,\n}) => (\n <div className=\"flex h-full items-center justify-center\">\n <div className=\"text-center\">\n <AlertCircle className=\"mx-auto mb-4 size-12 text-status-error-text\" />\n <h2 className=\"mb-2 text-xl font-semibold text-text-primary\">Failed to load product</h2>\n <p className=\"mb-4 text-text-muted\">\n {error.message || 'An error occurred while loading the product details.'}\n </p>\n <div className=\"flex justify-center gap-3\">\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-action-primary-text transition-opacity hover:opacity-90\"\n >\n Try Again\n </button>\n <button\n type=\"button\"\n onClick={onBack}\n className=\"rounded-lg border border-border-default px-4 py-2 text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n Go Back\n </button>\n </div>\n </div>\n </div>\n);\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * Product Detail Page Component\n *\n * Displays comprehensive product details using real GraphQL data\n */\nexport const ProductDetailPage: FC = () => {\n const { productId } = useParams<{ productId: string }>();\n const navigate = useNavigate();\n const location = useLocation();\n const { basePath, workspaceId } = useStore();\n const { addProduct, cartItems, addingToCart, createOrder, checkingOut } = useCart();\n const installationsFilter = useMemo(\n () => (productId && workspaceId ? { productId, workspaceId } : undefined),\n [productId, workspaceId]\n );\n const { installations: myInstallations, refetch: refetchInstallations } = useInstallations({\n filter: installationsFilter,\n limit: 1,\n });\n const isInstalledInCurrentWorkspace = myInstallations.some(\n (i) => i.productId === productId && i.workspaceId === workspaceId && i.status === 'ACTIVE'\n );\n const { createReview, loading: creatingReview } = useCreateReview();\n const { updateReview, loading: updatingReview } = useUpdateReview();\n const { deleteReview, loading: deletingReview } = useDeleteReview();\n const { markHelpful, loading: markingHelpful } = useMarkReviewHelpful();\n const bus = useEventBus();\n\n const [showFullDescription, setShowFullDescription] = useState(false);\n const [showAllReviews, setShowAllReviews] = useState(false);\n const [buyingNow, setBuyingNow] = useState(false);\n const [actionError, setActionError] = useState<string | null>(null);\n const [reviewNotice, setReviewNotice] = useState<string | null>(null);\n const [reviewNoticeTone, setReviewNoticeTone] = useState<'success' | 'error'>('success');\n const [isReviewFormOpen, setIsReviewFormOpen] = useState(false);\n const [reviewTitle, setReviewTitle] = useState('');\n const [reviewComment, setReviewComment] = useState('');\n const [reviewRating, setReviewRating] = useState(5);\n const [helpfulReviewId, setHelpfulReviewId] = useState<string | null>(null);\n\n // Install modal state\n const [isInstallModalOpen, setIsInstallModalOpen] = useState(false);\n\n // Fetch product details using GraphQL\n const { data, loading, error, refetch } = useStoreProductDetails({\n id: productId,\n slug: productId, // Also try as slug\n includeReviews: true,\n reviewsLimit: 10,\n includeRelated: true,\n relatedLimit: 4,\n includeVersions: true,\n });\n\n // Cast data to typed response\n const productDetails = data as StoreProductDetailsResponse | null;\n const product = productDetails?.product;\n const publisher = productDetails?.publisher;\n\n // Check if product is already in cart (must be before any early returns)\n const isInCart = cartItems.some((item) => item.productId === product?.id);\n\n // Handle Add to Cart (must be before any early returns)\n const handleAddToCart = useCallback(async () => {\n if (!product) return;\n\n setActionError(null);\n\n if (isInCart) {\n navigate(`${basePath}/cart`);\n return;\n }\n\n try {\n const cartProduct = convertToCartProduct(product, publisher);\n // Add to backend cart via GraphQL API call\n // This will make a mutation to global-public-gateway:4004 → tenantmodule-store-svc:4017\n await addProduct(cartProduct, undefined, 1);\n // Cart drawer will open automatically after adding\n } catch (error) {\n console.error('Failed to add product to cart:', error);\n setActionError('Failed to add this product to cart. Please try again.');\n }\n }, [product, publisher, addProduct, isInCart, navigate, basePath]);\n\n // Handle Buy Now - creates an order and immediately proceeds to checkout\n const handleBuyNow = useCallback(async () => {\n if (!product) return;\n\n setActionError(null);\n setBuyingNow(true);\n\n try {\n // Get product price\n const price = product.price || 0;\n\n // Build line item for this product\n const lineItem = {\n productId: product.id,\n name: product.name,\n quantity: 1,\n unitPrice: price,\n subtotal: price,\n itemType: product.nature?.toLowerCase() || 'digital',\n pricingModel: product.pricingModel || 'PAID_ONETIME',\n };\n\n // Create order input\n const orderInput = {\n total: price,\n lineItems: [lineItem],\n billingAccountId: '', // Will be set on billing page\n };\n\n // Call createStoreOrder mutation to create PENDING order\n const order = await createOrder(orderInput);\n\n if (order?.id) {\n // Navigate to billing page, preserving org/workspace/tenant context params\n navigate(`/billing/checkout/store/${order.id}${location.search}`);\n } else {\n console.error('Failed to create order');\n setActionError('Failed to create order. Please try again.');\n setBuyingNow(false);\n }\n } catch (error) {\n console.error('Buy Now error:', error);\n const message = error instanceof Error ? error.message : 'Failed to start checkout';\n setActionError(message);\n setBuyingNow(false);\n }\n }, [product, createOrder, navigate]);\n\n // Handle Install Free - Open modal for workspace selection (must be before any early returns)\n const handleInstallFree = useCallback(() => {\n if (!product) return;\n setIsInstallModalOpen(true);\n }, [product]);\n\n // Emit product.viewed event once product data loads. Read product via ref so\n // we only emit on id transitions, not on every field change.\n const productRef = useRef(product);\n productRef.current = product;\n const busRef = useRef(bus);\n busRef.current = bus;\n useEffect(() => {\n const p = productRef.current;\n if (!p) return;\n (busRef.current as unknown as { emit: (name: string, payload: unknown) => void }).emit(\n 'store.product.viewed',\n {\n productId: p.id,\n productSlug: p.slug,\n productType: p.type,\n pricingModel: p.pricingModel,\n }\n );\n }, [product?.id]);\n\n // Handle successful installation (must be before any early returns)\n const handleInstallSuccess = useCallback(\n (workspaceId: string, workspaceName: string) => {\n if (!product) return;\n (bus as unknown as { emit: (name: string, payload: unknown) => void }).emit(\n 'store.product.installed',\n {\n productId: product.id,\n workspaceId,\n }\n );\n console.log(\n `Successfully installed ${product.name} to workspace ${workspaceName} (${workspaceId})`\n );\n void refetchInstallations();\n },\n [product, bus, refetchInstallations]\n );\n\n // Handle installation error (must be before any early returns)\n const handleInstallError = useCallback((error: Error) => {\n console.error('Installation failed:', error.message);\n // Error is shown in the modal\n }, []);\n\n const openReviewForm = useCallback(() => {\n setReviewTitle(productDetails?.userReview?.title ?? '');\n setReviewComment(productDetails?.userReview?.comment ?? '');\n setReviewRating(productDetails?.userReview?.rating ?? 5);\n setReviewNotice(null);\n setReviewNoticeTone('success');\n setIsReviewFormOpen(true);\n }, [productDetails?.userReview]);\n\n const handleSubmitReview = useCallback(async () => {\n if (!product) {\n return;\n }\n\n if (reviewRating < 1 || reviewRating > 5) {\n setReviewNoticeTone('error');\n setReviewNotice('Choose a rating from 1 to 5 stars.');\n return;\n }\n\n const payload = {\n productId: product.id,\n rating: reviewRating,\n title: reviewTitle.trim() || undefined,\n comment: reviewComment.trim() || undefined,\n };\n\n const result = productDetails?.userReview\n ? await updateReview(productDetails.userReview.id, {\n rating: payload.rating,\n title: payload.title,\n comment: payload.comment,\n })\n : await createReview(payload);\n\n if (!result) {\n setReviewNoticeTone('error');\n setReviewNotice('We could not save your review. Please try again.');\n return;\n }\n\n setReviewNoticeTone('success');\n setReviewNotice(\n productDetails?.userReview ? 'Your review was updated.' : 'Your review was submitted.'\n );\n setIsReviewFormOpen(false);\n (bus as unknown as { emit: (name: string, payload: unknown) => void }).emit(\n 'store.review.submitted',\n {\n productId: product.id,\n rating: reviewRating,\n }\n );\n await refetch();\n }, [\n bus,\n createReview,\n product,\n productDetails?.userReview,\n refetch,\n reviewComment,\n reviewRating,\n reviewTitle,\n updateReview,\n ]);\n\n const handleDeleteReview = useCallback(async () => {\n if (!productDetails?.userReview) {\n return;\n }\n void nativeImpact('medium');\n const confirmed = await nativeConfirm({\n title: 'Delete review',\n message: 'Are you sure you want to remove your review?',\n okButtonTitle: 'Delete',\n cancelButtonTitle: 'Cancel',\n });\n if (confirmed === false) {\n return;\n }\n\n const deleted = await deleteReview(productDetails.userReview.id);\n if (!deleted) {\n setReviewNoticeTone('error');\n setReviewNotice('We could not remove your review. Please try again.');\n void nativeNotify('error');\n return;\n }\n\n setReviewNoticeTone('success');\n setReviewNotice('Your review was removed.');\n setIsReviewFormOpen(false);\n setReviewTitle('');\n setReviewComment('');\n setReviewRating(5);\n void nativeNotify('success');\n await refetch();\n }, [deleteReview, productDetails?.userReview, refetch]);\n\n const handleMarkHelpful = useCallback(\n async (reviewId: string) => {\n setHelpfulReviewId(reviewId);\n const result = await markHelpful(reviewId);\n if (result) {\n await refetch();\n }\n setHelpfulReviewId(null);\n },\n [markHelpful, refetch]\n );\n\n // Handle loading state\n if (loading) {\n return <LoadingSkeleton />;\n }\n\n // Handle error state\n if (error) {\n return (\n <ErrorDisplay\n error={error}\n onRetry={refetch}\n onBack={() => navigate(`${basePath}/marketplace`)}\n />\n );\n }\n\n // Handle not found state\n if (!productDetails?.product) {\n return (\n <div className=\"flex h-full items-center justify-center\">\n <div className=\"text-center\">\n <h2 className=\"mb-2 text-xl font-semibold text-text-primary\">Product not found</h2>\n <p className=\"mb-4 text-text-muted\">\n The product you are looking for does not exist or has been removed.\n </p>\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/marketplace`)}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-action-primary-text transition-opacity hover:opacity-90\"\n >\n Back to Marketplace\n </button>\n </div>\n </div>\n );\n }\n\n const {\n reviews,\n reviewsCount,\n relatedProducts,\n ratingDistribution,\n isPurchased,\n userEntitlement,\n } = productDetails;\n\n // Type assertion: we know product is defined because we checked !productDetails?.product above\n const safeProduct = product!;\n\n // Calculate rating distribution percentages\n const totalRatings = ratingDistribution\n ? ratingDistribution.fiveStars +\n ratingDistribution.fourStars +\n ratingDistribution.threeStars +\n ratingDistribution.twoStars +\n ratingDistribution.oneStar\n : 0;\n\n const ratingDistributionData = ratingDistribution\n ? [\n {\n stars: 5,\n count: ratingDistribution.fiveStars,\n percentage: totalRatings > 0 ? (ratingDistribution.fiveStars / totalRatings) * 100 : 0,\n },\n {\n stars: 4,\n count: ratingDistribution.fourStars,\n percentage: totalRatings > 0 ? (ratingDistribution.fourStars / totalRatings) * 100 : 0,\n },\n {\n stars: 3,\n count: ratingDistribution.threeStars,\n percentage: totalRatings > 0 ? (ratingDistribution.threeStars / totalRatings) * 100 : 0,\n },\n {\n stars: 2,\n count: ratingDistribution.twoStars,\n percentage: totalRatings > 0 ? (ratingDistribution.twoStars / totalRatings) * 100 : 0,\n },\n {\n stars: 1,\n count: ratingDistribution.oneStar,\n percentage: totalRatings > 0 ? (ratingDistribution.oneStar / totalRatings) * 100 : 0,\n },\n ]\n : [];\n\n // Parse permissions from manifest or requiredPermissions\n // Filter out mis-serialized \"[object Object]\" strings that can occur if\n // the publish pipeline stores permission objects before they are stringified.\n const permissions = (safeProduct.requiredPermissions || []).filter(\n (p) => p && p !== '[object Object]',\n );\n\n // Parse integrations from integrationDeps\n const integrations = safeProduct.integrationDeps || [];\n\n // Pricing display\n const getPriceDisplay = () => {\n if (safeProduct.pricingModel === 'FREE') return 'Free';\n if (safeProduct.pricingModel === 'SUBSCRIPTION') {\n return `${formatPrice(safeProduct.price, safeProduct.currency)}/mo`;\n }\n return formatPrice(safeProduct.price, safeProduct.currency);\n };\n\n // Check if product is free\n const isFree = safeProduct.pricingModel === 'FREE' || safeProduct.price === 0;\n\n return (\n <div className=\"h-full overflow-y-auto bg-bg-base\">\n {/* Hero Section - Two Column Layout */}\n <div className=\"relative bg-bg-surface\">\n <div className=\"mx-auto max-w-7xl\">\n <div className=\"flex flex-col lg:flex-row\">\n {/* Left Column - Product Info */}\n <div className=\"flex-1 px-6 py-8 lg:max-w-xl lg:py-12\">\n {/* Back Button */}\n <button\n type=\"button\"\n onClick={() => navigate(-1)}\n className=\"mb-6 cursor-pointer inline-flex items-center gap-2 text-sm text-text-muted transition-colors hover:text-text-primary\"\n >\n <ArrowLeft className=\"size-4\" />\n Back\n </button>\n\n {/* App Title - Large Typography */}\n <h1 className=\"mb-4 text-4xl font-normal leading-tight text-text-primary lg:text-5xl\">\n {safeProduct.name}\n </h1>\n\n {/* Publisher */}\n <div className=\"mb-2\">\n {publisher?.websiteUrl ? (\n <a\n href={publisher.websiteUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-base font-medium text-text-link hover:underline\"\n >\n {publisher.name}\n </a>\n ) : (\n <span className=\"text-base font-medium text-text-primary\">\n {publisher?.name || safeProduct.authorName || 'Unknown Publisher'}\n </span>\n )}\n {publisher?.isVerified && (\n <ShieldCheck className=\"ml-1.5 inline size-4 text-status-success-text\" />\n )}\n </div>\n\n {/* Metadata */}\n <p className=\"mb-6 text-sm text-text-muted\">\n {safeProduct.category && <span>{safeProduct.category}</span>}\n {safeProduct.category && ' · '}\n {formatNumber(safeProduct.downloads)}+ downloads\n </p>\n\n {/* Stats Row */}\n <div className=\"mb-6 flex items-center gap-4\">\n {/* App Icon Badge */}\n <div className=\"flex size-12 items-center justify-center overflow-hidden rounded-xl bg-bg-sunken\">\n {safeProduct.icon ? (\n <img src={safeProduct.icon} alt=\"\" className=\"size-full object-cover\" />\n ) : (\n <span className=\"text-lg font-bold text-text-muted\">\n {safeProduct.name.charAt(0)}\n </span>\n )}\n </div>\n\n {/* Rating */}\n <div className=\"flex items-center gap-1 border-l border-border-default pl-4\">\n <span className=\"text-sm font-medium text-text-primary\">\n {(safeProduct.rating || 0).toFixed(1)}\n </span>\n <Star className=\"size-4 fill-current text-status-warning-text\" />\n <span className=\"ml-1 text-xs text-text-muted\">\n {formatNumber(reviewsCount || safeProduct.reviewCount)} reviews\n </span>\n </div>\n\n {/* Downloads */}\n <div className=\"border-l border-border-default pl-4\">\n <span className=\"text-sm font-medium text-text-primary\">\n {formatNumber(safeProduct.downloads)}+\n </span>\n <p className=\"text-xs text-text-muted\">Downloads</p>\n </div>\n\n {/* Type Badge */}\n <div className=\"border-l border-border-default pl-4\">\n <span className=\"rounded bg-bg-sunken px-2 py-1 text-xs font-medium text-text-primary\">\n {safeProduct.type}\n </span>\n <p className=\"mt-0.5 text-xs text-text-muted\">Type</p>\n </div>\n </div>\n\n {/* Action Buttons Row */}\n {actionError && (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-lg border border-status-error-bg bg-status-error-bg-subtle px-4 py-3 text-sm text-status-error-text\"\n >\n {actionError}\n </div>\n )}\n\n <div className=\"mb-6 flex items-center gap-3\">\n {isInstalledInCurrentWorkspace ? (\n <button\n type=\"button\"\n disabled\n className=\"flex items-center gap-2 rounded-full bg-status-success-bg-subtle px-8 py-3 font-medium text-status-success-text cursor-default\"\n >\n <svg\n className=\"size-4\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"2,8 6,12 14,4\" />\n </svg>\n Installed\n </button>\n ) : isPurchased && !isFree ? (\n <button\n type=\"button\"\n onClick={handleInstallFree}\n className=\"cursor-pointer rounded-full bg-action-primary-bg px-8 py-3 font-medium text-action-primary-text transition-opacity hover:opacity-90\"\n >\n Install to Workspace\n </button>\n ) : isFree ? (\n <button\n type=\"button\"\n onClick={handleInstallFree}\n className=\"cursor-pointer rounded-full bg-action-primary-bg px-8 py-3 font-medium text-action-primary-text transition-opacity hover:opacity-90\"\n >\n Install\n </button>\n ) : (\n <button\n type=\"button\"\n onClick={handleBuyNow}\n disabled={buyingNow || checkingOut}\n className=\"cursor-pointer flex items-center gap-2 rounded-full bg-action-primary-bg px-8 py-3 font-medium text-action-primary-text transition-opacity hover:opacity-90 disabled:opacity-70\"\n >\n {buyingNow || checkingOut ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Processing…\n </>\n ) : (\n `Buy ${getPriceDisplay()}`\n )}\n </button>\n )}\n\n {/* Add to Cart / Wishlist */}\n {!isFree && !isPurchased && (\n <button\n type=\"button\"\n onClick={handleAddToCart}\n disabled={addingToCart}\n className=\"cursor-pointer flex items-center gap-2 rounded-full border border-border-default px-4 py-3 text-sm text-text-primary transition-colors hover:bg-bg-sunken disabled:opacity-50\"\n >\n {addingToCart ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : isInCart ? (\n <Check className=\"size-4 text-status-success-text\" />\n ) : (\n <ShoppingCart className=\"size-4\" />\n )}\n {isInCart ? 'In Cart' : 'Add to Cart'}\n </button>\n )}\n </div>\n\n {/* Info Text */}\n <p className=\"flex items-center gap-2 text-xs text-text-muted\">\n <Package className=\"size-4\" />\n This app is available for your workspace\n </p>\n\n {/* License Status */}\n {userEntitlement && (\n <p className=\"mt-2 flex items-center gap-2 text-xs text-text-muted\">\n <ShieldCheck className=\"size-4 text-status-success-text\" />\n License: {userEntitlement.status}\n {userEntitlement.expiresAt &&\n ` (Expires: ${new Date(userEntitlement.expiresAt).toLocaleDateString()})`}\n </p>\n )}\n </div>\n\n {/* Right Column - Hero Screenshot */}\n <div className=\"relative flex-1 bg-bg-sunken lg:min-h-[500px]\">\n {safeProduct.screenshots && safeProduct.screenshots.length > 0 ? (\n <img\n src={safeProduct.screenshots[0]}\n alt={`${safeProduct.name} screenshot`}\n className=\"size-full object-cover\"\n />\n ) : (\n <div className=\"flex h-full min-h-[300px] items-center justify-center\">\n <div className=\"text-center\">\n <div className=\"mx-auto mb-4 flex size-24 items-center justify-center rounded-2xl bg-bg-surface text-4xl font-bold text-text-muted\">\n {safeProduct.name.charAt(0)}\n </div>\n <p className=\"text-sm text-text-muted\">No preview available</p>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n\n {/* Main Content Area */}\n <main className=\"mx-auto max-w-7xl px-6 py-8\">\n <div className=\"flex flex-col gap-8 lg:flex-row\">\n {/* Left Content */}\n <div className=\"flex-1 lg:max-w-3xl\">\n {/* Screenshots Gallery */}\n {safeProduct.screenshots && safeProduct.screenshots.length > 1 && (\n <section className=\"mb-8\">\n <div className=\"flex gap-4 overflow-x-auto pb-4\">\n {safeProduct.screenshots.map((screenshot, index) => (\n <div\n key={index}\n className=\"relative h-64 w-96 flex-shrink-0 overflow-hidden rounded-xl bg-bg-sunken\"\n >\n <img\n src={screenshot}\n alt={`Screenshot ${index + 1}`}\n className=\"size-full object-cover\"\n />\n </div>\n ))}\n </div>\n </section>\n )}\n\n {/* About this app */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between text-left\">\n <h2 className=\"text-lg font-medium text-text-primary\">About this app</h2>\n </div>\n <div className=\"text-sm leading-relaxed text-text-secondary\">\n <p className={!showFullDescription ? 'line-clamp-4' : ''}>\n {safeProduct.longDescription ||\n safeProduct.description ||\n 'No description available.'}\n </p>\n {((safeProduct.longDescription || safeProduct.description)?.length ?? 0) > 200 && (\n <button\n type=\"button\"\n onClick={() => setShowFullDescription(!showFullDescription)}\n className=\"cursor-pointer mt-3 text-sm font-medium text-text-link\"\n >\n {showFullDescription ? 'Show less' : 'Show more'}\n </button>\n )}\n </div>\n {/* Tags */}\n {safeProduct.tags && safeProduct.tags.length > 0 && (\n <div className=\"mt-4 flex flex-wrap gap-2\">\n {safeProduct.tags.map((tag) => (\n <span\n key={tag}\n className=\"rounded-full border border-border-default px-3 py-1.5 text-xs text-text-muted transition-colors hover:bg-bg-sunken\"\n >\n {tag}\n </span>\n ))}\n </div>\n )}\n </section>\n\n {/* Ratings & Reviews */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between text-left\">\n <h2 className=\"text-lg font-medium text-text-primary\">Ratings & Reviews</h2>\n </div>\n\n <div className=\"rounded-xl border border-border-default bg-bg-surface p-5\">\n {reviews && reviews.length > 0 ? (\n <div className=\"flex items-start gap-8\">\n {/* Rating Score */}\n <div className=\"text-center\">\n <p className=\"text-5xl font-light text-text-primary\">\n {(safeProduct.rating || 0).toFixed(1)}\n </p>\n <div className=\"my-2 flex justify-center gap-0.5\">\n {[1, 2, 3, 4, 5].map((star) => (\n <Star\n key={star}\n className={`size-4 ${\n star <= Math.round(safeProduct.rating || 0)\n ? 'fill-current text-status-warning-text'\n : 'text-text-muted'\n }`}\n />\n ))}\n </div>\n <p className=\"text-sm text-text-muted\">\n {formatNumber(reviewsCount || safeProduct.reviewCount)} reviews\n </p>\n </div>\n\n {/* Rating Distribution */}\n {ratingDistributionData.length > 0 && (\n <div className=\"flex-1 space-y-1.5\">\n {ratingDistributionData.map((item) => (\n <RatingBar key={item.stars} {...item} />\n ))}\n </div>\n )}\n </div>\n ) : (\n <div className=\"flex flex-col items-center justify-center py-6 text-center\">\n <div className=\"mb-3 flex gap-0.5\">\n {[1, 2, 3, 4, 5].map((star) => (\n <Star key={star} className=\"size-5 text-border-default\" />\n ))}\n </div>\n <p className=\"font-medium text-text-primary\">No reviews yet</p>\n <p className=\"mt-1 text-sm text-text-muted\">\n Be the first to share your experience with this app.\n </p>\n </div>\n )}\n\n {/* Write Review */}\n <div className=\"mt-6 border-t border-border-default pt-4\">\n {reviewNotice && (\n <p\n role={reviewNoticeTone === 'success' ? 'status' : 'alert'}\n className={`mb-3 rounded-lg px-3 py-2 text-sm ${\n reviewNoticeTone === 'success'\n ? 'bg-status-success-bg-subtle text-status-success-text'\n : 'bg-status-error-bg-subtle text-status-error-text'\n }`}\n >\n {reviewNotice}\n </p>\n )}\n {isPurchased || productDetails?.userReview ? (\n <div className=\"space-y-4\">\n <button\n type=\"button\"\n onClick={() =>\n isReviewFormOpen ? setIsReviewFormOpen(false) : openReviewForm()\n }\n className=\"w-full cursor-pointer py-2 text-center text-sm font-medium text-text-primary transition-colors hover:text-text-link\"\n >\n {productDetails?.userReview\n ? isReviewFormOpen\n ? 'Cancel review editing'\n : 'Edit your review'\n : isReviewFormOpen\n ? 'Cancel review'\n : 'Write a Review'}\n </button>\n\n {isReviewFormOpen && (\n <div className=\"rounded-xl border border-border-default bg-bg-sunken p-4\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Your rating</p>\n <div className=\"mt-2 flex flex-wrap gap-2\">\n {[1, 2, 3, 4, 5].map((star) => (\n <button\n key={star}\n type=\"button\"\n onClick={() => setReviewRating(star)}\n className={`cursor-pointer rounded-full border px-3 py-1.5 text-sm transition-colors ${\n reviewRating === star\n ? 'border-action-primary-border bg-action-primary-bg text-action-primary-text'\n : 'border-border-default bg-bg-surface text-text-primary hover:bg-bg-surface'\n }`}\n >\n {star} ★\n </button>\n ))}\n </div>\n </div>\n\n <label className=\"mt-4 block text-sm font-medium text-text-primary\">\n Title\n <input\n aria-label=\"Review title\"\n value={reviewTitle}\n onChange={(event) => setReviewTitle(event.target.value)}\n className=\"mt-2 w-full rounded-lg border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-primary outline-none focus:border-action-primary-border\"\n placeholder=\"Summarize your experience\"\n />\n </label>\n\n <label className=\"mt-4 block text-sm font-medium text-text-primary\">\n Review\n <textarea\n aria-label=\"Review body\"\n value={reviewComment}\n onChange={(event) => setReviewComment(event.target.value)}\n rows={4}\n required\n aria-required=\"true\"\n className=\"mt-2 w-full rounded-lg border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-primary outline-none focus:border-action-primary-border\"\n placeholder=\"What worked well? What should improve?\"\n />\n </label>\n\n <div className=\"mt-4 flex flex-wrap gap-3\">\n <button\n type=\"button\"\n onClick={handleSubmitReview}\n disabled={creatingReview || updatingReview}\n className=\"cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {creatingReview || updatingReview\n ? 'Saving...'\n : productDetails?.userReview\n ? 'Update Review'\n : 'Submit Review'}\n </button>\n {productDetails?.userReview && (\n <button\n type=\"button\"\n onClick={handleDeleteReview}\n disabled={deletingReview}\n className=\"cursor-pointer rounded-lg border border-status-error-border px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {deletingReview ? 'Removing...' : 'Delete Review'}\n </button>\n )}\n </div>\n </div>\n )}\n </div>\n ) : (\n <p className=\"text-center text-sm text-text-muted\">\n Purchase this app to submit a review.\n </p>\n )}\n </div>\n </div>\n\n {/* Reviews List */}\n {reviews && reviews.length > 0 && (\n <div className=\"mt-4 space-y-3\">\n <ul className=\"space-y-3\">\n {(showAllReviews ? reviews : reviews.slice(0, 2)).map((review) => (\n <li key={review.id}>\n <ReviewCard\n review={review}\n onMarkHelpful={handleMarkHelpful}\n markingHelpful={markingHelpful && helpfulReviewId === review.id}\n />\n </li>\n ))}\n </ul>\n {reviews.length > 2 && (\n <button\n type=\"button\"\n onClick={() => setShowAllReviews(!showAllReviews)}\n className=\"cursor-pointer text-sm font-medium text-text-link\"\n >\n {showAllReviews ? 'Show less' : `Show all ${reviews.length} reviews`}\n </button>\n )}\n </div>\n )}\n {(!reviews || reviews.length === 0) && (\n <p className=\"mt-4 text-sm text-text-muted\">\n No reviews yet. Be the first to review!\n </p>\n )}\n </section>\n\n {/* Permissions */}\n {permissions.length > 0 && (\n <section className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-medium text-text-primary\">Required Permissions</h2>\n <div className=\"space-y-2\">\n {permissions.map((permission) => (\n <div\n key={permission}\n className=\"flex items-center gap-3 rounded-lg bg-bg-surface px-4 py-3\"\n >\n <ShieldCheck className=\"size-5 text-status-success-text\" />\n <span className=\"text-sm text-text-primary\">{permission}</span>\n </div>\n ))}\n </div>\n </section>\n )}\n\n {/* Integrations */}\n {integrations.length > 0 && (\n <section className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-medium text-text-primary\">Integrations</h2>\n <div className=\"flex flex-wrap gap-2\">\n {integrations.map((integration) => (\n <span\n key={integration}\n className=\"rounded-lg bg-bg-surface px-4 py-2 text-sm font-medium text-text-primary\"\n >\n {integration}\n </span>\n ))}\n </div>\n </section>\n )}\n\n {/* Additional Information */}\n <section className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-medium text-text-primary\">Additional Information</h2>\n <div className=\"grid grid-cols-2 gap-6 md:grid-cols-3\">\n {safeProduct.manifestVersion && (\n <div>\n <p className=\"text-xs text-text-muted\">Version</p>\n <p className=\"mt-1 text-sm font-medium text-text-primary\">\n {safeProduct.manifestVersion}\n </p>\n </div>\n )}\n <div>\n <p className=\"text-xs text-text-muted\">Type</p>\n <p className=\"mt-1 text-sm font-medium text-text-primary\">{safeProduct.type}</p>\n </div>\n {safeProduct.publishedAt && (\n <div>\n <p className=\"text-xs text-text-muted\">Published</p>\n <p className=\"mt-1 text-sm font-medium text-text-primary\">\n {new Date(safeProduct.publishedAt).toLocaleDateString()}\n </p>\n </div>\n )}\n <div>\n <p className=\"text-xs text-text-muted\">Updated</p>\n <p className=\"mt-1 text-sm font-medium text-text-primary\">\n {new Date(safeProduct.updatedAt).toLocaleDateString()}\n </p>\n </div>\n {safeProduct.license && (\n <div>\n <p className=\"text-xs text-text-muted\">License</p>\n <p className=\"mt-1 text-sm font-medium text-text-primary\">\n {safeProduct.license}\n </p>\n </div>\n )}\n {safeProduct.minPlatformVersion && (\n <div>\n <p className=\"text-xs text-text-muted\">Min Platform Version</p>\n <p className=\"mt-1 text-sm font-medium text-text-primary\">\n {safeProduct.minPlatformVersion}\n </p>\n </div>\n )}\n </div>\n </section>\n </div>\n\n {/* Right Sidebar */}\n <div className=\"w-full lg:w-80\">\n {/* App Support */}\n {(safeProduct.documentationUrl || safeProduct.repositoryUrl || publisher?.email) && (\n <div className=\"mb-6 rounded-xl border border-border-default bg-bg-surface p-4\">\n <h3 className=\"font-medium text-text-primary\">App support</h3>\n <div className=\"mt-3 space-y-2 text-sm\">\n {safeProduct.documentationUrl && (\n <a\n href={safeProduct.documentationUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"block text-text-link hover:underline\"\n >\n Documentation\n </a>\n )}\n {safeProduct.repositoryUrl && (\n <a\n href={safeProduct.repositoryUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"block text-text-link hover:underline\"\n >\n Source repository\n </a>\n )}\n {publisher?.email && (\n <a\n href={`mailto:${publisher.email}`}\n className=\"block text-text-link hover:underline\"\n >\n Contact publisher\n </a>\n )}\n </div>\n </div>\n )}\n\n {/* More by Publisher */}\n {publisher && (\n <div className=\"mb-6 rounded-xl border border-border-default bg-bg-surface p-4\">\n <h3 className=\"font-medium text-text-primary\">Publisher</h3>\n <p className=\"mt-2 text-sm text-text-primary\">{publisher.name}</p>\n {publisher.bio && <p className=\"mt-2 text-sm text-text-muted\">{publisher.bio}</p>}\n {publisher.websiteUrl && (\n <a\n href={publisher.websiteUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"mt-3 inline-block text-sm text-text-link hover:underline\"\n >\n Visit publisher website\n </a>\n )}\n </div>\n )}\n\n {/* Similar Apps */}\n {relatedProducts && relatedProducts.length > 0 && (\n <div>\n <div className=\"mb-4 flex items-center justify-between text-left\">\n <span className=\"font-medium text-text-primary\">Similar apps</span>\n </div>\n <div className=\"space-y-3\">\n {relatedProducts.slice(0, 4).map((related) => (\n <button\n type=\"button\"\n key={related.id}\n onClick={() => navigate(`${basePath}/marketplace/product/${related.id}`)}\n className=\"flex w-full cursor-pointer items-center gap-3 rounded-lg p-2 text-left transition-colors hover:bg-bg-sunken\"\n >\n {related.icon ? (\n <img\n src={related.icon}\n alt={related.name}\n className=\"size-12 rounded-xl object-cover\"\n />\n ) : (\n <div className=\"flex size-12 items-center justify-center rounded-xl bg-bg-sunken text-lg font-bold text-text-muted\">\n {related.name.charAt(0)}\n </div>\n )}\n <div className=\"flex-1 overflow-hidden\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {related.name}\n </p>\n <p className=\"text-xs text-text-muted\">{publisher?.name || 'Unknown'}</p>\n {(related.reviewCount ?? 0) > 0 && (\n <div className=\"flex items-center gap-1\">\n <span className=\"text-xs text-text-muted\">\n {(related.rating || 0).toFixed(1)}\n </span>\n <Star className=\"size-3 fill-current text-status-warning-text\" />\n </div>\n )}\n </div>\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n </div>\n </main>\n\n {/* Install App Modal */}\n {safeProduct && (\n <InstallAppModal\n isOpen={isInstallModalOpen}\n onClose={() => setIsInstallModalOpen(false)}\n app={{\n id: safeProduct.id,\n name: safeProduct.name,\n slug: safeProduct.slug,\n icon: safeProduct.icon,\n type: safeProduct.type,\n version: safeProduct.manifestVersion,\n requiredPermissions: permissions,\n }}\n purchaseState={isPurchased && !isFree ? 'purchased' : 'free'}\n onInstallSuccess={handleInstallSuccess}\n onInstallError={handleInstallError}\n />\n )}\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProductDetailPage.js","names":[],"sources":["../../src/pages/ProductDetailPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport { useParams, useNavigate, useLocation } from 'react-router-dom';\nimport { useEventBus } from '@burdenoff/fe-libs/shared/events';\nimport {\n ArrowLeft,\n Star,\n ShieldCheck,\n Check,\n ThumbsUp,\n Package,\n AlertCircle,\n ShoppingCart,\n Loader2,\n} from 'lucide-react';\nimport { useStore } from '../providers/StoreProvider';\nimport { nativeConfirm, nativeImpact, nativeNotify } from '../utils/nativeBridge';\nimport {\n useCreateReview,\n useDeleteReview,\n useMarkReviewHelpful,\n useStoreProductDetails,\n useUpdateReview,\n} from '../hooks/useStoreGraphQL';\nimport { useCart } from '../hooks/useCart';\nimport { useInstallations } from '../hooks/useInstallations';\nimport { formatNumber, formatPrice } from '../utils';\nimport { InstallAppModal } from '../components/InstallAppModal';\nimport {\n GlassCard,\n EmphasisPanel,\n PagePurpose,\n NextSteps,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport type {\n Product,\n ItemType,\n ProductType,\n PricingModel as CartPricingModel,\n ProductStatus,\n} from '../types';\n\n// ============================================================================\n// Type Definitions for GraphQL Response\n// ============================================================================\n\ninterface Publisher {\n id: string;\n userId?: string;\n name: string;\n email?: string;\n websiteUrl?: string;\n logoUrl?: string;\n bio?: string;\n isVerified: boolean;\n totalSales?: number;\n totalEarnings?: number;\n createdAt?: string;\n}\n\ninterface ProductReview {\n id: string;\n productId: string;\n userId: string;\n rating: number;\n title?: string;\n comment?: string;\n status: string;\n helpful: number;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface RelatedProduct {\n id: string;\n name: string;\n slug?: string;\n icon?: string;\n type: string;\n price: number;\n pricingModel: string;\n rating?: number;\n reviewCount?: number;\n downloads: number;\n publisher?: {\n id: string;\n name: string;\n isVerified: boolean;\n };\n}\n\ninterface RatingDistribution {\n fiveStars: number;\n fourStars: number;\n threeStars: number;\n twoStars: number;\n oneStar: number;\n}\n\ninterface UserEntitlement {\n id: string;\n status: string;\n licenseKey?: string;\n expiresAt?: string;\n}\n\ninterface StoreProduct {\n id: string;\n name: string;\n slug?: string;\n type: string;\n nature: string;\n status: string;\n description?: string;\n longDescription?: string;\n pricingModel: string;\n price: number;\n currency: string;\n icon?: string;\n screenshots: string[];\n videoUrls?: string[];\n documentationUrl?: string;\n repositoryUrl?: string;\n category?: string;\n tags?: string[];\n featured: boolean;\n zipFileUrl?: string;\n downloads: number;\n viewCount?: number;\n rating?: number;\n reviewCount: number;\n publishedAt?: string;\n createdAt: string;\n updatedAt: string;\n // Manifest fields\n subType?: string;\n manifestVersion?: string;\n authorName?: string;\n license?: string;\n minPlatformVersion?: string;\n compatibleProducts?: string[];\n requiredPermissions?: string[];\n integrationDeps?: string[];\n // Physical product fields\n sku?: string;\n stockQuantity?: number;\n trackInventory?: boolean;\n requiresShipping?: boolean;\n weight?: number;\n weightUnit?: string;\n brand?: string;\n manifest?: Record<string, unknown>;\n publisher?: Publisher;\n}\n\ninterface StoreProductDetailsResponse {\n product: StoreProduct;\n publisher: Publisher;\n reviews: ProductReview[];\n reviewsCount: number;\n relatedProducts: RelatedProduct[];\n userReview?: ProductReview;\n isPurchased: boolean;\n userEntitlement?: UserEntitlement;\n ratingDistribution?: RatingDistribution;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Convert StoreProduct (GraphQL) to Product (Cart) type\n */\nconst convertToCartProduct = (storeProduct: StoreProduct, publisher?: Publisher): Product => {\n // Map GraphQL pricing model to cart pricing model\n const mapPricingModel = (model: string): CartPricingModel => {\n const mapping: Record<string, CartPricingModel> = {\n FREE: 'FREE',\n PAID_ONETIME: 'ONE_TIME',\n SUBSCRIPTION: 'SUBSCRIPTION',\n USAGE_BASED: 'USAGE_BASED',\n FREEMIUM: 'FREEMIUM',\n };\n return mapping[model] || 'ONE_TIME';\n };\n\n // Map product type\n const mapProductType = (type: string): ProductType => {\n const mapping: Record<string, ProductType> = {\n APP: 'STANDALONE_APP',\n BOTAPP: 'STANDALONE_APP',\n AGENT: 'STANDALONE_APP',\n WORKFLOW: 'WORKFLOW_TEMPLATE',\n TEMPLATE: 'WORKFLOW_TEMPLATE',\n INTEGRATION: 'API_INTEGRATION',\n EXTENSION: 'BROWSER_EXTENSION',\n THEME: 'UI_THEME',\n PLUGIN: 'WORKSPACE_MODULE',\n COMPONENT: 'WORKSPACE_MODULE',\n WIDGET: 'WORKSPACE_MODULE',\n VIBEMODULE: 'WORKSPACE_MODULE',\n CONSOLE: 'STANDALONE_APP',\n NODE: 'WORKSPACE_MODULE',\n };\n return mapping[type] || 'STANDALONE_APP';\n };\n\n // Map item type\n const mapItemType = (nature: string, type: string): ItemType => {\n if (nature === 'PHYSICAL') return 'PHYSICAL';\n const typeMapping: Record<string, ItemType> = {\n APP: 'APP',\n BOTAPP: 'APP',\n AGENT: 'APP',\n WORKFLOW: 'WORKFLOW',\n TEMPLATE: 'TEMPLATE',\n INTEGRATION: 'INTEGRATION',\n EXTENSION: 'EXTENSION',\n THEME: 'THEME',\n };\n return typeMapping[type] || 'APP';\n };\n\n return {\n id: storeProduct.id,\n publisherId: publisher?.id || '',\n publisher: {\n id: publisher?.id || '',\n name: publisher?.name || storeProduct.authorName || 'Unknown',\n displayName: publisher?.name || storeProduct.authorName || 'Unknown',\n email: publisher?.email || '',\n verified: publisher?.isVerified || false,\n totalProducts: 0,\n totalDownloads: 0,\n averageRating: 0,\n joinedAt: publisher?.createdAt || storeProduct.createdAt,\n website: publisher?.websiteUrl,\n logoUrl: publisher?.logoUrl,\n },\n name: storeProduct.name,\n slug: storeProduct.slug || storeProduct.id,\n displayName: storeProduct.name,\n description: storeProduct.longDescription || storeProduct.description || '',\n shortDescription: storeProduct.description || '',\n iconUrl: storeProduct.icon,\n screenshotUrls: storeProduct.screenshots || [],\n videoUrls: storeProduct.videoUrls || [],\n itemType: mapItemType(storeProduct.nature, storeProduct.type),\n type: mapProductType(storeProduct.type),\n tags: storeProduct.tags || [],\n pricingModel: mapPricingModel(storeProduct.pricingModel),\n basePrice: storeProduct.price,\n currency: storeProduct.currency || 'USD',\n variants: [],\n status: (storeProduct.status as ProductStatus) || 'PUBLISHED',\n featured: storeProduct.featured,\n verified: publisher?.isVerified || false,\n downloadCount: storeProduct.downloads,\n installCount: storeProduct.downloads,\n orderCount: 0,\n averageRating: storeProduct.rating || 0,\n reviewCount: storeProduct.reviewCount,\n createdAt: storeProduct.createdAt,\n updatedAt: storeProduct.updatedAt,\n publishedAt: storeProduct.publishedAt,\n };\n};\n\n// ============================================================================\n// Helper Components\n// ============================================================================\n\n/**\n * Rating bar component for rating distribution\n */\nconst RatingBar: FC<{ stars: number; percentage: number; count: number }> = ({\n stars,\n percentage,\n count,\n}) => (\n <div className=\"flex items-center gap-2\">\n <span className=\"w-3 text-xs text-text-muted\">{stars}</span>\n <div className=\"h-2 flex-1 overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-full rounded-full bg-status-warning-bg-subtle\"\n style={{ width: `${percentage}%` }}\n />\n </div>\n <span className=\"w-12 text-right text-xs text-text-muted\">{formatNumber(count)}</span>\n </div>\n);\n\n/**\n * Review card component\n */\nconst ReviewCard: FC<{\n review: ProductReview;\n onMarkHelpful: (reviewId: string) => void;\n markingHelpful: boolean;\n}> = ({ review, onMarkHelpful, markingHelpful }) => {\n const formatDate = (dateString: string) => {\n try {\n return new Date(dateString).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n } catch {\n return dateString;\n }\n };\n\n return (\n <div className=\"rounded-lg border border-border-seam bg-bg-surface p-4 transition-[box-shadow,border-color] hover:border-border-strong hover:shadow-[var(--shadow-pop)]\">\n <div className=\"mb-3 flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex size-10 items-center justify-center rounded-full bg-bg-sunken text-text-muted\">\n {review.userId.charAt(0).toUpperCase()}\n </div>\n <div>\n <p className=\"font-medium text-text-primary\">User {review.userId.slice(0, 8)}</p>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex gap-0.5\">\n {[1, 2, 3, 4, 5].map((star) => (\n <Star\n key={star}\n className={`size-3 ${\n star <= review.rating\n ? 'fill-current text-status-warning-text'\n : 'text-text-muted'\n }`}\n />\n ))}\n </div>\n <span className=\"text-xs text-text-muted\">{formatDate(review.createdAt)}</span>\n </div>\n </div>\n </div>\n </div>\n {review.title && <h4 className=\"mb-2 font-medium text-text-primary\">{review.title}</h4>}\n {review.comment && <p className=\"mb-3 text-sm text-text-muted\">{review.comment}</p>}\n <div className=\"flex items-center justify-between\">\n <button\n type=\"button\"\n onClick={() => onMarkHelpful(review.id)}\n disabled={markingHelpful}\n aria-label={`Mark review from ${review.userId} as helpful`}\n className=\"flex items-center gap-1 text-xs text-text-muted transition-colors hover:text-text-primary disabled:cursor-not-allowed disabled:opacity-60\"\n >\n <ThumbsUp className=\"size-3.5\" />\n <span>{markingHelpful ? 'Updating…' : `Helpful (${review.helpful})`}</span>\n </button>\n </div>\n </div>\n );\n};\n\n/**\n * Loading skeleton component - comprehensive skeleton matching full page layout\n */\nconst LoadingSkeleton: FC = () => (\n <div className=\"h-full overflow-y-auto\">\n {/* Header Skeleton */}\n <div className=\"sticky top-0 z-10 border-b border-border-default bg-bg-surface px-6 py-4\">\n <div className=\"flex items-center gap-4\">\n <div className=\"size-10 animate-pulse rounded-lg bg-bg-sunken\" />\n <div className=\"h-6 w-48 flex-1 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"flex gap-2\">\n <div className=\"size-10 animate-pulse rounded-lg bg-bg-sunken\" />\n <div className=\"size-10 animate-pulse rounded-lg bg-bg-sunken\" />\n </div>\n </div>\n </div>\n\n <div className=\"mx-auto max-w-6xl p-6\">\n {/* App Header Section Skeleton */}\n <div className=\"mb-8 flex flex-col gap-6 md:flex-row\">\n {/* App Icon & Basic Info */}\n <div className=\"flex gap-4 md:w-1/2\">\n <div className=\"size-28 animate-pulse rounded-2xl bg-bg-sunken\" />\n <div className=\"flex flex-1 flex-col justify-center gap-2\">\n <div className=\"h-8 w-3/4 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"flex items-center gap-2\">\n <div className=\"h-4 w-32 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"size-4 animate-pulse rounded-full bg-bg-sunken\" />\n </div>\n <div className=\"flex gap-3\">\n <div className=\"h-5 w-16 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"h-5 w-24 animate-pulse rounded bg-bg-sunken\" />\n </div>\n </div>\n </div>\n\n {/* Rating & Install Skeleton */}\n <div className=\"flex flex-col gap-4 md:w-1/2 md:items-end\">\n <div className=\"flex items-center gap-4\">\n <div className=\"text-center\">\n <div className=\"h-10 w-16 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"mt-1 h-3 w-20 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"h-12 w-px bg-border-default\" />\n <div className=\"text-center\">\n <div className=\"h-8 w-16 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"mt-1 h-3 w-16 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"h-12 w-px bg-border-default\" />\n <div className=\"text-center\">\n <div className=\"h-8 w-20 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"mt-1 h-3 w-12 animate-pulse rounded bg-bg-sunken\" />\n </div>\n </div>\n <div className=\"flex gap-3\">\n <div className=\"h-12 w-40 animate-pulse rounded-lg bg-bg-sunken\" />\n <div className=\"size-12 animate-pulse rounded-lg bg-bg-sunken\" />\n </div>\n </div>\n </div>\n\n {/* Screenshots Skeleton */}\n <section className=\"mb-8\">\n <div className=\"aspect-video animate-pulse rounded-lg bg-bg-sunken\" />\n <div className=\"mt-4 flex gap-4\">\n {[...Array(4)].map((_, i) => (\n <div key={i} className=\"h-20 w-36 animate-pulse rounded-lg bg-bg-sunken\" />\n ))}\n </div>\n </section>\n\n {/* About Section Skeleton */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center gap-2\">\n <div className=\"size-5 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"h-6 w-32 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"animate-pulse rounded-lg border border-border-seam bg-bg-surface p-4\">\n <div className=\"space-y-2\">\n <div className=\"h-4 w-full rounded bg-bg-sunken\" />\n <div className=\"h-4 w-full rounded bg-bg-sunken\" />\n <div className=\"h-4 w-3/4 rounded bg-bg-sunken\" />\n <div className=\"h-4 w-5/6 rounded bg-bg-sunken\" />\n </div>\n <div className=\"mt-4 flex gap-2\">\n {[...Array(4)].map((_, i) => (\n <div key={i} className=\"h-6 w-16 rounded-full bg-bg-sunken\" />\n ))}\n </div>\n </div>\n </section>\n\n {/* Ratings & Reviews Skeleton */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <div className=\"size-5 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"h-6 w-40 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"h-4 w-16 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"mb-6 flex flex-col gap-6 md:flex-row\">\n <div className=\"animate-pulse rounded-lg border border-border-seam bg-bg-surface p-4 md:w-64\">\n <div className=\"flex items-center gap-6\">\n <div className=\"text-center\">\n <div className=\"h-12 w-16 rounded bg-bg-sunken\" />\n <div className=\"my-1 flex justify-center gap-0.5\">\n {[...Array(5)].map((_, i) => (\n <div key={i} className=\"size-4 rounded bg-bg-sunken\" />\n ))}\n </div>\n <div className=\"h-3 w-20 rounded bg-bg-sunken\" />\n </div>\n <div className=\"flex-1 space-y-1\">\n {[...Array(5)].map((_, i) => (\n <div key={i} className=\"flex items-center gap-2\">\n <div className=\"h-2 w-3 rounded bg-bg-sunken\" />\n <div className=\"h-2 flex-1 rounded-full bg-bg-sunken\" />\n <div className=\"h-2 w-8 rounded bg-bg-sunken\" />\n </div>\n ))}\n </div>\n </div>\n </div>\n <div className=\"h-12 w-32 animate-pulse rounded-lg bg-bg-sunken\" />\n </div>\n {/* Review Cards Skeleton */}\n <div className=\"space-y-4\">\n {[...Array(2)].map((_, i) => (\n <div\n key={i}\n className=\"animate-pulse rounded-lg border border-border-seam bg-bg-surface p-4\"\n >\n <div className=\"mb-3 flex items-start gap-3\">\n <div className=\"size-10 rounded-full bg-bg-sunken\" />\n <div className=\"flex-1\">\n <div className=\"h-4 w-32 rounded bg-bg-sunken\" />\n <div className=\"mt-1 flex items-center gap-2\">\n <div className=\"flex gap-0.5\">\n {[...Array(5)].map((_, j) => (\n <div key={j} className=\"size-3 rounded bg-bg-sunken\" />\n ))}\n </div>\n <div className=\"h-3 w-20 rounded bg-bg-sunken\" />\n </div>\n </div>\n </div>\n <div className=\"space-y-2\">\n <div className=\"h-4 w-full rounded bg-bg-sunken\" />\n <div className=\"h-4 w-2/3 rounded bg-bg-sunken\" />\n </div>\n </div>\n ))}\n </div>\n </section>\n\n {/* Additional Info Skeleton */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center gap-2\">\n <div className=\"size-5 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"h-6 w-48 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"animate-pulse rounded-lg border border-border-seam bg-bg-surface p-4\">\n <div className=\"grid gap-4 md:grid-cols-2\">\n {[...Array(6)].map((_, i) => (\n <div key={i}>\n <div className=\"h-3 w-16 rounded bg-bg-sunken\" />\n <div className=\"mt-1 h-5 w-24 rounded bg-bg-sunken\" />\n </div>\n ))}\n </div>\n </div>\n </section>\n\n {/* Related Products Skeleton */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <div className=\"size-5 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"h-6 w-40 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"h-4 w-16 animate-pulse rounded bg-bg-sunken\" />\n </div>\n <div className=\"grid gap-4 md:grid-cols-4\">\n {[...Array(4)].map((_, i) => (\n <div\n key={i}\n className=\"animate-pulse rounded-lg border border-border-seam bg-bg-surface p-3\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"size-14 rounded-xl bg-bg-sunken\" />\n <div className=\"flex-1\">\n <div className=\"h-4 w-24 rounded bg-bg-sunken\" />\n <div className=\"mt-1 h-3 w-16 rounded bg-bg-sunken\" />\n <div className=\"mt-1 flex items-center gap-2\">\n <div className=\"h-3 w-8 rounded bg-bg-sunken\" />\n <div className=\"h-3 w-12 rounded bg-bg-sunken\" />\n </div>\n </div>\n </div>\n </div>\n ))}\n </div>\n </section>\n\n {/* Publisher Skeleton */}\n <section className=\"mb-8\">\n <div className=\"mb-4 h-6 w-36 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"animate-pulse rounded-lg border border-border-seam bg-bg-surface p-4\">\n <div className=\"flex items-center gap-4\">\n <div className=\"size-12 rounded-lg bg-bg-sunken\" />\n <div>\n <div className=\"flex items-center gap-2\">\n <div className=\"h-5 w-32 rounded bg-bg-sunken\" />\n <div className=\"size-4 rounded-full bg-bg-sunken\" />\n </div>\n <div className=\"mt-1 h-4 w-40 rounded bg-bg-sunken\" />\n </div>\n </div>\n <div className=\"mt-3 space-y-2\">\n <div className=\"h-4 w-full rounded bg-bg-sunken\" />\n <div className=\"h-4 w-2/3 rounded bg-bg-sunken\" />\n </div>\n </div>\n </section>\n </div>\n </div>\n);\n\n/**\n * Error display component\n */\nconst ErrorDisplay: FC<{ error: Error; onRetry: () => void; onBack: () => void }> = ({\n error,\n onRetry,\n onBack,\n}) => (\n <div className=\"flex h-full items-center justify-center\">\n <div className=\"text-center\">\n <AlertCircle className=\"mx-auto mb-4 size-12 text-status-error-text\" />\n <h2 className=\"mb-2 text-xl font-semibold text-text-primary\">Failed to load product</h2>\n <p className=\"mb-4 text-text-muted\">\n {error.message || 'An error occurred while loading the product details.'}\n </p>\n <div className=\"flex justify-center gap-3\">\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-action-primary-text transition-opacity hover:opacity-90\"\n >\n Try Again\n </button>\n <button\n type=\"button\"\n onClick={onBack}\n className=\"rounded-lg border border-border-default px-4 py-2 text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n Go Back\n </button>\n </div>\n </div>\n </div>\n);\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * Product Detail Page Component\n *\n * Displays comprehensive product details using real GraphQL data\n */\nexport const ProductDetailPage: FC = () => {\n const { productId } = useParams<{ productId: string }>();\n const navigate = useNavigate();\n const location = useLocation();\n const { basePath, workspaceId } = useStore();\n const { addProduct, cartItems, addingToCart, createOrder, checkingOut } = useCart();\n const installationsFilter = useMemo(\n () => (productId && workspaceId ? { productId, workspaceId } : undefined),\n [productId, workspaceId]\n );\n const { installations: myInstallations, refetch: refetchInstallations } = useInstallations({\n filter: installationsFilter,\n limit: 1,\n });\n const isInstalledInCurrentWorkspace = myInstallations.some(\n (i) => i.productId === productId && i.workspaceId === workspaceId && i.status === 'ACTIVE'\n );\n const { createReview, loading: creatingReview } = useCreateReview();\n const { updateReview, loading: updatingReview } = useUpdateReview();\n const { deleteReview, loading: deletingReview } = useDeleteReview();\n const { markHelpful, loading: markingHelpful } = useMarkReviewHelpful();\n const bus = useEventBus();\n\n const [showFullDescription, setShowFullDescription] = useState(false);\n const [showAllReviews, setShowAllReviews] = useState(false);\n const [buyingNow, setBuyingNow] = useState(false);\n const [actionError, setActionError] = useState<string | null>(null);\n const [reviewNotice, setReviewNotice] = useState<string | null>(null);\n const [reviewNoticeTone, setReviewNoticeTone] = useState<'success' | 'error'>('success');\n const [isReviewFormOpen, setIsReviewFormOpen] = useState(false);\n const [reviewTitle, setReviewTitle] = useState('');\n const [reviewComment, setReviewComment] = useState('');\n const [reviewRating, setReviewRating] = useState(5);\n const [helpfulReviewId, setHelpfulReviewId] = useState<string | null>(null);\n\n // Install modal state\n const [isInstallModalOpen, setIsInstallModalOpen] = useState(false);\n\n // Fetch product details using GraphQL\n const { data, loading, error, refetch } = useStoreProductDetails({\n id: productId,\n slug: productId, // Also try as slug\n includeReviews: true,\n reviewsLimit: 10,\n includeRelated: true,\n relatedLimit: 4,\n includeVersions: true,\n });\n\n // Cast data to typed response\n const productDetails = data as StoreProductDetailsResponse | null;\n const product = productDetails?.product;\n const publisher = productDetails?.publisher;\n\n // Check if product is already in cart (must be before any early returns)\n const isInCart = cartItems.some((item) => item.productId === product?.id);\n\n // Handle Add to Cart (must be before any early returns)\n const handleAddToCart = useCallback(async () => {\n if (!product) return;\n\n setActionError(null);\n\n if (isInCart) {\n navigate(`${basePath}/cart`);\n return;\n }\n\n try {\n const cartProduct = convertToCartProduct(product, publisher);\n // Add to backend cart via GraphQL API call\n // This will make a mutation to global-public-gateway:4004 → tenantmodule-store-svc:4017\n await addProduct(cartProduct, undefined, 1);\n // Cart drawer will open automatically after adding\n } catch (error) {\n console.error('Failed to add product to cart:', error);\n setActionError('Failed to add this product to cart. Please try again.');\n }\n }, [product, publisher, addProduct, isInCart, navigate, basePath]);\n\n // Handle Buy Now - creates an order and immediately proceeds to checkout\n const handleBuyNow = useCallback(async () => {\n if (!product) return;\n\n setActionError(null);\n setBuyingNow(true);\n\n try {\n // Get product price\n const price = product.price || 0;\n\n // Build line item for this product\n const lineItem = {\n productId: product.id,\n name: product.name,\n quantity: 1,\n unitPrice: price,\n subtotal: price,\n itemType: product.nature?.toLowerCase() || 'digital',\n pricingModel: product.pricingModel || 'PAID_ONETIME',\n };\n\n // Create order input\n const orderInput = {\n total: price,\n lineItems: [lineItem],\n billingAccountId: '', // Will be set on billing page\n };\n\n // Call createStoreOrder mutation to create PENDING order\n const order = await createOrder(orderInput);\n\n if (order?.id) {\n // Navigate to billing page, preserving org/workspace/tenant context params\n navigate(`/billing/checkout/store/${order.id}${location.search}`);\n } else {\n console.error('Failed to create order');\n setActionError('Failed to create order. Please try again.');\n setBuyingNow(false);\n }\n } catch (error) {\n console.error('Buy Now error:', error);\n const message = error instanceof Error ? error.message : 'Failed to start checkout';\n setActionError(message);\n setBuyingNow(false);\n }\n }, [product, createOrder, navigate]);\n\n // Handle Install Free - Open modal for workspace selection (must be before any early returns)\n const handleInstallFree = useCallback(() => {\n if (!product) return;\n setIsInstallModalOpen(true);\n }, [product]);\n\n // Emit product.viewed event once product data loads. Read product via ref so\n // we only emit on id transitions, not on every field change.\n const productRef = useRef(product);\n productRef.current = product;\n const busRef = useRef(bus);\n busRef.current = bus;\n useEffect(() => {\n const p = productRef.current;\n if (!p) return;\n (busRef.current as unknown as { emit: (name: string, payload: unknown) => void }).emit(\n 'store.product.viewed',\n {\n productId: p.id,\n productSlug: p.slug,\n productType: p.type,\n pricingModel: p.pricingModel,\n }\n );\n }, [product?.id]);\n\n // Handle successful installation (must be before any early returns)\n const handleInstallSuccess = useCallback(\n (workspaceId: string, workspaceName: string) => {\n if (!product) return;\n (bus as unknown as { emit: (name: string, payload: unknown) => void }).emit(\n 'store.product.installed',\n {\n productId: product.id,\n workspaceId,\n }\n );\n console.log(\n `Successfully installed ${product.name} to workspace ${workspaceName} (${workspaceId})`\n );\n void refetchInstallations();\n },\n [product, bus, refetchInstallations]\n );\n\n // Handle installation error (must be before any early returns)\n const handleInstallError = useCallback((error: Error) => {\n console.error('Installation failed:', error.message);\n // Error is shown in the modal\n }, []);\n\n const openReviewForm = useCallback(() => {\n setReviewTitle(productDetails?.userReview?.title ?? '');\n setReviewComment(productDetails?.userReview?.comment ?? '');\n setReviewRating(productDetails?.userReview?.rating ?? 5);\n setReviewNotice(null);\n setReviewNoticeTone('success');\n setIsReviewFormOpen(true);\n }, [productDetails?.userReview]);\n\n const handleSubmitReview = useCallback(async () => {\n if (!product) {\n return;\n }\n\n if (reviewRating < 1 || reviewRating > 5) {\n setReviewNoticeTone('error');\n setReviewNotice('Choose a rating from 1 to 5 stars.');\n return;\n }\n\n const payload = {\n productId: product.id,\n rating: reviewRating,\n title: reviewTitle.trim() || undefined,\n comment: reviewComment.trim() || undefined,\n };\n\n const result = productDetails?.userReview\n ? await updateReview(productDetails.userReview.id, {\n rating: payload.rating,\n title: payload.title,\n comment: payload.comment,\n })\n : await createReview(payload);\n\n if (!result) {\n setReviewNoticeTone('error');\n setReviewNotice('We could not save your review. Please try again.');\n return;\n }\n\n setReviewNoticeTone('success');\n setReviewNotice(\n productDetails?.userReview ? 'Your review was updated.' : 'Your review was submitted.'\n );\n setIsReviewFormOpen(false);\n (bus as unknown as { emit: (name: string, payload: unknown) => void }).emit(\n 'store.review.submitted',\n {\n productId: product.id,\n rating: reviewRating,\n }\n );\n await refetch();\n }, [\n bus,\n createReview,\n product,\n productDetails?.userReview,\n refetch,\n reviewComment,\n reviewRating,\n reviewTitle,\n updateReview,\n ]);\n\n const handleDeleteReview = useCallback(async () => {\n if (!productDetails?.userReview) {\n return;\n }\n void nativeImpact('medium');\n const confirmed = await nativeConfirm({\n title: 'Delete review',\n message: 'Are you sure you want to remove your review?',\n okButtonTitle: 'Delete',\n cancelButtonTitle: 'Cancel',\n });\n if (confirmed === false) {\n return;\n }\n\n const deleted = await deleteReview(productDetails.userReview.id);\n if (!deleted) {\n setReviewNoticeTone('error');\n setReviewNotice('We could not remove your review. Please try again.');\n void nativeNotify('error');\n return;\n }\n\n setReviewNoticeTone('success');\n setReviewNotice('Your review was removed.');\n setIsReviewFormOpen(false);\n setReviewTitle('');\n setReviewComment('');\n setReviewRating(5);\n void nativeNotify('success');\n await refetch();\n }, [deleteReview, productDetails?.userReview, refetch]);\n\n const handleMarkHelpful = useCallback(\n async (reviewId: string) => {\n setHelpfulReviewId(reviewId);\n const result = await markHelpful(reviewId);\n if (result) {\n await refetch();\n }\n setHelpfulReviewId(null);\n },\n [markHelpful, refetch]\n );\n\n // Handle loading state\n if (loading) {\n return <LoadingSkeleton />;\n }\n\n // Handle error state\n if (error) {\n return (\n <ErrorDisplay\n error={error}\n onRetry={refetch}\n onBack={() => navigate(`${basePath}/marketplace`)}\n />\n );\n }\n\n // Handle not found state\n if (!productDetails?.product) {\n return (\n <div className=\"flex h-full items-center justify-center p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Product not found\"\n description=\"The product you are looking for does not exist or has been removed.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/marketplace`)}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-action-primary-text transition-opacity hover:opacity-90\"\n >\n Back to Marketplace\n </button>\n }\n />\n </div>\n );\n }\n\n const {\n reviews,\n reviewsCount,\n relatedProducts,\n ratingDistribution,\n isPurchased,\n userEntitlement,\n } = productDetails;\n\n // Type assertion: we know product is defined because we checked !productDetails?.product above\n const safeProduct = product!;\n\n // Calculate rating distribution percentages\n const totalRatings = ratingDistribution\n ? ratingDistribution.fiveStars +\n ratingDistribution.fourStars +\n ratingDistribution.threeStars +\n ratingDistribution.twoStars +\n ratingDistribution.oneStar\n : 0;\n\n const ratingDistributionData = ratingDistribution\n ? [\n {\n stars: 5,\n count: ratingDistribution.fiveStars,\n percentage: totalRatings > 0 ? (ratingDistribution.fiveStars / totalRatings) * 100 : 0,\n },\n {\n stars: 4,\n count: ratingDistribution.fourStars,\n percentage: totalRatings > 0 ? (ratingDistribution.fourStars / totalRatings) * 100 : 0,\n },\n {\n stars: 3,\n count: ratingDistribution.threeStars,\n percentage: totalRatings > 0 ? (ratingDistribution.threeStars / totalRatings) * 100 : 0,\n },\n {\n stars: 2,\n count: ratingDistribution.twoStars,\n percentage: totalRatings > 0 ? (ratingDistribution.twoStars / totalRatings) * 100 : 0,\n },\n {\n stars: 1,\n count: ratingDistribution.oneStar,\n percentage: totalRatings > 0 ? (ratingDistribution.oneStar / totalRatings) * 100 : 0,\n },\n ]\n : [];\n\n // Parse permissions from manifest or requiredPermissions\n const permissions = safeProduct.requiredPermissions || [];\n\n // Parse integrations from integrationDeps\n const integrations = safeProduct.integrationDeps || [];\n\n // Pricing display\n const getPriceDisplay = () => {\n if (safeProduct.pricingModel === 'FREE') return 'Free';\n if (safeProduct.pricingModel === 'SUBSCRIPTION') {\n return `${formatPrice(safeProduct.price, safeProduct.currency)}/mo`;\n }\n return formatPrice(safeProduct.price, safeProduct.currency);\n };\n\n // Check if product is free\n const isFree = safeProduct.pricingModel === 'FREE' || safeProduct.price === 0;\n\n return (\n <div className=\"h-full overflow-y-auto bg-bg-base\">\n {/* Hero Section - Two Column Layout */}\n <div className=\"relative bg-bg-surface\">\n <div className=\"mx-auto max-w-7xl\">\n <div className=\"flex flex-col lg:flex-row\">\n {/* Left Column - Product Info */}\n <div className=\"flex-1 px-6 py-8 lg:max-w-xl lg:py-12\">\n {/* Back Button */}\n <button\n type=\"button\"\n onClick={() => navigate(-1)}\n className=\"mb-6 cursor-pointer inline-flex items-center gap-2 text-sm text-text-muted transition-colors hover:text-text-primary\"\n >\n <ArrowLeft className=\"size-4\" />\n Back\n </button>\n\n {/* App Title - Large Typography */}\n <h1 className=\"mb-4 text-4xl font-normal leading-tight text-text-primary lg:text-5xl\">\n {safeProduct.name}\n </h1>\n\n {/* Publisher */}\n <div className=\"mb-2\">\n {publisher?.websiteUrl ? (\n <a\n href={publisher.websiteUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-base font-medium text-text-link hover:underline\"\n >\n {publisher.name}\n </a>\n ) : (\n <span className=\"text-base font-medium text-text-primary\">\n {publisher?.name || safeProduct.authorName || 'Unknown Publisher'}\n </span>\n )}\n {publisher?.isVerified && (\n <ShieldCheck className=\"ml-1.5 inline size-4 text-status-success-text\" />\n )}\n </div>\n\n {/* Metadata */}\n <p className=\"mb-6 text-sm text-text-muted\">\n {safeProduct.category && <span>{safeProduct.category}</span>}\n {safeProduct.category && ' · '}\n {formatNumber(safeProduct.downloads)}+ downloads\n </p>\n\n {/* Stats + primary action — the single emphasis zone for this page */}\n <EmphasisPanel className=\"mb-6 p-5\">\n {/* Stats Row */}\n <div className=\"mb-6 flex items-center gap-4\">\n {/* App Icon Badge */}\n <div className=\"flex size-12 items-center justify-center overflow-hidden rounded-xl bg-bg-sunken\">\n {safeProduct.icon ? (\n <img src={safeProduct.icon} alt=\"\" className=\"size-full object-cover\" />\n ) : (\n <span className=\"text-lg font-bold text-text-muted\">\n {safeProduct.name.charAt(0)}\n </span>\n )}\n </div>\n\n {/* Rating */}\n <div className=\"flex items-center gap-1 border-l border-border-default pl-4\">\n <span className=\"text-sm font-medium text-text-primary\">\n {(safeProduct.rating || 0).toFixed(1)}\n </span>\n <Star className=\"size-4 fill-current text-status-warning-text\" />\n <span className=\"ml-1 text-xs text-text-muted\">\n {formatNumber(reviewsCount || safeProduct.reviewCount)} reviews\n </span>\n </div>\n\n {/* Downloads */}\n <div className=\"border-l border-border-default pl-4\">\n <span className=\"text-sm font-medium text-text-primary\">\n {formatNumber(safeProduct.downloads)}+\n </span>\n <p className=\"text-xs text-text-muted\">Downloads</p>\n </div>\n\n {/* Type Badge */}\n <div className=\"border-l border-border-default pl-4\">\n <span className=\"rounded bg-bg-sunken px-2 py-1 text-xs font-medium text-text-primary\">\n {safeProduct.type}\n </span>\n <p className=\"mt-0.5 text-xs text-text-muted\">Type</p>\n </div>\n </div>\n\n {/* Action Buttons Row */}\n {actionError && (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-lg border border-status-error-bg bg-status-error-bg-subtle px-4 py-3 text-sm text-status-error-text\"\n >\n {actionError}\n </div>\n )}\n\n <div className=\"mb-6 flex items-center gap-3\">\n {isInstalledInCurrentWorkspace ? (\n <button\n type=\"button\"\n disabled\n className=\"flex items-center gap-2 rounded-full bg-status-success-bg-subtle px-8 py-3 font-medium text-status-success-text cursor-default\"\n >\n <svg\n className=\"size-4\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"2,8 6,12 14,4\" />\n </svg>\n Installed\n </button>\n ) : isPurchased && !isFree ? (\n <button\n type=\"button\"\n onClick={handleInstallFree}\n className=\"cursor-pointer rounded-full bg-action-primary-bg px-8 py-3 font-medium text-action-primary-text transition-opacity hover:opacity-90\"\n >\n Install to Workspace\n </button>\n ) : isFree ? (\n <button\n type=\"button\"\n onClick={handleInstallFree}\n className=\"cursor-pointer rounded-full bg-action-primary-bg px-8 py-3 font-medium text-action-primary-text transition-opacity hover:opacity-90\"\n >\n Install\n </button>\n ) : (\n <button\n type=\"button\"\n onClick={handleBuyNow}\n disabled={buyingNow || checkingOut}\n className=\"cursor-pointer flex items-center gap-2 rounded-full bg-action-primary-bg px-8 py-3 font-medium text-action-primary-text transition-opacity hover:opacity-90 disabled:opacity-70\"\n >\n {buyingNow || checkingOut ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Processing…\n </>\n ) : (\n `Buy ${getPriceDisplay()}`\n )}\n </button>\n )}\n\n {/* Add to Cart / Wishlist */}\n {!isFree && !isPurchased && (\n <button\n type=\"button\"\n onClick={handleAddToCart}\n disabled={addingToCart}\n className=\"cursor-pointer flex items-center gap-2 rounded-full border border-border-default px-4 py-3 text-sm text-text-primary transition-colors hover:bg-bg-sunken disabled:opacity-50\"\n >\n {addingToCart ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : isInCart ? (\n <Check className=\"size-4 text-status-success-text\" />\n ) : (\n <ShoppingCart className=\"size-4\" />\n )}\n {isInCart ? 'In Cart' : 'Add to Cart'}\n </button>\n )}\n </div>\n\n {/* Info Text */}\n <p className=\"flex items-center gap-2 text-xs text-text-muted\">\n <Package className=\"size-4\" />\n This app is available for your workspace\n </p>\n\n {/* License Status */}\n {userEntitlement && (\n <p className=\"mt-2 flex items-center gap-2 text-xs text-text-muted\">\n <ShieldCheck className=\"size-4 text-status-success-text\" />\n License: {userEntitlement.status}\n {userEntitlement.expiresAt &&\n ` (Expires: ${new Date(userEntitlement.expiresAt).toLocaleDateString()})`}\n </p>\n )}\n </EmphasisPanel>\n </div>\n\n {/* Right Column - Hero Screenshot */}\n <div className=\"relative flex-1 bg-bg-sunken lg:min-h-[500px]\">\n {safeProduct.screenshots && safeProduct.screenshots.length > 0 ? (\n <img\n src={safeProduct.screenshots[0]}\n alt={`${safeProduct.name} screenshot`}\n className=\"size-full object-cover\"\n />\n ) : (\n <div className=\"flex h-full min-h-[300px] items-center justify-center\">\n <div className=\"text-center\">\n <div className=\"mx-auto mb-4 flex size-24 items-center justify-center rounded-2xl bg-bg-surface text-4xl font-bold text-text-muted\">\n {safeProduct.name.charAt(0)}\n </div>\n <p className=\"text-sm text-text-muted\">No preview available</p>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n\n {/* Main Content Area */}\n <main className=\"mx-auto max-w-7xl px-6 py-8\">\n <PagePurpose className=\"mb-6\">\n Everything you need to decide whether to install {safeProduct.name}: what it does,\n screenshots, pricing, the permissions and integrations it needs, and real customer reviews.\n When you're ready, install it (free apps) or buy it, then add it to a workspace — and leave\n a review once you've used it.\n </PagePurpose>\n\n <NextSteps\n className=\"mb-8\"\n storageKey=\"store-product-detail\"\n steps={[\n isFree\n ? {\n id: 'install',\n label: 'Install this app',\n description: 'It’s free — add it to a workspace in a couple of clicks.',\n onClick: handleInstallFree,\n done: isInstalledInCurrentWorkspace,\n }\n : {\n id: 'buy',\n label: isPurchased ? 'Install to a workspace' : 'Buy or add to cart',\n description: isPurchased\n ? 'You already own this — install it where you need it.'\n : 'Purchase now, or add it to your cart to check out later.',\n onClick: isPurchased ? handleInstallFree : handleBuyNow,\n done: isInstalledInCurrentWorkspace,\n },\n ...(permissions.length > 0\n ? [\n {\n id: 'permissions',\n label: 'Review what it can access',\n description: 'Check the permissions this app requires before installing.',\n href: '#about-permissions',\n },\n ]\n : []),\n {\n id: 'reviews',\n label: 'Read the reviews',\n description: 'See what other customers think before committing.',\n href: '#ratings-reviews',\n },\n ]}\n />\n\n <div className=\"flex flex-col gap-8 lg:flex-row\">\n {/* Left Content */}\n <div className=\"flex-1 lg:max-w-3xl\">\n {/* Screenshots Gallery */}\n {safeProduct.screenshots && safeProduct.screenshots.length > 1 && (\n <section className=\"mb-8\">\n <div className=\"flex gap-4 overflow-x-auto pb-4\">\n {safeProduct.screenshots.map((screenshot, index) => (\n <div\n key={index}\n className=\"relative h-64 w-96 flex-shrink-0 overflow-hidden rounded-xl bg-bg-sunken\"\n >\n <img\n src={screenshot}\n alt={`Screenshot ${index + 1}`}\n className=\"size-full object-cover\"\n />\n </div>\n ))}\n </div>\n </section>\n )}\n\n {/* About this app */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between text-left\">\n <h2 className=\"text-lg font-medium text-text-primary\">About this app</h2>\n </div>\n <div className=\"text-sm leading-relaxed text-text-secondary\">\n <p className={!showFullDescription ? 'line-clamp-4' : ''}>\n {safeProduct.longDescription ||\n safeProduct.description ||\n 'No description available.'}\n </p>\n {((safeProduct.longDescription || safeProduct.description)?.length ?? 0) > 200 && (\n <button\n type=\"button\"\n onClick={() => setShowFullDescription(!showFullDescription)}\n className=\"cursor-pointer mt-3 text-sm font-medium text-text-link\"\n >\n {showFullDescription ? 'Show less' : 'Show more'}\n </button>\n )}\n </div>\n {/* Tags */}\n {safeProduct.tags && safeProduct.tags.length > 0 && (\n <div className=\"mt-4 flex flex-wrap gap-2\">\n {safeProduct.tags.map((tag) => (\n <span\n key={tag}\n className=\"rounded-full border border-border-seam px-3 py-1.5 text-xs text-text-muted transition-colors hover:bg-bg-sunken\"\n >\n {tag}\n </span>\n ))}\n </div>\n )}\n </section>\n\n {/* Ratings & Reviews */}\n <section id=\"ratings-reviews\" className=\"mb-8 scroll-mt-6\">\n <div className=\"mb-4 flex items-center justify-between text-left\">\n <h2 className=\"text-lg font-medium text-text-primary\">Ratings & Reviews</h2>\n </div>\n\n <GlassCard treatment=\"insight\" className=\"p-5\">\n {reviews && reviews.length > 0 ? (\n <div className=\"flex items-start gap-8\">\n {/* Rating Score */}\n <div className=\"text-center\">\n <p className=\"text-5xl font-light tabular-nums text-text-primary\">\n {(safeProduct.rating || 0).toFixed(1)}\n </p>\n <div className=\"my-2 flex justify-center gap-0.5\">\n {[1, 2, 3, 4, 5].map((star) => (\n <Star\n key={star}\n className={`size-4 ${\n star <= Math.round(safeProduct.rating || 0)\n ? 'fill-current text-status-warning-text'\n : 'text-text-muted'\n }`}\n />\n ))}\n </div>\n <p className=\"text-sm text-text-muted\">\n {formatNumber(reviewsCount || safeProduct.reviewCount)} reviews\n </p>\n </div>\n\n {/* Rating Distribution */}\n {ratingDistributionData.length > 0 && (\n <div className=\"flex-1 space-y-1.5\">\n {ratingDistributionData.map((item) => (\n <RatingBar key={item.stars} {...item} />\n ))}\n </div>\n )}\n </div>\n ) : (\n <div className=\"flex flex-col items-center justify-center py-6 text-center\">\n <div className=\"mb-3 flex gap-0.5\">\n {[1, 2, 3, 4, 5].map((star) => (\n <Star key={star} className=\"size-5 text-border-default\" />\n ))}\n </div>\n <p className=\"font-medium text-text-primary\">No reviews yet</p>\n <p className=\"mt-1 text-sm text-text-muted\">\n Be the first to share your experience with this app.\n </p>\n </div>\n )}\n\n {/* Write Review */}\n <div className=\"mt-6 border-t border-border-seam pt-4\">\n {reviewNotice && (\n <p\n role={reviewNoticeTone === 'success' ? 'status' : 'alert'}\n className={`mb-3 rounded-lg px-3 py-2 text-sm ${\n reviewNoticeTone === 'success'\n ? 'bg-status-success-bg-subtle text-status-success-text'\n : 'bg-status-error-bg-subtle text-status-error-text'\n }`}\n >\n {reviewNotice}\n </p>\n )}\n {isPurchased || productDetails?.userReview ? (\n <div className=\"space-y-4\">\n <button\n type=\"button\"\n onClick={() =>\n isReviewFormOpen ? setIsReviewFormOpen(false) : openReviewForm()\n }\n className=\"w-full cursor-pointer py-2 text-center text-sm font-medium text-text-primary transition-colors hover:text-text-link\"\n >\n {productDetails?.userReview\n ? isReviewFormOpen\n ? 'Cancel review editing'\n : 'Edit your review'\n : isReviewFormOpen\n ? 'Cancel review'\n : 'Write a Review'}\n </button>\n\n {isReviewFormOpen && (\n <div className=\"rounded-xl border border-border-seam bg-bg-sunken p-4\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Your rating</p>\n <div className=\"mt-2 flex flex-wrap gap-2\">\n {[1, 2, 3, 4, 5].map((star) => (\n <button\n key={star}\n type=\"button\"\n onClick={() => setReviewRating(star)}\n className={`cursor-pointer rounded-full border px-3 py-1.5 text-sm transition-colors ${\n reviewRating === star\n ? 'border-action-primary-border bg-action-primary-bg text-action-primary-text'\n : 'border-border-default bg-bg-surface text-text-primary hover:bg-bg-surface'\n }`}\n >\n {star} ★\n </button>\n ))}\n </div>\n </div>\n\n <label className=\"mt-4 block text-sm font-medium text-text-primary\">\n Title\n <input\n aria-label=\"Review title\"\n value={reviewTitle}\n onChange={(event) => setReviewTitle(event.target.value)}\n className=\"mt-2 w-full rounded-lg border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-primary outline-none focus:border-action-primary-border\"\n placeholder=\"Summarize your experience\"\n />\n </label>\n\n <label className=\"mt-4 block text-sm font-medium text-text-primary\">\n Review\n <textarea\n aria-label=\"Review body\"\n value={reviewComment}\n onChange={(event) => setReviewComment(event.target.value)}\n rows={4}\n required\n aria-required=\"true\"\n className=\"mt-2 w-full rounded-lg border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-primary outline-none focus:border-action-primary-border\"\n placeholder=\"What worked well? What should improve?\"\n />\n </label>\n\n <div className=\"mt-4 flex flex-wrap gap-3\">\n <button\n type=\"button\"\n onClick={handleSubmitReview}\n disabled={creatingReview || updatingReview}\n className=\"cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {creatingReview || updatingReview\n ? 'Saving...'\n : productDetails?.userReview\n ? 'Update Review'\n : 'Submit Review'}\n </button>\n {productDetails?.userReview && (\n <button\n type=\"button\"\n onClick={handleDeleteReview}\n disabled={deletingReview}\n className=\"cursor-pointer rounded-lg border border-status-error-border px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {deletingReview ? 'Removing...' : 'Delete Review'}\n </button>\n )}\n </div>\n </div>\n )}\n </div>\n ) : (\n <p className=\"text-center text-sm text-text-muted\">\n Purchase this app to submit a review.\n </p>\n )}\n </div>\n </GlassCard>\n\n {/* Reviews List */}\n {reviews && reviews.length > 0 && (\n <div className=\"mt-4 space-y-3\">\n <ul className=\"space-y-3\">\n {(showAllReviews ? reviews : reviews.slice(0, 2)).map((review) => (\n <li key={review.id}>\n <ReviewCard\n review={review}\n onMarkHelpful={handleMarkHelpful}\n markingHelpful={markingHelpful && helpfulReviewId === review.id}\n />\n </li>\n ))}\n </ul>\n {reviews.length > 2 && (\n <button\n type=\"button\"\n onClick={() => setShowAllReviews(!showAllReviews)}\n className=\"cursor-pointer text-sm font-medium text-text-link\"\n >\n {showAllReviews ? 'Show less' : `Show all ${reviews.length} reviews`}\n </button>\n )}\n </div>\n )}\n {(!reviews || reviews.length === 0) && (\n <p className=\"mt-4 text-sm text-text-muted\">\n No reviews yet. Be the first to review!\n </p>\n )}\n </section>\n\n {/* Permissions */}\n {permissions.length > 0 && (\n <section id=\"about-permissions\" className=\"mb-8 scroll-mt-6\">\n <h2 className=\"mb-4 text-lg font-medium text-text-primary\">Required Permissions</h2>\n <div className=\"space-y-2\">\n {permissions.map((permission) => (\n <div\n key={permission}\n className=\"flex items-center gap-3 rounded-lg bg-bg-surface px-4 py-3\"\n >\n <ShieldCheck className=\"size-5 text-status-success-text\" />\n <span className=\"text-sm text-text-primary\">{permission}</span>\n </div>\n ))}\n </div>\n </section>\n )}\n\n {/* Integrations */}\n {integrations.length > 0 && (\n <section className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-medium text-text-primary\">Integrations</h2>\n <div className=\"flex flex-wrap gap-2\">\n {integrations.map((integration) => (\n <span\n key={integration}\n className=\"rounded-lg bg-bg-surface px-4 py-2 text-sm font-medium text-text-primary\"\n >\n {integration}\n </span>\n ))}\n </div>\n </section>\n )}\n\n {/* Additional Information */}\n <section className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-medium text-text-primary\">Additional Information</h2>\n <GlassCard treatment=\"metric\" className=\"grid grid-cols-2 gap-6 p-5 md:grid-cols-3\">\n {safeProduct.manifestVersion && (\n <div>\n <p className=\"text-xs text-text-muted\">Version</p>\n <p className=\"mt-1 text-sm font-medium text-text-primary\">\n {safeProduct.manifestVersion}\n </p>\n </div>\n )}\n <div>\n <p className=\"text-xs text-text-muted\">Type</p>\n <p className=\"mt-1 text-sm font-medium text-text-primary\">{safeProduct.type}</p>\n </div>\n {safeProduct.publishedAt && (\n <div>\n <p className=\"text-xs text-text-muted\">Published</p>\n <p className=\"mt-1 text-sm font-medium text-text-primary\">\n {new Date(safeProduct.publishedAt).toLocaleDateString()}\n </p>\n </div>\n )}\n <div>\n <p className=\"text-xs text-text-muted\">Updated</p>\n <p className=\"mt-1 text-sm font-medium text-text-primary\">\n {new Date(safeProduct.updatedAt).toLocaleDateString()}\n </p>\n </div>\n {safeProduct.license && (\n <div>\n <p className=\"text-xs text-text-muted\">License</p>\n <p className=\"mt-1 text-sm font-medium text-text-primary\">\n {safeProduct.license}\n </p>\n </div>\n )}\n {safeProduct.minPlatformVersion && (\n <div>\n <p className=\"text-xs text-text-muted\">Min Platform Version</p>\n <p className=\"mt-1 text-sm font-medium text-text-primary\">\n {safeProduct.minPlatformVersion}\n </p>\n </div>\n )}\n </GlassCard>\n </section>\n </div>\n\n {/* Right Sidebar */}\n <div className=\"w-full lg:w-80\">\n {/* App Support */}\n {(safeProduct.documentationUrl || safeProduct.repositoryUrl || publisher?.email) && (\n <GlassCard className=\"mb-6 p-4\">\n <h3 className=\"font-medium text-text-primary\">App support</h3>\n <div className=\"mt-3 space-y-2 text-sm\">\n {safeProduct.documentationUrl && (\n <a\n href={safeProduct.documentationUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"block text-text-link hover:underline\"\n >\n Documentation\n </a>\n )}\n {safeProduct.repositoryUrl && (\n <a\n href={safeProduct.repositoryUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"block text-text-link hover:underline\"\n >\n Source repository\n </a>\n )}\n {publisher?.email && (\n <a\n href={`mailto:${publisher.email}`}\n className=\"block text-text-link hover:underline\"\n >\n Contact publisher\n </a>\n )}\n </div>\n </GlassCard>\n )}\n\n {/* More by Publisher */}\n {publisher && (\n <GlassCard className=\"mb-6 p-4\">\n <h3 className=\"font-medium text-text-primary\">Publisher</h3>\n <p className=\"mt-2 text-sm text-text-primary\">{publisher.name}</p>\n {publisher.bio && <p className=\"mt-2 text-sm text-text-muted\">{publisher.bio}</p>}\n {publisher.websiteUrl && (\n <a\n href={publisher.websiteUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"mt-3 inline-block text-sm text-text-link hover:underline\"\n >\n Visit publisher website\n </a>\n )}\n </GlassCard>\n )}\n\n {/* Similar Apps */}\n {relatedProducts && relatedProducts.length > 0 && (\n <div>\n <div className=\"mb-4 flex items-center justify-between text-left\">\n <span className=\"font-medium text-text-primary\">Similar apps</span>\n </div>\n <div className=\"space-y-3\">\n {relatedProducts.slice(0, 4).map((related) => (\n <button\n type=\"button\"\n key={related.id}\n onClick={() => navigate(`${basePath}/marketplace/product/${related.id}`)}\n className=\"flex w-full cursor-pointer items-center gap-3 rounded-lg p-2 text-left transition-colors hover:bg-bg-sunken\"\n >\n {related.icon ? (\n <img\n src={related.icon}\n alt={related.name}\n className=\"size-12 rounded-xl object-cover\"\n />\n ) : (\n <div className=\"flex size-12 items-center justify-center rounded-xl bg-bg-sunken text-lg font-bold text-text-muted\">\n {related.name.charAt(0)}\n </div>\n )}\n <div className=\"flex-1 overflow-hidden\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {related.name}\n </p>\n <p className=\"text-xs text-text-muted\">{publisher?.name || 'Unknown'}</p>\n {(related.reviewCount ?? 0) > 0 && (\n <div className=\"flex items-center gap-1\">\n <span className=\"text-xs text-text-muted\">\n {(related.rating || 0).toFixed(1)}\n </span>\n <Star className=\"size-3 fill-current text-status-warning-text\" />\n </div>\n )}\n </div>\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n </div>\n </main>\n\n {/* Install App Modal */}\n {safeProduct && (\n <InstallAppModal\n isOpen={isInstallModalOpen}\n onClose={() => setIsInstallModalOpen(false)}\n app={{\n id: safeProduct.id,\n name: safeProduct.name,\n slug: safeProduct.slug,\n icon: safeProduct.icon,\n type: safeProduct.type,\n version: safeProduct.manifestVersion,\n }}\n purchaseState={isPurchased && !isFree ? 'purchased' : 'free'}\n onInstallSuccess={handleInstallSuccess}\n onInstallError={handleInstallError}\n />\n )}\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AA+KA,IAAM,MAAwB,GAA4B,OAkDjD;CACL,IAAI,EAAa;CACjB,aAAa,GAAW,MAAM;CAC9B,WAAW;EACT,IAAI,GAAW,MAAM;EACrB,MAAM,GAAW,QAAQ,EAAa,cAAc;EACpD,aAAa,GAAW,QAAQ,EAAa,cAAc;EAC3D,OAAO,GAAW,SAAS;EAC3B,UAAU,GAAW,cAAc;EACnC,eAAe;EACf,gBAAgB;EAChB,eAAe;EACf,UAAU,GAAW,aAAa,EAAa;EAC/C,SAAS,GAAW;EACpB,SAAS,GAAW;EACrB;CACD,MAAM,EAAa;CACnB,MAAM,EAAa,QAAQ,EAAa;CACxC,aAAa,EAAa;CAC1B,aAAa,EAAa,mBAAmB,EAAa,eAAe;CACzE,kBAAkB,EAAa,eAAe;CAC9C,SAAS,EAAa;CACtB,gBAAgB,EAAa,eAAe,EAAE;CAC9C,WAAW,EAAa,aAAa,EAAE;CACvC,YAvCmB,GAAgB,MAC/B,MAAW,aAAmB,aACY;EAC5C,KAAK;EACL,QAAQ;EACR,OAAO;EACP,UAAU;EACV,UAAU;EACV,aAAa;EACb,WAAW;EACX,OAAO;EACR,CACkB,MAAS,OA2BN,EAAa,QAAQ,EAAa,KAAK;CAC7D,QA7DsB,OACuB;EAC3C,KAAK;EACL,QAAQ;EACR,OAAO;EACP,UAAU;EACV,UAAU;EACV,aAAa;EACb,WAAW;EACX,OAAO;EACP,QAAQ;EACR,WAAW;EACX,QAAQ;EACR,YAAY;EACZ,SAAS;EACT,MAAM;EACP,EACc,MAAS,kBA4CH,EAAa,KAAK;CACvC,MAAM,EAAa,QAAQ,EAAE;CAC7B,gBA3EuB,OAC2B;EAChD,MAAM;EACN,cAAc;EACd,cAAc;EACd,aAAa;EACb,UAAU;EACX,EACc,MAAU,YAmEK,EAAa,aAAa;CACxD,WAAW,EAAa;CACxB,UAAU,EAAa,YAAY;CACnC,UAAU,EAAE;CACZ,QAAS,EAAa,UAA4B;CAClD,UAAU,EAAa;CACvB,UAAU,GAAW,cAAc;CACnC,eAAe,EAAa;CAC5B,cAAc,EAAa;CAC3B,YAAY;CACZ,eAAe,EAAa,UAAU;CACtC,aAAa,EAAa;CAC1B,WAAW,EAAa;CACxB,WAAW,EAAa;CACxB,aAAa,EAAa;CAC3B,GAUG,MAAuE,EAC3E,UACA,eACA,eAEA,kBAAC,OAAD;CAAK,WAAU;WAAf;EACE,kBAAC,QAAD;GAAM,WAAU;aAA+B;GAAa,CAAA;EAC5D,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IACE,WAAU;IACV,OAAO,EAAE,OAAO,GAAG,EAAW,IAAI;IAClC,CAAA;GACE,CAAA;EACN,kBAAC,QAAD;GAAM,WAAU;aAA2C,EAAa,EAAM;GAAQ,CAAA;EAClF;IAMF,MAIA,EAAE,WAAQ,kBAAe,wBAc3B,kBAAC,OAAD;CAAK,WAAU;WAAf;EACE,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAO,OAAO,OAAO,EAAE,CAAC,aAAa;KAClC,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;KAAG,WAAU;eAAb,CAA6C,SAAM,EAAO,OAAO,MAAM,GAAG,EAAE,CAAK;QACjF,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBACZ;OAAC;OAAG;OAAG;OAAG;OAAG;OAAE,CAAC,KAAK,MACpB,kBAAC,GAAD,EAEE,WAAW,UACT,KAAQ,EAAO,SACX,0CACA,qBAEN,EANK,EAML,CACF;MACE,CAAA,EACN,kBAAC,QAAD;MAAM,WAAU;kBAlCR,MAAuB;AACzC,WAAI;AACF,eAAO,IAAI,KAAK,EAAW,CAAC,mBAAmB,SAAS;SACtD,MAAM;SACN,OAAO;SACP,KAAK;SACN,CAAC;eACI;AACN,eAAO;;SA0BuD,EAAO,UAAU;MAAQ,CAAA,CAC3E;OACF,EAAA,CAAA,CACF;;GACF,CAAA;EACL,EAAO,SAAS,kBAAC,MAAD;GAAI,WAAU;aAAsC,EAAO;GAAW,CAAA;EACtF,EAAO,WAAW,kBAAC,KAAD;GAAG,WAAU;aAAgC,EAAO;GAAY,CAAA;EACnF,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAc,EAAO,GAAG;IACvC,UAAU;IACV,cAAY,oBAAoB,EAAO,OAAO;IAC9C,WAAU;cALZ,CAOE,kBAAC,GAAD,EAAU,WAAU,YAAa,CAAA,EACjC,kBAAC,QAAD,EAAA,UAAO,IAAiB,cAAc,YAAY,EAAO,QAAQ,IAAU,CAAA,CACpE;;GACL,CAAA;EACF;IAOJ,WACJ,kBAAC,OAAD;CAAK,WAAU;WAAf,CAEE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,OAAD,EAAK,WAAU,iDAAkD,CAAA;IACjE,kBAAC,OAAD,EAAK,WAAU,sDAAuD,CAAA;IACtE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD,EAAK,WAAU,iDAAkD,CAAA,EACjE,kBAAC,OAAD,EAAK,WAAU,iDAAkD,CAAA,CAC7D;;IACF;;EACF,CAAA,EAEN,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,OAAD;IAAK,WAAU;cAAf,CAEE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD,EAAK,WAAU,kDAAmD,CAAA,EAClE,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,OAAD,EAAK,WAAU,gDAAiD,CAAA;OAChE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,+CAAgD,CAAA,EAC/D,kBAAC,OAAD,EAAK,WAAU,kDAAmD,CAAA,CAC9D;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,+CAAgD,CAAA,EAC/D,kBAAC,OAAD,EAAK,WAAU,+CAAgD,CAAA,CAC3D;;OACF;QACF;QAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,gDAAiD,CAAA,EAChE,kBAAC,OAAD,EAAK,WAAU,oDAAqD,CAAA,CAChE;;OACN,kBAAC,OAAD,EAAK,WAAU,+BAAgC,CAAA;OAC/C,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,+CAAgD,CAAA,EAC/D,kBAAC,OAAD,EAAK,WAAU,oDAAqD,CAAA,CAChE;;OACN,kBAAC,OAAD,EAAK,WAAU,+BAAgC,CAAA;OAC/C,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,+CAAgD,CAAA,EAC/D,kBAAC,OAAD,EAAK,WAAU,oDAAqD,CAAA,CAChE;;OACF;SACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,mDAAoD,CAAA,EACnE,kBAAC,OAAD,EAAK,WAAU,iDAAkD,CAAA,CAC7D;QACF;OACF;;GAGN,kBAAC,WAAD;IAAS,WAAU;cAAnB,CACE,kBAAC,OAAD,EAAK,WAAU,sDAAuD,CAAA,EACtE,kBAAC,OAAD;KAAK,WAAU;eACZ,CAAC,GAAG;;;;;MAAQ,CAAC,CAAC,KAAK,GAAG,MACrB,kBAAC,OAAD,EAAa,WAAU,mDAAoD,EAAjE,EAAiE,CAC3E;KACE,CAAA,CACE;;GAGV,kBAAC,WAAD;IAAS,WAAU;cAAnB,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD,EAAK,WAAU,6CAA8C,CAAA,EAC7D,kBAAC,OAAD,EAAK,WAAU,+CAAgD,CAAA,CAC3D;QACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,OAAD,EAAK,WAAU,mCAAoC,CAAA;OACnD,kBAAC,OAAD,EAAK,WAAU,mCAAoC,CAAA;OACnD,kBAAC,OAAD,EAAK,WAAU,kCAAmC,CAAA;OAClD,kBAAC,OAAD,EAAK,WAAU,kCAAmC,CAAA;OAC9C;SACN,kBAAC,OAAD;MAAK,WAAU;gBACZ,CAAC,GAAG;;;;;OAAQ,CAAC,CAAC,KAAK,GAAG,MACrB,kBAAC,OAAD,EAAa,WAAU,sCAAuC,EAApD,EAAoD,CAC9D;MACE,CAAA,CACF;OACE;;GAGV,kBAAC,WAAD;IAAS,WAAU;cAAnB;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,6CAA8C,CAAA,EAC7D,kBAAC,OAAD,EAAK,WAAU,+CAAgD,CAAA,CAC3D;UACN,kBAAC,OAAD,EAAK,WAAU,+CAAgD,CAAA,CAC3D;;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,OAAD,EAAK,WAAU,kCAAmC,CAAA;UAClD,kBAAC,OAAD;WAAK,WAAU;qBACZ,CAAC,GAAG;;;;;;YAAQ,CAAC,CAAC,KAAK,GAAG,MACrB,kBAAC,OAAD,EAAa,WAAU,+BAAgC,EAA7C,EAA6C,CACvD;WACE,CAAA;UACN,kBAAC,OAAD,EAAK,WAAU,iCAAkC,CAAA;UAC7C;YACN,kBAAC,OAAD;SAAK,WAAU;mBACZ,CAAC,GAAG;;;;;;UAAQ,CAAC,CAAC,KAAK,GAAG,MACrB,kBAAC,OAAD;UAAa,WAAU;oBAAvB;WACE,kBAAC,OAAD,EAAK,WAAU,gCAAiC,CAAA;WAChD,kBAAC,OAAD,EAAK,WAAU,wCAAyC,CAAA;WACxD,kBAAC,OAAD,EAAK,WAAU,gCAAiC,CAAA;WAC5C;YAJI,EAIJ,CACN;SACE,CAAA,CACF;;OACF,CAAA,EACN,kBAAC,OAAD,EAAK,WAAU,mDAAoD,CAAA,CAC/D;;KAEN,kBAAC,OAAD;MAAK,WAAU;gBACZ,CAAC,GAAG,KAAQ,CAAC,CAAC,KAAK,GAAG,MACrB,kBAAC,OAAD;OAEE,WAAU;iBAFZ,CAIE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,qCAAsC,CAAA,EACrD,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,iCAAkC,CAAA,EACjD,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,OAAD;WAAK,WAAU;qBACZ,CAAC,GAAG;;;;;;YAAQ,CAAC,CAAC,KAAK,GAAG,MACrB,kBAAC,OAAD,EAAa,WAAU,+BAAgC,EAA7C,EAA6C,CACvD;WACE,CAAA,EACN,kBAAC,OAAD,EAAK,WAAU,iCAAkC,CAAA,CAC7C;YACF;WACF;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,mCAAoC,CAAA,EACnD,kBAAC,OAAD,EAAK,WAAU,kCAAmC,CAAA,CAC9C;UACF;SArBC,EAqBD,CACN;MACE,CAAA;KACE;;GAGV,kBAAC,WAAD;IAAS,WAAU;cAAnB,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD,EAAK,WAAU,6CAA8C,CAAA,EAC7D,kBAAC,OAAD,EAAK,WAAU,+CAAgD,CAAA,CAC3D;QACN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBACZ,CAAC,GAAG;;;;;;;OAAQ,CAAC,CAAC,KAAK,GAAG,MACrB,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD,EAAK,WAAU,iCAAkC,CAAA,EACjD,kBAAC,OAAD,EAAK,WAAU,sCAAuC,CAAA,CAClD,EAAA,EAHI,EAGJ,CACN;MACE,CAAA;KACF,CAAA,CACE;;GAGV,kBAAC,WAAD;IAAS,WAAU;cAAnB,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,6CAA8C,CAAA,EAC7D,kBAAC,OAAD,EAAK,WAAU,+CAAgD,CAAA,CAC3D;SACN,kBAAC,OAAD,EAAK,WAAU,+CAAgD,CAAA,CAC3D;QACN,kBAAC,OAAD;KAAK,WAAU;eACZ,CAAC,GAAG;;;;;MAAQ,CAAC,CAAC,KAAK,GAAG,MACrB,kBAAC,OAAD;MAEE,WAAU;gBAEV,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,mCAAoC,CAAA,EACnD,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,OAAD,EAAK,WAAU,iCAAkC,CAAA;SACjD,kBAAC,OAAD,EAAK,WAAU,sCAAuC,CAAA;SACtD,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,gCAAiC,CAAA,EAChD,kBAAC,OAAD,EAAK,WAAU,iCAAkC,CAAA,CAC7C;;SACF;UACF;;MACF,EAdC,EAcD,CACN;KACE,CAAA,CACE;;GAGV,kBAAC,WAAD;IAAS,WAAU;cAAnB,CACE,kBAAC,OAAD,EAAK,WAAU,oDAAqD,CAAA,EACpE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,mCAAoC,CAAA,EACnD,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,iCAAkC,CAAA,EACjD,kBAAC,OAAD,EAAK,WAAU,oCAAqC,CAAA,CAChD;UACN,kBAAC,OAAD,EAAK,WAAU,sCAAuC,CAAA,CAClD,EAAA,CAAA,CACF;SACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,mCAAoC,CAAA,EACnD,kBAAC,OAAD,EAAK,WAAU,kCAAmC,CAAA,CAC9C;QACF;OACE;;GACN;IACF;IAMF,MAA+E,EACnF,UACA,YACA,gBAEA,kBAAC,OAAD;CAAK,WAAU;WACb,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD,EAAa,WAAU,+CAAgD,CAAA;GACvE,kBAAC,MAAD;IAAI,WAAU;cAA+C;IAA2B,CAAA;GACxF,kBAAC,KAAD;IAAG,WAAU;cACV,EAAM,WAAW;IAChB,CAAA;GACJ,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,UAAD;KACE,MAAK;KACL,SAAS;KACT,WAAU;eACX;KAEQ,CAAA,EACT,kBAAC,UAAD;KACE,MAAK;KACL,SAAS;KACT,WAAU;eACX;KAEQ,CAAA,CACL;;GACF;;CACF,CAAA,EAYK,WAA8B;CACzC,IAAM,EAAE,iBAAc,IAAkC,EAClD,IAAW,IAAa,EACxB,KAAW,IAAa,EACxB,EAAE,aAAU,mBAAgB,GAAU,EACtC,EAAE,eAAY,eAAW,iBAAc,gBAAa,mBAAgB,GAAS,EAK7E,EAAE,eAAe,IAAiB,SAAS,MAAyB,GAAiB;EACzF,QAL0B,SACnB,KAAa,IAAc;GAAE;GAAW;GAAa,GAAG,KAAA,GAC/D,CAAC,GAAW,EAAY,CACzB;EAGC,OAAO;EACR,CAAC,EACI,IAAgC,GAAgB,MACnD,MAAM,EAAE,cAAc,KAAa,EAAE,gBAAgB,KAAe,EAAE,WAAW,SACnF,EACK,EAAE,iBAAc,SAAS,MAAmB,IAAiB,EAC7D,EAAE,kBAAc,SAAS,OAAmB,IAAiB,EAC7D,EAAE,kBAAc,SAAS,OAAmB,IAAiB,EAC7D,EAAE,iBAAa,SAAS,OAAmB,IAAsB,EACjE,IAAM,IAAa,EAEnB,CAAC,GAAqB,MAA0B,EAAS,GAAM,EAC/D,CAAC,GAAgB,MAAqB,EAAS,GAAM,EACrD,CAAC,IAAW,KAAgB,EAAS,GAAM,EAC3C,CAAC,IAAa,KAAkB,EAAwB,KAAK,EAC7D,CAAC,IAAc,KAAmB,EAAwB,KAAK,EAC/D,CAAC,IAAkB,KAAuB,EAA8B,UAAU,EAClF,CAAC,GAAkB,KAAuB,EAAS,GAAM,EACzD,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,GAAe,KAAoB,EAAS,GAAG,EAChD,CAAC,GAAc,KAAmB,EAAS,EAAE,EAC7C,CAAC,IAAiB,MAAsB,EAAwB,KAAK,EAGrE,CAAC,IAAoB,MAAyB,EAAS,GAAM,EAG7D,EAAE,UAAM,aAAS,WAAO,eAAY,GAAuB;EAC/D,IAAI;EACJ,MAAM;EACN,gBAAgB;EAChB,cAAc;EACd,gBAAgB;EAChB,cAAc;EACd,iBAAiB;EAClB,CAAC,EAGI,IAAiB,IACjB,IAAU,GAAgB,SAC1B,IAAY,GAAgB,WAG5B,IAAW,GAAU,MAAM,MAAS,EAAK,cAAc,GAAS,GAAG,EAGnE,KAAkB,EAAY,YAAY;AACzC,SAIL;OAFA,EAAe,KAAK,EAEhB,GAAU;AACZ,MAAS,GAAG,EAAS,OAAO;AAC5B;;AAGF,OAAI;AAIF,UAAM,EAHc,GAAqB,GAAS,EAAU,EAG9B,KAAA,GAAW,EAAE;YAEpC,GAAO;AAEd,IADA,QAAQ,MAAM,kCAAkC,EAAM,EACtD,EAAe,wDAAwD;;;IAExE;EAAC;EAAS;EAAW;EAAY;EAAU;EAAU;EAAS,CAAC,EAG5D,KAAe,EAAY,YAAY;AACtC,SAGL;GADA,EAAe,KAAK,EACpB,EAAa,GAAK;AAElB,OAAI;IAEF,IAAM,IAAQ,EAAQ,SAAS,GAqBzB,IAAQ,MAAM,EAPD;KACjB,OAAO;KACP,WAAW,CAbI;MACf,WAAW,EAAQ;MACnB,MAAM,EAAQ;MACd,UAAU;MACV,WAAW;MACX,UAAU;MACV,UAAU,EAAQ,QAAQ,aAAa,IAAI;MAC3C,cAAc,EAAQ,gBAAgB;MACvC,CAKsB;KACrB,kBAAkB;KACnB,CAG0C;AAE3C,IAAI,GAAO,KAET,EAAS,2BAA2B,EAAM,KAAK,GAAS,SAAS,IAEjE,QAAQ,MAAM,yBAAyB,EACvC,EAAe,4CAA4C,EAC3D,EAAa,GAAM;YAEd,GAAO;AAId,IAHA,QAAQ,MAAM,kBAAkB,EAAM,EAEtC,EADgB,aAAiB,QAAQ,EAAM,UAAU,2BAClC,EACvB,EAAa,GAAM;;;IAEpB;EAAC;EAAS;EAAa;EAAS,CAAC,EAG9B,IAAoB,QAAkB;AACrC,OACL,GAAsB,GAAK;IAC1B,CAAC,EAAQ,CAAC,EAIP,KAAa,GAAO,EAAQ;AAClC,IAAW,UAAU;CACrB,IAAM,KAAS,GAAO,EAAI;AAE1B,CADA,GAAO,UAAU,GACjB,SAAgB;EACd,IAAM,IAAI,GAAW;AAChB,OACJ,GAAO,QAA0E,KAChF,wBACA;GACE,WAAW,EAAE;GACb,aAAa,EAAE;GACf,aAAa,EAAE;GACf,cAAc,EAAE;GACjB,CACF;IACA,CAAC,GAAS,GAAG,CAAC;CAGjB,IAAM,KAAuB,GAC1B,GAAqB,MAA0B;AACzC,QACJ,EAAsE,KACrE,2BACA;GACE,WAAW,EAAQ;GACnB;GACD,CACF,EACD,QAAQ,IACN,0BAA0B,EAAQ,KAAK,gBAAgB,EAAc,IAAI,EAAY,GACtF,EACI,GAAsB;IAE7B;EAAC;EAAS;EAAK;EAAqB,CACrC,EAGK,KAAqB,GAAa,MAAiB;AACvD,UAAQ,MAAM,wBAAwB,EAAM,QAAQ;IAEnD,EAAE,CAAC,EAEA,KAAiB,QAAkB;AAMvC,EALA,EAAe,GAAgB,YAAY,SAAS,GAAG,EACvD,EAAiB,GAAgB,YAAY,WAAW,GAAG,EAC3D,EAAgB,GAAgB,YAAY,UAAU,EAAE,EACxD,EAAgB,KAAK,EACrB,EAAoB,UAAU,EAC9B,EAAoB,GAAK;IACxB,CAAC,GAAgB,WAAW,CAAC,EAE1B,KAAqB,EAAY,YAAY;AACjD,MAAI,CAAC,EACH;AAGF,MAAI,IAAe,KAAK,IAAe,GAAG;AAExC,GADA,EAAoB,QAAQ,EAC5B,EAAgB,qCAAqC;AACrD;;EAGF,IAAM,IAAU;GACd,WAAW,EAAQ;GACnB,QAAQ;GACR,OAAO,EAAY,MAAM,IAAI,KAAA;GAC7B,SAAS,EAAc,MAAM,IAAI,KAAA;GAClC;AAUD,MAAI,EARW,GAAgB,aAC3B,MAAM,GAAa,EAAe,WAAW,IAAI;GAC/C,QAAQ,EAAQ;GAChB,OAAO,EAAQ;GACf,SAAS,EAAQ;GAClB,CAAC,GACF,MAAM,EAAa,EAAQ,GAElB;AAEX,GADA,EAAoB,QAAQ,EAC5B,EAAgB,mDAAmD;AACnE;;AAeF,EAZA,EAAoB,UAAU,EAC9B,EACE,GAAgB,aAAa,6BAA6B,6BAC3D,EACD,EAAoB,GAAM,EACzB,EAAsE,KACrE,0BACA;GACE,WAAW,EAAQ;GACnB,QAAQ;GACT,CACF,EACD,MAAM,GAAS;IACd;EACD;EACA;EACA;EACA,GAAgB;EAChB;EACA;EACA;EACA;EACA;EACD,CAAC,EAEI,KAAqB,EAAY,YAAY;AAC5C,SAAgB,eAGhB,GAAa,SAAS,EACT,MAAM,GAAc;GACpC,OAAO;GACP,SAAS;GACT,eAAe;GACf,mBAAmB;GACpB,CAAC,KACgB,KAKlB;OAAI,CADY,MAAM,GAAa,EAAe,WAAW,GAAG,EAClD;AAGP,IAFL,EAAoB,QAAQ,EAC5B,EAAgB,qDAAqD,EAChE,GAAa,QAAQ;AAC1B;;AAUF,GAPA,EAAoB,UAAU,EAC9B,EAAgB,2BAA2B,EAC3C,EAAoB,GAAM,EAC1B,EAAe,GAAG,EAClB,EAAiB,GAAG,EACpB,EAAgB,EAAE,EACb,GAAa,UAAU,EAC5B,MAAM,GAAS;;IACd;EAAC;EAAc,GAAgB;EAAY;EAAQ,CAAC,EAEjD,KAAoB,EACxB,OAAO,MAAqB;AAM1B,EALA,GAAmB,EAAS,EACb,MAAM,GAAY,EAAS,IAExC,MAAM,GAAS,EAEjB,GAAmB,KAAK;IAE1B,CAAC,IAAa,EAAQ,CACvB;AAGD,KAAI,GACF,QAAO,kBAAC,IAAD,EAAmB,CAAA;AAI5B,KAAI,GACF,QACE,kBAAC,IAAD;EACS;EACP,SAAS;EACT,cAAc,EAAS,GAAG,EAAS,cAAc;EACjD,CAAA;AAKN,KAAI,CAAC,GAAgB,QACnB,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,IAAD;GACE,cAAa;GACb,OAAM;GACN,aAAY;GACZ,QACE,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAS,GAAG,EAAS,cAAc;IAClD,WAAU;cACX;IAEQ,CAAA;GAEX,CAAA;EACE,CAAA;CAIV,IAAM,EACJ,YACA,iBACA,oBACA,uBACA,gBACA,uBACE,GAGE,IAAc,GAGd,IAAe,IACjB,EAAmB,YACnB,EAAmB,YACnB,EAAmB,aACnB,EAAmB,WACnB,EAAmB,UACnB,GAEE,KAAyB,IAC3B;EACE;GACE,OAAO;GACP,OAAO,EAAmB;GAC1B,YAAY,IAAe,IAAK,EAAmB,YAAY,IAAgB,MAAM;GACtF;EACD;GACE,OAAO;GACP,OAAO,EAAmB;GAC1B,YAAY,IAAe,IAAK,EAAmB,YAAY,IAAgB,MAAM;GACtF;EACD;GACE,OAAO;GACP,OAAO,EAAmB;GAC1B,YAAY,IAAe,IAAK,EAAmB,aAAa,IAAgB,MAAM;GACvF;EACD;GACE,OAAO;GACP,OAAO,EAAmB;GAC1B,YAAY,IAAe,IAAK,EAAmB,WAAW,IAAgB,MAAM;GACrF;EACD;GACE,OAAO;GACP,OAAO,EAAmB;GAC1B,YAAY,IAAe,IAAK,EAAmB,UAAU,IAAgB,MAAM;GACpF;EACF,GACD,EAAE,EAGA,IAAc,EAAY,uBAAuB,EAAE,EAGnD,KAAe,EAAY,mBAAmB,EAAE,EAGhD,WACA,EAAY,iBAAiB,SAAe,SAC5C,EAAY,iBAAiB,iBACxB,GAAG,EAAY,EAAY,OAAO,EAAY,SAAS,CAAC,OAE1D,EAAY,EAAY,OAAO,EAAY,SAAS,EAIvD,IAAS,EAAY,iBAAiB,UAAU,EAAY,UAAU;AAE5E,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBAAf,CAEE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QAEE,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,EAAS,GAAG;SAC3B,WAAU;mBAHZ,CAKE,kBAAC,IAAD,EAAW,WAAU,UAAW,CAAA,EAAA,OAEzB;;QAGT,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAY;SACV,CAAA;QAGL,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACG,GAAW,aACV,kBAAC,KAAD;UACE,MAAM,EAAU;UAChB,QAAO;UACP,KAAI;UACJ,WAAU;oBAET,EAAU;UACT,CAAA,GAEJ,kBAAC,QAAD;UAAM,WAAU;oBACb,GAAW,QAAQ,EAAY,cAAc;UACzC,CAAA,EAER,GAAW,cACV,kBAAC,GAAD,EAAa,WAAU,iDAAkD,CAAA,CAEvE;;QAGN,kBAAC,KAAD;SAAG,WAAU;mBAAb;UACG,EAAY,YAAY,kBAAC,QAAD,EAAA,UAAO,EAAY,UAAgB,CAAA;UAC3D,EAAY,YAAY;UACxB,EAAa,EAAY,UAAU;UAAC;UACnC;;QAGJ,kBAAC,IAAD;SAAe,WAAU;mBAAzB;UAEA,kBAAC,OAAD;WAAK,WAAU;qBAAf;YAEE,kBAAC,OAAD;aAAK,WAAU;uBACZ,EAAY,OACX,kBAAC,OAAD;cAAK,KAAK,EAAY;cAAM,KAAI;cAAG,WAAU;cAA2B,CAAA,GAExE,kBAAC,QAAD;cAAM,WAAU;wBACb,EAAY,KAAK,OAAO,EAAE;cACtB,CAAA;aAEL,CAAA;YAGN,kBAAC,OAAD;aAAK,WAAU;uBAAf;cACE,kBAAC,QAAD;eAAM,WAAU;0BACZ,EAAY,UAAU,GAAG,QAAQ,EAAE;eAChC,CAAA;cACP,kBAAC,GAAD,EAAM,WAAU,gDAAiD,CAAA;cACjE,kBAAC,QAAD;eAAM,WAAU;yBAAhB,CACG,EAAa,KAAgB,EAAY,YAAY,EAAC,WAClD;;cACH;;YAGN,kBAAC,OAAD;aAAK,WAAU;uBAAf,CACE,kBAAC,QAAD;cAAM,WAAU;wBAAhB,CACG,EAAa,EAAY,UAAU,EAAC,IAChC;iBACP,kBAAC,KAAD;cAAG,WAAU;wBAA0B;cAAa,CAAA,CAChD;;YAGN,kBAAC,OAAD;aAAK,WAAU;uBAAf,CACE,kBAAC,QAAD;cAAM,WAAU;wBACb,EAAY;cACR,CAAA,EACP,kBAAC,KAAD;cAAG,WAAU;wBAAiC;cAAQ,CAAA,CAClD;;YACF;;UAGL,MACC,kBAAC,OAAD;WACE,MAAK;WACL,WAAU;qBAET;WACG,CAAA;UAGR,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACG,IACC,kBAAC,UAAD;YACE,MAAK;YACL,UAAA;YACA,WAAU;sBAHZ,CAKE,kBAAC,OAAD;aACE,WAAU;aACV,SAAQ;aACR,MAAK;aACL,QAAO;aACP,aAAY;aACZ,eAAc;aACd,gBAAe;aACf,eAAY;uBAEZ,kBAAC,YAAD,EAAU,QAAO,iBAAkB,CAAA;aAC/B,CAAA,EAAA,YAEC;gBACP,KAAe,CAAC,IAClB,kBAAC,UAAD;YACE,MAAK;YACL,SAAS;YACT,WAAU;sBACX;YAEQ,CAAA,GACP,IACF,kBAAC,UAAD;YACE,MAAK;YACL,SAAS;YACT,WAAU;sBACX;YAEQ,CAAA,GAET,kBAAC,UAAD;YACE,MAAK;YACL,SAAS;YACT,UAAU,MAAa;YACvB,WAAU;sBAET,MAAa,IACZ,kBAAA,IAAA,EAAA,UAAA,CACE,kBAAC,IAAD,EAAS,WAAU,uBAAwB,CAAA,EAAA,cAE1C,EAAA,CAAA,GAEH,OAAO,IAAiB;YAEnB,CAAA,EAIV,CAAC,KAAU,CAAC,KACX,kBAAC,UAAD;YACE,MAAK;YACL,SAAS;YACT,UAAU;YACV,WAAU;sBAJZ,CAMG,IACC,kBAAC,IAAD,EAAS,WAAU,uBAAwB,CAAA,GACzC,IACF,kBAAC,IAAD,EAAO,WAAU,mCAAoC,CAAA,GAErD,kBAAC,IAAD,EAAc,WAAU,UAAW,CAAA,EAEpC,IAAW,YAAY,cACjB;cAEP;;UAGN,kBAAC,KAAD;WAAG,WAAU;qBAAb,CACE,kBAAC,IAAD,EAAS,WAAU,UAAW,CAAA,EAAA,2CAE5B;;UAGH,KACC,kBAAC,KAAD;WAAG,WAAU;qBAAb;YACE,kBAAC,GAAD,EAAa,WAAU,mCAAoC,CAAA;;YACjD,EAAgB;YACzB,EAAgB,aACf,cAAc,IAAI,KAAK,EAAgB,UAAU,CAAC,oBAAoB,CAAC;YACvE;;UAEU;;QACZ;UAGN,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAY,eAAe,EAAY,YAAY,SAAS,IAC3D,kBAAC,OAAD;QACE,KAAK,EAAY,YAAY;QAC7B,KAAK,GAAG,EAAY,KAAK;QACzB,WAAU;QACV,CAAA,GAEF,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UAAK,WAAU;oBACZ,EAAY,KAAK,OAAO,EAAE;UACvB,CAAA,EACN,kBAAC,KAAD;UAAG,WAAU;oBAA0B;UAAwB,CAAA,CAC3D;;QACF,CAAA;OAEJ,CAAA,CACF;;KACF,CAAA;IACF,CAAA;GAGN,kBAAC,QAAD;IAAM,WAAU;cAAhB;KACE,kBAAC,IAAD;MAAa,WAAU;gBAAvB;OAA8B;OACsB,EAAY;OAAK;OAIvD;;KAEd,kBAAC,IAAD;MACE,WAAU;MACV,YAAW;MACX,OAAO;OACL,IACI;QACE,IAAI;QACJ,OAAO;QACP,aAAa;QACb,SAAS;QACT,MAAM;QACP,GACD;QACE,IAAI;QACJ,OAAO,IAAc,2BAA2B;QAChD,aAAa,IACT,yDACA;QACJ,SAAS,IAAc,IAAoB;QAC3C,MAAM;QACP;OACL,GAAI,EAAY,SAAS,IACrB,CACE;QACE,IAAI;QACJ,OAAO;QACP,aAAa;QACb,MAAM;QACP,CACF,GACD,EAAE;OACN;QACE,IAAI;QACJ,OAAO;QACP,aAAa;QACb,MAAM;QACP;OACF;MACD,CAAA;KAEF,kBAAC,OAAD;MAAK,WAAU;gBAAf,CAEE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QAEG,EAAY,eAAe,EAAY,YAAY,SAAS,KAC3D,kBAAC,WAAD;SAAS,WAAU;mBACjB,kBAAC,OAAD;UAAK,WAAU;oBACZ,EAAY,YAAY,KAAK,GAAY,MACxC,kBAAC,OAAD;WAEE,WAAU;qBAEV,kBAAC,OAAD;YACE,KAAK;YACL,KAAK,cAAc,IAAQ;YAC3B,WAAU;YACV,CAAA;WACE,EARC,EAQD,CACN;UACE,CAAA;SACE,CAAA;QAIZ,kBAAC,WAAD;SAAS,WAAU;mBAAnB;UACE,kBAAC,OAAD;WAAK,WAAU;qBACb,kBAAC,MAAD;YAAI,WAAU;sBAAwC;YAAmB,CAAA;WACrE,CAAA;UACN,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,KAAD;YAAG,WAAY,IAAuC,KAAjB;sBAClC,EAAY,mBACX,EAAY,eACZ;YACA,CAAA,IACD,EAAY,mBAAmB,EAAY,cAAc,UAAU,KAAK,OACzE,kBAAC,UAAD;YACE,MAAK;YACL,eAAe,GAAuB,CAAC,EAAoB;YAC3D,WAAU;sBAET,IAAsB,cAAc;YAC9B,CAAA,CAEP;;UAEL,EAAY,QAAQ,EAAY,KAAK,SAAS,KAC7C,kBAAC,OAAD;WAAK,WAAU;qBACZ,EAAY,KAAK,KAAK,MACrB,kBAAC,QAAD;YAEE,WAAU;sBAET;YACI,EAJA,EAIA,CACP;WACE,CAAA;UAEA;;QAGV,kBAAC,WAAD;SAAS,IAAG;SAAkB,WAAU;mBAAxC;UACE,kBAAC,OAAD;WAAK,WAAU;qBACb,kBAAC,MAAD;YAAI,WAAU;sBAAwC;YAAsB,CAAA;WACxE,CAAA;UAEN,kBAAC,GAAD;WAAW,WAAU;WAAU,WAAU;qBAAzC,CACG,KAAW,EAAQ,SAAS,IAC3B,kBAAC,OAAD;YAAK,WAAU;sBAAf,CAEE,kBAAC,OAAD;aAAK,WAAU;uBAAf;cACE,kBAAC,KAAD;eAAG,WAAU;0BACT,EAAY,UAAU,GAAG,QAAQ,EAAE;eACnC,CAAA;cACJ,kBAAC,OAAD;eAAK,WAAU;yBACZ;gBAAC;gBAAG;gBAAG;gBAAG;gBAAG;gBAAE,CAAC,KAAK,MACpB,kBAAC,GAAD,EAEE,WAAW,UACT,KAAQ,KAAK,MAAM,EAAY,UAAU,EAAE,GACvC,0CACA,qBAEN,EANK,EAML,CACF;eACE,CAAA;cACN,kBAAC,KAAD;eAAG,WAAU;yBAAb,CACG,EAAa,KAAgB,EAAY,YAAY,EAAC,WACrD;;cACA;gBAGL,GAAuB,SAAS,KAC/B,kBAAC,OAAD;aAAK,WAAU;uBACZ,GAAuB,KAAK,MAC3B,kBAAC,IAAD,EAA4B,GAAI,GAAQ,EAAxB,EAAK,MAAmB,CACxC;aACE,CAAA,CAEJ;gBAEN,kBAAC,OAAD;YAAK,WAAU;sBAAf;aACE,kBAAC,OAAD;cAAK,WAAU;wBACZ;eAAC;eAAG;eAAG;eAAG;eAAG;eAAE,CAAC,KAAK,MACpB,kBAAC,GAAD,EAAiB,WAAU,8BAA+B,EAA/C,EAA+C,CAC1D;cACE,CAAA;aACN,kBAAC,KAAD;cAAG,WAAU;wBAAgC;cAAkB,CAAA;aAC/D,kBAAC,KAAD;cAAG,WAAU;wBAA+B;cAExC,CAAA;aACA;eAIR,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACG,MACC,kBAAC,KAAD;aACE,MAAM,OAAqB,YAAY,WAAW;aAClD,WAAW,qCACT,OAAqB,YACjB,yDACA;uBAGL;aACC,CAAA,EAEL,KAAe,GAAgB,aAC9B,kBAAC,OAAD;aAAK,WAAU;uBAAf,CACE,kBAAC,UAAD;cACE,MAAK;cACL,eACE,IAAmB,EAAoB,GAAM,GAAG,IAAgB;cAElE,WAAU;wBAET,GAAgB,aACb,IACE,0BACA,qBACF,IACE,kBACA;cACC,CAAA,EAER,KACC,kBAAC,OAAD;cAAK,WAAU;wBAAf;eACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;gBAAG,WAAU;0BAAwC;gBAAe,CAAA,EACpE,kBAAC,OAAD;gBAAK,WAAU;0BACZ;iBAAC;iBAAG;iBAAG;iBAAG;iBAAG;iBAAE,CAAC,KAAK,MACpB,kBAAC,UAAD;iBAEE,MAAK;iBACL,eAAe,EAAgB,EAAK;iBACpC,WAAW,4EACT,MAAiB,IACb,+EACA;2BAPR,CAUG,GAAK,KACC;mBAVF,EAUE,CACT;gBACE,CAAA,CACF,EAAA,CAAA;eAEN,kBAAC,SAAD;gBAAO,WAAU;0BAAjB,CAAoE,SAElE,kBAAC,SAAD;iBACE,cAAW;iBACX,OAAO;iBACP,WAAW,MAAU,EAAe,EAAM,OAAO,MAAM;iBACvD,WAAU;iBACV,aAAY;iBACZ,CAAA,CACI;;eAER,kBAAC,SAAD;gBAAO,WAAU;0BAAjB,CAAoE,UAElE,kBAAC,YAAD;iBACE,cAAW;iBACX,OAAO;iBACP,WAAW,MAAU,EAAiB,EAAM,OAAO,MAAM;iBACzD,MAAM;iBACN,UAAA;iBACA,iBAAc;iBACd,WAAU;iBACV,aAAY;iBACZ,CAAA,CACI;;eAER,kBAAC,OAAD;gBAAK,WAAU;0BAAf,CACE,kBAAC,UAAD;iBACE,MAAK;iBACL,SAAS;iBACT,UAAU,KAAkB;iBAC5B,WAAU;2BAET,KAAkB,KACf,cACA,GAAgB,aACd,kBACA;iBACC,CAAA,EACR,GAAgB,cACf,kBAAC,UAAD;iBACE,MAAK;iBACL,SAAS;iBACT,UAAU;iBACV,WAAU;2BAET,KAAiB,gBAAgB;iBAC3B,CAAA,CAEP;;eACF;gBAEJ;iBAEN,kBAAC,KAAD;aAAG,WAAU;uBAAsC;aAE/C,CAAA,CAEF;cACI;;UAGX,KAAW,EAAQ,SAAS,KAC3B,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,MAAD;YAAI,WAAU;uBACV,IAAiB,IAAU,EAAQ,MAAM,GAAG,EAAE,EAAE,KAAK,MACrD,kBAAC,MAAD,EAAA,UACE,kBAAC,IAAD;aACU;aACR,eAAe;aACf,gBAAgB,MAAkB,OAAoB,EAAO;aAC7D,CAAA,EACC,EANI,EAAO,GAMX,CACL;YACC,CAAA,EACJ,EAAQ,SAAS,KAChB,kBAAC,UAAD;YACE,MAAK;YACL,eAAe,GAAkB,CAAC,EAAe;YACjD,WAAU;sBAET,IAAiB,cAAc,YAAY,EAAQ,OAAO;YACpD,CAAA,CAEP;;WAEN,CAAC,KAAW,EAAQ,WAAW,MAC/B,kBAAC,KAAD;WAAG,WAAU;qBAA+B;WAExC,CAAA;UAEE;;QAGT,EAAY,SAAS,KACpB,kBAAC,WAAD;SAAS,IAAG;SAAoB,WAAU;mBAA1C,CACE,kBAAC,MAAD;UAAI,WAAU;oBAA6C;UAAyB,CAAA,EACpF,kBAAC,OAAD;UAAK,WAAU;oBACZ,EAAY,KAAK,MAChB,kBAAC,OAAD;WAEE,WAAU;qBAFZ,CAIE,kBAAC,GAAD,EAAa,WAAU,mCAAoC,CAAA,EAC3D,kBAAC,QAAD;YAAM,WAAU;sBAA6B;YAAkB,CAAA,CAC3D;aALC,EAKD,CACN;UACE,CAAA,CACE;;QAIX,GAAa,SAAS,KACrB,kBAAC,WAAD;SAAS,WAAU;mBAAnB,CACE,kBAAC,MAAD;UAAI,WAAU;oBAA6C;UAAiB,CAAA,EAC5E,kBAAC,OAAD;UAAK,WAAU;oBACZ,GAAa,KAAK,MACjB,kBAAC,QAAD;WAEE,WAAU;qBAET;WACI,EAJA,EAIA,CACP;UACE,CAAA,CACE;;QAIZ,kBAAC,WAAD;SAAS,WAAU;mBAAnB,CACE,kBAAC,MAAD;UAAI,WAAU;oBAA6C;UAA2B,CAAA,EACtF,kBAAC,GAAD;UAAW,WAAU;UAAS,WAAU;oBAAxC;WACG,EAAY,mBACX,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;YAAG,WAAU;sBAA0B;YAAW,CAAA,EAClD,kBAAC,KAAD;YAAG,WAAU;sBACV,EAAY;YACX,CAAA,CACA,EAAA,CAAA;WAER,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;YAAG,WAAU;sBAA0B;YAAQ,CAAA,EAC/C,kBAAC,KAAD;YAAG,WAAU;sBAA8C,EAAY;YAAS,CAAA,CAC5E,EAAA,CAAA;WACL,EAAY,eACX,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;YAAG,WAAU;sBAA0B;YAAa,CAAA,EACpD,kBAAC,KAAD;YAAG,WAAU;sBACV,IAAI,KAAK,EAAY,YAAY,CAAC,oBAAoB;YACrD,CAAA,CACA,EAAA,CAAA;WAER,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;YAAG,WAAU;sBAA0B;YAAW,CAAA,EAClD,kBAAC,KAAD;YAAG,WAAU;sBACV,IAAI,KAAK,EAAY,UAAU,CAAC,oBAAoB;YACnD,CAAA,CACA,EAAA,CAAA;WACL,EAAY,WACX,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;YAAG,WAAU;sBAA0B;YAAW,CAAA,EAClD,kBAAC,KAAD;YAAG,WAAU;sBACV,EAAY;YACX,CAAA,CACA,EAAA,CAAA;WAEP,EAAY,sBACX,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;YAAG,WAAU;sBAA0B;YAAwB,CAAA,EAC/D,kBAAC,KAAD;YAAG,WAAU;sBACV,EAAY;YACX,CAAA,CACA,EAAA,CAAA;WAEE;YACJ;;QACN;UAGN,kBAAC,OAAD;OAAK,WAAU;iBAAf;SAEI,EAAY,oBAAoB,EAAY,iBAAiB,GAAW,UACxE,kBAAC,GAAD;SAAW,WAAU;mBAArB,CACE,kBAAC,MAAD;UAAI,WAAU;oBAAgC;UAAgB,CAAA,EAC9D,kBAAC,OAAD;UAAK,WAAU;oBAAf;WACG,EAAY,oBACX,kBAAC,KAAD;YACE,MAAM,EAAY;YAClB,QAAO;YACP,KAAI;YACJ,WAAU;sBACX;YAEG,CAAA;WAEL,EAAY,iBACX,kBAAC,KAAD;YACE,MAAM,EAAY;YAClB,QAAO;YACP,KAAI;YACJ,WAAU;sBACX;YAEG,CAAA;WAEL,GAAW,SACV,kBAAC,KAAD;YACE,MAAM,UAAU,EAAU;YAC1B,WAAU;sBACX;YAEG,CAAA;WAEF;YACI;;QAIb,KACC,kBAAC,GAAD;SAAW,WAAU;mBAArB;UACE,kBAAC,MAAD;WAAI,WAAU;qBAAgC;WAAc,CAAA;UAC5D,kBAAC,KAAD;WAAG,WAAU;qBAAkC,EAAU;WAAS,CAAA;UACjE,EAAU,OAAO,kBAAC,KAAD;WAAG,WAAU;qBAAgC,EAAU;WAAQ,CAAA;UAChF,EAAU,cACT,kBAAC,KAAD;WACE,MAAM,EAAU;WAChB,QAAO;WACP,KAAI;WACJ,WAAU;qBACX;WAEG,CAAA;UAEI;;QAIb,KAAmB,EAAgB,SAAS,KAC3C,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,QAAD;UAAM,WAAU;oBAAgC;UAAmB,CAAA;SAC/D,CAAA,EACN,kBAAC,OAAD;SAAK,WAAU;mBACZ,EAAgB,MAAM,GAAG,EAAE,CAAC,KAAK,MAChC,kBAAC,UAAD;UACE,MAAK;UAEL,eAAe,EAAS,GAAG,EAAS,uBAAuB,EAAQ,KAAK;UACxE,WAAU;oBAJZ,CAMG,EAAQ,OACP,kBAAC,OAAD;WACE,KAAK,EAAQ;WACb,KAAK,EAAQ;WACb,WAAU;WACV,CAAA,GAEF,kBAAC,OAAD;WAAK,WAAU;qBACZ,EAAQ,KAAK,OAAO,EAAE;WACnB,CAAA,EAER,kBAAC,OAAD;WAAK,WAAU;qBAAf;YACE,kBAAC,KAAD;aAAG,WAAU;uBACV,EAAQ;aACP,CAAA;YACJ,kBAAC,KAAD;aAAG,WAAU;uBAA2B,GAAW,QAAQ;aAAc,CAAA;aACvE,EAAQ,eAAe,KAAK,KAC5B,kBAAC,OAAD;aAAK,WAAU;uBAAf,CACE,kBAAC,QAAD;cAAM,WAAU;yBACZ,EAAQ,UAAU,GAAG,QAAQ,EAAE;cAC5B,CAAA,EACP,kBAAC,GAAD,EAAM,WAAU,gDAAiD,CAAA,CAC7D;;YAEJ;aACC;YA7BF,EAAQ,GA6BN,CACT;SACE,CAAA,CACF,EAAA,CAAA;QAEJ;SACF;;KACD;;GAGN,KACC,kBAAC,IAAD;IACE,QAAQ;IACR,eAAe,GAAsB,GAAM;IAC3C,KAAK;KACH,IAAI,EAAY;KAChB,MAAM,EAAY;KAClB,MAAM,EAAY;KAClB,MAAM,EAAY;KAClB,MAAM,EAAY;KAClB,SAAS,EAAY;KACtB;IACD,eAAe,KAAe,CAAC,IAAS,cAAc;IACtD,kBAAkB;IAClB,gBAAgB;IAChB,CAAA;GAEA"}
@@ -1,6 +1,6 @@
1
- import { getMainDefinition as e } from "../node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMainDefinition.js";
2
- import { GraphQLWsLink as t } from "../node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/subscriptions/index.js";
3
- import { createClient as n } from "../node_modules/.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws/dist/client.js";
1
+ import { getMainDefinition as e } from "../node_modules/@apollo/client/utilities/internal/getMainDefinition.js";
2
+ import { GraphQLWsLink as t } from "../node_modules/@apollo/client/link/subscriptions/index.js";
3
+ import { createClient as n } from "../node_modules/graphql-ws/dist/client.js";
4
4
  import { createContext as r, use as i, useMemo as a } from "react";
5
5
  import { ApolloClient as o, InMemoryCache as s, createHttpLink as c, from as l, split as u } from "@apollo/client/core";
6
6
  import { ApolloProvider as d } from "@apollo/client/react";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-store",
3
- "version": "2026.625.5",
3
+ "version": "2026.626.2",
4
4
  "description": "Store microfrontend for Burdenoff products",
5
5
  "type": "module",
6
6
  "files": [
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@apollo/client": "^4.0.11",
43
- "@burdenoff/fe-libs": "workspace:*",
43
+ "@burdenoff/fe-libs": "2026.625.5",
44
44
  "@tanstack/react-query": "^5.90.16",
45
45
  "clsx": "^2.1.1",
46
46
  "graphql": "^16.10.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"CombinedGraphQLErrors.js","names":[],"sources":["../../../../../../../../../../node_modules/.bun/@apollo+client@4.1.9+e571b0b00fd00a97/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js"],"sourcesContent":["import { brand, isBranded } from \"./utils.js\";\nfunction defaultFormatMessage(errors) {\n return (errors\n // Handle non-spec-compliant servers: See #1185\n .filter((e) => e)\n .map((e) => e.message || \"Error message not found.\")\n .join(\"\\n\"));\n}\n/**\n * Represents the combined list of GraphQL errors returned from the server in a\n * GraphQL response. This error type is used when your GraphQL operation returns\n * errors in the `errors` field of the response.\n *\n * @remarks\n *\n * When your GraphQL operation encounters errors on the server side (such as\n * resolver errors, validation errors, or syntax errors), the server returns\n * these errors in the `errors` array of the GraphQL response. Apollo Client\n * wraps these errors in a `CombinedGraphQLErrors` object, which provides access\n * to the individual errors while maintaining additional context about the\n * response.\n *\n * @example\n *\n * ```ts\n * import { CombinedGraphQLErrors } from \"@apollo/client/errors\";\n *\n * // Check if an error is a CombinedGraphQLErrors object\n * if (CombinedGraphQLErrors.is(error)) {\n * // Access individual GraphQL errors\n * error.errors.forEach((graphQLError) => {\n * console.log(graphQLError.message);\n * console.log(graphQLError.path);\n * console.log(graphQLError.locations);\n * });\n *\n * // Access the original GraphQL result\n * console.log(error.result);\n * }\n * ```\n */\nexport class CombinedGraphQLErrors extends Error {\n /**\n * A method that determines whether an error is a `CombinedGraphQLErrors`\n * object. This method enables TypeScript to narrow the error type.\n * \n * @example\n * \n * ```ts\n * if (CombinedGraphQLErrors.is(error)) {\n * // TypeScript now knows `error` is a `CombinedGraphQLErrors` object\n * console.log(error.errors);\n * }\n * ```\n */\n static is(error) {\n return isBranded(error, \"CombinedGraphQLErrors\");\n }\n /**\n * A function that formats the error message used for the error's `message`\n * property. Override this method to provide your own formatting.\n * \n * @remarks\n * \n * The `formatMessage` function is called by the `CombinedGraphQLErrors`\n * constructor to provide a formatted message as the `message` property of the\n * `CombinedGraphQLErrors` object. Follow the [\"Providing a custom message\n * formatter\"](https://www.apollographql.com/docs/react/api/errors/CombinedGraphQLErrors#providing-a-custom-message-formatter) guide to learn how to modify the message format.\n * \n * @param errors - The array of GraphQL errors returned from the server in\n * the `errors` field of the response.\n * @param options - Additional context that could be useful when formatting\n * the message.\n */\n static formatMessage = defaultFormatMessage;\n /**\n * The raw list of GraphQL errors returned by the `errors` field in the GraphQL response.\n */\n errors;\n /**\n * Partial data returned in the `data` field of the GraphQL response.\n */\n data;\n /**\n * Extensions returned by the `extensions` field in the GraphQL response.\n */\n extensions;\n constructor(result, errors = result.errors || []) {\n super(CombinedGraphQLErrors.formatMessage(errors, {\n result,\n defaultFormatMessage,\n }));\n this.errors = errors;\n this.data = result.data;\n this.extensions = result.extensions;\n this.name = \"CombinedGraphQLErrors\";\n brand(this);\n Object.setPrototypeOf(this, CombinedGraphQLErrors.prototype);\n }\n}\n//# sourceMappingURL=CombinedGraphQLErrors.js.map\n"],"x_google_ignoreList":[0],"mappings":";;AACA,SAAS,EAAqB,GAAQ;AAClC,QAAQ,EAEH,QAAQ,MAAM,EAAE,CAChB,KAAK,MAAM,EAAE,WAAW,2BAA2B,CACnD,KAAK,KAAK;;AAmCnB,IAAa,IAAb,MAAa,UAA8B,MAAM;CAc7C,OAAO,GAAG,GAAO;AACb,SAAO,EAAU,GAAO,wBAAwB;;CAkBpD,OAAO,gBAAgB;CAIvB;CAIA;CAIA;CACA,YAAY,GAAQ,IAAS,EAAO,UAAU,EAAE,EAAE;AAU9C,EATA,MAAM,EAAsB,cAAc,GAAQ;GAC9C;GACA;GACH,CAAC,CAAC,EACH,KAAK,SAAS,GACd,KAAK,OAAO,EAAO,MACnB,KAAK,aAAa,EAAO,YACzB,KAAK,OAAO,yBACZ,EAAM,KAAK,EACX,OAAO,eAAe,MAAM,EAAsB,UAAU"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../../../../../../../../../node_modules/.bun/@apollo+client@4.1.9+e571b0b00fd00a97/node_modules/@apollo/client/errors/utils.js"],"sourcesContent":["export function isBranded(error, name) {\n return (typeof error === \"object\" &&\n error !== null &&\n error[Symbol.for(\"apollo.error\")] === name);\n}\nexport function brand(error) {\n Object.defineProperty(error, Symbol.for(\"apollo.error\"), {\n value: error.name,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n}\n//# sourceMappingURL=utils.js.map"],"x_google_ignoreList":[0],"mappings":";AAAA,SAAgB,EAAU,GAAO,GAAM;AACnC,QAAQ,OAAO,KAAU,cACrB,KACA,EAAM,OAAO,IAAI,eAAe,MAAM;;AAE9C,SAAgB,EAAM,GAAO;AACzB,QAAO,eAAe,GAAO,OAAO,IAAI,eAAe,EAAE;EACrD,OAAO,EAAM;EACb,YAAY;EACZ,UAAU;EACV,cAAc;EACjB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ApolloLink.js","names":[],"sources":["../../../../../../../../../../../node_modules/.bun/@apollo+client@4.1.9+e571b0b00fd00a97/node_modules/@apollo/client/link/core/ApolloLink.js"],"sourcesContent":["import { EMPTY } from \"rxjs\";\nimport { createOperation } from \"@apollo/client/link/utils\";\nimport { __DEV__ } from \"@apollo/client/utilities/environment\";\nimport { invariant, newInvariantError, } from \"@apollo/client/utilities/invariant\";\n/**\n * The base class for all links in Apollo Client. A link represents either a\n * self-contained modification to a GraphQL operation or a side effect (such as\n * logging).\n *\n * @remarks\n *\n * Links enable you to customize Apollo Client's request flow by composing\n * together different pieces of functionality into a chain of links. Each\n * link represents a specific capability, such as adding authentication headers,\n * retrying failed requests, batching operations, or sending requests to a\n * GraphQL server.\n *\n * Every link must define a request handler via its constructor or by extending\n * this class and implementing the `request` method.\n *\n * @example\n *\n * ```ts\n * import { ApolloLink } from \"@apollo/client\";\n *\n * const link = new ApolloLink((operation, forward) => {\n * console.log(\"Operation:\", operation.operationName);\n * return forward(operation);\n * });\n * ```\n */\nexport class ApolloLink {\n /**\n * Creates a link that completes immediately and does not emit a result.\n *\n * @example\n *\n * ```ts\n * const link = ApolloLink.empty();\n * ```\n */\n static empty() {\n return new ApolloLink(() => EMPTY);\n }\n /**\n * Composes multiple links into a single composed link that executes each\n * provided link in serial order.\n *\n * @example\n *\n * ```ts\n * import { from, HttpLink, ApolloLink } from \"@apollo/client\";\n * import { RetryLink } from \"@apollo/client/link/retry\";\n * import MyAuthLink from \"../auth\";\n *\n * const link = ApolloLink.from([\n * new RetryLink(),\n * new MyAuthLink(),\n * new HttpLink({ uri: \"http://localhost:4000/graphql\" }),\n * ]);\n * ```\n *\n * @param links - An array of `ApolloLink` instances or request handlers that\n * are executed in serial order.\n */\n static from(links) {\n if (links.length === 0)\n return ApolloLink.empty();\n const [first, ...rest] = links;\n return first.concat(...rest);\n }\n /**\n * Creates a link that conditionally routes a request to different links.\n *\n * @example\n *\n * ```ts\n * import { ApolloLink, HttpLink } from \"@apollo/client\";\n *\n * const link = ApolloLink.split(\n * (operation) => operation.getContext().version === 1,\n * new HttpLink({ uri: \"http://localhost:4000/v1/graphql\" }),\n * new HttpLink({ uri: \"http://localhost:4000/v2/graphql\" })\n * );\n * ```\n *\n * @param test - A predicate function that receives the current `operation`\n * and returns a boolean indicating which link to execute. Returning `true`\n * executes the `left` link. Returning `false` executes the `right` link.\n *\n * @param left - The link that executes when the `test` function returns\n * `true`.\n *\n * @param right - The link that executes when the `test` function returns\n * `false`. If the `right` link is not provided, the request is forwarded to\n * the next link in the chain.\n */\n static split(test, left, right = new ApolloLink((op, forward) => forward(op))) {\n const link = new ApolloLink((operation, forward) => {\n const result = test(operation);\n if (__DEV__) {\n if (typeof result !== \"boolean\") {\n __DEV__ && invariant.warn(63, result);\n }\n }\n return result ?\n left.request(operation, forward)\n : right.request(operation, forward);\n });\n return Object.assign(link, { left, right });\n }\n /**\n * Executes a GraphQL request against a link. The `execute` function begins\n * the request by calling the request handler of the link.\n *\n * @example\n *\n * ```ts\n * const observable = ApolloLink.execute(link, { query, variables }, { client });\n *\n * observable.subscribe({\n * next(value) {\n * console.log(\"Received\", value);\n * },\n * error(error) {\n * console.error(\"Oops got error\", error);\n * },\n * complete() {\n * console.log(\"Request complete\");\n * },\n * });\n * ```\n *\n * @param link - The `ApolloLink` instance to execute the request.\n *\n * @param request - The GraphQL request details, such as the `query` and\n * `variables`.\n *\n * @param context - The execution context for the request, such as the\n * `client` making the request.\n */\n static execute(link, request, context) {\n return link.request(createOperation(request, context), () => {\n if (__DEV__) {\n __DEV__ && invariant.warn(64);\n }\n return EMPTY;\n });\n }\n /**\n * Combines multiple links into a single composed link.\n *\n * @example\n *\n * ```ts\n * const link = ApolloLink.concat(firstLink, secondLink, thirdLink);\n * ```\n *\n * @param links - The links to concatenate into a single link. Each link will\n * execute in serial order.\n *\n * @deprecated Use `ApolloLink.from` instead. `ApolloLink.concat` will be\n * removed in a future major version.\n */\n static concat(...links) {\n return ApolloLink.from(links);\n }\n constructor(request) {\n if (request)\n this.request = request;\n }\n /**\n * Concatenates a link that conditionally routes a request to different links.\n *\n * @example\n *\n * ```ts\n * import { ApolloLink, HttpLink } from \"@apollo/client\";\n *\n * const previousLink = new ApolloLink((operation, forward) => {\n * // Handle the request\n *\n * return forward(operation);\n * });\n *\n * const link = previousLink.split(\n * (operation) => operation.getContext().version === 1,\n * new HttpLink({ uri: \"http://localhost:4000/v1/graphql\" }),\n * new HttpLink({ uri: \"http://localhost:4000/v2/graphql\" })\n * );\n * ```\n *\n * @param test - A predicate function that receives the current `operation`\n * and returns a boolean indicating which link to execute. Returning `true`\n * executes the `left` link. Returning `false` executes the `right` link.\n *\n * @param left - The link that executes when the `test` function returns\n * `true`.\n *\n * @param right - The link that executes when the `test` function returns\n * `false`. If the `right` link is not provided, the request is forwarded to\n * the next link in the chain.\n */\n split(test, left, right) {\n return this.concat(ApolloLink.split(test, left, right));\n }\n /**\n * Combines the link with other links into a single composed link.\n *\n * @example\n *\n * ```ts\n * import { ApolloLink, HttpLink } from \"@apollo/client\";\n *\n * const previousLink = new ApolloLink((operation, forward) => {\n * // Handle the request\n *\n * return forward(operation);\n * });\n *\n * const link = previousLink.concat(\n * link1,\n * link2,\n * new HttpLink({ uri: \"http://localhost:4000/graphql\" })\n * );\n * ```\n */\n concat(...links) {\n if (links.length === 0) {\n return this;\n }\n return links.reduce(this.combine.bind(this), this);\n }\n combine(left, right) {\n const link = new ApolloLink((operation, forward) => {\n return left.request(operation, (op) => right.request(op, forward));\n });\n return Object.assign(link, { left, right });\n }\n /**\n * Runs the request handler for the provided operation.\n *\n * > [!NOTE]\n * > This is called by the `ApolloLink.execute` function for you and should\n * > not be called directly. Prefer using `ApolloLink.execute` to make the\n * > request instead.\n */\n request(operation, forward) {\n throw newInvariantError(65);\n }\n /**\n * @internal\n * Used to iterate through all links that are concatenations or `split` links.\n * \n * @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.\n */\n left;\n /**\n * @internal\n * Used to iterate through all links that are concatenations or `split` links.\n * \n * @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.\n */\n right;\n}\n//# sourceMappingURL=ApolloLink.js.map\n"],"x_google_ignoreList":[0],"mappings":";;;;AA+BA,IAAa,IAAb,MAAa,EAAW;CAUpB,OAAO,QAAQ;AACX,SAAO,IAAI,QAAiB,EAAM;;CAuBtC,OAAO,KAAK,GAAO;AACf,MAAI,EAAM,WAAW,EACjB,QAAO,EAAW,OAAO;EAC7B,IAAM,CAAC,GAAO,GAAG,KAAQ;AACzB,SAAO,EAAM,OAAO,GAAG,EAAK;;CA4BhC,OAAO,MAAM,GAAM,GAAM,IAAQ,IAAI,GAAY,GAAI,MAAY,EAAQ,EAAG,CAAC,EAAE;EAC3E,IAAM,IAAO,IAAI,GAAY,GAAW,MACrB,EAAK,EAAU,GAO1B,EAAK,QAAQ,GAAW,EAAQ,GAC9B,EAAM,QAAQ,GAAW,EAAQ,CACzC;AACF,SAAO,OAAO,OAAO,GAAM;GAAE;GAAM;GAAO,CAAC;;CAgC/C,OAAO,QAAQ,GAAM,GAAS,GAAS;AACnC,SAAO,EAAK,QAAQ,EAAgB,GAAS,EAAQ,QAI1C,EACT;;CAiBN,OAAO,OAAO,GAAG,GAAO;AACpB,SAAO,EAAW,KAAK,EAAM;;CAEjC,YAAY,GAAS;AACjB,EAAI,MACA,KAAK,UAAU;;CAkCvB,MAAM,GAAM,GAAM,GAAO;AACrB,SAAO,KAAK,OAAO,EAAW,MAAM,GAAM,GAAM,EAAM,CAAC;;CAuB3D,OAAO,GAAG,GAAO;AAIb,SAHI,EAAM,WAAW,IACV,OAEJ,EAAM,OAAO,KAAK,QAAQ,KAAK,KAAK,EAAE,KAAK;;CAEtD,QAAQ,GAAM,GAAO;EACjB,IAAM,IAAO,IAAI,GAAY,GAAW,MAC7B,EAAK,QAAQ,IAAY,MAAO,EAAM,QAAQ,GAAI,EAAQ,CAAC,CACpE;AACF,SAAO,OAAO,OAAO,GAAM;GAAE;GAAM;GAAO,CAAC;;CAU/C,QAAQ,GAAW,GAAS;AACxB,QAAM,EAAkB,GAAG;;CAQ/B;CAOA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../../../../../../../../node_modules/.bun/@apollo+client@4.1.9+e571b0b00fd00a97/node_modules/@apollo/client/link/subscriptions/index.js"],"sourcesContent":["// This file is adapted from the graphql-ws npm package:\n// https://github.com/enisdenjo/graphql-ws\n//\n// Most of the file comes from that package's README; some other parts (such as\n// isLikeCloseEvent) come from its source.\n//\n// Here's the license of the original code:\n//\n// The MIT License (MIT)\n//\n// Copyright (c) 2020-2021 Denis Badurina\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nimport { Observable } from \"rxjs\";\nimport { CombinedGraphQLErrors } from \"@apollo/client/errors\";\nimport { ApolloLink } from \"@apollo/client/link\";\nimport { print } from \"@apollo/client/utilities\";\nimport { isNonNullObject } from \"@apollo/client/utilities/internal\";\n// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close_event\nfunction isLikeCloseEvent(val) {\n return isNonNullObject(val) && \"code\" in val && \"reason\" in val;\n}\n// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/error_event\nfunction isLikeErrorEvent(err) {\n return isNonNullObject(err) && err.target?.readyState === WebSocket.CLOSED;\n}\n/**\n * The `GraphQLWsLink` is a terminating link sends GraphQL operations over a\n * WebSocket connection using the [`graphql-ws`](https://www.npmjs.com/package/graphql-ws) library. It's used most\n * commonly with GraphQL [subscriptions](https://apollographql.com/docs/react/data/subscriptions/),\n *\n * > [!NOTE]\n * > This link works with the `graphql-ws` library. If your server uses\n * > the deprecated `subscriptions-transport-ws` library, use the deprecated\n * > [`WebSocketLink`](https://apollographql.com/docs/react/api/link/apollo-link-ws) link instead.\n *\n * @example\n *\n * ```ts\n * import { GraphQLWsLink } from \"@apollo/client/link/subscriptions\";\n * import { createClient } from \"graphql-ws\";\n *\n * const link = new GraphQLWsLink(\n * createClient({\n * url: \"ws://localhost:3000/subscriptions\",\n * })\n * );\n * ```\n */\nexport class GraphQLWsLink extends ApolloLink {\n client;\n constructor(client) {\n super();\n this.client = client;\n }\n request(operation) {\n return new Observable((observer) => {\n const { query, variables, operationName, extensions } = operation;\n return this.client.subscribe({ variables, operationName, extensions, query: print(query) }, {\n next: observer.next.bind(observer),\n complete: observer.complete.bind(observer),\n error: (err) => {\n if (err instanceof Error) {\n return observer.error(err);\n }\n const likeClose = isLikeCloseEvent(err);\n if (likeClose || isLikeErrorEvent(err)) {\n return observer.error(\n // reason will be available on clean closes\n new Error(`Socket closed${likeClose ? ` with event ${err.code}` : \"\"}${likeClose ? ` ${err.reason}` : \"\"}`));\n }\n return observer.error(new CombinedGraphQLErrors({\n errors: Array.isArray(err) ? err : [err],\n }));\n },\n // casting around a wrong type in graphql-ws, which incorrectly expects `Sink<ExecutionResult>`\n });\n });\n }\n}\n//# sourceMappingURL=index.js.map"],"x_google_ignoreList":[0],"mappings":";;;;;;AAmCA,SAAS,EAAiB,GAAK;AAC3B,QAAO,EAAgB,EAAI,IAAI,UAAU,KAAO,YAAY;;AAGhE,SAAS,EAAiB,GAAK;AAC3B,QAAO,EAAgB,EAAI,IAAI,EAAI,QAAQ,eAAe,UAAU;;AAyBxE,IAAa,IAAb,cAAmC,EAAW;CAC1C;CACA,YAAY,GAAQ;AAEhB,EADA,OAAO,EACP,KAAK,SAAS;;CAElB,QAAQ,GAAW;AACf,SAAO,IAAI,GAAY,MAAa;GAChC,IAAM,EAAE,UAAO,cAAW,kBAAe,kBAAe;AACxD,UAAO,KAAK,OAAO,UAAU;IAAE;IAAW;IAAe;IAAY,OAAO,EAAM,EAAM;IAAE,EAAE;IACxF,MAAM,EAAS,KAAK,KAAK,EAAS;IAClC,UAAU,EAAS,SAAS,KAAK,EAAS;IAC1C,QAAQ,MAAQ;AACZ,SAAI,aAAe,MACf,QAAO,EAAS,MAAM,EAAI;KAE9B,IAAM,IAAY,EAAiB,EAAI;AAMvC,YALI,KAAa,EAAiB,EAAI,GAC3B,EAAS,MAEhB,gBAAI,MAAM,gBAAgB,IAAY,eAAe,EAAI,SAAS,KAAK,IAAY,IAAI,EAAI,WAAW,KAAK,CAAC,GAEzG,EAAS,MAAM,IAAI,EAAsB,EAC5C,QAAQ,MAAM,QAAQ,EAAI,GAAG,IAAM,CAAC,EAAI,EAC3C,CAAC,CAAC;;IAGV,CAAC;IACJ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"createOperation.js","names":[],"sources":["../../../../../../../../../../../node_modules/.bun/@apollo+client@4.1.9+e571b0b00fd00a97/node_modules/@apollo/client/link/utils/createOperation.js"],"sourcesContent":["import { getOperationDefinition, getOperationName, } from \"@apollo/client/utilities/internal\";\nexport function createOperation(request, { client }) {\n const operation = {\n query: request.query,\n variables: request.variables || {},\n extensions: request.extensions || {},\n operationName: getOperationName(request.query),\n operationType: getOperationDefinition(request.query).operation,\n };\n let context = { ...request.context };\n const setContext = (next) => {\n if (typeof next === \"function\") {\n context = { ...context, ...next(getContext()) };\n }\n else {\n context = { ...context, ...next };\n }\n };\n const getContext = () => Object.freeze({ ...context });\n Object.defineProperty(operation, \"setContext\", {\n enumerable: false,\n value: setContext,\n });\n Object.defineProperty(operation, \"getContext\", {\n enumerable: false,\n value: getContext,\n });\n Object.defineProperty(operation, \"client\", {\n enumerable: false,\n value: client,\n });\n return operation;\n}\n//# sourceMappingURL=createOperation.js.map"],"x_google_ignoreList":[0],"mappings":";;;AACA,SAAgB,EAAgB,GAAS,EAAE,aAAU;CACjD,IAAM,IAAY;EACd,OAAO,EAAQ;EACf,WAAW,EAAQ,aAAa,EAAE;EAClC,YAAY,EAAQ,cAAc,EAAE;EACpC,eAAe,EAAiB,EAAQ,MAAM;EAC9C,eAAe,EAAuB,EAAQ,MAAM,CAAC;EACxD,EACG,IAAU,EAAE,GAAG,EAAQ,SAAS,EAC9B,KAAc,MAAS;AACzB,EAII,IAJA,OAAO,KAAS,aACN;GAAE,GAAG;GAAS,GAAG,EAAK,GAAY,CAAC;GAAE,GAGrC;GAAE,GAAG;GAAS,GAAG;GAAM;IAGnC,UAAmB,OAAO,OAAO,EAAE,GAAG,GAAS,CAAC;AAatD,QAZA,OAAO,eAAe,GAAW,cAAc;EAC3C,YAAY;EACZ,OAAO;EACV,CAAC,EACF,OAAO,eAAe,GAAW,cAAc;EAC3C,YAAY;EACZ,OAAO;EACV,CAAC,EACF,OAAO,eAAe,GAAW,UAAU;EACvC,YAAY;EACZ,OAAO;EACV,CAAC,EACK"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sizes.js","names":["global"],"sources":["../../../../../../../../../../../node_modules/.bun/@apollo+client@4.1.9+e571b0b00fd00a97/node_modules/@apollo/client/utilities/caching/sizes.js"],"sourcesContent":["import { global } from \"@apollo/client/utilities/internal/globals\";\nconst cacheSizeSymbol = Symbol.for(\"apollo.cacheSize\");\n/**\n * The global cache size configuration for Apollo Client.\n *\n * @remarks\n *\n * You can directly modify this object, but any modification will\n * only have an effect on caches that are created after the modification.\n *\n * So for global caches, such as `canonicalStringify` and `print`,\n * you might need to call `.reset` on them, which will essentially re-create them.\n *\n * Alternatively, you can set `globalThis[Symbol.for(\"apollo.cacheSize\")]` before\n * you load the Apollo Client package:\n *\n * @example\n *\n * ```ts\n * globalThis[Symbol.for(\"apollo.cacheSize\")] = {\n * print: 100,\n * } satisfies Partial<CacheSizes>; // the `satisfies` is optional if using TypeScript\n * ```\n */\nexport const cacheSizes = { ...global[cacheSizeSymbol] };\n//# sourceMappingURL=sizes.js.map"],"x_google_ignoreList":[0],"mappings":";AAwBA,IAAa,IAAa,EAAE,GAAGA,EAvBP,OAAO,IAAI,mBAAmB,GAuBE"}