@toototech/webbuilder-plugins 0.1.0

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 (193) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +3 -0
  3. package/dist/basic/cssScope.d.ts +3 -0
  4. package/dist/basic/index.d.ts +81 -0
  5. package/dist/basic/injectStyle.d.ts +20 -0
  6. package/dist/basic/plugin.d.ts +19 -0
  7. package/dist/basic/publisher.d.ts +4 -0
  8. package/dist/basic/registries/interactive/accordion/index.d.ts +3 -0
  9. package/dist/basic/registries/interactive/backButton/index.d.ts +3 -0
  10. package/dist/basic/registries/interactive/button/index.d.ts +10 -0
  11. package/dist/basic/registries/interactive/countUp/index.d.ts +9 -0
  12. package/dist/basic/registries/interactive/customCode/index.d.ts +3 -0
  13. package/dist/basic/registries/interactive/index.d.ts +2 -0
  14. package/dist/basic/registries/interactive/inquiryForm/index.d.ts +3 -0
  15. package/dist/basic/registries/interactive/klaviyoSubscribe/index.d.ts +3 -0
  16. package/dist/basic/registries/interactive/popup/index.d.ts +5 -0
  17. package/dist/basic/registries/interactive/salesmartlyChatButton/index.d.ts +10 -0
  18. package/dist/basic/registries/interactive/search/index.d.ts +10 -0
  19. package/dist/basic/registries/interactive/socialShare/index.d.ts +33 -0
  20. package/dist/basic/registries/interactive/tabs/index.d.ts +3 -0
  21. package/dist/basic/registries/layout/container/index.d.ts +19 -0
  22. package/dist/basic/registries/layout/divider/index.d.ts +7 -0
  23. package/dist/basic/registries/layout/grid/index.d.ts +11 -0
  24. package/dist/basic/registries/layout/index.d.ts +2 -0
  25. package/dist/basic/registries/layout/layoutBase/index.d.ts +10 -0
  26. package/dist/basic/registries/layout/section/index.d.ts +3 -0
  27. package/dist/basic/registries/layout/sectionGridBlock/index.d.ts +3 -0
  28. package/dist/basic/registries/layout/spacer/index.d.ts +7 -0
  29. package/dist/basic/registries/media/banner/index.d.ts +11 -0
  30. package/dist/basic/registries/media/carousel/index.d.ts +6 -0
  31. package/dist/basic/registries/media/flipbook/index.d.ts +5 -0
  32. package/dist/basic/registries/media/icon/index.d.ts +3 -0
  33. package/dist/basic/registries/media/image/index.d.ts +3 -0
  34. package/dist/basic/registries/media/index.d.ts +2 -0
  35. package/dist/basic/registries/media/industryTabs/index.d.ts +3 -0
  36. package/dist/basic/registries/media/marquee/index.d.ts +4 -0
  37. package/dist/basic/registries/media/ourSolutions/helpers.d.ts +289 -0
  38. package/dist/basic/registries/media/ourSolutions/index.d.ts +4 -0
  39. package/dist/basic/registries/media/ourSolutions/script.d.ts +1 -0
  40. package/dist/basic/registries/media/ourSolutions/style.d.ts +1 -0
  41. package/dist/basic/registries/media/pdfViewer/index.d.ts +3 -0
  42. package/dist/basic/registries/media/productCategories/index.d.ts +4 -0
  43. package/dist/basic/registries/media/tabMediaGallery/index.d.ts +3 -0
  44. package/dist/basic/registries/media/video/index.d.ts +12 -0
  45. package/dist/basic/registries/navigation/footer/index.d.ts +10 -0
  46. package/dist/basic/registries/navigation/index.d.ts +2 -0
  47. package/dist/basic/registries/navigation/languageSwitcher/index.d.ts +6 -0
  48. package/dist/basic/registries/navigation/logo/index.d.ts +9 -0
  49. package/dist/basic/registries/navigation/navbar/constants.d.ts +38 -0
  50. package/dist/basic/registries/navigation/navbar/factories.d.ts +848 -0
  51. package/dist/basic/registries/navigation/navbar/helpers.d.ts +12 -0
  52. package/dist/basic/registries/navigation/navbar/index.d.ts +4 -0
  53. package/dist/basic/registries/navigation/navbar/registerMegaTypes.d.ts +2 -0
  54. package/dist/basic/registries/navigation/navbar/registerMenuTypes.d.ts +2 -0
  55. package/dist/basic/registries/navigation/navbar/registerRootTypes.d.ts +2 -0
  56. package/dist/basic/registries/navigation/navbar/script.d.ts +1 -0
  57. package/dist/basic/registries/navigation/navbar/style.d.ts +1 -0
  58. package/dist/basic/registries/navigation/socialLinks/index.d.ts +3 -0
  59. package/dist/basic/registries/section/allApplications/index.d.ts +3 -0
  60. package/dist/basic/registries/section/cardCarouselSection/index.d.ts +3 -0
  61. package/dist/basic/registries/section/caseSpotlight/index.d.ts +3 -0
  62. package/dist/basic/registries/section/companyScale/index.d.ts +3 -0
  63. package/dist/basic/registries/section/customizationGrid/index.d.ts +3 -0
  64. package/dist/basic/registries/section/factoryMap/index.d.ts +3 -0
  65. package/dist/basic/registries/section/focaHistoryTimeline/index.d.ts +3 -0
  66. package/dist/basic/registries/section/historyTimeline/index.d.ts +3 -0
  67. package/dist/basic/registries/section/homeBannerCarousel/index.d.ts +4 -0
  68. package/dist/basic/registries/section/hotspotShowcase/index.d.ts +30 -0
  69. package/dist/basic/registries/section/index.d.ts +2 -0
  70. package/dist/basic/registries/section/map/index.d.ts +4 -0
  71. package/dist/basic/registries/section/milestoneCardStrip/index.d.ts +3 -0
  72. package/dist/basic/registries/section/moreCardCarousel/index.d.ts +3 -0
  73. package/dist/basic/registries/section/ourAdvantages/index.d.ts +4 -0
  74. package/dist/basic/registries/section/overviewSplit/index.d.ts +3 -0
  75. package/dist/basic/registries/section/processTimeline/index.d.ts +3 -0
  76. package/dist/basic/registries/section/productCardStrip/index.d.ts +3 -0
  77. package/dist/basic/registries/section/resourceSection/index.d.ts +6 -0
  78. package/dist/basic/registries/section/responsiveHeroCarousel/index.d.ts +4 -0
  79. package/dist/basic/registries/section/serviceIconGrid/index.d.ts +4 -0
  80. package/dist/basic/registries/section/servicesCarousel/index.d.ts +4 -0
  81. package/dist/basic/registries/section/servicesShowcase/index.d.ts +4 -0
  82. package/dist/basic/registries/section/servicesThb/index.d.ts +4 -0
  83. package/dist/basic/registries/section/solutionList/index.d.ts +4 -0
  84. package/dist/basic/registries/section/staticPinMap/index.d.ts +4 -0
  85. package/dist/basic/registries/section/statsCards/index.d.ts +3 -0
  86. package/dist/basic/registries/section/swiperRuntime.d.ts +3 -0
  87. package/dist/basic/registries/shared/sharedTraits.d.ts +37 -0
  88. package/dist/basic/registries/types.d.ts +5 -0
  89. package/dist/basic/registries/typography/heading/index.d.ts +8 -0
  90. package/dist/basic/registries/typography/index.d.ts +2 -0
  91. package/dist/basic/registries/typography/textEditor/index.d.ts +6 -0
  92. package/dist/basic/registryManifest.d.ts +9 -0
  93. package/dist/basic/styleHelpers.d.ts +29 -0
  94. package/dist/basic/svgIcon.d.ts +11 -0
  95. package/dist/basic/traitBridge.d.ts +20 -0
  96. package/dist/basic/traitFactory.d.ts +106 -0
  97. package/dist/basic.js +1146 -0
  98. package/dist/cms/cmsFactory.d.ts +164 -0
  99. package/dist/cms/dynamicRenderPipeline.d.ts +12 -0
  100. package/dist/cms/index.d.ts +31 -0
  101. package/dist/cms/plugin.d.ts +12 -0
  102. package/dist/cms/publisher.d.ts +7 -0
  103. package/dist/cms/registries/dynamic/cms/constants.d.ts +16 -0
  104. package/dist/cms/registries/dynamic/cms/dynamicField/bindings.d.ts +78 -0
  105. package/dist/cms/registries/dynamic/cms/dynamicField/blocks/breadcrumbBlock.d.ts +1 -0
  106. package/dist/cms/registries/dynamic/cms/dynamicField/blocks/conditionalBlock.d.ts +1 -0
  107. package/dist/cms/registries/dynamic/cms/dynamicField/blocks/datetimeBlock.d.ts +1 -0
  108. package/dist/cms/registries/dynamic/cms/dynamicField/blocks/htmlBlock.d.ts +1 -0
  109. package/dist/cms/registries/dynamic/cms/dynamicField/blocks/imageBlock.d.ts +1 -0
  110. package/dist/cms/registries/dynamic/cms/dynamicField/blocks/linkBlock.d.ts +1 -0
  111. package/dist/cms/registries/dynamic/cms/dynamicField/blocks/seoBlock.d.ts +1 -0
  112. package/dist/cms/registries/dynamic/cms/dynamicField/blocks/textBlock.d.ts +1 -0
  113. package/dist/cms/registries/dynamic/cms/dynamicField/blocks/tocBlock.d.ts +1 -0
  114. package/dist/cms/registries/dynamic/cms/dynamicField/constants.d.ts +19 -0
  115. package/dist/cms/registries/dynamic/cms/dynamicField/helpers.d.ts +52 -0
  116. package/dist/cms/registries/dynamic/cms/dynamicField/registerBlock.d.ts +57 -0
  117. package/dist/cms/registries/dynamic/cms/dynamicField/styles.d.ts +7 -0
  118. package/dist/cms/registries/dynamic/cms/media/previewMediaTrait.d.ts +7 -0
  119. package/dist/cms/registries/dynamic/cms/menu/siteMenuAttrs.d.ts +11 -0
  120. package/dist/cms/registries/dynamic/cms/menuTree/menuTreeAttrs.d.ts +8 -0
  121. package/dist/cms/registries/dynamic/cms/post/styles.d.ts +6 -0
  122. package/dist/cms/registries/dynamic/cms/product/detail.styles.d.ts +1 -0
  123. package/dist/cms/registries/dynamic/cms/product/detailV2.styles.d.ts +1 -0
  124. package/dist/cms/registries/dynamic/cms/product/previewProductTrait.d.ts +6 -0
  125. package/dist/cms/registries/dynamic/cms/product/styles.d.ts +6 -0
  126. package/dist/cms/registries/dynamic/dataProvider.d.ts +45 -0
  127. package/dist/cms/registries/dynamic/loopGrid/paginationStyles.d.ts +5 -0
  128. package/dist/cms/registries/dynamic/loopGrid/preview.d.ts +16 -0
  129. package/dist/cms/registries/dynamic/loopGrid/publisher.d.ts +3 -0
  130. package/dist/cms/registries/dynamic/loopGrid/types.d.ts +97 -0
  131. package/dist/cms/registries/navigation/navbarThb/index.d.ts +3 -0
  132. package/dist/cms/registries/navigation/navbarThb/script.d.ts +1 -0
  133. package/dist/cms/registries/navigation/navbarThb/style.d.ts +1 -0
  134. package/dist/cms.js +4535 -0
  135. package/dist/global-settings/components/FontFamilySelect.vue.d.ts +29 -0
  136. package/dist/global-settings/components/FontManagerPanel.vue.d.ts +37 -0
  137. package/dist/global-settings/index.d.ts +8 -0
  138. package/dist/global-settings/plugin.d.ts +3 -0
  139. package/dist/global-settings/publisher.d.ts +15 -0
  140. package/dist/global-settings/runtime/canvasInjection.d.ts +13 -0
  141. package/dist/global-settings/runtime/panelDraftSave.d.ts +17 -0
  142. package/dist/global-settings/runtime/settingsSource.d.ts +4 -0
  143. package/dist/global-settings/useFontManager.d.ts +38 -0
  144. package/dist/global-settings/useGoogleFonts.d.ts +20 -0
  145. package/dist/global-settings/vue.d.ts +1 -0
  146. package/dist/global-settings.js +66 -0
  147. package/dist/i18n/I18nPanel.vue.d.ts +23 -0
  148. package/dist/i18n/i18n.d.ts +25 -0
  149. package/dist/i18n/index.d.ts +7 -0
  150. package/dist/i18n/languageOrder.d.ts +9 -0
  151. package/dist/i18n/plugin.d.ts +21 -0
  152. package/dist/i18n/types.d.ts +101 -0
  153. package/dist/i18n/useWebBuilderI18n.d.ts +164 -0
  154. package/dist/i18n/vue.d.ts +1 -0
  155. package/dist/i18n-BYR3l48y.js +959 -0
  156. package/dist/i18n.js +929 -0
  157. package/dist/index-CxJlLwvG.js +35378 -0
  158. package/dist/index-DWfJ4PBm.js +5724 -0
  159. package/dist/index.d.ts +9 -0
  160. package/dist/index.js +12 -0
  161. package/dist/layout-template/components/LayoutPanel.vue.d.ts +37 -0
  162. package/dist/layout-template/components/TemplateRulesPanel.vue.d.ts +41 -0
  163. package/dist/layout-template/config/layoutSharedResources.d.ts +9 -0
  164. package/dist/layout-template/config/templateSharedResources.d.ts +28 -0
  165. package/dist/layout-template/index.d.ts +9 -0
  166. package/dist/layout-template/plugin.d.ts +13 -0
  167. package/dist/layout-template/runtime/storageAdapter.d.ts +49 -0
  168. package/dist/layout-template/utils/layoutProjectData.d.ts +15 -0
  169. package/dist/layout-template/utils/layoutRulePages.d.ts +19 -0
  170. package/dist/layout-template/utils/layoutSettings.d.ts +45 -0
  171. package/dist/layout-template/utils/templateRules.d.ts +52 -0
  172. package/dist/layout-template/vue.d.ts +2 -0
  173. package/dist/layout-template.js +435 -0
  174. package/dist/layoutSettings-D4SYUMri.js +252 -0
  175. package/dist/plugin-BPA8qlaC.js +40 -0
  176. package/dist/plugin-C0PrxrIe.js +228 -0
  177. package/dist/plugin-DQshk1sY.js +361 -0
  178. package/dist/plugin-DebyCjXx.js +191 -0
  179. package/dist/plugin-Dr6TOtyH.js +73 -0
  180. package/dist/publisher/index.d.ts +5 -0
  181. package/dist/publisher/publisherAssets.d.ts +9 -0
  182. package/dist/publisher/publisherComponents.d.ts +7 -0
  183. package/dist/publisher/publisherPlugins.d.ts +12 -0
  184. package/dist/publisher-C6VWXq8u.js +25 -0
  185. package/dist/publisher.js +1711 -0
  186. package/dist/solar-BsElUqfQ.js +29843 -0
  187. package/dist/style.css +1181 -0
  188. package/dist/templateSharedResources-D1u7eFIs.js +89 -0
  189. package/dist/types-DNbok59z.js +2359 -0
  190. package/dist/useFontManager-CdrLq1eG.js +336 -0
  191. package/dist/vue.d.ts +3 -0
  192. package/dist/vue.js +2171 -0
  193. package/package.json +77 -0
package/dist/cms.js ADDED
@@ -0,0 +1,4535 @@
1
+ import { C, a, b, d, c, c as c2 } from "./plugin-C0PrxrIe.js";
2
+ import { b as LOOP_GRID_NEXT_ICON, a as LOOP_GRID_PREV_ICON, D as DEFAULT_LOOP_GRID_SCHEMA, L as LOOP_GRID_PAGINATION_STYLE } from "./types-DNbok59z.js";
3
+ import { C as C2, o, f, q, s, t, u, v, c as c3, w, R, x, y, z, A, B, E, F, G, H, I, J, K, M, N, O, P, W, Q, S, T, U, V, X, Y, Z, _, $, a0, a1, a2, a3, a4, a5, a6, a7, a8, e, a9, aa, ab, ac, ad, ae, af, ag, ah, d as d2, p, ai, l, k, j, aj, g, h, i, n, r, m, ak, al, am, an } from "./types-DNbok59z.js";
4
+ const POST_CARD_CSS = `
5
+ .wb-post-card { position: relative; overflow: hidden; }
6
+ .wb-post-card-img-wrap { overflow: hidden; aspect-ratio: 4 / 3; }
7
+ .wb-post-card-img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.2s ease; }
8
+ .wb-post-card:hover .wb-post-card-img { transform: scale(1.1); }
9
+ .wb-post-card-body { transition: all 0.3s; padding-top: 16px; padding-bottom: 16px; }
10
+ .wb-post-card-date { font-size: 14px; margin-bottom: 12px; display: block; color: #264FAA; }
11
+ .wb-post-card-title { font-size: 20px; color: #041038; font-weight: 500; line-height: 1.18; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-bottom: 8px; }
12
+ .wb-post-card-excerpt { color: #193143; line-height: 1.6; height: 3.2em; font-weight: 300; margin-bottom: 16px; font-size: 14px; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }
13
+ .wb-post-card-link { color: #041038; cursor: pointer; line-height: 1.5; text-decoration: none; font-size: 14px; }
14
+ .wb-post-card:hover .wb-post-card-date,
15
+ .wb-post-card:hover .wb-post-card-title,
16
+ .wb-post-card:hover .wb-post-card-excerpt,
17
+ .wb-post-card:hover .wb-post-card-link { color: #1B43ED; }
18
+ .wb-post-card-link::after { content:''; position:absolute; inset:0; }
19
+ @media (max-width: 1023px) {
20
+ .wb-post-card-body { padding-top: 14px; padding-bottom: 14px; }
21
+ .wb-post-card-title { font-size: 18px; }
22
+ }
23
+ @media (max-width: 767px) {
24
+ .wb-post-card-body { padding-top: 12px; padding-bottom: 12px; }
25
+ .wb-post-card-date { font-size: 13px; margin-bottom: 10px; }
26
+ .wb-post-card-title {
27
+ font-size: 16px;
28
+ white-space: normal;
29
+ display: -webkit-box;
30
+ -webkit-box-orient: vertical;
31
+ -webkit-line-clamp: 2;
32
+ }
33
+ .wb-post-card-excerpt { font-size: 13px; margin-bottom: 12px; }
34
+ }
35
+ `;
36
+ const PRODUCT_CARD_CSS = `
37
+ .wb-product-list { position: relative; display: grid; grid-template-columns: 220px minmax(0, 1fr); column-gap: 20px; row-gap: 72px; align-items: start; }
38
+ .wb-product-list__grid { grid-column: 2; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 20px; row-gap: 72px; align-items: start; min-width: 0; }
39
+ .wb-product-datasheet { grid-column: 2; display: none; min-width: 0; overflow-x: auto; }
40
+ .wb-product-datasheet-page-title { display: none; }
41
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-list__grid,
42
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-list__grid { display: none; }
43
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet,
44
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet { display: block; }
45
+
46
+ .wb-product-list[data-list-mode="datasheet"],
47
+ .wb-product-list[data-wb-list-mode="datasheet"] {
48
+ display: block;
49
+ width: min(100%, 1540px);
50
+ margin: 0 auto;
51
+ padding: 0;
52
+ color: #101014;
53
+ font-family: inherit;
54
+ }
55
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-page-title,
56
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-page-title {
57
+ display: block;
58
+ margin: 0 0 24px;
59
+ color: #101014;
60
+ font-size: 56px;
61
+ line-height: 1.05;
62
+ font-weight: 800;
63
+ letter-spacing: 0;
64
+ }
65
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-list__toolbar,
66
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-list__toolbar,
67
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter-backdrop,
68
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter-backdrop,
69
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-list-pagination,
70
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-list-pagination,
71
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-list-loadmore,
72
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-list-loadmore {
73
+ display: none;
74
+ }
75
+
76
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter-drawer,
77
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter-drawer {
78
+ position: relative;
79
+ top: auto;
80
+ width: 100%;
81
+ max-height: none;
82
+ margin: 0 0 96px;
83
+ padding: 30px 30px 34px;
84
+ border-radius: 8px;
85
+ background: #f7f7f8;
86
+ box-shadow: none;
87
+ transform: none;
88
+ z-index: 20;
89
+ display: block;
90
+ }
91
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter__header,
92
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter__header {
93
+ display: flex;
94
+ align-items: center;
95
+ justify-content: space-between;
96
+ gap: 16px;
97
+ margin: 0 0 20px;
98
+ }
99
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter__title,
100
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter__title {
101
+ margin: 0;
102
+ color: #101014;
103
+ font-size: 22px;
104
+ line-height: 1.2;
105
+ font-weight: 700;
106
+ }
107
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter__close,
108
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter__close,
109
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter__footer,
110
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter__footer {
111
+ display: none;
112
+ }
113
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter__body,
114
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter__body {
115
+ position: relative;
116
+ overflow: visible;
117
+ }
118
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter__all-products,
119
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter__all-products {
120
+ position: absolute;
121
+ top: -48px;
122
+ right: 0;
123
+ width: auto;
124
+ min-height: 28px;
125
+ padding: 0;
126
+ border: none;
127
+ background: transparent;
128
+ color: #2454f4;
129
+ font-size: 0;
130
+ line-height: 1;
131
+ font-weight: 700;
132
+ cursor: pointer;
133
+ }
134
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter__all-products::before,
135
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter__all-products::before {
136
+ display: none;
137
+ }
138
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter__all-products::after,
139
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter__all-products::after {
140
+ content: "Reset All";
141
+ font-size: 16px;
142
+ }
143
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter__groups,
144
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter__groups {
145
+ display: grid;
146
+ grid-template-columns: repeat(4, minmax(220px, 1fr));
147
+ gap: 20px 16px;
148
+ align-items: start;
149
+ }
150
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter__group,
151
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter__group {
152
+ position: relative;
153
+ padding: 0;
154
+ border: none;
155
+ }
156
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__control,
157
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__control {
158
+ position: relative;
159
+ min-width: 0;
160
+ }
161
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__toggle,
162
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__toggle {
163
+ width: 100%;
164
+ min-height: 62px;
165
+ display: flex;
166
+ align-items: center;
167
+ justify-content: space-between;
168
+ gap: 16px;
169
+ padding: 0 22px;
170
+ border: 1px solid #e3e5ea;
171
+ border-radius: 8px;
172
+ background: #fff;
173
+ color: #111318;
174
+ font-size: 17px;
175
+ line-height: 1.2;
176
+ font-weight: 700;
177
+ letter-spacing: 0;
178
+ text-align: left;
179
+ cursor: pointer;
180
+ box-shadow: 0 1px 1px rgba(16, 24, 40, 0.02);
181
+ }
182
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__control.is-open .wb-product-datasheet-filter__toggle,
183
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__control.is-open .wb-product-datasheet-filter__toggle,
184
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__toggle:focus-visible,
185
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__toggle:focus-visible {
186
+ border-color: #2454f4;
187
+ outline: none;
188
+ box-shadow: 0 0 0 2px rgba(36, 84, 244, 0.18);
189
+ }
190
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__control.is-open .wb-product-datasheet-filter__toggle,
191
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__control.is-open .wb-product-datasheet-filter__toggle {
192
+ border-radius: 8px 8px 0 0;
193
+ background: #2454f4;
194
+ border-color: #2454f4;
195
+ color: #fff;
196
+ }
197
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__summary-value,
198
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__summary-value {
199
+ color: #2454f4;
200
+ }
201
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__control.is-open .wb-product-datasheet-filter__summary-value,
202
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__control.is-open .wb-product-datasheet-filter__summary-value {
203
+ color: #fff;
204
+ }
205
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__chevron,
206
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__chevron {
207
+ width: 12px;
208
+ height: 12px;
209
+ border-right: 1.8px solid currentColor;
210
+ border-bottom: 1.8px solid currentColor;
211
+ transform: rotate(45deg);
212
+ flex: 0 0 auto;
213
+ margin-top: -4px;
214
+ }
215
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__control.is-open .wb-product-datasheet-filter__chevron,
216
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__control.is-open .wb-product-datasheet-filter__chevron {
217
+ transform: rotate(225deg);
218
+ margin-top: 4px;
219
+ }
220
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__panel,
221
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__panel {
222
+ display: none;
223
+ position: absolute;
224
+ left: 0;
225
+ top: 100%;
226
+ width: 100%;
227
+ min-width: 300px;
228
+ padding: 22px;
229
+ border: 1px solid #e2e5ea;
230
+ border-top: 0;
231
+ border-radius: 0 0 8px 8px;
232
+ background: #fff;
233
+ box-shadow: 0 14px 28px rgba(15, 23, 42, 0.12);
234
+ z-index: 50;
235
+ }
236
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__control.is-open .wb-product-datasheet-filter__panel,
237
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__control.is-open .wb-product-datasheet-filter__panel {
238
+ display: block;
239
+ }
240
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__range-fields,
241
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__range-fields {
242
+ display: grid;
243
+ grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
244
+ gap: 12px;
245
+ align-items: center;
246
+ }
247
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__range-input,
248
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__range-input {
249
+ position: relative;
250
+ }
251
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__range-input input,
252
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__range-input input {
253
+ width: 100%;
254
+ height: 40px;
255
+ padding: 0 44px 0 12px;
256
+ border: 1px solid #dfe3ea;
257
+ border-radius: 5px;
258
+ background: #fff;
259
+ color: #111318;
260
+ font-size: 16px;
261
+ line-height: 1;
262
+ }
263
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__unit,
264
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__unit {
265
+ position: absolute;
266
+ right: 12px;
267
+ top: 50%;
268
+ transform: translateY(-50%);
269
+ color: #9aa0aa;
270
+ font-size: 16px;
271
+ pointer-events: none;
272
+ }
273
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__dash,
274
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__dash {
275
+ color: #101014;
276
+ font-size: 16px;
277
+ }
278
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__actions,
279
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__actions {
280
+ display: grid;
281
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
282
+ gap: 16px;
283
+ margin-top: 26px;
284
+ padding-top: 20px;
285
+ border-top: 1px solid #edf0f4;
286
+ }
287
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__action,
288
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__action {
289
+ min-height: 46px;
290
+ border: 1px solid #dfe3ea;
291
+ border-radius: 5px;
292
+ background: #fff;
293
+ color: #101014;
294
+ font-size: 16px;
295
+ font-weight: 700;
296
+ cursor: pointer;
297
+ }
298
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__action--primary,
299
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__action--primary {
300
+ border-color: #2454f4;
301
+ background: #2454f4;
302
+ color: #fff;
303
+ }
304
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__options,
305
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__options {
306
+ display: grid;
307
+ gap: 10px;
308
+ max-height: 260px;
309
+ overflow-y: auto;
310
+ }
311
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__option,
312
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__option {
313
+ display: flex;
314
+ align-items: center;
315
+ gap: 9px;
316
+ color: #111318;
317
+ font-size: 15px;
318
+ line-height: 1.35;
319
+ cursor: pointer;
320
+ }
321
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-filter__option input,
322
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-filter__option input {
323
+ width: 16px;
324
+ height: 16px;
325
+ margin: 0;
326
+ accent-color: #2454f4;
327
+ }
328
+
329
+ .wb-product-datasheet__summary { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin: 0 0 26px; }
330
+ .wb-product-datasheet__title { margin: 0; font-size: 30px; line-height: 1.2; font-weight: 750; color: #101014; }
331
+ .wb-product-datasheet__meta { display: flex; align-items: center; gap: 18px; margin-top: 8px; color: #101014; font-size: 18px; line-height: 1.45; font-weight: 600; }
332
+ .wb-product-datasheet__selected { color: #2454f4; font-weight: 600; }
333
+ .wb-product-datasheet__export { min-width: 154px; min-height: 44px; border: 1px solid #d1d5db; background: #fff; color: #101014; font-size: 16px; font-weight: 700; cursor: pointer; }
334
+ .wb-product-datasheet__export:disabled { cursor: not-allowed; opacity: 0.45; }
335
+ .wb-product-datasheet__table { min-width: 940px; overflow-x: auto; }
336
+ .wb-product-datasheet__header,
337
+ .wb-product-datasheet__row { display: grid; grid-template-columns: 72px minmax(230px, 1.45fr) repeat(var(--wb-datasheet-field-count, 5), minmax(160px, 1fr)); align-items: stretch; }
338
+ .wb-product-datasheet__header { background: #3152ed; color: #fff; font-weight: 800; }
339
+ .wb-product-datasheet__body { max-height: 640px; overflow-y: auto; scrollbar-color: #2b2f38 #e8e8ea; scrollbar-width: thin; }
340
+ .wb-product-datasheet__body::-webkit-scrollbar { width: 6px; }
341
+ .wb-product-datasheet__body::-webkit-scrollbar-track { background: #e8e8ea; }
342
+ .wb-product-datasheet__body::-webkit-scrollbar-thumb { background: #2b2f38; border-radius: 999px; }
343
+ .wb-product-datasheet__row { background: #fff; }
344
+ .wb-product-datasheet__row:nth-child(even) { background: #f6f6f7; }
345
+ .wb-product-datasheet__row.is-selected,
346
+ .wb-product-datasheet__row:has(input:checked) { background: #f2f5ff; }
347
+ .wb-product-datasheet__cell { display: flex; align-items: center; min-height: 62px; padding: 12px 22px; color: #3f3f46; font-size: 18px; line-height: 1.35; white-space: nowrap; }
348
+ .wb-product-datasheet__header .wb-product-datasheet__cell { color: #fff; font-weight: 700; }
349
+ .wb-product-datasheet__checkbox { justify-content: center; padding-inline: 10px; }
350
+ .wb-product-datasheet__checkbox input { width: 18px; height: 18px; margin: 0; accent-color: #2454f4; }
351
+ .wb-product-datasheet__designation-link { color: #2454f4; font-weight: 800; text-decoration: underline; }
352
+ .wb-product-list__toolbar { display: none; }
353
+ .wb-product-list__count { font-size: 15px; line-height: 1.6; color: #121821; }
354
+ .wb-product-list__filter-btn { border: none; background: transparent; padding: 0; display: inline-flex; align-items: center; gap: 10px; color: #121821; font-size: 18px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; }
355
+ .wb-product-list__filter-icon { position: relative; width: 16px; height: 14px; display: inline-block; }
356
+ .wb-product-list__filter-badge { display: none; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; background: currentColor; color: #fff; font-size: 11px; line-height: 1; }
357
+ .wb-product-list__filter-btn.is-active .wb-product-list__filter-badge { background: #fff; color: #121821; }
358
+ .wb-product-filter-backdrop { display: none; position: fixed; inset: 0; background: rgba(17, 24, 39, 0.38); opacity: 0; visibility: hidden; pointer-events: none; transition: opacity 0.25s ease; z-index: 998; }
359
+ .wb-product-filter-backdrop.is-open { opacity: 1; visibility: visible; pointer-events: auto; }
360
+ .wb-product-filter-drawer { grid-column: 1; grid-row: 1; position: sticky; top: 24px; width: 100%; max-height: calc(100vh - 48px); padding: 0 16px 0 0; background: transparent; transform: none; z-index: 1; display: flex; flex-direction: column; }
361
+ .wb-product-filter-drawer.is-open { transform: none; }
362
+ .wb-product-filter__header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 28px; }
363
+ .wb-product-filter__title { margin: 0; font-size: 28px; line-height: 1.15; font-weight: 600; color: #121821; }
364
+ .wb-product-filter__close { display: none; align-items: center; justify-content: center; width: 40px; height: 40px; border: 1px solid #d1d5db; border-radius: 999px; background: #fff; color: #111827; font-size: 24px; line-height: 1; cursor: pointer; }
365
+ .wb-product-filter__body { flex: 1; min-height: 0; overflow-y: auto; }
366
+ .wb-product-filter__all-products { width: 100%; display: flex; align-items: center; gap: 10px; padding: 0 0 18px; border: none; border-bottom: 1px solid #e5e7eb; background: transparent; color: #121821; font-size: 14px; line-height: 1.5; text-align: left; cursor: pointer; }
367
+ .wb-product-filter__all-products::before { content: ""; width: 10px; height: 10px; border: 1px solid #8a949e; box-sizing: border-box; }
368
+ .wb-product-filter__groups { display: flex; flex-direction: column; gap: 0; }
369
+ .wb-product-filter__group { padding: 24px 0; border-bottom: 1px solid #e5e7eb; }
370
+ .wb-product-filter__group:last-child { border-bottom: none; padding-bottom: 0; }
371
+ .wb-product-filter__group-header { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 0; border: none; background: transparent; color: #111827; cursor: pointer; }
372
+ .wb-product-filter__group-title { font-size: 14px; line-height: 1.5; font-weight: 600; text-align: left; }
373
+ .wb-product-filter__group-toggle { font-size: 18px; line-height: 1; font-weight: 400; }
374
+ .wb-product-filter__group-options { display: grid; gap: 10px; padding-top: 16px; }
375
+ .wb-product-filter__group.is-collapsed .wb-product-filter__group-options { display: none; }
376
+ .wb-product-filter__option { display: flex; align-items: center; gap: 8px; font-size: 13px; line-height: 1.45; color: #111827; cursor: pointer; }
377
+ .wb-product-filter__option input { width: 12px; height: 12px; margin: 0; cursor: pointer; accent-color: #ffe600; }
378
+ .wb-product-filter__range { display: flex; flex-direction: column; gap: 8px; padding: 2px 0 6px; }
379
+ .wb-product-filter__range-title { font-size: 13px; line-height: 1.45; font-weight: 500; color: #111827; }
380
+ .wb-product-filter__range-fields { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 8px; }
381
+ .wb-product-filter__range-fields input { width: 100%; min-width: 0; height: 34px; padding: 0 9px; border: 1px solid #d8dde6; border-radius: 4px; background: #fff; color: #111827; font-size: 13px; }
382
+ .wb-product-filter__empty { margin: 0; font-size: 14px; line-height: 1.7; color: #6b7280; }
383
+ .wb-product-filter__footer { display: none; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; padding-top: 28px; }
384
+ .wb-product-filter__footer-btn { min-height: 56px; border-radius: 0; border: 1px solid #111827; background: #fff; color: #111827; font-size: 16px; font-weight: 600; letter-spacing: 0.04em; cursor: pointer; text-transform: uppercase; }
385
+ .wb-product-filter__footer-btn--primary { background: #111827; color: #fff; }
386
+ .wb-product-card { position: relative; overflow: hidden; border-radius: 0; background: #fff; min-width: 0; }
387
+ .wb-product-card-img-wrap { overflow: hidden; aspect-ratio: 296 / 360; }
388
+ .wb-product-card-img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 8px; transition: transform 0.3s ease; }
389
+ .wb-product-card:hover .wb-product-card-img { transform: scale(1.05); }
390
+ .wb-product-card-body { padding: 16px 0 0; }
391
+ .wb-product-card-name { font-weight: 500; font-size: 16px; color: #1a1a2e; line-height: 1.35; margin: 0 0 8px; overflow: hidden; text-overflow: ellipsis; white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
392
+ .wb-product-card-link { display: inline; color: inherit; font: inherit; line-height: inherit; text-decoration: none; }
393
+ .wb-product-card-link::after { content: ""; position: absolute; inset: 0; z-index: 1; cursor: pointer; }
394
+ .wb-product-list-pagination { grid-column: 2; display: flex; justify-content: center; gap: 8px; padding: 16px 0; }
395
+ .wb-product-list-page-btn,
396
+ .wb-product-list-pagination > a,
397
+ .wb-product-list-pagination > button,
398
+ .wb-product-list-pagination > span { display: inline-flex; align-items: center; justify-content: center; min-width: 36px; height: 36px; padding: 0 10px; border: 1px solid #ddd; border-radius: 6px; background: #fff; font-size: 14px; color: #333; cursor: pointer; user-select: none; transition: all 0.2s; text-decoration: none; }
399
+ .wb-product-list-page-btn:hover,
400
+ .wb-product-list-pagination > a:hover,
401
+ .wb-product-list-pagination > button:hover { border-color: #264FAA; color: #264FAA; }
402
+ .wb-product-list-page-btn.active,
403
+ .wb-product-list-pagination > a.active,
404
+ .wb-product-list-pagination > button.active,
405
+ .wb-product-list-pagination > span.active { background: #264FAA; border-color: #264FAA; color: #fff; }
406
+ .wb-product-list-loadmore { grid-column: 2; display: flex; justify-content: center; padding: 12px 0 0; }
407
+ .wb-product-list-loadmore__btn { min-width: 168px; min-height: 44px; padding: 0 20px; border: 1px solid #111827; background: #fff; color: #111827; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.2s ease; }
408
+ .wb-product-list-loadmore__btn:hover { background: #111827; color: #fff; }
409
+ @media (max-width: 1023px) {
410
+ .wb-product-list { grid-template-columns: minmax(0, 1fr); column-gap: 8px; row-gap: 28px; }
411
+ .wb-product-list__grid { grid-column: 1 / -1; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 8px; row-gap: 28px; }
412
+ .wb-product-datasheet { grid-column: 1 / -1; }
413
+ .wb-product-datasheet__summary { align-items: flex-start; flex-direction: column; }
414
+ .wb-product-datasheet__title { font-size: 24px; }
415
+ .wb-product-datasheet__table { min-width: 760px; }
416
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-page-title,
417
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-page-title { font-size: 42px; }
418
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter__groups,
419
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter__groups { grid-template-columns: repeat(2, minmax(0, 1fr)); }
420
+ .wb-product-list__toolbar { grid-column: 1 / -1; display: flex; flex-wrap: nowrap; align-items: center; justify-content: flex-start; gap: 12px; padding-bottom: 4px; border-bottom: none; }
421
+ .wb-product-list__count { display: none; }
422
+ .wb-product-filter-backdrop { display: block; }
423
+ .wb-product-filter-drawer { position: fixed; top: 0; right: 0; bottom: 0; grid-column: auto; grid-row: auto; width: min(440px, 100vw); max-height: none; padding: 28px 22px 24px; background: #fff; transform: translateX(100%); transition: transform 0.28s ease; z-index: 999; }
424
+ .wb-product-filter-drawer.is-open { transform: translateX(0); }
425
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter-drawer,
426
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter-drawer { position: relative; inset: auto; width: 100%; max-height: none; margin: 0 0 72px; padding: 26px 22px 30px; background: #f7f7f8; transform: none; transition: none; z-index: 20; }
427
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter-drawer.is-open,
428
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter-drawer.is-open { transform: none; }
429
+ .wb-product-filter__header { margin-bottom: 20px; }
430
+ .wb-product-filter__title { font-size: 30px; }
431
+ .wb-product-filter__close { display: inline-flex; }
432
+ .wb-product-filter__body { padding-top: 16px; border-top: 1px solid #e5e7eb; }
433
+ .wb-product-filter__all-products { padding-bottom: 16px; }
434
+ .wb-product-filter__group { padding: 22px 0; }
435
+ .wb-product-filter__footer { display: grid; }
436
+ .wb-product-list-pagination,
437
+ .wb-product-list-loadmore { grid-column: 1 / -1; }
438
+ }
439
+ @media (max-width: 767px) {
440
+ .wb-product-list { grid-template-columns: minmax(0, 1fr); column-gap: 8px; row-gap: 28px; }
441
+ .wb-product-list__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 8px; row-gap: 28px; }
442
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter__groups,
443
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter__groups { grid-template-columns: minmax(0, 1fr); }
444
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-datasheet-page-title,
445
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-datasheet-page-title { font-size: 34px; }
446
+ .wb-product-datasheet__meta { font-size: 15px; flex-wrap: wrap; }
447
+ .wb-product-datasheet__cell { font-size: 15px; min-height: 54px; padding-inline: 16px; }
448
+ .wb-product-list__filter-btn { justify-content: center; }
449
+ .wb-product-filter-drawer { width: 100vw; padding: 22px 18px 20px; }
450
+ .wb-product-list[data-list-mode="datasheet"] .wb-product-filter-drawer,
451
+ .wb-product-list[data-wb-list-mode="datasheet"] .wb-product-filter-drawer { width: 100%; padding: 22px 16px 28px; margin-bottom: 54px; }
452
+ .wb-product-filter__title { font-size: 28px; }
453
+ .wb-product-filter__group { padding-bottom: 22px; }
454
+ .wb-product-filter__group-options { gap: 12px; padding-top: 14px; }
455
+ .wb-product-filter__footer { grid-template-columns: minmax(0, 1fr); }
456
+ .wb-product-filter__footer-btn { min-height: 48px; font-size: 14px; }
457
+ .wb-product-card-body { padding: 10px 0 0; }
458
+ .wb-product-card-name {
459
+ font-size: 15px;
460
+ }
461
+ .wb-product-list-pagination { flex-wrap: wrap; }
462
+ .wb-product-list-page-btn { min-width: 34px; height: 34px; font-size: 13px; }
463
+ }
464
+ @media (max-width: 360px) {
465
+ .wb-product-list__grid { grid-template-columns: minmax(0, 1fr); }
466
+ }
467
+ `;
468
+ const PRODUCT_DETAIL_STYLES = `
469
+ .wb-product-detail {
470
+ display:block;
471
+ width:100%;
472
+ background:#fff;
473
+ }
474
+
475
+ .wb-product-detail__header {
476
+ display:flex;
477
+ align-items:center;
478
+ gap:8px;
479
+ padding:6px 10px;
480
+ background:#fef3c7;
481
+ border-bottom:1px solid #fde68a;
482
+ border-radius:4px 4px 0 0;
483
+ font-size:11px;
484
+ color:#78350f;
485
+ pointer-events:none;
486
+ user-select:none;
487
+ font-weight:500;
488
+ }
489
+
490
+ .wb-product-detail__container { max-width:1200px; margin:0 auto; padding:0 40px; }
491
+ .wb-product-detail__breadcrumb { display:flex; align-items:center; gap:16px; padding:20px 0; font-size:13px; color:#888; }
492
+ .wb-product-detail__breadcrumb-back {
493
+ display:inline-flex;
494
+ align-items:center;
495
+ justify-content:center;
496
+ gap:6px;
497
+ flex:0 0 auto;
498
+ padding:0;
499
+ border:none;
500
+ background:none;
501
+ color:#333;
502
+ text-decoration:none;
503
+ font-size:12px;
504
+ line-height:1.3;
505
+ cursor:pointer;
506
+ border-right: 1px solid #979797;
507
+ padding-right: 12px;
508
+ }
509
+ .wb-product-detail__breadcrumb-back-icon {
510
+ display:inline-flex;
511
+ align-items:center;
512
+ justify-content:center;
513
+ width:1em;
514
+ height:1em;
515
+ flex:0 0 auto;
516
+ font-size:inherit;
517
+ line-height:1;
518
+ }
519
+ .wb-product-detail__breadcrumb-back-icon svg {
520
+ display:block;
521
+ width:1em;
522
+ height:1em;
523
+ }
524
+ .wb-product-detail__breadcrumb-back-label { white-space:nowrap; }
525
+ .wb-product-detail__breadcrumb-name {
526
+ min-width:0;
527
+ color:#000;
528
+ font-size: 12px;
529
+ line-height:1.3;
530
+ }
531
+
532
+ .wb-product-detail__hero {
533
+ display:grid;
534
+ grid-template-columns:1fr 1fr;
535
+ gap:48px;
536
+ padding:8px 0 48px;
537
+ align-items:start;
538
+ border-bottom: 1px solid #D8D8D8;
539
+ }
540
+
541
+ .wb-product-gallery { margin-bottom:0; }
542
+ .wb-product-gallery__stage {
543
+ position:relative;
544
+ overflow:hidden;
545
+ border-radius:8px;
546
+ background:#ECEFF3;
547
+ aspect-ratio:1/1;
548
+ margin-bottom:16px;
549
+ cursor:zoom-in;
550
+ }
551
+ .wb-product-gallery__stage.is-zooming { cursor:crosshair; }
552
+ .wb-product-gallery__main-img {
553
+ width:100%;
554
+ height:100%;
555
+ display:block;
556
+ object-fit:contain;
557
+ transition:transform .18s ease;
558
+ transform-origin:center center;
559
+ background:#fff;
560
+ }
561
+ .wb-product-gallery__thumbs-wrap {
562
+ display:grid;
563
+ grid-template-columns:36px 1fr 36px;
564
+ align-items:center;
565
+ gap:12px;
566
+ }
567
+ .wb-product-gallery__thumbs-viewport {
568
+ overflow-x:auto;
569
+ scrollbar-width:none;
570
+ }
571
+ .wb-product-gallery__thumbs-viewport::-webkit-scrollbar { display:none; }
572
+ .wb-product-gallery__thumbs {
573
+ display:flex;
574
+ gap:10px;
575
+ align-items:center;
576
+ }
577
+ .wb-product-gallery__thumb {
578
+ width:72px;
579
+ height:72px;
580
+ border:none;
581
+ background:#fff;
582
+ border-radius:8px;
583
+ cursor:pointer;
584
+ padding:6px;
585
+ flex:0 0 auto;
586
+ display:flex;
587
+ align-items:center;
588
+ justify-content:center;
589
+ box-shadow:0 0 0 1px #e5e5e5 inset;
590
+ transition:all .2s ease;
591
+ }
592
+ .wb-product-gallery__thumb:hover,
593
+ .wb-product-gallery__thumb.is-active {
594
+ box-shadow:0 0 0 1px #111 inset;
595
+ }
596
+ .wb-product-gallery__thumb-img {
597
+ width:100%;
598
+ height:100%;
599
+ display:block;
600
+ object-fit:contain;
601
+ }
602
+ .wb-product-gallery__nav {
603
+ width:36px;
604
+ height:36px;
605
+ border:none;
606
+ background:#fff;
607
+ border-radius:9999px;
608
+ cursor:pointer;
609
+ display:inline-flex;
610
+ align-items:center;
611
+ justify-content:center;
612
+ font-size:22px;
613
+ line-height:1;
614
+ color:#333;
615
+ }
616
+
617
+ .wb-product-detail__info { display:flex; flex-direction:column; }
618
+ .wb-product-detail__name {
619
+ font-size: 48px;
620
+ font-weight:600;
621
+ color:#111;
622
+ line-height:1.25;
623
+ margin:0 0 16px;
624
+ letter-spacing:-0.01em;
625
+ }
626
+ .wb-product-detail__desc {
627
+ font-size:16px;
628
+ margin:0 0 24px;
629
+ color: rgba(0,0,0,0.6);
630
+ line-height:1.5;
631
+ }
632
+
633
+ .wb-product-detail__accordion { border-top:1px solid #e8e8e8; }
634
+ .wb-product-detail__accordion-item { border-bottom:1px solid #e8e8e8; }
635
+ .wb-product-detail__accordion-summary {
636
+ display:flex;
637
+ justify-content:space-between;
638
+ align-items:center;
639
+ padding:14px 0;
640
+ font-size:16px;
641
+ font-weight:500;
642
+ color:#000;
643
+ cursor:pointer;
644
+ list-style:none;
645
+ }
646
+ .wb-product-detail__accordion-summary::-webkit-details-marker { display:none; }
647
+ .wb-product-detail__accordion-summary::marker { display:none; content:''; }
648
+ .wb-product-detail__accordion-icon {
649
+ font-size:18px;
650
+ color:#999;
651
+ font-weight:300;
652
+ transition:transform .2s;
653
+ }
654
+ .wb-product-detail__accordion-item[open] .wb-product-detail__accordion-icon {
655
+ transform:rotate(45deg);
656
+ }
657
+ .wb-product-detail__accordion-body {
658
+ padding:0 0 16px;
659
+ font-size:16px;
660
+ color: rgba(0,0,0,0.8);
661
+ line-height:1.5;
662
+ white-space: pre-wrap;
663
+ }
664
+ .wb-product-detail__accordion-body ul { margin:0; padding:0 0 0 18px; list-style:disc; }
665
+ .wb-product-detail__accordion-body li { margin-bottom:4px; text-transform:capitalize; }
666
+
667
+ .wb-product-detail__download {
668
+ display:inline-flex;
669
+ align-items:center;
670
+ gap:10px;
671
+ padding:10px 16px;
672
+ margin:0;
673
+ background:#f5f7fa;
674
+ border-radius:8px;
675
+ font-size:13px;
676
+ color:#333;
677
+ }
678
+ .wb-product-detail__download-icon { color:#2563eb; font-size:14px; }
679
+
680
+ .wb-product-detail__cta {
681
+ display:block;
682
+ width:100%;
683
+ padding:12px;
684
+ margin-top:32px;
685
+ background:#0057CE;
686
+ color:#fff;
687
+ border:none;
688
+ font-weight:500;
689
+ cursor:pointer;
690
+ text-align:center;
691
+ transition:background .2s;
692
+ }
693
+ .wb-product-detail__cta:hover { background:#1d4ed8; }
694
+
695
+ .wb-product-detail__sections { display:flex; flex-direction:column; }
696
+ .wb-product-detail__section { padding:48px 0; }
697
+ .wb-product-detail__section-header {
698
+ display:grid;
699
+ grid-template-columns:1fr 1fr;
700
+ gap:48px;
701
+ margin-bottom:32px;
702
+ align-items:start;
703
+ }
704
+ .wb-product-detail__section-title {
705
+ font-size:36px;
706
+ font-weight:700;
707
+ color:#111;
708
+ line-height:1.15;
709
+ margin:0;
710
+ letter-spacing:-0.01em;
711
+ }
712
+ .wb-product-detail__section-desc {
713
+ font-size:14px;
714
+ color:#666;
715
+ line-height:1.75;
716
+ margin:0;
717
+ padding-top:8px;
718
+ }
719
+ .wb-product-detail__section-content { font-size:14px; line-height:1.75; color:#444; }
720
+ .wb-product-detail__section-img { width:100%; border-radius:8px; display:block; }
721
+
722
+ .wb-product-detail__table { width:100%; border-collapse:collapse; font-size:13px; }
723
+ .wb-product-detail__table th {
724
+ background:#9e9e9e;
725
+ color:#fff;
726
+ padding:10px 16px;
727
+ font-weight:500;
728
+ text-align:center;
729
+ }
730
+ .wb-product-detail__table td {
731
+ padding:10px 16px;
732
+ border-bottom:1px solid #e8e8e8;
733
+ text-align:center;
734
+ color:#333;
735
+ }
736
+
737
+ .wb-product-detail__nav {
738
+ display:flex;
739
+ justify-content:space-between;
740
+ align-items:center;
741
+ padding:28px 0;
742
+ border-top:1px solid #e8e8e8;
743
+ margin-top:16px;
744
+ }
745
+ .wb-product-detail__nav-item {
746
+ display:flex;
747
+ align-items:center;
748
+ gap:6px;
749
+ color:#333;
750
+ font-size:14px;
751
+ text-decoration:none;
752
+ }
753
+ .wb-product-detail__nav-arrow { font-size:16px; color:#666; }
754
+
755
+ .pm-doc-block__link {
756
+ color:#000;
757
+ text-decoration:none;
758
+ display:flex;
759
+ font-size:14px;
760
+ line-height:20px;
761
+ align-items:center;
762
+ border:1px #e9ebf0 solid;
763
+ padding:12px 16px;
764
+ gap:8px;
765
+ width:max-content;
766
+ }
767
+ .pm-gallery-block{
768
+ padding: 80px 0;
769
+ }
770
+ .pm-gallery-block__wrap {
771
+ display:grid;
772
+ grid-template-columns:repeat(2, 1fr);
773
+ }
774
+ .pm-gallery-block__title {
775
+ font-size:48px;
776
+ line-height:1.15;
777
+ font-weight:600;
778
+ color:#000;
779
+ margin:0;
780
+ max-width: 380px;
781
+ }
782
+ .pm-gallery-block__desc { margin:0; color:rgba(0,0,0,0.6); line-height:1.5; }
783
+ .pm-gallery-block__carousel {
784
+ position:relative;
785
+ margin-top:56px;
786
+ overflow:hidden;
787
+ width:100%;
788
+ grid-column:1 / -1;
789
+ aspect-ratio:2 / 1;
790
+ --swiper-theme-color:#6d28d9;
791
+ --swiper-navigation-size:18px;
792
+ }
793
+ .pm-gallery-block__slide { display:flex; align-items:stretch; height:auto; }
794
+ .pm-gallery-block__image {
795
+ width:100%;
796
+ display:block;
797
+ aspect-ratio:4 / 3;
798
+ object-fit:cover;
799
+ border-radius:12px;
800
+ background:#f3e8ff;
801
+ }
802
+ .pm-gallery-block__pagination { position:relative; margin-top:14px; }
803
+ .pm-gallery-block__pagination .swiper-pagination-bullet {
804
+ width:8px;
805
+ height:8px;
806
+ background:rgba(109,40,217,.28);
807
+ opacity:1;
808
+ }
809
+ .pm-gallery-block__pagination .swiper-pagination-bullet-active {
810
+ width:22px;
811
+ border-radius:999px;
812
+ background:#6d28d9;
813
+ }
814
+ .pm-gallery-block__nav {
815
+ width:38px;
816
+ height:38px;
817
+ border-radius:999px;
818
+ background:rgba(255,255,255,.96);
819
+ box-shadow:0 8px 22px rgba(91,82,115,.16);
820
+ color:#4c1d95;
821
+ }
822
+ .pm-gallery-block__nav::after { font-size:14px; font-weight:700; }
823
+ .pm-gallery-block__nav.swiper-button-disabled { opacity:.35; }
824
+
825
+ .pm-image-block__wrap {
826
+ display:grid;
827
+ grid-template-columns:repeat(2, 1fr);
828
+ }
829
+ .pm-image-block__title {
830
+ font-size:48px;
831
+ font-weight:600;
832
+ line-height:1.15;
833
+ color:#000;
834
+ margin:0;
835
+ max-width: 380px;
836
+ }
837
+ .pm-image-block__desc { margin:0; color:rgba(0,0,0,0.6); line-height:1.5; }
838
+ .pm-image-block__image {
839
+ grid-column:1 / -1;
840
+ margin-top:56px;
841
+ width:100%;
842
+ }
843
+
844
+ .pm-video-block {
845
+ padding:16px 20px;
846
+ margin-bottom:12px;
847
+ background:#fef2f2;
848
+ border:1px dashed #fca5a5;
849
+ border-radius:8px;
850
+ }
851
+ .pm-video-block h3 {
852
+ font-size:48px;
853
+ font-weight:600;
854
+ line-height:1.15;
855
+ color:#000;
856
+ margin:0;
857
+ }
858
+
859
+ @media (max-width: 1023px) {
860
+ .wb-product-detail__container { padding:0 20px; }
861
+ .wb-product-detail__breadcrumb { flex-wrap:wrap; padding:16px 0; }
862
+ .wb-product-detail__hero { grid-template-columns:1fr; gap:24px; }
863
+ .wb-product-detail__name { font-size:28px; }
864
+ .wb-product-detail__desc { margin-bottom:20px; }
865
+ .wb-product-gallery__stage { margin-bottom:12px; }
866
+ .wb-product-gallery__thumbs-wrap { grid-template-columns:32px 1fr 32px; gap:10px; }
867
+ .wb-product-gallery__thumb { width:64px; height:64px; }
868
+ .wb-product-gallery__nav { width:32px; height:32px; font-size:18px; }
869
+ .wb-product-detail__section { padding:36px 0; }
870
+ .wb-product-detail__section-header { grid-template-columns:1fr; gap:12px; }
871
+ .wb-product-detail__section-title { font-size:28px; }
872
+ .pm-gallery-block__wrap,
873
+ .pm-image-block__wrap { grid-template-columns:1fr; gap:16px; }
874
+ .pm-gallery-block__title,
875
+ .pm-image-block__title,
876
+ .pm-video-block h3 { font-size:36px; }
877
+ .pm-gallery-block__carousel,
878
+ .pm-image-block__image { margin-top:32px; }
879
+ }
880
+
881
+ @media (max-width: 767px) {
882
+ .wb-product-detail__container { padding:0; }
883
+ .wb-product-detail__breadcrumb { font-size:12px; gap: 12px; }
884
+ .wb-product-detail__name { font-size:24px; }
885
+ .wb-product-detail__desc { font-size:13px; }
886
+ .wb-product-gallery__thumb { width:56px; height:56px; }
887
+ .wb-product-detail__accordion-summary { padding:12px 0; font-size:13px; }
888
+ .wb-product-detail__cta { font-size:14px; padding:13px; }
889
+ .wb-product-detail__section { padding:28px 0; }
890
+ .wb-product-detail__section-title { font-size:24px; }
891
+ .wb-product-detail__section-desc,
892
+ .wb-product-detail__section-content { font-size:13px; }
893
+ .wb-product-detail__table { display:block; overflow-x:auto; white-space:nowrap; }
894
+ .pm-gallery-block { padding: 50px 0; }
895
+ .pm-video-block { padding:14px 16px; }
896
+ .pm-gallery-block__title,
897
+ .pm-image-block__title,
898
+ .pm-video-block h3 { font-size:28px; }
899
+ .pm-gallery-block__carousel,
900
+ .pm-image-block__image { margin-top:24px; }
901
+ .pm-gallery-block__nav { width:32px; height:32px; }
902
+ .wb-product-detail__accordion-body{font-size: 13px;}
903
+ .pm-image-block__desc,
904
+ .pm-gallery-block__desc{font-size: 13px;}
905
+ }
906
+ `;
907
+ const PRODUCT_DETAIL_V2_STYLES = `
908
+ .wb-product-detail-v2 {
909
+ display:block;
910
+ width:100%;
911
+ background:#fff;
912
+ color:#1e3f5a;
913
+ font-family:"Poppins","Nunito Sans","PingFang SC","Helvetica Neue",Arial,sans-serif;
914
+ }
915
+
916
+ .wb-product-detail-v2__header {
917
+ display:flex;
918
+ align-items:center;
919
+ gap:8px;
920
+ padding:6px 10px;
921
+ background:#fef3c7;
922
+ border-bottom:1px solid #fde68a;
923
+ border-radius:4px 4px 0 0;
924
+ font-size:11px;
925
+ color:#78350f;
926
+ pointer-events:none;
927
+ user-select:none;
928
+ font-weight:500;
929
+ }
930
+
931
+ .wb-product-detail-v2__container {
932
+ max-width:1160px;
933
+ margin:0 auto;
934
+ padding: 72px 20px 0;
935
+ }
936
+
937
+ .wb-product-detail-v2__breadcrumb {
938
+ display:flex;
939
+ align-items:center;
940
+ gap:10px;
941
+ padding:16px 0 18px;
942
+ font-size:11px;
943
+ line-height:1.4;
944
+ color:#6f8090;
945
+ }
946
+
947
+ .wb-product-detail-v2__breadcrumb-back {
948
+ display:inline-flex;
949
+ align-items:center;
950
+ gap:5px;
951
+ padding:0;
952
+ border:none;
953
+ background:none;
954
+ color:#415c72;
955
+ cursor:pointer;
956
+ font-size:11px;
957
+ line-height:1.4;
958
+ }
959
+
960
+ .wb-product-detail-v2__breadcrumb-name {
961
+ min-width:0;
962
+ color:#6f8090;
963
+ }
964
+
965
+ .wb-product-detail-v2__hero {
966
+ display:grid;
967
+ grid-template-columns:minmax(430px, 0.92fr) minmax(470px, 1fr);
968
+ gap:42px;
969
+ align-items:start;
970
+ padding-bottom: 80px;
971
+ }
972
+
973
+ @media (min-width: 768px){
974
+ .wb-product-gallery{
975
+ position: sticky;
976
+ top: 72px;
977
+ }
978
+ }
979
+
980
+ .wb-product-gallery { margin-bottom:0; }
981
+ .wb-product-gallery__stage {
982
+ position:relative;
983
+ overflow:hidden;
984
+ background:#f4f5f7;
985
+ aspect-ratio:1/1;
986
+ margin-bottom:12px;
987
+ cursor:zoom-in;
988
+ border:1px solid #e4e8ee;
989
+ }
990
+ .wb-product-gallery__stage.is-zooming { cursor:crosshair; }
991
+ .wb-product-gallery__main-img {
992
+ width:100%;
993
+ height:100%;
994
+ display:block;
995
+ object-fit:cover;
996
+ background:#fff;
997
+ transition:transform .18s ease;
998
+ transform-origin:center center;
999
+ }
1000
+ .wb-product-gallery__thumbs-wrap {
1001
+ display:block;
1002
+ }
1003
+ .wb-product-gallery__thumbs-viewport {
1004
+ overflow:visible;
1005
+ scrollbar-width:none;
1006
+ }
1007
+ .wb-product-gallery__thumbs-viewport::-webkit-scrollbar { display:none; }
1008
+ .wb-product-gallery__thumbs {
1009
+ display:grid;
1010
+ grid-template-columns:repeat(4, minmax(0, 1fr));
1011
+ gap:10px;
1012
+ align-items:stretch;
1013
+ }
1014
+ .wb-product-gallery__thumb {
1015
+ width:100%;
1016
+ height:auto;
1017
+ aspect-ratio:1/1;
1018
+ border:1px solid #d8dee6;
1019
+ background:#fff;
1020
+ cursor:pointer;
1021
+ padding:0;
1022
+ overflow:hidden;
1023
+ transition:border-color .2s ease, box-shadow .2s ease;
1024
+ }
1025
+ .wb-product-gallery__thumb.is-active {
1026
+ border-color:#7c90a4;
1027
+ box-shadow:0 0 0 1px #7c90a4 inset;
1028
+ }
1029
+ .wb-product-gallery__thumb-img {
1030
+ width:100%;
1031
+ height:100%;
1032
+ display:block;
1033
+ object-fit:cover;
1034
+ }
1035
+ .wb-product-gallery__nav {
1036
+ display:none;
1037
+ }
1038
+ .wb-product-gallery__nav svg {
1039
+ width:16px;
1040
+ height:16px;
1041
+ display:block;
1042
+ }
1043
+
1044
+ .wb-product-detail-v2__info {
1045
+ display:flex;
1046
+ flex-direction:column;
1047
+ gap:8px;
1048
+ padding-top:10px;
1049
+ }
1050
+
1051
+ .wb-product-detail-v2__brand {
1052
+ margin:0;
1053
+ font-size:14px;
1054
+ line-height:1.6;
1055
+ color:#1E2C32;
1056
+ }
1057
+
1058
+ .wb-product-detail-v2__name {
1059
+ margin:0;
1060
+ font-size:30px;
1061
+ line-height:1.25;
1062
+ font-weight:600;
1063
+ color:#000A11;
1064
+ max-width:600px;
1065
+ }
1066
+
1067
+ .wb-product-detail-v2__docs {
1068
+ display:flex;
1069
+ flex-wrap:wrap;
1070
+ gap:8px;
1071
+ margin-block: 24px;
1072
+ }
1073
+ .wb-product-detail-v2__docs:empty{
1074
+ margin-block: 10px;
1075
+ }
1076
+
1077
+ .wb-product-detail-v2__doc-link {
1078
+ display:inline-flex;
1079
+ align-items:center;
1080
+ gap:7px;
1081
+ color:#183b56;
1082
+ font-size:14px;
1083
+ line-height:1.7;
1084
+ font-weight:500;
1085
+ text-decoration:none;
1086
+ }
1087
+ .wb-product-detail-v2__doc-link svg {
1088
+ width:14px;
1089
+ height:14px;
1090
+ display:block;
1091
+ }
1092
+
1093
+ .wb-product-detail-v2__tabs {
1094
+ display:grid;
1095
+ grid-template-columns: repeat(4, 1fr);
1096
+ scroll-behavior:smooth;
1097
+ }
1098
+
1099
+ .wb-product-detail-v2__tab {
1100
+ border:none;
1101
+ background:#F0F0F0;
1102
+ color:#000A11;
1103
+ font-size:16px;
1104
+ line-height:1.4;
1105
+ font-weight:500;
1106
+ cursor:pointer;
1107
+ min-height: 48px;
1108
+ position: relative;
1109
+ }
1110
+ .wb-product-detail-v2__tab::before{
1111
+ content: '';
1112
+ position: absolute;
1113
+ inset: 0;
1114
+ background:#9aa8b5;
1115
+ opacity:0;
1116
+ z-index:1;
1117
+ }
1118
+ .wb-product-detail-v2__tab-text{
1119
+ position: relative;
1120
+ z-index:2;
1121
+ }
1122
+ .wb-product-detail-v2__tab:not(:last-of-type)::after{
1123
+ content: '';
1124
+ position: absolute;
1125
+ width: 0;
1126
+ height: 60%;
1127
+ border-left: 1px solid #d8d8d8;
1128
+ top: 50%;
1129
+ transform: translateY(-50%) scaleX(0.5);
1130
+ right: 0;
1131
+ }
1132
+
1133
+ .wb-product-detail-v2__tab.is-active {
1134
+ /* background:#9aa8b5; */
1135
+ color:#fff;
1136
+ }
1137
+ .wb-product-detail-v2__tab.is-active::before{
1138
+ opacity: 1;
1139
+ }
1140
+
1141
+ .wb-product-detail-v2__panel {
1142
+ display:none;
1143
+ padding:16px;
1144
+ }
1145
+
1146
+ .wb-product-detail-v2__panel.is-active {
1147
+ display:block;
1148
+ }
1149
+
1150
+ .wb-product-detail-v2__intro,
1151
+ .wb-product-detail-v2__feature-desc,
1152
+ .wb-product-detail-v2__faq-answer {
1153
+ font-size:14px;
1154
+ line-height:1.78;
1155
+ color:#5f7284;
1156
+ }
1157
+ .wb-product-detail-v2__intro p,
1158
+ .wb-product-detail-v2__feature-desc p,
1159
+ .wb-product-detail-v2__faq-answer p,
1160
+ .wb-product-detail-v2__spec-value p {
1161
+ margin:0 0 8px;
1162
+ }
1163
+ .wb-product-detail-v2__intro p:last-child,
1164
+ .wb-product-detail-v2__feature-desc p:last-child,
1165
+ .wb-product-detail-v2__faq-answer p:last-child,
1166
+ .wb-product-detail-v2__spec-value p:last-child {
1167
+ margin-bottom:0;
1168
+ }
1169
+
1170
+ .wb-product-detail-v2__feature-list,
1171
+ .wb-product-detail-v2__spec-groups,
1172
+ .wb-product-detail-v2__spec-list,
1173
+ .wb-product-detail-v2__faq-list {
1174
+ display:flex;
1175
+ flex-direction:column;
1176
+ gap:0;
1177
+ }
1178
+
1179
+ .wb-product-detail-v2__spec-groups {
1180
+ gap:28px;
1181
+ }
1182
+
1183
+ .wb-product-detail-v2__spec-group {
1184
+ min-width:0;
1185
+ }
1186
+
1187
+ .wb-product-detail-v2__spec-group-title {
1188
+ margin:0 0 10px;
1189
+ font-size:18px;
1190
+ line-height:1.35;
1191
+ font-weight:600;
1192
+ color:#000A11;
1193
+ }
1194
+
1195
+ .wb-product-detail-v2__spec-row,
1196
+ .wb-product-detail-v2__faq-item {
1197
+ border-bottom:1px solid #d7dde3;
1198
+ padding:16px 0;
1199
+ }
1200
+
1201
+ .wb-product-detail-v2__spec-key {
1202
+ font-size:14px;
1203
+ font-weight:500;
1204
+ color:#000A11;
1205
+ text-transform:uppercase;
1206
+ margin:0 0 6px;
1207
+ }
1208
+
1209
+ .wb-product-detail-v2__spec-row {
1210
+ display:grid;
1211
+ grid-template-columns:minmax(145px, 0.7fr) minmax(0, 1.3fr);
1212
+ gap:18px;
1213
+ align-items:start;
1214
+ }
1215
+
1216
+ .wb-product-detail-v2__spec-value {
1217
+ font-size:14px;
1218
+ line-height:1.78;
1219
+ color:#5f7284;
1220
+ }
1221
+
1222
+ .wb-product-detail-v2__feature-list {
1223
+ margin:0;
1224
+ padding-left:20px;
1225
+ display:block;
1226
+ }
1227
+
1228
+ .wb-product-detail-v2__feature-item {
1229
+ color:#5f7284;
1230
+ font-size:14px;
1231
+ line-height:1.78;
1232
+ margin:0 0 6px;
1233
+ padding:0;
1234
+ }
1235
+
1236
+ .wb-product-detail-v2__feature-item:last-child {
1237
+ margin-bottom:0;
1238
+ }
1239
+
1240
+ .wb-product-detail-v2__feature-text {
1241
+ display:inline;
1242
+ }
1243
+
1244
+ .wb-product-detail-v2__faq-item {
1245
+ padding:0;
1246
+ }
1247
+
1248
+ .wb-product-detail-v2__faq-summary {
1249
+ list-style:none;
1250
+ display:flex;
1251
+ align-items:center;
1252
+ justify-content:space-between;
1253
+ gap:16px;
1254
+ cursor:pointer;
1255
+ padding:16px 0;
1256
+ color:#183b56;
1257
+ font-weight:600;
1258
+ font-size:14px;
1259
+ line-height:1.5;
1260
+ }
1261
+
1262
+ .wb-product-detail-v2__faq-summary::-webkit-details-marker { display:none; }
1263
+ .wb-product-detail-v2__faq-summary::marker { display:none; content:''; }
1264
+
1265
+ .wb-product-detail-v2__faq-icon {
1266
+ color:#90a0ae;
1267
+ font-size:16px;
1268
+ transition:transform .2s ease;
1269
+ }
1270
+
1271
+ .wb-product-detail-v2__faq-item[open] .wb-product-detail-v2__faq-icon {
1272
+ transform:rotate(180deg);
1273
+ }
1274
+
1275
+ .wb-product-detail-v2__faq-answer {
1276
+ padding:0 0 16px;
1277
+ }
1278
+
1279
+ .wb-product-detail-v2__options {
1280
+ display:flex;
1281
+ flex-direction:column;
1282
+ gap:32px;
1283
+ padding-top:8px;
1284
+ }
1285
+
1286
+ .wb-product-detail-v2__option-group {
1287
+ padding-top:0;
1288
+ }
1289
+ .wb-product-detail-v2__actions--tips{
1290
+ font-size: 16px;
1291
+ line-height: 1;
1292
+ color: #344850;
1293
+ margin-top: 16px;
1294
+ }
1295
+ .wb-product-detail-v2__option-label {
1296
+ margin:0 0 16px;
1297
+ font-size:16px;
1298
+ line-height:1;
1299
+ color:#1B2149;
1300
+ font-weight: 400;
1301
+ }
1302
+
1303
+ .wb-product-detail-v2__option-values {
1304
+ display:flex;
1305
+ flex-wrap:wrap;
1306
+ gap:8px;
1307
+ }
1308
+
1309
+ .wb-product-detail-v2__option-value {
1310
+ display:inline-flex;
1311
+ align-items:center;
1312
+ justify-content:flex-start;
1313
+ gap:8px;
1314
+ min-height:48px;
1315
+ padding: 4px;
1316
+ border:1px solid #EDEDED;
1317
+ background:#fff;
1318
+ color:#44576a;
1319
+ font-size:12px;
1320
+ line-height:1.3;
1321
+ border-radius: 2px;
1322
+ box-sizing:border-box;
1323
+ white-space:nowrap;
1324
+ cursor:pointer;
1325
+ transition:border-color .2s ease, box-shadow .2s ease, background-color .2s ease;
1326
+ appearance:none;
1327
+ outline:none;
1328
+ }
1329
+ .wb-product-detail-v2__option-value:hover{
1330
+ border-color:#29375C;
1331
+ }
1332
+ .wb-product-detail-v2__option-value.is-active {
1333
+ border-color:#29375C;
1334
+ }
1335
+ .wb-product-detail-v2__option-value.is-text-only {
1336
+ justify-content:center;
1337
+ padding-inline: 16px;
1338
+ }
1339
+
1340
+ .wb-product-detail-v2__option-swatch {
1341
+ width:40px;
1342
+ height:40px;
1343
+ display:inline-block;
1344
+ flex:0 0 auto;
1345
+ }
1346
+
1347
+ .wb-product-detail-v2__option-image {
1348
+ width:40px;
1349
+ height:40px;
1350
+ object-fit:cover;
1351
+ flex:0 0 auto;
1352
+ }
1353
+
1354
+ .wb-product-detail-v2__option-text {
1355
+ display:inline-block;
1356
+ max-width:100%;
1357
+ }
1358
+
1359
+ .wb-product-detail-v2__actions {
1360
+ display:flex;
1361
+ flex-wrap:wrap;
1362
+ gap:10px;
1363
+ margin-top: 64px;
1364
+ }
1365
+
1366
+ .wb-product-detail-v2__action {
1367
+ flex:1;
1368
+ display: flex;
1369
+ align-items: center;
1370
+ justify-content: center;
1371
+ min-width:112px;
1372
+ min-height: 50px;
1373
+ padding:10px 20px;
1374
+ border:1px solid #183b56;
1375
+ background:#fff;
1376
+ color:#183b56;
1377
+ text-decoration:none;
1378
+ text-align:center;
1379
+ font-weight:500;
1380
+ font-size:16px;
1381
+ line-height:1.2;
1382
+ box-sizing:border-box;
1383
+ cursor: pointer;
1384
+ }
1385
+
1386
+ .wb-product-detail-v2__action--primary {
1387
+ background:#ffd30a;
1388
+ border-color:#ffd30a;
1389
+ color:#183b56;
1390
+ }
1391
+
1392
+ .wb-product-detail-v2__related {
1393
+ width:100vw;
1394
+ margin-left:calc(50% - 50vw);
1395
+ margin-right:calc(50% - 50vw);
1396
+ margin-top:0;
1397
+ padding:100px 0;
1398
+ background-color: #ECEEF0;
1399
+ overflow:hidden;
1400
+ box-sizing:border-box;
1401
+ }
1402
+ .wb-product-detail-v2__related,
1403
+ .wb-product-detail-v2__related *,
1404
+ .wb-product-detail-v2__related *::before,
1405
+ .wb-product-detail-v2__related *::after {
1406
+ box-sizing:border-box;
1407
+ }
1408
+ .wb-product-detail-v2__related a {
1409
+ color:currentColor;
1410
+ text-decoration:none;
1411
+ }
1412
+ .wb-product-detail-v2__related .wb-content-carousel__container {
1413
+ width:100%;
1414
+ max-width: 1160px;
1415
+ margin:0 auto;
1416
+ padding:0 20px;
1417
+ }
1418
+ .wb-product-detail-v2__related .wb-content-carousel__header {
1419
+ display:flex;
1420
+ align-items:flex-start;
1421
+ gap:24px;
1422
+ margin-bottom:48px;
1423
+ }
1424
+ .wb-product-detail-v2__related .wb-content-carousel__title {
1425
+ margin:0;
1426
+ color:#000a11;
1427
+ font-size:48px;
1428
+ font-weight:600;
1429
+ line-height:1.15;
1430
+ letter-spacing:0;
1431
+ }
1432
+ .wb-product-detail-v2__related .wb-content-carousel__nav {
1433
+ margin-left:auto;
1434
+ display:flex;
1435
+ align-items:center;
1436
+ gap:16px;
1437
+ }
1438
+ .wb-product-detail-v2__related .wb-content-carousel__nav-btn {
1439
+ width:64px;
1440
+ height:64px;
1441
+ display:inline-flex;
1442
+ align-items:center;
1443
+ justify-content:center;
1444
+ padding:0;
1445
+ border:0;
1446
+ border-radius:0;
1447
+ color:#000a11;
1448
+ background:transparent;
1449
+ cursor:pointer;
1450
+ }
1451
+ .wb-product-detail-v2__related .wb-content-carousel__nav-icon {
1452
+ width:48px;
1453
+ height:48px;
1454
+ }
1455
+ .wb-product-detail-v2__related .wb-content-carousel__carousel-wrap {
1456
+ margin:0 -20px;
1457
+ }
1458
+ .wb-product-detail-v2__related .wb-content-carousel__track {
1459
+ display:grid;
1460
+ grid-auto-flow:column;
1461
+ grid-auto-columns:calc((100% - 48px) / 3);
1462
+ gap:24px;
1463
+ padding:0 20px;
1464
+ overflow-x:auto;
1465
+ scroll-snap-type:x mandatory;
1466
+ scroll-behavior:smooth;
1467
+ scroll-padding-inline:20px;
1468
+ -webkit-overflow-scrolling:touch;
1469
+ scrollbar-width:none;
1470
+ }
1471
+ .wb-product-detail-v2__related .wb-content-carousel__track::-webkit-scrollbar {
1472
+ display:none;
1473
+ }
1474
+ .wb-product-detail-v2__related .wb-content-carousel__item {
1475
+ position:relative;
1476
+ display:flex;
1477
+ min-width:0;
1478
+ flex-direction:column;
1479
+ gap:16px;
1480
+ scroll-snap-align:center;
1481
+ }
1482
+ .wb-product-detail-v2__related .wb-content-carousel__item:first-child {
1483
+ scroll-snap-align:start;
1484
+ }
1485
+ .wb-product-detail-v2__related .wb-content-carousel__item:last-child {
1486
+ scroll-snap-align:end;
1487
+ }
1488
+ .wb-product-detail-v2__related .wb-content-carousel__media {
1489
+ display:block;
1490
+ width:100%;
1491
+ aspect-ratio:42 / 46;
1492
+ overflow:hidden;
1493
+ background:#d5dbe1;
1494
+ }
1495
+ .wb-product-detail-v2__related .wb-content-carousel__img {
1496
+ display:block;
1497
+ width:100%;
1498
+ height:100%;
1499
+ object-fit:cover;
1500
+ transition:transform 260ms ease;
1501
+ }
1502
+ .wb-product-detail-v2__related .wb-content-carousel__item:hover .wb-content-carousel__img {
1503
+ transform:scale(1.04);
1504
+ }
1505
+ .wb-product-detail-v2__related .wb-content-carousel__item-title {
1506
+ margin:0;
1507
+ color:#000a11;
1508
+ font-size:20px;
1509
+ font-weight:500;
1510
+ line-height:1.4;
1511
+ letter-spacing:0;
1512
+ overflow-wrap:anywhere;
1513
+ }
1514
+ .wb-product-detail-v2__related .wb-content-carousel__link::after {
1515
+ content:"";
1516
+ position:absolute;
1517
+ inset:0;
1518
+ }
1519
+
1520
+ @media (max-width: 1024px) {
1521
+ .wb-product-detail-v2__container {
1522
+ padding:0 24px 56px;
1523
+ }
1524
+
1525
+ .wb-product-detail-v2__hero {
1526
+ grid-template-columns:1fr;
1527
+ gap:32px;
1528
+ }
1529
+
1530
+ .wb-product-detail-v2__name {
1531
+ font-size:34px;
1532
+ }
1533
+
1534
+ }
1535
+
1536
+ @media (max-width: 767px) {
1537
+ .wb-product-detail-v2__breadcrumb{
1538
+ display: none;
1539
+ }
1540
+ .wb-product-gallery{
1541
+ width: 100vw;
1542
+ margin-left: calc(50% - 50vw);
1543
+ margin-right: calc(50% - 50vw);
1544
+ }
1545
+ .wb-product-detail-v2__container {
1546
+
1547
+ }
1548
+ .wb-product-gallery__stage{
1549
+ margin-bottom:
1550
+ }
1551
+
1552
+ .wb-product-detail-v2__name {
1553
+ font-size:20px;
1554
+ }
1555
+
1556
+ .wb-product-gallery__thumb {
1557
+ width:100%;
1558
+ height:auto;
1559
+ }
1560
+
1561
+ .wb-product-gallery__thumbs {
1562
+ grid-template-columns:repeat(4, minmax(0, 1fr));
1563
+ gap:8px;
1564
+ }
1565
+
1566
+ .wb-product-detail-v2__tabs {
1567
+ display:flex;
1568
+ grid-template-columns:none;
1569
+ overflow-x:auto;
1570
+ overflow-y:hidden;
1571
+ scroll-snap-type:x mandatory;
1572
+ scroll-padding-inline:20px;
1573
+ -webkit-overflow-scrolling:touch;
1574
+ scrollbar-width:none;
1575
+ margin-inline:-24px;
1576
+ padding-inline:24px;
1577
+ width:100vw;
1578
+ }
1579
+ .wb-product-detail-v2__tabs::-webkit-scrollbar { display:none; }
1580
+
1581
+ .wb-product-detail-v2__tab {
1582
+ flex:0 0 auto;
1583
+ min-width:150px;
1584
+ padding:10px 16px;
1585
+ scroll-snap-align:center;
1586
+ }
1587
+ .wb-product-detail-v2__tab-text{
1588
+ font-size: 13px;
1589
+ }
1590
+ .wb-product-detail-v2__spec-row {
1591
+ grid-template-columns:1fr;
1592
+ }
1593
+
1594
+ .wb-product-detail-v2__actions {
1595
+ flex-direction:column;
1596
+ }
1597
+
1598
+ .wb-product-detail-v2__action {
1599
+ width:100%;
1600
+ }
1601
+
1602
+ .wb-product-detail-v2__related {
1603
+ padding:40px 0;
1604
+ }
1605
+ .wb-product-detail-v2__related .wb-content-carousel__header {
1606
+ margin-bottom:24px;
1607
+ }
1608
+ .wb-product-detail-v2__related .wb-content-carousel__title {
1609
+ font-size:24px;
1610
+ }
1611
+ .wb-product-detail-v2__related .wb-content-carousel__nav {
1612
+ gap:8px;
1613
+ }
1614
+ .wb-product-detail-v2__related .wb-content-carousel__nav-btn {
1615
+ width:32px;
1616
+ height:32px;
1617
+ }
1618
+ .wb-product-detail-v2__related .wb-content-carousel__nav-icon {
1619
+ width:24px;
1620
+ height:24px;
1621
+ }
1622
+ .wb-product-detail-v2__related .wb-content-carousel__track {
1623
+ grid-auto-columns:calc((100% - 12px) / 1.5);
1624
+ gap:12px;
1625
+ }
1626
+ .wb-product-detail-v2__related .wb-content-carousel__item {
1627
+ gap:8px;
1628
+ }
1629
+ .wb-product-detail-v2__related .wb-content-carousel__item-title {
1630
+ font-size:13px;
1631
+ }
1632
+ }
1633
+ `;
1634
+ function normalizeSiteHref$1(rawValue) {
1635
+ let value = String(rawValue ?? "").trim();
1636
+ if (!value)
1637
+ return "";
1638
+ if (value.startsWith("/") || value.startsWith("#") || value.startsWith("mailto:") || value.startsWith("tel:") || /^https?:\/\//i.test(value) || value.startsWith("//")) {
1639
+ return value;
1640
+ }
1641
+ if (value.startsWith("./"))
1642
+ value = value.slice(2);
1643
+ return `/${value}`;
1644
+ }
1645
+ function composeDynamicUrl$1(value, template) {
1646
+ const raw = String(value ?? "");
1647
+ const tpl = String(template ?? "").trim();
1648
+ if (!tpl)
1649
+ return raw;
1650
+ if (tpl.includes("{{encoded}}"))
1651
+ return tpl.replace(/\{\{encoded\}\}/g, encodeURIComponent(raw));
1652
+ if (tpl.includes("{{value}}"))
1653
+ return tpl.replace(/\{\{value\}\}/g, raw);
1654
+ return `${tpl}${raw}`;
1655
+ }
1656
+ function composePlaceholderUrl(field, template) {
1657
+ const token = field ? `{{${field}}}` : "";
1658
+ return composeDynamicUrl$1(token, template);
1659
+ }
1660
+ function removeDynamicRenderCloneIds(root) {
1661
+ const nodes = [
1662
+ ...root.hasAttribute("id") ? [root] : [],
1663
+ ...Array.from(root.querySelectorAll("[id]"))
1664
+ ];
1665
+ nodes.forEach((el) => el.removeAttribute("id"));
1666
+ }
1667
+ const selectBoundElements = (root, selector) => [
1668
+ ...root.matches(selector) ? [root] : [],
1669
+ ...Array.from(root.querySelectorAll(selector))
1670
+ ];
1671
+ function normalizeDynamicLinkElement$1(el, doc) {
1672
+ var _a;
1673
+ if (el.tagName === "A")
1674
+ return el;
1675
+ const link = doc.createElement("a");
1676
+ Array.from(el.attributes).forEach((attr) => link.setAttribute(attr.name, attr.value));
1677
+ link.setAttribute("href", el.getAttribute("href") || "#");
1678
+ while (el.firstChild)
1679
+ link.appendChild(el.firstChild);
1680
+ (_a = el.parentNode) == null ? void 0 : _a.replaceChild(link, el);
1681
+ return link;
1682
+ }
1683
+ function normalizeDynamicImageElement$1(el, doc) {
1684
+ var _a;
1685
+ if (el.tagName === "IMG")
1686
+ return el;
1687
+ const image = doc.createElement("img");
1688
+ Array.from(el.attributes).forEach((attr) => image.setAttribute(attr.name, attr.value));
1689
+ image.setAttribute("alt", el.getAttribute("alt") || "");
1690
+ (_a = el.parentNode) == null ? void 0 : _a.replaceChild(image, el);
1691
+ return image;
1692
+ }
1693
+ function normalizeDynamicElements(root, doc) {
1694
+ let nextRoot = root;
1695
+ selectBoundElements(root, '[data-wb-dynamic="image"]').forEach((el) => {
1696
+ const normalized = normalizeDynamicImageElement$1(el, doc);
1697
+ if (el === nextRoot)
1698
+ nextRoot = normalized;
1699
+ });
1700
+ selectBoundElements(nextRoot, '[data-wb-dynamic="link"], [data-cms-bind-href]').forEach((el) => {
1701
+ const normalized = normalizeDynamicLinkElement$1(el, doc);
1702
+ if (el === nextRoot)
1703
+ nextRoot = normalized;
1704
+ });
1705
+ return nextRoot;
1706
+ }
1707
+ const removeAttr = (el, attr, enabled) => {
1708
+ if (enabled)
1709
+ el.removeAttribute(attr);
1710
+ };
1711
+ const isDynamicConditionTruthy = (value) => {
1712
+ if (Array.isArray(value))
1713
+ return value.length > 0;
1714
+ if (value == null)
1715
+ return false;
1716
+ if (typeof value === "boolean")
1717
+ return value;
1718
+ if (typeof value === "number")
1719
+ return Number.isFinite(value) && value !== 0;
1720
+ if (typeof value === "string")
1721
+ return value.trim().length > 0;
1722
+ if (typeof value === "object")
1723
+ return Object.keys(value).length > 0;
1724
+ return Boolean(value);
1725
+ };
1726
+ const shouldShowDynamicCondition = (value, mode) => {
1727
+ const truthy = isDynamicConditionTruthy(value);
1728
+ if (mode === "falsy" || mode === "isEmpty")
1729
+ return !truthy;
1730
+ return truthy;
1731
+ };
1732
+ const applyDynamicConditions = (root, data, removeAttrs) => {
1733
+ selectBoundElements(root, "[data-cms-if]").forEach((el) => {
1734
+ const key = `${el.getAttribute("data-cms-if") ?? ""}`.trim();
1735
+ if (!key || !(key in data))
1736
+ return;
1737
+ const mode = `${el.getAttribute("data-cms-if-mode") ?? "truthy"}`.trim() || "truthy";
1738
+ if (!shouldShowDynamicCondition(data[key], mode)) {
1739
+ el.remove();
1740
+ return;
1741
+ }
1742
+ removeAttr(el, "data-cms-if", removeAttrs);
1743
+ removeAttr(el, "data-cms-if-mode", removeAttrs);
1744
+ });
1745
+ };
1746
+ function bindDynamicRenderData(root, data, options = {}) {
1747
+ const doc = options.doc ?? root.ownerDocument;
1748
+ const removeAttrs = options.removeBindingAttrs === true;
1749
+ const imageStrategy = options.imageStrategy ?? "preview-background";
1750
+ let boundRoot = options.normalizeDynamicElements && doc ? normalizeDynamicElements(root, doc) : root;
1751
+ applyDynamicConditions(boundRoot, data, removeAttrs);
1752
+ selectBoundElements(boundRoot, "[data-cms-bind]").forEach((el) => {
1753
+ const key = el.getAttribute("data-cms-bind");
1754
+ if (key in data)
1755
+ el.textContent = String(data[key] ?? "");
1756
+ removeAttr(el, "data-cms-bind", removeAttrs);
1757
+ });
1758
+ selectBoundElements(boundRoot, "[data-cms-html]").forEach((el) => {
1759
+ const key = el.getAttribute("data-cms-html");
1760
+ if (key in data)
1761
+ el.innerHTML = String(data[key] ?? "");
1762
+ removeAttr(el, "data-cms-html", removeAttrs);
1763
+ });
1764
+ selectBoundElements(boundRoot, "[data-cms-bind-src]").forEach((el) => {
1765
+ var _a;
1766
+ const key = el.getAttribute("data-cms-bind-src");
1767
+ const altKey = el.getAttribute("data-cms-bind-alt") || "";
1768
+ const src = data[key];
1769
+ removeAttr(el, "data-cms-bind-src", removeAttrs);
1770
+ if (!src)
1771
+ return;
1772
+ if (el.tagName === "IMG") {
1773
+ el.src = String(src);
1774
+ return;
1775
+ }
1776
+ if (imageStrategy === "seo-img" && doc) {
1777
+ const img = doc.createElement("img");
1778
+ img.src = String(src);
1779
+ img.alt = altKey && altKey in data ? String(data[altKey] ?? "") : "";
1780
+ const style = el.getAttribute("style");
1781
+ if (style)
1782
+ img.setAttribute("style", style);
1783
+ const cls = el.getAttribute("class");
1784
+ if (cls)
1785
+ img.setAttribute("class", cls);
1786
+ (_a = el.parentNode) == null ? void 0 : _a.replaceChild(img, el);
1787
+ if (el === boundRoot)
1788
+ boundRoot = img;
1789
+ return;
1790
+ }
1791
+ const htmlEl = el;
1792
+ htmlEl.style.backgroundImage = `url('${String(src)}')`;
1793
+ htmlEl.style.backgroundSize = "cover";
1794
+ htmlEl.style.backgroundPosition = "center";
1795
+ htmlEl.textContent = "";
1796
+ });
1797
+ const bindAttribute = (selector, sourceAttr, targetAttr) => {
1798
+ selectBoundElements(boundRoot, selector).forEach((el) => {
1799
+ const key = el.getAttribute(sourceAttr);
1800
+ if (key in data) {
1801
+ const value = data[key];
1802
+ if (value)
1803
+ el.setAttribute(targetAttr, String(value));
1804
+ else
1805
+ el.removeAttribute(targetAttr);
1806
+ }
1807
+ removeAttr(el, sourceAttr, removeAttrs);
1808
+ });
1809
+ };
1810
+ bindAttribute("[data-cms-bind-alt]", "data-cms-bind-alt", "alt");
1811
+ bindAttribute("[data-cms-bind-target]", "data-cms-bind-target", "target");
1812
+ bindAttribute("[data-cms-bind-content]", "data-cms-bind-content", "content");
1813
+ bindAttribute("[data-cms-bind-title]", "data-cms-bind-title", "title");
1814
+ bindAttribute("[data-cms-bind-value]", "data-cms-bind-value", "value");
1815
+ bindAttribute("[data-cms-bind-style]", "data-cms-bind-style", "style");
1816
+ bindAttribute("[data-cms-bind-aria-current]", "data-cms-bind-aria-current", "aria-current");
1817
+ bindAttribute(
1818
+ "[data-cms-bind-data-product-spec-values]",
1819
+ "data-cms-bind-data-product-spec-values",
1820
+ "data-product-spec-values"
1821
+ );
1822
+ selectBoundElements(boundRoot, "[data-cms-bind-class]").forEach((el) => {
1823
+ const key = el.getAttribute("data-cms-bind-class");
1824
+ if (key in data) {
1825
+ const value = data[key];
1826
+ if (value)
1827
+ el.setAttribute("class", String(value));
1828
+ else
1829
+ el.removeAttribute("class");
1830
+ }
1831
+ removeAttr(el, "data-cms-bind-class", removeAttrs);
1832
+ });
1833
+ selectBoundElements(boundRoot, "[data-cms-bind-classappend]").forEach((el) => {
1834
+ const key = el.getAttribute("data-cms-bind-classappend");
1835
+ if (key in data) {
1836
+ const value = data[key];
1837
+ if (value) {
1838
+ String(value).split(/\s+/).filter(Boolean).forEach((className) => el.classList.add(className));
1839
+ }
1840
+ }
1841
+ removeAttr(el, "data-cms-bind-classappend", removeAttrs);
1842
+ });
1843
+ selectBoundElements(boundRoot, "[data-cms-bind-href]").forEach((el) => {
1844
+ const key = el.getAttribute("data-cms-bind-href");
1845
+ const template = el.getAttribute("data-cms-bind-href-template") || "";
1846
+ if (key in data) {
1847
+ el.href = composeDynamicUrl$1(data[key], template) || "#";
1848
+ }
1849
+ removeAttr(el, "data-cms-bind-href", removeAttrs);
1850
+ removeAttr(el, "data-cms-bind-href-template", removeAttrs);
1851
+ });
1852
+ return boundRoot;
1853
+ }
1854
+ let cmsFactoryDataProvider = {};
1855
+ const setCmsFactoryDataProvider = (provider) => {
1856
+ const previousProvider = cmsFactoryDataProvider;
1857
+ cmsFactoryDataProvider = provider;
1858
+ return () => {
1859
+ cmsFactoryDataProvider = previousProvider;
1860
+ };
1861
+ };
1862
+ function getEffectiveTenantId() {
1863
+ var _a;
1864
+ return (_a = cmsFactoryDataProvider.getEffectiveTenantId) == null ? void 0 : _a.call(cmsFactoryDataProvider);
1865
+ }
1866
+ function getRuntimeEndpoints() {
1867
+ var _a;
1868
+ return ((_a = cmsFactoryDataProvider.getRuntimeEndpoints) == null ? void 0 : _a.call(cmsFactoryDataProvider)) ?? {};
1869
+ }
1870
+ function getRuntimeEndpoint(key) {
1871
+ return `${getRuntimeEndpoints()[key] ?? ""}`.trim();
1872
+ }
1873
+ function getRuntimeRequestConfig() {
1874
+ var _a;
1875
+ const config = ((_a = cmsFactoryDataProvider.getRuntimeRequestConfig) == null ? void 0 : _a.call(cmsFactoryDataProvider)) ?? {};
1876
+ return {
1877
+ headerName: `${config.headerName ?? ""}`.trim(),
1878
+ headerValue: config.headerValue ?? getEffectiveTenantId() ?? ""
1879
+ };
1880
+ }
1881
+ const CMS_RUNTIME_API_MAP = {
1882
+ "post-list": { endpoint: "postPage", entity: "post" },
1883
+ "cases-list": { endpoint: "postPage", entity: "post" },
1884
+ "media-list": { endpoint: "mediaPage", entity: "media" },
1885
+ "product-list": { endpoint: "productPage", entity: "product" }
1886
+ };
1887
+ function normalizeSiteHref(rawValue) {
1888
+ let value = String(rawValue ?? "").trim();
1889
+ if (!value)
1890
+ return "";
1891
+ if (value.startsWith("/") || value.startsWith("#") || value.startsWith("mailto:") || value.startsWith("tel:") || /^https?:\/\//i.test(value) || value.startsWith("//")) {
1892
+ return value;
1893
+ }
1894
+ if (value.startsWith("./"))
1895
+ value = value.slice(2);
1896
+ return `/${value}`;
1897
+ }
1898
+ function isTruthyFlag(value) {
1899
+ const normalized = String(value ?? "").trim().toLowerCase();
1900
+ return ["1", "true", "yes", "on"].includes(normalized);
1901
+ }
1902
+ const LOOP_GRID_EXPORT_ATTRS = [
1903
+ "data-wb-instance-id",
1904
+ "data-wb-loop-grid-version",
1905
+ "data-wb-grid-id",
1906
+ "data-wb-filter-key",
1907
+ "data-wb-source-type",
1908
+ "data-wb-query-mode",
1909
+ "data-wb-item-template-id",
1910
+ "data-wb-pagination",
1911
+ "data-wb-provider-key",
1912
+ "data-wb-loop-grid-schema",
1913
+ "data-wb-page-size",
1914
+ "data-wb-max-pages",
1915
+ "data-wb-category-id",
1916
+ "data-wb-sort-field",
1917
+ "data-wb-sort-asc"
1918
+ ];
1919
+ function hasLoopGridSignature(attrs) {
1920
+ return attrs["data-wb-component"] === "loop-grid" || attrs["data-wb-loop-grid-version"] !== void 0 || attrs["data-wb-loop-grid-schema"] !== void 0;
1921
+ }
1922
+ function cleanupLoopGridExportAttrsRecord(attrs, options) {
1923
+ LOOP_GRID_EXPORT_ATTRS.forEach((attr) => {
1924
+ if (attr === "data-wb-instance-id")
1925
+ return;
1926
+ delete attrs[attr];
1927
+ });
1928
+ }
1929
+ function cleanupLoopGridExportAttrsElement(el) {
1930
+ LOOP_GRID_EXPORT_ATTRS.forEach((attr) => el.removeAttribute(attr));
1931
+ }
1932
+ function resolvePaginationClass(dataCmsComponent) {
1933
+ if (dataCmsComponent === "product-list")
1934
+ return "wb-product-list-pagination";
1935
+ if (dataCmsComponent === "media-list")
1936
+ return "wb-cms-media-pagination";
1937
+ return "wb-post-list-pagination";
1938
+ }
1939
+ function resolvePaginationPageBtnClass(dataCmsComponent) {
1940
+ if (dataCmsComponent === "product-list")
1941
+ return "wb-product-list-page-btn";
1942
+ if (dataCmsComponent === "media-list")
1943
+ return "wb-cms-media-page-btn";
1944
+ return "wb-post-list-page-btn";
1945
+ }
1946
+ function isLoopGridPaginationNav(nav) {
1947
+ return nav.classList.contains("wb-loop-grid-pagination");
1948
+ }
1949
+ const CMS_TRANSFORM_FN = {
1950
+ post: `function transform(item) {
1951
+ var content = item && item.contents && item.contents[0] || {};
1952
+ var explicitUrl = ${normalizeSiteHref.toString()}(
1953
+ item && (item.url || item.postUrl || item.detailUrl || item.link)
1954
+ || (content && (content.url || content.postUrl || content.detailUrl || content.link))
1955
+ );
1956
+ var slug = String(item && item.slug || '').trim();
1957
+ var typeCode = String(item && item.typeCode || '').trim();
1958
+ var postId = item && item.id;
1959
+ var identifier = slug || (postId == null ? '' : String(postId).trim());
1960
+ return {
1961
+ 'post.name': item.name || '',
1962
+ 'post.image': item.image || '',
1963
+ 'post.excerpt': item.excerpt || '',
1964
+ 'post.url': explicitUrl || (identifier && typeCode ? ('/en/post/' + encodeURIComponent(typeCode) + '/' + encodeURIComponent(identifier) + '.html') : '#'),
1965
+ 'post.categoryIds': item.categoryIds || [],
1966
+ 'post.categoryNames': item.categoryNames || [],
1967
+ 'post.tagIds': item.tagIds || [],
1968
+ 'post.tagNames': item.tagNames || []
1969
+ };
1970
+ }`,
1971
+ media: `function transform(item) {
1972
+ function formatFileSize(size) {
1973
+ var normalized = Number(size);
1974
+ if (!isFinite(normalized) || normalized < 0) return '';
1975
+ if (normalized === 0) return '0 B';
1976
+ var units = ['B', 'KB', 'MB', 'GB'];
1977
+ var index = Math.min(Math.floor(Math.log(normalized) / Math.log(1024)), units.length - 1);
1978
+ var value = normalized / Math.pow(1024, index);
1979
+ var text = value >= 100 ? value.toFixed(0) : value.toFixed(1).replace(/\\.0$/, '');
1980
+ return text + ' ' + units[index];
1981
+ }
1982
+ var mediaUrl = ${normalizeSiteHref.toString()}(
1983
+ item && (item.url || item.mediaUrl || item.link)
1984
+ );
1985
+ var explicitUrl = ${normalizeSiteHref.toString()}(
1986
+ item && (item.detailUrl || item.url || item.mediaUrl || item.link)
1987
+ );
1988
+ var slug = String(item && item.slug || '').trim();
1989
+ var categoryCode = String(item && item.categoryCode || '').trim();
1990
+ var mediaId = item && item.id;
1991
+ var identifier = slug || (mediaId == null ? '' : String(mediaId).trim());
1992
+ return {
1993
+ 'media.title': item.title || '',
1994
+ 'media.url': mediaUrl || '',
1995
+ 'media.size': formatFileSize(item && (item.size != null ? item.size : item.fileSize)),
1996
+ 'media.coverUrl': item.coverUrl || '',
1997
+ 'media.description': item.description || '',
1998
+ 'media.detailUrl': explicitUrl || (identifier && categoryCode ? ('/' + resolveLanguage() + '/' + encodeURIComponent(categoryCode) + '/' + encodeURIComponent(identifier) + '.html') : '#')
1999
+ };
2000
+ }`,
2001
+ product: `function transform(item) {
2002
+ var slug = String((item && (item.slug || item.productSlug)) || '').trim();
2003
+ var productId = item && (item.id != null ? item.id : item.spuId);
2004
+ var identifier = slug || (productId == null ? '' : String(productId).trim());
2005
+ var canonicalUrl = identifier ? '/products/' + encodeURIComponent(identifier) + '.html' : '#';
2006
+ var explicitUrl = ${normalizeSiteHref.toString()}(item && (item.url || item.productUrl));
2007
+ return {
2008
+ 'product.name': item.name || '',
2009
+ 'product.picUrl': item.picUrl || '',
2010
+ 'product.priceFormatted': '$' + (item.price / 100).toFixed(2),
2011
+ 'product.salesCount': (item.salesCount || 0) + ' sold',
2012
+ 'product.url': (explicitUrl && /^\\/(?:[a-z]{2}(?:-[a-z]{2})?)?\\/?products\\//i.test(explicitUrl))
2013
+ ? explicitUrl
2014
+ : canonicalUrl
2015
+ };
2016
+ }`
2017
+ };
2018
+ const STATIC_CHILD = {
2019
+ selectable: false,
2020
+ draggable: false,
2021
+ droppable: false,
2022
+ hoverable: false,
2023
+ layerable: false,
2024
+ copyable: false,
2025
+ removable: false,
2026
+ badgable: false,
2027
+ highlightable: false
2028
+ };
2029
+ function makePreviewHeader(headerClass, content) {
2030
+ return { tagName: "div", ...STATIC_CHILD, attributes: { class: headerClass }, content };
2031
+ }
2032
+ function makePreviewGrid(repeatEntity, gridClass, cards) {
2033
+ return {
2034
+ tagName: "div",
2035
+ ...STATIC_CHILD,
2036
+ attributes: {
2037
+ "data-cms-repeat": repeatEntity,
2038
+ "data-cms-repeat-container": "true",
2039
+ class: gridClass
2040
+ },
2041
+ components: cards
2042
+ };
2043
+ }
2044
+ function makePaginationNav(paginationClass, pageBtnClass, options) {
2045
+ const interactiveChild = (options == null ? void 0 : options.interactiveInEditor) ? {
2046
+ draggable: false,
2047
+ droppable: false,
2048
+ copyable: false,
2049
+ removable: false,
2050
+ editable: false
2051
+ } : STATIC_CHILD;
2052
+ return {
2053
+ tagName: "nav",
2054
+ ...interactiveChild,
2055
+ attributes: { "data-cms-pagination": "", class: paginationClass },
2056
+ components: [
2057
+ {
2058
+ tagName: "span",
2059
+ ...interactiveChild,
2060
+ attributes: { class: `${pageBtnClass} active` },
2061
+ content: "1"
2062
+ },
2063
+ { tagName: "span", ...interactiveChild, attributes: { class: pageBtnClass }, content: "2" },
2064
+ { tagName: "span", ...interactiveChild, attributes: { class: pageBtnClass }, content: "3" },
2065
+ {
2066
+ tagName: "span",
2067
+ ...interactiveChild,
2068
+ attributes: { class: pageBtnClass, "aria-label": "下一页" },
2069
+ content: paginationClass.includes("wb-loop-grid-pagination") ? LOOP_GRID_NEXT_ICON : "下一页 »"
2070
+ }
2071
+ ]
2072
+ };
2073
+ }
2074
+ function ensurePaginationNavElement(doc, el, dataCmsComponent) {
2075
+ let paginationNav = el.querySelector("nav[data-cms-pagination]");
2076
+ if (paginationNav)
2077
+ return paginationNav;
2078
+ if (!["post-list", "cases-list", "product-list", "media-list"].includes(dataCmsComponent)) {
2079
+ return null;
2080
+ }
2081
+ paginationNav = doc.createElement("nav");
2082
+ paginationNav.setAttribute("data-cms-pagination", "");
2083
+ paginationNav.setAttribute("class", resolvePaginationClass(dataCmsComponent));
2084
+ el.appendChild(paginationNav);
2085
+ return paginationNav;
2086
+ }
2087
+ function ensurePaginationNavFallback(doc, paginationNav, dataCmsComponent) {
2088
+ if (paginationNav.children.length)
2089
+ return;
2090
+ const pageBtnClass = resolvePaginationPageBtnClass(dataCmsComponent);
2091
+ const useLoopGridIcons = isLoopGridPaginationNav(paginationNav);
2092
+ const labels = ["1", "2", "3"];
2093
+ labels.forEach((label, index) => {
2094
+ const item = doc.createElement("span");
2095
+ item.setAttribute("class", `${pageBtnClass}${index === 0 ? " active" : ""}`);
2096
+ item.textContent = label;
2097
+ paginationNav.appendChild(item);
2098
+ });
2099
+ const next = doc.createElement("span");
2100
+ next.setAttribute("class", pageBtnClass);
2101
+ next.setAttribute("aria-label", "下一页");
2102
+ if (useLoopGridIcons) {
2103
+ next.innerHTML = LOOP_GRID_NEXT_ICON;
2104
+ } else {
2105
+ next.textContent = "下一页 »";
2106
+ }
2107
+ paginationNav.appendChild(next);
2108
+ }
2109
+ function ensurePostListRootStructure(doc, el, dataCmsComponent) {
2110
+ if (dataCmsComponent !== "post-list" && dataCmsComponent !== "cases-list")
2111
+ return null;
2112
+ const classList = new Set(
2113
+ String(el.getAttribute("class") || "").split(/\s+/).filter(Boolean).filter(
2114
+ (className) => !["wb-post-list-grid", "wb-cases-list-grid", "wb-cases-list__grid"].includes(className)
2115
+ )
2116
+ );
2117
+ classList.add("wb-post-list");
2118
+ if (dataCmsComponent === "cases-list")
2119
+ classList.add("wb-cases-list");
2120
+ else
2121
+ classList.delete("wb-cases-list");
2122
+ el.setAttribute("class", Array.from(classList).join(" "));
2123
+ let grid = el.querySelector(
2124
+ "[data-wb-post-grid], .wb-post-list__grid, .wb-cases-list__grid"
2125
+ );
2126
+ if (!grid) {
2127
+ grid = doc.createElement("div");
2128
+ grid.setAttribute("data-wb-post-grid", "");
2129
+ grid.setAttribute("class", "wb-post-list__grid");
2130
+ } else {
2131
+ const gridClasses = new Set(
2132
+ String(grid.getAttribute("class") || "").split(/\s+/).filter(Boolean)
2133
+ );
2134
+ gridClasses.delete("wb-cases-list__grid");
2135
+ gridClasses.delete("wb-post-list-grid");
2136
+ gridClasses.delete("wb-cases-list-grid");
2137
+ gridClasses.add(
2138
+ dataCmsComponent === "cases-list" ? "wb-cases-list__grid" : "wb-post-list__grid"
2139
+ );
2140
+ grid.setAttribute("data-wb-post-grid", "");
2141
+ grid.setAttribute("class", Array.from(gridClasses).join(" "));
2142
+ }
2143
+ const paginationNav = el.querySelector("nav[data-cms-pagination]");
2144
+ const scriptAnchor = el.querySelector(
2145
+ "script[data-post-list-card-template], script[data-wb-product-card-template], script.cms-card-tpl"
2146
+ );
2147
+ if (grid.parentElement !== el) {
2148
+ if (paginationNav)
2149
+ el.insertBefore(grid, paginationNav);
2150
+ else if (scriptAnchor)
2151
+ el.insertBefore(grid, scriptAnchor);
2152
+ else
2153
+ el.appendChild(grid);
2154
+ } else if (paginationNav && grid.compareDocumentPosition(paginationNav) & Node.DOCUMENT_POSITION_PRECEDING) {
2155
+ el.insertBefore(grid, paginationNav);
2156
+ } else if (!paginationNav && scriptAnchor && grid.compareDocumentPosition(scriptAnchor) & Node.DOCUMENT_POSITION_PRECEDING) {
2157
+ el.insertBefore(grid, scriptAnchor);
2158
+ }
2159
+ Array.from(el.children).forEach((child) => {
2160
+ if (child === grid)
2161
+ return;
2162
+ const childEl = child;
2163
+ if (childEl.getAttribute("data-cms-repeat") === "post" || childEl.classList.contains("wb-post-card")) {
2164
+ grid == null ? void 0 : grid.appendChild(childEl);
2165
+ }
2166
+ });
2167
+ return grid;
2168
+ }
2169
+ const PAGINATION_TRAITS = [
2170
+ { type: "number", label: "每页数量", name: "cmsPageSize", changeProp: true, min: 1, max: 50 },
2171
+ {
2172
+ type: "select",
2173
+ label: "分页模式",
2174
+ name: "cmsPagination",
2175
+ changeProp: true,
2176
+ options: [
2177
+ { value: "static", label: "静态分页(SEO 最佳)" },
2178
+ { value: "loadmore", label: "加载更多" },
2179
+ { value: "none", label: "不分页" }
2180
+ ]
2181
+ },
2182
+ { type: "number", label: "最大页数", name: "cmsMaxPages", changeProp: true, min: 1, max: 100 }
2183
+ ];
2184
+ const PAGINATION_PROPS = { cmsPageSize: 12, cmsPagination: "static", cmsMaxPages: 10 };
2185
+ const PAGINATION_ATTRS = {
2186
+ "data-page-size": "12",
2187
+ "data-pagination": "static",
2188
+ "data-max-pages": "10"
2189
+ };
2190
+ function syncPaginationAttrs(model) {
2191
+ return {
2192
+ "data-page-size": String(model.get("cmsPageSize") || 12),
2193
+ "data-pagination": model.get("cmsPagination") || "static",
2194
+ "data-max-pages": String(model.get("cmsMaxPages") || 10)
2195
+ };
2196
+ }
2197
+ const VOID_TAGS = /* @__PURE__ */ new Set([
2198
+ "img",
2199
+ "br",
2200
+ "hr",
2201
+ "input",
2202
+ "meta",
2203
+ "link",
2204
+ "area",
2205
+ "base",
2206
+ "col",
2207
+ "embed",
2208
+ "source",
2209
+ "track",
2210
+ "wbr"
2211
+ ]);
2212
+ function componentsToHtml(defs) {
2213
+ if (!defs || defs.length === 0)
2214
+ return "";
2215
+ return defs.map((def) => {
2216
+ if (typeof def === "string")
2217
+ return def;
2218
+ const tag = def.tagName || "div";
2219
+ const attrs = { ...def.attributes || {} };
2220
+ if (!attrs.style && def.style && typeof def.style === "object") {
2221
+ attrs.style = Object.entries(def.style).map(([k2, v2]) => `${k2}:${v2}`).join(";");
2222
+ }
2223
+ const attrStr = Object.entries(attrs).filter(([_2, v2]) => v2 !== void 0 && v2 !== null).map(([k2, v2]) => `${k2}="${String(v2).replace(/"/g, "&quot;")}"`).join(" ");
2224
+ if (VOID_TAGS.has(tag)) {
2225
+ return `<${tag}${attrStr ? " " + attrStr : ""} />`;
2226
+ }
2227
+ const content = def.content || "";
2228
+ let children = def.components;
2229
+ if (attrs["data-cms-repeat"] && Array.isArray(children) && children.length > 1) {
2230
+ children = [children[0]];
2231
+ }
2232
+ const childrenHtml = children ? componentsToHtml(children) : "";
2233
+ return `<${tag}${attrStr ? " " + attrStr : ""}>${content}${childrenHtml}</${tag}>`;
2234
+ }).join("\n");
2235
+ }
2236
+ function buildRuntimeCardTemplate(cardEl) {
2237
+ const cardClone = cardEl.cloneNode(true);
2238
+ cardClone.removeAttribute("data-cms-repeat");
2239
+ cardClone.removeAttribute("id");
2240
+ cardClone.querySelectorAll("[id]").forEach((el) => el.removeAttribute("id"));
2241
+ cardClone.querySelectorAll("[data-cms-bind][data-cms-format]").forEach((bindEl) => {
2242
+ const field = bindEl.getAttribute("data-cms-bind") || "";
2243
+ const format = bindEl.getAttribute("data-cms-format") || "";
2244
+ bindEl.textContent = field ? `{{@format:${field}:${format}}}` : "";
2245
+ bindEl.removeAttribute("data-cms-bind");
2246
+ bindEl.removeAttribute("data-cms-format");
2247
+ });
2248
+ cardClone.querySelectorAll("[data-cms-bind]").forEach((bindEl) => {
2249
+ const field = bindEl.getAttribute("data-cms-bind") || "";
2250
+ bindEl.textContent = field ? `{{${field}}}` : "";
2251
+ bindEl.removeAttribute("data-cms-bind");
2252
+ });
2253
+ cardClone.querySelectorAll("[data-cms-bind-src]").forEach((bindEl) => {
2254
+ const field = bindEl.getAttribute("data-cms-bind-src") || "";
2255
+ bindEl.setAttribute("src", field ? `{{${field}}}` : "");
2256
+ bindEl.removeAttribute("data-cms-bind-src");
2257
+ });
2258
+ cardClone.querySelectorAll("[data-cms-bind-alt]").forEach((bindEl) => {
2259
+ const field = bindEl.getAttribute("data-cms-bind-alt") || "";
2260
+ bindEl.setAttribute("alt", field ? `{{${field}}}` : "");
2261
+ bindEl.removeAttribute("data-cms-bind-alt");
2262
+ });
2263
+ cardClone.querySelectorAll("[data-cms-bind-href]").forEach((bindEl) => {
2264
+ const field = bindEl.getAttribute("data-cms-bind-href") || "";
2265
+ const template = bindEl.getAttribute("data-cms-bind-href-template") || "";
2266
+ bindEl.setAttribute("href", field ? composePlaceholderUrl(field, template) : "#");
2267
+ bindEl.removeAttribute("data-cms-bind-href");
2268
+ bindEl.removeAttribute("data-cms-bind-href-template");
2269
+ });
2270
+ cardClone.querySelectorAll("[data-cms-bind-target]").forEach((bindEl) => {
2271
+ const field = bindEl.getAttribute("data-cms-bind-target") || "";
2272
+ if (field)
2273
+ bindEl.setAttribute("target", `{{${field}}}`);
2274
+ else
2275
+ bindEl.removeAttribute("target");
2276
+ bindEl.removeAttribute("data-cms-bind-target");
2277
+ });
2278
+ cardClone.querySelectorAll("[data-cms-bind-style]").forEach((bindEl) => {
2279
+ const field = bindEl.getAttribute("data-cms-bind-style") || "";
2280
+ if (field)
2281
+ bindEl.setAttribute("style", `{{${field}}}`);
2282
+ else
2283
+ bindEl.removeAttribute("style");
2284
+ bindEl.removeAttribute("data-cms-bind-style");
2285
+ });
2286
+ cardClone.querySelectorAll("[data-cms-html]").forEach((bindEl) => {
2287
+ const field = bindEl.getAttribute("data-cms-html") || "";
2288
+ bindEl.innerHTML = field ? `{{${field}}}` : "";
2289
+ bindEl.removeAttribute("data-cms-html");
2290
+ });
2291
+ return cardClone.outerHTML;
2292
+ }
2293
+ function buildPostListTagFilterIIFE(config) {
2294
+ const runtimeConfig = JSON.stringify({
2295
+ pageSize: config.pageSize,
2296
+ categoryId: config.categoryId,
2297
+ postPageEndpoint: config.postPageEndpoint,
2298
+ postTagListEndpoint: config.postTagListEndpoint,
2299
+ postTagListAllEndpoint: config.postTagListAllEndpoint,
2300
+ requestHeaderName: config.requestConfig.headerName,
2301
+ requestHeaderValue: config.requestConfig.headerValue,
2302
+ selectionMode: config.selectionMode || "single-all"
2303
+ });
2304
+ return `
2305
+ (function(){
2306
+ var cfg = ${runtimeConfig};
2307
+ var comp = document.currentScript.parentElement;
2308
+ var filterBar = comp.querySelector('[data-post-list-tag-filter]');
2309
+ var cardTplEl = comp.querySelector('script[data-post-list-card-template]');
2310
+ var paginationEl = comp.querySelector('.wb-post-list-pagination');
2311
+ var listEl = comp.querySelector('[data-wb-post-grid], .wb-cases-list__grid, .wb-post-list__grid') || comp;
2312
+ if (!filterBar || !cardTplEl) return;
2313
+
2314
+ var pageSize = parseInt(cfg.pageSize || '12', 10) || 12;
2315
+ var selectionMode = String(cfg.selectionMode || 'single-all').toLowerCase() === 'multi-none' ? 'multi-none' : 'single-all';
2316
+ var resolvedCategoryId = resolveCategoryId();
2317
+ var resolvedLegacyTypeId = resolveLegacyTypeId();
2318
+ var currentTagId = '';
2319
+ var selectedTagIds = [];
2320
+ var currentPage = 1;
2321
+ var staticCardsHtml = collectCardHtml();
2322
+ var staticPaginationHtml = paginationEl ? paginationEl.innerHTML : '';
2323
+ var staticPaginationDisplay = paginationEl ? (paginationEl.style.display || '') : '';
2324
+ var tplHtml = cardTplEl.textContent || cardTplEl.innerHTML || '';
2325
+
2326
+ fetchTags();
2327
+
2328
+ function fetchTags() {
2329
+ fetchTagList(true)
2330
+ .then(function(list){
2331
+ if (list.length || resolvedCategoryId || !resolvedLegacyTypeId) return list;
2332
+ return fetchTagList(false);
2333
+ })
2334
+ .then(function(list){
2335
+ if (list.length || resolvedCategoryId) return list;
2336
+ return fetchTagList('all');
2337
+ })
2338
+ .then(function(list){
2339
+ if (!list.length) {
2340
+ if (filterBar.children.length) {
2341
+ filterBar.classList.add('is-active');
2342
+ return;
2343
+ }
2344
+ filterBar.remove();
2345
+ return;
2346
+ }
2347
+ renderTagButtons(list);
2348
+ filterBar.classList.add('is-active');
2349
+ })
2350
+ .catch(function(){
2351
+ if (filterBar.children.length) {
2352
+ filterBar.classList.add('is-active');
2353
+ return;
2354
+ }
2355
+ filterBar.remove();
2356
+ });
2357
+ }
2358
+
2359
+ function fetchTagList(useTypeId) {
2360
+ var path = useTypeId === 'all' ? cfg.postTagListAllEndpoint : cfg.postTagListEndpoint;
2361
+ if (!path) return Promise.resolve([]);
2362
+ var params = new URLSearchParams();
2363
+ if (useTypeId === true) {
2364
+ if (resolvedCategoryId) params.set('categoryId', String(resolvedCategoryId));
2365
+ else if (resolvedLegacyTypeId) params.set('typeId', String(resolvedLegacyTypeId));
2366
+ }
2367
+ var qs = params.toString() ? ('?' + params.toString()) : '';
2368
+ return fetch(path + qs, { headers: buildHeaders() })
2369
+ .then(function(res){ return res.json(); })
2370
+ .then(function(json){
2371
+ return Array.isArray(json && json.data) ? json.data : [];
2372
+ });
2373
+ }
2374
+
2375
+ function renderTagButtons(tags) {
2376
+ var normalizedTags = tags.map(function(tag){
2377
+ return {
2378
+ id: tag && tag.id != null ? String(tag.id) : '',
2379
+ name: String((tag && tag.name) || '').trim(),
2380
+ };
2381
+ }).filter(function(tag){ return tag.id && tag.name; });
2382
+
2383
+ if (selectionMode === 'multi-none') {
2384
+ if (!normalizedTags.length) {
2385
+ filterBar.remove();
2386
+ return;
2387
+ }
2388
+ filterBar.innerHTML = normalizedTags.map(function(tag){
2389
+ return '<label class="wb-post-list-tag-check" data-tag-id="' + escAttr(tag.id) + '">'
2390
+ + '<span class="wb-post-list-tag-text">' + escHtml(tag.name) + '</span>'
2391
+ + '<input type="checkbox" class="wb-post-list-tag-checkbox" data-tag-id="' + escAttr(tag.id) + '" />'
2392
+ + '</label>';
2393
+ }).join('');
2394
+
2395
+ Array.prototype.forEach.call(filterBar.querySelectorAll('.wb-post-list-tag-checkbox[data-tag-id]'), function(input){
2396
+ input.addEventListener('change', function(){
2397
+ selectedTagIds = collectSelectedTagIds();
2398
+ syncSelectedTag();
2399
+ if (!selectedTagIds.length) {
2400
+ restoreBaseContent();
2401
+ return;
2402
+ }
2403
+ fetchPosts(1);
2404
+ });
2405
+ });
2406
+ syncSelectedTag();
2407
+ return;
2408
+ }
2409
+
2410
+ var items = [{ id: '', name: 'ALL' }].concat(normalizedTags);
2411
+ filterBar.innerHTML = items.map(function(tag){
2412
+ var cls = 'wb-post-list-tag-btn' + (!tag.id ? ' is-selected' : '');
2413
+ return '<button type="button" class="' + cls + '" data-tag-id="' + escAttr(tag.id) + '">' + escHtml(tag.name) + '</button>';
2414
+ }).join('');
2415
+
2416
+ Array.prototype.forEach.call(filterBar.querySelectorAll('[data-tag-id]'), function(btn){
2417
+ btn.addEventListener('click', function(){
2418
+ var nextTagId = String(btn.getAttribute('data-tag-id') || '');
2419
+ if (nextTagId === currentTagId) return;
2420
+ currentTagId = nextTagId;
2421
+ syncSelectedTag();
2422
+ if (!currentTagId) {
2423
+ restoreBaseContent();
2424
+ return;
2425
+ }
2426
+ fetchPosts(1);
2427
+ });
2428
+ });
2429
+ }
2430
+
2431
+ function syncSelectedTag() {
2432
+ if (selectionMode === 'multi-none') {
2433
+ var selectedMap = {};
2434
+ selectedTagIds.forEach(function(tagId){ selectedMap[String(tagId)] = true; });
2435
+ Array.prototype.forEach.call(filterBar.querySelectorAll('.wb-post-list-tag-check[data-tag-id]'), function(label){
2436
+ var tagId = String(label.getAttribute('data-tag-id') || '');
2437
+ var selected = !!selectedMap[tagId];
2438
+ label.classList.toggle('is-selected', selected);
2439
+ });
2440
+ Array.prototype.forEach.call(filterBar.querySelectorAll('.wb-post-list-tag-checkbox[data-tag-id]'), function(input){
2441
+ var tagId = String(input.getAttribute('data-tag-id') || '');
2442
+ input.checked = !!selectedMap[tagId];
2443
+ });
2444
+ return;
2445
+ }
2446
+
2447
+ Array.prototype.forEach.call(filterBar.querySelectorAll('.wb-post-list-tag-btn'), function(btn){
2448
+ var isSelected = String(btn.getAttribute('data-tag-id') || '') === currentTagId;
2449
+ btn.classList.toggle('is-selected', isSelected);
2450
+ });
2451
+ }
2452
+
2453
+ function collectSelectedTagIds() {
2454
+ return Array.prototype.slice.call(filterBar.querySelectorAll('.wb-post-list-tag-checkbox[data-tag-id]:checked'))
2455
+ .map(function(input){ return String(input.getAttribute('data-tag-id') || ''); })
2456
+ .filter(Boolean);
2457
+ }
2458
+
2459
+ function restoreStaticContent() {
2460
+ clearDynamicCards();
2461
+ insertHtml(staticCardsHtml);
2462
+ if (paginationEl) {
2463
+ paginationEl.innerHTML = staticPaginationHtml;
2464
+ paginationEl.style.display = staticPaginationDisplay;
2465
+ }
2466
+ currentPage = 1;
2467
+ }
2468
+
2469
+ function restoreBaseContent() {
2470
+ if (resolvedCategoryId || resolvedLegacyTypeId) {
2471
+ fetchPosts(1);
2472
+ return;
2473
+ }
2474
+ restoreStaticContent();
2475
+ }
2476
+
2477
+ function fetchPosts(pageNo) {
2478
+ currentPage = pageNo;
2479
+ renderStatus('Loading...');
2480
+ if (paginationEl) {
2481
+ paginationEl.style.display = 'none';
2482
+ paginationEl.innerHTML = '';
2483
+ }
2484
+
2485
+ var params = new URLSearchParams();
2486
+ params.set('pageNo', String(pageNo));
2487
+ params.set('pageSize', String(pageSize));
2488
+ if (resolvedCategoryId) params.set('categoryId', String(resolvedCategoryId));
2489
+ if (resolvedLegacyTypeId) params.set('typeId', String(resolvedLegacyTypeId));
2490
+ if (selectionMode === 'multi-none') {
2491
+ if (selectedTagIds.length) params.set('tagIds', selectedTagIds.join(','));
2492
+ } else if (currentTagId) {
2493
+ params.set('tagIds', String(currentTagId));
2494
+ }
2495
+ var lang = resolveLanguage();
2496
+ if (lang) params.set('language', lang);
2497
+
2498
+ if (!cfg.postPageEndpoint) {
2499
+ renderStatus('Dynamic article endpoint is not configured.');
2500
+ return;
2501
+ }
2502
+ fetch(cfg.postPageEndpoint + '?' + params.toString(), { headers: buildHeaders() })
2503
+ .then(function(res){ return res.json(); })
2504
+ .then(function(json){
2505
+ var data = json && json.data;
2506
+ var list = Array.isArray(data && data.list) ? data.list : [];
2507
+ var total = Number(data && data.total) || 0;
2508
+ renderPostList(list);
2509
+ renderPagination(total);
2510
+ })
2511
+ .catch(function(){
2512
+ renderStatus('Failed to load articles.');
2513
+ });
2514
+ }
2515
+
2516
+ function renderPostList(list) {
2517
+ clearDynamicCards();
2518
+ if (!Array.isArray(list) || !list.length) {
2519
+ renderStatus('No articles found.');
2520
+ return;
2521
+ }
2522
+ insertHtml(list.map(function(item){ return renderCard(item); }).join(''));
2523
+ }
2524
+
2525
+ function renderPagination(total) {
2526
+ if (!paginationEl) return;
2527
+ var totalPages = Math.ceil((Number(total) || 0) / pageSize);
2528
+ if (totalPages <= 1) {
2529
+ if (staticPaginationHtml) {
2530
+ paginationEl.innerHTML = staticPaginationHtml;
2531
+ paginationEl.style.display = staticPaginationDisplay;
2532
+ } else {
2533
+ paginationEl.style.display = 'none';
2534
+ paginationEl.innerHTML = '';
2535
+ }
2536
+ return;
2537
+ }
2538
+
2539
+ var html = '';
2540
+ if (currentPage > 1) {
2541
+ html += '<button type="button" class="wb-post-list-page-btn" data-page-no="' + (currentPage - 1) + '" aria-label="上一页">${LOOP_GRID_PREV_ICON}</button>';
2542
+ }
2543
+ for (var page = 1; page <= totalPages; page++) {
2544
+ var activeCls = page === currentPage ? ' active' : '';
2545
+ html += '<button type="button" class="wb-post-list-page-btn' + activeCls + '" data-page-no="' + page + '">' + page + '</button>';
2546
+ }
2547
+ if (currentPage < totalPages) {
2548
+ html += '<button type="button" class="wb-post-list-page-btn" data-page-no="' + (currentPage + 1) + '" aria-label="下一页">${LOOP_GRID_NEXT_ICON}</button>';
2549
+ }
2550
+
2551
+ paginationEl.innerHTML = html;
2552
+ paginationEl.style.display = '';
2553
+ Array.prototype.forEach.call(paginationEl.querySelectorAll('[data-page-no]'), function(btn){
2554
+ btn.addEventListener('click', function(){
2555
+ var pageNo = parseInt(btn.getAttribute('data-page-no') || '1', 10) || 1;
2556
+ if (pageNo === currentPage) return;
2557
+ fetchPosts(pageNo);
2558
+ });
2559
+ });
2560
+ }
2561
+
2562
+ function renderCard(item) {
2563
+ var data = {
2564
+ 'post.name': String(item && item.name || ''),
2565
+ 'post.image': String(item && item.image || ''),
2566
+ 'post.excerpt': String(item && item.excerpt || ''),
2567
+ 'post.publishTime': item && item.publishTime != null ? item.publishTime : '',
2568
+ 'post.url': resolvePostUrl(item),
2569
+ 'post.categoryIds': item && item.categoryIds || [],
2570
+ 'post.categoryNames': item && item.categoryNames || [],
2571
+ 'post.tagIds': item && item.tagIds || [],
2572
+ 'post.tagNames': item && item.tagNames || []
2573
+ };
2574
+ return renderTemplate(tplHtml, data);
2575
+ }
2576
+
2577
+ function resolvePostUrl(item) {
2578
+ var content = item && item.contents && item.contents[0] || {};
2579
+ var explicitUrl = normalizePostHref(
2580
+ item && (item.url || item.postUrl || item.detailUrl || item.link)
2581
+ || (content && (content.url || content.postUrl || content.detailUrl || content.link))
2582
+ || ''
2583
+ );
2584
+ if (explicitUrl) return explicitUrl;
2585
+ var slug = String(item && item.slug || '').trim();
2586
+ var typeCode = String(item && item.typeCode || '').trim();
2587
+ if (!slug || !typeCode) return '#';
2588
+ var lang = resolveLanguage();
2589
+ return '/' + lang + '/post/' + encodeURIComponent(typeCode) + '/' + encodeURIComponent(slug) + '.html';
2590
+ }
2591
+
2592
+ function normalizePostHref(rawValue) {
2593
+ var value = String(rawValue || '').trim();
2594
+ if (!value) return '';
2595
+ if (
2596
+ value.charAt(0) === '/'
2597
+ || value.charAt(0) === '#'
2598
+ || /^mailto:/i.test(value)
2599
+ || /^tel:/i.test(value)
2600
+ || /^https?:///i.test(value)
2601
+ || value.indexOf('//') === 0
2602
+ ) {
2603
+ return value;
2604
+ }
2605
+ if (value.indexOf('./') === 0) value = value.slice(2);
2606
+ return '/' + value;
2607
+ }
2608
+
2609
+ function renderTemplate(template, data) {
2610
+ return String(template || '')
2611
+ .replace(/\\{\\{@format:([^:}]+):([^}]+)\\}\\}/g, function(_, field, format){
2612
+ return escHtml(formatDate(data[field], format));
2613
+ })
2614
+ .replace(/\\{\\{([^}]+)\\}\\}/g, function(_, field){
2615
+ return escHtml(data[field] == null ? '' : String(data[field]));
2616
+ });
2617
+ }
2618
+
2619
+ function formatDate(value, format) {
2620
+ if (value == null || value === '') return '';
2621
+ var date = null;
2622
+ if (Array.isArray(value) && value.length >= 3) {
2623
+ date = new Date(Number(value[0]), Number(value[1]) - 1, Number(value[2]), Number(value[3] || 0), Number(value[4] || 0), Number(value[5] || 0));
2624
+ } else if (typeof value === 'string' || typeof value === 'number') {
2625
+ date = new Date(value);
2626
+ }
2627
+ if (!date || isNaN(date.getTime())) return String(value);
2628
+ var parts = {
2629
+ yyyy: String(date.getFullYear()),
2630
+ MM: ('0' + (date.getMonth() + 1)).slice(-2),
2631
+ dd: ('0' + date.getDate()).slice(-2),
2632
+ HH: ('0' + date.getHours()).slice(-2),
2633
+ mm: ('0' + date.getMinutes()).slice(-2),
2634
+ ss: ('0' + date.getSeconds()).slice(-2),
2635
+ };
2636
+ return String(format || 'yyyy-MM-dd').replace(/yyyy|MM|dd|HH|mm|ss/g, function(token){
2637
+ return parts[token] || token;
2638
+ });
2639
+ }
2640
+
2641
+ function renderStatus(message) {
2642
+ clearDynamicCards();
2643
+ insertHtml('<div class="wb-post-list-empty">' + escHtml(message) + '</div>');
2644
+ }
2645
+
2646
+ function clearDynamicCards() {
2647
+ Array.prototype.slice.call(listEl.children).forEach(function(child){
2648
+ if (!child || !child.classList) return;
2649
+ if (child.classList.contains('wb-post-card') || child.classList.contains('wb-post-list-empty')) {
2650
+ child.remove();
2651
+ }
2652
+ });
2653
+ }
2654
+
2655
+ function collectCardHtml() {
2656
+ return Array.prototype.slice.call(listEl.children)
2657
+ .filter(function(child){ return child && child.classList && child.classList.contains('wb-post-card'); })
2658
+ .map(function(child){ return child.outerHTML; })
2659
+ .join('');
2660
+ }
2661
+
2662
+ function insertHtml(html) {
2663
+ if (!html) return;
2664
+ listEl.insertAdjacentHTML('beforeend', html);
2665
+ }
2666
+
2667
+ function buildHeaders() {
2668
+ var headers = {};
2669
+ if (cfg.requestHeaderName && cfg.requestHeaderValue) {
2670
+ headers[cfg.requestHeaderName] = String(cfg.requestHeaderValue);
2671
+ }
2672
+ return headers;
2673
+ }
2674
+
2675
+ function resolveCategoryId() {
2676
+ try {
2677
+ var url = new URL(window.location.href);
2678
+ var override = String(url.searchParams.get('categoryId') || '').trim();
2679
+ if (override) return override;
2680
+ } catch (_) {
2681
+ // noop
2682
+ }
2683
+ return String(cfg.categoryId || '').trim();
2684
+ }
2685
+
2686
+ function resolveLegacyTypeId() {
2687
+ try {
2688
+ var url = new URL(window.location.href);
2689
+ var override = String(url.searchParams.get('typeId') || '').trim();
2690
+ if (override) return override;
2691
+ } catch (_) {
2692
+ // noop
2693
+ }
2694
+ return '';
2695
+ }
2696
+
2697
+ function resolveLanguage() {
2698
+ var attrLang = String(document.documentElement.getAttribute('lang') || '').trim();
2699
+ if (attrLang) return attrLang;
2700
+ var seg = String((window.location.pathname || '/').split('/').filter(Boolean)[0] || '').trim();
2701
+ return /^[a-z]{2}(?:-[a-z]{2})?$/i.test(seg) ? seg : 'en';
2702
+ }
2703
+
2704
+ function escHtml(value) {
2705
+ return String(value == null ? '' : value)
2706
+ .replace(/&/g, '&amp;')
2707
+ .replace(/</g, '&lt;')
2708
+ .replace(/>/g, '&gt;')
2709
+ .replace(/"/g, '&quot;')
2710
+ .replace(/'/g, '&#39;');
2711
+ }
2712
+
2713
+ function escAttr(value) {
2714
+ return escHtml(value).replace(/\`/g, '&#96;');
2715
+ }
2716
+ })();`;
2717
+ }
2718
+ function buildCategoryQueryOverrideIIFE(config) {
2719
+ const runtimeConfig = JSON.stringify({
2720
+ endpoint: config.endpoint,
2721
+ paramKey: config.paramKey,
2722
+ entity: config.entity,
2723
+ pageSize: config.pageSize,
2724
+ requestHeaderName: config.requestConfig.headerName,
2725
+ requestHeaderValue: config.requestConfig.headerValue,
2726
+ includeLanguage: Boolean(config.includeLanguage),
2727
+ initialValue: config.initialValue
2728
+ });
2729
+ const transformFn = CMS_TRANSFORM_FN[config.entity];
2730
+ return `
2731
+ (function(){
2732
+ var cfg = ${runtimeConfig};
2733
+ var transform = ${transformFn};
2734
+ var comp = document.currentScript.parentElement;
2735
+ var tplEl = comp.querySelector('script[data-wb-category-query-template]');
2736
+ if (!tplEl) return;
2737
+
2738
+ var activeValue = readActiveValue();
2739
+ if (!activeValue || activeValue === String(cfg.initialValue || '').trim()) return;
2740
+
2741
+ var pageSize = parseInt(cfg.pageSize || '12', 10) || 12;
2742
+ var listEl = cfg.entity === 'media'
2743
+ ? (comp.querySelector('[data-cms-repeat="media"]') || comp)
2744
+ : (comp.querySelector('[data-wb-post-grid], .wb-cases-list__grid, .wb-post-list__grid') || comp);
2745
+ var paginationEl = comp.querySelector('nav[data-cms-pagination], .wb-post-list-pagination');
2746
+ var currentPage = readCurrentPage();
2747
+ fetchPage(currentPage);
2748
+
2749
+ function readActiveValue() {
2750
+ try {
2751
+ var url = new URL(window.location.href);
2752
+ return String(url.searchParams.get(cfg.paramKey) || '').trim();
2753
+ } catch (_) {
2754
+ return '';
2755
+ }
2756
+ }
2757
+
2758
+ function readCurrentPage() {
2759
+ try {
2760
+ var url = new URL(window.location.href);
2761
+ var raw = url.searchParams.get('page') || url.searchParams.get('pageNo') || '1';
2762
+ var page = parseInt(raw, 10);
2763
+ return Number.isFinite(page) && page > 0 ? page : 1;
2764
+ } catch (_) {
2765
+ return 1;
2766
+ }
2767
+ }
2768
+
2769
+ function buildPageHref(page) {
2770
+ try {
2771
+ var url = new URL(window.location.href);
2772
+ if (page <= 1) {
2773
+ url.searchParams.delete('page');
2774
+ url.searchParams.delete('pageNo');
2775
+ } else {
2776
+ url.searchParams.set('page', String(page));
2777
+ url.searchParams.delete('pageNo');
2778
+ }
2779
+ return url.pathname + url.search + url.hash;
2780
+ } catch (_) {
2781
+ return page > 1 ? ('?page=' + page) : (window.location.pathname || '#');
2782
+ }
2783
+ }
2784
+
2785
+ function syncPageUrl(page, mode) {
2786
+ try {
2787
+ var href = buildPageHref(page);
2788
+ var method = mode === 'push' ? 'pushState' : 'replaceState';
2789
+ window.history && window.history[method] && window.history[method](null, '', href);
2790
+ } catch (_) {
2791
+ // noop
2792
+ }
2793
+ }
2794
+
2795
+ function fetchPage(page) {
2796
+ currentPage = page;
2797
+ renderStatus('Loading...');
2798
+ if (paginationEl) {
2799
+ paginationEl.innerHTML = '';
2800
+ paginationEl.style.display = 'none';
2801
+ }
2802
+
2803
+ var params = new URLSearchParams();
2804
+ params.set('pageNo', String(page));
2805
+ params.set('pageSize', String(pageSize));
2806
+ params.set(cfg.paramKey, activeValue);
2807
+ var lang = resolveLanguage();
2808
+ if (lang && cfg.includeLanguage) {
2809
+ params.set('language', lang);
2810
+ }
2811
+
2812
+ if (!cfg.endpoint) {
2813
+ renderStatus('Dynamic content endpoint is not configured.');
2814
+ return;
2815
+ }
2816
+
2817
+ fetch(cfg.endpoint + '?' + params.toString(), { headers: buildHeaders() })
2818
+ .then(function(res){ return res.json(); })
2819
+ .then(function(json){
2820
+ var data = json && json.data;
2821
+ var list = Array.isArray(data && data.list) ? data.list : [];
2822
+ var total = Number(data && data.total) || 0;
2823
+ renderList(list);
2824
+ renderPagination(total);
2825
+ })
2826
+ .catch(function(){
2827
+ renderStatus('Failed to load content.');
2828
+ });
2829
+ }
2830
+
2831
+ function renderList(list) {
2832
+ if (!Array.isArray(list) || !list.length) {
2833
+ renderStatus('No content found.');
2834
+ return;
2835
+ }
2836
+ listEl.innerHTML = list.map(function(item){
2837
+ return renderTemplate(tplEl.textContent || tplEl.innerHTML || '', transform(item));
2838
+ }).join('');
2839
+ }
2840
+
2841
+ function renderPagination(total) {
2842
+ if (!paginationEl) return;
2843
+ var totalPages = Math.ceil((Number(total) || 0) / pageSize);
2844
+ if (totalPages <= 1) {
2845
+ paginationEl.innerHTML = '';
2846
+ paginationEl.style.display = 'none';
2847
+ syncPageUrl(1, 'replace');
2848
+ return;
2849
+ }
2850
+
2851
+ var html = '';
2852
+ if (currentPage > 1) {
2853
+ html += '<button type="button" class="wb-post-list-page-btn" data-page-no="' + (currentPage - 1) + '" aria-label="上一页">${LOOP_GRID_PREV_ICON}</button>';
2854
+ }
2855
+ for (var page = 1; page <= totalPages; page++) {
2856
+ var activeCls = page === currentPage ? ' active' : '';
2857
+ html += '<button type="button" class="wb-post-list-page-btn' + activeCls + '" data-page-no="' + page + '">' + page + '</button>';
2858
+ }
2859
+ if (currentPage < totalPages) {
2860
+ html += '<button type="button" class="wb-post-list-page-btn" data-page-no="' + (currentPage + 1) + '" aria-label="下一页">${LOOP_GRID_NEXT_ICON}</button>';
2861
+ }
2862
+
2863
+ paginationEl.innerHTML = html;
2864
+ paginationEl.style.display = '';
2865
+ Array.prototype.forEach.call(paginationEl.querySelectorAll('[data-page-no]'), function(btn){
2866
+ btn.addEventListener('click', function(){
2867
+ var pageNo = parseInt(btn.getAttribute('data-page-no') || '1', 10) || 1;
2868
+ if (pageNo === currentPage) return;
2869
+ syncPageUrl(pageNo, 'push');
2870
+ fetchPage(pageNo);
2871
+ });
2872
+ });
2873
+ syncPageUrl(currentPage, 'replace');
2874
+ }
2875
+
2876
+ function renderTemplate(template, data) {
2877
+ return String(template || '')
2878
+ .replace(/\\{\\{@format:([^:}]+):([^}]+)\\}\\}/g, function(_, field, format){
2879
+ return escHtml(formatDate(data[field], format));
2880
+ })
2881
+ .replace(/\\{\\{([^}]+)\\}\\}/g, function(_, field){
2882
+ return escHtml(data[field] == null ? '' : String(data[field]));
2883
+ });
2884
+ }
2885
+
2886
+ function formatDate(value, format) {
2887
+ if (value == null || value === '') return '';
2888
+ var date = null;
2889
+ if (Array.isArray(value) && value.length >= 3) {
2890
+ date = new Date(Number(value[0]), Number(value[1]) - 1, Number(value[2]), Number(value[3] || 0), Number(value[4] || 0), Number(value[5] || 0));
2891
+ } else if (typeof value === 'string' || typeof value === 'number') {
2892
+ date = new Date(value);
2893
+ }
2894
+ if (!date || isNaN(date.getTime())) return String(value);
2895
+ var parts = {
2896
+ yyyy: String(date.getFullYear()),
2897
+ MM: ('0' + (date.getMonth() + 1)).slice(-2),
2898
+ dd: ('0' + date.getDate()).slice(-2),
2899
+ HH: ('0' + date.getHours()).slice(-2),
2900
+ mm: ('0' + date.getMinutes()).slice(-2),
2901
+ ss: ('0' + date.getSeconds()).slice(-2),
2902
+ };
2903
+ return String(format || 'yyyy-MM-dd').replace(/yyyy|MM|dd|HH|mm|ss/g, function(token){
2904
+ return parts[token] || token;
2905
+ });
2906
+ }
2907
+
2908
+ function renderStatus(message) {
2909
+ listEl.innerHTML = '<div class="wb-post-list-empty">' + escHtml(message) + '</div>';
2910
+ }
2911
+
2912
+ function buildHeaders() {
2913
+ var headers = {};
2914
+ if (cfg.requestHeaderName && cfg.requestHeaderValue) {
2915
+ headers[cfg.requestHeaderName] = String(cfg.requestHeaderValue);
2916
+ }
2917
+ return headers;
2918
+ }
2919
+
2920
+ function resolveLanguage() {
2921
+ var attrLang = String(document.documentElement.getAttribute('lang') || '').trim();
2922
+ if (attrLang) return attrLang;
2923
+ var seg = String((window.location.pathname || '/').split('/').filter(Boolean)[0] || '').trim();
2924
+ return /^[a-z]{2}(?:-[a-z]{2})?$/i.test(seg) ? seg : 'en';
2925
+ }
2926
+
2927
+ function escHtml(value) {
2928
+ return String(value == null ? '' : value)
2929
+ .replace(/&/g, '&amp;')
2930
+ .replace(/</g, '&lt;')
2931
+ .replace(/>/g, '&gt;')
2932
+ .replace(/"/g, '&quot;')
2933
+ .replace(/'/g, '&#39;');
2934
+ }
2935
+ })();`;
2936
+ }
2937
+ function buildSearchIIFE(endpoint, requestConfig) {
2938
+ const runtimeConfig = JSON.stringify({
2939
+ endpoint,
2940
+ requestHeaderName: requestConfig.headerName,
2941
+ requestHeaderValue: requestConfig.headerValue
2942
+ });
2943
+ return `
2944
+ (function(){
2945
+ var cfg = ${runtimeConfig};
2946
+ var PAGE_SIZE = 20;
2947
+ var currentPage = 1;
2948
+ var currentKeyword = '';
2949
+ var comp = document.currentScript.parentElement;
2950
+ var qInput = comp.querySelector('.cms-search-q');
2951
+ var btn = comp.querySelector('.cms-search-submit');
2952
+ var statsEl = comp.querySelector('.cms-search-stats');
2953
+ var resultsEl = comp.querySelector('.cms-search-results');
2954
+ var pagEl = comp.querySelector('.cms-search-pagination');
2955
+ if (!qInput || !btn || !resultsEl) return;
2956
+
2957
+ var LANG = resolveLanguage();
2958
+ btn.onclick = function(){ doSearch(1); };
2959
+ qInput.addEventListener('keydown', function(e){ if(e.key==='Enter') doSearch(1); });
2960
+ hydrateFromUrl();
2961
+
2962
+ function resolveLanguage() {
2963
+ var attrLang = (document.documentElement.getAttribute('data-language') || '').trim();
2964
+ if (attrLang) return attrLang;
2965
+ var htmlLang = (document.documentElement.lang || '').trim();
2966
+ if (htmlLang) return htmlLang;
2967
+ var seg = (location.pathname.split('/')[1] || '').trim();
2968
+ return /^[a-z]{2}(?:[-_][a-z]{2})?$/i.test(seg) ? seg : '';
2969
+ }
2970
+
2971
+ function hydrateFromUrl() {
2972
+ try {
2973
+ var params = new URLSearchParams(window.location.search || '');
2974
+ var initialKeyword = (params.get('q') || '').trim();
2975
+ if (!initialKeyword) return;
2976
+ qInput.value = initialKeyword;
2977
+ doSearch(1, { syncUrl: false });
2978
+ } catch (e) {
2979
+ console.warn('[wb-cms-search] failed to read query params', e);
2980
+ }
2981
+ }
2982
+
2983
+ function syncUrl(kw) {
2984
+ try {
2985
+ var url = new URL(window.location.href);
2986
+ if (kw) url.searchParams.set('q', kw);
2987
+ else url.searchParams.delete('q');
2988
+ window.history.replaceState({}, '', url.toString());
2989
+ } catch (e) {
2990
+ console.warn('[wb-cms-search] failed to sync query params', e);
2991
+ }
2992
+ }
2993
+
2994
+ function doSearch(pageNo, options) {
2995
+ options = options || {};
2996
+ var kw = qInput.value.trim();
2997
+ if (!kw) return;
2998
+ currentKeyword = kw;
2999
+ currentPage = pageNo;
3000
+ if (options.syncUrl !== false && pageNo === 1) syncUrl(kw);
3001
+ resultsEl.innerHTML = '<div style="text-align:center;padding:24px;color:#6b7280;">Searching...</div>';
3002
+ if (statsEl) statsEl.textContent = '';
3003
+ if (pagEl) pagEl.innerHTML = '';
3004
+
3005
+ var qs = 'keyword=' + encodeURIComponent(kw)
3006
+ + '&pageNo=' + pageNo + '&pageSize=' + PAGE_SIZE;
3007
+ if (LANG) qs += '&language=' + encodeURIComponent(LANG);
3008
+ if (!cfg.endpoint) { showError(); return; }
3009
+ fetch(cfg.endpoint + '?' + qs, { headers: buildHeaders() })
3010
+ .then(function(r){ return r.json(); })
3011
+ .then(function(json){
3012
+ if (json.code !== 0 || !json.data) { showError(); return; }
3013
+ var list = json.data.list || [];
3014
+ var total = json.data.total || 0;
3015
+ if (list.length === 0) { showNoResults(); return; }
3016
+ if (statsEl) statsEl.textContent = total + ' results found';
3017
+ resultsEl.innerHTML = list.map(function(item){ return renderCard(item); }).join('');
3018
+ var totalPages = Math.ceil(total / PAGE_SIZE);
3019
+ if (totalPages > 1 && pagEl) renderPagination(totalPages);
3020
+ })
3021
+ .catch(function(e){ console.error(e); showError(); });
3022
+ }
3023
+
3024
+ function buildHeaders() {
3025
+ var headers = {};
3026
+ if (cfg.requestHeaderName && cfg.requestHeaderValue) {
3027
+ headers[cfg.requestHeaderName] = String(cfg.requestHeaderValue);
3028
+ }
3029
+ return headers;
3030
+ }
3031
+
3032
+ function showNoResults() {
3033
+ resultsEl.innerHTML = '<div style="text-align:center;padding:24px;color:#9ca3af;">No results found.</div>';
3034
+ if (statsEl) statsEl.textContent = '0 results found';
3035
+ }
3036
+ function showError() {
3037
+ resultsEl.innerHTML = '<div style="text-align:center;padding:24px;color:#9ca3af;">Search failed, please try again.</div>';
3038
+ }
3039
+
3040
+ function renderCard(item) {
3041
+ var typeLabel = { post:'Article', product:'Product', media:'Media' };
3042
+ var typeBg = { post:'#dbeafe', product:'#dcfce7', media:'#fef3c7' };
3043
+ var typeColor = { post:'#1d4ed8', product:'#15803d', media:'#b45309' };
3044
+ var img = item.image ? '<img style="width:100px;aspect-ratio:1;;object-fit:contain;border-radius:6px;flex-shrink:0;background:#f3f4f6;" src="' + esc(item.image) + '" alt="" />' : '';
3045
+ var time = formatTime(item.publishTime);
3046
+ var timeHtml = time ? '<div style="font-size:12px;color:#9ca3af;margin-top:4px;">' + time + '</div>' : '';
3047
+ var title = highlight(esc(item.title || ''));
3048
+ var desc = highlight(esc(item.description || ''));
3049
+ return '<div style="background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:12px;">'
3050
+ + '<a href="' + esc(item.url || '#') + '" style="text-decoration:none;color:inherit;display:flex;gap:12px;">'
3051
+ + img
3052
+ + '<div style="flex:1;min-width:0;">'
3053
+ + '<span style="display:inline-block;font-size:11px;font-weight:600;text-transform:uppercase;padding:2px 8px;border-radius:4px;margin-bottom:4px;background:' + (typeBg[item.type]||'#f3f4f6') + ';color:' + (typeColor[item.type]||'#374151') + ';">' + (typeLabel[item.type]||esc(item.type)) + '</span>'
3054
+ + '<div style="font-size:15px;font-weight:600;margin-bottom:2px;">' + title + '</div>'
3055
+ + '<div style="font-size:13px;color:#6b7280;line-height:1.5;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;">' + desc + '</div>'
3056
+ + timeHtml
3057
+ + '</div></a></div>';
3058
+ }
3059
+
3060
+ function formatTime(t) {
3061
+ if (!t) return '';
3062
+ if (typeof t === 'number') {
3063
+ var d = new Date(t);
3064
+ return d.getFullYear() + '-' + ('0'+(d.getMonth()+1)).slice(-2) + '-' + ('0'+d.getDate()).slice(-2);
3065
+ }
3066
+ if (Array.isArray(t)) { return t[0]+'-'+('0'+t[1]).slice(-2)+'-'+('0'+t[2]).slice(-2); }
3067
+ if (typeof t === 'string') return t.substring(0,10);
3068
+ return '';
3069
+ }
3070
+
3071
+ function highlight(text) {
3072
+ if (!currentKeyword || !text) return text;
3073
+ var re = new RegExp('(' + escRe(currentKeyword) + ')', 'gi');
3074
+ return text.replace(re, '<span style="color:#dc2626;font-weight:700;">$1</span>');
3075
+ }
3076
+ function escRe(s) { return s.replace(new RegExp('[.*+?^$' + '{}()|\\\\[\\\\]\\\\\\\\]', 'g'), '\\\\$&'); }
3077
+
3078
+ function renderPagination(totalPages) {
3079
+ var prevDis = currentPage <= 1 ? ' disabled' : '';
3080
+ var nextDis = currentPage >= totalPages ? ' disabled' : '';
3081
+ var btnStyle = 'padding:6px 14px;border:1px solid #d1d5db;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;';
3082
+ pagEl.innerHTML = '<button class="cms-search-prev" style="' + btnStyle + '"' + prevDis + '>Prev</button>'
3083
+ + '<span style="padding:6px 10px;font-size:13px;color:#6b7280;">' + currentPage + ' / ' + totalPages + '</span>'
3084
+ + '<button class="cms-search-next" style="' + btnStyle + '"' + nextDis + '>Next</button>';
3085
+ var prevBtn = pagEl.querySelector('.cms-search-prev');
3086
+ var nextBtn = pagEl.querySelector('.cms-search-next');
3087
+ if (prevBtn) prevBtn.onclick = function(){ doSearch(currentPage - 1); };
3088
+ if (nextBtn) nextBtn.onclick = function(){ doSearch(currentPage + 1); };
3089
+ }
3090
+
3091
+ function esc(s) { var d=document.createElement('div'); d.textContent=s; return d.innerHTML; }
3092
+ })();`;
3093
+ }
3094
+ const cmsTypeRegistry = /* @__PURE__ */ new Map();
3095
+ function registerCmsTypeEntry(entry) {
3096
+ cmsTypeRegistry.set(entry.dataCmsComponent, entry);
3097
+ }
3098
+ function getCmsAttributesCallback() {
3099
+ return (component, attrs) => {
3100
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
3101
+ if (!attrs["data-cms-component"] && !attrs["data-wb-component"])
3102
+ return attrs;
3103
+ try {
3104
+ (_a = component == null ? void 0 : component._syncAttrs) == null ? void 0 : _a.call(component);
3105
+ } catch {
3106
+ }
3107
+ const latestAttrs = ((_b = component == null ? void 0 : component.getAttributes) == null ? void 0 : _b.call(component)) || attrs;
3108
+ const result = { ...attrs, ...latestAttrs };
3109
+ if (result["data-wb-component"] === "cms-cases-list") {
3110
+ result["data-cms-component"] = "cases-list";
3111
+ }
3112
+ if (result["data-wb-component"] && !result["data-cms-component"]) {
3113
+ for (const entry of cmsTypeRegistry.values()) {
3114
+ if (entry.dataWbComponent === result["data-wb-component"]) {
3115
+ result["data-cms-component"] = entry.dataCmsComponent;
3116
+ break;
3117
+ }
3118
+ }
3119
+ }
3120
+ if (result["data-cms-component"] === "product-list") {
3121
+ const categoryId = String(
3122
+ ((_c = component == null ? void 0 : component.get) == null ? void 0 : _c.call(component, "cmsCategoryId")) ?? result["data-category-id"] ?? result["data-wb-category-id"] ?? ""
3123
+ ).trim();
3124
+ const sortField = String(
3125
+ ((_d = component == null ? void 0 : component.get) == null ? void 0 : _d.call(component, "cmsSortField")) ?? result["data-sort-field"] ?? result["data-wb-sort-field"] ?? "createTime"
3126
+ ).trim() || "createTime";
3127
+ const sortAsc = String(
3128
+ ((_e = component == null ? void 0 : component.get) == null ? void 0 : _e.call(component, "cmsSortAsc")) ?? result["data-sort-asc"] ?? result["data-wb-sort-asc"] ?? "false"
3129
+ ).trim() || "false";
3130
+ const pageSize = String(
3131
+ ((_f = component == null ? void 0 : component.get) == null ? void 0 : _f.call(component, "cmsPageSize")) ?? result["data-page-size"] ?? result["data-wb-page-size"] ?? "12"
3132
+ ).trim() || "12";
3133
+ const pagination = String(
3134
+ ((_g = component == null ? void 0 : component.get) == null ? void 0 : _g.call(component, "cmsPagination")) ?? result["data-pagination"] ?? result["data-wb-pagination"] ?? "static"
3135
+ ).trim() || "static";
3136
+ const maxPages = String(
3137
+ ((_h = component == null ? void 0 : component.get) == null ? void 0 : _h.call(component, "cmsMaxPages")) ?? result["data-max-pages"] ?? result["data-wb-max-pages"] ?? "10"
3138
+ ).trim() || "10";
3139
+ const listMode = String(
3140
+ ((_i = component == null ? void 0 : component.get) == null ? void 0 : _i.call(component, "cmsListMode")) ?? result["data-list-mode"] ?? result["data-wb-list-mode"] ?? "grid"
3141
+ ).trim() || "grid";
3142
+ const loadAll = listMode === "datasheet" || result["data-load-all"] === "true" || result["data-wb-load-all"] === "true" ? "true" : "false";
3143
+ result["data-category-id"] = categoryId;
3144
+ result["data-wb-category-id"] = categoryId;
3145
+ result["data-sort-field"] = sortField;
3146
+ result["data-wb-sort-field"] = sortField;
3147
+ result["data-sort-asc"] = sortAsc;
3148
+ result["data-wb-sort-asc"] = sortAsc;
3149
+ result["data-page-size"] = loadAll === "true" ? "9999" : pageSize;
3150
+ result["data-wb-page-size"] = loadAll === "true" ? "9999" : pageSize;
3151
+ result["data-pagination"] = loadAll === "true" ? "none" : pagination;
3152
+ result["data-wb-pagination"] = loadAll === "true" ? "none" : pagination;
3153
+ result["data-max-pages"] = loadAll === "true" ? "1" : maxPages;
3154
+ result["data-wb-max-pages"] = loadAll === "true" ? "1" : maxPages;
3155
+ result["data-list-mode"] = listMode;
3156
+ result["data-wb-list-mode"] = listMode;
3157
+ result["data-load-all"] = loadAll;
3158
+ result["data-wb-load-all"] = loadAll;
3159
+ }
3160
+ if (result["data-cms-component"] === "faq-section") {
3161
+ const categoryId = String(
3162
+ ((_j = component == null ? void 0 : component.get) == null ? void 0 : _j.call(component, "cmsCategoryId")) ?? result["data-category-id"] ?? result["data-wb-category-id"] ?? ""
3163
+ ).trim();
3164
+ const limit = String(
3165
+ ((_k = component == null ? void 0 : component.get) == null ? void 0 : _k.call(component, "cmsLimit")) ?? result["data-limit"] ?? result["data-wb-limit"] ?? "6"
3166
+ ).trim() || "6";
3167
+ result["data-category-id"] = categoryId;
3168
+ result["data-wb-category-id"] = categoryId;
3169
+ result["data-limit"] = limit;
3170
+ result["data-wb-limit"] = limit;
3171
+ }
3172
+ if (result["data-cms-component"] === "post-list" || result["data-cms-component"] === "cases-list") {
3173
+ const isCasesList = result["data-cms-component"] === "cases-list";
3174
+ const categoryId = String(
3175
+ ((_l = component == null ? void 0 : component.get) == null ? void 0 : _l.call(component, "cmsCategoryId")) ?? result["data-category-id"] ?? result["data-wb-category-id"] ?? ""
3176
+ ).trim();
3177
+ const enableTagFilter = isTruthyFlag((_m = component == null ? void 0 : component.get) == null ? void 0 : _m.call(component, "cmsEnableTagFilter")) || isTruthyFlag(result["data-enable-tag-filter"]) || isTruthyFlag(result["data-enable-tag"]) ? "true" : "false";
3178
+ const pageSize = String(
3179
+ ((_n = component == null ? void 0 : component.get) == null ? void 0 : _n.call(component, "cmsPageSize")) ?? result["data-page-size"] ?? result["data-wb-page-size"] ?? "12"
3180
+ ).trim() || "12";
3181
+ const pagination = String(
3182
+ ((_o = component == null ? void 0 : component.get) == null ? void 0 : _o.call(component, "cmsPagination")) ?? result["data-pagination"] ?? result["data-wb-pagination"] ?? "static"
3183
+ ).trim() || "static";
3184
+ const maxPages = String(
3185
+ ((_p = component == null ? void 0 : component.get) == null ? void 0 : _p.call(component, "cmsMaxPages")) ?? result["data-max-pages"] ?? result["data-wb-max-pages"] ?? "10"
3186
+ ).trim() || "10";
3187
+ const typeCode = String(
3188
+ ((_q = component == null ? void 0 : component.get) == null ? void 0 : _q.call(component, "cmsTypeCode")) ?? result["data-type-code"] ?? result["data-post-type-code"] ?? ""
3189
+ ).trim();
3190
+ const selectionModeRaw = String(
3191
+ result["data-tag-selection-mode"] ?? result["data-tag-filter-mode"] ?? result["data-tag-mode"] ?? ""
3192
+ ).trim().toLowerCase();
3193
+ const selectionMode = selectionModeRaw === "multi-none" ? "multi-none" : isCasesList ? "multi-none" : "single-all";
3194
+ result["data-category-id"] = categoryId;
3195
+ result["data-wb-category-id"] = categoryId;
3196
+ result["data-enable-tag-filter"] = enableTagFilter;
3197
+ result["data-tag-selection-mode"] = selectionMode;
3198
+ result["data-page-size"] = pageSize;
3199
+ result["data-wb-page-size"] = pageSize;
3200
+ result["data-pagination"] = pagination;
3201
+ result["data-wb-pagination"] = pagination;
3202
+ result["data-max-pages"] = maxPages;
3203
+ result["data-wb-max-pages"] = maxPages;
3204
+ result["data-type-code"] = typeCode;
3205
+ }
3206
+ if (hasLoopGridSignature(result)) {
3207
+ cleanupLoopGridExportAttrsRecord(result);
3208
+ }
3209
+ delete result["data-wb-component"];
3210
+ return result;
3211
+ };
3212
+ }
3213
+ function fixCmsComponentsHtml(htmlStr, editor) {
3214
+ var _a, _b, _c, _d;
3215
+ if (!htmlStr || !editor)
3216
+ return htmlStr;
3217
+ const cmsModels = [];
3218
+ function walk(component) {
3219
+ var _a2, _b2, _c2, _d2, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
3220
+ const attrs = ((_a2 = component.getAttributes) == null ? void 0 : _a2.call(component)) || {};
3221
+ const cmsComp = attrs["data-wb-component"] === "cms-cases-list" ? "cases-list" : attrs["data-cms-component"] || "";
3222
+ if (cmsComp && (cmsTypeRegistry.has(cmsComp) || cmsComp === "loop-grid")) {
3223
+ try {
3224
+ (_b2 = component == null ? void 0 : component._syncAttrs) == null ? void 0 : _b2.call(component);
3225
+ } catch {
3226
+ }
3227
+ const syncedAttrs = ((_c2 = component.getAttributes) == null ? void 0 : _c2.call(component)) || attrs;
3228
+ const id = ((_d2 = component.getId) == null ? void 0 : _d2.call(component)) || ((_e = component.get) == null ? void 0 : _e.call(component, "id")) || "";
3229
+ const instanceId = String(
3230
+ syncedAttrs["data-wb-instance-id"] || ((_f = component.getId) == null ? void 0 : _f.call(component)) || component.cid || ""
3231
+ ).trim();
3232
+ const isLoopGrid = hasLoopGridSignature(syncedAttrs);
3233
+ const publishHtml = isLoopGrid ? String(((_g = component.getInnerHTML) == null ? void 0 : _g.call(component)) || "") : "";
3234
+ cmsModels.push({
3235
+ id,
3236
+ dataCmsComponent: cmsComp,
3237
+ instanceId,
3238
+ isLoopGrid,
3239
+ publishHtml,
3240
+ attributes: { ...syncedAttrs },
3241
+ props: {
3242
+ cmsCategoryId: String(((_h = component.get) == null ? void 0 : _h.call(component, "cmsCategoryId")) ?? "").trim(),
3243
+ cmsEnableTagFilter: String(((_i = component.get) == null ? void 0 : _i.call(component, "cmsEnableTagFilter")) ?? "").trim(),
3244
+ cmsLimit: String(((_j = component.get) == null ? void 0 : _j.call(component, "cmsLimit")) ?? "").trim(),
3245
+ cmsSortField: String(((_k = component.get) == null ? void 0 : _k.call(component, "cmsSortField")) ?? "").trim(),
3246
+ cmsSortAsc: String(((_l = component.get) == null ? void 0 : _l.call(component, "cmsSortAsc")) ?? "").trim(),
3247
+ cmsPageSize: String(((_m = component.get) == null ? void 0 : _m.call(component, "cmsPageSize")) ?? "").trim(),
3248
+ cmsPagination: String(((_n = component.get) == null ? void 0 : _n.call(component, "cmsPagination")) ?? "").trim(),
3249
+ cmsMaxPages: String(((_o = component.get) == null ? void 0 : _o.call(component, "cmsMaxPages")) ?? "").trim(),
3250
+ cmsListMode: String(((_p = component.get) == null ? void 0 : _p.call(component, "cmsListMode")) ?? "").trim(),
3251
+ cmsTypeCode: String(((_q = component.get) == null ? void 0 : _q.call(component, "cmsTypeCode")) ?? "").trim()
3252
+ }
3253
+ });
3254
+ }
3255
+ const children = (_r = component.components) == null ? void 0 : _r.call(component);
3256
+ if (children && children.length) {
3257
+ children.forEach((child) => walk(child));
3258
+ }
3259
+ }
3260
+ const pages = ((_b = (_a = editor.Pages) == null ? void 0 : _a.getAll) == null ? void 0 : _b.call(_a)) || [];
3261
+ if (pages.length > 0) {
3262
+ pages.forEach((page) => {
3263
+ var _a2;
3264
+ const main = (_a2 = page.getMainComponent) == null ? void 0 : _a2.call(page);
3265
+ if (main)
3266
+ walk(main);
3267
+ });
3268
+ } else {
3269
+ const wrapper = (_d = (_c = editor.DomComponents) == null ? void 0 : _c.getWrapper) == null ? void 0 : _d.call(_c);
3270
+ if (wrapper)
3271
+ walk(wrapper);
3272
+ }
3273
+ const parser = new DOMParser();
3274
+ const doc = parser.parseFromString(htmlStr, "text/html");
3275
+ const cmsModelTypeCounts = cmsModels.reduce((acc, item) => {
3276
+ acc[item.dataCmsComponent] = (acc[item.dataCmsComponent] || 0) + 1;
3277
+ return acc;
3278
+ }, {});
3279
+ const docCmsTypeCounts = Array.from(doc.querySelectorAll("[data-cms-component]")).reduce((acc, el) => {
3280
+ const type = String(el.getAttribute("data-cms-component") || "").trim();
3281
+ if (!type)
3282
+ return acc;
3283
+ acc[type] = (acc[type] || 0) + 1;
3284
+ return acc;
3285
+ }, {});
3286
+ cmsModels.forEach(
3287
+ ({ id, dataCmsComponent, instanceId, isLoopGrid, publishHtml, attributes, props }) => {
3288
+ var _a2;
3289
+ const entry = cmsTypeRegistry.get(dataCmsComponent);
3290
+ if (!entry && dataCmsComponent !== "loop-grid")
3291
+ return;
3292
+ let el = null;
3293
+ if (id)
3294
+ el = doc.getElementById(id);
3295
+ if (!el && instanceId) {
3296
+ el = doc.querySelector(`[data-wb-instance-id="${CSS.escape(instanceId)}"]`);
3297
+ }
3298
+ if (!el && cmsModelTypeCounts[dataCmsComponent] === 1 && docCmsTypeCounts[dataCmsComponent] === 1) {
3299
+ el = doc.querySelector(`[data-cms-component="${dataCmsComponent}"]`);
3300
+ }
3301
+ if (!el && cmsModelTypeCounts[dataCmsComponent] === 1 && entry) {
3302
+ el = doc.querySelector(`[data-wb-component="${entry.dataWbComponent}"]`);
3303
+ }
3304
+ if (!el && dataCmsComponent === "loop-grid" && cmsModelTypeCounts[dataCmsComponent] === 1) {
3305
+ el = doc.querySelector(
3306
+ '[data-wb-component="loop-grid"], .wb-loop-grid, [data-wb-loop-grid-schema]'
3307
+ );
3308
+ }
3309
+ if (!el && dataCmsComponent === "loop-grid" && cmsModelTypeCounts[dataCmsComponent] === 1) {
3310
+ const paginationOnly = doc.querySelector(".wb-loop-grid-pagination");
3311
+ if (paginationOnly) {
3312
+ const wrapper = doc.createElement("div");
3313
+ wrapper.setAttribute("class", "wb-loop-grid");
3314
+ paginationOnly.replaceWith(wrapper);
3315
+ wrapper.appendChild(paginationOnly);
3316
+ el = wrapper;
3317
+ }
3318
+ }
3319
+ if (!el)
3320
+ return;
3321
+ const mergedAttributes = { ...attributes, "data-cms-component": dataCmsComponent };
3322
+ if (dataCmsComponent === "product-list") {
3323
+ const categoryId = props.cmsCategoryId || mergedAttributes["data-category-id"] || mergedAttributes["data-wb-category-id"] || "";
3324
+ const sortField = props.cmsSortField || mergedAttributes["data-sort-field"] || mergedAttributes["data-wb-sort-field"] || "createTime";
3325
+ const sortAsc = props.cmsSortAsc || mergedAttributes["data-sort-asc"] || mergedAttributes["data-wb-sort-asc"] || "false";
3326
+ const pageSize = props.cmsPageSize || mergedAttributes["data-page-size"] || mergedAttributes["data-wb-page-size"] || "12";
3327
+ const pagination = props.cmsPagination || mergedAttributes["data-pagination"] || mergedAttributes["data-wb-pagination"] || "static";
3328
+ const maxPages = props.cmsMaxPages || mergedAttributes["data-max-pages"] || mergedAttributes["data-wb-max-pages"] || "10";
3329
+ const listMode = props.cmsListMode || mergedAttributes["data-list-mode"] || mergedAttributes["data-wb-list-mode"] || "grid";
3330
+ const loadAll = listMode === "datasheet" || mergedAttributes["data-load-all"] === "true" || mergedAttributes["data-wb-load-all"] === "true" ? "true" : "false";
3331
+ mergedAttributes["data-category-id"] = categoryId;
3332
+ mergedAttributes["data-wb-category-id"] = categoryId;
3333
+ mergedAttributes["data-sort-field"] = sortField;
3334
+ mergedAttributes["data-wb-sort-field"] = sortField;
3335
+ mergedAttributes["data-sort-asc"] = sortAsc;
3336
+ mergedAttributes["data-wb-sort-asc"] = sortAsc;
3337
+ mergedAttributes["data-page-size"] = loadAll === "true" ? "9999" : pageSize;
3338
+ mergedAttributes["data-wb-page-size"] = loadAll === "true" ? "9999" : pageSize;
3339
+ mergedAttributes["data-pagination"] = loadAll === "true" ? "none" : pagination;
3340
+ mergedAttributes["data-wb-pagination"] = loadAll === "true" ? "none" : pagination;
3341
+ mergedAttributes["data-max-pages"] = loadAll === "true" ? "1" : maxPages;
3342
+ mergedAttributes["data-wb-max-pages"] = loadAll === "true" ? "1" : maxPages;
3343
+ mergedAttributes["data-list-mode"] = listMode;
3344
+ mergedAttributes["data-wb-list-mode"] = listMode;
3345
+ mergedAttributes["data-load-all"] = loadAll;
3346
+ mergedAttributes["data-wb-load-all"] = loadAll;
3347
+ }
3348
+ if (dataCmsComponent === "faq-section") {
3349
+ const categoryId = props.cmsCategoryId || mergedAttributes["data-category-id"] || mergedAttributes["data-wb-category-id"] || "";
3350
+ const limit = props.cmsLimit || mergedAttributes["data-limit"] || mergedAttributes["data-wb-limit"] || "6";
3351
+ mergedAttributes["data-category-id"] = categoryId;
3352
+ mergedAttributes["data-wb-category-id"] = categoryId;
3353
+ mergedAttributes["data-limit"] = limit;
3354
+ mergedAttributes["data-wb-limit"] = limit;
3355
+ }
3356
+ if (dataCmsComponent === "post-list" || dataCmsComponent === "cases-list") {
3357
+ const isCasesList = dataCmsComponent === "cases-list";
3358
+ const categoryId = props.cmsCategoryId || mergedAttributes["data-category-id"] || mergedAttributes["data-wb-category-id"] || "";
3359
+ const enableTagFilter = isTruthyFlag(props.cmsEnableTagFilter) || isTruthyFlag(mergedAttributes["data-enable-tag-filter"]) || isTruthyFlag(mergedAttributes["data-enable-tag"]) ? "true" : "false";
3360
+ const pageSize = props.cmsPageSize || mergedAttributes["data-page-size"] || mergedAttributes["data-wb-page-size"] || "12";
3361
+ const pagination = props.cmsPagination || mergedAttributes["data-pagination"] || mergedAttributes["data-wb-pagination"] || "static";
3362
+ const maxPages = props.cmsMaxPages || mergedAttributes["data-max-pages"] || mergedAttributes["data-wb-max-pages"] || "10";
3363
+ const typeCode = props.cmsTypeCode || mergedAttributes["data-type-code"] || mergedAttributes["data-post-type-code"] || "";
3364
+ const selectionModeRaw = String(
3365
+ mergedAttributes["data-tag-selection-mode"] || mergedAttributes["data-tag-filter-mode"] || mergedAttributes["data-tag-mode"] || ""
3366
+ ).trim().toLowerCase();
3367
+ const selectionMode = selectionModeRaw === "multi-none" ? "multi-none" : isCasesList ? "multi-none" : "single-all";
3368
+ mergedAttributes["data-category-id"] = categoryId;
3369
+ mergedAttributes["data-wb-category-id"] = categoryId;
3370
+ mergedAttributes["data-enable-tag-filter"] = enableTagFilter;
3371
+ mergedAttributes["data-tag-selection-mode"] = selectionMode;
3372
+ mergedAttributes["data-page-size"] = pageSize;
3373
+ mergedAttributes["data-wb-page-size"] = pageSize;
3374
+ mergedAttributes["data-pagination"] = pagination;
3375
+ mergedAttributes["data-wb-pagination"] = pagination;
3376
+ mergedAttributes["data-max-pages"] = maxPages;
3377
+ mergedAttributes["data-wb-max-pages"] = maxPages;
3378
+ mergedAttributes["data-type-code"] = typeCode;
3379
+ }
3380
+ for (const [key, value] of Object.entries(mergedAttributes)) {
3381
+ const keepEmptyAttr = key === "data-category-id";
3382
+ if (value !== void 0 && value !== null && (value !== "" || keepEmptyAttr)) {
3383
+ el.setAttribute(key, String(value));
3384
+ } else {
3385
+ el.removeAttribute(key);
3386
+ }
3387
+ }
3388
+ el.setAttribute("data-cms-component", dataCmsComponent);
3389
+ if (isLoopGrid && publishHtml) {
3390
+ el.innerHTML = publishHtml;
3391
+ }
3392
+ const postListGrid = ensurePostListRootStructure(doc, el, dataCmsComponent);
3393
+ if (dataCmsComponent === "product-list" || dataCmsComponent === "search") {
3394
+ const requestConfig = getRuntimeRequestConfig();
3395
+ if (requestConfig.headerName) {
3396
+ el.setAttribute("data-wb-request-header-name", requestConfig.headerName);
3397
+ }
3398
+ if (requestConfig.headerValue !== void 0 && requestConfig.headerValue !== null && requestConfig.headerValue !== "") {
3399
+ el.setAttribute("data-wb-request-header-value", String(requestConfig.headerValue));
3400
+ }
3401
+ if (dataCmsComponent === "product-list") {
3402
+ const runtimeTemplateEl = el.querySelector("script[data-wb-product-card-template]");
3403
+ const templateCard = el.querySelector('[data-cms-repeat="product"]');
3404
+ if (runtimeTemplateEl && templateCard) {
3405
+ runtimeTemplateEl.textContent = buildRuntimeCardTemplate(templateCard);
3406
+ }
3407
+ }
3408
+ }
3409
+ if (entry && !entry.dynamicPublish && !isLoopGrid) {
3410
+ el.innerHTML = entry.publishTemplate;
3411
+ }
3412
+ if (dataCmsComponent === "post-list" || dataCmsComponent === "cases-list") {
3413
+ const isCasesList = dataCmsComponent === "cases-list";
3414
+ const enableTagFilter = String(mergedAttributes["data-enable-tag-filter"] || "").trim() === "true";
3415
+ const existingFilterBar = el.querySelector("[data-post-list-tag-filter]");
3416
+ if (!enableTagFilter) {
3417
+ existingFilterBar == null ? void 0 : existingFilterBar.remove();
3418
+ } else {
3419
+ let filterBar = existingFilterBar;
3420
+ if (!filterBar) {
3421
+ filterBar = doc.createElement("div");
3422
+ filterBar.setAttribute("class", "wb-post-list-tag-filter");
3423
+ filterBar.setAttribute("data-post-list-tag-filter", "true");
3424
+ el.insertBefore(filterBar, el.firstChild);
3425
+ }
3426
+ const templateCard = (postListGrid == null ? void 0 : postListGrid.querySelector('[data-cms-repeat="post"]')) || el.querySelector(
3427
+ '[data-wb-post-grid] [data-cms-repeat="post"], .wb-cases-list__grid [data-cms-repeat="post"], .wb-post-list__grid [data-cms-repeat="post"]'
3428
+ ) || Array.from(el.children).find((child) => child.classList.contains("wb-post-card"));
3429
+ if (templateCard) {
3430
+ const tplScript = doc.createElement("script");
3431
+ tplScript.setAttribute("type", "text/html");
3432
+ tplScript.setAttribute("data-post-list-card-template", "true");
3433
+ tplScript.textContent = buildRuntimeCardTemplate(templateCard);
3434
+ el.appendChild(tplScript);
3435
+ const iifeScript = doc.createElement("script");
3436
+ iifeScript.textContent = buildPostListTagFilterIIFE({
3437
+ pageSize: String(mergedAttributes["data-page-size"] || "12"),
3438
+ categoryId: String(mergedAttributes["data-category-id"] || ""),
3439
+ postPageEndpoint: getRuntimeEndpoint("postPage"),
3440
+ postTagListEndpoint: getRuntimeEndpoint("postTagList"),
3441
+ postTagListAllEndpoint: getRuntimeEndpoint("postTagListAll"),
3442
+ requestConfig: getRuntimeRequestConfig(),
3443
+ selectionMode: String(
3444
+ mergedAttributes["data-tag-selection-mode"] || (isCasesList ? "multi-none" : "single-all")
3445
+ )
3446
+ });
3447
+ el.appendChild(iifeScript);
3448
+ }
3449
+ }
3450
+ }
3451
+ if (dataCmsComponent === "post-list" || dataCmsComponent === "cases-list" || dataCmsComponent === "media-list") {
3452
+ const loopItemType = String(mergedAttributes["data-loop-item-type"] || "").trim();
3453
+ const isCategoryLoop = ["postCategory", "mediaCategory"].includes(loopItemType);
3454
+ const queryTemplateCard = isCategoryLoop ? null : dataCmsComponent === "media-list" ? el.querySelector('.wb-cms-media-grid [data-cms-repeat="media"]') || el.querySelector('[data-cms-repeat="media"] > *') : (postListGrid == null ? void 0 : postListGrid.querySelector('[data-cms-repeat="post"]')) || el.querySelector(
3455
+ '[data-wb-post-grid] [data-cms-repeat="post"], .wb-cases-list__grid [data-cms-repeat="post"], .wb-post-list__grid [data-cms-repeat="post"]'
3456
+ ) || Array.from(el.children).find((child) => child.classList.contains("wb-post-card"));
3457
+ if (queryTemplateCard) {
3458
+ const tplScript = doc.createElement("script");
3459
+ tplScript.setAttribute("type", "text/html");
3460
+ tplScript.setAttribute("data-wb-category-query-template", "true");
3461
+ tplScript.textContent = buildRuntimeCardTemplate(queryTemplateCard);
3462
+ el.appendChild(tplScript);
3463
+ const iifeScript = doc.createElement("script");
3464
+ iifeScript.textContent = buildCategoryQueryOverrideIIFE({
3465
+ endpoint: dataCmsComponent === "media-list" ? getRuntimeEndpoint("mediaPage") : getRuntimeEndpoint("postPage"),
3466
+ paramKey: "categoryId",
3467
+ entity: dataCmsComponent === "media-list" ? "media" : "post",
3468
+ pageSize: String(mergedAttributes["data-page-size"] || "12"),
3469
+ requestConfig: getRuntimeRequestConfig(),
3470
+ includeLanguage: true,
3471
+ initialValue: String(mergedAttributes["data-category-id"] || "")
3472
+ });
3473
+ el.appendChild(iifeScript);
3474
+ }
3475
+ }
3476
+ if (dataCmsComponent === "search") {
3477
+ const iifeScript = doc.createElement("script");
3478
+ iifeScript.textContent = buildSearchIIFE(
3479
+ getRuntimeEndpoint("search"),
3480
+ getRuntimeRequestConfig()
3481
+ );
3482
+ el.appendChild(iifeScript);
3483
+ }
3484
+ const paginationMode = mergedAttributes["data-pagination"] || "static";
3485
+ const paginationNav = paginationMode === "static" ? ensurePaginationNavElement(doc, el, dataCmsComponent) : el.querySelector("nav[data-cms-pagination]");
3486
+ if (paginationMode === "none") {
3487
+ if (paginationNav)
3488
+ paginationNav.remove();
3489
+ } else if (paginationMode === "loadmore") {
3490
+ if (paginationNav)
3491
+ paginationNav.remove();
3492
+ const shouldUseLegacyLoadMore = dataCmsComponent !== "product-list";
3493
+ const apiInfo = shouldUseLegacyLoadMore ? CMS_RUNTIME_API_MAP[dataCmsComponent] : void 0;
3494
+ if (apiInfo) {
3495
+ const tplDoc = isLoopGrid ? null : new DOMParser().parseFromString((entry == null ? void 0 : entry.publishTemplate) || "", "text/html");
3496
+ const repeatContainer = isLoopGrid ? el.querySelector("[data-cms-repeat]") : tplDoc == null ? void 0 : tplDoc.querySelector("[data-cms-repeat]");
3497
+ const listGrid = isLoopGrid ? repeatContainer == null ? void 0 : repeatContainer.parentElement : repeatContainer;
3498
+ const gridClass = (listGrid == null ? void 0 : listGrid.getAttribute("class")) || "";
3499
+ const templateCard = isLoopGrid ? repeatContainer : (_a2 = repeatContainer == null ? void 0 : repeatContainer.children) == null ? void 0 : _a2[0];
3500
+ let cardTplHtml = "";
3501
+ if (templateCard) {
3502
+ const cardClone = templateCard.cloneNode(true);
3503
+ cardClone.removeAttribute("id");
3504
+ cardClone.querySelectorAll("[id]").forEach((el2) => el2.removeAttribute("id"));
3505
+ cardClone.querySelectorAll("[data-cms-bind]").forEach((bindEl) => {
3506
+ const field = bindEl.getAttribute("data-cms-bind") || "";
3507
+ bindEl.textContent = `{{${field}}}`;
3508
+ bindEl.removeAttribute("data-cms-bind");
3509
+ });
3510
+ cardClone.querySelectorAll("[data-cms-bind-src]").forEach((bindEl) => {
3511
+ const field = bindEl.getAttribute("data-cms-bind-src") || "";
3512
+ bindEl.setAttribute("src", `{{${field}}}`);
3513
+ bindEl.removeAttribute("data-cms-bind-src");
3514
+ });
3515
+ cardClone.querySelectorAll("[data-cms-bind-href]").forEach((bindEl) => {
3516
+ const field = bindEl.getAttribute("data-cms-bind-href") || "";
3517
+ const template = bindEl.getAttribute("data-cms-bind-href-template") || "";
3518
+ bindEl.setAttribute("href", composePlaceholderUrl(field, template));
3519
+ bindEl.removeAttribute("data-cms-bind-href");
3520
+ bindEl.removeAttribute("data-cms-bind-href-template");
3521
+ });
3522
+ cardTplHtml = cardClone.outerHTML;
3523
+ }
3524
+ const params = {};
3525
+ if (mergedAttributes["data-category-id"]) {
3526
+ params.categoryId = mergedAttributes["data-category-id"];
3527
+ }
3528
+ if (mergedAttributes["data-resource-type"]) {
3529
+ if (apiInfo.entity === "media")
3530
+ params.type = mergedAttributes["data-resource-type"];
3531
+ else
3532
+ params.resourceType = mergedAttributes["data-resource-type"];
3533
+ }
3534
+ if (mergedAttributes["data-sort-field"])
3535
+ params.sortingField = mergedAttributes["data-sort-field"];
3536
+ if (mergedAttributes["data-sort-asc"])
3537
+ params.asc = mergedAttributes["data-sort-asc"];
3538
+ const pageSize = mergedAttributes["data-page-size"] || "12";
3539
+ const transformFn = CMS_TRANSFORM_FN[apiInfo.entity] || "function transform(item){return item;}";
3540
+ const requestConfig = getRuntimeRequestConfig();
3541
+ const tplScript = doc.createElement("script");
3542
+ tplScript.setAttribute("type", "text/html");
3543
+ tplScript.setAttribute("class", "cms-card-tpl");
3544
+ tplScript.textContent = cardTplHtml;
3545
+ el.appendChild(tplScript);
3546
+ const loadMoreWrap = doc.createElement("div");
3547
+ loadMoreWrap.setAttribute("class", "cms-loadmore-wrap");
3548
+ loadMoreWrap.setAttribute("style", "text-align:center;padding:20px 0;");
3549
+ loadMoreWrap.innerHTML = '<button class="cms-loadmore-btn" style="padding:10px 32px;cursor:pointer;border:1px solid #ddd;background:#fff;border-radius:4px;font-size:14px;">Load More</button>';
3550
+ el.appendChild(loadMoreWrap);
3551
+ const iifeScript = doc.createElement("script");
3552
+ iifeScript.textContent = `
3553
+ (function(){
3554
+ var cfg = {
3555
+ endpoint: '${getRuntimeEndpoint(apiInfo.endpoint)}',
3556
+ pageSize: ${pageSize},
3557
+ params: ${JSON.stringify(params)},
3558
+ gridClass: '${gridClass.split(" ")[0]}',
3559
+ requestHeaderName: ${JSON.stringify(requestConfig.headerName)},
3560
+ requestHeaderValue: ${JSON.stringify(requestConfig.headerValue)}
3561
+ };
3562
+ var currentPage = 2;
3563
+ var comp = document.currentScript.parentElement;
3564
+ var grid = comp.querySelector('.' + cfg.gridClass);
3565
+ var tpl = comp.querySelector('script.cms-card-tpl');
3566
+ var wrap = comp.querySelector('.cms-loadmore-wrap');
3567
+ var btn = comp.querySelector('.cms-loadmore-btn');
3568
+ if (!grid || !tpl || !btn) return;
3569
+ var tplHtml = tpl.textContent || tpl.innerHTML;
3570
+ var language = resolveLanguage();
3571
+
3572
+ ${transformFn}
3573
+
3574
+ function resolveLanguage() {
3575
+ var attrLang = (document.documentElement.getAttribute('data-language') || '').trim();
3576
+ if (attrLang) return attrLang;
3577
+ var htmlLang = (document.documentElement.lang || '').trim();
3578
+ if (htmlLang) return htmlLang;
3579
+ var seg = (location.pathname.split('/')[1] || '').trim();
3580
+ return /^[a-z]{2}(?:[-_][a-z]{2})?$/i.test(seg) ? seg : '';
3581
+ }
3582
+
3583
+ function escHtml(value) {
3584
+ return String(value == null ? '' : value)
3585
+ .replace(/&/g, '&amp;')
3586
+ .replace(/</g, '&lt;')
3587
+ .replace(/>/g, '&gt;')
3588
+ .replace(/"/g, '&quot;')
3589
+ .replace(/'/g, '&#39;');
3590
+ }
3591
+
3592
+ // URL 字段不做 HTML 实体转义(仅用于 href/src 属性,已经过 encodeURIComponent 处理)
3593
+ var URL_FIELDS = { 'post.image': true, 'post.url': true, 'media.url': true, 'media.coverUrl': true, 'media.detailUrl': true, 'product.picUrl': true, 'product.url': true };
3594
+
3595
+
3596
+ function renderCard(item) {
3597
+ var d = transform(item);
3598
+ var html = tplHtml;
3599
+ for (var k in d) {
3600
+ var v = d[k] == null ? '' : d[k];
3601
+ html = html.split('{{' + k + '}}').join(URL_FIELDS[k] ? v : escHtml(v));
3602
+ }
3603
+ return html;
3604
+ }
3605
+
3606
+ btn.onclick = function() {
3607
+ btn.disabled = true;
3608
+ btn.textContent = 'Loading...';
3609
+ var qs = 'pageNo=' + currentPage + '&pageSize=' + cfg.pageSize;
3610
+ if (language) qs += '&language=' + encodeURIComponent(language);
3611
+ for (var k in cfg.params) {
3612
+ if (cfg.params[k]) qs += '&' + k + '=' + encodeURIComponent(cfg.params[k]);
3613
+ }
3614
+ if (!cfg.endpoint) return;
3615
+ fetch(cfg.endpoint + '?' + qs, { headers: buildHeaders() })
3616
+ .then(function(r){ return r.json(); })
3617
+ .then(function(json){
3618
+ var list = (json.data && json.data.list) || [];
3619
+ var total = (json.data && json.data.total) || 0;
3620
+ list.forEach(function(item){
3621
+ grid.insertAdjacentHTML('beforeend', renderCard(item));
3622
+ });
3623
+ currentPage++;
3624
+ btn.disabled = false;
3625
+ btn.textContent = 'Load More';
3626
+ if (currentPage * cfg.pageSize >= total + cfg.pageSize) {
3627
+ wrap.style.display = 'none';
3628
+ }
3629
+ })
3630
+ .catch(function(){
3631
+ btn.disabled = false;
3632
+ btn.textContent = 'Load More';
3633
+ });
3634
+ };
3635
+
3636
+ function buildHeaders() {
3637
+ var headers = {};
3638
+ if (cfg.requestHeaderName && cfg.requestHeaderValue) {
3639
+ headers[cfg.requestHeaderName] = String(cfg.requestHeaderValue);
3640
+ }
3641
+ return headers;
3642
+ }
3643
+ })();`;
3644
+ el.appendChild(iifeScript);
3645
+ }
3646
+ }
3647
+ if (paginationMode === "static" && paginationNav) {
3648
+ ensurePaginationNavFallback(doc, paginationNav, dataCmsComponent);
3649
+ }
3650
+ el.removeAttribute("data-wb-component");
3651
+ if (isLoopGrid) {
3652
+ cleanupLoopGridExportAttrsElement(el);
3653
+ }
3654
+ }
3655
+ );
3656
+ doc.querySelectorAll("[data-wb-component]").forEach((el) => {
3657
+ var _a2;
3658
+ const wbComp = el.getAttribute("data-wb-component") || "";
3659
+ for (const entry of cmsTypeRegistry.values()) {
3660
+ if (entry.dataWbComponent === wbComp) {
3661
+ const existingCmsComponent = el.getAttribute("data-cms-component") || "";
3662
+ const effectiveCmsComponent = cmsTypeRegistry.has(existingCmsComponent) ? existingCmsComponent : entry.dataCmsComponent;
3663
+ el.setAttribute("data-cms-component", effectiveCmsComponent);
3664
+ if (effectiveCmsComponent === "product-list" || effectiveCmsComponent === "search") {
3665
+ const requestConfig = getRuntimeRequestConfig();
3666
+ if (requestConfig.headerName) {
3667
+ el.setAttribute("data-wb-request-header-name", requestConfig.headerName);
3668
+ }
3669
+ if (requestConfig.headerValue !== "") {
3670
+ el.setAttribute("data-wb-request-header-value", String(requestConfig.headerValue));
3671
+ }
3672
+ if (effectiveCmsComponent === "product-list") {
3673
+ const runtimeTemplateEl = el.querySelector("script[data-wb-product-card-template]");
3674
+ const templateCard = el.querySelector('[data-cms-repeat="product"]');
3675
+ if (runtimeTemplateEl && templateCard) {
3676
+ runtimeTemplateEl.textContent = buildRuntimeCardTemplate(templateCard);
3677
+ }
3678
+ }
3679
+ }
3680
+ if (!entry.dynamicPublish) {
3681
+ el.innerHTML = entry.publishTemplate;
3682
+ }
3683
+ ensurePostListRootStructure(doc, el, effectiveCmsComponent);
3684
+ if (effectiveCmsComponent === "search") {
3685
+ const iifeScript = doc.createElement("script");
3686
+ iifeScript.textContent = buildSearchIIFE(
3687
+ getRuntimeEndpoint("search"),
3688
+ getRuntimeRequestConfig()
3689
+ );
3690
+ el.appendChild(iifeScript);
3691
+ }
3692
+ const pMode = el.getAttribute("data-pagination") || "static";
3693
+ if (pMode === "none" || pMode === "loadmore") {
3694
+ (_a2 = el.querySelector("nav[data-cms-pagination]")) == null ? void 0 : _a2.remove();
3695
+ } else if (pMode === "static") {
3696
+ const paginationNav = ensurePaginationNavElement(
3697
+ doc,
3698
+ el,
3699
+ effectiveCmsComponent
3700
+ );
3701
+ if (paginationNav) {
3702
+ ensurePaginationNavFallback(doc, paginationNav, effectiveCmsComponent);
3703
+ }
3704
+ }
3705
+ el.removeAttribute("data-wb-component");
3706
+ break;
3707
+ }
3708
+ }
3709
+ });
3710
+ doc.querySelectorAll("[data-wb-loop-grid-version], [data-wb-loop-grid-schema]").forEach((el) => {
3711
+ cleanupLoopGridExportAttrsElement(el);
3712
+ el.removeAttribute("data-wb-component");
3713
+ });
3714
+ doc.querySelectorAll("[data-cms-preview]").forEach((el) => el.remove());
3715
+ doc.querySelectorAll("[data-cms-preview-wrapper]").forEach((el) => el.remove());
3716
+ doc.querySelectorAll("[data-cms-hidden]").forEach((el) => {
3717
+ el.style.removeProperty("display");
3718
+ el.removeAttribute("data-cms-hidden");
3719
+ });
3720
+ doc.querySelectorAll(
3721
+ ".wb-cms-editor-header, .wb-cms-latest-header, .wb-cms-detail-header, .wb-cms-search-header"
3722
+ ).forEach((el) => el.remove());
3723
+ if (doc.querySelector(".wb-post-card") && !doc.getElementById("wb-post-card-styles")) {
3724
+ const style = doc.createElement("style");
3725
+ style.id = "wb-post-card-styles";
3726
+ style.textContent = POST_CARD_CSS;
3727
+ doc.head.appendChild(style);
3728
+ }
3729
+ if (doc.querySelector(".wb-product-card") && !doc.getElementById("wb-product-card-styles")) {
3730
+ const style = doc.createElement("style");
3731
+ style.id = "wb-product-card-styles";
3732
+ style.textContent = PRODUCT_CARD_CSS;
3733
+ doc.head.appendChild(style);
3734
+ }
3735
+ if (doc.querySelector(".wb-product-detail") && !doc.getElementById("wb-product-detail-styles")) {
3736
+ const style = doc.createElement("style");
3737
+ style.id = "wb-product-detail-styles";
3738
+ style.textContent = PRODUCT_DETAIL_STYLES;
3739
+ doc.head.appendChild(style);
3740
+ }
3741
+ if (doc.querySelector(".wb-product-detail-v2") && !doc.getElementById("wb-product-detail-v2-styles")) {
3742
+ const style = doc.createElement("style");
3743
+ style.id = "wb-product-detail-v2-styles";
3744
+ style.textContent = PRODUCT_DETAIL_V2_STYLES;
3745
+ doc.head.appendChild(style);
3746
+ }
3747
+ const isFullDocument = htmlStr.trim().toLowerCase().startsWith("<!doctype");
3748
+ return isFullDocument ? `<!DOCTYPE html>
3749
+ ${doc.documentElement.outerHTML}` : doc.body.innerHTML;
3750
+ }
3751
+ function registerCmsComponent(editor, config) {
3752
+ const domComponents = editor == null ? void 0 : editor.DomComponents;
3753
+ if (!domComponents || domComponents.getType(config.type))
3754
+ return;
3755
+ const startIdx = config.publishStartIndex ?? 1;
3756
+ const publishTemplate = config.publishTemplate ?? componentsToHtml(config.components.slice(startIdx));
3757
+ cmsTypeRegistry.set(config.dataCmsComponent, {
3758
+ publishTemplate,
3759
+ dataCmsComponent: config.dataCmsComponent,
3760
+ dataWbComponent: config.dataWbComponent,
3761
+ dynamicPublish: config.dynamicPublish
3762
+ });
3763
+ domComponents.addType(config.type, {
3764
+ isComponent: (el) => {
3765
+ var _a;
3766
+ return ((_a = el == null ? void 0 : el.getAttribute) == null ? void 0 : _a.call(el, "data-wb-component")) === config.dataWbComponent ? { type: config.type } : false;
3767
+ },
3768
+ model: {
3769
+ defaults: {
3770
+ name: config.name,
3771
+ tagName: "div",
3772
+ draggable: "*",
3773
+ droppable: config.droppable ?? false,
3774
+ selectable: true,
3775
+ editable: false,
3776
+ stylable: true,
3777
+ attributes: {
3778
+ "data-wb-component": config.dataWbComponent,
3779
+ "data-cms-component": config.dataCmsComponent,
3780
+ ...config.defaultAttributes
3781
+ },
3782
+ style: config.defaultStyle ?? { display: "block", width: "100%" },
3783
+ styles: config.styles,
3784
+ script: config.script,
3785
+ "script-export": config.scriptExport ?? config.script,
3786
+ "script-props": config.scriptProps,
3787
+ ...config.defaultProps,
3788
+ traits: config.traits,
3789
+ components: config.components
3790
+ },
3791
+ init() {
3792
+ var _a;
3793
+ const eventStr = config.watchProps.map((p2) => `change:${p2}`).join(" ");
3794
+ if (eventStr) {
3795
+ this.on(eventStr, this._syncAttrs);
3796
+ }
3797
+ this._syncAttrs();
3798
+ (_a = config.onModelInit) == null ? void 0 : _a.call(config, this, editor);
3799
+ },
3800
+ _syncAttrs() {
3801
+ var _a;
3802
+ this.addAttributes({
3803
+ // 始终确保 data-cms-component 存在(旧 schema 可能缺失此属性)
3804
+ "data-cms-component": config.dataCmsComponent,
3805
+ "data-wb-instance-id": String(((_a = this.getId) == null ? void 0 : _a.call(this)) || this.cid || ""),
3806
+ ...config.syncAttrs(this)
3807
+ });
3808
+ },
3809
+ /**
3810
+ * 覆盖 toJSON():
3811
+ * - 默认模式:不序列化 components(静态子组件,从 defaults 恢复,避免 MutationObserver 污染)
3812
+ * - dynamicPublish 模式:保留 components(子组件含用户可配置状态,需要持久化)
3813
+ */
3814
+ toJSON(opts) {
3815
+ const baseType = domComponents.getType("default");
3816
+ const obj = baseType.model.prototype.toJSON.call(this, opts);
3817
+ if (!config.dynamicPublish) {
3818
+ delete obj.components;
3819
+ }
3820
+ return obj;
3821
+ },
3822
+ /**
3823
+ * 覆盖 getInnerHTML():
3824
+ * - 默认模式:输出静态发布模板,绕过 MutationObserver 污染
3825
+ * - dynamicPublish 模式:从实时组件树生成,反映用户对子组件的配置修改
3826
+ */
3827
+ getInnerHTML() {
3828
+ if (config.dynamicPublish) {
3829
+ const children = this.components();
3830
+ if (!children || children.length <= startIdx)
3831
+ return "";
3832
+ const parts = [];
3833
+ for (let i2 = startIdx; i2 < children.length; i2++) {
3834
+ parts.push(children.at(i2).toHTML());
3835
+ }
3836
+ return parts.join("\n");
3837
+ }
3838
+ return publishTemplate;
3839
+ }
3840
+ }
3841
+ });
3842
+ }
3843
+ const emptyList = async () => [];
3844
+ const emptyPage = async () => ({ list: [], total: 0, pageNo: 1, pageSize: 1 });
3845
+ const emptyDetail = async () => null;
3846
+ const createFallbackDynamicDataProvider = () => ({
3847
+ pages: {
3848
+ loadList: emptyPage,
3849
+ loadDraft: emptyDetail,
3850
+ loadHistoryDetail: emptyDetail
3851
+ },
3852
+ posts: {
3853
+ loadPage: emptyPage,
3854
+ loadDetail: emptyDetail
3855
+ },
3856
+ postCategories: {
3857
+ loadList: emptyList
3858
+ },
3859
+ faqCategories: {
3860
+ loadList: emptyList
3861
+ },
3862
+ faqItems: {
3863
+ loadList: emptyList
3864
+ },
3865
+ productCategoryContent: {
3866
+ loadDetail: emptyDetail
3867
+ },
3868
+ media: {
3869
+ loadPage: emptyPage
3870
+ },
3871
+ mediaCategories: {
3872
+ loadList: emptyList
3873
+ },
3874
+ products: {
3875
+ loadPage: emptyPage,
3876
+ loadDetail: emptyDetail,
3877
+ loadSimpleList: emptyList
3878
+ },
3879
+ productCategories: {
3880
+ loadList: emptyList
3881
+ },
3882
+ tenant: {
3883
+ getEffectiveTenantId: () => void 0
3884
+ }
3885
+ });
3886
+ let dynamicDataProvider = createFallbackDynamicDataProvider();
3887
+ const getWebBuilderDynamicDataProvider = () => dynamicDataProvider;
3888
+ const setWebBuilderDynamicDataProvider = (provider) => {
3889
+ const previousProvider = dynamicDataProvider;
3890
+ dynamicDataProvider = provider;
3891
+ return () => {
3892
+ dynamicDataProvider = previousProvider;
3893
+ };
3894
+ };
3895
+ async function initPreviewProductTrait(model, options = {}) {
3896
+ var _a;
3897
+ const traitName = options.traitName || "cmsPreviewProductId";
3898
+ const emptyLabel = options.emptyLabel || "未选择(显示占位模板)";
3899
+ const trait = (_a = model.getTrait) == null ? void 0 : _a.call(model, traitName);
3900
+ if (!trait)
3901
+ return;
3902
+ try {
3903
+ const list = await getWebBuilderDynamicDataProvider().products.loadSimpleList();
3904
+ const options2 = Array.isArray(list) ? list.map((item) => ({
3905
+ value: String(item.id ?? ""),
3906
+ label: item.name ? `${item.name} (#${item.id})` : `#${item.id}`
3907
+ })) : [];
3908
+ trait.set("options", [{ value: "", label: emptyLabel }, ...options2]);
3909
+ } catch {
3910
+ trait.set("options", [
3911
+ { value: "", label: emptyLabel },
3912
+ { value: model.get(traitName) || "", label: "加载产品列表失败,请手动输入 ID" }
3913
+ ]);
3914
+ }
3915
+ }
3916
+ async function initPreviewMediaTrait(model, options = {}) {
3917
+ var _a;
3918
+ const traitName = options.traitName || "cmsPreviewMediaId";
3919
+ const emptyLabel = options.emptyLabel || "未选择(显示占位模板)";
3920
+ const trait = (_a = model.getTrait) == null ? void 0 : _a.call(model, traitName);
3921
+ if (!trait)
3922
+ return;
3923
+ try {
3924
+ const params = {
3925
+ pageNo: 1,
3926
+ pageSize: 100
3927
+ };
3928
+ const categoryId = String(options.categoryId || "").trim();
3929
+ if (categoryId) {
3930
+ params.categoryId = categoryId;
3931
+ }
3932
+ const result = await getWebBuilderDynamicDataProvider().media.loadPage(params);
3933
+ const list = Array.isArray(result == null ? void 0 : result.list) ? result.list : Array.isArray(result) ? result : [];
3934
+ const previewOptions = list.map((item) => {
3935
+ var _a2, _b;
3936
+ const title = (item == null ? void 0 : item.title) || ((_b = (_a2 = item == null ? void 0 : item.contents) == null ? void 0 : _a2[0]) == null ? void 0 : _b.title) || "";
3937
+ const id = String((item == null ? void 0 : item.id) ?? "");
3938
+ return {
3939
+ value: id,
3940
+ label: title ? `${title} (#${id})` : `#${id}`
3941
+ };
3942
+ });
3943
+ trait.set("options", [{ value: "", label: emptyLabel }, ...previewOptions]);
3944
+ } catch {
3945
+ trait.set("options", [
3946
+ { value: "", label: emptyLabel },
3947
+ { value: model.get(traitName) || "", label: "加载媒体资源失败,请手动输入 ID" }
3948
+ ]);
3949
+ }
3950
+ }
3951
+ const DEFAULT_SITE_MENU_CODE = "main-menu";
3952
+ const normalizeBindKey = (rawValue) => rawValue.replace(/[^a-zA-Z0-9_-]/g, "_") || "site_menu";
3953
+ function resolveSiteMenuAttrs(model) {
3954
+ var _a, _b, _c, _d, _e;
3955
+ const attrs = ((_a = model == null ? void 0 : model.getAttributes) == null ? void 0 : _a.call(model)) || {};
3956
+ const menuCode = String(
3957
+ ((_b = model == null ? void 0 : model.get) == null ? void 0 : _b.call(model, "menuCode")) ?? attrs["data-menu-code"] ?? DEFAULT_SITE_MENU_CODE
3958
+ ).trim() || DEFAULT_SITE_MENU_CODE;
3959
+ const layout = String(
3960
+ ((_c = model == null ? void 0 : model.get) == null ? void 0 : _c.call(model, "menuLayout")) ?? attrs["data-layout"] ?? "horizontal"
3961
+ ).trim() || "horizontal";
3962
+ const submenuTrigger = String(
3963
+ ((_d = model == null ? void 0 : model.get) == null ? void 0 : _d.call(model, "submenuTrigger")) ?? attrs["data-submenu-trigger"] ?? "hover"
3964
+ ).trim() || "hover";
3965
+ const bindKey = `menu_html_${normalizeBindKey(String(((_e = model == null ? void 0 : model.getId) == null ? void 0 : _e.call(model)) || (model == null ? void 0 : model.cid) || "site_menu"))}`;
3966
+ return {
3967
+ class: "wb-site-menu notranslate",
3968
+ "data-menu-code": menuCode,
3969
+ "data-layout": layout,
3970
+ "data-submenu-trigger": submenuTrigger,
3971
+ "data-menu-bind-key": bindKey,
3972
+ "data-cms-html": bindKey,
3973
+ "data-wb-i18n-skip": "true",
3974
+ translate: "no"
3975
+ };
3976
+ }
3977
+ const TEMPLATE_REGISTRY = {
3978
+ "post-card": { id: "post-card", label: "Post Card", kind: "item", accentColor: "#1d4ed8" },
3979
+ "product-card": {
3980
+ id: "product-card",
3981
+ label: "Product Card",
3982
+ kind: "item",
3983
+ accentColor: "#0f766e"
3984
+ },
3985
+ "taxonomy-card": {
3986
+ id: "taxonomy-card",
3987
+ label: "Taxonomy Card",
3988
+ kind: "item",
3989
+ accentColor: "#7c3aed"
3990
+ },
3991
+ "minimal-card": {
3992
+ id: "minimal-card",
3993
+ label: "Minimal Card",
3994
+ kind: "item",
3995
+ accentColor: "#475569"
3996
+ },
3997
+ "empty-default": {
3998
+ id: "empty-default",
3999
+ label: "Default Empty",
4000
+ kind: "empty",
4001
+ accentColor: "#64748b"
4002
+ }
4003
+ };
4004
+ function applyFilterState(items, filterState) {
4005
+ let nextItems = [...items];
4006
+ const taxonomyFilters = [...filterState.taxonomy, ...filterState.category, ...filterState.tag].map((item) => item.trim().toLowerCase()).filter(Boolean);
4007
+ if (taxonomyFilters.length > 0) {
4008
+ nextItems = nextItems.filter(
4009
+ (item) => taxonomyFilters.some((filter) => `${item.taxonomy ?? ""}`.toLowerCase().includes(filter))
4010
+ );
4011
+ }
4012
+ const search = `${filterState.search ?? ""}`.trim().toLowerCase();
4013
+ if (search) {
4014
+ nextItems = nextItems.filter(
4015
+ (item) => [item.title, item.subtitle, item.excerpt].some(
4016
+ (field) => `${field ?? ""}`.toLowerCase().includes(search)
4017
+ )
4018
+ );
4019
+ }
4020
+ return nextItems;
4021
+ }
4022
+ function escapeHtml(value) {
4023
+ return String(value ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
4024
+ }
4025
+ function resolveTemplateLabel(templateId) {
4026
+ var _a;
4027
+ return ((_a = TEMPLATE_REGISTRY[templateId]) == null ? void 0 : _a.label) ?? templateId;
4028
+ }
4029
+ function getRecordValue(record, field) {
4030
+ const fields = record.fields;
4031
+ if (fields && Object.prototype.hasOwnProperty.call(fields, field)) {
4032
+ return fields[field];
4033
+ }
4034
+ const key = field.split(".").pop() || field;
4035
+ if (key === "name")
4036
+ return record.title;
4037
+ if (key === "title")
4038
+ return record.title;
4039
+ if (key === "introduction" || key === "description" || key === "excerpt")
4040
+ return record.excerpt;
4041
+ if (key === "picUrl" || key === "coverUrl" || key === "image")
4042
+ return record.image;
4043
+ if (key === "url" || key === "detailUrl" || key === "buyNowUrl")
4044
+ return record.href;
4045
+ if (key === "priceFormatted")
4046
+ return record.price;
4047
+ if (key === "categoryName" || key === "typeName" || key === "type")
4048
+ return record.taxonomy;
4049
+ if (key === "publishTime" || key === "createTime")
4050
+ return record.meta;
4051
+ return record[key] ?? "";
4052
+ }
4053
+ function composeDynamicUrl(value, template) {
4054
+ const raw = String(value ?? "");
4055
+ const tpl = String(template ?? "").trim();
4056
+ if (!tpl)
4057
+ return raw;
4058
+ if (tpl.includes("{{encoded}}"))
4059
+ return tpl.replace(/\{\{encoded\}\}/g, encodeURIComponent(raw));
4060
+ if (tpl.includes("{{value}}"))
4061
+ return tpl.replace(/\{\{value\}\}/g, raw);
4062
+ return `${tpl}${raw}`;
4063
+ }
4064
+ function escapeRegExp(value) {
4065
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4066
+ }
4067
+ function parseNumber(value, fallback, options) {
4068
+ const numeric = Number(value);
4069
+ if (!Number.isFinite(numeric))
4070
+ return fallback;
4071
+ if ((options == null ? void 0 : options.min) !== void 0 && numeric < options.min)
4072
+ return options.min;
4073
+ if ((options == null ? void 0 : options.max) !== void 0 && numeric > options.max)
4074
+ return options.max;
4075
+ return numeric;
4076
+ }
4077
+ function sanitizeIdSuffix(value) {
4078
+ return value.replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "item";
4079
+ }
4080
+ function uniquifyLoopItemIds(root, suffix) {
4081
+ const idMap = {};
4082
+ const elements = [
4083
+ ...root.hasAttribute("id") ? [root] : [],
4084
+ ...Array.from(root.querySelectorAll("[id]"))
4085
+ ];
4086
+ elements.forEach((el) => {
4087
+ const id = `${el.getAttribute("id") || ""}`.trim();
4088
+ if (!id)
4089
+ return;
4090
+ const nextId = `${id}-${sanitizeIdSuffix(suffix)}`;
4091
+ idMap[id] = nextId;
4092
+ el.setAttribute("id", nextId);
4093
+ });
4094
+ return idMap;
4095
+ }
4096
+ function rewriteIdReferences(root, idMap) {
4097
+ const rewriteTokenList = (value) => value.split(/\s+/).map((token) => idMap[token] || token).join(" ");
4098
+ const elements = [root, ...Array.from(root.querySelectorAll("*"))];
4099
+ elements.forEach((el) => {
4100
+ ["for", "aria-labelledby", "aria-describedby", "aria-controls", "aria-owns", "list"].forEach(
4101
+ (attr) => {
4102
+ const value = el.getAttribute(attr);
4103
+ if (value)
4104
+ el.setAttribute(attr, rewriteTokenList(value));
4105
+ }
4106
+ );
4107
+ ["href", "xlink:href", "data-bs-target", "data-target"].forEach((attr) => {
4108
+ const value = el.getAttribute(attr);
4109
+ if (!(value == null ? void 0 : value.startsWith("#")))
4110
+ return;
4111
+ const nextId = idMap[value.slice(1)];
4112
+ if (nextId)
4113
+ el.setAttribute(attr, `#${nextId}`);
4114
+ });
4115
+ });
4116
+ }
4117
+ function rewriteCssIds(css, idMap) {
4118
+ return Object.entries(idMap).reduce((nextCss, [oldId, newId]) => {
4119
+ if (!oldId || !newId)
4120
+ return nextCss;
4121
+ return nextCss.replace(new RegExp(`#${escapeRegExp(oldId)}(?![-_a-zA-Z0-9])`, "g"), `#${newId}`);
4122
+ }, css);
4123
+ }
4124
+ function normalizeDynamicLinkElement(el, doc) {
4125
+ var _a;
4126
+ if (el.tagName === "A")
4127
+ return el;
4128
+ const link = doc.createElement("a");
4129
+ Array.from(el.attributes).forEach((attr) => link.setAttribute(attr.name, attr.value));
4130
+ link.setAttribute("href", el.getAttribute("href") || "#");
4131
+ while (el.firstChild)
4132
+ link.appendChild(el.firstChild);
4133
+ (_a = el.parentNode) == null ? void 0 : _a.replaceChild(link, el);
4134
+ return link;
4135
+ }
4136
+ function normalizeDynamicLinks(root, doc) {
4137
+ let nextRoot = root;
4138
+ const matches = [
4139
+ ...root.matches('[data-wb-dynamic="link"], [data-cms-bind-href]') ? [root] : [],
4140
+ ...Array.from(root.querySelectorAll('[data-wb-dynamic="link"], [data-cms-bind-href]'))
4141
+ ];
4142
+ matches.forEach((el) => {
4143
+ const normalized = normalizeDynamicLinkElement(el, doc);
4144
+ if (el === nextRoot)
4145
+ nextRoot = normalized;
4146
+ });
4147
+ return nextRoot;
4148
+ }
4149
+ function normalizeDynamicImageElement(el, doc) {
4150
+ var _a;
4151
+ if (el.tagName === "IMG")
4152
+ return el;
4153
+ const image = doc.createElement("img");
4154
+ Array.from(el.attributes).forEach((attr) => image.setAttribute(attr.name, attr.value));
4155
+ image.setAttribute("alt", el.getAttribute("alt") || "");
4156
+ (_a = el.parentNode) == null ? void 0 : _a.replaceChild(image, el);
4157
+ return image;
4158
+ }
4159
+ function normalizeDynamicImages(root, doc) {
4160
+ let nextRoot = root;
4161
+ const matches = [
4162
+ ...root.matches('[data-wb-dynamic="image"]') ? [root] : [],
4163
+ ...Array.from(root.querySelectorAll('[data-wb-dynamic="image"]'))
4164
+ ];
4165
+ matches.forEach((el) => {
4166
+ const normalized = normalizeDynamicImageElement(el, doc);
4167
+ if (el === nextRoot)
4168
+ nextRoot = normalized;
4169
+ });
4170
+ return nextRoot;
4171
+ }
4172
+ function renderCustomTemplate(template, record, suffix) {
4173
+ const parser = new DOMParser();
4174
+ const doc = parser.parseFromString(template.html, "text/html");
4175
+ let rootEl = doc.body.firstElementChild;
4176
+ if (!rootEl)
4177
+ return renderCard(record, "minimal-card");
4178
+ rootEl = normalizeDynamicImages(rootEl, doc);
4179
+ rootEl = normalizeDynamicLinks(rootEl, doc);
4180
+ const root = rootEl;
4181
+ const idMap = uniquifyLoopItemIds(root, suffix);
4182
+ rewriteIdReferences(root, idMap);
4183
+ root.removeAttribute("data-cms-repeat");
4184
+ root.querySelectorAll("[data-cms-repeat]").forEach((el) => el.removeAttribute("data-cms-repeat"));
4185
+ const selectBoundElements2 = (selector) => [
4186
+ ...root.matches(selector) ? [root] : [],
4187
+ ...Array.from(root.querySelectorAll(selector))
4188
+ ];
4189
+ selectBoundElements2("[data-cms-bind]").forEach((el) => {
4190
+ const field = el.getAttribute("data-cms-bind") || "";
4191
+ el.textContent = String(getRecordValue(record, field) ?? "");
4192
+ });
4193
+ selectBoundElements2("[data-cms-html]").forEach((el) => {
4194
+ const field = el.getAttribute("data-cms-html") || "";
4195
+ el.innerHTML = String(getRecordValue(record, field) ?? "");
4196
+ });
4197
+ selectBoundElements2("[data-cms-bind-src]").forEach((el) => {
4198
+ const field = el.getAttribute("data-cms-bind-src") || "";
4199
+ const value = getRecordValue(record, field);
4200
+ if (value)
4201
+ el.setAttribute("src", String(value));
4202
+ });
4203
+ selectBoundElements2("[data-cms-bind-href]").forEach((el) => {
4204
+ const field = el.getAttribute("data-cms-bind-href") || "";
4205
+ const template2 = el.getAttribute("data-cms-bind-href-template") || "";
4206
+ const value = getRecordValue(record, field);
4207
+ if (value)
4208
+ el.setAttribute("href", composeDynamicUrl(value, template2));
4209
+ });
4210
+ selectBoundElements2("[data-cms-bind-alt]").forEach((el) => {
4211
+ const field = el.getAttribute("data-cms-bind-alt") || "";
4212
+ el.setAttribute("alt", String(getRecordValue(record, field) ?? ""));
4213
+ });
4214
+ root.setAttribute("data-wb-loop-grid-preview-item", "");
4215
+ const css = template.css ? rewriteCssIds(template.css, idMap) : "";
4216
+ return `${css ? `<style data-wb-loop-item-preview-style>${css}</style>` : ""}${root.outerHTML}`;
4217
+ }
4218
+ function renderCard(record, templateId) {
4219
+ var _a;
4220
+ const accent = ((_a = TEMPLATE_REGISTRY[templateId]) == null ? void 0 : _a.accentColor) ?? "#1d4ed8";
4221
+ const taxonomy = escapeHtml(record.taxonomy || "Unassigned");
4222
+ const badge = record.badge ? `<span class="wb-loop-grid-card__badge">${escapeHtml(record.badge)}</span>` : "";
4223
+ if (templateId === "minimal-card") {
4224
+ return `
4225
+ <article class="wb-loop-grid-card wb-loop-grid-card--minimal" style="--wb-loop-grid-accent:${accent}">
4226
+ <div class="wb-loop-grid-card__meta">${taxonomy}</div>
4227
+ <h4 class="wb-loop-grid-card__title">${escapeHtml(record.title)}</h4>
4228
+ <p class="wb-loop-grid-card__excerpt">${escapeHtml(record.excerpt)}</p>
4229
+ </article>
4230
+ `;
4231
+ }
4232
+ if (templateId === "product-card") {
4233
+ return `
4234
+ <article class="wb-loop-grid-card wb-loop-grid-card--product" style="--wb-loop-grid-accent:${accent}">
4235
+ <div class="wb-loop-grid-card__meta-row">
4236
+ <span class="wb-loop-grid-card__meta">${taxonomy}</span>
4237
+ ${badge}
4238
+ </div>
4239
+ <h4 class="wb-loop-grid-card__title">${escapeHtml(record.title)}</h4>
4240
+ <p class="wb-loop-grid-card__subtitle">${escapeHtml(record.subtitle)}</p>
4241
+ <p class="wb-loop-grid-card__excerpt">${escapeHtml(record.excerpt)}</p>
4242
+ <div class="wb-loop-grid-card__footer">
4243
+ <span class="wb-loop-grid-card__price">${escapeHtml(record.price || "$0.00")}</span>
4244
+ <span class="wb-loop-grid-card__action">View</span>
4245
+ </div>
4246
+ </article>
4247
+ `;
4248
+ }
4249
+ if (templateId === "taxonomy-card") {
4250
+ return `
4251
+ <article class="wb-loop-grid-card wb-loop-grid-card--taxonomy" style="--wb-loop-grid-accent:${accent}">
4252
+ <div class="wb-loop-grid-card__meta">${taxonomy}</div>
4253
+ <h4 class="wb-loop-grid-card__title">${escapeHtml(record.title)}</h4>
4254
+ <p class="wb-loop-grid-card__excerpt">${escapeHtml(record.excerpt)}</p>
4255
+ <div class="wb-loop-grid-card__footer"><span class="wb-loop-grid-card__action">Open Archive</span></div>
4256
+ </article>
4257
+ `;
4258
+ }
4259
+ return `
4260
+ <article class="wb-loop-grid-card" style="--wb-loop-grid-accent:${accent}">
4261
+ <div class="wb-loop-grid-card__meta-row">
4262
+ <span class="wb-loop-grid-card__meta">${taxonomy}</span>
4263
+ ${badge}
4264
+ </div>
4265
+ <h4 class="wb-loop-grid-card__title">${escapeHtml(record.title)}</h4>
4266
+ <p class="wb-loop-grid-card__subtitle">${escapeHtml(record.subtitle)}</p>
4267
+ <p class="wb-loop-grid-card__excerpt">${escapeHtml(record.excerpt)}</p>
4268
+ <div class="wb-loop-grid-card__footer">
4269
+ <span>${escapeHtml(record.meta)}</span>
4270
+ <span class="wb-loop-grid-card__action">Read More</span>
4271
+ </div>
4272
+ </article>
4273
+ `;
4274
+ }
4275
+ function buildLoopGridPageHref(page) {
4276
+ return page > 1 ? `page/${page}.html` : "./";
4277
+ }
4278
+ function buildPagination(totalPages, currentPage, mode) {
4279
+ if (mode === "none" || totalPages <= 1)
4280
+ return "";
4281
+ const buttons = Array.from({ length: totalPages }, (_2, index) => {
4282
+ const page = index + 1;
4283
+ const active = page === currentPage ? " active" : "";
4284
+ return `<a class="wb-loop-grid-pagination__number${active}" href="${buildLoopGridPageHref(page)}" data-wb-loop-grid-page="${page}"${page === currentPage ? ' aria-current="page"' : ""}>${page}</a>`;
4285
+ }).join("");
4286
+ const prev = currentPage > 1 ? `<a class="wb-loop-grid-pagination__btn" href="${buildLoopGridPageHref(currentPage - 1)}" data-wb-loop-grid-page="${currentPage - 1}" aria-label="上一页">${LOOP_GRID_PREV_ICON}</a>` : "";
4287
+ const next = currentPage < totalPages ? `<a class="wb-loop-grid-pagination__btn" href="${buildLoopGridPageHref(currentPage + 1)}" data-wb-loop-grid-page="${currentPage + 1}" aria-label="下一页">${LOOP_GRID_NEXT_ICON}</a>` : "";
4288
+ return `${LOOP_GRID_PAGINATION_STYLE}<nav class="wb-loop-grid-pagination" data-cms-pagination>${prev}${buttons}${next}</nav>`;
4289
+ }
4290
+ function isProductCategoryContextLoopType(schema) {
4291
+ return schema.loopItemType === "productCategoryFaq" || schema.loopItemType === "post" && !!`${schema.query.contextCollection ?? ""}`.trim();
4292
+ }
4293
+ function renderLoopGridMissingTemplate(schema) {
4294
+ const selectedTemplate = `${schema.loopItemTemplateResourceId || schema.itemTemplateId || ""}`.trim();
4295
+ return `
4296
+ <div class="wb-loop-grid-empty" data-wb-loop-grid-missing-template>
4297
+ <strong>Loop Item Template not loaded</strong>
4298
+ <p>${selectedTemplate ? `Selected template ID: ${escapeHtml(selectedTemplate)}` : "Please select a loop item template."}</p>
4299
+ </div>
4300
+ `;
4301
+ }
4302
+ function renderLoopGridPreview(schemaInput, itemTemplate, previewData) {
4303
+ const schema = {
4304
+ ...DEFAULT_LOOP_GRID_SCHEMA,
4305
+ ...schemaInput
4306
+ };
4307
+ if (previewData == null ? void 0 : previewData.loading) {
4308
+ return `
4309
+ <div class="wb-loop-grid-render" data-wb-loop-grid-render>
4310
+ <div class="wb-loop-grid-empty">
4311
+ <strong>Loading loop data...</strong>
4312
+ <p>正在读取真实数据用于预览。</p>
4313
+ </div>
4314
+ </div>
4315
+ `;
4316
+ }
4317
+ if (previewData == null ? void 0 : previewData.error) {
4318
+ return `
4319
+ <div class="wb-loop-grid-render" data-wb-loop-grid-render>
4320
+ <div class="wb-loop-grid-empty">
4321
+ <strong>Loop data preview failed</strong>
4322
+ <p>${escapeHtml(previewData.error)}</p>
4323
+ </div>
4324
+ </div>
4325
+ `;
4326
+ }
4327
+ const resolvedItems = applyFilterState((previewData == null ? void 0 : previewData.items) || [], schema.filterState);
4328
+ const currentPage = Math.max(1, (previewData == null ? void 0 : previewData.pageNo) || schema.filterState.currentPage || 1);
4329
+ const perPage = Math.max(1, schema.layout.itemsPerPage || 1);
4330
+ const totalPages = Math.max(
4331
+ 1,
4332
+ (previewData == null ? void 0 : previewData.totalPages) || Math.ceil(((previewData == null ? void 0 : previewData.total) || resolvedItems.length) / perPage)
4333
+ );
4334
+ const normalizedPage = Math.min(currentPage, totalPages);
4335
+ const itemOffset = (normalizedPage - 1) * perPage;
4336
+ const pagedItems = resolvedItems.slice(0, perPage);
4337
+ if (pagedItems.length === 0) {
4338
+ return `
4339
+ <div class="wb-loop-grid-render" data-wb-loop-grid-render>
4340
+ <div class="wb-loop-grid-empty">
4341
+ <strong>${escapeHtml((itemTemplate == null ? void 0 : itemTemplate.label) || resolveTemplateLabel(schema.emptyTemplateId || "empty-default"))}</strong>
4342
+ <p>${escapeHtml(schema.emptyState.nothingFoundText)}</p>
4343
+ </div>
4344
+ </div>
4345
+ `;
4346
+ }
4347
+ if (!(itemTemplate == null ? void 0 : itemTemplate.html) && schema.loopItemTemplateResourceId) {
4348
+ return renderLoopGridMissingTemplate(schema);
4349
+ }
4350
+ const cards = pagedItems.map((item, index) => {
4351
+ if (itemTemplate == null ? void 0 : itemTemplate.html) {
4352
+ return renderCustomTemplate(
4353
+ itemTemplate,
4354
+ item,
4355
+ `${schema.gridId || schema.loopItemTemplateResourceId || schema.itemTemplateId}-preview-${itemOffset + index + 1}`
4356
+ );
4357
+ }
4358
+ return renderCard(item, schema.itemTemplateId);
4359
+ }).join("");
4360
+ const isCarousel = !!schema.layout.loopCarousel;
4361
+ const scrollSnap = isCarousel || !!schema.layout.horizontalScroll;
4362
+ const carouselItemWidth = parseNumber(schema.layout.carouselItemWidth, 360, {
4363
+ min: 160,
4364
+ max: 960
4365
+ });
4366
+ const mobileScrollItemWidth = parseNumber(schema.layout.scrollItemWidth, 320, {
4367
+ min: 160,
4368
+ max: 720
4369
+ });
4370
+ const arrowPosition = parseNumber(schema.layout.carouselArrowPosition, 50, {
4371
+ min: 0,
4372
+ max: 100
4373
+ });
4374
+ const trackStyle = [
4375
+ "display:grid",
4376
+ `grid-template-columns:repeat(${schema.layout.columns}, minmax(0, 1fr))`,
4377
+ `column-gap:${schema.layout.columnGap}px`,
4378
+ `row-gap:${schema.layout.rowGap}px`,
4379
+ scrollSnap ? `--wb-loop-grid-carousel-item-width:${carouselItemWidth}px` : "",
4380
+ scrollSnap ? `--wb-loop-grid-mobile-item-width:${mobileScrollItemWidth}px` : "",
4381
+ scrollSnap ? "grid-template-columns:none" : "",
4382
+ scrollSnap ? "grid-auto-flow:column" : "",
4383
+ isCarousel ? "grid-auto-columns:min(var(--wb-loop-grid-carousel-item-width), 86vw)" : "",
4384
+ !isCarousel && schema.layout.horizontalScroll ? "grid-auto-columns:min(var(--wb-loop-grid-mobile-item-width), 86vw)" : "",
4385
+ scrollSnap ? "overflow-x:auto" : "",
4386
+ scrollSnap ? "overflow-y:hidden" : "",
4387
+ scrollSnap ? "-webkit-overflow-scrolling:touch" : "",
4388
+ scrollSnap ? "scroll-snap-type:x mandatory" : "",
4389
+ isCarousel ? "scroll-padding-inline:calc((100% - min(var(--wb-loop-grid-carousel-item-width), 86vw)) / 2)" : "",
4390
+ !isCarousel && schema.layout.horizontalScroll ? "scroll-padding-inline:calc((100% - min(var(--wb-loop-grid-mobile-item-width), 86vw)) / 2)" : ""
4391
+ ].filter(Boolean).join(";");
4392
+ return `
4393
+ <div class="wb-loop-grid-render" data-wb-loop-grid-render data-wb-loop-item-template-id="${escapeHtml(schema.loopItemTemplateResourceId || schema.itemTemplateId)}">
4394
+ ${isCarousel ? `<div class="wb-loop-grid-carousel-shell" style="--wb-loop-grid-carousel-arrow-y:${arrowPosition}%">
4395
+ <button type="button" class="wb-loop-grid-carousel-arrow wb-loop-grid-carousel-arrow--prev" data-wb-loop-carousel-prev aria-label="Previous">${LOOP_GRID_PREV_ICON}</button>` : ""}
4396
+ <div class="wb-loop-grid-cards" ${scrollSnap ? "data-wb-loop-carousel-track" : ""} style="${trackStyle};">
4397
+ ${cards}
4398
+ </div>
4399
+ ${isCarousel ? `<button type="button" class="wb-loop-grid-carousel-arrow wb-loop-grid-carousel-arrow--next" data-wb-loop-carousel-next aria-label="Next">${LOOP_GRID_NEXT_ICON}</button>
4400
+ </div>` : ""}
4401
+ ${buildPagination(
4402
+ totalPages,
4403
+ normalizedPage,
4404
+ isProductCategoryContextLoopType(schema) ? "none" : schema.pagination.mode
4405
+ )}
4406
+ </div>
4407
+ `;
4408
+ }
4409
+ function mergeFilterState(currentFilterState, incomingFilterState) {
4410
+ return {
4411
+ ...currentFilterState,
4412
+ ...incomingFilterState || {},
4413
+ taxonomy: (incomingFilterState == null ? void 0 : incomingFilterState.taxonomy) ?? currentFilterState.taxonomy,
4414
+ tag: (incomingFilterState == null ? void 0 : incomingFilterState.tag) ?? currentFilterState.tag,
4415
+ category: (incomingFilterState == null ? void 0 : incomingFilterState.category) ?? currentFilterState.category,
4416
+ author: (incomingFilterState == null ? void 0 : incomingFilterState.author) ?? currentFilterState.author,
4417
+ currentPage: (incomingFilterState == null ? void 0 : incomingFilterState.currentPage) ?? 1
4418
+ };
4419
+ }
4420
+ export {
4421
+ C as CMS_COMPONENTS_CAPABILITY,
4422
+ a as CMS_COMPONENTS_PLUGIN_ID,
4423
+ b as CMS_COMPONENT_LOAD_TYPES,
4424
+ d as CMS_COMPONENT_REQUIRED_HOST_SERVICES,
4425
+ C2 as CONTEXT_DETAIL_CMS_COMPONENT,
4426
+ o as DEFAULT_DYNAMIC_CONTEXT,
4427
+ DEFAULT_LOOP_GRID_SCHEMA,
4428
+ f as DEFAULT_MENU_TREE_CODE,
4429
+ DEFAULT_SITE_MENU_CODE,
4430
+ q as DYNAMIC_FIELD_MAP,
4431
+ s as DYNAMIC_FIELD_STYLES,
4432
+ t as DYNAMIC_FIELD_STYLE_KEY,
4433
+ u as DYNAMIC_REPEAT_MAP,
4434
+ LOOP_GRID_NEXT_ICON,
4435
+ v as LOOP_GRID_PAGINATION_CSS,
4436
+ c3 as LOOP_GRID_PAGINATION_SCRIPT,
4437
+ LOOP_GRID_PAGINATION_STYLE,
4438
+ LOOP_GRID_PREV_ICON,
4439
+ w as LOOP_GRID_SCHEMA_VERSION,
4440
+ PAGINATION_ATTRS,
4441
+ PAGINATION_PROPS,
4442
+ PAGINATION_TRAITS,
4443
+ POST_CARD_CSS,
4444
+ PRODUCT_CARD_CSS,
4445
+ PRODUCT_DETAIL_STYLES,
4446
+ PRODUCT_DETAIL_V2_STYLES,
4447
+ R as RESOURCE_TYPE_TO_DYNAMIC_CONTEXT,
4448
+ STATIC_CHILD,
4449
+ x as WB_CMS_DYNAMIC_FIELD_TYPES,
4450
+ y as WB_CMS_DYN_BREADCRUMB_TYPE,
4451
+ z as WB_CMS_DYN_DATETIME_TYPE,
4452
+ A as WB_CMS_DYN_HTML_TYPE,
4453
+ B as WB_CMS_DYN_IF_TYPE,
4454
+ E as WB_CMS_DYN_IMAGE_TYPE,
4455
+ F as WB_CMS_DYN_LINK_TYPE,
4456
+ G as WB_CMS_DYN_REPEAT_ITEM_TYPE,
4457
+ H as WB_CMS_DYN_REPEAT_TYPE,
4458
+ I as WB_CMS_DYN_SEO_TYPE,
4459
+ J as WB_CMS_DYN_TEXT_TYPE,
4460
+ K as WB_CMS_DYN_TOC_TYPE,
4461
+ M as WB_CMS_FAQ_SECTION_TYPE,
4462
+ N as WB_CMS_MEDIA_DETAIL_TYPE,
4463
+ O as WB_CMS_MEDIA_LATEST_TYPE,
4464
+ P as WB_CMS_MEDIA_LIST_TYPE,
4465
+ W as WB_CMS_MENU_TREE_TYPE,
4466
+ Q as WB_CMS_POST_DETAIL_TYPE,
4467
+ S as WB_CMS_POST_LATEST_TYPE,
4468
+ T as WB_CMS_PRODUCT_CATEGORY_FAQ_TYPE,
4469
+ U as WB_CMS_PRODUCT_FEATURED_TYPE,
4470
+ V as WB_CMS_PRODUCT_LATEST_TYPE,
4471
+ X as WB_CMS_PRODUCT_RELATED_TYPE,
4472
+ Y as WB_CMS_SEARCH_TYPE,
4473
+ Z as WB_CMS_SITE_MENU_TYPE,
4474
+ _ as WB_CMS_TECHNICAL_DOWNLOAD_LIST_TYPE,
4475
+ $ as WB_CMS_TECHNICAL_SERVICE_LIST_TYPE,
4476
+ a0 as WB_CMS_TECHNICAL_SUPPORT_DETAIL_TYPE,
4477
+ a1 as WB_DYN_MARK_ATTR,
4478
+ a2 as WB_TEMPLATE_CONTEXT_KEY,
4479
+ a3 as applyBindAttribute,
4480
+ bindDynamicRenderData,
4481
+ a4 as buildFieldSelectOptions,
4482
+ a5 as buildSparseAttrs,
4483
+ a6 as buildTraitOptions,
4484
+ a7 as clearTraitValueIfUnavailable,
4485
+ c as componentsCms,
4486
+ composeDynamicUrl$1 as composeDynamicUrl,
4487
+ composePlaceholderUrl,
4488
+ c2 as createCmsComponentsPlugin,
4489
+ a8 as createLoopGridId,
4490
+ e as encodeLoopGridSchema,
4491
+ a9 as filterFieldsByKind,
4492
+ aa as findAncestorRepeat,
4493
+ ab as findAncestorRepeats,
4494
+ ac as findFieldMeta,
4495
+ ad as findRepeatSource,
4496
+ fixCmsComponentsHtml,
4497
+ ae as getAllRepeatItemFields,
4498
+ getCmsAttributesCallback,
4499
+ af as getDynamicContextFromComponent,
4500
+ ag as getPageLevelFields,
4501
+ ah as getRepeatSourceOptions,
4502
+ getWebBuilderDynamicDataProvider,
4503
+ initPreviewMediaTrait,
4504
+ initPreviewProductTrait,
4505
+ makePaginationNav,
4506
+ makePreviewGrid,
4507
+ makePreviewHeader,
4508
+ mergeFilterState,
4509
+ normalizeSiteHref$1 as normalizeSiteHref,
4510
+ d2 as parseCsvList,
4511
+ p as parseNumber,
4512
+ ai as refreshTraitOptions,
4513
+ registerCmsComponent,
4514
+ registerCmsTypeEntry,
4515
+ l as registerDynamicBreadcrumbBlock,
4516
+ k as registerDynamicConditionalBlock,
4517
+ j as registerDynamicDatetimeBlock,
4518
+ aj as registerDynamicFieldBlock,
4519
+ g as registerDynamicHtmlBlock,
4520
+ h as registerDynamicImageBlock,
4521
+ i as registerDynamicLinkBlock,
4522
+ n as registerDynamicSeoBlock,
4523
+ r as registerDynamicTextBlock,
4524
+ m as registerDynamicTocBlock,
4525
+ removeDynamicRenderCloneIds,
4526
+ renderLoopGridPreview,
4527
+ ak as resolveAvailableFields,
4528
+ al as resolveDynamicContext,
4529
+ am as resolveMenuTreeAttrs,
4530
+ resolveSiteMenuAttrs,
4531
+ an as serializeCsvList,
4532
+ setCmsFactoryDataProvider,
4533
+ setWebBuilderDynamicDataProvider,
4534
+ syncPaginationAttrs
4535
+ };