├── Block
├── Adminhtml
│ └── Index
│ │ └── Index.php
└── Product
│ ├── ImageFactory.php
│ └── Renderer
│ └── Configurable.php
├── Controller
└── Adminhtml
│ └── Index
│ └── Index.php
├── DeferJS.php
├── KnockoutMagento2React.jpg
├── KnockoutMagento2React.png
├── LICENSE.md
├── README.md
├── React
└── React
│ ├── .babelrc
│ ├── .gitignore
│ └── composer.json
├── ReactInjectPlugin.php
├── RemoveMagentoInitScripts.php
├── Template.php
├── composer.json
├── etc
├── acl.xml
├── adminhtml
│ ├── menu.xml
│ ├── routes.xml
│ └── system.xml
├── config.xml
├── di.xml
├── frontend
│ └── events.xml
└── module.xml
├── package.json
├── pub
└── static
│ ├── category-styles-m.css
│ ├── product-critical-m.css
│ ├── product-styles-m.css
│ ├── styles-l.css
│ └── styles-m.css
├── registration.php
├── src
├── components
│ ├── AddToCartForm.js
│ └── App.js
├── gridjs.js
├── index.js
└── styles
│ ├── gridjs.css
│ └── index.css
├── view
├── adminhtml
│ ├── layout
│ │ └── default.xml
│ └── templates
│ │ └── index
│ │ └── index.phtml
├── base
│ ├── requirejs-config.js
│ ├── templates
│ │ ├── component.phtml
│ │ ├── react-component.phtml
│ │ └── vue-component.phtml
│ └── web
│ │ └── js
│ │ ├── htm.module.js
│ │ ├── index_bundle.js
│ │ ├── preact.module.js
│ │ ├── react-dom.development.js
│ │ ├── react-dom.js
│ │ ├── react-dom.production.min.js
│ │ ├── react.development.js
│ │ ├── react.js
│ │ ├── react.production.min.js
│ │ ├── vue.js
│ │ └── vue2.production.min.js
└── frontend
│ ├── etc
│ └── view.xml
│ ├── layout
│ ├── catalog_category_view.xml
│ ├── catalog_product_view.xml
│ ├── catalog_product_view_type_configurable.xml
│ ├── default.xml
│ └── default_head_blocks.xml
│ ├── templates
│ ├── product
│ │ ├── breadcrumbs.phtml
│ │ ├── image_with_borders.phtml
│ │ ├── listing
│ │ │ └── renderer.phtml
│ │ └── view
│ │ │ ├── gallery.phtml
│ │ │ └── renderer.phtml
│ ├── react-footer-css.phtml
│ ├── react-footer.phtml
│ ├── react-header-css.phtml
│ ├── react-header.phtml
│ └── topmenu-account.phtml
│ └── web
│ └── js
│ ├── cash.js
│ ├── react-core.js
│ └── rum.js
└── webpack.config.js
/Block/Adminhtml/Index/Index.php:
--------------------------------------------------------------------------------
1 | objectManager = $objectManager;
70 | $this->presentationConfig = $presentationConfig;
71 | $this->viewAssetPlaceholderFactory = $viewAssetPlaceholderFactory;
72 | $this->viewAssetImageFactory = $viewAssetImageFactory;
73 | $this->imageParamsBuilder = $imageParamsBuilder;
74 | }
75 |
76 | /**
77 | * Remove class from custom attributes
78 | *
79 | * @param array $attributes
80 | * @return array
81 | */
82 | private function filterCustomAttributes(array $attributes): array
83 | {
84 | if (isset($attributes['class'])) {
85 | unset($attributes['class']);
86 | }
87 | return $attributes;
88 | }
89 |
90 | /**
91 | * Retrieve image class for HTML element
92 | *
93 | * @param array $attributes
94 | * @return string
95 | */
96 | private function getClass(array $attributes): string
97 | {
98 | return $attributes['class'] ?? 'product-image-photo';
99 | }
100 |
101 | /**
102 | * Calculate image ratio
103 | *
104 | * @param int $width
105 | * @param int $height
106 | * @return float
107 | */
108 | private function getRatio(int $width, int $height): float
109 | {
110 | if ($width && $height) {
111 | return $height / $width;
112 | }
113 | return 1.0;
114 | }
115 |
116 | /**
117 | * Get image label
118 | *
119 | * @param Product $product
120 | * @param string $imageType
121 | * @return string
122 | */
123 | private function getLabel(Product $product, string $imageType): string
124 | {
125 | $label = $product->getData($imageType . '_' . 'label');
126 | if (empty($label)) {
127 | $label = $product->getName();
128 | }
129 | return (string) $label;
130 | }
131 |
132 | /**
133 | * Create image block from product
134 | *
135 | * @param Product $product
136 | * @param string $imageId
137 | * @param array|null $attributes
138 | * @return ImageBlock
139 | */
140 | public function create(Product $product, string $imageId, array $attributes = null): ImageBlock
141 | {
142 | $viewImageConfig = $this->presentationConfig->getViewConfig()->getMediaAttributes(
143 | 'Magento_Catalog',
144 | ImageHelper::MEDIA_TYPE_CONFIG_NODE,
145 | $imageId
146 | );
147 |
148 | $imageMiscParams = $this->imageParamsBuilder->build($viewImageConfig);
149 | $originalFilePath = $product->getData($imageMiscParams['image_type']);
150 |
151 | if ($originalFilePath === null || $originalFilePath === 'no_selection') {
152 | $imageAsset = $this->viewAssetPlaceholderFactory->create(
153 | [
154 | 'type' => $imageMiscParams['image_type'],
155 | ]
156 | );
157 | } else {
158 | $imageAsset = $this->viewAssetImageFactory->create(
159 | [
160 | 'miscParams' => $imageMiscParams,
161 | 'filePath' => $originalFilePath,
162 | ]
163 | );
164 | }
165 |
166 | $attributes = $attributes === null ? [] : $attributes;
167 |
168 | $data = [
169 | 'data' => [
170 | 'template' => self::TEMPLATE,
171 | 'image_url' => $imageAsset->getUrl(),
172 | 'width' => $imageMiscParams['image_width'],
173 | 'height' => $imageMiscParams['image_height'],
174 | 'label' => $this->getLabel($product, $imageMiscParams['image_type'] ?? ''),
175 | 'ratio' => $this->getRatio($imageMiscParams['image_width'] ?? 0, $imageMiscParams['image_height'] ?? 0),
176 | 'custom_attributes' => $this->filterCustomAttributes($attributes),
177 | 'class' => $this->getClass($attributes),
178 | 'product_id' => $product->getId(),
179 | ],
180 | ];
181 |
182 | return $this->objectManager->create(ImageBlock::class, $data);
183 | }
184 | }
185 |
--------------------------------------------------------------------------------
/Block/Product/Renderer/Configurable.php:
--------------------------------------------------------------------------------
1 | isProductHasSwatchAttribute() ?
20 | self::SWATCH_RENDERER_TEMPLATE : self::CONFIGURABLE_RENDERER_TEMPLATE;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/Index/Index.php:
--------------------------------------------------------------------------------
1 | resultPageFactory = $resultPageFactory;
22 | parent::__construct($context);
23 | }
24 |
25 | /**
26 | * Execute view action
27 | *
28 | * @return \Magento\Framework\Controller\ResultInterface
29 | */
30 | public function execute()
31 | {
32 | return $this->resultPageFactory->create();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/DeferJS.php:
--------------------------------------------------------------------------------
1 | config->getValue('react_vue_config/junk/remove'));
19 |
20 | if ($removeAdobeJSJunk) {
21 | return;
22 | }
23 | $response = $observer->getEvent()->getData('response');
24 | if (!$response) {
25 | return;
26 | }
27 | $html = $response->getBody();
28 | if ($html == '') {
29 | return;
30 | }
31 | $conditionalJsPattern = '@(?:
112 | // Babel to avoid compilation
113 |
114 |
115 | //Add to the page to render React component
116 |
117 |
118 | //Write you scripts using babel
119 |
135 | ```
136 |
137 | # Magento 2 live reload
138 |
139 | This project aims to solve the case where you want assets served by your Magento app server, but still want reloads triggered from web packs build pipeline.
140 |
141 | Add a script tag to your page pointed at the livereload server
142 |
143 | ```
144 |
145 | ```
146 | For development purposes, better disable browser caching (https://www.technipages.com/google-chrome-how-to-completely-disable-cache)
147 |
148 | Disable react bundle caching for development purposes using Nginx (not tested yet):
149 |
150 | ```
151 | location ~ index_bundle\.js {
152 | add_header Cache-Control no-cache;
153 | expires 0;
154 | }
155 | ```
156 |
--------------------------------------------------------------------------------
/React/React/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env", "@babel/preset-react"],
3 | "plugins": ["@babel/plugin-proposal-class-properties"]
4 | }
5 |
--------------------------------------------------------------------------------
/React/React/.gitignore:
--------------------------------------------------------------------------------
1 | ./node_modules
2 |
--------------------------------------------------------------------------------
/React/React/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react/react",
3 | "description": "",
4 | "type": "magento2-module",
5 | "license": "proprietary",
6 | "authors": [
7 | {
8 | "email": "egorshitikov@gmail.com",
9 | "name": "Yegor Shytikov"
10 | },
11 | {
12 | "email": "sh.kiruh@gmail.com",
13 | "name": "Kirill Shytikov"
14 | }
15 | ],
16 | "minimum-stability": "stable",
17 | "require": {},
18 | "autoload": {
19 | "psr-4": {
20 | "React\\React\\": "React/React"
21 | },
22 | "files": [
23 | "registration.php"
24 | ]
25 | }
26 | }
--------------------------------------------------------------------------------
/ReactInjectPlugin.php:
--------------------------------------------------------------------------------
1 | config->getValue('react_vue_config/react/enable'));
72 | $vueEnabled = boolval($this->config->getValue('react_vue_config/vue/enable'));
73 | /* remove default Magento Junky JS */
74 | $removeAdobeJSJunk = boolval($this->config->getValue('react_vue_config/junk/remove'));
75 | $removeCSSjunk = boolval($this->config->getValue('react_vue_config/css/remove'));
76 | $criticalCSSHTML = boolval($this->config->getValue('react_vue_config/css/critical'));
77 |
78 | if (isset($_GET['css-react']) && $_GET['css-react'] === "false") {
79 | $removeCSSjunk = false;
80 | }
81 | if (isset($_GET['css-react']) && $_GET['css-react'] === "true") {
82 | $removeCSSjunk = true;
83 | }
84 |
85 | if (isset($_GET['js-junk']) && $_GET['js-junk'] === "false") {
86 | $removeAdobeJSJunk = false;
87 | }
88 | if (isset($_GET['js-junk']) && $_GET['js-junk'] === "true") {
89 | $removeAdobeJSJunk = true;
90 | }
91 |
92 | $area = $this->state->getAreaCode();
93 | $pageFilter = ['checkout', 'customer'];
94 |
95 | $request = $objectManager->get(\Magento\Framework\App\Request\Http::class);
96 | $actionName = $request->getFullActionName();
97 | @header("Action-Name: $actionName");
98 | $requestURL = $_SERVER['REQUEST_URI'];
99 | $removeProtection = boolval(boolval(strpos($requestURL, 'checkout')) || boolval(strpos($requestURL, 'customer')) || $area === 'adminhtml');
100 | @header("React-Protection: $removeProtection");
101 | $block = $objectManager->get(\Magento\Framework\View\Element\Template::class);
102 | $assets = $this->processMerge($group->getAll(), $group);
103 | $attributes = $this->getGroupAttributes($group);
104 | $type = $group->getProperties()['content_type'];
105 | $result = '';
106 | $template = '';
107 | $assetOptimized = false;
108 | $assetOptimizedLarge = false;
109 | $assetProductOptimized = false;
110 | $assetCategoryOptimized = false;
111 | $assetNotOptimisedMobile = false;
112 | $optimisedProductCSSFileCriticalPath = false;
113 | $optimisedCategoryCSSFileCriticalPath = false;
114 |
115 | $removeController = in_array($actionName, $this->actionFilter);
116 | $isProduct = in_array($actionName, ['catalog_product_view']);
117 | $isCategory = in_array($actionName, ['catalog_category_view', 'catalogsearch_result_index']);
118 |
119 | try {
120 | /** @var $asset \Magento\Framework\View\Asset\AssetInterface */
121 | // Changes Start
122 | $baseURL = $this->store->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_STATIC);
123 | if ($removeCSSjunk && $type === 'css') {
124 | foreach ($assets as $key => $asset) {
125 | if (in_array($actionName, $this->actionFilter) && strpos($asset->getUrl(), 'styles-m')) {
126 | // http://**/static/version1642788857/frontend/Magento/luma/en_US/css/styles-m.css
127 | $assetNotOptimisedMobile = $asset->getUrl();
128 | $optimisedCSSFileUrl = $baseURL . 'styles-m.css';
129 | $optimisedCSSFilePath = BP . '/pub/static/styles-m.css';
130 |
131 | $optimisedProductCSSFileUrl = $baseURL . 'product-styles-m.css';
132 | $optimisedProductCSSFileCriticalUrl = $baseURL . 'product-critical-m.css';
133 | $optimisedProductCSSFileCriticalPath = BP . '/pub/static/product-critical-m.css';
134 | $optimisedProductCSSFilePath = BP . '/pub/static/product-styles-m.css';
135 |
136 | $optimisedCategoryCSSFileUrl = $baseURL . 'category-styles-m.css';
137 | $optimisedCategoryCSSFilePath = BP . '/pub/static/category-styles-m.css';
138 | $optimisedCategoryCSSFileCriticalUrl = $baseURL . 'category-critical-m.css';
139 | $optimisedCategoryCSSFileCriticalPath = BP . '/pub/static/category-critical-m.css';
140 |
141 | if (file_exists($optimisedCSSFilePath)) {
142 | // echo $optimisedCSSFileUrl;
143 | $assetOptimized = $optimisedCSSFileUrl;
144 | unset($assets[$key]);
145 | }
146 | if (file_exists($optimisedProductCSSFilePath) && $isProduct) {
147 | // echo $optimisedCSSFileUrl;
148 | $assetProductOptimized = $optimisedProductCSSFileUrl;
149 | unset($assets[$key]);
150 | }
151 | if (file_exists($optimisedCategoryCSSFilePath) && $isCategory) {
152 | // echo $optimisedCSSFileUrl;
153 | $assetCategoryOptimized = $optimisedCategoryCSSFileUrl;
154 | unset($assets[$key]);
155 | }
156 |
157 | }
158 | if (in_array($actionName, $this->actionFilter) && strpos($asset->getUrl(), 'styles-l')) {
159 | // http://**/static/version1642788857/frontend/Magento/luma/en_US/css/styles-l.css
160 | $optimisedCSSFileUrlLarge = $baseURL . 'styles-l.css';
161 | $optimisedCSSFilePathLarge = BP . '/pub/static/styles-l.css';
162 | $assetNotOptimisedLarge = $asset->getUrl();
163 | if (file_exists($optimisedCSSFilePathLarge)) {
164 | // echo $optimisedCSSFileUrl;
165 | $assetOptimizedLarge = $optimisedCSSFileUrlLarge;
166 | unset($assets[$key]);
167 | } else {
168 | @header('Optimised-CSS: false');
169 | }
170 | }
171 | if (in_array($actionName, $this->actionFilter) && strpos($asset->getUrl(), 'calendar')) {
172 | unset($assets[$key]);
173 | }
174 | if (in_array($actionName, $this->actionFilter) && strpos($asset->getUrl(), 'gallery')) {
175 | unset($assets[$key]);
176 | }
177 | if (in_array($actionName, $this->actionFilter) && strpos($asset->getUrl(), 'uppy-custom')) {
178 | unset($assets[$key]);
179 | }
180 | }
181 | }
182 | // dump($assets);
183 | foreach ($assets as $key => $asset) {
184 | if ($type === 'js' && $removeAdobeJSJunk) {
185 | if (strpos($asset->getUrl(), 'js/react')) {
186 | unset($assets[$key]);
187 | if ($reactEnabled) {
188 | array_unshift($assets, $asset);
189 | }
190 | }
191 | if (strpos($asset->getUrl(), 'vue')) {
192 | unset($assets[$key]);
193 | if ($vueEnabled) {
194 | array_unshift($assets, $asset);
195 | }
196 | }
197 | if (strpos($asset->getUrl(), 'require')) {
198 | if ($removeAdobeJSJunk)
199 | //dd($removeAdobeJSJunk);
200 | {
201 | unset($assets[$key]);
202 | }
203 |
204 | // junk True ; protection False
205 | // echo "require " . (string) $removeProtection;
206 | if (!$removeAdobeJSJunk || !in_array($actionName, $this->actionFilter));
207 | array_unshift($assets, $asset);
208 | }
209 | if (strpos($asset->getUrl(), 'require')) {
210 | if ($removeAdobeJSJunk)
211 | //dd($removeAdobeJSJunk);
212 | {
213 | unset($assets[$key]);
214 | }
215 |
216 | // junk True ; protection False
217 | // echo "require " . (string) $removeProtection;
218 | if (!$removeAdobeJSJunk || !in_array($actionName, $this->actionFilter));
219 | array_unshift($assets, $asset);
220 | }
221 | }
222 | if ($type === 'css') {
223 | if (strpos($asset->getUrl(), 'styles-')) {
224 | unset($assets[$key]);
225 | if (!$removeCSSjunk || !in_array($actionName, $this->actionFilter)) {
226 | array_unshift($assets, $asset);
227 | }
228 | }
229 | }
230 | }
231 | // we need execute it one more time to make scripts the same order
232 | foreach ($assets as $key => $asset) {
233 | if (strpos($asset->getUrl(), 'require') && $removeAdobeJSJunk) {
234 | unset($assets[$key]);
235 | array_unshift($assets, $asset);
236 | // dd($assets);
237 | }
238 | }
239 |
240 | if ($type === 'js' && $removeAdobeJSJunk) {
241 | foreach ($assets as $key => $asset) {
242 | if (strpos($asset->getUrl(), 'js/react') || strpos($asset->getUrl(), 'vue')) {
243 | unset($assets[$key]);
244 | array_unshift($assets, $asset);
245 | }
246 | }
247 | }
248 |
249 | // Changes Ends
250 |
251 | foreach ($assets as $asset) {
252 | $template = $this->getAssetTemplate(
253 | $group->getProperty(GroupedCollection::PROPERTY_CONTENT_TYPE),
254 | $this->addDefaultAttributes($this->getAssetContentType($asset), $attributes)
255 | );
256 | $result .= sprintf($template, $asset->getUrl());
257 | }
258 | } catch (LocalizedException $e) {
259 | $this->logger->critical($e);
260 | $result .= sprintf($template, $this->urlBuilder->getUrl('', ['_direct' => 'core/index/notFound']));
261 | }
262 |
263 | if ($removeCSSjunk) {
264 | // mobile CSS
265 | if ($assetOptimized && !($assetProductOptimized || $assetCategoryOptimized)) {
266 | $result = '' . "\n" . $result;
267 | }
268 | if ($assetOptimizedLarge) {
269 | $result = '' . "\n" . $result;
270 | }
271 | if ($assetProductOptimized && $isProduct) {
272 | if ($optimisedProductCSSFileCriticalPath && file_exists($optimisedProductCSSFileCriticalPath)) {
273 | if (!$criticalCSSHTML) {
274 | // ToDo: check if push works
275 | @header("Link: <" . $optimisedProductCSSFileCriticalUrl . ">; rel=preload; as=style", false);
276 | $result = '' . "\n" . $result;
277 | }
278 | $result = '' . "\n" . $result;
279 | } else {
280 | $result = '' . "\n" . $result;
281 | }
282 | } else if (!$assetProductOptimized && $isProduct) {
283 | if ($optimisedProductCSSFileCriticalPath && file_exists($optimisedProductCSSFileCriticalPath)) {
284 | $result = '' . "\n" . $result;
285 | $result = '' . "\n" . $result;
286 | }
287 | }
288 | if ($assetCategoryOptimized && $isCategory) {
289 | if ($optimisedCategoryCSSFileCriticalPath && file_exists($optimisedCategoryCSSFileCriticalPath)) {
290 | $result = '' . "\n" . $result;
291 | $result = '' . "\n" . $result;
292 | } else {
293 | $result = '' . "\n" . $result;
294 | }
295 | } else if (!$assetCategoryOptimized && $isCategory) {
296 | if ($optimisedCategoryCSSFileCriticalPath && file_exists($optimisedCategoryCSSFileCriticalPath)) {
297 | $result = '' . "\n" . $result;
298 | $result = '' . "\n" . $result;
299 | }
300 | }
301 | }
302 |
303 | if ($removeAdobeJSJunk && $type === 'js' && $removeController) {
304 | // dd($result);
305 | // Remove RequireJS and other scripts if needed
306 | $result = preg_replace('/@msU';
72 | preg_match_all($conditionalJsPattern, $html, $_matches);
73 | $jsHtml = implode('', $_matches[0]);
74 | $html = preg_replace($conditionalJsPattern, '', $html);
75 | $html .= $jsHtml;
76 |
77 | $result = $html;
78 |
79 | return $result;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/Template.php:
--------------------------------------------------------------------------------
1 | om = $om;
25 | $this->registry = $registry;
26 | $this->config = $config;
27 | parent::__construct($context, $data);
28 | }
29 |
30 | // Function to encode an image as Base64
31 | public function imageToBase64($imagePath)
32 | {
33 | if (file_exists($imagePath)) {
34 | $imageData = file_get_contents($imagePath);
35 | $base64 = base64_encode($imageData);
36 | $mimeType = mime_content_type($imagePath); // Get MIME type
37 | return "data:$mimeType;base64,$base64";
38 | }
39 | return "";
40 | }
41 |
42 | public function removeAdobeJSJunk()
43 | {
44 | if (isset($_GET['js-junk']) && $_GET['js-junk'] === "false") {
45 | return $removeAdobeJSJunk = false;
46 | }
47 | if (isset($_GET['js-junk']) && $_GET['js-junk'] === "true") {
48 | return $removeAdobeJSJunk = true;
49 | }
50 | return boolval($this->config->getValue('react_vue_config/junk/remove'));
51 | }
52 |
53 | public function removeAdobeCSSJunk()
54 | {
55 | if (!isset($_GET['css-react'])) {
56 | return $removeCSSjunk = boolval($this->config->getValue('react_vue_config/junk/remove'));
57 | }
58 |
59 | if (isset($_GET['css-react']) && $_GET['css-react'] === "false") {
60 | $removeCSSjunk = false;
61 | }
62 | if (isset($_GET['css-react']) && $_GET['css-react'] === "true") {
63 | $removeCSSjunk = true;
64 | }
65 | return $removeCSSjunk;
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "genaker/react-luma",
3 | "description": "",
4 | "type": "magento2-module",
5 | "license": "proprietary",
6 | "authors": [
7 | {
8 | "email": "egorshitikov@gmail.com",
9 | "name": "Yegor Shytikov"
10 | },
11 | {
12 | "email": "sh.kiruh@gmail.com",
13 | "name": "Kirill Shytikov"
14 | }
15 | ],
16 | "minimum-stability": "stable",
17 | "require": {},
18 | "autoload": {
19 | "files": [
20 | "registration.php"
21 | ],
22 | "psr-4": {
23 | "React\\React\\": ""
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/etc/acl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/etc/adminhtml/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
--------------------------------------------------------------------------------
/etc/adminhtml/routes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/etc/adminhtml/system.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | react_vue
10 | React_React::config_react_react
11 |
12 |
13 |
14 |
15 | Magento\Config\Model\Config\Source\Yesno
16 | enable VueJS
17 |
18 |
19 |
20 |
21 |
22 |
23 | Magento\Config\Model\Config\Source\Yesno
24 | enable ReactJS
25 |
26 |
27 |
28 |
29 |
30 |
31 | Magento\Config\Model\Config\Source\Yesno
32 | enable GridJS (https://gridjs.io/)
33 |
34 |
35 |
36 |
37 |
38 |
39 | Magento\Config\Model\Config\Source\Yesno
40 | Remove Magento's default JS garbage (Require,Knokout,jQuery). You will need implement required functionality or use Magento Open Source ReactJS Luma Theme
41 |
42 |
43 |
44 |
45 |
46 |
47 | Magento\Config\Model\Config\Source\Yesno
48 | Remove Magento's default CSS garbage. You will need add optimized CSS to pub/static/styles-m.css and pub/static/styles-l.css. The files will be automaticaly included if they are exists
49 |
50 |
51 |
52 | Magento\Config\Model\Config\Source\Yesno
53 | Output Critical CSS to HTML
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 0
7 |
8 |
9 | 0
10 |
11 |
12 | 0
13 |
14 |
15 | 1
16 |
17 |
18 | 1
19 | 1
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/etc/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/etc/frontend/events.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
--------------------------------------------------------------------------------
/etc/module.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "reacttable",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "webpack --mode development --watch",
8 | "build": "webpack --mode production"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "@babel/core": "^7.4.4",
14 | "@babel/plugin-proposal-class-properties": "^7.4.4",
15 | "@babel/preset-env": "^7.4.4",
16 | "@babel/preset-react": "^7.0.0",
17 | "babel-loader": "^8.0.5",
18 | "copy-webpack-plugin": "^5.0.3",
19 | "css-loader": "^2.1.1",
20 | "html-webpack-harddisk-plugin": "^1.0.1",
21 | "style-loader": "^0.23.1",
22 | "webpack": "^4.32.0",
23 | "webpack-cli": "^3.3.2",
24 | "webpack-livereload-plugin": "^2.2.0"
25 | },
26 | "dependencies": {
27 | "html-react-parser": "^0.7.1",
28 | "js-cookie": "^2.2.0",
29 | "react": "^16.8.6",
30 | "react-dom": "^16.8.6"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/pub/static/product-critical-m.css:
--------------------------------------------------------------------------------
1 | body{margin:0;padding:0}header,main,nav{display:block}nav ul{list-style:none none}img{max-width:100%;height:auto;border:0}html{font-size:62.5%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;font-size-adjust:100%}body{color:#333;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;font-size:1.4rem}p{margin-top:0;margin-bottom:1rem}strong{font-weight:700}h1{font-weight:300;line-height:1.1;font-size:2.6rem;margin-top:0;margin-bottom:2rem}a{color:#006bb4;text-decoration:none}a:visited{color:#006bb4;text-decoration:none}ul{margin-top:0;margin-bottom:2.5rem}ul>li{margin-top:0;margin-bottom:1rem}ul ul{margin-bottom:0}button{background-image:none;background:#eee;border:1px solid #ccc;color:#333;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:600;margin:0;padding:7px 15px;font-size:1.4rem;line-height:1.6rem;box-sizing:border-box;vertical-align:middle}button[disabled]{opacity:.5}button::-moz-focus-inner{border:0;padding:0}input[type=number],input[type=text]{background:#fff;background-clip:padding-box;border:1px solid #c2c2c2;border-radius:1px;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:14px;height:32px;line-height:1.42857143;padding:0 9px;vertical-align:baseline;width:100%;box-sizing:border-box}input[type=number]::-moz-placeholder,input[type=text]::-moz-placeholder{color:#575757}input[type=number]::-webkit-input-placeholder,input[type=text]::-webkit-input-placeholder{color:#575757}input[type=number]:-ms-input-placeholder,input[type=text]:-ms-input-placeholder{color:#575757}input[type=number]{-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input::-moz-focus-inner{border:0;padding:0}:focus{box-shadow:none;outline:0}.box-tocart .action.tocart{line-height:2.2rem;padding:14px 17px;font-size:1.8rem}.box-tocart .action.tocart{width:100%}.box-tocart .input-text.qty{text-align:center;width:54px}.block{margin-bottom:40px}.action.skip:not(:focus),.minicart-wrapper .action.showcart .counter-label,.minicart-wrapper .action.showcart .text,.product-item-actions .actions-secondary>.action span{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.header.content:after,.header.content:before{content:'';display:table}.header.content:after{clear:both}.columns .column.main,.search-autocomplete{box-sizing:border-box}.product-item .action.towishlist,.product-item-actions .actions-secondary>.action,.product-social-links .action.tocompare,.product-social-links .action.towishlist{color:#666;font-weight:600;letter-spacing:.05em;text-transform:uppercase;display:inline-block;text-decoration:none}.product-item .action.towishlist:before,.product-item-actions .actions-secondary>.action:before,.product-social-links .action.tocompare:before,.product-social-links .action.towishlist:before{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:16px;line-height:16px;color:inherit;font-family:luma-icons;margin:-2px 5px 0 0;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.product-item .action.towishlist:before,.product-item-actions .actions-secondary>.action:before,.product-social-links .action.tocompare:before,.product-social-links .action.towishlist:before{width:18px}.box-tocart{margin:0 0 30px}.no-display{display:none}.columns{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;box-sizing:border-box}.columns:after{clear:both;content:' ';display:block;height:0;overflow:hidden;visibility:hidden}.columns .column.main{padding-bottom:40px;-webkit-flex-basis:auto;flex-basis:auto;-webkit-flex-grow:1;flex-grow:1;-ms-flex-order:1;-webkit-order:1;order:1;width:100%}.panel.header .links{display:none}.nav-sections{background:#f0f0f0}.nav-toggle{display:inline-block;text-decoration:none;display:block;font-size:0;left:15px;position:absolute;top:15px;z-index:14}.nav-toggle:before{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:28px;line-height:inherit;color:#757575;content:'\e609';font-family:luma-icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.nav-toggle>span{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}button{border-radius:3px}button:not(.primary){box-shadow:none}.action.primary{background-image:none;background:#1979c3;border:1px solid #1979c3;color:#fff;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:600;padding:7px 15px;font-size:1.4rem;box-sizing:border-box;vertical-align:middle}.action.primary[disabled]{opacity:.5}.breadcrumbs{margin:0 0 15px;min-height:24px}.breadcrumbs a{color:#006bb4;text-decoration:none}.breadcrumbs a:visited{color:#006bb4;text-decoration:none}.swatch-attribute-label{font-weight:700;position:relative}.swatch-attribute-selected-option{color:#646464;padding-left:17px}.swatch-attribute-options{margin:10px 0}.swatch-attribute.size .swatch-option{background:#f0f0f0;color:#949494}.swatch-option{border:1px solid #dadada;float:left;height:20px;margin:0 10px 5px 0;max-width:100%;min-width:30px;overflow:hidden;padding:1px 2px;position:relative;text-align:center;text-overflow:ellipsis}.swatch-option.text{background:#f0f0f0;color:#686868;font-size:12px;font-weight:700;line-height:20px;margin-right:7px;min-width:22px;padding:4px 8px}.swatch-opt{margin:20px 0}.swatch-input{left:-1000px;position:absolute;visibility:hidden}.clearfix:after{clear:both;content:'';display:block;height:0;visibility:hidden}.price-container.weee:before{display:none}.product-item-actions>*{font-size:1.4rem}.product-item-actions .actions-secondary{display:inline-block;font-size:1.4rem;vertical-align:middle}.product-item-actions .actions-secondary>.action{line-height:35px;text-align:center;width:35px}.product-item-actions .actions-secondary>.action:before{margin:0}.product-item .tocompare:before{content:'\e61e'}.price-container .price{font-size:1.4rem}.product-info-main .product-info-price{color:#575757;border-bottom:1px solid #c1c1c1;display:table;margin-bottom:15px;width:100%}.product-info-main .product-info-price .price-box{display:inline-block;vertical-align:top;width:auto}.product-info-main .product-info-price .price-box .price-container>span{display:block;margin-bottom:5px}.product-info-main .product-info-price .weee{font-size:1.4rem}.product-info-main .product-info-price .weee .price{font-size:1.4rem;font-weight:600;line-height:16px}.product-info-main .product-info-price .price-wrapper .price{font-size:2.2rem;font-weight:600;line-height:22px}.product-info-main .product-info-price .price{white-space:nowrap}.product-info-main .product.attribute.sku{word-break:break-all;word-wrap:break-word}.product-info-main .product.attribute.sku .type{font-weight:400;margin-right:5px}.product-info-main .product.attribute.sku .type:after{content:'#:'}.product-info-main .product.attribute.sku .value{display:inline-block}.product-info-main .product-add-form{clear:both;padding-top:15px}.product-info-main .product-reviews-summary{float:left}.product-info-main .product-options-bottom .box-tocart{margin-top:20px}.product-info-price .price-box{color:#575757;display:table-cell;padding-bottom:10px;vertical-align:top}.product-info-price .price-box .price-container>span{display:block;margin-bottom:5px}.product-info-price .price-box .price-container .price{font-size:22px;font-weight:600;line-height:22px}.box-tocart .action.tocart{vertical-align:top}.box-tocart .action.tocart:not(:last-child){margin-bottom:15px}.product-social-links{margin:0 0 20px;text-align:center}.product-social-links .action.tocompare:before{content:'\e61e'}.block-search{margin-bottom:0}.block-search .block-title{display:none}.block-search .block-content{margin-bottom:0}.block-search .label{text-decoration:none;display:inline-block;float:right}.block-search .label>span{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.block-search .label:before{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:22px;line-height:28px;color:#757575;content:'\e615';font-family:luma-icons;margin:0 10px 0 0;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.block-search .action.search{display:none}.block-search .control{border-top:1px solid #ccc;clear:both;margin:0 -15px -1px;padding:0 15px}.block-search input{font-size:16px;left:-300%;margin:15px 0;position:absolute}.block-search .nested{display:none}.search-autocomplete{display:none;margin-top:-15px;overflow:hidden;position:absolute;z-index:3}.minicart-wrapper{display:inline-block;position:relative;float:right}.minicart-wrapper:after,.minicart-wrapper:before{content:'';display:table}.minicart-wrapper:after{clear:both}.minicart-wrapper .action.showcart{display:inline-block;text-decoration:none}.minicart-wrapper .action.showcart:before{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:22px;line-height:28px;color:#757575;content:'\e611';font-family:luma-icons;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.minicart-wrapper .block-minicart{margin:0;padding:0;list-style:none none;background:#fff;border:1px solid #bbb;margin-top:4px;min-width:100%;width:320px;z-index:101;box-sizing:border-box;display:none;position:absolute;top:100%;right:-10px;box-shadow:0 3px 3px rgba(0,0,0,.15)}.minicart-wrapper .block-minicart:after,.minicart-wrapper .block-minicart:before{border-bottom-style:solid;content:'';display:block;height:0;position:absolute;width:0}.minicart-wrapper .block-minicart:before{border:6px solid;border-color:transparent transparent #fff transparent;z-index:99}.minicart-wrapper .block-minicart:after{border:7px solid;border-color:transparent transparent #bbb transparent;z-index:98}.minicart-wrapper .block-minicart:before{right:12px;top:-12px}.minicart-wrapper .block-minicart:after{right:11px;top:-14px}.minicart-wrapper .block-minicart{padding:25px 20px}.minicart-wrapper .action.showcart{white-space:nowrap}.minicart-wrapper .action.showcart .counter.qty{background:#ff5501;color:#fff;height:24px;line-height:24px;border-radius:2px;display:inline-block;margin:3px 0 0;min-width:18px;overflow:hidden;padding:0 3px;text-align:center;white-space:normal}.minicart-wrapper .action.showcart .counter.qty.empty{display:none}.minicart-wrapper .action.showcart .counter-number{text-shadow:0 0 7px #000}.block .title{display:block;margin-bottom:10px}.block .title strong{font-weight:700;line-height:1.1;font-size:1.4rem;margin-top:2rem;margin-bottom:2rem}.block.newsletter .title{display:none}.rating-summary{overflow:hidden;white-space:nowrap}.rating-summary .rating-result{width:88px;display:inline-block;position:relative;vertical-align:middle}.rating-summary .rating-result:before{left:0;position:absolute;top:0;width:100%;z-index:1;-webkit-font-smoothing:antialiased;color:#c7c7c7;font-family:luma-icons;font-size:16px;height:16px;letter-spacing:2px;line-height:16px;content:'\e605' '\e605' '\e605' '\e605' '\e605';display:block;font-style:normal;font-weight:400;speak:none}.rating-summary .rating-result>span{display:block;overflow:hidden}.rating-summary .rating-result>span:before{position:relative;z-index:2;-webkit-font-smoothing:antialiased;color:#ff5501;font-family:luma-icons;font-size:16px;height:16px;letter-spacing:2px;line-height:16px;content:'\e605' '\e605' '\e605' '\e605' '\e605';display:block;font-style:normal;font-weight:400;speak:none}.rating-summary .rating-result>span span{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.product-reviews-summary .rating-summary .label{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.review-add .block-title{display:none}.product-reviews-summary{margin-bottom:5px}.product-reviews-summary .rating-summary{display:inline-block;vertical-align:middle}.product-reviews-summary .reviews-actions{display:inline-block;font-size:11px;vertical-align:middle}.product-reviews-summary .reviews-actions a:not(:last-child){margin-right:30px}.product-reviews-summary .reviews-actions .action.add{white-space:nowrap}.product-info-main .rating-summary{margin-right:30px}body{background-color:#fff}.page-wrapper{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;min-height:100vh}.page-main{-webkit-flex-grow:1;flex-grow:1}.page-header{border-bottom:1px solid #ccc;margin-bottom:20px}.page-header .panel.wrapper{background-color:#6e716e;color:#fff}.header.panel>.header.links{margin:0;padding:0;list-style:none none;float:right;font-size:0;margin-left:auto;margin-right:20px}.header.panel>.header.links>li{display:inline-block;vertical-align:top}.header.panel>.header.links>li{font-size:14px;margin:0 0 0 15px}.header.panel>.header.links>li>a{color:#fff;text-decoration:none}.header.panel>.header.links>li>a:visited{color:#fff;text-decoration:none}.header.content{padding-top:10px;position:relative}.logo{float:left;margin:0 0 10px 40px;max-width:50%;position:relative;z-index:5}.logo img{display:block;height:auto}.action-skip-wrapper{height:0;position:relative}.message.global p{margin:0}.message.global.noscript{margin:0 0 10px;padding:12px 20px 12px 25px;display:block;font-size:1.3rem;background:#ffee9c;border-color:#d6ca8e;color:#333;margin:0}.message.global.demo{margin:0 0 10px;padding:12px 20px 12px 25px;display:block;font-size:1.3rem;background:#ff0101;border-color:none;color:#fff;margin-bottom:0;text-align:center}.cookie-status-message{display:none}.product-item .action.towishlist:before,.product-social-links .action.towishlist:before{content:'\e600'}@media only screen and (max-width:768px){.breadcrumbs,.header.content,.navigation,.page-header .header.panel,.page-main{padding-left:15px;padding-right:15px}.navigation{padding:0}.navigation .parent .level-top{display:block;text-decoration:none;position:relative}.navigation .parent .level-top:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:42px;line-height:inherit;color:inherit;content:'\e622';font-family:luma-icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.navigation .parent .level-top:after{position:absolute;right:7px;top:-8px}.nav-sections{-webkit-overflow-scrolling:touch;height:100%;left:calc(-1 * (100% - 54px));overflow:auto;position:fixed;top:0;width:calc(100% - 54px)}.nav-sections .header.links{margin:0;padding:0;list-style:none none;border-bottom:1px solid #d1d1d1}.nav-sections .header.links li{font-size:1.6rem;margin:0}.nav-sections .header.links li>a{border-top:1px solid #d1d1d1}.nav-sections .header.links a{color:#575757;text-decoration:none;display:block;font-weight:700;padding:.8rem 15px}.nav-sections-items{position:relative;z-index:1}.nav-sections-items:after,.nav-sections-items:before{content:'';display:table}.nav-sections-items:after{clear:both}.nav-sections-item-title{background:#e3e3e3;border:solid #d7d7d7;border-width:0 0 1px 1px;box-sizing:border-box;float:left;height:71px;padding-top:24px;text-align:center;width:33.33%}.nav-sections-item-content{box-sizing:border-box;float:right;margin-left:-100%;margin-top:71px;width:100%;padding:25px 0}.nav-sections-item-content:after,.nav-sections-item-content:before{content:'';display:table}.nav-sections-item-content:after{clear:both}.navigation{background:#f0f0f0;box-sizing:border-box}.navigation ul{margin:0;padding:0}.navigation li{margin:0}.navigation a{display:block;padding-top:10px;padding-right:0;padding-bottom:10px;padding-left:15px}.navigation a{color:#575757;text-decoration:none}.navigation .level0{border-top:1px solid #d1d1d1;font-size:1.6rem}.navigation .level0>.level-top{font-weight:700;padding:8px 40px 8px 15px;text-transform:uppercase;word-wrap:break-word}.navigation .level0>.level1{font-weight:600}.navigation li.level0:last-child{border-bottom:1px solid #d1d1d1}.navigation .submenu>li{word-wrap:break-word}.navigation .submenu:not(:first-child){font-weight:400;line-height:1.3;left:auto!important;overflow-x:hidden;padding:0;position:relative;top:auto!important}.navigation .submenu:not(:first-child)>li>a{padding-left:15px}.navigation .submenu:not(:first-child)>li:last-child{margin-bottom:0}.navigation .submenu:not(:first-child) ul{display:block;padding-left:15px}.navigation .submenu:not(:first-child) ul>li{margin:0}.navigation .submenu:not(:first-child) ul>li a{color:#575757;display:block;line-height:normal}.breadcrumbs{display:none}.catalog-product-view .column.main{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.catalog-product-view .product.media{-ms-flex-order:-1;-webkit-order:-1;order:-1}.compare.wrapper{display:none}.block-search{margin-top:10px}.minicart-wrapper{margin-top:10px}.minicart-wrapper:after,.minicart-wrapper:before{content:'';display:table}.minicart-wrapper:after{clear:both}.navigation .parent .level-top:after{font-size:1.6rem;right:10px;top:7px}.logo{margin-bottom:13px;margin-top:4px}}@media only screen and (max-width:639px){.product-info-price{margin:0 -10px 0;width:calc(100% + 2*10px)!important}.product-info-price>:first-child{padding-left:10px}.product-info-price>:last-child{padding-right:10px}}@media only screen and (max-width:479px){.minicart-wrapper .block-minicart{width:290px}}
--------------------------------------------------------------------------------
/registration.php:
--------------------------------------------------------------------------------
1 |
21 |
26 |
27 | )
28 | }
29 | }
30 |
31 | export default AddToCartForm;
32 |
--------------------------------------------------------------------------------
/src/components/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AddToCartForm from './AddToCartForm';
4 | //import jQuery from 'jquery';
5 |
6 | class App extends React.Component {
7 |
8 | constructor(props) {
9 | super(props);
10 | //Add to cart Toggle flag
11 | document.afterAddToCart = false;
12 | document.warrantyPopUpWasOpen = false;
13 |
14 | this.state = {
15 | data: document.global_data_for_react_app,
16 | selected: false,
17 | selectedItem: null,
18 | };
19 |
20 | this.togglePopup = this.togglePopup.bind(this);
21 | }
22 |
23 | togglePopup() {
24 |
25 | }
26 |
27 |
28 | componentDidMount() {
29 | }
30 |
31 |
32 |
33 |
34 | render() {
35 | return (
36 |
37 |
React Component<\h1>
38 |
39 |
40 | );
41 | }
42 | }
43 |
44 | export default App;
45 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './styles/index.css';
4 | import App from './components/App';
5 |
6 | const reactApp = function(){
7 | return {
8 | init(element,parameter) {
9 | console.log('Rendering React Component Into:' + element);
10 | let live = '';
11 | /// Magento site live reloading feature
12 | if (window.location.hostname == 'localhost' || window.location.hostname.includes('loc')){
13 | live ='';
14 | var imported = document.createElement('script');
15 | imported.src = 'http://localhost:35729/livereload.js';
16 | document.head.appendChild(imported);
17 | }
18 |
19 | return ReactDOM.render(, document.getElementById(element));
20 | }
21 | }
22 | }
23 |
24 | define(reactApp);
--------------------------------------------------------------------------------
/src/styles/gridjs.css:
--------------------------------------------------------------------------------
1 | .gridjs-footer button,.gridjs-head button{background-color:transparent;background-image:none;border:none;cursor:pointer;margin:0;outline:none;padding:0}.gridjs-temp{position:relative}.gridjs-head{margin-bottom:5px;padding:5px 1px;width:100%}.gridjs-head:after{clear:both;content:"";display:block}.gridjs-head:empty{border:none;padding:0}.gridjs-container{color:#000;display:inline-block;overflow:hidden;padding:2px;position:relative;z-index:0}.gridjs-footer{background-color:#fff;border-bottom-width:1px;border-color:#e5e7eb;border-radius:0 0 8px 8px;border-top:1px solid #e5e7eb;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.26);display:block;padding:12px 24px;position:relative;width:100%;z-index:5}.gridjs-footer:empty{border:none;padding:0}input.gridjs-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border:1px solid #d2d6dc;border-radius:5px;font-size:14px;line-height:1.45;outline:none;padding:10px 13px}input.gridjs-input:focus{border-color:#9bc2f7;box-shadow:0 0 0 3px rgba(149,189,243,.5)}.gridjs-pagination{color:#3d4044}.gridjs-pagination:after{clear:both;content:"";display:block}.gridjs-pagination .gridjs-summary{float:left;margin-top:5px}.gridjs-pagination .gridjs-pages{float:right}.gridjs-pagination .gridjs-pages button{background-color:#fff;border:1px solid #d2d6dc;border-right:none;outline:none;padding:5px 14px;-webkit-user-select:none;-moz-user-select:none;user-select:none}.gridjs-pagination .gridjs-pages button:focus{border-right:1px solid #d2d6dc;box-shadow:0 0 0 2px rgba(149,189,243,.5);margin-right:-1px;position:relative}.gridjs-pagination .gridjs-pages button:hover{background-color:#f7f7f7;color:#3c4257;outline:none}.gridjs-pagination .gridjs-pages button:disabled,.gridjs-pagination .gridjs-pages button:hover:disabled,.gridjs-pagination .gridjs-pages button[disabled]{background-color:#fff;color:#6b7280;cursor:default}.gridjs-pagination .gridjs-pages button.gridjs-spread{background-color:#fff;box-shadow:none;cursor:default}.gridjs-pagination .gridjs-pages button.gridjs-currentPage{background-color:#f7f7f7;font-weight:700}.gridjs-pagination .gridjs-pages button:last-child{border-bottom-right-radius:6px;border-right:1px solid #d2d6dc;border-top-right-radius:6px}.gridjs-pagination .gridjs-pages button:first-child{border-bottom-left-radius:6px;border-top-left-radius:6px}.gridjs-pagination .gridjs-pages button:last-child:focus{margin-right:0}button.gridjs-sort{background-color:transparent;background-position-x:center;background-repeat:no-repeat;background-size:contain;border:none;cursor:pointer;float:right;height:24px;margin:0;outline:none;padding:0;width:13px}button.gridjs-sort-neutral{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MDEuOTk4IiBoZWlnaHQ9IjQwMS45OTgiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDQwMS45OTggNDAxLjk5OCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZD0iTTczLjA5MiAxNjQuNDUyaDI1NS44MTNjNC45NDkgMCA5LjIzMy0xLjgwNyAxMi44NDgtNS40MjQgMy42MTMtMy42MTYgNS40MjctNy44OTggNS40MjctMTIuODQ3cy0xLjgxMy05LjIyOS01LjQyNy0xMi44NUwyMTMuODQ2IDUuNDI0QzIxMC4yMzIgMS44MTIgMjA1Ljk1MSAwIDIwMC45OTkgMHMtOS4yMzMgMS44MTItMTIuODUgNS40MjRMNjAuMjQyIDEzMy4zMzFjLTMuNjE3IDMuNjE3LTUuNDI0IDcuOTAxLTUuNDI0IDEyLjg1IDAgNC45NDggMS44MDcgOS4yMzEgNS40MjQgMTIuODQ3IDMuNjIxIDMuNjE3IDcuOTAyIDUuNDI0IDEyLjg1IDUuNDI0ek0zMjguOTA1IDIzNy41NDlINzMuMDkyYy00Ljk1MiAwLTkuMjMzIDEuODA4LTEyLjg1IDUuNDIxLTMuNjE3IDMuNjE3LTUuNDI0IDcuODk4LTUuNDI0IDEyLjg0N3MxLjgwNyA5LjIzMyA1LjQyNCAxMi44NDhMMTg4LjE0OSAzOTYuNTdjMy42MjEgMy42MTcgNy45MDIgNS40MjggMTIuODUgNS40MjhzOS4yMzMtMS44MTEgMTIuODQ3LTUuNDI4bDEyNy45MDctMTI3LjkwNmMzLjYxMy0zLjYxNCA1LjQyNy03Ljg5OCA1LjQyNy0xMi44NDggMC00Ljk0OC0xLjgxMy05LjIyOS01LjQyNy0xMi44NDctMy42MTQtMy42MTYtNy44OTktNS40Mi0xMi44NDgtNS40MnoiLz48L3N2Zz4=");background-position-y:center;opacity:.3}button.gridjs-sort-asc{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOTIuMzYyIiBoZWlnaHQ9IjI5Mi4zNjEiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDI5Mi4zNjIgMjkyLjM2MSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZD0iTTI4Ni45MzUgMTk3LjI4NyAxNTkuMDI4IDY5LjM4MWMtMy42MTMtMy42MTctNy44OTUtNS40MjQtMTIuODQ3LTUuNDI0cy05LjIzMyAxLjgwNy0xMi44NSA1LjQyNEw1LjQyNCAxOTcuMjg3QzEuODA3IDIwMC45MDQgMCAyMDUuMTg2IDAgMjEwLjEzNHMxLjgwNyA5LjIzMyA1LjQyNCAxMi44NDdjMy42MjEgMy42MTcgNy45MDIgNS40MjUgMTIuODUgNS40MjVoMjU1LjgxM2M0Ljk0OSAwIDkuMjMzLTEuODA4IDEyLjg0OC01LjQyNSAzLjYxMy0zLjYxMyA1LjQyNy03Ljg5OCA1LjQyNy0xMi44NDdzLTEuODE0LTkuMjMtNS40MjctMTIuODQ3eiIvPjwvc3ZnPg==");background-position-y:35%;background-size:10px}button.gridjs-sort-desc{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOTIuMzYyIiBoZWlnaHQ9IjI5Mi4zNjIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDI5Mi4zNjIgMjkyLjM2MiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZD0iTTI4Ni45MzUgNjkuMzc3Yy0zLjYxNC0zLjYxNy03Ljg5OC01LjQyNC0xMi44NDgtNS40MjRIMTguMjc0Yy00Ljk1MiAwLTkuMjMzIDEuODA3LTEyLjg1IDUuNDI0QzEuODA3IDcyLjk5OCAwIDc3LjI3OSAwIDgyLjIyOGMwIDQuOTQ4IDEuODA3IDkuMjI5IDUuNDI0IDEyLjg0N2wxMjcuOTA3IDEyNy45MDdjMy42MjEgMy42MTcgNy45MDIgNS40MjggMTIuODUgNS40MjhzOS4yMzMtMS44MTEgMTIuODQ3LTUuNDI4TDI4Ni45MzUgOTUuMDc0YzMuNjEzLTMuNjE3IDUuNDI3LTcuODk4IDUuNDI3LTEyLjg0NyAwLTQuOTQ4LTEuODE0LTkuMjI5LTUuNDI3LTEyLjg1eiIvPjwvc3ZnPg==");background-position-y:65%;background-size:10px}button.gridjs-sort:focus{outline:none}table.gridjs-table{border-collapse:collapse;display:table;margin:0;max-width:100%;overflow:auto;padding:0;table-layout:fixed;text-align:left;width:100%}.gridjs-tbody,td.gridjs-td{background-color:#fff}td.gridjs-td{border:1px solid #e5e7eb;box-sizing:content-box;padding:12px 24px}td.gridjs-td:first-child{border-left:none}td.gridjs-td:last-child{border-right:none}td.gridjs-message{text-align:center}th.gridjs-th{background-color:#f9fafb;border:1px solid #e5e7eb;border-top:none;box-sizing:border-box;color:#6b7280;outline:none;padding:14px 24px;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;white-space:nowrap}th.gridjs-th .gridjs-th-content{float:left;overflow:hidden;text-overflow:ellipsis;width:100%}th.gridjs-th-sort{cursor:pointer}th.gridjs-th-sort .gridjs-th-content{width:calc(100% - 15px)}th.gridjs-th-sort:focus,th.gridjs-th-sort:hover{background-color:#e5e7eb}th.gridjs-th-fixed{box-shadow:0 1px 0 0 #e5e7eb;position:sticky}@supports (-moz-appearance:none){th.gridjs-th-fixed{box-shadow:0 0 0 1px #e5e7eb}}th.gridjs-th:first-child{border-left:none}th.gridjs-th:last-child{border-right:none}.gridjs-tr{border:none}.gridjs-tr-selected td{background-color:#ebf5ff}.gridjs-tr:last-child td{border-bottom:0}.gridjs *,.gridjs :after,.gridjs :before{box-sizing:border-box}.gridjs-wrapper{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;border-color:#e5e7eb;border-radius:8px 8px 0 0;border-top-width:1px;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.26);display:block;overflow:auto;position:relative;width:100%;z-index:1}.gridjs-wrapper:nth-last-of-type(2){border-bottom-width:1px;border-radius:8px}.gridjs-search{float:left}.gridjs-search-input{width:250px}.gridjs-loading-bar{background-color:#fff;opacity:.5;z-index:10}.gridjs-loading-bar,.gridjs-loading-bar:after{bottom:0;left:0;position:absolute;right:0;top:0}.gridjs-loading-bar:after{animation:shimmer 2s infinite;background-image:linear-gradient(90deg,hsla(0,0%,80%,0),hsla(0,0%,80%,.2) 20%,hsla(0,0%,80%,.5) 60%,hsla(0,0%,80%,0));content:"";transform:translateX(-100%)}@keyframes shimmer{to{transform:translateX(100%)}}.gridjs-td .gridjs-checkbox{cursor:pointer;display:block;margin:auto}.gridjs-resizable{bottom:0;position:absolute;right:0;top:0;width:5px}.gridjs-resizable:hover{background-color:#9bc2f7;cursor:ew-resize}
2 |
--------------------------------------------------------------------------------
/src/styles/index.css:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/view/adminhtml/layout/default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/view/adminhtml/templates/index/index.phtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
16 |
--------------------------------------------------------------------------------
/view/base/requirejs-config.js:
--------------------------------------------------------------------------------
1 | var config = {
2 | /* map: {
3 | '*': {
4 | 'react': 'React_React/js/react',
5 | 'react-dom': 'React_React/js/react-dom',
6 | 'react-app': 'React_React/js/index_bundle',
7 | }
8 | },*/
9 | };
10 |
--------------------------------------------------------------------------------
/view/base/templates/component.phtml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
18 |
--------------------------------------------------------------------------------
/view/base/templates/react-component.phtml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
18 |
--------------------------------------------------------------------------------
/view/base/templates/vue-component.phtml:
--------------------------------------------------------------------------------
1 |
2 |
{{ message }} -> {{ name }} !
3 |
4 |
--------------------------------------------------------------------------------
/view/base/web/js/htm.module.js:
--------------------------------------------------------------------------------
1 | var n = function (t, s, r, e) {var u;s[0] = 0;for (var h = 1; h < s.length; h++) {var p = s[h++],a = s[h] ? (s[0] |= p ? 1 : 2, r[s[h++]]) : s[++h];3 === p ? e[0] = a : 4 === p ? e[1] = Object.assign(e[1] || {}, a) : 5 === p ? (e[1] = e[1] || {})[s[++h]] = a : 6 === p ? e[1][s[++h]] += a + "" : p ? (u = t.apply(a, n(t, a, r, ["", null])), e.push(u), a[0] ? s[0] |= 2 : (s[h - 2] = 0, s[h] = u)) : e.push(a);}return e;},t = new Map();export default function (s) {var r = t.get(this);return r || (r = new Map(), t.set(this, r)), (r = n(this, r.get(s) || (r.set(s, r = function (n) {for (var t, s, r = 1, e = "", u = "", h = [0], p = function (n) {1 === r && (n || (e = e.replace(/^\s*\n\s*|\s*\n\s*$/g, ""))) ? h.push(0, n, e) : 3 === r && (n || e) ? (h.push(3, n, e), r = 2) : 2 === r && "..." === e && n ? h.push(4, n, 0) : 2 === r && e && !n ? h.push(5, 0, !0, e) : r >= 5 && ((e || !n && 5 === r) && (h.push(r, 0, e, s), r = 6), n && (h.push(r, n, 0, s), r = 6)), e = "";}, a = 0; a < n.length; a++) {a && (1 === r && p(), p(a));for (var l = 0; l < n[a].length; l++) t = n[a][l], 1 === r ? "<" === t ? (p(), h = [h], r = 3) : e += t : 4 === r ? "--" === e && ">" === t ? (r = 1, e = "") : e = t + e[0] : u ? t === u ? u = "" : e += t : '"' === t || "'" === t ? u = t : ">" === t ? (p(), r = 1) : r && ("=" === t ? (r = 5, s = e, e = "") : "/" === t && (r < 5 || ">" === n[a][l + 1]) ? (p(), 3 === r && (h = h[0]), r = h, (h = h[0]).push(2, 0, r), r = 0) : " " === t || "\t" === t || "\n" === t || "\r" === t ? (p(), r = 2) : e += t), 3 === r && "!--" === e && (r = 4, h = h[0]);}return p(), h;}(s)), r), arguments, [])).length > 1 ? r : r[0];}
--------------------------------------------------------------------------------
/view/base/web/js/index_bundle.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Genaker/reactmagento2/a66d7e36b76183634589c684b09bfb832655135d/view/base/web/js/index_bundle.js
--------------------------------------------------------------------------------
/view/base/web/js/preact.module.js:
--------------------------------------------------------------------------------
1 | var n,l,u,i,t,r,o,f,e = {},c = [],s = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function a(n, l) {for (var u in l) n[u] = l[u];return n;}function h(n) {var l = n.parentNode;l && l.removeChild(n);}function v(l, u, i) {var t,r,o,f = {};for (o in u) "key" == o ? t = u[o] : "ref" == o ? r = u[o] : f[o] = u[o];if (arguments.length > 2 && (f.children = arguments.length > 3 ? n.call(arguments, 2) : i), "function" == typeof l && null != l.defaultProps) for (o in l.defaultProps) void 0 === f[o] && (f[o] = l.defaultProps[o]);return y(l, f, t, r, null);}function y(n, i, t, r, o) {var f = { type: n, props: i, key: t, ref: r, __k: null, __: null, __b: 0, __e: null, __d: void 0, __c: null, __h: null, constructor: void 0, __v: null == o ? ++u : o };return null == o && null != l.vnode && l.vnode(f), f;}function p() {return { current: null };}function d(n) {return n.children;}function _(n, l) {this.props = n, this.context = l;}function k(n, l) {if (null == l) return n.__ ? k(n.__, n.__.__k.indexOf(n) + 1) : null;for (var u; l < n.__k.length; l++) if (null != (u = n.__k[l]) && null != u.__e) return u.__e;return "function" == typeof n.type ? k(n) : null;}function b(n) {var l, u;if (null != (n = n.__) && null != n.__c) {for (n.__e = n.__c.base = null, l = 0; l < n.__k.length; l++) if (null != (u = n.__k[l]) && null != u.__e) {n.__e = n.__c.base = u.__e;break;}return b(n);}}function m(n) {(!n.__d && (n.__d = !0) && t.push(n) && !g.__r++ || o !== l.debounceRendering) && ((o = l.debounceRendering) || r)(g);}function g() {for (var n; g.__r = t.length;) n = t.sort(function (n, l) {return n.__v.__b - l.__v.__b;}), t = [], n.some(function (n) {var l, u, i, t, r, o;n.__d && (r = (t = (l = n).__v).__e, (o = l.__P) && (u = [], (i = a({}, t)).__v = t.__v + 1, j(o, t, i, l.__n, void 0 !== o.ownerSVGElement, null != t.__h ? [r] : null, u, null == r ? k(t) : r, t.__h), z(u, t), t.__e != r && b(t)));});}function w(n, l, u, i, t, r, o, f, s, a) {var h,v,p,_,b,m,g,w = i && i.__k || c,A = w.length;for (u.__k = [], h = 0; h < l.length; h++) if (null != (_ = u.__k[h] = null == (_ = l[h]) || "boolean" == typeof _ ? null : "string" == typeof _ || "number" == typeof _ || "bigint" == typeof _ ? y(null, _, null, null, _) : Array.isArray(_) ? y(d, { children: _ }, null, null, null) : _.__b > 0 ? y(_.type, _.props, _.key, null, _.__v) : _)) {if (_.__ = u, _.__b = u.__b + 1, null === (p = w[h]) || p && _.key == p.key && _.type === p.type) w[h] = void 0;else for (v = 0; v < A; v++) {if ((p = w[v]) && _.key == p.key && _.type === p.type) {w[v] = void 0;break;}p = null;}j(n, _, p = p || e, t, r, o, f, s, a), b = _.__e, (v = _.ref) && p.ref != v && (g || (g = []), p.ref && g.push(p.ref, null, _), g.push(v, _.__c || b, _)), null != b ? (null == m && (m = b), "function" == typeof _.type && _.__k === p.__k ? _.__d = s = x(_, s, n) : s = P(n, _, p, w, b, s), "function" == typeof u.type && (u.__d = s)) : s && p.__e == s && s.parentNode != n && (s = k(p));}for (u.__e = m, h = A; h--;) null != w[h] && ("function" == typeof u.type && null != w[h].__e && w[h].__e == u.__d && (u.__d = k(i, h + 1)), N(w[h], w[h]));if (g) for (h = 0; h < g.length; h++) M(g[h], g[++h], g[++h]);}function x(n, l, u) {for (var i, t = n.__k, r = 0; t && r < t.length; r++) (i = t[r]) && (i.__ = n, l = "function" == typeof i.type ? x(i, l, u) : P(u, i, i, t, i.__e, l));return l;}function A(n, l) {return l = l || [], null == n || "boolean" == typeof n || (Array.isArray(n) ? n.some(function (n) {A(n, l);}) : l.push(n)), l;}function P(n, l, u, i, t, r) {var o, f, e;if (void 0 !== l.__d) o = l.__d, l.__d = void 0;else if (null == u || t != r || null == t.parentNode) n: if (null == r || r.parentNode !== n) n.appendChild(t), o = null;else {for (f = r, e = 0; (f = f.nextSibling) && e < i.length; e += 2) if (f == t) break n;n.insertBefore(t, r), o = r;}return void 0 !== o ? o : t.nextSibling;}function C(n, l, u, i, t) {var r;for (r in u) "children" === r || "key" === r || r in l || H(n, r, null, u[r], i);for (r in l) t && "function" != typeof l[r] || "children" === r || "key" === r || "value" === r || "checked" === r || u[r] === l[r] || H(n, r, l[r], u[r], i);}function $(n, l, u) {"-" === l[0] ? n.setProperty(l, u) : n[l] = null == u ? "" : "number" != typeof u || s.test(l) ? u : u + "px";}function H(n, l, u, i, t) {var r;n: if ("style" === l) {if ("string" == typeof u) n.style.cssText = u;else {if ("string" == typeof i && (n.style.cssText = i = ""), i) for (l in i) u && l in u || $(n.style, l, "");if (u) for (l in u) i && u[l] === i[l] || $(n.style, l, u[l]);}} else if ("o" === l[0] && "n" === l[1]) r = l !== (l = l.replace(/Capture$/, "")), l = l.toLowerCase() in n ? l.toLowerCase().slice(2) : l.slice(2), n.l || (n.l = {}), n.l[l + r] = u, u ? i || n.addEventListener(l, r ? T : I, r) : n.removeEventListener(l, r ? T : I, r);else if ("dangerouslySetInnerHTML" !== l) {if (t) l = l.replace(/xlink[H:h]/, "h").replace(/sName$/, "s");else if ("href" !== l && "list" !== l && "form" !== l && "tabIndex" !== l && "download" !== l && l in n) try {n[l] = null == u ? "" : u;break n;} catch (n) {}"function" == typeof u || (null != u && (!1 !== u || "a" === l[0] && "r" === l[1]) ? n.setAttribute(l, u) : n.removeAttribute(l));}}function I(n) {this.l[n.type + !1](l.event ? l.event(n) : n);}function T(n) {this.l[n.type + !0](l.event ? l.event(n) : n);}function j(n, u, i, t, r, o, f, e, c) {var s,h,v,y,p,k,b,m,g,x,A,P = u.type;if (void 0 !== u.constructor) return null;null != i.__h && (c = i.__h, e = u.__e = i.__e, u.__h = null, o = [e]), (s = l.__b) && s(u);try {n: if ("function" == typeof P) {if (m = u.props, g = (s = P.contextType) && t[s.__c], x = s ? g ? g.props.value : s.__ : t, i.__c ? b = (h = u.__c = i.__c).__ = h.__E : ("prototype" in P && P.prototype.render ? u.__c = h = new P(m, x) : (u.__c = h = new _(m, x), h.constructor = P, h.render = O), g && g.sub(h), h.props = m, h.state || (h.state = {}), h.context = x, h.__n = t, v = h.__d = !0, h.__h = []), null == h.__s && (h.__s = h.state), null != P.getDerivedStateFromProps && (h.__s == h.state && (h.__s = a({}, h.__s)), a(h.__s, P.getDerivedStateFromProps(m, h.__s))), y = h.props, p = h.state, v) null == P.getDerivedStateFromProps && null != h.componentWillMount && h.componentWillMount(), null != h.componentDidMount && h.__h.push(h.componentDidMount);else {if (null == P.getDerivedStateFromProps && m !== y && null != h.componentWillReceiveProps && h.componentWillReceiveProps(m, x), !h.__e && null != h.shouldComponentUpdate && !1 === h.shouldComponentUpdate(m, h.__s, x) || u.__v === i.__v) {h.props = m, h.state = h.__s, u.__v !== i.__v && (h.__d = !1), h.__v = u, u.__e = i.__e, u.__k = i.__k, u.__k.forEach(function (n) {n && (n.__ = u);}), h.__h.length && f.push(h);break n;}null != h.componentWillUpdate && h.componentWillUpdate(m, h.__s, x), null != h.componentDidUpdate && h.__h.push(function () {h.componentDidUpdate(y, p, k);});}h.context = x, h.props = m, h.state = h.__s, (s = l.__r) && s(u), h.__d = !1, h.__v = u, h.__P = n, s = h.render(h.props, h.state, h.context), h.state = h.__s, null != h.getChildContext && (t = a(a({}, t), h.getChildContext())), v || null == h.getSnapshotBeforeUpdate || (k = h.getSnapshotBeforeUpdate(y, p)), A = null != s && s.type === d && null == s.key ? s.props.children : s, w(n, Array.isArray(A) ? A : [A], u, i, t, r, o, f, e, c), h.base = u.__e, u.__h = null, h.__h.length && f.push(h), b && (h.__E = h.__ = null), h.__e = !1;} else null == o && u.__v === i.__v ? (u.__k = i.__k, u.__e = i.__e) : u.__e = L(i.__e, u, i, t, r, o, f, c);(s = l.diffed) && s(u);} catch (n) {u.__v = null, (c || null != o) && (u.__e = e, u.__h = !!c, o[o.indexOf(e)] = null), l.__e(n, u, i);}}function z(n, u) {l.__c && l.__c(u, n), n.some(function (u) {try {n = u.__h, u.__h = [], n.some(function (n) {n.call(u);});} catch (n) {l.__e(n, u.__v);}});}function L(l, u, i, t, r, o, f, c) {var s,a,v,y = i.props,p = u.props,d = u.type,_ = 0;if ("svg" === d && (r = !0), null != o) for (; _ < o.length; _++) if ((s = o[_]) && "setAttribute" in s == !!d && (d ? s.localName === d : 3 === s.nodeType)) {l = s, o[_] = null;break;}if (null == l) {if (null === d) return document.createTextNode(p);l = r ? document.createElementNS("http://www.w3.org/2000/svg", d) : document.createElement(d, p.is && p), o = null, c = !1;}if (null === d) y === p || c && l.data === p || (l.data = p);else {if (o = o && n.call(l.childNodes), a = (y = i.props || e).dangerouslySetInnerHTML, v = p.dangerouslySetInnerHTML, !c) {if (null != o) for (y = {}, _ = 0; _ < l.attributes.length; _++) y[l.attributes[_].name] = l.attributes[_].value;(v || a) && (v && (a && v.__html == a.__html || v.__html === l.innerHTML) || (l.innerHTML = v && v.__html || ""));}if (C(l, p, y, r, c), v) u.__k = [];else if (_ = u.props.children, w(l, Array.isArray(_) ? _ : [_], u, i, t, r && "foreignObject" !== d, o, f, o ? o[0] : i.__k && k(i, 0), c), null != o) for (_ = o.length; _--;) null != o[_] && h(o[_]);c || ("value" in p && void 0 !== (_ = p.value) && (_ !== y.value || _ !== l.value || "progress" === d && !_) && H(l, "value", _, y.value, !1), "checked" in p && void 0 !== (_ = p.checked) && _ !== l.checked && H(l, "checked", _, y.checked, !1));}return l;}function M(n, u, i) {try {"function" == typeof n ? n(u) : n.current = u;} catch (n) {l.__e(n, i);}}function N(n, u, i) {var t, r;if (l.unmount && l.unmount(n), (t = n.ref) && (t.current && t.current !== n.__e || M(t, null, u)), null != (t = n.__c)) {if (t.componentWillUnmount) try {t.componentWillUnmount();} catch (n) {l.__e(n, u);}t.base = t.__P = null;}if (t = n.__k) for (r = 0; r < t.length; r++) t[r] && N(t[r], u, "function" != typeof n.type);i || null == n.__e || h(n.__e), n.__e = n.__d = void 0;}function O(n, l, u) {return this.constructor(n, u);}function S(u, i, t) {var r, o, f;l.__ && l.__(u, i), o = (r = "function" == typeof t) ? null : t && t.__k || i.__k, f = [], j(i, u = (!r && t || i).__k = v(d, null, [u]), o || e, e, void 0 !== i.ownerSVGElement, !r && t ? [t] : o ? null : i.firstChild ? n.call(i.childNodes) : null, f, !r && t ? t : o ? o.__e : i.firstChild, r), z(f, u);}function q(n, l) {S(n, l, q);}function B(l, u, i) {var t,r,o,f = a({}, l.props);for (o in u) "key" == o ? t = u[o] : "ref" == o ? r = u[o] : f[o] = u[o];return arguments.length > 2 && (f.children = arguments.length > 3 ? n.call(arguments, 2) : i), y(l.type, f, t || l.key, r || l.ref, null);}function D(n, l) {var u = { __c: l = "__cC" + f++, __: n, Consumer: function (n, l) {return n.children(l);}, Provider: function (n) {var u, i;return this.getChildContext || (u = [], (i = {})[l] = this, this.getChildContext = function () {return i;}, this.shouldComponentUpdate = function (n) {this.props.value !== n.value && u.some(m);}, this.sub = function (n) {u.push(n);var l = n.componentWillUnmount;n.componentWillUnmount = function () {u.splice(u.indexOf(n), 1), l && l.call(n);};}), n.children;} };return u.Provider.__ = u.Consumer.contextType = u;}n = c.slice, l = { __e: function (n, l) {for (var u, i, t; l = l.__;) if ((u = l.__c) && !u.__) try {if ((i = u.constructor) && null != i.getDerivedStateFromError && (u.setState(i.getDerivedStateFromError(n)), t = u.__d), null != u.componentDidCatch && (u.componentDidCatch(n), t = u.__d), t) return u.__E = u;} catch (l) {n = l;}throw n;} }, u = 0, i = function (n) {return null != n && void 0 === n.constructor;}, _.prototype.setState = function (n, l) {var u;u = null != this.__s && this.__s !== this.state ? this.__s : this.__s = a({}, this.state), "function" == typeof n && (n = n(a({}, u), this.props)), n && a(u, n), null != n && this.__v && (l && this.__h.push(l), m(this));}, _.prototype.forceUpdate = function (n) {this.__v && (this.__e = !0, n && this.__h.push(n), m(this));}, _.prototype.render = d, t = [], r = "function" == typeof Promise ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, g.__r = 0, f = 0;export { S as render, q as hydrate, v as createElement, v as h, d as Fragment, p as createRef, i as isValidElement, _ as Component, B as cloneElement, D as createContext, A as toChildArray, l as options };
--------------------------------------------------------------------------------
/view/base/web/js/react-dom.js:
--------------------------------------------------------------------------------
1 | /**
2 | * ReactDOM v15.3.2
3 | *
4 | * Copyright 2013-present, Facebook, Inc.
5 | * All rights reserved.
6 | *
7 | * This source code is licensed under the BSD-style license found in the
8 | * LICENSE file in the root directory of this source tree. An additional grant
9 | * of patent rights can be found in the PATENTS file in the same directory.
10 | *
11 | */
12 | // Based off https://github.com/ForbesLindesay/umd/blob/master/template.js
13 | ;(function(f) {
14 | // CommonJS
15 | if (typeof exports === "object" && typeof module !== "undefined") {
16 | module.exports = f(require('react'));
17 |
18 | // RequireJS
19 | } else if (typeof define === "function" && define.amd) {
20 | define(['react'], f);
21 |
22 | //
21 |
22 | Vue.js production version, optimized for size and speed
23 |
24 | -->
25 |
26 |
27 |
28 |
29 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/view/frontend/templates/product/breadcrumbs.phtml:
--------------------------------------------------------------------------------
1 | getData('viewModel');
13 | $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
14 | $product = $objectManager->get('Magento\Framework\Registry')->registry('current_product');
15 | $collection = $objectManager->get(Collection::class);
16 | $categoryHelper = $objectManager->get(\Magento\Catalog\Helper\Data::class);
17 | $categoryIds = $product->getCategoryIds();
18 |
19 | $categoryPath = [];
20 |
21 | if (!empty($categoryIds)) {
22 |
23 | $categoryRepository = $objectManager->get(\Magento\Catalog\Model\CategoryRepository::class);
24 |
25 | // Get the category with the **deepest path** (most specific category)
26 | $maxLevel = 0;
27 | $selectedCategory = null;
28 |
29 | $categories = $collection->addAttributeToSelect('entity_id')
30 | ->addFieldToFilter('entity_id', ['in' => $categoryIds])->getItems();
31 |
32 | // Stupid Adobe doesn't have getList for categories for prefetch...
33 | //$categoryList = $categoryRepository->getList($searchCriteria)->getItems();
34 |
35 | foreach ($categories as $category) {
36 | try {
37 | if ($category->getLevel() > $maxLevel) {
38 | $maxLevel = $category->getLevel();
39 | $selectedCategory = $category;
40 | }
41 | } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
42 | continue;
43 | }
44 | }
45 |
46 | // If we have a selected category, build its breadcrumb path
47 | if ($selectedCategory) {
48 | $pathIds = explode('/', $selectedCategory->getPath()); // Category path
49 |
50 | foreach ($pathIds as $pathId) {
51 | if ($pathId > 1) { // Ignore root category (ID:1)
52 | try {
53 | $parentCategory = $categoryRepository->get($pathId);
54 | $categoryPath[] = [
55 | 'label' => $parentCategory->getName(),
56 | 'link' => $parentCategory->getUrl(),
57 | ];
58 | } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
59 | continue;
60 | }
61 | }
62 | }
63 | }
64 | }
65 |
66 | $endTime = microtime(true);
67 | $time = $endTime - $startTime;
68 |
69 | // Regularly: 4-10ms.
70 | //header("Server-Timing: x-mag-bread;dur=" . number_format($time * 1000, 2), false);
71 |
72 | unset($categoryPath[0]);
73 | ?>
74 |
152 |
169 |
170 | helper(\Magento\Framework\Json\Helper\Data::class)->jsonDecode($viewModel->getJsonConfigurationHtmlEscaped());
172 | //$widgetOptions = $this->helper(\Magento\Framework\Json\Helper\Data::class)->jsonEncode($widget['breadcrumbs']);
173 | //dd($widgetOptions);
174 | ?>
--------------------------------------------------------------------------------
/view/frontend/templates/product/image_with_borders.phtml:
--------------------------------------------------------------------------------
1 |
7 | getWidth();
12 | $height = (int) $block->getHeight();
13 | $paddingBottom = $block->getRatio() * 100;
14 | if (!isset($_GET['cat_image'])) {
15 | $_GET['cat_image'] = 0;
16 | }
17 | $_GET['cat_image']++;
18 | ?>
19 |
20 |
21 |
getCustomAttributes() as $name => $value): ?>
23 | =$escaper->escapeHtmlAttr($name)?>="=$escaper->escapeHtml($value)?>"
24 |
25 | src="=$escaper->escapeUrl($block->getImageUrl())?>"
26 | 2) { ?>
27 |
28 | loading="lazy"
29 |
30 | width="=$escaper->escapeHtmlAttr($block->getWidth())?>"
31 | height="=$escaper->escapeHtmlAttr($block->getHeight())?>"
32 | alt="=$escaper->escapeHtmlAttr($block->getLabel())?>"/>
33 |
34 | getProductId()} {
37 | width: {$width}px;
38 | height: auto;
39 | aspect-ratio: {$width} / {$height};
40 | }
41 | .product-image-container-{$block->getProductId()} span.product-image-wrapper {
42 | height: 100%;
43 | width: 100%;
44 | }
45 | @supports not (aspect-ratio: auto) {
46 | .product-image-container-{$block->getProductId()} span.product-image-wrapper {
47 | padding-bottom: {$paddingBottom}%;
48 | }
49 | }
50 | STYLE;
51 | ?>
52 | =/* @noEscape */$secureRenderer->renderTag('style', [], $styles, false)?>
53 |
--------------------------------------------------------------------------------
/view/frontend/templates/product/listing/renderer.phtml:
--------------------------------------------------------------------------------
1 | getProduct()
14 | ?>
15 | isAvailable()): ?>
16 | getId() ?>
17 |
18 | getConfigurableViewModel() ?>
19 |
21 | ".product-item-details",
23 | "onlySwatches" => true,
24 | "enableControlLabel" => false,
25 | "numberToShow" => json_decode($block->escapeJs($block->getNumberSwatchesPerProduct()), true),
26 | "jsonConfig"=> json_decode($block->getJsonConfig(), true),
27 | "jsonSwatchConfig"=> json_decode($block->getJsonSwatchConfig(), true),
28 | "mediaCallback" => json_decode($block->escapeJs($block->escapeUrl($block->getMediaCallback())), true),
29 | "jsonSwatchImageSizeConfig" => json_decode($block->getJsonSwatchSizeConfig(), true),
30 | "showTooltip"=> json_decode($block->escapeJs($configurableViewModel->getShowSwatchTooltip()), true)];
31 |
32 | $configurableImages = $swatchData["jsonConfig"]['images'];
33 | $swatchConfig = $swatchData["jsonConfig"];
34 | $swatchAttributes = $swatchData["jsonSwatchConfig"];
35 | ?>
36 |
38 | {
39 | "[data-role=priceBox][data-price-box=product-id-= $block->escapeJs($productId) ?>]": {
40 | "priceBox": {
41 | "priceConfig": {
42 | "priceFormat": = $block->getPriceFormatJson() ?>,
43 | "prices": = $block->getPricesJson() ?>
44 | }
45 | }
46 | }
47 | }
48 |
49 | */
50 | ?>
51 |
52 |
--------------------------------------------------------------------------------
/view/frontend/templates/product/view/gallery.phtml:
--------------------------------------------------------------------------------
1 |
14 |
15 | getProduct();
17 | $images = $block->getGalleryImages()->getItems();
18 | $mainImage = current(array_filter($images, function ($img) use ($block) {
19 | return $block->isMainImage($img);
20 | }));
21 |
22 | if (!empty($images) && empty($mainImage)) {
23 | $mainImage = $block->getGalleryImages()->getFirstItem();
24 | }
25 |
26 | // Function to encode an image as Base64
27 | function imageToBase64($imagePath)
28 | {
29 | if (file_exists($imagePath)) {
30 | $imageData = file_get_contents($imagePath);
31 | $base64 = base64_encode($imageData);
32 | $mimeType = mime_content_type($imagePath); // Get MIME type
33 | return "data:$mimeType;base64,$base64";
34 | }
35 | return "";
36 | }
37 |
38 |
39 | $helper = $block->getData('imageHelper');
40 | $mainImageData = $mainImage ?
41 | $mainImage->getData('medium_image_url') :
42 | $helper->getDefaultPlaceholderUrl('image');
43 | $imageWidth = $block->getImageAttribute('product_page_image_medium', 'width');
44 | $imageHeight = $block->getImageAttribute('product_page_image_medium', 'height');
45 | $mobileImage = $helper->init($product, 'product_page_image_small')->resize(365, 260)->keepAspectRatio(true)->setQuality(85);
46 | $mobileImageUrl = $mobileImage->getUrl();
47 |
48 | if (true) {
49 | $mobileImagePath = BP . '/pub/' . parse_url($mobileImageUrl, PHP_URL_PATH);
50 | $mobileImageUrl = imageToBase64($mobileImagePath);
51 | }
52 | //dd($mobileImagePath);
53 | $gallaryData = $block->getGalleryImagesJson();
54 |
55 | $images = json_decode($gallaryData, true);
56 | //dump($images);
57 | ?>
58 |
59 |
60 |
61 |
62 |
63 |
64 | $image): ?>
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | 1): foreach ($images as $image): ?>
79 |
![<?=$image['caption'];?>](<?=$image['thumb'];?>)
80 |
81 | @media (max-width: 768px) {.gallery {min-height: 255px !important;}";}?>
82 |
83 |
84 |
85 |
86 |
90 |
91 |
162 |
163 |
236 |
264 |
265 |
--------------------------------------------------------------------------------
/view/frontend/templates/product/view/renderer.phtml:
--------------------------------------------------------------------------------
1 |
7 | getConfigurableViewModel()
11 | ?>
12 |
13 | json_decode($block->getJsonConfig(), true),
17 | "jsonSwatchConfig" => json_decode($block->getJsonSwatchConfig(), true),
18 | "mediaCallback" => json_decode($block->escapeJs($block->escapeUrl($block->getMediaCallback())), true),
19 | "jsonSwatchImageSizeConfig" => json_decode($block->getJsonSwatchSizeConfig(), true),
20 | "showTooltip" => json_decode($block->escapeJs($configurableViewModel->getShowSwatchTooltip()), true),
21 | ];
22 |
23 | $configurableImages = $swatchData["jsonConfig"]['images'];
24 | $swatchConfig = $swatchData["jsonConfig"];
25 | $swatchAttributes = $swatchData["jsonSwatchConfig"];
26 |
27 | $optionToImage = [];
28 | $imageIndex = $swatchData["jsonConfig"]['index'];
29 | foreach ($imageIndex as $imageId => $options) {
30 | foreach ($options as $option) {
31 | $optionToImage[$option] = $imageId;
32 | }
33 | }
34 |
35 | //dd($optionToImage);
36 | $configurableGallary = [];
37 |
38 | foreach ($configurableImages as $productId => $images) {
39 | $galleryHtml = '
40 |
';
41 |
42 | // Loop through images to find the main image
43 | foreach ($images as $image) {
44 | if ($image['isMain']) {
45 | $galleryHtml .= '
![' . htmlspecialchars($image['caption']) . '](' . $image['img'] . ')
';
46 | }
47 | }
48 |
49 | $galleryHtml .= '
50 |
';
51 |
52 | // Loop through images to generate thumbnails
53 | foreach ($images as $image) {
54 | $galleryHtml .= '
![' . htmlspecialchars($image['caption']) . '](' . $image['thumb'] . ')
';
63 | }
64 |
65 | $galleryHtml .= '
66 |
';
67 |
68 | // Store the generated HTML in the array
69 | $configurableGallery[$productId] = $galleryHtml;
70 | }
71 |
72 | ?>
73 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | $swatchData): ?>
86 |
89 |
90 |
=$escaper->escapeHtml($swatchData['label'])?>
92 |
93 |
94 |
95 | $optionData): ?>
96 |
100 |
101 |
107 | =$optionData['type'] == 0 ? $escaper->escapeHtml($optionData['value']) : ''?>
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
210 |
--------------------------------------------------------------------------------
/view/frontend/templates/react-footer-css.phtml:
--------------------------------------------------------------------------------
1 | registry->registry('current_product');
3 | ?>
4 |
5 |
6 |
7 |
8 |
9 |
288 |
--------------------------------------------------------------------------------
/view/frontend/templates/react-footer.phtml:
--------------------------------------------------------------------------------
1 |
7 |
8 | removeAdobeJSJunk()) {
10 | if(!$inlineJs) {
11 | ?>
12 |
13 | getInlineJs('react-core.js');
16 | }
17 | }
18 | ?>
19 |
20 |
--------------------------------------------------------------------------------
/view/frontend/templates/react-header-css.phtml:
--------------------------------------------------------------------------------
1 |
2 |
59 |
156 |
--------------------------------------------------------------------------------
/view/frontend/templates/react-header.phtml:
--------------------------------------------------------------------------------
1 | registry->registry('current_product') ? true : false;
3 | $criticalCSSHTML = boolval($this->config->getValue('react_vue_config/css/critical'));
4 |
5 | if ($criticalCSSHTML || isset($_GET['css-html'])) {
6 | $criticalCSSHTML = true;
7 | }
8 | if ($isProductPage && $criticalCSSHTML) {
9 | $css = @file_get_contents(BP . '/pub/static/product-critical-m.css');
10 | ?>
11 |
14 |
16 |
34 |
35 |
36 | removeAdobeJSJunk()) {
38 | ?>
39 |
49 |
52 |
53 |
--------------------------------------------------------------------------------
/view/frontend/templates/topmenu-account.phtml:
--------------------------------------------------------------------------------
1 |
20 |
--------------------------------------------------------------------------------
/view/frontend/web/js/cash.js:
--------------------------------------------------------------------------------
1 | //CAsh v1.0.0
2 | "use strict";!function(t,e){"function"==typeof define&&define.amd?define(e):"undefined"!=typeof exports?module.exports=e():t.cash=t.$=e()}(this,function(){function t(e,n){return new t.fn.init(e,n)}function e(t){var e=e||s.createDocumentFragment(),n=n||e.appendChild(s.createElement("div"));return n.innerHTML=t,n}function n(t,e){return parseInt(u.getComputedStyle(t[0],null)[e],10)}function i(){function t(t){var e=(Math.random().toString(16)+"000000000").substr(2,8);return t?"-"+e.substr(0,4)+"-"+e.substr(4,4):e}return t()+t(!0)+t(!0)+t()}function r(e,n,r){var s=t(e).data("cshid")||i();t(e).data("cshid",s),s in p||(p[s]={}),n in p[s]||(p[s][n]=[]),p[s][n].push(r)}var s=document,u=window,c=Array.prototype,a=c.slice,h=c.filter,o=/^#[\w-]*$/,f=/^\.[\w-]*$/,l=/^[\w-]*$/,d=t.fn=t.prototype={cash:!0,length:0};d.init=function(e,n){var i,r,u=[];if(!e)return this;if(this.length=1,"string"!=typeof e)return e.cash?e:(this[0]=e,this);if("<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3)u=t.parseHTML(e);else{if(i=o.test(e),r=e.slice(1),!n&&i)return this[0]=s.getElementById(r),this;n=t(n)[0]||s,u=a.call(l.test(r)?f.test(e)?s.getElementsByClassName(r):s.getElementsByTagName(e):n.querySelectorAll(e))}return this.length=0,t.merge(this,u),this},d.init.prototype=d,t.each=function(t,e){for(var n=t.length,i=0;n>i;i++)e.call(t[i],t[i],i,t)},t.extend=d.extend=function(t,e){var n;e||(e=t,t=this);for(n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t},t.matches=function(t,e){return(t.matches||t.matchesSelector||t.msMatchesSelector||t.mozMatchesSelector||t.webkitMatchesSelector||t.oMatchesSelector).call(t,e)},t.merge=function(t,e){for(var n=+e.length,i=t.length,r=0;n>r;i++,r++)t[i]=e[r];return t.length=i,t},t.parseHTML=function(t){var n=/^<(\w+)\s*\/?>(?:<\/\1>|)$/.exec(t);return n?[s.createElement(n[1])]:(n=e(t),a.call(n.childNodes))},t.unique=function(e){return t.merge(t(),a.call(e).filter(function(t,e,n){return n.indexOf(t)===e}))};var m=/\S+/g;d.extend({addClass:function(t){var e,n,i=t.match(m);return this.each(function(t){if(n=i.length,t.classList)for(;n--;)t.classList.add(i[n]);else for(;n--;)e=" "+t.className+" ",-1===e.indexOf(" "+i[n]+" ")&&(t.className+=" "+i[n])}),this},attr:function(t,e){return e?(this.each(function(n){return n.setAttribute(t,e)}),this):this[0].getAttribute(t)},hasClass:function(t){return this[0].classList?this[0].classList.contains(t):-1!==this[0].className.indexOf(t)},prop:function(t){return this[0][t]},removeAttr:function(t){return this.each(function(e){return e.removeAttribute(t)}),this},removeClass:function(t){var e,n,i=t.match(m);return this.each(function(t){if(e=i.length,t.classList)for(;e--;)t.classList.remove(i[e]);else{for(n=" "+t.className+" ";e--;)n=n.replace(" "+i[e]+" "," ");t.className=n.trim()}}),this}}),d.extend({add:function(){var e,n=a.call(this),i=0;for(e=arguments.length;e>i;i++)n=n.concat(a.call(t(arguments[i])));return t.unique(n)},each:function(e){t.each(this,e)},eq:function(e){return t(this[e])},filter:function(e){return"string"==typeof e?h.call(this,function(n){return t.matches(n,e)}):h.call(this,e)},first:function(){return t(this[0])},get:function(t){return this[t]},index:function(e){return e?a.call(t(e).children()).indexOf(this[0]):a.call(t(this[0]).parent().children()).indexOf(this[0])},last:function(){return t(this[this.length-1])}}),d.extend({css:function(t,e){return"object"!=typeof t?e?(this.each(function(n){return n.style[t]=e}),this):u.getComputedStyle(this[0],null)[t]:void this.each(function(e){for(var n in t)t.hasOwnProperty(n)&&(e.style[n]=t[n])})}}),d.extend({data:function(e,n){return n?(this.each(function(i){i.dataset?i.dataset[e]=n:t(i).attr("data-"+e,n)}),this):this[0].dataset?this[0].dataset[e]:t(this[0]).attr("data-"+e)},removeData:function(e){return this.each(function(n){n.dataset?delete n.dataset[e]:t(n).removeAttr("data-"+e)}),this}}),d.extend({height:function(){return this[0].getBoundingClientRect().height},innerWidth:function(){return this[0].clientWidth},innerHeight:function(){return this[0].clientHeight},outerWidth:function(t){return t===!0?this[0].offsetWidth+(n(this,"margin-left")||n(this,"marginLeft")||0)+(n(this,"margin-right")||n(this,"marginRight")||0):this[0].offsetWidth},outerHeight:function(t){return t===!0?this[0].offsetHeight+(n(this,"margin-top")||n(this,"marginTop")||0)+(n(this,"margin-bottom")||n(this,"marginBottom")||0):this[0].offsetHeight},width:function(){return this[0].getBoundingClientRect().width}});var p={};d.extend({off:function(e,n){return this.each(function(i){if(n)i.removeEventListener(e,n);else for(var r in p[t(i).data("cshid")][e])i.removeEventListener(e,p[t(i).data("cshid")][e][r])}),this},on:function(e,n,i){return"function"==typeof n?(i=n,this.each(function(n){r(t(n),e,i),n.addEventListener(e,i)}),this):(this.each(function(s){function u(e){var r=e.target;if(t.matches(r,n))i.call(r);else{for(;!t.matches(r,n);){if(r===s)return r=!1;r=r.parentNode}r&&i.call(r)}}r(t(s),e,u),s.addEventListener(e,u)}),this)},ready:function(t){this[0].addEventListener("DOMContentLoaded",t)},trigger:function(t){var e=s.createEvent("HTMLEvents");return e.initEvent(t,!0,!1),this.each(function(t){return t.dispatchEvent(e)}),this}});var g=encodeURIComponent;return d.extend({serialize:function(){var t,e,n,i=this[0],r="";for(e=i.elements.length-1;e>=0;e--)if(t=i.elements[e],t.name&&"file"!==t.type&&"reset"!==t.type)if("select-multiple"===t.type)for(n=i.elements[e].options.length-1;n>=0;n--)t.options[n].selected&&(r+="&"+t.name+"="+g(t.options[n].value).replace(/%20/g,"+"));else"submit"!==t.type&&"button"!==t.type&&(r+="&"+t.name+"="+g(t.value).replace(/%20/g,"+"));return r.substr(1)},val:function(t){return void 0===t?this[0].value:(this.each(function(e){return e.value=t}),this)}}),d.extend({append:function(e){return this[0].appendChild(t(e)[0]),this},appendTo:function(e){return t(e)[0].appendChild(this[0]),this},clone:function(){return t(this[0].cloneNode(!0))},empty:function(){return this.each(function(t){return t.innerHTML=""}),this},html:function(e){var n;return"undefined"===e?this[0].innerHTML:(n="object"==typeof e?t(e)[0].outerHTML:e,this.each(function(t){return t.innerHTML=""+n}),this)},insertAfter:function(e){return t(e)[0].insertAdjacentHTML("afterend",this[0].outerHTML),this},insertBefore:function(e){return t(e)[0].insertAdjacentHTML("beforebegin",this[0].outerHTML),this},prepend:function(e){return t(this)[0].insertAdjacentHTML("afterBegin",t(e)[0].outerHTML),this},prependTo:function(e){return t(e)[0].insertAdjacentHTML("afterBegin",this[0].outerHTML),this},remove:function(){this.each(function(t){return t.parentNode.removeChild(t)})},text:function(t){return t?(this.each(function(e){return e.textContent=t}),this):this[0].textContent}}),d.extend({children:function(e){return e?t(this[0].children).filter(function(n){return t.matches(n,e)}):t.fn.extend(this[0].children,t.fn)},closest:function(e){return!e||t.matches(this[0],e)?this:this.parent().closest(e)},is:function(e){return e?e.cash?this[0]===e[0]:"string"==typeof e?t.matches(this[0],e):!1:!1},find:function(e){return t.fn.extend(this[0].querySelectorAll(e),t.fn)},has:function(e){return h.call(this,function(n){return 0!==t(n).find(e).length})},next:function(){return t(this[0].nextElementSibling)},not:function(e){return h.call(this,function(n){return!t.matches(n,e)})},parent:function(){var e=c.map.call(this,function(t){return t.parentElement||s.body.parentNode});return t.unique(e)},parents:function(e){var n,i=[],r=0;return this.each(function(u){for(n=u;n!==s.body.parentNode;)n=n.parentElement,(!e||e&&t.matches(n,e))&&(i[r]=n,r++)}),t.unique(i)},prev:function(){return t(this[0].previousElementSibling)},siblings:function(){var t=this.parent().children(),e=this[0];return h.call(t,function(t){return t!==e})}}),t});
--------------------------------------------------------------------------------
/view/frontend/web/js/react-core.js:
--------------------------------------------------------------------------------
1 | var mage = (() => {
2 | var loaded = false;
3 | var localStorage = window.localStorage;
4 | var doc = document;
5 | window.addEventListener('load', () => {
6 | loaded = true;
7 | });
8 |
9 | function isLoaded(){
10 | return loaded;
11 | }
12 |
13 | function getCookie(name) {
14 | let match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
15 | return match ? decodeURIComponent(match[2]) : null;
16 | }
17 |
18 | function setCookie(name, value, days = 7, path = "/") {
19 | let expires = "";
20 | if (days) {
21 | let date = new Date();
22 | date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
23 | expires = "; expires=" + date.toUTCString();
24 | }
25 | document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}${expires}; path=${path}`;
26 | }
27 |
28 | function displayMessages() {
29 | const cookieMessages = getCookie('mage-messages'); // Ensure the cookie name matches Magento's setup
30 | if (!cookieMessages) return;
31 |
32 | try {
33 | let messages = JSON.parse(cookieMessages);
34 | if (!Array.isArray(messages) || messages.length === 0) return;
35 | const messageContainer = document.querySelector('.page.messages');
36 |
37 | messageContainer.innerHTML = ""; // Clear existing messages
38 |
39 | messages.forEach(message => {
40 | let messageDiv = document.createElement("div");
41 | messageContainer.style.display = "block";
42 | messageDiv.className = `message-${message.type} ${message.type} message`;
43 | messageDiv.setAttribute("data-ui-id", `message-${message.type}`);
44 | messageDiv.innerHTML = `${message.text}
`;
45 |
46 | messageContainer.appendChild(messageDiv);
47 | });
48 | document.cookie = "mage-messages=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
49 | // Optionally, clear messages after 5 seconds
50 | setTimeout(() => {
51 | const messageContainer = document.querySelector('.page.messages');
52 | const messageDiv = document.querySelector("message");
53 | messageContainer.innerHTML = "";
54 | messageContainer.style.display = "none";
55 | }, 10000);
56 | } catch (error) {
57 | console.error("Error parsing messages from cookie:", error);
58 | }
59 | }
60 |
61 | const defaultSectionData = [
62 | "messages", "customer",
63 | "compare-products",
64 | "last-ordered-items",
65 | "cart", "wishlist",
66 | "loggedAsCustomer"
67 | ];
68 |
69 | async function loadSectionData(sections=defaultSectionData) {
70 | try {
71 | let valid = false;
72 | let data = null;
73 | const privateContentVersionCokies = getCookie('private_content_version');
74 | const privateContentVersionLocal = localStorage.getItem('private_content_version');
75 | const url = BASE_URL+`customer/section/load/?sections=${encodeURIComponent(sections.join(','))}`;
76 |
77 | if(privateContentVersionCokies && privateContentVersionLocal &&
78 | privateContentVersionCokies === privateContentVersionLocal) {
79 | const ttl = new Date(localStorage.getItem('mage-cache-timeout'));
80 | if (ttl < new Date()) {
81 | valid = false
82 | localStorage.removeItem('mage-cache-storage');
83 | localStorage.removeItem('mage-cache-timeout');
84 | localStorage.removeItem('private_content_version');
85 | } else {
86 | valid = true
87 | data = JSON.parse(localStorage.getItem('mage-cache-storage'));
88 | }
89 | }
90 | if (!valid){
91 | const request = new Request(url,
92 | {
93 | method: 'GET',
94 | cache: 'no-store',
95 | headers: {
96 | 'Content-Type': 'application/json',
97 | 'X-Requested-With': 'XMLHttpRequest'
98 | }
99 | }
100 | );
101 | const response = await fetch(request);
102 |
103 | if (!response.ok) {
104 | throw new Error(`Failed to fetch data: ${response.status} ${response.statusText}`);
105 | }
106 |
107 | data = await response.json();
108 | localStorage.setItem('mage-cache-storage', JSON.stringify(data));
109 | localStorage.setItem('mage-cache-timeout', new Date(Date.now() + (3600 * 1000)).toISOString());
110 | const version = getCookie('private_content_version');
111 | localStorage.setItem('private_content_version', version);
112 |
113 | setCookie(
114 | 'section_data_ids',
115 | JSON.stringify(
116 | Object.keys(data).reduce((ids, key) => {
117 | ids[key] = data[key]['data_id'];
118 | return ids;
119 | }, {})
120 | ),
121 | false,
122 | true
123 | );
124 | }
125 | if(typeof data === null){
126 | console.log("Private Data issue");
127 | }
128 |
129 | //console.log("Fetched private content:", data);
130 | updateCartData(data.cart);
131 | updateCustomer(data.customer);
132 | updateFormKeys();
133 | return data;
134 | } catch (error) {
135 | console.error("Error fetching private content:", error);
136 | return null;
137 | }
138 | }
139 |
140 | function getLocalStorage() {
141 | if (!window.localStorage) {
142 | console.warn('Local Storage is issue');
143 | return false;
144 | }
145 | return window.localStorage
146 | }
147 |
148 | function updateCustomer(data) {
149 | let isLoggedIn = false;
150 | if (data) {
151 | const name = data.firstname;
152 |
153 | const customerName = document.querySelector('.customer-name');
154 | if (customerName && name && name !== '') {
155 | isLoggedIn = true;
156 | customerName.innerHTML += 'Welcome, ' + name + '';
157 | const customerMenu = document.querySelector(".customer-menu");
158 | document.querySelectorAll('.link.logout').forEach(elem => (elem.style.display="none"));
159 | document.querySelectorAll('.link.login').forEach(elem => (elem.style.display="block"));
160 |
161 | customerName.addEventListener("click", function (event) {
162 | event.preventDefault();
163 | if (customerMenu) {
164 | customerMenu.style.display = customerMenu.style.display === "block" ? "none" : "block";
165 | }
166 | });
167 | }
168 | }
169 | if (!isLoggedIn){
170 | document.querySelectorAll('.link.logout').forEach(elem => (elem.style.display="block"));
171 | document.querySelectorAll('.link.login').forEach(elem => (elem.style.display="none"));
172 | }
173 | }
174 |
175 | function updateCartData(data) {
176 | if (data) {
177 | const summaryCount = data.summary_count; // Number of items
178 | if (summaryCount !== 0 && summaryCount !== null){
179 | const subtotalAmount = parseFloat(data.subtotalAmount); // Subtotal amount
180 | // Updatethe cart counter
181 | const subtotalElement = document.querySelector('.counter-number');
182 | if (subtotalElement) {
183 | const cartElement = document.querySelector('.counter.qty.empty');
184 | if (cartElement) {
185 | cartElement.classList.remove('empty');
186 | }
187 | subtotalElement.innerText = subtotalAmount ? `$${subtotalAmount.toFixed(2)}` : '';
188 | }
189 | }
190 | }
191 | }
192 |
193 | getFormKey = function () {
194 | let formKey = getCookie('form_key');
195 | if (!formKey) {
196 | formKey = crypto.randomUUID(); // More secure than random strings
197 | setCookie('form_key', formKey, 86400); // Set for 1 day
198 | }
199 | return formKey;
200 | };
201 |
202 | updateFormKeys = function () {
203 | const formKey = getFormKey().replace(/-/g, '\\u002D');
204 | document.querySelectorAll('input[name="form_key"]').forEach(input => input.value = formKey);
205 | };
206 |
207 | onLoad = (callback, ...args) => {
208 | window.addEventListener("load", () => callback(...args));
209 | };
210 |
211 | onDOM = (callback, ...args) => {
212 | document.addEventListener("DOMContentLoaded", () => callback(...args));
213 | }
214 |
215 | const checkInterval = 150;
216 | const loadTimeout = 3000
217 |
218 | // Function to run code only after the page has loaded, with optional arguments
219 | runAfterLoad = (interval = checkInterval, callback, ...args) => {
220 | let counter = 5;
221 | const checkLoad = setInterval(() => {
222 | if (isLoaded()) {
223 | clearInterval(checkLoad);
224 | callback(...args);
225 | }
226 | counter++;
227 | }, interval);
228 | }
229 |
230 | loadScript = (src) => {
231 | return new Promise((resolve, reject) => {
232 | const script = document.createElement("script");
233 | script.src = src;
234 | script.async = true;
235 | script.onload = () => resolve(src);
236 | script.onerror = () => reject(new Error(`Failed to load script: ${src}`));
237 | document.head.appendChild(script);
238 | });
239 | }
240 |
241 | getUenc = () => {
242 | return window.curentUenc;
243 | }
244 |
245 | async function addToCompare(productId) {
246 | try {
247 | const formKey = getFormKey();
248 | const postUrl = BASE_URL + `catalog/product_compare/add/`;
249 | const bodyData = new URLSearchParams({
250 | form_key: formKey,
251 | product: productId,
252 | uenc: getUenc()
253 | });
254 |
255 | const request = new Request(postUrl,
256 | {
257 | method: 'POST',
258 | cache: 'no-store',
259 | headers: {
260 | "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
261 | },
262 | body: bodyData,
263 | mode: "cors",
264 | credentials: "include"
265 | }
266 | );
267 |
268 | const response = await fetch(request);
269 |
270 | if (response.redirected) {
271 | window.location.href = response.url;
272 | }
273 | loadSectionData();
274 | } catch (error) {
275 | if (typeof window.dispatchMessages !== "undefined") {
276 | alert(`❌ Error: ${error.message || "An unexpected error occurred."}`);
277 | }
278 | }
279 | }
280 |
281 | async function addToWishlist(productId) {
282 | try {
283 | const formKey = getFormKey();
284 | const postUrl = BASE_URL + `wishlist/index/add/`;
285 | const uenc = getUenc();
286 |
287 | const response = await fetch(postUrl, {
288 | method: "POST",
289 | headers: {
290 | "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
291 | },
292 | body: new URLSearchParams({
293 | form_key: formKey,
294 | product: productId,
295 | uenc: uenc,
296 | }),
297 | mode: "cors",
298 | credentials: "include",
299 | });
300 |
301 | if (response.redirected) {
302 | window.location.href = response.url;
303 | return;
304 | }
305 |
306 | if (!response.ok) {
307 | alert("⚠️ Could not add item to wishlist.");
308 | return;
309 | }
310 |
311 | const data = await response.json();
312 |
313 | alert(
314 | data.success
315 | ? "✅ Product has been added to your Wish List."
316 | : `❌ ${data.error_message || "Something went wrong!"}`
317 | );
318 |
319 | // Trigger customer section reload
320 | loadSectionData()
321 | } catch (error) {
322 | alert(`❌ Error: ${error.message || "An unexpected error occurred."}`);
323 | }
324 | }
325 |
326 | return {
327 | displayMessages,
328 | loadSectionData,
329 | getLocalStorage,
330 | updateCartData,
331 | updateFormKeys,
332 | addToWishlist,
333 | localStorage,
334 | addToCompare,
335 | getFormKey,
336 | isLoaded,
337 | getUenc,
338 | onLoad,
339 | onDOM,
340 | doc
341 | };
342 | })();
343 |
344 | mage.loadSectionData();
345 |
346 | mage.onDOM( function () {
347 | const navToggle = document.querySelector(".action.nav-toggle");
348 | const navMenu = document.querySelector(".nav-sections");
349 | // Toggle menu on click
350 | navToggle.addEventListener("click", function () {
351 | navMenu.classList.toggle("active");
352 | });
353 | // Close menu when clicking outside
354 | document.addEventListener("click", function (event) {
355 | if (!navMenu.contains(event.target) && event.target !== navToggle) {
356 | navMenu.classList.remove("active");
357 | }
358 | });
359 | });
360 |
361 | mage.onDOM( function () {
362 | const filterSections = document.querySelectorAll(".filter-options-item");
363 | filterSections.forEach(section => {
364 | const title = section.querySelector(".filter-options-title");
365 | title.addEventListener("click", function () {
366 | // Toggle active class
367 | section.classList.toggle("active");
368 | });
369 | });
370 | });
371 |
372 | mage.onDOM( function () {
373 | mage.displayMessages();
374 | setInterval(() => {
375 | mage.displayMessages();;
376 | }, 5000);
377 | });
378 |
379 | mage.onDOM( function () {
380 | document.querySelectorAll(".block.related li.item.product.product-item").forEach(productItem => {
381 | productItem.style.display = "";
382 | });
383 | }
384 | );
385 |
386 | if(window.productType === "simple") {
387 | const button = document.getElementById("product-addtocart-button");
388 | if (button) {
389 | button.removeAttribute("disabled");
390 | }
391 | }
392 |
393 | if(window.controller === "category"){
394 | const buttons = document.querySelectorAll(".action.tocart.primary");
395 | if (buttons) {
396 | buttons.forEach(btn => {
397 | btn.removeAttribute("disabled");
398 | });
399 | }}
400 |
401 | window.onload = () => {
402 | const sorter = document.getElementById("sorter");
403 | if(sorter){
404 | sorter.addEventListener("change", function () {
405 | const selectedValue = sorter.value;
406 | const currentUrl = new URL(window.location.href);
407 | currentUrl.searchParams.set("product_list_order", selectedValue);
408 | window.location.href = currentUrl.toString();
409 | });
410 | }
411 | };
412 |
413 | mage.onDOM( function () {
414 | const limiterSelect = document.getElementById("limiter");
415 |
416 | if (limiterSelect) {
417 | limiterSelect.addEventListener("change", function () {
418 | const selectedValue = this.value;
419 | const currentUrl = new URL(window.location.href);
420 |
421 | // Update the 'limit' query parameter
422 | currentUrl.searchParams.set("product_list_limit", selectedValue);
423 |
424 | // Redirect to the updated URL
425 | window.location.href = currentUrl.toString();
426 | });
427 | }
428 | });
429 |
430 | mage.onDOM( function () {
431 | const sortDirectionLink = document.querySelector("[data-role='direction-switcher']");
432 |
433 | if (sortDirectionLink) {
434 | sortDirectionLink.addEventListener("click", function (event) {
435 | event.preventDefault(); // Prevent the default link behavior
436 |
437 | const currentUrl = new URL(window.location.href);
438 | const currentDirection = currentUrl.searchParams.get("dir") || "asc"; // Default to ascending
439 | const newDirection = currentDirection === "asc" ? "desc" : "asc"; // Toggle between asc and desc
440 |
441 | // Update the 'dir' query parameter
442 | currentUrl.searchParams.set("product_list_dir", newDirection);
443 |
444 | // Redirect to the updated URL
445 | window.location.href = currentUrl.toString();
446 | });
447 | }
448 | });
449 |
450 | mage.onDOM(function () {
451 | function toggleSection(event) {
452 | event.preventDefault();
453 |
454 | const targetId = this.getAttribute("href");
455 | const contentElements = document.querySelectorAll('.section-item-content.nav-sections-item-content');
456 | contentElements.forEach(content => {
457 | content.style.display = "none";
458 | });
459 |
460 | document.querySelectorAll(".section-item-title").forEach(title => {
461 | title.classList.remove("active");
462 | });
463 |
464 | document.getElementById(targetId.substring(1)).style.display = 'block';
465 |
466 | this.parentElement.setAttribute("aria-hidden", "true");
467 | this.parentElement.classList.add("active");
468 |
469 | }
470 |
471 | // Attach event listeners to menu and account links
472 | document.querySelectorAll("a.nav-sections-item-switch").forEach(link => {
473 | link.addEventListener("click", toggleSection);
474 | });
475 | var n = 0;
476 | document.querySelectorAll(".section-item-content.nav-sections-item-content").forEach(menu => {
477 | if(menu.id !== "store.menu"){
478 | menu.style.display = "none";
479 | }
480 | });
481 |
482 | // Select all parent menu items
483 | document.querySelectorAll("level0.category-item.parent > a").forEach(menuItem => {
484 | menuItem.addEventListener("click", function (event) {
485 | event.preventDefault(); // Prevent the default link behavior
486 |
487 | let submenu = this.nextElementSibling; // Get the submenu
488 | if (submenu) {
489 | submenu.style.display = submenu.style.display === "block" ? "none" : "block";
490 | }
491 | });
492 | });
493 | });
494 |
495 | mage.onDOM(() => {
496 | // Select the search button and the input field
497 | const searchButton = document.querySelector('[data-role="minisearch-label"]');
498 | const searchBlock = document.querySelector('form.minisearch .control');
499 |
500 | if (searchButton && searchBlock) {
501 | searchButton.addEventListener('click', function() {
502 | // Toggle the display property
503 | if (searchBlock.style.display === 'block') {
504 | searchBlock.style.display = 'none';
505 | } else {
506 | searchBlock.style.display = 'block';
507 | }
508 | });
509 | }
510 |
511 | const shopByTitle = document.querySelector('strong[data-role="title"]');
512 | const filterOptions = document.querySelector('.filter-options');
513 |
514 | if (shopByTitle && filterOptions) {
515 | shopByTitle.addEventListener("click", function () {
516 | filterOptions.style.display =
517 | filterOptions.style.display === "none" || filterOptions.style.display === ""
518 | ? "block"
519 | : "none";
520 | });
521 | }
522 | });
--------------------------------------------------------------------------------
/view/frontend/web/js/rum.js:
--------------------------------------------------------------------------------
1 | !function(){var e={343:function(e){"use strict";for(var t=[],n=0;n<256;++n)t[n]=(n+256).toString(16).substr(1);e.exports=function(e,n){var r=n||0,i=t;return[i[e[r++]],i[e[r++]],i[e[r++]],i[e[r++]],"-",i[e[r++]],i[e[r++]],"-",i[e[r++]],i[e[r++]],"-",i[e[r++]],i[e[r++]],"-",i[e[r++]],i[e[r++]],i[e[r++]],i[e[r++]],i[e[r++]],i[e[r++]]].join("")}},944:function(e){"use strict";var t="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(t){var n=new Uint8Array(16);e.exports=function(){return t(n),n}}else{var r=new Array(16);e.exports=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),r[t]=e>>>((3&t)<<3)&255;return r}}},508:function(e,t,n){"use strict";var r=n(944),i=n(343);e.exports=function(e,t,n){var o=t&&n||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var a=(e=e||{}).random||(e.rng||r)();if(a[6]=15&a[6]|64,a[8]=63&a[8]|128,t)for(var c=0;c<16;++c)t[o+c]=a[c];return t||i(a)}},168:function(e,t,n){"use strict";var r=this&&this.__assign||function(){return r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&(t+=r)}return t}function t(e,t){for(var n in e){var r=e[n];void 0!==t&&("number"!=typeof r&&"string"!=typeof r||(t[n]=r))}}!function(){var n,u,s=window.performance||window.webkitPerformance||window.msPerformance||window.mozPerformance,f="data-cf-beacon",d=document.currentScript||("function"==typeof document.querySelector?document.querySelector("script[".concat(f,"]")):void 0),l=c(),v=[],p=window.__cfBeacon?window.__cfBeacon:{};if(!p||"single"!==p.load){if(d){var m=d.getAttribute(f);if(m)try{p=r(r({},p),JSON.parse(m))}catch(e){}else{var g=d.getAttribute("src");if(g&&"function"==typeof URLSearchParams){var y=new URLSearchParams(g.replace(/^[^\?]+\??/,"")),h=y.get("token");h&&(p.token=h);var T=y.get("spa");p.spa=null===T||"true"===T}}p&&"multi"!==p.load&&(p.load="single"),window.__cfBeacon=p}if(s&&p&&p.token){var w,S,b=!1;document.addEventListener("visibilitychange",(function(){if("hidden"===document.visibilityState){if(L&&A()){var t=e();(null==w?void 0:w.url)==t&&(null==w?void 0:w.triggered)||P(),_(t)}!b&&w&&(b=!0,B())}else"visible"===document.visibilityState&&(new Date).getTime()}));var E={};"function"==typeof PerformanceObserver&&((0,a.onLCP)(x),(0,a.onFID)(x),(0,a.onFCP)(x),(0,a.onINP)(x),(0,a.onTTFB)(x),PerformanceObserver.supportedEntryTypes&&PerformanceObserver.supportedEntryTypes.includes("layout-shift")&&(0,a.onCLS)(x));var L=p&&(void 0===p.spa||!0===p.spa),C=p.send&&p.send.to?p.send.to:void 0===p.version?"https://cloudflareinsights.com/cdn-cgi/rum":null,P=function(r){var a=function(r){var o,a,c=s.timing,u=s.memory,f=r||e(),d={memory:{},timings:{},resources:[],referrer:(o=document.referrer||"",a=v[v.length-1],L&&w&&a?a.url:o),eventType:i.EventType.Load,firstPaint:0,firstContentfulPaint:0,startTime:F(),versions:{fl:p?p.version:"",js:"2024.6.1",timings:1},pageloadId:l,location:f,nt:S,serverTimings:I()};if(null==n){if("function"==typeof s.getEntriesByType){var m=s.getEntriesByType("navigation");m&&Array.isArray(m)&&m.length>0&&(d.timingsV2={},d.versions.timings=2,d.dt=m[0].deliveryType,delete d.timings,t(m[0],d.timingsV2))}1===d.versions.timings&&t(c,d.timings),t(u,d.memory)}else O(d);return d.firstPaint=k("first-paint"),d.firstContentfulPaint=k("first-contentful-paint"),p&&(p.icTag&&(d.icTag=p.icTag),d.siteToken=p.token),void 0!==n&&(delete d.timings,delete d.memory),d}(r);a&&p&&(a.resources=[],p&&((0,o.sendObjectBeacon)("",a,(function(){}),!1,C),void 0!==p.forward&&void 0!==p.forward.url&&(0,o.sendObjectBeacon)("",a,(function(){}),!1,p.forward.url)))},B=function(){var t=function(){var t=s.getEntriesByType("navigation")[0],n="";try{n="function"==typeof s.getEntriesByType?new URL(null==t?void 0:t.name).pathname:u?new URL(u).pathname:window.location.pathname}catch(e){}var r={referrer:document.referrer||"",eventType:i.EventType.WebVitalsV2,versions:{js:"2024.6.1"},pageloadId:l,location:e(),landingPath:n,startTime:F(),nt:S,serverTimings:I()};return p&&(p.version&&(r.versions.fl=p.version),p.icTag&&(r.icTag=p.icTag),r.siteToken=p.token),E&&["lcp","fid","cls","fcp","ttfb","inp"].forEach((function(e){r[e]={value:-1,path:void 0},E[e]&&void 0!==E[e].value&&(r[e]=E[e])})),O(r),r}();p&&(0,o.sendObjectBeacon)("",t,(function(){}),!0,C)},R=function(){var t=window.__cfRl&&window.__cfRl.done||window.__cfQR&&window.__cfQR.done;t?t.then(P):P(),w={id:l,url:e(),ts:(new Date).getTime(),triggered:!0}};"complete"===window.document.readyState?R():window.addEventListener("load",(function(){window.setTimeout(R)}));var A=function(){return L&&0===v.filter((function(e){return e.id===l})).length},_=function(e){v.push({id:l,url:e,ts:(new Date).getTime()}),v.length>3&&v.shift()};L&&(u=e(),function(t){var r=t.pushState;if(r){var i=function(){l=c()};t.pushState=function(o,a,c){n=e(c);var u=e(),s=!0;return n==u&&(s=!1),s&&(A()&&((null==w?void 0:w.url)==u&&(null==w?void 0:w.triggered)||P(u),_(u)),i()),r.apply(t,[o,a,c])},window.addEventListener("popstate",(function(t){A()&&((null==w?void 0:w.url)==n&&(null==w?void 0:w.triggered)||P(n),_(n)),n=e(),i()}))}}(window.history))}}function x(e){var t,n,r,i,o,a,c,u=window.location.pathname;switch(S||(S=e.navigationType),"INP"!==e.name&&(E[e.name.toLowerCase()]={value:e.value,path:u}),e.name){case"CLS":(c=e.attribution)&&E.cls&&(E.cls.element=c.largestShiftTarget,E.cls.currentRect=null===(t=c.largestShiftSource)||void 0===t?void 0:t.currentRect,E.cls.previousRect=null===(n=c.largestShiftSource)||void 0===n?void 0:n.previousRect);break;case"FID":(c=e.attribution)&&E.fid&&(E.fid.element=c.eventTarget,E.fid.name=c.eventType);break;case"LCP":(c=e.attribution)&&E.lcp&&(E.lcp.element=c.element,E.lcp.size=null===(r=c.lcpEntry)||void 0===r?void 0:r.size,E.lcp.url=c.url,E.lcp.rld=c.resourceLoadDelay,E.lcp.rlt=c.resourceLoadTime,E.lcp.erd=c.elementRenderDelay,E.lcp.it=null===(i=c.lcpResourceEntry)||void 0===i?void 0:i.initiatorType,E.lcp.fp=null===(a=null===(o=c.lcpEntry)||void 0===o?void 0:o.element)||void 0===a?void 0:a.getAttribute("fetchpriority"));break;case"INP":(null==E.inp||Number(E.inp.value)-1&&parseInt(c[1])<81&&(a=!1)}catch(e){}if(navigator&&"function"==typeof navigator.sendBeacon&&a&&r){t.st=1;var u=JSON.stringify(t),s=navigator.sendBeacon&&navigator.sendBeacon.bind(navigator);null==s||s(o,new Blob([u],{type:"application/json"}))}else{t.st=2,u=JSON.stringify(t);var f=new XMLHttpRequest;n&&(f.onreadystatechange=function(){4==this.readyState&&204==this.status&&n()}),f.open("POST",o,!0),f.setRequestHeader("content-type","application/json"),f.send(u)}}},699:function(e,t){"use strict";var n,r;t.__esModule=!0,t.FetchPriority=t.EventType=void 0,(r=t.EventType||(t.EventType={}))[r.Load=1]="Load",r[r.Additional=2]="Additional",r[r.WebVitalsV2=3]="WebVitalsV2",(n=t.FetchPriority||(t.FetchPriority={})).High="high",n.Low="low",n.Auto="auto"},104:function(e,t){!function(e){"use strict";var t,n,r,i,o,a=function(){return window.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0]},c=function(e){if("loading"===document.readyState)return"loading";var t=a();if(t){if(e(t||100)-1)return n||i;if(n=n?i+">"+n:i,r.id)break;e=r.parentNode}}catch(e){}return n},f=-1,d=function(){return f},l=function(e){addEventListener("pageshow",(function(t){t.persisted&&(f=t.timeStamp,e(t))}),!0)},v=function(){var e=a();return e&&e.activationStart||0},p=function(e,t){var n=a(),r="navigate";return d()>=0?r="back-forward-cache":n&&(document.prerendering||v()>0?r="prerender":document.wasDiscarded?r="restore":n.type&&(r=n.type.replace(/_/g,"-"))),{name:e,value:void 0===t?-1:t,rating:"good",delta:0,entries:[],id:"v3-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r}},m=function(e,t,n){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var r=new PerformanceObserver((function(e){Promise.resolve().then((function(){t(e.getEntries())}))}));return r.observe(Object.assign({type:e,buffered:!0},n||{})),r}}catch(e){}},g=function(e,t,n,r){var i,o;return function(a){t.value>=0&&(a||r)&&((o=t.value-(i||0))||void 0===i)&&(i=t.value,t.delta=o,t.rating=function(e,t){return e>t[1]?"poor":e>t[0]?"needs-improvement":"good"}(t.value,n),e(t))}},y=function(e){requestAnimationFrame((function(){return requestAnimationFrame((function(){return e()}))}))},h=function(e){var t=function(t){"pagehide"!==t.type&&"hidden"!==document.visibilityState||e(t)};addEventListener("visibilitychange",t,!0),addEventListener("pagehide",t,!0)},T=function(e){var t=!1;return function(n){t||(e(n),t=!0)}},w=-1,S=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},b=function(e){"hidden"===document.visibilityState&&w>-1&&(w="visibilitychange"===e.type?e.timeStamp:0,L())},E=function(){addEventListener("visibilitychange",b,!0),addEventListener("prerenderingchange",b,!0)},L=function(){removeEventListener("visibilitychange",b,!0),removeEventListener("prerenderingchange",b,!0)},C=function(){return w<0&&(w=S(),E(),l((function(){setTimeout((function(){w=S(),E()}),0)}))),{get firstHiddenTime(){return w}}},P=function(e){document.prerendering?addEventListener("prerenderingchange",(function(){return e()}),!0):e()},B=[1800,3e3],R=function(e,t){t=t||{},P((function(){var n,r=C(),i=p("FCP"),o=m("paint",(function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(o.disconnect(),e.startTime=0&&n1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,t){var n=function(){F(e,t),i()},r=function(){i()},i=function(){removeEventListener("pointerup",n,_),removeEventListener("pointercancel",r,_)};addEventListener("pointerup",n,_),addEventListener("pointercancel",r,_)}(t,e):F(t,e)}},k=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(t){return e(t,O,_)}))},M=[100,300],D=function(e,r){r=r||{},P((function(){var o,a=C(),c=p("FID"),u=function(e){e.startTimet.latency){if(n)n.entries.push(e),n.latency=Math.max(n.latency,e.duration);else{var r={id:e.interactionId,latency:e.duration,entries:[e]};X[r.id]=r,Q.push(r)}Q.sort((function(e,t){return t.latency-e.latency})),Q.splice(10).forEach((function(e){delete X[e.id]}))}},K=[2500,4e3],Y={},Z=[800,1800],$=function e(t){document.prerendering?P((function(){return e(t)})):"complete"!==document.readyState?addEventListener("load",(function(){return e(t)}),!0):setTimeout(t,0)},ee=function(e,t){t=t||{};var n=p("TTFB"),r=g(e,n,Z,t.reportAllChanges);$((function(){var i=a();if(i){var o=i.responseStart;if(o<=0||o>performance.now())return;n.value=Math.max(o-v(),0),n.entries=[i],r(!0),l((function(){n=p("TTFB",0),(r=g(e,n,Z,t.reportAllChanges))(!0)}))}}))};e.CLSThresholds=A,e.FCPThresholds=B,e.FIDThresholds=M,e.INPThresholds=U,e.LCPThresholds=K,e.TTFBThresholds=Z,e.onCLS=function(e,t){!function(e,t){t=t||{},R(T((function(){var n,r=p("CLS",0),i=0,o=[],a=function(e){e.forEach((function(e){if(!e.hadRecentInput){var t=o[0],n=o[o.length-1];i&&e.startTime-n.startTime<1e3&&e.startTime-t.startTime<5e3?(i+=e.value,o.push(e)):(i=e.value,o=[e])}})),i>r.value&&(r.value=i,r.entries=o,n())},c=m("layout-shift",a);c&&(n=g(e,r,A,t.reportAllChanges),h((function(){a(c.takeRecords()),n(!0)})),l((function(){i=0,r=p("CLS",0),n=g(e,r,A,t.reportAllChanges),y((function(){return n()}))})),setTimeout(n,0))})))}((function(t){!function(e){if(e.entries.length){var t=e.entries.reduce((function(e,t){return e&&e.value>t.value?e:t}));if(t&&t.sources&&t.sources.length){var n=(r=t.sources).find((function(e){return e.node&&1===e.node.nodeType}))||r[0];if(n)return void(e.attribution={largestShiftTarget:s(n.node),largestShiftTime:t.startTime,largestShiftValue:t.value,largestShiftSource:n,largestShiftEntry:t,loadState:c(t.startTime)})}}var r;e.attribution={}}(t),e(t)}),t)},e.onFCP=function(e,t){R((function(t){!function(e){if(e.entries.length){var t=a(),n=e.entries[e.entries.length-1];if(t){var r=t.activationStart||0,i=Math.max(0,t.responseStart-r);return void(e.attribution={timeToFirstByte:i,firstByteToFCP:e.value-i,loadState:c(e.entries[0].startTime),navigationEntry:t,fcpEntry:n})}}e.attribution={timeToFirstByte:0,firstByteToFCP:e.value,loadState:c(d())}}(t),e(t)}),t)},e.onFID=function(e,t){D((function(t){!function(e){var t=e.entries[0];e.attribution={eventTarget:s(t.target),eventType:t.name,eventTime:t.startTime,eventEntry:t,loadState:c(t.startTime)}}(t),e(t)}),t)},e.onINP=function(e,t){!function(e,t){t=t||{},P((function(){var n;z();var r,i=p("INP"),o=function(e){e.forEach((function(e){e.interactionId&&G(e),"first-input"===e.entryType&&!Q.some((function(t){return t.entries.some((function(t){return e.duration===t.duration&&e.startTime===t.startTime}))}))&&G(e)}));var t,n=(t=Math.min(Q.length-1,Math.floor(W()/50)),Q[t]);n&&n.latency!==i.value&&(i.value=n.latency,i.entries=n.entries,r())},a=m("event",o,{durationThreshold:null!==(n=t.durationThreshold)&&void 0!==n?n:40});r=g(e,i,U,t.reportAllChanges),a&&("PerformanceEventTiming"in window&&"interactionId"in PerformanceEventTiming.prototype&&a.observe({type:"first-input",buffered:!0}),h((function(){o(a.takeRecords()),i.value<0&&W()>0&&(i.value=0,i.entries=[]),r(!0)})),l((function(){Q=[],J=H(),i=p("INP"),r=g(e,i,U,t.reportAllChanges)})))}))}((function(t){!function(e){if(e.entries.length){var t=e.entries.sort((function(e,t){return t.duration-e.duration||t.processingEnd-t.processingStart-(e.processingEnd-e.processingStart)}))[0],n=e.entries.find((function(e){return e.target}));e.attribution={eventTarget:s(n&&n.target),eventType:t.name,eventTime:t.startTime,eventEntry:t,loadState:c(t.startTime)}}else e.attribution={}}(t),e(t)}),t)},e.onLCP=function(e,t){!function(e,t){t=t||{},P((function(){var n,r=C(),i=p("LCP"),o=function(e){var t=e[e.length-1];t&&t.startTime