@pisell/pisellos 2.3.73 → 2.3.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.js +111 -71
- package/dist/model/strategy/adapter/promotion/index.js +9 -0
- package/dist/model/strategy/adapter/walletPass/example.js +3 -26
- package/dist/model/strategy/strategy-example.js +5 -19
- package/dist/modules/Cart/index.js +0 -3
- package/dist/modules/Cart/utils/cartProduct.js +0 -1
- package/dist/modules/Date/index.js +1 -5
- package/dist/modules/Discount/index.js +2 -4
- package/dist/modules/OpenData/index.js +0 -2
- package/dist/modules/Order/index.d.ts +1 -1
- package/dist/modules/Order/index.js +36 -64
- package/dist/modules/Payment/index.js +97 -162
- package/dist/modules/Quotation/index.d.ts +6 -0
- package/dist/modules/Quotation/index.js +75 -19
- package/dist/modules/Rules/index.js +1 -4
- package/dist/modules/Schedule/index.js +0 -1
- package/dist/modules/Schedule/utils.js +0 -1
- package/dist/modules/Step/index.js +0 -1
- package/dist/plugins/request.d.ts +1 -0
- package/dist/plugins/request.js +1 -4
- package/dist/plugins/window.js +2 -6
- package/dist/server/index.d.ts +8 -2
- package/dist/server/index.js +303 -269
- package/dist/server/modules/floor-plan/index.d.ts +4 -0
- package/dist/server/modules/floor-plan/index.js +240 -98
- package/dist/server/modules/menu/index.js +75 -59
- package/dist/server/modules/order/index.d.ts +17 -7
- package/dist/server/modules/order/index.js +421 -211
- package/dist/server/modules/products/index.d.ts +8 -2
- package/dist/server/modules/products/index.js +191 -117
- package/dist/server/modules/quotation/index.js +29 -38
- package/dist/server/modules/resource/index.js +24 -17
- package/dist/server/modules/schedule/index.js +27 -35
- package/dist/server/utils/product.js +0 -1
- package/dist/solution/BaseSales/index.js +38 -41
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingByStep/index.js +7 -59
- package/dist/solution/BookingByStep/utils/capacity.js +1 -11
- package/dist/solution/BookingByStep/utils/resources.js +1 -3
- package/dist/solution/BookingByStep/utils/timeslots.js +2 -43
- package/dist/solution/BookingTicket/index.js +0 -2
- package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +6 -7
- package/dist/solution/BookingTicket/utils/scan/handleScan.js +25 -31
- package/dist/solution/BookingTicket/utils/scan/index.js +6 -10
- package/dist/solution/BuyTickets/index.js +9 -12
- package/dist/solution/Checkout/index.js +177 -252
- package/dist/solution/Checkout/utils/index.js +4 -16
- package/dist/solution/RegisterAndLogin/index.js +30 -76
- package/dist/solution/ScanOrder/index.js +50 -60
- package/dist/solution/ShopDiscount/index.js +2 -7
- package/dist/solution/VenueBooking/index.js +45 -55
- package/dist/utils/task.js +15 -18
- package/dist/utils/watch.js +0 -1
- package/lib/apis/picoding.js +2 -0
- package/lib/core/index.d.ts +7 -0
- package/lib/core/index.js +149 -131
- package/lib/effects/index.js +46 -57
- package/lib/index.js +82 -49
- package/lib/model/index.js +14 -21
- package/lib/model/strategy/adapter/dataVariant/adapter.js +38 -50
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +162 -236
- package/lib/model/strategy/adapter/dataVariant/examples.js +229 -237
- package/lib/model/strategy/adapter/dataVariant/index.js +39 -34
- package/lib/model/strategy/adapter/dataVariant/type.js +57 -28
- package/lib/model/strategy/adapter/index.js +100 -64
- package/lib/model/strategy/adapter/itemRule/adapter.js +156 -144
- package/lib/model/strategy/adapter/itemRule/evaluator.js +36 -48
- package/lib/model/strategy/adapter/itemRule/examples.js +295 -225
- package/lib/model/strategy/adapter/itemRule/index.js +83 -57
- package/lib/model/strategy/adapter/itemRule/type.js +97 -36
- package/lib/model/strategy/adapter/promotion/adapter.js +91 -69
- package/lib/model/strategy/adapter/promotion/evaluator.js +444 -310
- package/lib/model/strategy/adapter/promotion/examples.js +222 -234
- package/lib/model/strategy/adapter/promotion/index.js +1 -0
- package/lib/model/strategy/adapter/promotion/type.js +243 -36
- package/lib/model/strategy/adapter/type.js +4 -16
- package/lib/model/strategy/adapter/walletPass/evaluator.js +180 -150
- package/lib/model/strategy/adapter/walletPass/example.js +217 -190
- package/lib/model/strategy/adapter/walletPass/index.js +75 -51
- package/lib/model/strategy/adapter/walletPass/locales.js +36 -58
- package/lib/model/strategy/adapter/walletPass/type.js +4 -16
- package/lib/model/strategy/adapter/walletPass/utils.js +588 -378
- package/lib/model/strategy/engine.js +270 -168
- package/lib/model/strategy/index.js +49 -34
- package/lib/model/strategy/strategy-example.js +243 -239
- package/lib/model/strategy/type.js +100 -40
- package/lib/modules/Account/index.js +39 -53
- package/lib/modules/Account/types.js +20 -33
- package/lib/modules/AccountList/index.js +116 -154
- package/lib/modules/AccountList/types.js +30 -31
- package/lib/modules/AccountList/utils.js +18 -30
- package/lib/modules/BaseModule.js +23 -42
- package/lib/modules/BookingContext/index.js +158 -136
- package/lib/modules/BookingContext/types.js +46 -32
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +138 -146
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +78 -83
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +170 -150
- package/lib/modules/BookingContext/utils/flexible.js +38 -55
- package/lib/modules/BookingContext/utils/formatResourceList.js +19 -34
- package/lib/modules/BookingContext/utils/index.js +124 -41
- package/lib/modules/BookingContext/utils/noResource.js +58 -70
- package/lib/modules/BookingContext/utils/orderLineDisplay.js +14 -41
- package/lib/modules/BookingContext/utils/productExtend.js +202 -155
- package/lib/modules/BookingContext/utils/resourceErrors.js +53 -53
- package/lib/modules/BookingContext/utils/resourceSelection.js +19 -41
- package/lib/modules/BookingContext/utils/resources.js +209 -167
- package/lib/modules/BookingContext/utils/serviceTimes.js +115 -116
- package/lib/modules/BookingContext/utils/timeSlices.js +76 -86
- package/lib/modules/Cart/index.js +170 -124
- package/lib/modules/Cart/types.js +46 -51
- package/lib/modules/Cart/utils/cartAccount.js +40 -39
- package/lib/modules/Cart/utils/cartDate.js +56 -61
- package/lib/modules/Cart/utils/cartDiscount.js +28 -33
- package/lib/modules/Cart/utils/cartNote.js +27 -32
- package/lib/modules/Cart/utils/cartProduct.js +321 -251
- package/lib/modules/Cart/utils/cartRelationForms.js +29 -35
- package/lib/modules/Cart/utils/cartResource.js +70 -78
- package/lib/modules/Cart/utils/changePrice.js +22 -50
- package/lib/modules/Cart/utils/index.js +106 -48
- package/lib/modules/Customer/constants.js +13 -34
- package/lib/modules/Customer/index.js +235 -172
- package/lib/modules/Customer/types.js +38 -35
- package/lib/modules/Date/index.js +116 -115
- package/lib/modules/Date/types.js +16 -28
- package/lib/modules/Date/utils.js +174 -123
- package/lib/modules/Discount/index.js +122 -127
- package/lib/modules/Discount/types.js +9 -31
- package/lib/modules/Guests/index.js +30 -56
- package/lib/modules/Guests/types.js +23 -33
- package/lib/modules/Holder/index.js +209 -189
- package/lib/modules/Holder/types.js +4 -16
- package/lib/modules/Holder/utils.js +20 -49
- package/lib/modules/OpenData/index.js +70 -76
- package/lib/modules/OpenData/types.js +4 -16
- package/lib/modules/OpenData/utils.js +44 -78
- package/lib/modules/Order/index.d.ts +1 -1
- package/lib/modules/Order/index.js +1713 -2118
- package/lib/modules/Order/payment-utils.js +77 -120
- package/lib/modules/Order/types.js +88 -35
- package/lib/modules/Order/utils/bundleDiscountHydration.js +41 -74
- package/lib/modules/Order/utils/discountProductLineIdentity.js +142 -100
- package/lib/modules/Order/utils/manualProductDiscount.js +124 -123
- package/lib/modules/Order/utils/orderCollectionIdentity.js +184 -244
- package/lib/modules/Order/utils.js +814 -647
- package/lib/modules/Payment/cash.js +20 -33
- package/lib/modules/Payment/cashRecommendationAlgorithm.js +145 -76
- package/lib/modules/Payment/eftpos.js +16 -30
- package/lib/modules/Payment/index.js +532 -399
- package/lib/modules/Payment/mx51.js +1 -0
- package/lib/modules/Payment/types.js +230 -108
- package/lib/modules/Payment/utils.js +52 -51
- package/lib/modules/Payment/walletpass.js +485 -660
- package/lib/modules/Product/index.js +51 -46
- package/lib/modules/Product/types.js +4 -16
- package/lib/modules/Product/utils.js +32 -33
- package/lib/modules/ProductList/index.js +113 -123
- package/lib/modules/ProductList/types.js +9 -31
- package/lib/modules/Quotation/index.d.ts +6 -0
- package/lib/modules/Quotation/index.js +110 -103
- package/lib/modules/Quotation/types.js +4 -16
- package/lib/modules/Resource/index.js +27 -59
- package/lib/modules/Resource/types.js +22 -32
- package/lib/modules/Resource/utils.js +30 -38
- package/lib/modules/ResourcePlanner/index.js +25 -23
- package/lib/modules/ResourcePlanner/localClock.js +54 -119
- package/lib/modules/ResourcePlanner/planner.js +589 -770
- package/lib/modules/ResourcePlanner/types.js +10 -29
- package/lib/modules/Rules/index.js +1218 -959
- package/lib/modules/Rules/types.js +17 -40
- package/lib/modules/SalesSummary/index.js +85 -90
- package/lib/modules/SalesSummary/types.js +4 -16
- package/lib/modules/SalesSummary/utils.js +355 -430
- package/lib/modules/ScanOrderLogger/index.js +59 -79
- package/lib/modules/ScanOrderLogger/providers/feishu.js +54 -78
- package/lib/modules/ScanOrderLogger/providers/grafana.js +13 -36
- package/lib/modules/ScanOrderLogger/types.js +4 -16
- package/lib/modules/Schedule/getDateIsInSchedule.js +334 -163
- package/lib/modules/Schedule/index.js +100 -114
- package/lib/modules/Schedule/type.js +4 -16
- package/lib/modules/Schedule/types.js +4 -16
- package/lib/modules/Schedule/utils.js +433 -291
- package/lib/modules/Step/index.js +40 -52
- package/lib/modules/Step/tyeps.js +4 -16
- package/lib/modules/Summary/index.js +66 -71
- package/lib/modules/Summary/types.js +4 -16
- package/lib/modules/Summary/utils.js +773 -418
- package/lib/modules/SurchargeList/index.js +46 -60
- package/lib/modules/SurchargeList/types.js +4 -16
- package/lib/modules/index.js +245 -63
- package/lib/plugins/app.js +4 -16
- package/lib/plugins/index.js +36 -25
- package/lib/plugins/request.d.ts +1 -0
- package/lib/plugins/request.js +137 -126
- package/lib/plugins/shopStore.js +4 -16
- package/lib/plugins/user.js +4 -16
- package/lib/plugins/window.js +171 -179
- package/lib/server/index.d.ts +8 -2
- package/lib/server/index.js +3083 -2663
- package/lib/server/modules/floor-plan/index.d.ts +4 -0
- package/lib/server/modules/floor-plan/index.js +159 -127
- package/lib/server/modules/floor-plan/types.js +15 -30
- package/lib/server/modules/index.js +106 -68
- package/lib/server/modules/menu/index.js +170 -124
- package/lib/server/modules/menu/types.js +18 -31
- package/lib/server/modules/order/index.d.ts +17 -7
- package/lib/server/modules/order/index.js +916 -977
- package/lib/server/modules/order/types.js +122 -33
- package/lib/server/modules/order/utils/filterBookings.js +219 -194
- package/lib/server/modules/order/utils/filterOrders.js +118 -92
- package/lib/server/modules/payment/index.js +59 -83
- package/lib/server/modules/payment/types.js +4 -16
- package/lib/server/modules/products/index.d.ts +8 -2
- package/lib/server/modules/products/index.js +656 -471
- package/lib/server/modules/products/types.js +44 -34
- package/lib/server/modules/quotation/index.js +137 -172
- package/lib/server/modules/quotation/types.js +21 -31
- package/lib/server/modules/resource/index.js +225 -186
- package/lib/server/modules/resource/types.js +42 -33
- package/lib/server/modules/schedule/index.js +135 -123
- package/lib/server/modules/schedule/types.js +14 -21
- package/lib/server/modules/schedule/utils.js +334 -163
- package/lib/server/types.js +4 -16
- package/lib/server/utils/index.js +25 -23
- package/lib/server/utils/product.js +196 -139
- package/lib/server/utils/schedule.js +34 -41
- package/lib/server/utils/small-ticket.js +479 -456
- package/lib/server/utils/time.js +40 -49
- package/lib/solution/BaseSales/index.js +1186 -1410
- package/lib/solution/BaseSales/types.js +42 -38
- package/lib/solution/BaseSales/utils/cartPromotion.js +642 -498
- package/lib/solution/BaseSales/utils/parseSalesResponse.js +85 -105
- package/lib/solution/BaseSales/utils/quotationPrice.js +56 -114
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +108 -145
- package/lib/solution/BaseSales/utils.js +158 -143
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingByStep/index.js +1527 -1340
- package/lib/solution/BookingByStep/types.js +40 -99
- package/lib/solution/BookingByStep/utils/capacity.js +192 -160
- package/lib/solution/BookingByStep/utils/products.js +42 -52
- package/lib/solution/BookingByStep/utils/resources.js +527 -330
- package/lib/solution/BookingByStep/utils/stock.js +65 -44
- package/lib/solution/BookingByStep/utils/timeslots.js +129 -131
- package/lib/solution/BookingTicket/index.js +607 -522
- package/lib/solution/BookingTicket/types.js +99 -77
- package/lib/solution/BookingTicket/utils/addProductDecision.js +226 -189
- package/lib/solution/BookingTicket/utils/addTimeAvailability.js +58 -89
- package/lib/solution/BookingTicket/utils/bookingStatus.js +107 -78
- package/lib/solution/BookingTicket/utils/cartView.js +114 -99
- package/lib/solution/BookingTicket/utils/exampleData.js +185 -0
- package/lib/solution/BookingTicket/utils/orderCustomer.js +18 -41
- package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +219 -86
- package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +168 -116
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +79 -91
- package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +54 -41
- package/lib/solution/BookingTicket/utils/scan/handleScan.js +84 -81
- package/lib/solution/BookingTicket/utils/scan/index.js +98 -104
- package/lib/solution/BookingTicket/utils/scan/scanCache.js +90 -43
- package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +52 -64
- package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +56 -58
- package/lib/solution/BookingTicket/utils/weighingProductSku.js +34 -48
- package/lib/solution/BuyTickets/index.js +67 -70
- package/lib/solution/BuyTickets/types.js +22 -38
- package/lib/solution/Checkout/index.js +1451 -1158
- package/lib/solution/Checkout/types.js +91 -61
- package/lib/solution/Checkout/utils/index.js +228 -156
- package/lib/solution/PlaceOrder/index.js +55 -0
- package/lib/solution/RegisterAndLogin/config.js +493 -460
- package/lib/solution/RegisterAndLogin/index.js +633 -630
- package/lib/solution/RegisterAndLogin/types.js +189 -76
- package/lib/solution/RegisterAndLogin/utils.js +183 -125
- package/lib/solution/Sales/index.js +328 -324
- package/lib/solution/Sales/types.js +27 -33
- package/lib/solution/ScanOrder/index.js +832 -864
- package/lib/solution/ScanOrder/types.js +33 -34
- package/lib/solution/ScanOrder/utils.js +409 -374
- package/lib/solution/ShopDiscount/index.js +226 -232
- package/lib/solution/ShopDiscount/types.js +15 -37
- package/lib/solution/ShopDiscount/utils.js +300 -172
- package/lib/solution/UnifiedBookingSales/index.js +1035 -1201
- package/lib/solution/UnifiedBookingSales/remoteOccupancyCache.js +99 -159
- package/lib/solution/UnifiedBookingSales/types.js +10 -32
- package/lib/solution/VenueBooking/index.js +811 -879
- package/lib/solution/VenueBooking/types.js +19 -39
- package/lib/solution/VenueBooking/utils/dateSummary.js +27 -56
- package/lib/solution/VenueBooking/utils/resource.js +31 -54
- package/lib/solution/VenueBooking/utils/slotMerge.js +94 -107
- package/lib/solution/VenueBooking/utils/timeSlot.js +132 -132
- package/lib/solution/VenueBooking/utils.js +130 -67
- package/lib/solution/index.js +124 -41
- package/lib/store/createStore.js +32 -29
- package/lib/types/index.js +4 -16
- package/lib/utils/payment-number.js +26 -46
- package/lib/utils/task.js +36 -36
- package/lib/utils/watch.js +81 -47
- package/package.json +2 -1
|
@@ -1,36 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __export = (target, all) => {
|
|
6
|
-
for (var name in all)
|
|
7
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
-
};
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (let key of __getOwnPropNames(from))
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
17
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
1
|
+
"use strict";
|
|
18
2
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
__export(adapter_exports, {
|
|
22
|
-
ItemRuleAdapter: () => ItemRuleAdapter,
|
|
23
|
-
default: () => adapter_default
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
24
5
|
});
|
|
25
|
-
|
|
26
|
-
var
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
6
|
+
exports.default = exports.ItemRuleAdapter = void 0;
|
|
7
|
+
var _type = require("./type");
|
|
8
|
+
/**
|
|
9
|
+
* ItemRule 适配器
|
|
10
|
+
*
|
|
11
|
+
* 将堂食扫码点餐的商品规则业务数据转换为策略引擎格式,
|
|
12
|
+
* 并将引擎结果转换为数量校验和预填购物车的业务结果。
|
|
13
|
+
*/
|
|
14
|
+
class ItemRuleAdapter {
|
|
15
|
+
name = 'ItemRuleAdapter';
|
|
16
|
+
version = '1.0.0';
|
|
32
17
|
prepareContext(businessData) {
|
|
33
|
-
const {
|
|
18
|
+
const {
|
|
19
|
+
pax,
|
|
20
|
+
cartItems,
|
|
21
|
+
serviceType,
|
|
22
|
+
submissionIndex,
|
|
23
|
+
custom
|
|
24
|
+
} = businessData;
|
|
34
25
|
return {
|
|
35
26
|
entities: {
|
|
36
27
|
cartItems,
|
|
@@ -38,7 +29,7 @@ var ItemRuleAdapter = class {
|
|
|
38
29
|
pax
|
|
39
30
|
},
|
|
40
31
|
attributes: {
|
|
41
|
-
serviceType: serviceType ||
|
|
32
|
+
serviceType: serviceType || '',
|
|
42
33
|
totalPax: pax.total,
|
|
43
34
|
adultPax: pax.adult,
|
|
44
35
|
childPax: pax.child,
|
|
@@ -56,47 +47,61 @@ var ItemRuleAdapter = class {
|
|
|
56
47
|
const quantityChecks = [];
|
|
57
48
|
const prefillItems = [];
|
|
58
49
|
if (!result.applicable || !businessData) {
|
|
59
|
-
return {
|
|
50
|
+
return {
|
|
51
|
+
quantityChecks,
|
|
52
|
+
prefillItems
|
|
53
|
+
};
|
|
60
54
|
}
|
|
61
55
|
for (const action of result.matchedActions) {
|
|
62
|
-
if (action.type ===
|
|
56
|
+
if (action.type === _type.ITEM_RULE_ACTION_TYPES.QUANTITY_CHECK) {
|
|
63
57
|
const checkResult = this.processQuantityCheck(action, businessData);
|
|
64
58
|
if (checkResult) {
|
|
65
59
|
quantityChecks.push(checkResult);
|
|
66
60
|
}
|
|
67
|
-
} else if (action.type ===
|
|
61
|
+
} else if (action.type === _type.ITEM_RULE_ACTION_TYPES.PREFILL_CART) {
|
|
68
62
|
const items = this.processPrefillCart(action, businessData);
|
|
69
63
|
prefillItems.push(...items);
|
|
70
64
|
}
|
|
71
65
|
}
|
|
72
|
-
return {
|
|
66
|
+
return {
|
|
67
|
+
quantityChecks,
|
|
68
|
+
prefillItems
|
|
69
|
+
};
|
|
73
70
|
}
|
|
74
71
|
formatConfig(result, businessData) {
|
|
75
|
-
return {
|
|
72
|
+
return {
|
|
73
|
+
result,
|
|
74
|
+
businessData
|
|
75
|
+
};
|
|
76
76
|
}
|
|
77
|
+
|
|
77
78
|
// ============================================
|
|
78
79
|
// Quantity Check 处理
|
|
79
80
|
// ============================================
|
|
81
|
+
|
|
80
82
|
processQuantityCheck(action, businessData) {
|
|
81
83
|
const config = action.config;
|
|
82
|
-
if (!config)
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
if (!config) return null;
|
|
85
|
+
const {
|
|
86
|
+
scope,
|
|
87
|
+
quantityRules,
|
|
88
|
+
targetType,
|
|
89
|
+
targets,
|
|
90
|
+
validationMessage
|
|
91
|
+
} = config;
|
|
85
92
|
if (!this.shouldEvaluateForScope(scope, businessData.submissionIndex ?? 0)) {
|
|
86
93
|
return null;
|
|
87
94
|
}
|
|
88
|
-
const actualQuantity = this.calculateActualQuantity(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
);
|
|
93
|
-
const { passed, failedRules, requiredMin, requiredMax, requiredExact, mustInclude } = this.evaluateQuantityRules(quantityRules, actualQuantity, businessData);
|
|
94
|
-
const message = this.formatValidationMessage(
|
|
95
|
-
validationMessage,
|
|
95
|
+
const actualQuantity = this.calculateActualQuantity(targets, scope, businessData);
|
|
96
|
+
const {
|
|
97
|
+
passed,
|
|
98
|
+
failedRules,
|
|
96
99
|
requiredMin,
|
|
97
100
|
requiredMax,
|
|
98
|
-
requiredExact
|
|
99
|
-
|
|
101
|
+
requiredExact,
|
|
102
|
+
mustInclude
|
|
103
|
+
} = this.evaluateQuantityRules(quantityRules, actualQuantity, businessData);
|
|
104
|
+
const message = this.formatValidationMessage(validationMessage, requiredMin, requiredMax, requiredExact);
|
|
100
105
|
return {
|
|
101
106
|
ruleId: action.id,
|
|
102
107
|
passed,
|
|
@@ -109,42 +114,44 @@ var ItemRuleAdapter = class {
|
|
|
109
114
|
mustInclude,
|
|
110
115
|
validationMessage: message,
|
|
111
116
|
scope,
|
|
112
|
-
failedRules: passed ?
|
|
117
|
+
failedRules: passed ? undefined : failedRules
|
|
113
118
|
};
|
|
114
119
|
}
|
|
120
|
+
|
|
115
121
|
/**
|
|
116
122
|
* 根据 scope 判断当前提交是否需要评估此规则
|
|
117
123
|
*/
|
|
118
124
|
shouldEvaluateForScope(scope, submissionIndex) {
|
|
119
125
|
switch (scope) {
|
|
120
|
-
case
|
|
126
|
+
case 'each_submission':
|
|
121
127
|
return true;
|
|
122
|
-
case
|
|
128
|
+
case 'first_submission_only':
|
|
123
129
|
return submissionIndex === 0;
|
|
124
|
-
case
|
|
130
|
+
case 'subsequent_only':
|
|
125
131
|
return submissionIndex > 0;
|
|
126
|
-
case
|
|
132
|
+
case 'cumulative':
|
|
127
133
|
return true;
|
|
128
134
|
default:
|
|
129
135
|
return true;
|
|
130
136
|
}
|
|
131
137
|
}
|
|
138
|
+
|
|
132
139
|
/**
|
|
133
140
|
* 计算目标商品在购物车中的实际数量
|
|
134
141
|
*
|
|
135
142
|
* cumulative scope 时还会加上历史订单数量。
|
|
136
143
|
*/
|
|
137
144
|
calculateActualQuantity(targets, scope, businessData) {
|
|
138
|
-
const targetIds = new Set(targets.map(
|
|
145
|
+
const targetIds = new Set(targets.map(t => t.product_id));
|
|
139
146
|
let quantity = 0;
|
|
140
|
-
const countFromItems =
|
|
147
|
+
const countFromItems = items => {
|
|
141
148
|
for (const item of items) {
|
|
142
149
|
if (targetIds.has(item.product_id)) {
|
|
143
150
|
quantity += item.quantity;
|
|
144
151
|
}
|
|
145
152
|
}
|
|
146
153
|
};
|
|
147
|
-
if (scope ===
|
|
154
|
+
if (scope === 'cumulative') {
|
|
148
155
|
if (businessData.historicalItems) {
|
|
149
156
|
countFromItems(businessData.historicalItems);
|
|
150
157
|
}
|
|
@@ -166,38 +173,42 @@ var ItemRuleAdapter = class {
|
|
|
166
173
|
for (const rule of rules) {
|
|
167
174
|
const resolvedValue = this.resolveQuantityValue(rule, businessData);
|
|
168
175
|
switch (rule.comparison) {
|
|
169
|
-
case
|
|
170
|
-
|
|
171
|
-
requiredMin
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
case "maximum": {
|
|
179
|
-
if (requiredMax === void 0 || resolvedValue < requiredMax) {
|
|
180
|
-
requiredMax = resolvedValue;
|
|
176
|
+
case 'minimum':
|
|
177
|
+
{
|
|
178
|
+
if (requiredMin === undefined || resolvedValue > requiredMin) {
|
|
179
|
+
requiredMin = resolvedValue;
|
|
180
|
+
}
|
|
181
|
+
if (actualQuantity < resolvedValue) {
|
|
182
|
+
failedRules.push(rule);
|
|
183
|
+
}
|
|
184
|
+
break;
|
|
181
185
|
}
|
|
182
|
-
|
|
183
|
-
|
|
186
|
+
case 'maximum':
|
|
187
|
+
{
|
|
188
|
+
if (requiredMax === undefined || resolvedValue < requiredMax) {
|
|
189
|
+
requiredMax = resolvedValue;
|
|
190
|
+
}
|
|
191
|
+
if (actualQuantity > resolvedValue) {
|
|
192
|
+
failedRules.push(rule);
|
|
193
|
+
}
|
|
194
|
+
break;
|
|
184
195
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
196
|
+
case 'exact':
|
|
197
|
+
{
|
|
198
|
+
requiredExact = resolvedValue;
|
|
199
|
+
if (actualQuantity !== resolvedValue) {
|
|
200
|
+
failedRules.push(rule);
|
|
201
|
+
}
|
|
202
|
+
break;
|
|
191
203
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
204
|
+
case 'must_include':
|
|
205
|
+
{
|
|
206
|
+
mustInclude = true;
|
|
207
|
+
if (actualQuantity < 1) {
|
|
208
|
+
failedRules.push(rule);
|
|
209
|
+
}
|
|
210
|
+
break;
|
|
198
211
|
}
|
|
199
|
-
break;
|
|
200
|
-
}
|
|
201
212
|
}
|
|
202
213
|
}
|
|
203
214
|
return {
|
|
@@ -209,36 +220,39 @@ var ItemRuleAdapter = class {
|
|
|
209
220
|
mustInclude
|
|
210
221
|
};
|
|
211
222
|
}
|
|
223
|
+
|
|
212
224
|
/**
|
|
213
225
|
* 根据 source 解析出数量规则的实际数值
|
|
214
226
|
*/
|
|
215
227
|
resolveQuantityValue(rule, businessData) {
|
|
216
228
|
switch (rule.source) {
|
|
217
|
-
case
|
|
229
|
+
case 'total_pax':
|
|
218
230
|
return businessData.pax.total;
|
|
219
|
-
case
|
|
231
|
+
case 'adult_pax':
|
|
220
232
|
return businessData.pax.adult;
|
|
221
|
-
case
|
|
233
|
+
case 'fixed':
|
|
222
234
|
return rule.value ?? 0;
|
|
223
235
|
default:
|
|
224
236
|
return rule.value ?? 0;
|
|
225
237
|
}
|
|
226
238
|
}
|
|
239
|
+
|
|
227
240
|
/**
|
|
228
241
|
* 格式化校验提示语,替换 {min} {max} 占位符
|
|
229
242
|
*/
|
|
230
243
|
formatValidationMessage(template, min, max, exact, locale) {
|
|
231
|
-
if (!template)
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
text = text.replace(/\{
|
|
235
|
-
text = text.replace(/\{
|
|
236
|
-
text = text.replace(/\{exact\}/g, String(exact ?? ""));
|
|
244
|
+
if (!template) return undefined;
|
|
245
|
+
let text = typeof template === 'string' ? template : template[locale || 'en'] || Object.values(template)[0] || '';
|
|
246
|
+
text = text.replace(/\{min\}/g, String(min ?? ''));
|
|
247
|
+
text = text.replace(/\{max\}/g, String(max ?? ''));
|
|
248
|
+
text = text.replace(/\{exact\}/g, String(exact ?? ''));
|
|
237
249
|
return text;
|
|
238
250
|
}
|
|
251
|
+
|
|
239
252
|
// ============================================
|
|
240
253
|
// Quantity Limit 提取(仅读取配置,不做校验)
|
|
241
254
|
// ============================================
|
|
255
|
+
|
|
242
256
|
/**
|
|
243
257
|
* 从单个 QUANTITY_CHECK action 中提取数量限制配置。
|
|
244
258
|
*
|
|
@@ -248,9 +262,14 @@ var ItemRuleAdapter = class {
|
|
|
248
262
|
*/
|
|
249
263
|
extractQuantityLimits(action, businessData) {
|
|
250
264
|
const config = action.config;
|
|
251
|
-
if (!config)
|
|
252
|
-
|
|
253
|
-
|
|
265
|
+
if (!config) return null;
|
|
266
|
+
const {
|
|
267
|
+
scope,
|
|
268
|
+
quantityRules,
|
|
269
|
+
targetType,
|
|
270
|
+
targets,
|
|
271
|
+
validationMessage
|
|
272
|
+
} = config;
|
|
254
273
|
if (!this.shouldEvaluateForScope(scope, businessData.submissionIndex ?? 0)) {
|
|
255
274
|
return null;
|
|
256
275
|
}
|
|
@@ -261,40 +280,34 @@ var ItemRuleAdapter = class {
|
|
|
261
280
|
for (const rule of quantityRules) {
|
|
262
281
|
const resolvedValue = this.resolveQuantityValue(rule, businessData);
|
|
263
282
|
switch (rule.comparison) {
|
|
264
|
-
case
|
|
265
|
-
|
|
266
|
-
requiredMin
|
|
283
|
+
case 'minimum':
|
|
284
|
+
{
|
|
285
|
+
if (requiredMin === undefined || resolvedValue > requiredMin) {
|
|
286
|
+
requiredMin = resolvedValue;
|
|
287
|
+
}
|
|
288
|
+
break;
|
|
267
289
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
290
|
+
case 'maximum':
|
|
291
|
+
{
|
|
292
|
+
if (requiredMax === undefined || resolvedValue < requiredMax) {
|
|
293
|
+
requiredMax = resolvedValue;
|
|
294
|
+
}
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
case 'exact':
|
|
298
|
+
{
|
|
299
|
+
requiredExact = resolvedValue;
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
case 'must_include':
|
|
303
|
+
{
|
|
304
|
+
mustInclude = true;
|
|
305
|
+
break;
|
|
273
306
|
}
|
|
274
|
-
break;
|
|
275
|
-
}
|
|
276
|
-
case "exact": {
|
|
277
|
-
requiredExact = resolvedValue;
|
|
278
|
-
break;
|
|
279
|
-
}
|
|
280
|
-
case "must_include": {
|
|
281
|
-
mustInclude = true;
|
|
282
|
-
break;
|
|
283
|
-
}
|
|
284
307
|
}
|
|
285
308
|
}
|
|
286
|
-
const remainingMax = this.calculateRemainingMax(
|
|
287
|
-
|
|
288
|
-
requiredMax,
|
|
289
|
-
targets,
|
|
290
|
-
businessData
|
|
291
|
-
);
|
|
292
|
-
const formattedValidationMessage = this.formatValidationMessage(
|
|
293
|
-
validationMessage,
|
|
294
|
-
requiredMin,
|
|
295
|
-
requiredMax,
|
|
296
|
-
requiredExact
|
|
297
|
-
);
|
|
309
|
+
const remainingMax = this.calculateRemainingMax(scope, requiredMax, targets, businessData);
|
|
310
|
+
const formattedValidationMessage = this.formatValidationMessage(validationMessage, requiredMin, requiredMax, requiredExact);
|
|
298
311
|
return {
|
|
299
312
|
ruleId: action.id,
|
|
300
313
|
targetType,
|
|
@@ -309,6 +322,7 @@ var ItemRuleAdapter = class {
|
|
|
309
322
|
rawValidationMessage: validationMessage
|
|
310
323
|
};
|
|
311
324
|
}
|
|
325
|
+
|
|
312
326
|
/**
|
|
313
327
|
* 计算当前提交剩余可选的最大数量。
|
|
314
328
|
*
|
|
@@ -317,14 +331,14 @@ var ItemRuleAdapter = class {
|
|
|
317
331
|
* 其余场景返回 undefined,保持向后兼容。
|
|
318
332
|
*/
|
|
319
333
|
calculateRemainingMax(scope, requiredMax, targets, businessData) {
|
|
320
|
-
if (scope !==
|
|
321
|
-
return
|
|
334
|
+
if (scope !== 'cumulative' || typeof requiredMax !== 'number') {
|
|
335
|
+
return undefined;
|
|
322
336
|
}
|
|
323
337
|
const historicalItems = businessData.historicalItems;
|
|
324
|
-
if (!
|
|
338
|
+
if (!historicalItems?.length) {
|
|
325
339
|
return Math.max(0, requiredMax);
|
|
326
340
|
}
|
|
327
|
-
const targetIds = new Set(targets.map(
|
|
341
|
+
const targetIds = new Set(targets.map(t => t.product_id));
|
|
328
342
|
let historicalQty = 0;
|
|
329
343
|
for (const item of historicalItems) {
|
|
330
344
|
if (targetIds.has(item.product_id)) {
|
|
@@ -333,18 +347,18 @@ var ItemRuleAdapter = class {
|
|
|
333
347
|
}
|
|
334
348
|
return Math.max(0, requiredMax - historicalQty);
|
|
335
349
|
}
|
|
350
|
+
|
|
336
351
|
// ============================================
|
|
337
352
|
// Prefill Cart 处理
|
|
338
353
|
// ============================================
|
|
354
|
+
|
|
339
355
|
processPrefillCart(action, businessData) {
|
|
340
356
|
const config = action.config;
|
|
341
|
-
if (!
|
|
342
|
-
return [];
|
|
357
|
+
if (!config?.products) return [];
|
|
343
358
|
const results = [];
|
|
344
359
|
for (const prefillProduct of config.products) {
|
|
345
360
|
const quantity = this.resolvePrefillQuantity(prefillProduct.quantityFrom, prefillProduct.quantity, businessData);
|
|
346
|
-
if (quantity <= 0)
|
|
347
|
-
continue;
|
|
361
|
+
if (quantity <= 0) continue;
|
|
348
362
|
results.push({
|
|
349
363
|
ruleId: action.id,
|
|
350
364
|
product_id: prefillProduct.product_id,
|
|
@@ -354,24 +368,22 @@ var ItemRuleAdapter = class {
|
|
|
354
368
|
}
|
|
355
369
|
return results;
|
|
356
370
|
}
|
|
371
|
+
|
|
357
372
|
/**
|
|
358
373
|
* 根据 quantityFrom 计算预填数量
|
|
359
374
|
*/
|
|
360
375
|
resolvePrefillQuantity(quantityFrom, fixedValue, businessData) {
|
|
361
376
|
switch (quantityFrom) {
|
|
362
|
-
case
|
|
377
|
+
case 'total_pax':
|
|
363
378
|
return businessData.pax.total;
|
|
364
|
-
case
|
|
379
|
+
case 'adult_pax':
|
|
365
380
|
return businessData.pax.adult;
|
|
366
|
-
case
|
|
381
|
+
case 'fixed':
|
|
367
382
|
return fixedValue ?? 0;
|
|
368
383
|
default:
|
|
369
384
|
return fixedValue ?? 0;
|
|
370
385
|
}
|
|
371
386
|
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
0 && (module.exports = {
|
|
376
|
-
ItemRuleAdapter
|
|
377
|
-
});
|
|
387
|
+
}
|
|
388
|
+
exports.ItemRuleAdapter = ItemRuleAdapter;
|
|
389
|
+
var _default = exports.default = ItemRuleAdapter;
|
|
@@ -1,56 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __export = (target, all) => {
|
|
6
|
-
for (var name in all)
|
|
7
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
-
};
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (let key of __getOwnPropNames(from))
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
17
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
1
|
+
"use strict";
|
|
18
2
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
__export(evaluator_exports, {
|
|
22
|
-
ItemRuleEvaluator: () => ItemRuleEvaluator
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
23
5
|
});
|
|
24
|
-
|
|
25
|
-
var
|
|
26
|
-
var
|
|
27
|
-
var
|
|
28
|
-
|
|
6
|
+
exports.ItemRuleEvaluator = void 0;
|
|
7
|
+
var _engine = require("../../engine");
|
|
8
|
+
var _adapter = require("./adapter");
|
|
9
|
+
var _type = require("./type");
|
|
10
|
+
/**
|
|
11
|
+
* ItemRule 评估器
|
|
12
|
+
*
|
|
13
|
+
* 组合 StrategyEngine + ItemRuleAdapter,提供面向业务的高层 API。
|
|
14
|
+
* 支持批量评估多条 item_rule 策略配置,聚合数量校验和预填购物车结果。
|
|
15
|
+
*/
|
|
16
|
+
class ItemRuleEvaluator {
|
|
17
|
+
engine;
|
|
18
|
+
adapter;
|
|
19
|
+
strategyConfigs = [];
|
|
29
20
|
constructor() {
|
|
30
|
-
this.
|
|
31
|
-
this.engine = new import_engine.StrategyEngine({
|
|
21
|
+
this.engine = new _engine.StrategyEngine({
|
|
32
22
|
debug: false,
|
|
33
23
|
enableTrace: false
|
|
34
24
|
});
|
|
35
|
-
this.adapter = new
|
|
25
|
+
this.adapter = new _adapter.ItemRuleAdapter();
|
|
36
26
|
}
|
|
27
|
+
|
|
37
28
|
/**
|
|
38
29
|
* 设置策略配置列表
|
|
39
30
|
* 自动过滤 metadata.type === 'item_rule' 的配置
|
|
40
31
|
*/
|
|
41
32
|
setStrategyConfigs(configs) {
|
|
42
|
-
this.strategyConfigs = configs.filter(
|
|
43
|
-
(c) => c.metadata.type === "item_rule"
|
|
44
|
-
);
|
|
33
|
+
this.strategyConfigs = configs.filter(c => c.metadata.type === 'item_rule');
|
|
45
34
|
}
|
|
46
35
|
getStrategyConfigs() {
|
|
47
36
|
return this.strategyConfigs;
|
|
48
37
|
}
|
|
38
|
+
|
|
49
39
|
/**
|
|
50
40
|
* 完整评估:数量校验 + 预填购物车
|
|
51
41
|
*/
|
|
52
42
|
evaluate(businessData) {
|
|
53
|
-
const configs = businessData.strategyConfigs ? businessData.strategyConfigs.filter(
|
|
43
|
+
const configs = businessData.strategyConfigs ? businessData.strategyConfigs.filter(c => c.metadata.type === 'item_rule') : this.strategyConfigs;
|
|
54
44
|
const allQuantityChecks = [];
|
|
55
45
|
const allPrefillItems = [];
|
|
56
46
|
const rawResults = [];
|
|
@@ -58,14 +48,14 @@ var ItemRuleEvaluator = class {
|
|
|
58
48
|
for (const config of configs) {
|
|
59
49
|
const evalResult = this.engine.evaluate(config, context);
|
|
60
50
|
rawResults.push(evalResult);
|
|
61
|
-
const {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
);
|
|
51
|
+
const {
|
|
52
|
+
quantityChecks,
|
|
53
|
+
prefillItems
|
|
54
|
+
} = this.adapter.transformResult(evalResult, businessData);
|
|
65
55
|
allQuantityChecks.push(...quantityChecks);
|
|
66
56
|
allPrefillItems.push(...prefillItems);
|
|
67
57
|
}
|
|
68
|
-
const failedChecks = allQuantityChecks.filter(
|
|
58
|
+
const failedChecks = allQuantityChecks.filter(c => !c.passed);
|
|
69
59
|
return {
|
|
70
60
|
quantityChecks: allQuantityChecks,
|
|
71
61
|
prefillItems: allPrefillItems,
|
|
@@ -74,6 +64,7 @@ var ItemRuleEvaluator = class {
|
|
|
74
64
|
rawResults
|
|
75
65
|
};
|
|
76
66
|
}
|
|
67
|
+
|
|
77
68
|
/**
|
|
78
69
|
* 获取当前配置中各商品的数量限制
|
|
79
70
|
*
|
|
@@ -82,16 +73,14 @@ var ItemRuleEvaluator = class {
|
|
|
82
73
|
* 会评估条件是否满足、根据 scope + submissionIndex 过滤。
|
|
83
74
|
*/
|
|
84
75
|
getQuantityLimits(businessData) {
|
|
85
|
-
const configs = businessData.strategyConfigs ? businessData.strategyConfigs.filter(
|
|
76
|
+
const configs = businessData.strategyConfigs ? businessData.strategyConfigs.filter(c => c.metadata.type === 'item_rule') : this.strategyConfigs;
|
|
86
77
|
const results = [];
|
|
87
78
|
const context = this.adapter.prepareContext(businessData);
|
|
88
79
|
for (const config of configs) {
|
|
89
80
|
const evalResult = this.engine.evaluate(config, context);
|
|
90
|
-
if (!evalResult.applicable)
|
|
91
|
-
continue;
|
|
81
|
+
if (!evalResult.applicable) continue;
|
|
92
82
|
for (const action of evalResult.matchedActions) {
|
|
93
|
-
if (action.type !==
|
|
94
|
-
continue;
|
|
83
|
+
if (action.type !== _type.ITEM_RULE_ACTION_TYPES.QUANTITY_CHECK) continue;
|
|
95
84
|
const limit = this.adapter.extractQuantityLimits(action, businessData);
|
|
96
85
|
if (limit) {
|
|
97
86
|
results.push(limit);
|
|
@@ -100,6 +89,7 @@ var ItemRuleEvaluator = class {
|
|
|
100
89
|
}
|
|
101
90
|
return results;
|
|
102
91
|
}
|
|
92
|
+
|
|
103
93
|
/**
|
|
104
94
|
* 便捷方法:仅做数量校验,返回是否全部通过及失败详情
|
|
105
95
|
*/
|
|
@@ -110,6 +100,7 @@ var ItemRuleEvaluator = class {
|
|
|
110
100
|
failures: result.failedChecks
|
|
111
101
|
};
|
|
112
102
|
}
|
|
103
|
+
|
|
113
104
|
/**
|
|
114
105
|
* 便捷方法:仅获取需要预填到购物车的商品
|
|
115
106
|
*/
|
|
@@ -117,8 +108,5 @@ var ItemRuleEvaluator = class {
|
|
|
117
108
|
const result = this.evaluate(businessData);
|
|
118
109
|
return result.prefillItems;
|
|
119
110
|
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
0 && (module.exports = {
|
|
123
|
-
ItemRuleEvaluator
|
|
124
|
-
});
|
|
111
|
+
}
|
|
112
|
+
exports.ItemRuleEvaluator = ItemRuleEvaluator;
|