fw-webbuilder 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # FwWebbuilder
2
+
3
+ This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.3.0.
4
+
5
+ ## Code scaffolding
6
+
7
+ Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
8
+
9
+ ```bash
10
+ ng generate component component-name
11
+ ```
12
+
13
+ For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
14
+
15
+ ```bash
16
+ ng generate --help
17
+ ```
18
+
19
+ ## Building
20
+
21
+ To build the library, run:
22
+
23
+ ```bash
24
+ ng build fw-webbuilder
25
+ ```
26
+
27
+ This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
28
+
29
+ ### Publishing the Library
30
+
31
+ Once the project is built, you can publish your library by following these steps:
32
+
33
+ 1. Navigate to the `dist` directory:
34
+ ```bash
35
+ cd dist/fw-webbuilder
36
+ ```
37
+
38
+ 2. Run the `npm publish` command to publish your library to the npm registry:
39
+ ```bash
40
+ npm publish
41
+ ```
42
+
43
+ ## Running unit tests
44
+
45
+ To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
46
+
47
+ ```bash
48
+ ng test
49
+ ```
50
+
51
+ ## Running end-to-end tests
52
+
53
+ For end-to-end (e2e) testing, run:
54
+
55
+ ```bash
56
+ ng e2e
57
+ ```
58
+
59
+ Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
60
+
61
+ ## Additional Resources
62
+
63
+ For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
@@ -0,0 +1 @@
1
+ import*as e from"@angular/common/http";import{HttpParams as t}from"@angular/common/http";import*as i from"@angular/core";import{InjectionToken as n,inject as o,Injectable as r,HostListener as s,Input as a,Component as l}from"@angular/core";import{Subject as d,firstValueFrom as c,catchError as h,throwError as p}from"rxjs";import{io as g}from"socket.io-client";import*as b from"@angular/common";import{CommonModule as u}from"@angular/common";const f=[{label:"Sắp xếp lớp",icon:"layout"},{label:"Lấy thuộc tính từ màn",icon:"sliders"},{label:"Xóa",icon:"delete"}],_=[{label:"Thêm khung",icon:"plus-square"},{label:"Thêm vật thể",icon:"plus-circle"},{label:"Sắp xếp lớp",icon:"layout"},{label:"Lên trên",icon:"arrow-up"},{label:"Xuống dưới",icon:"arrow-down"},{label:"Lấy thuộc tính từ màn",icon:"sliders"},{label:"Xóa",icon:"delete"}],m=[{tool_tip:"Máy tính",icon:"desktop",value:"desktop"},{tool_tip:"Máy tính bảng ngang",icon:"tablet",value:"tablet_landscape"},{tool_tip:"Máy tính bảng dọc",icon:"tablet",value:"tablet_portrait"},{tool_tip:"Điện thoại ngang",icon:"mobile",value:"mobile_landscape"},{tool_tip:"Điện thoại dọc",icon:"mobile",value:"mobile_portrait"}],v={name:"",link:"",component_config:"WbPageConfig",desktop_class:{page:{"--bg-color":"#ffffff"}},desktop_config:{id_header:"",id_footer:""},tablet_landscape_class:{page:{"--bg-color":"#ffffff"}},tablet_landscape_config:{id_header:"",id_footer:""},tablet_portrait_class:{page:{"--bg-color":"#ffffff"}},tablet_portrait_config:{id_header:"",id_footer:""},mobile_landscape_class:{page:{"--bg-color":"#ffffff"}},mobile_landscape_config:{id_header:"",id_footer:""},mobile_portrait_class:{page:{"--bg-color":"#ffffff"}},mobile_portrait_config:{id_header:"",id_footer:""},seo:{title:"",description:"",keywords:"",og_title:"",og_description:"",og_type:""},type:""},y=[{desc:{vi:'<p>Sữa HiPP 3 Combiotic Organic 2482 800gr<br>Trẻ từ 1 tuổi trở lên vẫn cần bổ sung dinh dưỡng thiết yếu, mẹ cần bổ sung hàm lượng Canxi cho bé mỗi ngày. Tuy nhiên hàm lượng Sắt, kẽm, I-ốt và các khoáng chất trong sữa bò tự nhiên thường không cao. Sữa bột Hipp 3 Combiotic chứa đầy đủ dưỡng chất thiết yếu cho sự tăng trưởng và phát triển của bé trong giai đoạn tăng trưởng từ 1 tuổi trở lên cho con yêu thông minh, mau lớn và khỏe mạnh.</p><p>Đặc điểm nổi bật của sản phẩm</p><p>Sữa Hipp 3 với nguồn nguyên liệu hoàn toàn hữu cơ và siêu sạch Organic đạt tiêu chuẩn của Liên Minh Châu Âu</p><p>Sữa bổ sung hàm lượng Probitik phân lập gốc từ sữa mẹ, Praebitik và vitamin A, C, D giúp tăng cường miễn dịch, hỗ trợ tiêu hóa.</p><p>Hàm lượng Protein phù hợp với sự phát triển của cơ thể bé, có tác dụng tăng cường miễn dịch, ức chế sự phát triển của các vi khuẩn, virut gây bệnh</p><p>Chất xơ thực phẩm quan trọng GOS chiết tách từ lactose trong sữa tạo môi trường thuận lợi cho lợi khuẩn Probiotic phát triển, tăng cường đường ruột, hỗ trợ hệ tiêu hóa của trẻ.</p><p>Sữa bổ sung ARA và DHA ( axit béo Omega 3 và Omega 6) có vai trò đặc biệt quan trọng giúp kích thích não bộ và các tế bào thần kinh, thị lực của bé phát triển</p><p>Bổ sung sắt có tác dụng trong quá trình tạo máu.</p><p>Bổ sung vitamin D và kháng thể tự nhiên IgG tăng cường hệ miễn dịch, giúp phát triển hoàn thiện chức năng nhìn của mắt, hệ thần kinh, giảm cholesterol toàn phần, và triglyceride máu, LDL-cholesterol (cholesterol xấu), giúp dự phòng các bệnh tim mạch.</p><p>Không chứa tinh bột, sữa bột Hipp 3 Combiotic chỉ chứa đường tự nhiên Lactose giúp bé dễ hấp thu và tiêu hóa tốt.</p><p>Đặc biệt sữa không chứa Gluten</p><p>Sữa bột Hipp3 dạng tơi xốp, dễ tan, không bị vón cục, có mùi thơm nhẹ, dễ uống giúp bé ăn ngon miệng và thích thú</p><p>KM</p><ul><li data-list-item-id="ed2ee73c6cba22f96af6f97cb988c3912">"Tưng bừng khai trương" - giảm giá 50% tất cả sản phẩm</li><li data-list-item-id="ed62a9ac50f6ee192e6a2cabeebff9b1b">Giảm thêm 500.000đ khi thanh toán bằng thẻ tín dụng tại TTMS</li><li data-list-item-id="e10a21617d914add51ebad5203874b999">Giảm ngay 100.000đ khi quét QR Code cùng Mastercard với đơn hàng 1.000.000đ</li></ul>'},desc_short:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Các nội dung Hướng dẫn mua hàng viết ở đây</span></p>'},name:{vi:"Sữa Hipp 3 Combiotic Organic 2482 800gr"},seo_title:{vi:""},seo_description:{vi:""},seo_keyword:{vi:""},brand:"Hipp",id_categorys:[],product_attributes:[{id:"8662d676-c1ac-4854-b956-3593583d174b",name:"Kích thước",values:["To","Nhỏ"]}],variations:[{id:"11881207-b902-4559-9a6c-9f5eb609f0f0",sku:"CDEQNL7L",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761656340302-812022711.png","http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761656342596-883421575.png","http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761656343612-416135702.png","http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761656344724-531521917.png"],import_price:0,original_price:6e5,retail_price:58e4,fields:[{value:"To",name:"Kích thước"}],weight:0,stock:10,hidden:!1},{id:"5ecf23b5-2c35-4db3-a66f-b70be938b051",sku:"LAE2SHJ4",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761656405318-593063767.png","http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761656407777-653200713.png","http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761656409981-32559064.png","http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761656411713-182955683.png"],import_price:0,original_price:6e5,retail_price:55e4,fields:[{value:"Nhỏ",name:"Kích thước"}],weight:0,stock:0,hidden:!1}],link:"sua-hipp-3-combiotic-organic-2482-800gr"},{desc:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Sữa Hipp 4 Combiotic Organic 800g cho bé phát triển toàn diện</span><br><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Sữa Hipp 4 Combiotic Organic 800g dành cho bé trên 3 tuổi. Với công thức đặc biệt bổ sung lợi khuẩn cùng chất xơ rất tốt cho hệ tiêu hóa, tăng cường hệ miễn dịch, dễ dàng hấp thụ. Không những vậy, sữa bột trẻ em Hipp còn tăng cường hàm lượng DHA, Omega 3 và Omega 6 giúp trẻ phát triển trí não, thông minh vượt trội.</span></p>'},desc_short:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Các nội dung Hướng dẫn mua hàng viết ở đây</span></p>'},name:{vi:"Sữa Hipp 4 Combiotic Organic 800g"},seo_title:{vi:""},seo_description:{vi:""},seo_keyword:{vi:""},brand:"Hipp",id_categorys:[],product_attributes:[],variations:[{id:"1bb8747f-980c-47fa-8bbd-1ea2adb1a968",sku:"2JUDEY1T",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761656502723-760473000.png"],import_price:0,original_price:4e5,retail_price:38e4,fields:[],weight:0,stock:10,hidden:!1}],link:"sua-hipp-4-combiotic-organic-800g"},{desc:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Giai đoạn đầu là giai đoạn giúp bé nhà bạn có thể hấp thụ chất dinh dưỡng tốt nhất, tăng cường khả năng miễn dịch cho bé lớn lên được an toàn và khỏe mạnh nhất. Vào giai đoạn này, hầu hết các mẹ đều cho con bú sữa mẹ hoàn toàn. Tuy nhiên nhiều mẹ do một số lý do mà không đủ sữa cho con bú nên việc cung cấp dinh dưỡng cho bé thông qua các sản phẩm sữa bột chất lượng là điều cần thiết và quan trọng. Sữa bột công thức Physiolac số 1 400g &nbsp;với những công thức tính toán cẩn trọng về thành phần, giúp trẻ dễ dàng hấp thu các chất dinh dưỡng, nâng cao sức đề kháng và tăng cường hệ miễn dịch trong giai đoạn từ 0-6 tháng tuổi.</span></p>'},desc_short:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Các nội dung Hướng dẫn mua hàng viết ở đây</span></p>'},name:{vi:"Sữa Physiolac số 2 400g"},seo_title:{vi:""},seo_description:{vi:""},seo_keyword:{vi:""},brand:"Physiolac",id_categorys:[],product_attributes:[],variations:[{id:"ed2eb369-8a67-4c38-bf65-dbd882bd1ae1",sku:"6QCPL5LN",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761656593161-876866227.png"],import_price:0,original_price:35e4,retail_price:34e4,fields:[],weight:0,stock:10,hidden:!1}],link:"sua-physiolac-so-2-400g"},{desc:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Giai đoạn đầu là giai đoạn giúp bé nhà bạn có thể hấp thụ chất dinh dưỡng tốt nhất, tăng cường khả năng miễn dịch cho bé lớn lên được an toàn và khỏe mạnh nhất. Vào giai đoạn này, hầu hết các mẹ đều cho con bú sữa mẹ hoàn toàn. Tuy nhiên nhiều mẹ do một số lý do mà không đủ sữa cho con bú nên việc cung cấp dinh dưỡng cho bé thông qua các sản phẩm sữa bột chất lượng là điều cần thiết và quan trọng. Sữa bột công thức Physiolac số 1 400g &nbsp;với những công thức tính toán cẩn trọng về thành phần, giúp trẻ dễ dàng hấp thu các chất dinh dưỡng, nâng cao sức đề kháng và tăng cường hệ miễn dịch trong giai đoạn từ 0-6 tháng tuổi.</span></p>'},desc_short:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Các nội dung Hướng dẫn mua hàng viết ở đây</span></p>'},name:{vi:"Sữa Physiolac số 1 - 400g"},seo_title:{vi:""},seo_description:{vi:""},seo_keyword:{vi:""},brand:"Physiolac",id_categorys:[],product_attributes:[],variations:[{id:"2650f2c9-7531-4d8a-9f8e-a980542e091f",sku:"BH3N4JT7",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761656677198-366596996.png"],import_price:0,original_price:35e4,retail_price:32e4,fields:[],weight:0,stock:10,hidden:!1}],link:"sua-physiolac-so-1---400g"},{desc:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Sữa Similac HMO số 3 IQ (1.7kg) công thức cải tiến mới vượt trội</span><br><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Sữa bột cho bé Similac HMO số 3 IQ với công thức cải tiến hệ dưỡng chất IQ và 2\'-FL HMO đáp ứng đầy đủ nhu cầu dinh dưỡng giúp trẻ từ 1-2 tuổi phát triển tối ưu. Không những vậy thành phần 2\'-FL HMO là Prebiotic tự nhiên tìm thấy trong sữa mẹ hỗ trợ tăng cường sức khỏe hệ miễn dịch giúp phòng tránh các mầm bệnh nguy hiểm và tạo nền tảng cho trẻ phát triển mạnh mẽ cả về trí não và thể chất.</span></p>'},desc_short:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Các nội dung Hướng dẫn mua hàng viết ở đây</span></p>'},name:{vi:"Sữa Similac IQ HMO số 4 900g"},seo_title:{vi:""},seo_description:{vi:""},seo_keyword:{vi:""},brand:"Similac",id_categorys:[],product_attributes:[],variations:[{id:"aaa789ec-b240-4eaf-9bc8-82ed153b1540",sku:"3EIACQ2G",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761656758760-168052267.png"],import_price:0,original_price:0,retail_price:7e5,fields:[],weight:0,stock:10,hidden:!1}],link:"sua-similac-iq-hmo-so-4-900g"},{desc:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Sữa Similac HMO số 3 IQ (1.7kg) công thức cải tiến mới vượt trội</span><br><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Sữa bột cho bé Similac HMO số 3 IQ với công thức cải tiến hệ dưỡng chất IQ và 2\'-FL HMO đáp ứng đầy đủ nhu cầu dinh dưỡng giúp trẻ từ 1-2 tuổi phát triển tối ưu. Không những vậy thành phần 2\'-FL HMO là Prebiotic tự nhiên tìm thấy trong sữa mẹ hỗ trợ tăng cường sức khỏe hệ miễn dịch giúp phòng tránh các mầm bệnh nguy hiểm và tạo nền tảng cho trẻ phát triển mạnh mẽ cả về trí não và thể chất.</span></p>'},desc_short:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Các nội dung Hướng dẫn mua hàng viết ở đây</span></p>'},name:{vi:"Sữa Similac Newborn IQ HMO 400g"},seo_title:{vi:""},seo_description:{vi:""},seo_keyword:{vi:""},brand:"Similac",id_categorys:[],product_attributes:[],variations:[{id:"5e6217fc-72df-4919-a342-2a034adf2362",sku:"08D0OFMU",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761656831526-957803788.png"],import_price:0,original_price:3e5,retail_price:279e3,fields:[],weight:0,stock:10,hidden:!1}],link:"sua-similac-newborn-iq-hmo-400g"},{desc:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Sữa Similac HMO số 3 IQ (1.7kg) công thức cải tiến mới vượt trội</span><br><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Sữa bột cho bé Similac HMO số 3 IQ với công thức cải tiến hệ dưỡng chất IQ và 2\'-FL HMO đáp ứng đầy đủ nhu cầu dinh dưỡng giúp trẻ từ 1-2 tuổi phát triển tối ưu. Không những vậy thành phần 2\'-FL HMO là Prebiotic tự nhiên tìm thấy trong sữa mẹ hỗ trợ tăng cường sức khỏe hệ miễn dịch giúp phòng tránh các mầm bệnh nguy hiểm và tạo nền tảng cho trẻ phát triển mạnh mẽ cả về trí não và thể chất.</span></p>'},desc_short:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Các nội dung Hướng dẫn mua hàng viết ở đây</span></p>'},name:{vi:"Sữa Similac HMO số 3 IQ 1,7kg"},seo_title:{vi:""},seo_description:{vi:""},seo_keyword:{vi:""},brand:"Similac",id_categorys:[],product_attributes:[],variations:[{id:"12898e54-8624-4a86-8b31-e0ce262253b4",sku:"UOZVCVHA",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761657025615-587614689.png"],import_price:0,original_price:0,retail_price:84e4,fields:[],weight:0,stock:10,hidden:!1}],link:"sua-similac-hmo-so-3-iq-1,7kg"},{desc:{vi:"<p>Sữa Frisolac Gold 3 1.5kg nguồn dinh dưỡng tối ưu dành cho bé từ 0 tới 6 tháng tuổi&nbsp;<br>Ngoài những dưỡng chất thiết yếu cho chế độ dinh dưỡng cân bằng, sữa bột cho bé Frisolac Gold 1 Mới, hộp thiếc 900gr, dành cho trẻ từ 0 – 6 tháng tuổi, nay với công thức cải tiến mới gồm sự kết hợp tối ưu giữa Synbiotics (Probiotics BB-12 &amp; L.casei 431&amp; Prebiotics GOS &amp; FOS) giúp hỗ trợ hệ tiêu hóa, đồng thời Frisolac Gold 1 còn cung cấp các dưỡng chất quan trọng để hỗ trợ cho sự phát triển trí não và thể chất của trẻ.</p><p>Công thức LockNutri đảm bảo dưỡng chất nguyên vẹn từ thiên nhiên trong quá trình chế biến .Giúp hấp thụ tối đa và dễ tiêu hoá - khoẻ mạnh từ bên trong</p>"},desc_short:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Các nội dung Hướng dẫn mua hàng viết ở đây</span></p>'},name:{vi:"Sữa Frisolac Gold 3 1.5kg"},seo_title:{vi:""},seo_description:{vi:""},seo_keyword:{vi:""},brand:"Frisolac",id_categorys:[],product_attributes:[],variations:[{id:"b6d2421c-eb5b-420e-9cfb-2e46c89e3bf3",sku:"KROBYEFT",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761657084217-482398164.png"],import_price:0,original_price:41e4,retail_price:4e5,fields:[],weight:0,stock:10,hidden:!1}],link:"sua-frisolac-gold-3-1.5kg"},{desc:{vi:"<p>Sữa Frisolac Gold 2 (900g) nguồn dinh dưỡng tối ưu dành cho bé từ 0 tới 6 tháng tuổi&nbsp;<br>Ngoài những dưỡng chất thiết yếu cho chế độ dinh dưỡng cân bằng, sữa bột cho bé Frisolac Gold 1 Mới, hộp thiếc 900gr, dành cho trẻ từ 0 – 6 tháng tuổi, nay với công thức cải tiến mới gồm sự kết hợp tối ưu giữa Synbiotics (Probiotics BB-12 &amp; L.casei 431&amp; Prebiotics GOS &amp; FOS) giúp hỗ trợ hệ tiêu hóa, đồng thời Frisolac Gold 1 còn cung cấp các dưỡng chất quan trọng để hỗ trợ cho sự phát triển trí não và thể chất của trẻ.</p><p>Công thức LockNutri đảm bảo dưỡng chất nguyên vẹn từ thiên nhiên trong quá trình chế biến .Giúp hấp thụ tối đa và dễ tiêu hoá - khoẻ mạnh từ bên trong</p>"},desc_short:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Các nội dung Hướng dẫn mua hàng viết ở đây</span></p>'},name:{vi:"Sữa Frisolac Gold 2 (900g)"},seo_title:{vi:""},seo_description:{vi:""},seo_keyword:{vi:""},brand:"Frisolac",id_categorys:[],product_attributes:[],variations:[{id:"8a71794f-b629-4d72-aa9a-306b73cba763",sku:"9217ZAS8",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761657146460-964400781.png"],import_price:0,original_price:0,retail_price:3e5,fields:[],weight:0,stock:0,hidden:!1}],link:"sua-frisolac-gold-2-(900g)"},{desc:{vi:"<p>Sữa Frisolac gold 1 (400gr) nguồn dinh dưỡng tối ưu dành cho bé từ 0 tới 6 tháng tuổi&nbsp;<br>Ngoài những dưỡng chất thiết yếu cho chế độ dinh dưỡng cân bằng, sữa bột cho bé Frisolac Gold 1 Mới, hộp thiếc 900gr, dành cho trẻ từ 0 – 6 tháng tuổi, nay với công thức cải tiến mới gồm sự kết hợp tối ưu giữa Synbiotics (Probiotics BB-12 &amp; L.casei 431&amp; Prebiotics GOS &amp; FOS) giúp hỗ trợ hệ tiêu hóa, đồng thời Frisolac Gold 1 còn cung cấp các dưỡng chất quan trọng để hỗ trợ cho sự phát triển trí não và thể chất của trẻ.</p><p>Công thức LockNutri đảm bảo dưỡng chất nguyên vẹn từ thiên nhiên trong quá trình chế biến .Giúp hấp thụ tối đa và dễ tiêu hoá - khoẻ mạnh từ bên trong</p>"},desc_short:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Các nội dung Hướng dẫn mua hàng viết ở đây</span></p>'},name:{vi:"Sữa Frisolac gold 1 (400gr)"},seo_title:{vi:""},seo_description:{vi:""},seo_keyword:{vi:""},brand:"Frisolac ",id_categorys:[],product_attributes:[],variations:[{id:"098f92ea-2d55-4d1f-98aa-fc7aa503e700",sku:"47MUEQUZ",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761657196987-928137824.png"],import_price:0,original_price:27e4,retail_price:262e3,fields:[],weight:0,stock:10,hidden:!1}],link:"sua-frisolac-gold-1-(400gr)"},{desc:{vi:"<p>Bỉm dán Pampers cao cấp JB NB68, khô thoáng và sạch sẽ cho trẻ<br>Để giữ vệ sinh an toàn sẽ giúp bé có sức khỏe và phát triển một cách mạnh mẽ nhất, việc lựa chọn một chiếc tã giấy hoặc bỉm cho bé nhà mình là một điều vô cùng cần thiết. Nhưng để chọn được một loại bỉm có chất lượng tốt cũng như nguồn gốc và xuất xứ rõ ràng lại là một điều không hề dễ dàng.</p><p>Bỉm dán Pampers Newborn 68 miếng là một trong số các loại bỉm cao cấp nhất tới từ Nhật Bản, được các chuyên gia kiểm thử nghiệm đảm bảo an toàn tuyệt đối cho sức khỏe của bé.</p>"},desc_short:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Các nội dung Hướng dẫn mua hàng viết ở đây</span></p>'},name:{vi:"Bỉm - Tã dán Pampers size L - 32 miếng"},seo_title:{vi:""},seo_description:{vi:""},seo_keyword:{vi:""},brand:"Pampers",id_categorys:[],product_attributes:[],variations:[{id:"183e4619-4d37-466b-9156-dc679a1509d0",sku:"AGYW1ML1",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761657276154-673160400.png"],import_price:0,original_price:21e4,retail_price:2e5,fields:[],weight:0,stock:10,hidden:!1}],link:"bim---ta-dan-pampers-size-l---32-mieng"},{desc:{vi:"<p>Bỉm dán Pampers cao cấp JB NB68, khô thoáng và sạch sẽ cho trẻ<br>Để giữ vệ sinh an toàn sẽ giúp bé có sức khỏe và phát triển một cách mạnh mẽ nhất, việc lựa chọn một chiếc tã giấy hoặc bỉm cho bé nhà mình là một điều vô cùng cần thiết. Nhưng để chọn được một loại bỉm có chất lượng tốt cũng như nguồn gốc và xuất xứ rõ ràng lại là một điều không hề dễ dàng.</p><p>Bỉm dán Pampers Newborn 68 miếng là một trong số các loại bỉm cao cấp nhất tới từ Nhật Bản, được các chuyên gia kiểm thử nghiệm đảm bảo an toàn tuyệt đối cho sức khỏe của bé.</p>"},desc_short:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Các nội dung Hướng dẫn mua hàng viết ở đây</span></p>'},name:{vi:"Bỉm - Tã dán Pampers size M - 50 miếng"},seo_title:{vi:""},seo_description:{vi:""},seo_keyword:{vi:""},brand:"Pampers",id_categorys:[],product_attributes:[],variations:[{id:"55e416e5-84c4-418b-b103-00f3fed3d8a3",sku:"GH63H9J7",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761657385743-490573315.png"],import_price:0,original_price:23e4,retail_price:2e5,fields:[],weight:0,stock:10,hidden:!1}],link:"bim---ta-dan-pampers-size-m---50-mieng"},{desc:{vi:"<p>Bỉm dán Pampers cao cấp JB NB68, khô thoáng và sạch sẽ cho trẻ<br>Để giữ vệ sinh an toàn sẽ giúp bé có sức khỏe và phát triển một cách mạnh mẽ nhất, việc lựa chọn một chiếc tã giấy hoặc bỉm cho bé nhà mình là một điều vô cùng cần thiết. Nhưng để chọn được một loại bỉm có chất lượng tốt cũng như nguồn gốc và xuất xứ rõ ràng lại là một điều không hề dễ dàng.</p><p>Bỉm dán Pampers Newborn 68 miếng là một trong số các loại bỉm cao cấp nhất tới từ Nhật Bản, được các chuyên gia kiểm thử nghiệm đảm bảo an toàn tuyệt đối cho sức khỏe của bé.</p>"},desc_short:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Các nội dung Hướng dẫn mua hàng viết ở đây</span></p>'},name:{vi:"Bỉm - Tã dán Pampers Nhật Newborn - 68 miếng"},seo_title:{vi:""},seo_description:{vi:""},seo_keyword:{vi:""},brand:"Pampers",id_categorys:[],product_attributes:[],variations:[{id:"52cc9977-ed0d-47be-b7da-7b14d34e1a7c",sku:"2VEU6ZRY",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761657452271-841964486.png"],import_price:0,original_price:3e5,retail_price:295e3,fields:[],weight:0,stock:10,hidden:!1}],link:"bim---ta-dan-pampers-nhat-newborn---68-mieng"},{desc:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Đến từ thương hiệu Unicharm nổi tiếng Nhật Bản, tã quần Moony size XL bé gái sẽ đem đến cho cô công chúa nhỏ nhà bạn những trải nghiệm đầy thích thú. Thiết kế dành riêng cho bé gái với màu hồng dễ thương cùng với những họa tiết ngộ nghĩnh, đáng yêu, chất liệu cao cấp, mềm mại, chỉ thị ướt báo thời gian thay tã thuận tiện, từng chiếc tã Moony không những đem đến cho bé cảm giác thoải mái, dễ chịu tối đa mà còn giúp mẹ dễ dàng và tiện lợi hơn trong công việc chăm sóc bé yêu hàng ngày.</span></p>'},desc_short:{vi:'<p><span style="background-color:rgb(255,255,255);color:rgb(112,112,112);font-size:14px;">Các nội dung Hướng dẫn mua hàng viết ở đây</span></p>'},name:{vi:"Bỉm - Tã dán Moony size M - 64 miếng"},seo_title:{vi:""},seo_description:{vi:""},seo_keyword:{vi:""},brand:"Moony ",id_categorys:[],product_attributes:[],variations:[{id:"98a53409-e67d-4e5f-a717-7e530d97112b",sku:"6ECWS54D",imgs:["http://localhost:3000/backend/uploads/68f65f70d8180afb2bb757c1/product/1761657517149-265443315.png"],import_price:0,original_price:3e5,retail_price:297e3,fields:[],weight:0,stock:0,hidden:!1}],link:"bim---ta-dan-moony-size-m---64-mieng"}],k=new n("WEBBUILDER_API_URL");class w{apiUrl=o(k);socket=null;connect(){this.socket||(this.socket=g(this.apiUrl),console.log("Socket connected"))}sendMessage(e,t){this.socket&&this.socket.emit(e,t)}onMessage(e,t){this.socket&&this.socket.on(e,t)}disconnect(){this.socket&&(this.socket.disconnect(),this.socket=null,console.log("Socket disconnected"))}static"ɵfac"=i.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"20.3.15",ngImport:i,type:w,deps:[],target:i.ɵɵFactoryTarget.Injectable});static"ɵprov"=i.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"20.3.15",ngImport:i,type:w,providedIn:"root"})}i.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"20.3.15",ngImport:i,type:w,decorators:[{type:r,args:[{providedIn:"root"}]}]});class P{http;socketService;apiUrl=o(k);urlBE=`${this.apiUrl}/api/v1`;group;projectWorking=null;parentChoosing=null;itemChoosing=null;elementChoosingRef=null;isShiftPressed=!1;arrayChoosing=[];currentPage=null;pages=[];blocks=[];objects=[];freeblocks=[];chatboxs=[];device=localStorage.getItem("device")?JSON.parse(localStorage.getItem("device")||""):"desktop";type="design";loading=!1;group_frames=[];group_objects=[];toolsBox=[];toolsBoxPosition={x:0};isFreeBlock=!1;header=null;footer=null;chatbox=null;blockPicking=null;heightMainDesign=0;resizeGroup={image:{width:"--width",height:"--height"},block:{width:"--width",height:"--min-height"}};clientId=Math.random().toString(36).slice(2)+Date.now();infoVirtualSelected={left:0,top:0,width:0,height:0};currentTool=null;EventBus=new d;zoom=1;allowCopy=!1;constructor(e,t){this.http=e,this.socketService=t}realTimeUpdate(){this.socketService.onMessage("add_doc",e=>{if(e.client_id!==this.clientId&&e.db==this.projectWorking._id&&("wb_pages"==e.col_name&&(this.pages=[...this.pages,e.data]),"wb_blocks"==e.col_name&&(this.blocks=[...this.blocks,e.data],"block_blank"==e.data.type?e.data.id_page==this.currentPage._id&&(this.currentPage.blocks=[...this.currentPage.blocks,e.data]):this.freeblocks=[...this.freeblocks,e.data]),"wb_objects"==e.col_name)){this.objects=[...this.objects,e.data];const t=e.data.id_object||e.data.id_block;if(t){const i=this.findItemById(t);i&&(i.objects||(i.objects=[]),i.objects.push(e.data))}}}),this.socketService.onMessage("update_doc",e=>{if(e.client_id!==this.clientId&&e.db==this.projectWorking._id){if("wb_pages"==e.col_name){const t=this.pages.findIndex(t=>t._id===e.docKey);if(-1==t)return;if(this.pages[t]={...this.pages[t],...e.data},this.currentPage&&this.currentPage._id===e.docKey){if(e.data.hasOwnProperty("id_clone_blocks"))if(this.currentPage.hasOwnProperty("id_clone_blocks")||(this.currentPage.id_clone_blocks=[]),e.data.id_clone_blocks?.length>this.currentPage.id_clone_blocks?.length){e.data.id_clone_blocks.filter(e=>!this.currentPage.id_clone_blocks.includes(e)).forEach(t=>{let i=this.blocks.find(e=>e._id==t);i&&(i=JSON.parse(JSON.stringify(i)),i.id_page=e.docKey,i.is_clone=!0,i.objects=this.getFullObjectsForBlock(i),this.currentPage.blocks.push(i))})}else this.currentPage.blocks=this.currentPage.blocks.filter(t=>e.data.id_clone_blocks.includes(t._id));this.currentPage={...this.currentPage,...e.data},e.data[this.device+"_config"]?.id_header?this.header=this.freeblocks.find(t=>t._id==e.data[this.device+"_config"].id_header):this.header=null,e.data[this.device+"_config"]?.id_footer?this.footer=this.freeblocks.find(t=>t._id==e.data[this.device+"_config"].id_footer):this.footer=null}}if("wb_blocks"==e.col_name){const t=this.blocks.findIndex(t=>t._id===e.docKey),i=this.freeblocks.findIndex(t=>t._id===e.docKey);if(-1!=t){let t=this.blocks.findIndex(t=>t._id===e.docKey);this.blocks[t]={...this.blocks[t],...e.data};const i=this.currentPage.blocks.findIndex(t=>t._id===e.docKey);if(-1!==i){if(e.data.hasOwnProperty("id_clone_objects"))if(this.currentPage.blocks[i].hasOwnProperty("id_clone_objects")||(this.currentPage.blocks[i].id_clone_objects=[]),e.data.id_clone_objects?.length>this.currentPage.blocks[i].id_clone_objects?.length){e.data.id_clone_objects.filter(e=>!this.currentPage.blocks[i].id_clone_objects.includes(e)).forEach(t=>{let n=this.objects.find(e=>e._id==t);n&&(n=JSON.parse(JSON.stringify(n)),n.id_block=e.docKey,n.is_clone=!0,delete n.id_object,n.objects=this.getFullObjectsForObject(n),this.currentPage.blocks[i].objects.push(n))})}else this.currentPage.blocks[i].objects=this.currentPage.blocks[i].objects.filter(t=>e.data.id_clone_objects.includes(t._id));this.currentPage.blocks[i]={...this.currentPage.blocks[i],...e.data}}}if(-1!=i){const t=this.freeblocks.findIndex(t=>t._id===e.docKey);if(-1!==t){if(e.data.hasOwnProperty("id_clone_objects"))if(this.freeblocks[t].hasOwnProperty("id_clone_objects")||(this.freeblocks[t].id_clone_objects=[]),e.data.id_clone_objects?.length>this.freeblocks[t].id_clone_objects?.length){e.data.id_clone_objects.filter(e=>!this.freeblocks[t].id_clone_objects.includes(e)).forEach(i=>{let n=this.objects.find(e=>e._id==i);n&&(n=JSON.parse(JSON.stringify(n)),n.id_block=e.docKey,n.is_clone=!0,delete n.id_object,n.objects=this.getFullObjectsForObject(n),this.freeblocks[t].objects.push(n))})}else this.freeblocks[t].objects=this.freeblocks[t].objects.filter(t=>e.data.id_clone_objects.includes(t._id));this.freeblocks[t]={...this.freeblocks[t],...e.data}}}}if("wb_objects"==e.col_name){const t=this.objects.findIndex(t=>t._id===e.docKey);if(-1==t)return;this.objects[t]={...this.objects[t],...e.data};let i=this.objects[t].id_object||this.objects[t].id_block;for(const t in e.data)t.includes("_position_")&&(i=t.split("_position_")[1]);if(i){const t=this.findItemById(i);if(t){const i=t.objects.findIndex(t=>t._id===e.docKey);if(-1!==i){if(e.data.hasOwnProperty("id_clone_objects")){const n=t.objects[i];if(n.hasOwnProperty("id_clone_objects")||(n.id_clone_objects=[]),e.data.id_clone_objects?.length>n.id_clone_objects?.length){e.data.id_clone_objects.filter(e=>!n.id_clone_objects.includes(e)).forEach(n=>{let o=this.objects.find(e=>e._id==n);o&&(o=JSON.parse(JSON.stringify(o)),o.id_object=e.docKey,o.is_clone=!0,delete o.id_block,o.objects=this.getFullObjectsForObject(o),t.objects[i].objects.push(o))})}else t.objects[i].objects=t.objects[i].objects.filter(t=>!t.is_clone||e.data.id_clone_objects.includes(t._id))}t.objects[i]={...t.objects[i],...e.data}}}}}}}),this.socketService.onMessage("delete_doc",e=>{if(e.client_id!==this.clientId&&e.db==this.projectWorking._id&&("wb_pages"==e.col_name&&(this.pages=this.pages.filter(t=>t._id!==e.docKey),this.currentPage&&this.currentPage._id===e.docKey&&(this.currentPage=null)),"wb_blocks"==e.col_name&&(this.blocks=this.blocks.filter(t=>t._id!==e.docKey),this.currentPage.blocks=this.currentPage.blocks.filter(t=>t._id!==e.docKey),this.freeblocks=this.freeblocks.filter(t=>t._id!==e.docKey)),"wb_objects"==e.col_name)){const t=this.objects.findIndex(t=>t._id===e.docKey);if(-1!==t){const i=this.objects[t];this.objects.splice(t,1);const n=i.id_object||i.id_block;if(n){const t=this.findItemById(n);t&&t.objects&&(t.objects=t.objects.filter(t=>t._id!==e.docKey))}}}})}closeConnection(){this.socketService.disconnect()}onNotifyChange(e){return this.EventBus.asObservable().subscribe(e)}notifyChange(e){this.EventBus.next(e)}findItemById(e){let t=null;const{currentPage:i,freeblocks:n}=this;for(const n of i.blocks)if(t=this.findItemInTree(n,e),t)break;if(!t)for(const i of n)if(t=this.findItemInTree(i,e),t)break;return t}findItemInTree(e,t){if(e._id===t)return e;if(e.objects)for(const i of e.objects){const e=this.findItemInTree(i,t);if(e)return e}return null}wrapApiCall(e){return c(e.pipe(h(e=>p(()=>{const t=e.error;return console.error("API Error:",e),t}))))}addProject(e){return new Promise((t,i)=>{this.wrapApiCall(this.http.post(`${this.urlBE}/projects`,{data:e})).then(e=>{let i=[];i.push(this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/add`,{col_name:"wb_pages",data:{...v,name:{vi:"Trang chủ"},type:"page_home"},db:e.data._id}))),y.forEach(t=>{i.push(this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/add`,{col_name:"products",data:t,db:e.data._id})))}),Promise.all(i).then(()=>{t(e)})})})}updateProject(e,t){return new Promise((i,n)=>{this.wrapApiCall(this.http.put(`${this.urlBE}/projects/${e}`,{value:t})).then(e=>{i(e)})})}deleteProject(e){return this.wrapApiCall(this.http.delete(`${this.urlBE}/projects/${e}`))}getProjects_byFields(e,i,n,o){const r=new t({fromObject:{page:String(n),limit:String(o),query:JSON.stringify(e??{}),sort:JSON.stringify(i??{})}});return this.wrapApiCall(this.http.get(`${this.urlBE}/projects`,{params:r})).then(e=>e)}sortVietnamese(e){const t=new Intl.Collator("vi",{sensitivity:"base"}),i=this.projectWorking.language.defaule;return[...e].sort((e,n)=>t.compare(e.name[i],n.name[i]))}getHeaderFooter(){const{currentPage:e,device:t,freeblocks:i}=this,{id_header:n,id_footer:o,id_chatboxs:r}=e[t+"_config"];if(n){const e=i.find(e=>e._id==n);this.header=e||null}else this.header=null;if(o){const e=i.find(e=>e._id==o);this.footer=e||null}else this.footer=null;this.chatboxs=this.freeblocks.filter(e=>r?.includes(e._id))}connectProject(e){return new Promise((t,i)=>{this.projectWorking?t():(this.socketService.connect(),this.socketService.sendMessage("get_project_data",{id_project:e}),this.socketService.onMessage("project_data",e=>{const i=JSON.parse(e);this.setProjectWorking(i),t()}))})}setProjectWorking(e){this.projectWorking=e.project,this.pages=this.sortVietnamese(e.pages),this.blocks=e.blocks.filter(e=>"block_blank"==e.type),this.freeblocks=e.blocks.filter(e=>"block_blank"!=e.type),this.objects=e.objects;let t=localStorage.getItem("page")?JSON.parse(localStorage.getItem("page")||""):null;t&&this.pages.find(e=>e._id==t)||(t=this.pages.find(e=>"page_home"==e.type)._id),this.freeblocks.forEach(e=>(e.objects=this.getFullObjectsForBlock(e),e)),this.currentPage=this.getDetailPage(t),this.getHeaderFooter(),this.updateHeightDesign()}getDetailPage(e){const t=structuredClone(this.pages.find(t=>t._id===e));if(t){const i=structuredClone(this.blocks.filter(t=>t.id_page===e));t.blocks=i.map(e=>(e.objects=this.getFullObjectsForBlock(e),e)),t.id_clone_blocks?.length&&t.id_clone_blocks.forEach(e=>{let i=this.blocks.find(t=>t._id==e);i&&(i=JSON.parse(JSON.stringify(i)),i.id_page=t._id,i.is_clone=!0,i.objects=this.getFullObjectsForBlock(i),t.blocks.push(i))})}return t.blocks.sort((e,t)=>e[this.device+"_position_"+e.id_page].index<t[this.device+"_position_"+t.id_page].index?-1:e[this.device+"_position_"+e.id_page].index>t[this.device+"_position_"+t.id_page].index?1:0),t}getFullObjectsForBlock(e){const t=[];e.id_clone_objects?.length&&e.id_clone_objects.forEach(i=>{let n=this.objects.find(e=>e._id==i);n&&(n=JSON.parse(JSON.stringify(n)),n.id_block=e._id,n.is_clone=!0,delete n.id_object,n.objects=this.getFullObjectsForObject(n),t.push(n))});return structuredClone(this.objects.filter(t=>t.id_block===e._id)).forEach(e=>{e.objects=this.getFullObjectsForObject(e),t.push(e)}),t}getFullObjectsForObject(e){let t=[];e.id_clone_objects?.length&&e.id_clone_objects.forEach(i=>{let n=this.objects.find(e=>e._id==i);n&&(n=JSON.parse(JSON.stringify(n)),n.id_object=e._id,n.is_clone=!0,delete n.id_block,n.objects=this.getFullObjectsForObject(n),t=[...t,n])});return structuredClone(this.objects.filter(t=>t.id_object===e._id)).forEach(e=>{e.objects=this.getFullObjectsForObject(e),t=[...t,e]}),t}addPage(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/add`,{col_name:"wb_pages",data:e,client_id:this.clientId,db:this.projectWorking._id})).then(e=>(this.pages=[...this.pages,e.data],this.sortVietnamese(this.pages),e))}deletePage(e){const t=this.getDetailPage(e);let i=this.flatNodes(t.blocks).map(e=>e.type.includes("block")?e.is_clone?this.deleteBlockClone(e):this.deleteBlockDbAndLocal(e._id):e.is_clone?this.deleteObject(e):this.deleteObjectDbAndLocal(e._id));return i.push(this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/delete`,{col_name:"wb_pages",docKey:e,client_id:this.clientId,db:this.projectWorking._id}))),Promise.all(i).then(t=>(this.pages=this.pages.filter(t=>t._id!==e),t))}getPage(e){return new Promise((t,i)=>{const n=this.pages.find(t=>t._id==e);n&&t({vcode:0,data:n})})}deleteBlockDbAndLocal(e){this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/delete`,{col_name:"wb_blocks",docKey:e,client_id:this.clientId,db:this.projectWorking._id})).then(t=>{this.blocks=this.blocks.filter(t=>t._id!=e)})}deleteObjectDbAndLocal(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/delete`,{col_name:"wb_objects",docKey:e,client_id:this.clientId,db:this.projectWorking._id})).then(t=>{this.objects=this.objects.filter(t=>t._id!=e)})}flatNodes(e){const t=[];for(const i of e)t.push(i),i.objects&&i.objects.length>0&&!i.is_clone&&t.push(...this.flatNodes(i.objects));return t}updatePage(e,t){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/update`,{col_name:"wb_pages",docKey:e,value:t,client_id:this.clientId,db:this.projectWorking._id})).then(i=>{this.pages=this.pages.map(i=>i._id==e?{...i,...t}:i)})}getPages(){return Promise.resolve({vcode:0,data:this.pages,msg:""})}addBlock(e){if("block_blank"==e.type){const t=this.getDetailPage(e.id_page);if(t){const i=t.blocks.reduce((t,i)=>Math.max(i[this.device+"_position_"+e.id_page].index,t),-1);e[this.device+"_position_"+e.id_page]={...e[this.device+"_position_"+e.id_page],index:i+1}}}return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/add`,{col_name:"wb_blocks",data:e,client_id:this.clientId,db:this.projectWorking._id})).then(t=>("block_blank"==e.type?(this.blocks=[...this.blocks,t.data],t.data.id_page==this.currentPage._id&&(this.currentPage.blocks=[...this.currentPage.blocks,t.data]),this.updateHeightDesign()):this.freeblocks=[...this.freeblocks,t.data],t))}updateBlock(e,t){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/update`,{col_name:"wb_blocks",docKey:e,value:t,client_id:this.clientId,db:this.projectWorking._id})).then(i=>{this.blocks=this.blocks.map(i=>i._id==e?{...i,...t}:i)})}deleteBlock(e){const t=structuredClone([...this.blocks,...this.freeblocks].find(t=>t._id===e)),i=this.getFullObjectsForBlock(t);let n=this.flatNodes(i).map(e=>e.type.includes("block")?e.is_clone?this.deleteBlockClone(e):this.deleteBlockDbAndLocal(e._id):e.is_clone?this.deleteObjectClone(e):this.deleteObjectDbAndLocal(e._id));return n.push(this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/delete`,{col_name:"wb_blocks",docKey:e,client_id:this.clientId,db:this.projectWorking._id}))),Promise.all(n).then(i=>{this.blocks=this.blocks.filter(t=>t._id!=e),this.freeblocks=this.freeblocks.filter(t=>t._id!=e),this.currentPage.blocks=this.currentPage.blocks.filter(t=>t._id!==e),"block_blank"==t.type&&this.currentPage.blocks.forEach((e,t)=>{e[`${this.device}_position_${this.currentPage._id}`]={...e[`${this.device}_position_${this.currentPage._id}`],index:t},this.updateBlock(e._id,{[`${this.device}_position_${this.currentPage._id}`]:e[`${this.device}_position_${this.currentPage._id}`]})})})}deleteBlockClone(e){return new Promise((t,i)=>{this.currentPage.id_clone_blocks.includes(e._id)&&(this.currentPage.id_clone_blocks=this.currentPage.id_clone_blocks.filter(t=>t!==e._id),this.updatePage(this.currentPage._id,{id_clone_blocks:this.currentPage.id_clone_blocks}).then(i=>{this.currentPage.blocks=this.currentPage.blocks.filter(t=>t._id!=e._id),t(i)}))})}addObject(e){return["object_text_repeat","object_button_repeat","object_image_repeat","object_video_repeat","object_youtube_repeat"].includes(e.type)&&!e.code&&(e.code=this.generateObjectId()),this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/add`,{col_name:"wb_objects",data:e,client_id:this.clientId,db:this.projectWorking._id})).then(t=>{this.objects.push(structuredClone(t.data));const i=e.id_object??e.id_block;if(i){const e=this.findItemById(i);e&&(e.objects||(e.objects=[]),e.objects.push(t.data))}return t})}updateObject(e,t){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/update`,{col_name:"wb_objects",docKey:e,value:t,client_id:this.clientId,db:this.projectWorking._id})).then(i=>{this.objects=this.objects.map(i=>i._id==e?{...i,...t}:i)})}deleteObject(e){const t=this.objects.find(t=>t._id==e),i=this.getFullObjectsForObject(t);let n=this.flatNodes(i).map(e=>e.is_clone?this.deleteObjectClone(e):this.deleteObjectDbAndLocal(e._id));return n.push(this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/delete`,{col_name:"wb_objects",docKey:e,client_id:this.clientId,db:this.projectWorking._id}))),Promise.all(n).then(i=>{const n=this.findItemById(t.id_object||t.id_block);n&&(n.objects=n.objects.filter(t=>t._id!==e)),this.objects=this.objects.filter(t=>t._id!=e)})}deleteObjectClone(e){return new Promise((t,i)=>{const n=this.findItemById(e.id_object||e.id_block);if(n){n.id_clone_objects=n.id_clone_objects.filter(t=>t!==e._id);let i=[];n.type.includes("block")?i.push(this.updateBlock(n._id,{id_clone_objects:n.id_clone_objects})):i.push(this.updateObject(n._id,{id_clone_objects:n.id_clone_objects})),Promise.all(i).then(i=>{n.objects=n.objects.filter(t=>t._id!==e._id),t(i)})}})}upLoadImage(e,t,i,n){const o=new FormData;return o.append("db",this.projectWorking._id),o.append("newPath",i),t&&o.append("oldPath",t),o.append("options",JSON.stringify(n)),o.append("file",e),this.wrapApiCall(this.http.post(`${this.urlBE}/upload`,o))}addCategory(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/add`,{col_name:"categories",data:e,db:this.projectWorking._id})).then(e=>e)}updateCategory(e,t){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/update`,{col_name:"categories",docKey:e,value:t,db:this.projectWorking._id})).then(e=>e)}deleteCategory(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/delete`,{col_name:"categories",docKey:e,db:this.projectWorking._id})).then(e=>e)}getCategories_byFields(e,t,i,n){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/get`,{col_name:"categories",db:this.projectWorking._id,query:e,sort:t,page:i,limit:n})).then(e=>{const t=(e=>{if(!e||0===e.length)return[];const t=[],i=(n,o=0)=>{e.filter(e=>e.id_parent==n).forEach(e=>{const n={...e,level:o};t.push(n),i(e._id,o+1)})};return i("",0),t})(e.data);return{...e,data:t}})}searchList_likeSearch(e,t,i){return(e=e.trim())&&""!==e?this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/searchList_likeSearch`,{value:e,col_name:t,field:i,lang:this.projectWorking.language.default,db:this.projectWorking._id})).then(e=>e):Promise.resolve({vcode:0,data:[]})}addProduct(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/add`,{col_name:"products",data:e,db:this.projectWorking._id})).then(e=>e)}updateProduct(e,t){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/update`,{col_name:"products",docKey:e,value:t,db:this.projectWorking._id})).then(e=>e)}deleteProduct(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/delete`,{col_name:"products",docKey:e,db:this.projectWorking._id})).then(e=>e)}getProducts_byFields(e,t,i,n){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/get`,{col_name:"products",db:this.projectWorking._id,query:e,sort:t,page:i,limit:n}))}getProducts_byCategoryLink(e,t,i,n,o){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/getdetail_bycategory`,{col_name:"products",db:this.projectWorking._id,link_category:e,query:t,sort:i,page:n,limit:o}))}getDetailProduct_byLink(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/getdetail_bylink`,{col_name:"products",db:this.projectWorking._id,link:e}))}addNews(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/add`,{col_name:"news",data:e,db:this.projectWorking._id})).then(e=>e)}updateNews(e,t){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/update`,{col_name:"news",docKey:e,value:t,db:this.projectWorking._id})).then(e=>e)}deleteNews(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/delete`,{col_name:"news",docKey:e,db:this.projectWorking._id})).then(e=>e)}getNews_byFields(e,t,i,n){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/get`,{col_name:"news",db:this.projectWorking._id,query:e,sort:t,page:i,limit:n}))}addNewField(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/add`,{col_name:"wb_newfields",data:e,db:this.projectWorking._id})).then(e=>e)}updateNewField(e,t){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/update`,{col_name:"wb_newfields",docKey:e,value:t,db:this.projectWorking._id})).then(e=>e)}deleteNewField(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/delete`,{col_name:"wb_newfields",docKey:e,db:this.projectWorking._id})).then(e=>e)}getNewField_byFields(e,t,i,n){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_template/get`,{col_name:"wb_newfields",db:this.projectWorking._id,query:e,sort:t,page:i,limit:n}))}displayBocksOfPage_byScroll(e){e.blocks.forEach(e=>{})}setItemChoosing(e,t,i){if("design"!=this.type)return;if(null==e||null==e){if(this.isFreeBlock)return;return this.itemChoosing=null,this.arrayChoosing=[],this.isFreeBlock=!1,this.blockPicking=null,this.elementChoosingRef=null,this.group_frames=[],this.group_objects=[],this.toolsBox=[],this.currentTool=null,void(this.allowCopy=!0)}this.itemChoosing=null,this.arrayChoosing=[e],this.parentChoosing=i||null,this.itemChoosing=e,e.type.includes("block")&&"block_blank"!=e.type&&(this.isFreeBlock=!0,this.blockPicking=e),this.itemChoosing[this.device+"_config"].drag_mode||(this.itemChoosing[this.device+"_config"].drag_mode="absolute"),e.type.includes("block")?(this.group_frames=this.group.blocks[e.type].group_frames,this.group_objects=this.group.blocks[e.type].group_objects):e.type.includes("frame")&&(this.group_frames=this.group.frames[e.type].group_frames,this.group_objects=this.group.frames[e.type].group_objects),this.toolsBox=e.type.includes("block")||e.type.includes("frame")?JSON.parse(JSON.stringify(_)):JSON.parse(JSON.stringify(f)),e.type.includes("frame")&&(this.toolsBox=this.toolsBox.filter(e=>!["Xuống dưới","Lên trên"].includes(e.label))),e.is_clone&&(this.toolsBox=this.toolsBox.filter(e=>["Sắp xếp lớp","Xóa"].includes(e.label)),"block_blank"==e.type&&(this.toolsBox=[...JSON.parse(JSON.stringify(_)).filter(e=>["Xuống dưới","Lên trên"].includes(e.label)),...this.toolsBox]),this.toolsBox=[{label:"Di chuyển đến đối tượng gốc",icon:"check-circle"},...this.toolsBox]),this.currentTool=null,["object_button_dialog","object_product_input_search"].includes(e.type)&&this.toolsBox.splice(1,0,{label:"Thiết kế khối hộp thoại",icon:"box-plot"}),e.type.includes("block")&&"block_blank"!=e.type&&(this.toolsBox=this.toolsBox.filter(e=>!["Lên trên","Xuống dưới"].includes(e.label)));const n=document.querySelector(`.${this.device}`),o=n&&n.parentNode?n.parentNode.getBoundingClientRect():null;this.toolsBoxPosition.x=n.getBoundingClientRect().left>o.left?n.getBoundingClientRect().left-150:o.left-150,console.log("data",e),setTimeout(()=>{this.allowCopy=!0,this.elementChoosingRef=t},0)}getCart(){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/carts/get`,{db:this.projectWorking._id}))}addToCart(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/carts/add`,{itemToAdd:e,db:this.projectWorking._id}))}deleteCartItem(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/carts/delete`,{id_variation:e,db:this.projectWorking._id}))}updateCartItem(e,t){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/carts/update`,{id_variation:e,quantity:t,db:this.projectWorking._id}))}addAddress(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/address/add`,{data:e,col_name:"address",db:this.projectWorking._id}))}updateAddress(e,t){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/address/update`,{docKey:e,col_name:"address",value:t,db:this.projectWorking._id}))}deleteAddress(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/address/delete`,{docKey:e,col_name:"address",db:this.projectWorking._id}))}getProvinces(){return c(this.http.get("assets/data/website-builder.provinces.json")).then(e=>({vcode:0,data:e.sort((e,t)=>e.name.localeCompare(t.name,"vi",{sensitivity:"base"}))}))}getDistricts(e){return c(this.http.get("assets/data/website-builder.districts.json")).then(t=>({vcode:0,data:t.filter(t=>t.province_code==e).sort((e,t)=>e.name.localeCompare(t.name,"vi",{sensitivity:"base"}))}))}getWards(e){return c(this.http.get("assets/data/website-builder.wards.json")).then(t=>({vcode:0,data:t.filter(t=>t.district_code==e).sort((e,t)=>e.name.localeCompare(t.name,"vi",{sensitivity:"base"}))}))}getCountries(){return this.wrapApiCall(this.http.get("https://restcountries.com/v3.1/all?fields=name,flags"))}updateHeightDesign(){setTimeout(()=>{this.heightMainDesign=this.currentPage.blocks.reduce((e,t)=>e+ +t[this.device+"_class"][t.resize_field][this.resizeGroup[t.resize_group].height].replace("px",""),0),this.heightMainDesign+=200},0)}getObject(e){return new Promise((t,i)=>{const n=this.objects.find(t=>t._id===e);n&&t({vcode:0,data:n})})}getBlock(e){return new Promise((t,i)=>{const n=this.blocks.find(t=>t._id===e);n?t({vcode:0,data:n}):i(new Error("Block not found"))})}handleCtrl_C(){return new Promise((e,t)=>{if(!this.allowCopy||0==this.arrayChoosing.length)return;let i={type:"ctrl_c",data:this.arrayChoosing};return navigator.clipboard.writeText(JSON.stringify(i)),e({vcode:0,msg:`Đã sao chép ${this.arrayChoosing.length} đối tượng`})})}handleCtrl_D(){return new Promise((e,t)=>{const{itemChoosing:i,arrayChoosing:n}=this;if(!this.allowCopy||0===n.length)return e({vcode:1,msg:"Không có gì để nhân bản"});if(i?.type.includes("block")&&"block_blank"!==i?.type)return t({vcode:1,msg:"Không thể nhân bản khối này, chỉ có thể nhân bản khối trống"});const o={type:"ctrl_d",data:n};return navigator.clipboard.writeText(JSON.stringify(o)),e({vcode:0,msg:"Nhân bản thành công"})})}handleCtrl_V(){navigator.clipboard.readText().then(async e=>{let t=e;try{if(t=JSON.parse(e),"ctrl_c"!=t.type||t.copy_page){if("ctrl_d"==t.type){let e=t.data;for(const t of e)if(t.type.includes("object")||t.type.includes("frame"))await this.handleCloneObject(this.itemChoosing,t,!0);else{if(this.currentPage.id_clone_blocks&&this.currentPage.id_clone_blocks.some(e=>e==t._id)||this.currentPage.blocks.some(e=>e._id==t._id))return console.error("Khối này đã tồn tại");await this.handleCloneBlock(this.currentPage,t)}}}else{const e=t.data;if(e[0].type.includes("object")||e[0].type.includes("frame")){if(0==this.arrayChoosing.length)return;if(this.itemChoosing?.type.includes("object")||["AtwFrameTabs","AtwFrameBanner","AtwFrameCollapse"].includes(this.itemChoosing?.component)||this.itemChoosing?.is_clone)return console.error("Không thể dán vào đối tượng này");if("AtwFrameRepeat"==this.itemChoosing?.component&&e.some(e=>!["AtwTextRepeat","AtwImageRepeat","AtwShape","AtwButtonRepeat"].includes(e.component)))return console.error("Không thể dán vào đối tượng này");this.loading=!0;for(const t of e)await this.handleCopyObject(this.itemChoosing,t,!0);this.loading=!1}else{this.loading=!0;for(const t of e)await this.handleCopyBlock(this.currentPage,t);this.loading=!1}}}catch{}})}applyFontLinks(e){(new DOMParser).parseFromString(e,"text/html").querySelectorAll("link").forEach(e=>{document.head.appendChild(e.cloneNode(!0))})}getFontNames(e){const t=(new DOMParser).parseFromString(e,"text/html"),i=t.querySelector("link[href*='fonts.googleapis.com/css2']")?.getAttribute("href");return i?[...i.matchAll(/family=([^:&]+)/g)].map(e=>decodeURIComponent(e[1]).replace(/\+/g," ")):[]}async handleCopyBlock(e,t){try{if(t.is_clone&&this.blocks.find(e=>e._id==t._id))await this.handleCloneBlock(e,t);else{let i={...t};delete i._id,delete i.is_clone,delete i.id_page,i.objects=[],i.id_clone_objects=[],i.name=t.name+"- Copy","block_blank"==i.type&&(i.id_page=e._id,m.forEach(n=>{const o=n.value;i[o+"_position_"+e._id]={...t[o+"_position_"+t.id_page]}}));const n=await this.addBlock(i);if(t.objects&&t.objects.length>0)for(const e of t.objects)await this.handleCopyObject(n.data,e)}}catch(e){console.error("error",e)}}async handleCopyObject(e,t,i=!1){if(t.is_clone&&this.objects.find(e=>e._id==t._id))this.handleCloneObject(e,t,i);else{delete t.is_clone;let n={...t};delete n._id,delete n.province,delete n.district,delete n.ward,n.objects=[],n.id_clone_objects=[],e.type.includes("block")?(n.id_block=e._id,delete n.id_object):(n.id_object=e._id,delete n.id_block),n.name=t.name+"- Copy",m.forEach(o=>{const r=o.value;n[r+"_position_"+e._id]={...t[r+"_position_"+(t.id_block||t.id_object)]},e._id==(t.id_block||t.id_object)?(n[r+"_position_"+e._id].top+=10,n[r+"_position_"+e._id].left+=10):i&&(n[r+"_position_"+e._id].top=0,n[r+"_position_"+e._id].left=0)});const o=await this.addObject(n);if(t.objects&&t.objects.length>0)for(const e of t.objects)await this.handleCopyObject(o.data,e)}}async handleCopyPage(e){const t=structuredClone(e),i=this.projectWorking.language.available;for(const e of i)t.name[e]=t.name[e]+"-Copy";t.link=t.link+"-copy",delete t._id,delete t.blocks,t.id_clone_blocks=[];const n=await this.addPage(t);if(e.blocks&&e.blocks.length>0)for(const t of e.blocks)try{await this.handleCopyBlock(n.data,t)}catch(e){console.error("error",e)}return n}async handleCloneBlock(e,t){const i=this.blocks.find(e=>e._id==t._id);if(!e||!i)return;e.id_clone_blocks||(e.id_clone_blocks=[]),e.blocks||(e.blocks=[]);const n={top:0,left:0,index:e.blocks.reduce((t,i)=>Math.max(t,i[this.device+"_position_"+e._id].index),-1)+1,z_index:1};await this.updateBlock(t._id,{["desktop_position_"+e._id]:n,["tablet_landscape_position_"+e._id]:n,["tablet_portrait_position_"+e._id]:n,["mobile_landscape_position_"+e._id]:n,["mobile_portrait_position_"+e._id]:n}),e.id_clone_blocks.some(e=>e==t._id)||(e.id_clone_blocks=[...e.id_clone_blocks,t._id],await this.updatePage(e._id,{id_clone_blocks:e.id_clone_blocks}));const o={...t,["desktop_position_"+e._id]:n,["tablet_landscape_position_"+e._id]:n,["tablet_portrait_position_"+e._id]:n,["mobile_landscape_position_"+e._id]:n,["mobile_portrait_position_"+e._id]:n};o.is_clone=!0,o.id_page=e._id,e.blocks=[...e.blocks,o]}async handleCloneObject(e,t,i=!1){if(!this.objects.some(e=>e._id==t._id))return;if(i){const{itemChoosing:e}=this;if(t._id===e?._id)return void console.error("Không thể clone chính đối tượng đang chọn");if(e?.objects.some(e=>e._id===t._id))return void console.error("Không thể clone đối tượng đã clone");if(this.findItemInTree(t,e._id))return void console.error("Không thể clone đối tượng là cha của đối tượng đang chọn")}const n={...t};m.forEach(o=>{const r=o.value;n[r+"_position_"+e._id]={...t[r+"_position_"+(t.id_block||t.id_object)]},i&&(n[r+"_position_"+e._id]={top:0,left:0,z_index:1})}),e.hasOwnProperty("id_clone_objects")||(e.id_clone_objects=[]),await this.updateObject(n._id,{["desktop_position_"+e._id]:n["desktop_position_"+e._id],["tablet_landscape_position_"+e._id]:n["tablet_landscape_position_"+e._id],["tablet_portrait_position_"+e._id]:n["tablet_portrait_position_"+e._id],["mobile_landscape_position_"+e._id]:n["mobile_landscape_position_"+e._id],["mobile_portrait_position_"+e._id]:n["mobile_portrait_position_"+e._id]}),e.id_clone_objects.some(e=>e==n._id)||(e.id_clone_objects.push(n._id),e.type.includes("block")?await this.updateBlock(e._id,{id_clone_objects:e.id_clone_objects}):await this.updateObject(e._id,{id_clone_objects:e.id_clone_objects})),n.is_clone=!0,e.type.includes("block")?(delete n.id_object,n.id_block=e._id):(delete n.id_block,n.id_object=e._id),e.objects=[...e.objects,n]}handleOrder(e,t,i){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/order`,{customer_info:e,note:t,payment_method:i,db:this.projectWorking._id}))}getOrders_byFields(e,t,i,n){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/get`,{col_name:"orders",db:this.projectWorking._id,query:e,sort:t,page:i,limit:n}))}updateOrder(e,t){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/update`,{col_name:"orders",docKey:e,value:t,db:this.projectWorking._id})).then(e=>e)}deleteOrder(e){return this.wrapApiCall(this.http.post(`${this.urlBE}/doc_database/delete`,{col_name:"orders",docKey:e,db:this.projectWorking._id})).then(e=>e)}generateObjectId(){return(Math.floor(Date.now()/1e3).toString(16)+"xxxxxxxxxxxxxxxx".replace(/[x]/g,()=>(16*Math.random()|0).toString(16))).slice(0,24)}static"ɵfac"=i.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"20.3.15",ngImport:i,type:P,deps:[{token:e.HttpClient},{token:w}],target:i.ɵɵFactoryTarget.Injectable});static"ɵprov"=i.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"20.3.15",ngImport:i,type:P,providedIn:"root"})}i.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"20.3.15",ngImport:i,type:P,decorators:[{type:r,args:[{providedIn:"root"}]}],ctorParameters:()=>[{type:e.HttpClient},{type:w}]});class S{webBuilderService;el;renderer;mode="absolute";boundaryEle;parent;data;device;top=0;left=0;type="preview";dragOffset={x:0,y:0};idParent="";direction="";initData={top:0,left:0,bottom:0,right:0};currPos={x:0,y:0};changed=!1;parentEleRect;parentData;keyPosition="";isDragging=!1;mouseMoveListener=null;mouseUpListener=null;constructor(e,t,i){this.webBuilderService=e,this.el=t,this.renderer=i}ngOnInit(){this.idParent=this.data.id_page||this.data.id_block||this.data.id_object,this.parentEleRect=this.boundaryEle?.getBoundingClientRect(),this.keyPosition=this.data[this.device+"_position_"+this.idParent]?this.device+"_position_"+this.idParent:this.device+"_position",this.updateUIPosition()}ngAfterViewInit(){this.updateInitBottomAndRight()}ngOnChanges(e){(e.top||e.left)&&this.updateUIPosition()}updateUIPosition(){const e=this.data.id_page||this.data.id_block||this.data.id_object,t=this.data[this.device+"_position_"+e]?`${this.device}_position_${e}`:`${this.device}_position`,{left:i,top:n,z_index:o}=this.data[t];"absolute"!==this.data[this.device+"_config"].drag_mode&&this.data[this.device+"_config"].drag_mode?(this.renderer.setStyle(this.el.nativeElement,"position","relative"),this.renderer.setStyle(this.el.nativeElement,"left","0"),this.renderer.setStyle(this.el.nativeElement,"top","0"),this.renderer.setStyle(this.el.nativeElement,"margin-left",`${i}px`),this.renderer.setStyle(this.el.nativeElement,"margin-top",`${n}px`),this.renderer.setStyle(this.el.nativeElement,"z-index",`${o}`)):(this.renderer.setStyle(this.el.nativeElement,"position","absolute"),this.renderer.setStyle(this.el.nativeElement,"left",`${i}px`),this.renderer.setStyle(this.el.nativeElement,"top",`${n}px`),this.renderer.setStyle(this.el.nativeElement,"margin-left","0"),this.renderer.setStyle(this.el.nativeElement,"margin-top","0"),this.renderer.setStyle(this.el.nativeElement,"z-index",`${o}`))}updateInitBottomAndRight(){const e=this.data[this.device+"_position_"+this.idParent]?this.device+"_position_"+this.idParent:this.device+"_position";this.data.type.includes("block")&&["block_blank","block_header","block_footer"].includes(this.data.type)?this.initData={top:0,left:0,bottom:+window.getComputedStyle(this.el.nativeElement).marginTop.replace("px","")+this.el.nativeElement.offsetHeight||0,right:this.el.nativeElement.offsetLeft+this.el.nativeElement.offsetWidth||0}:this.initData={top:this.data[e]?.top,left:this.data[e]?.left,bottom:this.data[e]?.top+this.el.nativeElement.offsetHeight||0,right:this.data[e]?.left+this.el.nativeElement.offsetWidth||0}}onPointerDown(e){if("design"==this.type&&(e.stopPropagation(),this.webBuilderService.isShiftPressed?this.handleChooseItems():this.handleChooseItem(),!["block_blank","block_header","block_footer"].includes(this.data.type)&&!this.data.is_child)){this.isDragging=!0;const{zoom:t}=this.webBuilderService;this.dragOffset.x=e.clientX/t,this.dragOffset.y=e.clientY/t,this.initData.left=this.data[this.keyPosition].left,this.initData.top=this.data[this.keyPosition].top,this.mouseMoveListener=this.renderer.listen("document","mousemove",e=>this.onMouseMove(e)),this.mouseUpListener=this.renderer.listen("document","mouseup",()=>this.onMouseUp())}}onMouseMove(e){if(!this.isDragging)return;const{zoom:t}=this.webBuilderService,i=e.clientX/t-this.dragOffset.x,n=e.clientY/t-this.dragOffset.y,o=Math.max(0,Math.min(Math.round(this.initData.left+i),this.boundaryEle.offsetWidth-this.el.nativeElement.offsetWidth)),r=Math.max(0,Math.min(Math.round(this.initData.top+n),this.boundaryEle.offsetHeight-this.el.nativeElement.offsetHeight));this.data[this.keyPosition].left==o&&this.data[this.keyPosition].top==r||(this.changed=!0),this.data[this.keyPosition].left=o,this.data[this.keyPosition].top=r}onMouseUp(){this.cleanupListeners(),this.isDragging=!1,this.updateInitBottomAndRight(),this.updatePosition()}ngOnDestroy(){this.cleanupListeners()}cleanupListeners(){this.mouseMoveListener&&(this.mouseMoveListener(),this.mouseMoveListener=null),this.mouseUpListener&&(this.mouseUpListener(),this.mouseUpListener=null)}handleChooseItems(){const{device:e}=this.webBuilderService;if((this.webBuilderService.arrayChoosing[0]?.id_page||this.webBuilderService.arrayChoosing[0].id_block||this.webBuilderService.arrayChoosing[0].id_object)!=(this.data.id_page||this.data.id_block||this.data.id_object))return;this.webBuilderService.itemChoosing=null,this.webBuilderService.arrayChoosing.find(e=>e._id==this.data._id)?this.webBuilderService.arrayChoosing=this.webBuilderService.arrayChoosing.filter(e=>e._id!=this.data._id):this.webBuilderService.arrayChoosing=[...this.webBuilderService.arrayChoosing,this.data];let t=Math.min(...this.webBuilderService.arrayChoosing.map(e=>e[this.device+"_position_"+(e.id_page||e.id_block||e.id_object)].left)),i=Math.min(...this.webBuilderService.arrayChoosing.map(e=>e[this.device+"_position_"+(e.id_page||e.id_block||e.id_object)].top??0)),n=Math.max(...this.webBuilderService.arrayChoosing.map(e=>e[this.device+"_position_"+(e.id_page||e.id_block||e.id_object)].left+ +e[this.device+"_class"][e.resize_field][this.webBuilderService.resizeGroup[e.resize_group].width].replace("px",""))),o=Math.max(...this.webBuilderService.arrayChoosing.map(e=>e[this.device+"_position_"+(e.id_page||e.id_block||e.id_object)].top+ +e[this.device+"_class"][e.resize_field][this.webBuilderService.resizeGroup[e.resize_group].height].replace("px","")));if(this.webBuilderService.arrayChoosing[0]?.type.includes("block")){t=0;const r=this.webBuilderService.arrayChoosing.reduce((t,i)=>Math.min(t,i[e+"_position_"+i.id_page].index),999999),s=this.webBuilderService.arrayChoosing.findIndex(t=>t[e+"_position_"+t.id_page].index==r),a=document.querySelector(`[id="${this.webBuilderService.arrayChoosing[s]._id}_root"]`);i=a.offsetTop,n=a.offsetWidth;const l=this.webBuilderService.arrayChoosing.reduce((t,i)=>Math.max(t,i[e+"_position_"+i.id_page].index),0),d=this.webBuilderService.arrayChoosing.findIndex(t=>t[e+"_position_"+t.id_page].index==l),c=this.webBuilderService.arrayChoosing[d];o=document.querySelector(`[id="${c._id}_root"]`).offsetTop+ +c[this.device+"_class"][c.resize_field][this.webBuilderService.resizeGroup[c.resize_group].height].replace("px","")}this.webBuilderService.infoVirtualSelected.left=t,this.webBuilderService.infoVirtualSelected.top=i,this.webBuilderService.infoVirtualSelected.width=n-t,this.webBuilderService.infoVirtualSelected.height=o-i}handleChooseItem(){this.webBuilderService.setItemChoosing(this.data,this.el.nativeElement,this.parent)}getLeftDrag(){return this.el.nativeElement.offsetLeft>24?-24:0}handleResizePointerDown(e,t){e.stopPropagation(),e.preventDefault(),this.direction=t,e.target.setPointerCapture(e.pointerId),this.currPos.x=this.el.nativeElement.getBoundingClientRect().left,this.currPos.y=this.el.nativeElement.getBoundingClientRect().top}handleResizePointerMove(e){"top"==this.direction&&(this.changed=!0,this.onResizeTop(e)),"bottom"==this.direction&&(this.changed=!0,this.onResizeBottom(e)),"left"==this.direction&&(this.changed=!0,this.onResizeLeft(e)),"right"==this.direction&&(this.changed=!0,this.onResizeRight(e)),"top-left"==this.direction&&(this.changed=!0,this.onResizeTop(e),this.onResizeLeft(e)),"top-right"==this.direction&&(this.changed=!0,this.onResizeTop(e),this.onResizeRight(e)),"bottom-left"==this.direction&&(this.changed=!0,this.onResizeBottom(e),this.onResizeLeft(e)),"bottom-right"==this.direction&&(this.changed=!0,this.onResizeBottom(e),this.onResizeRight(e))}handleResizePointerUp(e){e.target.releasePointerCapture(e.pointerId);const t=this.direction;if(this.direction="",this.changed){if(this.changed=!1,this.data.type.includes("block"))["block_blank"].includes(this.data.type)?(this.webBuilderService.currentPage.blocks.forEach((e,t)=>{e[this.keyPosition].top=0}),this.webBuilderService.updateHeightDesign()):["block_header","block_footer"].includes(this.data.type)&&(this.data[this.device+"_position"].top=0);else if(this.data.is_clone){let e=this.webBuilderService.objects.find(e=>e._id==this.data._id);e[this.keyPosition].top=this.data[this.keyPosition].top,e[this.keyPosition].left=this.data[this.keyPosition].left,e[this.keyPosition].z_index=this.data[this.keyPosition].z_index}["right","bottom","bottom-right"].includes(t)&&this.updateClass(),["top","left","top-left","top-right","bottom-left"].includes(t)&&this.updatePositionAndClass(),["top","left","top-left","top-right","bottom-left"].includes(t)&&this.data.objects?.length>0&&this.data.objects.forEach(e=>{this.webBuilderService.updateObject(e._id,{[this.device+"_position_"+this.data._id]:e[this.device+"_position_"+this.data._id]})}),this.updateInitBottomAndRight(),this.minTop=null,this.minLeft=null}}minTop=null;onResizeTop(e){this.currPos.y=this.el.nativeElement.getBoundingClientRect().top;let t=Math.round(e.clientY-this.currPos.y);this.currPos.y=e.clientY;let i=this.data[this.keyPosition].top+t;i=["block_blank","block_header","block_footer"].includes(this.data.type)?Math.min(i,this.initData.bottom):Math.max(0,Math.min(i,this.initData.bottom));let n=this.initData.bottom-i;if(this.data.objects.filter(e=>!e[this.device+"_hidden"])?.length>0&&!["frame_tab","frame_banner"].includes(this.data.type)){null==this.minTop&&(this.minTop=this.data.objects.filter(e=>!e[this.device+"_hidden"]).reduce((e,t)=>Math.min(e,t[`${this.device}_position_${this.data._id}`].top),99999)),i=Math.min(i,this.initData.top+this.minTop),n=this.initData.bottom-i;let e=i-this.data[this.keyPosition].top;this.data.objects.filter(e=>!e[this.device+"_hidden"]).forEach(t=>{t[`${this.device}_position_${this.data._id}`].top-=e})}this.data[this.device+"_class"][this.data.resize_field][this.webBuilderService.resizeGroup[this.data.resize_group].height]=n+"px",this.data[this.keyPosition].top=i}onResizeBottom(e){const t=this.el.nativeElement.getBoundingClientRect(),{zoom:i}=this.webBuilderService;let n=Math.max(0,Math.round((e.clientY-t.top)/i));if(this.data.type.includes("frame")||this.data.type.includes("object")){let o=this.boundaryEle.offsetHeight-this.data[this.keyPosition].top;n=Math.max(0,Math.min(Math.round((e.clientY-t.top)/i),o))}if(this.data.objects?.length>0&&!["frame_tab","frame_banner"].includes(this.data.type)){const e=this.data.objects.filter(e=>!e[this.device+"_hidden"]).reduce((e,t)=>{const i=t[`${this.device}_position_${this.data._id}`].top+ +t[this.device+"_class"][t.resize_field][this.webBuilderService.resizeGroup[t.resize_group].height].replace("px","");return Math.max(e,i)},0);n=Math.max(e,n)}this.data[this.device+"_class"][this.data.resize_field][this.webBuilderService.resizeGroup[this.data.resize_group].height]=n+"px"}minLeft=null;onResizeLeft(e){this.currPos.x=this.el.nativeElement.getBoundingClientRect().left;let t=Math.round(e.clientX-this.currPos.x);this.currPos.x=e.clientX;let i=this.data[this.keyPosition].left+t;i=Math.max(0,Math.min(i,this.initData.right));let n=this.initData.right-i;if(this.data.objects?.length>0&&!["frame_tab","frame_banner"].includes(this.data.type)){null==this.minLeft&&(this.minLeft=this.data.objects.filter(e=>!e[this.device+"_hidden"]).reduce((e,t)=>Math.min(e,t[`${this.device}_position_${this.data._id}`].left),99999)),i=Math.max(0,Math.min(i,this.initData.left+this.minLeft)),n=this.initData.right-i;const e=i-this.data[this.keyPosition].left;this.data.objects.filter(e=>!e[this.device+"_hidden"]).forEach(t=>{t[`${this.device}_position_${this.data._id}`].left-=e})}this.data[this.device+"_class"][this.data.resize_field][this.webBuilderService.resizeGroup[this.data.resize_group].width]=n+"px",this.data[this.keyPosition].left=i}onResizeRight(e){const{zoom:t}=this.webBuilderService,i=this.idParent?"position_"+this.idParent:"position",n=this.el.nativeElement.getBoundingClientRect();this.parentEleRect=this.boundaryEle.getBoundingClientRect();let o=this.parentEleRect.width/t-this.data[this.device+"_"+i].left,r=Math.max(0,Math.min(Math.round(e.clientX-n.left)/t,o));if(this.data.objects?.length>0&&!["frame_tab","frame_banner"].includes(this.data.type)){const e=this.data.objects.filter(e=>!e[this.device+"_hidden"]).reduce((e,t)=>{const i=t[`${this.device}_position_${this.data._id}`].left+ +t[this.device+"_class"][t.resize_field][this.webBuilderService.resizeGroup[t.resize_group].width].replace("px","");return Math.max(e,i)},0);r=Math.max(e,r)}this.data[this.device+"_class"][this.data.resize_field][this.webBuilderService.resizeGroup[this.data.resize_group].width]=r+"px"}updatePosition(){"design"==this.type&&this.changed&&(this.changed=!1,this.data.type.includes("block")?this.webBuilderService.updateBlock(this.data._id,{[this.keyPosition]:this.data[this.keyPosition]}):this.webBuilderService.updateObject(this.data._id,{[this.keyPosition]:this.data[this.keyPosition]}))}updateClass(){"design"==this.type&&(this.data.type.includes("block")?this.webBuilderService.updateBlock(this.data._id,{[this.device+"_class"]:this.data[this.device+"_class"]}):this.webBuilderService.updateObject(this.data._id,{[this.device+"_class"]:this.data[this.device+"_class"]}))}updatePositionAndClass(){"design"==this.type&&(this.data.type.includes("block")?this.webBuilderService.updateBlock(this.data._id,{[this.keyPosition]:this.data[this.keyPosition],[this.device+"_class"]:this.data[this.device+"_class"]}):this.webBuilderService.updateObject(this.data._id,{[this.keyPosition]:this.data[this.keyPosition],[this.device+"_class"]:this.data[this.device+"_class"]}))}conditionShowActive(){const{itemChoosing:e,arrayChoosing:t,elementChoosingRef:i}=this.webBuilderService;return e&&!e.is_child&&e._id==this.data._id&&i==this.el.nativeElement||t?.some(e=>e._id==this.data._id)}conditionShowResize(){const{itemChoosing:e,arrayChoosing:t,elementChoosingRef:i}=this.webBuilderService;return e&&!e.is_clone&&!e.is_child&&e._id==this.data._id&&i==this.el.nativeElement||t.length>1&&t?.some(e=>e._id==this.data._id)}static"ɵfac"=i.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"20.3.15",ngImport:i,type:S,deps:[{token:P},{token:i.ElementRef},{token:i.Renderer2}],target:i.ɵɵFactoryTarget.Component});static"ɵcmp"=i.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"20.3.15",type:S,isStandalone:!0,selector:"[wbdragdrop]",inputs:{mode:"mode",boundaryEle:"boundaryEle",parent:"parent",data:"data",device:"device",top:"top",left:"left",type:"type"},host:{listeners:{pointerdown:"onPointerDown($event)"}},usesOnChanges:!0,ngImport:i,template:'<ng-content></ng-content>\r\n\r\n\x3c!-- Lá cờ nắm kéo --\x3e\r\n@if (type == \'design\' && [\'frame_banner\'].includes(data.type)) {\r\n <div\r\n id="flag-drag"\r\n class="move relative"\r\n [ngStyle]="{ left: getLeftDrag() + \'px\' }"\r\n (pointerdown)="onPointerDown($event)"\r\n >\r\n <svg\r\n xmlns="http://www.w3.org/2000/svg"\r\n width="16"\r\n height="16"\r\n fill="currentColor"\r\n class="bi bi-arrows-move"\r\n viewBox="0 0 16 16"\r\n style="color: #fff"\r\n >\r\n <path\r\n fill-rule="evenodd"\r\n d="M7.646.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 1.707V5.5a.5.5 0 0 1-1 0V1.707L6.354 2.854a.5.5 0 1 1-.708-.708zM8 10a.5.5 0 0 1 .5.5v3.793l1.146-1.147a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 0 1 .708-.708L7.5 14.293V10.5A.5.5 0 0 1 8 10M.146 8.354a.5.5 0 0 1 0-.708l2-2a.5.5 0 1 1 .708.708L1.707 7.5H5.5a.5.5 0 0 1 0 1H1.707l1.147 1.146a.5.5 0 0 1-.708.708zM10 8a.5.5 0 0 1 .5-.5h3.793l-1.147-1.146a.5.5 0 0 1 .708-.708l2 2a.5.5 0 0 1 0 .708l-2 2a.5.5 0 0 1-.708-.708L14.293 8.5H10.5A.5.5 0 0 1 10 8"\r\n />\r\n </svg>\r\n\r\n <div class="absolute w-full h-full left-0 top-0" style="z-index: 9999"></div>\r\n </div>\r\n}\r\n\r\n\x3c!-- @if (conditionShowActive()) {\r\n <div class="border-active"></div>\r\n} --\x3e\r\n\r\n@if (conditionShowResize()) {\r\n @if ([\'block_blank\', \'block_header\', \'block_footer\'].includes(data.type)) {\r\n <div\r\n id="resize-top-block-blank"\r\n [ngStyle]="{ left: \'50%\', top: 0, transform: \'translateX(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'top\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-bottom-block-blank"\r\n [ngStyle]="{ left: \'50%\', bottom: 0, transform: \'translateX(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'bottom\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n } @else if ([\'object_line\'].includes(data.type)) {\r\n @if (data[device + \'_config\'][\'direction\'] == \'vertical\') {\r\n <div\r\n id="resize-top"\r\n class="resize resize-t"\r\n [ngStyle]="{ left: \'50%\', top: 0, transform: \'translateX(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'top\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-bottom"\r\n class="resize resize-b"\r\n [ngStyle]="{ left: \'50%\', bottom: 0, transform: \'translateX(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'bottom\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n } @else {\r\n <div\r\n id="resize-left"\r\n class="resize resize-ew"\r\n [ngStyle]="{ left: 0, top: \'50%\', transform: \'translateY(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'left\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-right"\r\n class="resize resize-ew"\r\n [ngStyle]="{ right: 0, top: \'50%\', transform: \'translateY(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'right\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n }\r\n } @else if ([\'WbText\'].includes(data.component)) {\r\n <div\r\n id="resize-left"\r\n class="resize resize-ew"\r\n [ngStyle]="{ left: 0, top: \'50%\', transform: \'translateY(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'left\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-right"\r\n class="resize resize-ew"\r\n [ngStyle]="{ right: 0, top: \'50%\', transform: \'translateY(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'right\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n } @else {\r\n <div\r\n id="resize-left"\r\n class="resize resize-ew"\r\n [ngStyle]="{ left: 0, top: \'50%\', transform: \'translateY(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'left\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-right"\r\n class="resize resize-ew"\r\n [ngStyle]="{ right: 0, top: \'50%\', transform: \'translateY(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'right\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-top"\r\n class="resize resize-t"\r\n [ngStyle]="{ left: \'50%\', top: 0, transform: \'translateX(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'top\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-bottom"\r\n class="resize resize-b"\r\n [ngStyle]="{ left: \'50%\', bottom: 0, transform: \'translateX(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'bottom\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-top-left"\r\n class="resize resize-tl"\r\n [ngStyle]="{ left: 0, top: 0 }"\r\n (pointerdown)="handleResizePointerDown($event, \'top-left\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-top-right"\r\n class="resize resize-tr"\r\n [ngStyle]="{ right: 0, top: 0 }"\r\n (pointerdown)="handleResizePointerDown($event, \'top-right\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-bottom-left"\r\n class="resize resize-bl"\r\n [ngStyle]="{ left: 0, bottom: 0 }"\r\n (pointerdown)="handleResizePointerDown($event, \'bottom-left\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-bottom-right"\r\n class="resize resize-br"\r\n [ngStyle]="{ right: 0, bottom: 0 }"\r\n (pointerdown)="handleResizePointerDown($event, \'bottom-right\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n }\r\n}\r\n\x3c!-- is_child là con của các frame đặc biệt như frame-tab, collapse, banner --\x3e\r\n@if (\r\n !webBuilderService.itemChoosing?.type.includes(\'block\') &&\r\n webBuilderService.itemChoosing?._id == data._id &&\r\n webBuilderService.elementChoosingRef == el.nativeElement &&\r\n !data.is_child\r\n) {\r\n @if (data[keyPosition].top < 150) {\r\n <div\r\n class="ruler-line ruler-top"\r\n [ngStyle]="{\r\n height: data[keyPosition].top + \'px\',\r\n top: -data[keyPosition].top + \'px\'\r\n }"\r\n >\r\n @if (data[keyPosition].top > 8) {\r\n <span class="text-[14px] absolute top-1/2 -translate-1/2">\r\n {{ data[keyPosition].top }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n @if (data[keyPosition].left < 150) {\r\n <div\r\n class="ruler-line ruler-left"\r\n [ngStyle]="{\r\n width: data[keyPosition].left + \'px\',\r\n left: -data[keyPosition].left + \'px\'\r\n }"\r\n >\r\n @if (data[keyPosition].left > 8) {\r\n <span class="text-[14px] absolute left-1/2 -translate-1/2">\r\n {{ data[keyPosition].left }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n @if (boundaryEle.offsetHeight - (data[keyPosition].top + el.nativeElement?.offsetHeight) < 150) {\r\n <div\r\n class="ruler-line ruler-bottom"\r\n [ngStyle]="{\r\n height:\r\n boundaryEle.offsetHeight -\r\n (data[keyPosition].top + el.nativeElement?.offsetHeight) +\r\n \'px\',\r\n bottom:\r\n -(boundaryEle.offsetHeight - (data[keyPosition].top + el.nativeElement?.offsetHeight)) +\r\n \'px\'\r\n }"\r\n >\r\n @if (\r\n boundaryEle.offsetHeight - (data[keyPosition].top + el.nativeElement?.offsetHeight) > 8\r\n ) {\r\n <span class="text-[14px] absolute top-1/2 -translate-1/2">\r\n {{ boundaryEle.offsetHeight - (data[keyPosition].top + el.nativeElement?.offsetHeight) }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n @if (boundaryEle.offsetWidth - (data[keyPosition].left + el.nativeElement?.offsetWidth) < 150) {\r\n <div\r\n class="ruler-line ruler-right"\r\n [ngStyle]="{\r\n width:\r\n boundaryEle.offsetWidth - (data[keyPosition].left + el.nativeElement?.offsetWidth) + \'px\',\r\n right:\r\n -(boundaryEle.offsetWidth - (data[keyPosition].left + el.nativeElement?.offsetWidth)) +\r\n \'px\'\r\n }"\r\n >\r\n @if (boundaryEle.offsetWidth - (data[keyPosition].left + el.nativeElement?.offsetWidth) > 8) {\r\n <span class="text-[14px] absolute right-1/2 -translate-y-1/2 translate-x-1/2">\r\n {{ boundaryEle.offsetWidth - (data[keyPosition].left + el.nativeElement?.offsetWidth) }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n}\r\n',styles:[".move{position:absolute;width:1.5rem;height:1.5rem;display:flex;align-items:center;justify-content:center;cursor:move;top:0;z-index:1000;background-color:#4399fa}.border-active{position:absolute;inset:0;border:1px solid #4399fa;pointer-events:none}.resize{z-index:9999;position:absolute;select-event:none;background-color:#3b82f6;width:.5rem;height:.5rem}.resize-ew{cursor:ew-resize}.resize-tl{cursor:nw-resize}.resize-tr{cursor:ne-resize}.resize-bl{cursor:sw-resize}.resize-br{cursor:se-resize}.resize-t,.resize-b{cursor:n-resize}#resize-top-block-blank{z-index:9999;position:absolute;select-event:none;background-color:#3b82f6;width:.5rem;height:.5rem;width:7rem;height:.75rem;border-radius:0 0 1rem 1rem;cursor:n-resize;border:2px solid #3b82f6;background-color:#fff}#resize-top-block-blank:hover{background-color:#3b82f6}#resize-bottom-block-blank{z-index:9999;position:absolute;select-event:none;background-color:#3b82f6;width:.5rem;height:.5rem;width:7rem;height:.75rem;border-radius:1rem 1rem 0 0;cursor:s-resize;border:2px solid #3b82f6;background-color:#fff}#resize-bottom-block-blank:hover{background-color:#3b82f6}.ruler-line{position:absolute;background-color:#ef4444;font-size:14px}.ruler-line.ruler-top,.ruler-line.ruler-bottom{width:.1px;left:50%;transform:translate(-50%)}.ruler-line.ruler-top span,.ruler-line.ruler-bottom span{top:50%}.ruler-line.ruler-left,.ruler-line.ruler-right{height:.1px;top:50%;transform:translateY(-50%)}.ruler-line.ruler-left span,.ruler-line.ruler-right span{left:50%}.ruler-line span{position:absolute;transform:translate(-50%,-50%)}\n"],dependencies:[{kind:"ngmodule",type:u},{kind:"directive",type:b.NgStyle,selector:"[ngStyle]",inputs:["ngStyle"]}]})}i.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"20.3.15",ngImport:i,type:S,decorators:[{type:l,args:[{selector:"[wbdragdrop]",imports:[u],template:'<ng-content></ng-content>\r\n\r\n\x3c!-- Lá cờ nắm kéo --\x3e\r\n@if (type == \'design\' && [\'frame_banner\'].includes(data.type)) {\r\n <div\r\n id="flag-drag"\r\n class="move relative"\r\n [ngStyle]="{ left: getLeftDrag() + \'px\' }"\r\n (pointerdown)="onPointerDown($event)"\r\n >\r\n <svg\r\n xmlns="http://www.w3.org/2000/svg"\r\n width="16"\r\n height="16"\r\n fill="currentColor"\r\n class="bi bi-arrows-move"\r\n viewBox="0 0 16 16"\r\n style="color: #fff"\r\n >\r\n <path\r\n fill-rule="evenodd"\r\n d="M7.646.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 1.707V5.5a.5.5 0 0 1-1 0V1.707L6.354 2.854a.5.5 0 1 1-.708-.708zM8 10a.5.5 0 0 1 .5.5v3.793l1.146-1.147a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 0 1 .708-.708L7.5 14.293V10.5A.5.5 0 0 1 8 10M.146 8.354a.5.5 0 0 1 0-.708l2-2a.5.5 0 1 1 .708.708L1.707 7.5H5.5a.5.5 0 0 1 0 1H1.707l1.147 1.146a.5.5 0 0 1-.708.708zM10 8a.5.5 0 0 1 .5-.5h3.793l-1.147-1.146a.5.5 0 0 1 .708-.708l2 2a.5.5 0 0 1 0 .708l-2 2a.5.5 0 0 1-.708-.708L14.293 8.5H10.5A.5.5 0 0 1 10 8"\r\n />\r\n </svg>\r\n\r\n <div class="absolute w-full h-full left-0 top-0" style="z-index: 9999"></div>\r\n </div>\r\n}\r\n\r\n\x3c!-- @if (conditionShowActive()) {\r\n <div class="border-active"></div>\r\n} --\x3e\r\n\r\n@if (conditionShowResize()) {\r\n @if ([\'block_blank\', \'block_header\', \'block_footer\'].includes(data.type)) {\r\n <div\r\n id="resize-top-block-blank"\r\n [ngStyle]="{ left: \'50%\', top: 0, transform: \'translateX(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'top\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-bottom-block-blank"\r\n [ngStyle]="{ left: \'50%\', bottom: 0, transform: \'translateX(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'bottom\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n } @else if ([\'object_line\'].includes(data.type)) {\r\n @if (data[device + \'_config\'][\'direction\'] == \'vertical\') {\r\n <div\r\n id="resize-top"\r\n class="resize resize-t"\r\n [ngStyle]="{ left: \'50%\', top: 0, transform: \'translateX(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'top\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-bottom"\r\n class="resize resize-b"\r\n [ngStyle]="{ left: \'50%\', bottom: 0, transform: \'translateX(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'bottom\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n } @else {\r\n <div\r\n id="resize-left"\r\n class="resize resize-ew"\r\n [ngStyle]="{ left: 0, top: \'50%\', transform: \'translateY(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'left\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-right"\r\n class="resize resize-ew"\r\n [ngStyle]="{ right: 0, top: \'50%\', transform: \'translateY(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'right\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n }\r\n } @else if ([\'WbText\'].includes(data.component)) {\r\n <div\r\n id="resize-left"\r\n class="resize resize-ew"\r\n [ngStyle]="{ left: 0, top: \'50%\', transform: \'translateY(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'left\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-right"\r\n class="resize resize-ew"\r\n [ngStyle]="{ right: 0, top: \'50%\', transform: \'translateY(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'right\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n } @else {\r\n <div\r\n id="resize-left"\r\n class="resize resize-ew"\r\n [ngStyle]="{ left: 0, top: \'50%\', transform: \'translateY(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'left\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-right"\r\n class="resize resize-ew"\r\n [ngStyle]="{ right: 0, top: \'50%\', transform: \'translateY(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'right\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-top"\r\n class="resize resize-t"\r\n [ngStyle]="{ left: \'50%\', top: 0, transform: \'translateX(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'top\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-bottom"\r\n class="resize resize-b"\r\n [ngStyle]="{ left: \'50%\', bottom: 0, transform: \'translateX(-50%)\' }"\r\n (pointerdown)="handleResizePointerDown($event, \'bottom\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-top-left"\r\n class="resize resize-tl"\r\n [ngStyle]="{ left: 0, top: 0 }"\r\n (pointerdown)="handleResizePointerDown($event, \'top-left\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-top-right"\r\n class="resize resize-tr"\r\n [ngStyle]="{ right: 0, top: 0 }"\r\n (pointerdown)="handleResizePointerDown($event, \'top-right\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-bottom-left"\r\n class="resize resize-bl"\r\n [ngStyle]="{ left: 0, bottom: 0 }"\r\n (pointerdown)="handleResizePointerDown($event, \'bottom-left\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n\r\n <div\r\n id="resize-bottom-right"\r\n class="resize resize-br"\r\n [ngStyle]="{ right: 0, bottom: 0 }"\r\n (pointerdown)="handleResizePointerDown($event, \'bottom-right\')"\r\n (pointermove)="handleResizePointerMove($event)"\r\n (pointerup)="handleResizePointerUp($event)"\r\n ></div>\r\n }\r\n}\r\n\x3c!-- is_child là con của các frame đặc biệt như frame-tab, collapse, banner --\x3e\r\n@if (\r\n !webBuilderService.itemChoosing?.type.includes(\'block\') &&\r\n webBuilderService.itemChoosing?._id == data._id &&\r\n webBuilderService.elementChoosingRef == el.nativeElement &&\r\n !data.is_child\r\n) {\r\n @if (data[keyPosition].top < 150) {\r\n <div\r\n class="ruler-line ruler-top"\r\n [ngStyle]="{\r\n height: data[keyPosition].top + \'px\',\r\n top: -data[keyPosition].top + \'px\'\r\n }"\r\n >\r\n @if (data[keyPosition].top > 8) {\r\n <span class="text-[14px] absolute top-1/2 -translate-1/2">\r\n {{ data[keyPosition].top }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n @if (data[keyPosition].left < 150) {\r\n <div\r\n class="ruler-line ruler-left"\r\n [ngStyle]="{\r\n width: data[keyPosition].left + \'px\',\r\n left: -data[keyPosition].left + \'px\'\r\n }"\r\n >\r\n @if (data[keyPosition].left > 8) {\r\n <span class="text-[14px] absolute left-1/2 -translate-1/2">\r\n {{ data[keyPosition].left }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n @if (boundaryEle.offsetHeight - (data[keyPosition].top + el.nativeElement?.offsetHeight) < 150) {\r\n <div\r\n class="ruler-line ruler-bottom"\r\n [ngStyle]="{\r\n height:\r\n boundaryEle.offsetHeight -\r\n (data[keyPosition].top + el.nativeElement?.offsetHeight) +\r\n \'px\',\r\n bottom:\r\n -(boundaryEle.offsetHeight - (data[keyPosition].top + el.nativeElement?.offsetHeight)) +\r\n \'px\'\r\n }"\r\n >\r\n @if (\r\n boundaryEle.offsetHeight - (data[keyPosition].top + el.nativeElement?.offsetHeight) > 8\r\n ) {\r\n <span class="text-[14px] absolute top-1/2 -translate-1/2">\r\n {{ boundaryEle.offsetHeight - (data[keyPosition].top + el.nativeElement?.offsetHeight) }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n @if (boundaryEle.offsetWidth - (data[keyPosition].left + el.nativeElement?.offsetWidth) < 150) {\r\n <div\r\n class="ruler-line ruler-right"\r\n [ngStyle]="{\r\n width:\r\n boundaryEle.offsetWidth - (data[keyPosition].left + el.nativeElement?.offsetWidth) + \'px\',\r\n right:\r\n -(boundaryEle.offsetWidth - (data[keyPosition].left + el.nativeElement?.offsetWidth)) +\r\n \'px\'\r\n }"\r\n >\r\n @if (boundaryEle.offsetWidth - (data[keyPosition].left + el.nativeElement?.offsetWidth) > 8) {\r\n <span class="text-[14px] absolute right-1/2 -translate-y-1/2 translate-x-1/2">\r\n {{ boundaryEle.offsetWidth - (data[keyPosition].left + el.nativeElement?.offsetWidth) }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n}\r\n',styles:[".move{position:absolute;width:1.5rem;height:1.5rem;display:flex;align-items:center;justify-content:center;cursor:move;top:0;z-index:1000;background-color:#4399fa}.border-active{position:absolute;inset:0;border:1px solid #4399fa;pointer-events:none}.resize{z-index:9999;position:absolute;select-event:none;background-color:#3b82f6;width:.5rem;height:.5rem}.resize-ew{cursor:ew-resize}.resize-tl{cursor:nw-resize}.resize-tr{cursor:ne-resize}.resize-bl{cursor:sw-resize}.resize-br{cursor:se-resize}.resize-t,.resize-b{cursor:n-resize}#resize-top-block-blank{z-index:9999;position:absolute;select-event:none;background-color:#3b82f6;width:.5rem;height:.5rem;width:7rem;height:.75rem;border-radius:0 0 1rem 1rem;cursor:n-resize;border:2px solid #3b82f6;background-color:#fff}#resize-top-block-blank:hover{background-color:#3b82f6}#resize-bottom-block-blank{z-index:9999;position:absolute;select-event:none;background-color:#3b82f6;width:.5rem;height:.5rem;width:7rem;height:.75rem;border-radius:1rem 1rem 0 0;cursor:s-resize;border:2px solid #3b82f6;background-color:#fff}#resize-bottom-block-blank:hover{background-color:#3b82f6}.ruler-line{position:absolute;background-color:#ef4444;font-size:14px}.ruler-line.ruler-top,.ruler-line.ruler-bottom{width:.1px;left:50%;transform:translate(-50%)}.ruler-line.ruler-top span,.ruler-line.ruler-bottom span{top:50%}.ruler-line.ruler-left,.ruler-line.ruler-right{height:.1px;top:50%;transform:translateY(-50%)}.ruler-line.ruler-left span,.ruler-line.ruler-right span{left:50%}.ruler-line span{position:absolute;transform:translate(-50%,-50%)}\n"]}]}],ctorParameters:()=>[{type:P},{type:i.ElementRef},{type:i.Renderer2}],propDecorators:{mode:[{type:a}],boundaryEle:[{type:a}],parent:[{type:a}],data:[{type:a}],device:[{type:a}],top:[{type:a}],left:[{type:a}],type:[{type:a}],onPointerDown:[{type:s,args:["pointerdown",["$event"]]}]}});class z{webBuilderService;el;boundaryEle;isDragging=!1;parentEleRect;dragOffset={x:0,y:0};currPos={x:0,y:0};idParent="";changed=!1;keyPosition;constructor(e,t){this.webBuilderService=e,this.el=t}ngOnInit(){this.idParent=this.webBuilderService.arrayChoosing[0].id_block??this.webBuilderService.arrayChoosing[0].id_object,this.keyPosition=`${this.webBuilderService.device}_position_${this.idParent}`}onHostMouseDown(e){if(e.stopPropagation(),"block_blank"==this.webBuilderService.arrayChoosing[0].type)return;this.el.nativeElement.setPointerCapture(e.pointerId);const{zoom:t,device:i}=this.webBuilderService;this.isDragging=!0,this.dragOffset.x=e.clientX/t,this.dragOffset.y=e.clientY/t,this.currPos.left=this.webBuilderService.infoVirtualSelected.left,this.currPos.top=this.webBuilderService.infoVirtualSelected.top}onPointerMove(e){if(!this.isDragging)return;const{zoom:t}=this.webBuilderService,i=e.clientX/t-this.dragOffset.x,n=e.clientY/t-this.dragOffset.y,o=Math.max(0,Math.min(Math.round(this.currPos.left+i),this.boundaryEle.offsetWidth-this.el.nativeElement.offsetWidth)),r=Math.max(0,Math.min(Math.round(this.currPos.top+n),this.boundaryEle.offsetHeight-this.el.nativeElement.offsetHeight)),s=o-this.webBuilderService.infoVirtualSelected.left,a=r-this.webBuilderService.infoVirtualSelected.top;this.webBuilderService.arrayChoosing.forEach(e=>{e[this.keyPosition].left=Math.round(e[this.keyPosition].left+s),e[this.keyPosition].top=Math.round(e[this.keyPosition].top+a)}),this.webBuilderService.infoVirtualSelected.left=o,this.webBuilderService.infoVirtualSelected.top=r,this.changed=!0}onPointerUp(e){this.isDragging&&(this.isDragging=!1,this.changed&&(this.changed=!1,this.webBuilderService.arrayChoosing.forEach(e=>{this.webBuilderService.updateObject(e._id,{[this.keyPosition]:e[this.keyPosition]})})))}static"ɵfac"=i.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"20.3.15",ngImport:i,type:z,deps:[{token:P},{token:i.ElementRef}],target:i.ɵɵFactoryTarget.Component});static"ɵcmp"=i.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"20.3.15",type:z,isStandalone:!0,selector:"[wbVirtualSelected]",inputs:{boundaryEle:"boundaryEle"},host:{listeners:{pointerdown:"onHostMouseDown($event)",pointermove:"onPointerMove($event)",pointerup:"onPointerUp($event)"}},ngImport:i,template:"@if (webBuilderService.arrayChoosing[0].type != 'block_blank') {\r\n \x3c!-- top --\x3e\r\n @if (webBuilderService.infoVirtualSelected.top < 150) {\r\n <div\r\n class=\"ruler-line ruler-top\"\r\n [ngStyle]=\"{\r\n height: webBuilderService.infoVirtualSelected.top + 'px',\r\n top: -webBuilderService.infoVirtualSelected.top + 'px',\r\n width: '0.1px'\r\n }\"\r\n >\r\n @if (webBuilderService.infoVirtualSelected.top > 8) {\r\n <span class=\"text-[14px] absolute top-1/2 -translate-1/2\">\r\n {{ webBuilderService.infoVirtualSelected.top }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n \x3c!-- left --\x3e\r\n @if (webBuilderService.infoVirtualSelected.left < 150) {\r\n <div\r\n class=\"ruler-line ruler-left\"\r\n [ngStyle]=\"{\r\n width: webBuilderService.infoVirtualSelected.left + 'px',\r\n left: -webBuilderService.infoVirtualSelected.left + 'px',\r\n height: '0.1px'\r\n }\"\r\n >\r\n @if (webBuilderService.infoVirtualSelected.left > 8) {\r\n <span class=\"text-[14px] absolute left-1/2 -translate-1/2\">\r\n {{ webBuilderService.infoVirtualSelected.left }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n \x3c!-- bottom --\x3e\r\n @if (\r\n boundaryEle.offsetHeight -\r\n (webBuilderService.infoVirtualSelected.top + el.nativeElement?.offsetHeight) <\r\n 150\r\n ) {\r\n <div\r\n class=\"ruler-line ruler-bottom\"\r\n [ngStyle]=\"{\r\n height:\r\n boundaryEle.offsetHeight -\r\n (webBuilderService.infoVirtualSelected.top + el.nativeElement?.offsetHeight) +\r\n 'px',\r\n bottom:\r\n -(\r\n boundaryEle.offsetHeight -\r\n (webBuilderService.infoVirtualSelected.top + el.nativeElement?.offsetHeight)\r\n ) + 'px',\r\n width: '0.1px'\r\n }\"\r\n >\r\n @if (\r\n boundaryEle.offsetHeight -\r\n (webBuilderService.infoVirtualSelected.top + el.nativeElement?.offsetHeight) >\r\n 8\r\n ) {\r\n <span class=\"text-[14px] absolute top-1/2 -translate-1/2\">\r\n {{\r\n boundaryEle.offsetHeight -\r\n (webBuilderService.infoVirtualSelected.top + el.nativeElement?.offsetHeight)\r\n }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n \x3c!-- right --\x3e\r\n @if (\r\n boundaryEle.offsetWidth -\r\n (webBuilderService.infoVirtualSelected.left + el.nativeElement?.offsetWidth) <\r\n 150\r\n ) {\r\n <div\r\n class=\"ruler-line ruler-right\"\r\n [ngStyle]=\"{\r\n width:\r\n boundaryEle.offsetWidth -\r\n (webBuilderService.infoVirtualSelected.left + el.nativeElement?.offsetWidth) +\r\n 'px',\r\n right:\r\n -(\r\n boundaryEle.offsetWidth -\r\n (webBuilderService.infoVirtualSelected.left + el.nativeElement?.offsetWidth)\r\n ) + 'px',\r\n height: '0.1px'\r\n }\"\r\n >\r\n @if (\r\n boundaryEle.offsetWidth -\r\n (webBuilderService.infoVirtualSelected.left + el.nativeElement?.offsetWidth) >\r\n 8\r\n ) {\r\n <span class=\"text-[14px] absolute right-1/2 -translate-y-1/2 translate-x-1/2\">\r\n {{\r\n boundaryEle.offsetWidth -\r\n (webBuilderService.infoVirtualSelected.left + el.nativeElement?.offsetWidth)\r\n }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n}\r\n",styles:[".move{position:absolute;width:1.5rem;height:1.5rem;display:flex;align-items:center;justify-content:center;cursor:move;top:0;z-index:1000;background-color:#4399fa}.border-active{position:absolute;inset:0;border:1px solid #4399fa;pointer-events:none}.ruler-line{position:absolute;background-color:#ef4444;font-size:14px}.ruler-line.ruler-top,.ruler-line.ruler-bottom{width:.1px;left:50%;transform:translate(-50%)}.ruler-line.ruler-top span,.ruler-line.ruler-bottom span{top:50%}.ruler-line.ruler-left,.ruler-line.ruler-right{height:.1px;top:50%;transform:translateY(-50%)}.ruler-line.ruler-left span,.ruler-line.ruler-right span{left:50%}.ruler-line span{position:absolute;transform:translate(-50%,-50%)}\n"],dependencies:[{kind:"ngmodule",type:u},{kind:"directive",type:b.NgStyle,selector:"[ngStyle]",inputs:["ngStyle"]}]})}i.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"20.3.15",ngImport:i,type:z,decorators:[{type:l,args:[{selector:"[wbVirtualSelected]",imports:[u],template:"@if (webBuilderService.arrayChoosing[0].type != 'block_blank') {\r\n \x3c!-- top --\x3e\r\n @if (webBuilderService.infoVirtualSelected.top < 150) {\r\n <div\r\n class=\"ruler-line ruler-top\"\r\n [ngStyle]=\"{\r\n height: webBuilderService.infoVirtualSelected.top + 'px',\r\n top: -webBuilderService.infoVirtualSelected.top + 'px',\r\n width: '0.1px'\r\n }\"\r\n >\r\n @if (webBuilderService.infoVirtualSelected.top > 8) {\r\n <span class=\"text-[14px] absolute top-1/2 -translate-1/2\">\r\n {{ webBuilderService.infoVirtualSelected.top }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n \x3c!-- left --\x3e\r\n @if (webBuilderService.infoVirtualSelected.left < 150) {\r\n <div\r\n class=\"ruler-line ruler-left\"\r\n [ngStyle]=\"{\r\n width: webBuilderService.infoVirtualSelected.left + 'px',\r\n left: -webBuilderService.infoVirtualSelected.left + 'px',\r\n height: '0.1px'\r\n }\"\r\n >\r\n @if (webBuilderService.infoVirtualSelected.left > 8) {\r\n <span class=\"text-[14px] absolute left-1/2 -translate-1/2\">\r\n {{ webBuilderService.infoVirtualSelected.left }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n \x3c!-- bottom --\x3e\r\n @if (\r\n boundaryEle.offsetHeight -\r\n (webBuilderService.infoVirtualSelected.top + el.nativeElement?.offsetHeight) <\r\n 150\r\n ) {\r\n <div\r\n class=\"ruler-line ruler-bottom\"\r\n [ngStyle]=\"{\r\n height:\r\n boundaryEle.offsetHeight -\r\n (webBuilderService.infoVirtualSelected.top + el.nativeElement?.offsetHeight) +\r\n 'px',\r\n bottom:\r\n -(\r\n boundaryEle.offsetHeight -\r\n (webBuilderService.infoVirtualSelected.top + el.nativeElement?.offsetHeight)\r\n ) + 'px',\r\n width: '0.1px'\r\n }\"\r\n >\r\n @if (\r\n boundaryEle.offsetHeight -\r\n (webBuilderService.infoVirtualSelected.top + el.nativeElement?.offsetHeight) >\r\n 8\r\n ) {\r\n <span class=\"text-[14px] absolute top-1/2 -translate-1/2\">\r\n {{\r\n boundaryEle.offsetHeight -\r\n (webBuilderService.infoVirtualSelected.top + el.nativeElement?.offsetHeight)\r\n }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n \x3c!-- right --\x3e\r\n @if (\r\n boundaryEle.offsetWidth -\r\n (webBuilderService.infoVirtualSelected.left + el.nativeElement?.offsetWidth) <\r\n 150\r\n ) {\r\n <div\r\n class=\"ruler-line ruler-right\"\r\n [ngStyle]=\"{\r\n width:\r\n boundaryEle.offsetWidth -\r\n (webBuilderService.infoVirtualSelected.left + el.nativeElement?.offsetWidth) +\r\n 'px',\r\n right:\r\n -(\r\n boundaryEle.offsetWidth -\r\n (webBuilderService.infoVirtualSelected.left + el.nativeElement?.offsetWidth)\r\n ) + 'px',\r\n height: '0.1px'\r\n }\"\r\n >\r\n @if (\r\n boundaryEle.offsetWidth -\r\n (webBuilderService.infoVirtualSelected.left + el.nativeElement?.offsetWidth) >\r\n 8\r\n ) {\r\n <span class=\"text-[14px] absolute right-1/2 -translate-y-1/2 translate-x-1/2\">\r\n {{\r\n boundaryEle.offsetWidth -\r\n (webBuilderService.infoVirtualSelected.left + el.nativeElement?.offsetWidth)\r\n }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n}\r\n",styles:[".move{position:absolute;width:1.5rem;height:1.5rem;display:flex;align-items:center;justify-content:center;cursor:move;top:0;z-index:1000;background-color:#4399fa}.border-active{position:absolute;inset:0;border:1px solid #4399fa;pointer-events:none}.ruler-line{position:absolute;background-color:#ef4444;font-size:14px}.ruler-line.ruler-top,.ruler-line.ruler-bottom{width:.1px;left:50%;transform:translate(-50%)}.ruler-line.ruler-top span,.ruler-line.ruler-bottom span{top:50%}.ruler-line.ruler-left,.ruler-line.ruler-right{height:.1px;top:50%;transform:translateY(-50%)}.ruler-line.ruler-left span,.ruler-line.ruler-right span{left:50%}.ruler-line span{position:absolute;transform:translate(-50%,-50%)}\n"]}]}],ctorParameters:()=>[{type:P},{type:i.ElementRef}],propDecorators:{boundaryEle:[{type:a}],onHostMouseDown:[{type:s,args:["pointerdown",["$event"]]}],onPointerMove:[{type:s,args:["pointermove",["$event"]]}],onPointerUp:[{type:s,args:["pointerup",["$event"]]}]}});export{k as WEBBUILDER_API_URL,S as WbDragDrop,z as WbVirtualSelected,P as webBuilderService};
package/index.d.ts ADDED
@@ -0,0 +1,411 @@
1
+ import { HttpClient } from '@angular/common/http';
2
+ import { Subject } from 'rxjs';
3
+ import * as i0 from '@angular/core';
4
+ import { OnInit, ElementRef, Renderer2, SimpleChanges, InjectionToken } from '@angular/core';
5
+
6
+ declare class SocketService {
7
+ private apiUrl;
8
+ private socket;
9
+ connect(): void;
10
+ sendMessage(event: string, data: any): void;
11
+ onMessage(event: string, callback: (data: any) => void): void;
12
+ disconnect(): void;
13
+ static ɵfac: i0.ɵɵFactoryDeclaration<SocketService, never>;
14
+ static ɵprov: i0.ɵɵInjectableDeclaration<SocketService>;
15
+ }
16
+
17
+ declare class webBuilderService {
18
+ private http;
19
+ private socketService;
20
+ private apiUrl;
21
+ private urlBE;
22
+ group: any;
23
+ projectWorking: any;
24
+ /**
25
+ * dữ liệu cha của đối tượng đang chọn
26
+ */
27
+ parentChoosing: any;
28
+ /**
29
+ * đối tượng đang chọn: object hoặc block
30
+ */
31
+ itemChoosing: any;
32
+ /**
33
+ * DOM của itemChoosing
34
+ */
35
+ elementChoosingRef: any;
36
+ /**
37
+ * Biến để theo dõi trạng thái phím Shift
38
+ */
39
+ isShiftPressed: boolean;
40
+ /**
41
+ * Danh sách đối tượng được chọn block | frame | object
42
+ */
43
+ arrayChoosing: any;
44
+ /**
45
+ * trang hiện tại(đầy đủ nhánh)
46
+ */
47
+ currentPage: any;
48
+ /**
49
+ * danh sách trang(ko có nhánh)
50
+ */
51
+ pages: any;
52
+ /**
53
+ * danh sách block blank(ko có nhánh)
54
+ */
55
+ blocks: any;
56
+ /**
57
+ * danh sách object(ko có nhánh)
58
+ */
59
+ objects: any;
60
+ /**
61
+ * danh sách freeblock(có nhánh)
62
+ * */
63
+ freeblocks: any;
64
+ /**
65
+ * chatboxs của trang
66
+ */
67
+ chatboxs: any;
68
+ /**
69
+ * thiết bị hiện tại đang thiết kế
70
+ */
71
+ device: string | 'desktop' | 'tablet_landscape' | 'tablet_portrait' | 'mobile_landscape' | 'mobile_portrait';
72
+ type: string | 'design' | 'preview' | 'admin';
73
+ loading: boolean;
74
+ group_frames: any;
75
+ group_objects: any;
76
+ toolsBox: any;
77
+ toolsBoxPosition: any;
78
+ isFreeBlock: boolean;
79
+ header: any;
80
+ footer: any;
81
+ chatbox: any;
82
+ /**
83
+ *
84
+ * Biến này để chọn freeblock
85
+ */
86
+ blockPicking: any;
87
+ heightMainDesign: number;
88
+ resizeGroup: any;
89
+ /**
90
+ * biến này dùng cho update realtime
91
+ */
92
+ clientId: string;
93
+ infoVirtualSelected: any;
94
+ currentTool: any;
95
+ EventBus: Subject<any>;
96
+ zoom: number;
97
+ /**
98
+ * Biến để kiểm soát việc có cho phép copy hay không
99
+ */
100
+ allowCopy: boolean;
101
+ constructor(http: HttpClient, socketService: SocketService);
102
+ realTimeUpdate(): void;
103
+ closeConnection(): void;
104
+ onNotifyChange(callback: (data: any) => void): any;
105
+ notifyChange(data: any): void;
106
+ /**
107
+ * Tìm đối tượng dù ở currentPage hay freeblocks
108
+ * @param id id của đối tượng cần tìm
109
+ * @returns
110
+ */
111
+ findItemById(id: string): any;
112
+ /**
113
+ * hàm tìm kiếm 1 đối tượng trong tree
114
+ * @param tree khối
115
+ * @returns id
116
+ */
117
+ findItemInTree(tree: any, id: string): any;
118
+ private wrapApiCall;
119
+ addProject(data: any): Promise<any>;
120
+ updateProject(id: string, data: any): Promise<any>;
121
+ deleteProject(id: string): Promise<any>;
122
+ getProjects_byFields(query: any, sort: any, page?: number, limit?: number): Promise<any>;
123
+ sortVietnamese(arr: string[]): string[];
124
+ getHeaderFooter(): void;
125
+ connectProject(_id: string): Promise<any>;
126
+ setProjectWorking(data: any): void;
127
+ /**
128
+ * Lấy chi tiết trang có tất cả nhánh
129
+ * @param id id trang
130
+ * @returns
131
+ */
132
+ getDetailPage(id: string): any;
133
+ /**
134
+ * hàm lấy full nhánh objects con cho block, lấy luôn danh dánh object nhân bản
135
+ * @param block
136
+ * @returns
137
+ */
138
+ getFullObjectsForBlock(block: any): any;
139
+ /**
140
+ * hàm lấy full nhánh objects con cho object, lấy luôn danh dánh object nhân bản
141
+ * @param object
142
+ * @returns
143
+ */
144
+ getFullObjectsForObject(object: any): any;
145
+ addPage(data: any): Promise<any>;
146
+ deletePage(id: string): Promise<any>;
147
+ getPage(id: string): Promise<any>;
148
+ deleteBlockDbAndLocal(id: string): void;
149
+ deleteObjectDbAndLocal(id: string): Promise<void>;
150
+ /**
151
+ *
152
+ * @param nodes nhánh cần làm phẳng từ page
153
+ */
154
+ flatNodes(nodes: any): any;
155
+ updatePage(id: string, data: any): Promise<any>;
156
+ getPages(): Promise<any>;
157
+ /**
158
+ *
159
+ * @param data ko cần tính index, hàm từ tính luôn
160
+ * @returns
161
+ */
162
+ addBlock(data: any): Promise<any>;
163
+ updateBlock(id: string, data: any): Promise<any>;
164
+ deleteBlock(id: string): Promise<any>;
165
+ deleteBlockClone(block: any): Promise<any>;
166
+ /**
167
+ *
168
+ * @param data dữ liệu object tạo mới
169
+ * @param sync đồng bộ giao diện, true thì giao diện sẽ cập nhật ngay, false thì không cập nhật giao diện chỉ add trên db
170
+ * @returns
171
+ */
172
+ addObject(data: any): Promise<any>;
173
+ updateObject(id: string, data: any): Promise<any>;
174
+ /**
175
+ * hàm này xóa tất cả object và nhánh con của nó
176
+ * @param id id của object cần xóa
177
+ * @returns
178
+ */
179
+ deleteObject(id: string): any;
180
+ deleteObjectClone(object: any): Promise<any>;
181
+ upLoadImage(file: any, oldPath: string, newPath: string, options?: any): Promise<any>;
182
+ addCategory(data: any): Promise<any>;
183
+ updateCategory(id: string, data: any): Promise<any>;
184
+ deleteCategory(id: string): Promise<any>;
185
+ getCategories_byFields(query: any, sort: any, page?: number, limit?: number): Promise<any>;
186
+ searchList_likeSearch(value: string, col_name: string, field: string): Promise<any>;
187
+ addProduct(data: any): Promise<any>;
188
+ updateProduct(id: string, data: any): Promise<any>;
189
+ deleteProduct(id: string): Promise<any>;
190
+ getProducts_byFields(query: any, sort: any, page?: number, limit?: number): Promise<any>;
191
+ getProducts_byCategoryLink(link_category: string, query: any, sort: any, page?: number, limit?: number): Promise<any>;
192
+ /**
193
+ * hàm này lấy chi tiết sản phẩm theo đường dẫn, đầy đù gồm categories
194
+ * {
195
+ "_id": "...",
196
+ "name": "...",
197
+ "id_categorys": ["catid1", "catid2"],
198
+ "categories": [
199
+ { "_id": "catid1", "name": "Tên 1" },
200
+ { "_id": "catid2", "name": "Tên 2" }
201
+ ]
202
+ }
203
+ * @param link đường dẫn của sản phẩm cần lấy chi tiết
204
+ * @returns
205
+ */
206
+ getDetailProduct_byLink(link: string): Promise<any>;
207
+ addNews(data: any): Promise<any>;
208
+ updateNews(id: string, data: any): Promise<any>;
209
+ deleteNews(id: string): Promise<any>;
210
+ getNews_byFields(query: any, sort: any, page?: number, limit?: number): Promise<any>;
211
+ addNewField(data: any): Promise<any>;
212
+ updateNewField(id: string, data: any): Promise<any>;
213
+ deleteNewField(id: string): Promise<any>;
214
+ getNewField_byFields(query: any, sort: any, page?: number, limit?: number): Promise<any>;
215
+ displayBocksOfPage_byScroll(_this: any): void;
216
+ /**
217
+ * @param data dữ liệu của khối, khung hoặc vật thể được chọn
218
+ * TRUYỀN NULL để bỏ set
219
+ */
220
+ setItemChoosing(data: any, node?: any, parent?: any): void;
221
+ getCart(): Promise<any>;
222
+ /**
223
+ * hàm thêm sản phẩm vào giỏ hàng
224
+ */
225
+ addToCart(itemToAdd: any): Promise<any>;
226
+ deleteCartItem(id_variation: string): Promise<any>;
227
+ updateCartItem(id_variation: string, qty: number): Promise<any>;
228
+ addAddress(data: any): Promise<any>;
229
+ updateAddress(id: string, data: any): Promise<any>;
230
+ deleteAddress(id: string): Promise<any>;
231
+ getProvinces(): Promise<any>;
232
+ getDistricts(province_code: string): Promise<any>;
233
+ getWards(district_code: string): Promise<any>;
234
+ getCountries(): Promise<any>;
235
+ /**
236
+ * hàm này tính lại min-height để khi resize block ko bị giật, chỉ cần tính ở design, tính khi đổi trang hoặc đôi thiết bị
237
+ */
238
+ updateHeightDesign(): void;
239
+ getObject(id: string): any;
240
+ getBlock(id: string): any;
241
+ handleCtrl_C(): Promise<any>;
242
+ handleCtrl_D(): Promise<any>;
243
+ handleCtrl_V(): any;
244
+ applyFontLinks(fontLinksFromDB: string): void;
245
+ getFontNames(fontLinkTag: string): string[];
246
+ /**
247
+ * hàm này dùng để copy block
248
+ * @param page _id của page chứa block
249
+ * @param block block có NHÁNH(objects) cần copy
250
+ */
251
+ handleCopyBlock(page: any, block: any): Promise<void>;
252
+ /**
253
+ * Hàm này dùng để copy object
254
+ * khi copy page thì cần mọi object nằm ở vị trí cũ,
255
+ * copy object thì cần nó ở vị trí top, left == 0 thì set change_position = true
256
+ * @param parent id của block hoặc object mà object sẽ add vào
257
+ * @param object object có NHÁNH(objects) cần copy
258
+ * @param change_position
259
+ */
260
+ handleCopyObject(parent: any, object: any, change_position?: boolean): Promise<void>;
261
+ /**
262
+ * hàm này copy page, page truyền vào phải có nhánh
263
+ * @param page page phải có NHÁNH
264
+ * @returns
265
+ */
266
+ handleCopyPage(page: any): Promise<any>;
267
+ /**
268
+ * hàm nhân bản block
269
+ * @param page hiện tại
270
+ * @param block block phải có NHÁNH
271
+ * @returns
272
+ */
273
+ handleCloneBlock(page: any, block: any): Promise<void>;
274
+ /**
275
+ * Chỉ cần dùng hàm này sẽ cập nhật dữ liệu và giao diện
276
+ * @param parent đối tượng cha
277
+ * @param object đối tượng clone
278
+ */
279
+ handleCloneObject(parent: any, object: any, change_position?: boolean): Promise<void>;
280
+ handleOrder(customer_info: any, note: any, payment_method: any): Promise<any>;
281
+ getOrders_byFields(query: any, sort: any, page?: number, limit?: number): Promise<any>;
282
+ updateOrder(id: string, data: any): Promise<any>;
283
+ deleteOrder(id: string): Promise<any>;
284
+ /**
285
+ * Hàm tạo ID đối tượng theo định dạng ObjectId của MongoDB
286
+ * @returns {string} ID đối tượng 24 ký tự hex
287
+ */
288
+ generateObjectId(): string;
289
+ static ɵfac: i0.ɵɵFactoryDeclaration<webBuilderService, never>;
290
+ static ɵprov: i0.ɵɵInjectableDeclaration<webBuilderService>;
291
+ }
292
+
293
+ type DragMode = 'absolute' | 'margin';
294
+ declare class WbDragDrop implements OnInit {
295
+ webBuilderService: webBuilderService;
296
+ el: ElementRef;
297
+ private renderer;
298
+ /**
299
+ * Input để chọn chế độ: 'absolute' (mặc định) hoặc 'margin'
300
+ * */
301
+ mode: DragMode;
302
+ /**
303
+ * DOM phần tử cha
304
+ */
305
+ boundaryEle: any;
306
+ /**
307
+ * dữ liệu phần tử cha
308
+ */
309
+ parent: any;
310
+ data: any;
311
+ device: any;
312
+ top: number;
313
+ left: number;
314
+ type: any | 'design' | 'admin' | 'preview';
315
+ dragOffset: {
316
+ x: number;
317
+ y: number;
318
+ };
319
+ idParent: string;
320
+ direction: string;
321
+ /**
322
+ * biến này để tính maxLeft,minLeft, maxTop, minTop để resize cho đúng
323
+ */
324
+ initData: {
325
+ top: number;
326
+ left: number;
327
+ bottom: number;
328
+ right: number;
329
+ };
330
+ /**
331
+ * biến này để theo dõi con trỏ chuột để resize top, left
332
+ * */
333
+ currPos: any;
334
+ /**
335
+ * biến cờ để biết đã kéo hay resize chưa, tránh click vào là update db luôn
336
+ */
337
+ changed: boolean;
338
+ parentEleRect: any;
339
+ parentData: any;
340
+ keyPosition: string;
341
+ private isDragging;
342
+ private mouseMoveListener;
343
+ private mouseUpListener;
344
+ constructor(webBuilderService: webBuilderService, el: ElementRef, renderer: Renderer2);
345
+ ngOnInit(): void;
346
+ ngAfterViewInit(): void;
347
+ /**
348
+ * Chỉ chạy khi một trong các @Input (top, left) thay đổi,
349
+ */
350
+ ngOnChanges(changes: SimpleChanges): void;
351
+ /**
352
+ * hàm cập nhật ví trí của đối tượng trên giao diện
353
+ * @param data
354
+ */
355
+ updateUIPosition(): void;
356
+ /**
357
+ * hàm này cập nhật bottom và right của phần tử resize sử dụng
358
+ */
359
+ updateInitBottomAndRight(): void;
360
+ onPointerDown(e: any): void;
361
+ private onMouseMove;
362
+ private onMouseUp;
363
+ ngOnDestroy(): void;
364
+ private cleanupListeners;
365
+ handleChooseItems(): void;
366
+ handleChooseItem(): void;
367
+ getLeftDrag(): 0 | -24;
368
+ handleResizePointerDown(e: any, direction: any): void;
369
+ handleResizePointerMove(e: any): void;
370
+ handleResizePointerUp(e: any): void;
371
+ minTop: any;
372
+ onResizeTop(e: any): void;
373
+ onResizeBottom(e: any): void;
374
+ minLeft: any;
375
+ onResizeLeft(e: any): void;
376
+ onResizeRight(e: any): void;
377
+ updatePosition(): void;
378
+ updateClass(): void;
379
+ updatePositionAndClass(): void;
380
+ conditionShowActive(): any;
381
+ conditionShowResize(): any;
382
+ static ɵfac: i0.ɵɵFactoryDeclaration<WbDragDrop, never>;
383
+ static ɵcmp: i0.ɵɵComponentDeclaration<WbDragDrop, "[wbdragdrop]", never, { "mode": { "alias": "mode"; "required": false; }; "boundaryEle": { "alias": "boundaryEle"; "required": false; }; "parent": { "alias": "parent"; "required": false; }; "data": { "alias": "data"; "required": false; }; "device": { "alias": "device"; "required": false; }; "top": { "alias": "top"; "required": false; }; "left": { "alias": "left"; "required": false; }; "type": { "alias": "type"; "required": false; }; }, {}, never, ["*"], true, never>;
384
+ }
385
+
386
+ declare class WbVirtualSelected implements OnInit {
387
+ webBuilderService: webBuilderService;
388
+ el: ElementRef;
389
+ boundaryEle: any;
390
+ isDragging: boolean;
391
+ parentEleRect: any;
392
+ dragOffset: {
393
+ x: number;
394
+ y: number;
395
+ };
396
+ currPos: any;
397
+ idParent: string;
398
+ changed: boolean;
399
+ keyPosition: any;
400
+ constructor(webBuilderService: webBuilderService, el: ElementRef);
401
+ ngOnInit(): void;
402
+ onHostMouseDown(e: any): void;
403
+ onPointerMove(event: any): void;
404
+ onPointerUp(e: any): void;
405
+ static ɵfac: i0.ɵɵFactoryDeclaration<WbVirtualSelected, never>;
406
+ static ɵcmp: i0.ɵɵComponentDeclaration<WbVirtualSelected, "[wbVirtualSelected]", never, { "boundaryEle": { "alias": "boundaryEle"; "required": false; }; }, {}, never, never, true, never>;
407
+ }
408
+
409
+ declare const WEBBUILDER_API_URL: InjectionToken<string>;
410
+
411
+ export { WEBBUILDER_API_URL, WbDragDrop, WbVirtualSelected, webBuilderService };
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "fw-webbuilder",
3
+ "version": "0.0.2",
4
+ "peerDependencies": {
5
+ "@angular/common": "^20.3.0",
6
+ "@angular/core": "^20.3.0"
7
+ },
8
+ "dependencies": {
9
+ "tslib": "^2.3.0"
10
+ },
11
+ "sideEffects": false,
12
+ "module": "fesm2022/fw-webbuilder.mjs",
13
+ "typings": "index.d.ts",
14
+ "exports": {
15
+ "./package.json": {
16
+ "default": "./package.json"
17
+ },
18
+ ".": {
19
+ "types": "./index.d.ts",
20
+ "default": "./fesm2022/fw-webbuilder.mjs"
21
+ }
22
+ }
23
+ }