@bprotsyk/aso-core 2.1.133 → 2.1.140
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/lib/app/app.d.ts +16 -16
- package/lib/general/domain.d.ts +6 -2
- package/lib/general/domain.js +2 -1
- package/lib/general/namecheap-domain.d.ts +5 -5
- package/lib/keitaro/keitaro-conversions.d.ts +52 -0
- package/lib/keitaro/keitaro-conversions.js +27 -0
- package/lib/keitaro/keitaro-utils.d.ts +2 -0
- package/lib/keitaro/keitaro-utils.js +108 -0
- package/lib/keitaro-utils.d.ts +2 -0
- package/lib/keitaro-utils.js +136 -0
- package/lib/network/keitaro/traffle/traffle-keitaro-service.js +2 -3
- package/lib/offers/list.d.ts +5 -5
- package/lib/offers/offer.d.ts +6 -6
- package/lib/offers/section.d.ts +2 -2
- package/lib/panel/user.d.ts +5 -5
- package/lib/utils/comparing.d.ts +31 -0
- package/lib/utils/comparing.js +104 -0
- package/lib/utils/traffle-keitaro-utils.js +28 -38
- package/package.json +3 -1
- package/src/app/app.ts +0 -1
- package/src/general/domain.ts +3 -1
- package/src/network/keitaro/traffle/traffle-keitaro-service.ts +2 -3
- package/src/utils/traffle-keitaro-utils.ts +12 -34
- package/lib/templates/words.txt +0 -212
- package/tsc +0 -0
package/lib/app/app.d.ts
CHANGED
|
@@ -198,17 +198,17 @@ export declare enum PlugType {
|
|
|
198
198
|
}
|
|
199
199
|
export declare const AppSchema: mongoose.Schema<any, mongoose.Model<any, any, any, any, any, any>, {}, {}, {}, {}, mongoose.DefaultSchemaOptions, {
|
|
200
200
|
id: number;
|
|
201
|
-
type:
|
|
201
|
+
type: AppType;
|
|
202
202
|
geo: string[];
|
|
203
203
|
enabled: boolean;
|
|
204
204
|
proxied: boolean;
|
|
205
205
|
ech: boolean;
|
|
206
|
-
imageFormat:
|
|
207
|
-
status:
|
|
208
|
-
team:
|
|
206
|
+
imageFormat: EImageFormat;
|
|
207
|
+
status: AppStatus;
|
|
208
|
+
team: ETeam;
|
|
209
209
|
bundle: string;
|
|
210
210
|
trackingUrl: string;
|
|
211
|
-
integrationVersion:
|
|
211
|
+
integrationVersion: IntegrationVersion;
|
|
212
212
|
removeInfo: any;
|
|
213
213
|
policyPath: string;
|
|
214
214
|
name?: string | null | undefined;
|
|
@@ -242,17 +242,17 @@ export declare const AppSchema: mongoose.Schema<any, mongoose.Model<any, any, an
|
|
|
242
242
|
} | null | undefined;
|
|
243
243
|
}, mongoose.Document<unknown, {}, mongoose.FlatRecord<{
|
|
244
244
|
id: number;
|
|
245
|
-
type:
|
|
245
|
+
type: AppType;
|
|
246
246
|
geo: string[];
|
|
247
247
|
enabled: boolean;
|
|
248
248
|
proxied: boolean;
|
|
249
249
|
ech: boolean;
|
|
250
|
-
imageFormat:
|
|
251
|
-
status:
|
|
252
|
-
team:
|
|
250
|
+
imageFormat: EImageFormat;
|
|
251
|
+
status: AppStatus;
|
|
252
|
+
team: ETeam;
|
|
253
253
|
bundle: string;
|
|
254
254
|
trackingUrl: string;
|
|
255
|
-
integrationVersion:
|
|
255
|
+
integrationVersion: IntegrationVersion;
|
|
256
256
|
removeInfo: any;
|
|
257
257
|
policyPath: string;
|
|
258
258
|
name?: string | null | undefined;
|
|
@@ -284,19 +284,19 @@ export declare const AppSchema: mongoose.Schema<any, mongoose.Model<any, any, an
|
|
|
284
284
|
name?: string | null | undefined;
|
|
285
285
|
clouflareZone?: string | null | undefined;
|
|
286
286
|
} | null | undefined;
|
|
287
|
-
}>> & mongoose.FlatRecord<{
|
|
287
|
+
}>, {}, mongoose.ResolveSchemaOptions<mongoose.DefaultSchemaOptions>> & mongoose.FlatRecord<{
|
|
288
288
|
id: number;
|
|
289
|
-
type:
|
|
289
|
+
type: AppType;
|
|
290
290
|
geo: string[];
|
|
291
291
|
enabled: boolean;
|
|
292
292
|
proxied: boolean;
|
|
293
293
|
ech: boolean;
|
|
294
|
-
imageFormat:
|
|
295
|
-
status:
|
|
296
|
-
team:
|
|
294
|
+
imageFormat: EImageFormat;
|
|
295
|
+
status: AppStatus;
|
|
296
|
+
team: ETeam;
|
|
297
297
|
bundle: string;
|
|
298
298
|
trackingUrl: string;
|
|
299
|
-
integrationVersion:
|
|
299
|
+
integrationVersion: IntegrationVersion;
|
|
300
300
|
removeInfo: any;
|
|
301
301
|
policyPath: string;
|
|
302
302
|
name?: string | null | undefined;
|
package/lib/general/domain.d.ts
CHANGED
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
/// <reference types="mongoose/types/populate" />
|
|
16
16
|
/// <reference types="mongoose/types/query" />
|
|
17
17
|
/// <reference types="mongoose/types/schemaoptions" />
|
|
18
|
-
/// <reference types="mongoose/types/schematypes" />
|
|
19
18
|
/// <reference types="mongoose/types/session" />
|
|
20
19
|
/// <reference types="mongoose/types/types" />
|
|
21
20
|
/// <reference types="mongoose/types/utility" />
|
|
22
21
|
/// <reference types="mongoose/types/validation" />
|
|
23
22
|
/// <reference types="mongoose/types/virtuals" />
|
|
23
|
+
/// <reference types="mongoose/types/schematypes" />
|
|
24
24
|
/// <reference types="mongoose/types/inferschematype" />
|
|
25
25
|
/// <reference types="mongoose/types/inferrawdoctype" />
|
|
26
26
|
import { ICloudflareDomainType } from "general/cloudflare-domain";
|
|
@@ -53,6 +53,7 @@ export interface IDomain extends Document {
|
|
|
53
53
|
note: string;
|
|
54
54
|
proxied: boolean;
|
|
55
55
|
appid: number;
|
|
56
|
+
expirationMessageSent?: boolean;
|
|
56
57
|
}
|
|
57
58
|
export interface IDomainsBuyRequestResponse {
|
|
58
59
|
requestId: string;
|
|
@@ -86,6 +87,7 @@ export declare const DomainSchema: Schema<any, Model<any, any, any, any, any, an
|
|
|
86
87
|
originalNameServers: string[];
|
|
87
88
|
txtRecords: string[];
|
|
88
89
|
assignedTo: number[];
|
|
90
|
+
expirationMessageSent: boolean;
|
|
89
91
|
id?: string | null | undefined;
|
|
90
92
|
name?: string | null | undefined;
|
|
91
93
|
type?: string | null | undefined;
|
|
@@ -113,6 +115,7 @@ export declare const DomainSchema: Schema<any, Model<any, any, any, any, any, an
|
|
|
113
115
|
originalNameServers: string[];
|
|
114
116
|
txtRecords: string[];
|
|
115
117
|
assignedTo: number[];
|
|
118
|
+
expirationMessageSent: boolean;
|
|
116
119
|
id?: string | null | undefined;
|
|
117
120
|
name?: string | null | undefined;
|
|
118
121
|
type?: string | null | undefined;
|
|
@@ -135,11 +138,12 @@ export declare const DomainSchema: Schema<any, Model<any, any, any, any, any, an
|
|
|
135
138
|
archived?: boolean | null | undefined;
|
|
136
139
|
note?: string | null | undefined;
|
|
137
140
|
appid?: number | null | undefined;
|
|
138
|
-
}>> & import("mongoose").FlatRecord<{
|
|
141
|
+
}>, {}, import("mongoose").ResolveSchemaOptions<import("mongoose").DefaultSchemaOptions>> & import("mongoose").FlatRecord<{
|
|
139
142
|
nameServers: string[];
|
|
140
143
|
originalNameServers: string[];
|
|
141
144
|
txtRecords: string[];
|
|
142
145
|
assignedTo: number[];
|
|
146
|
+
expirationMessageSent: boolean;
|
|
143
147
|
id?: string | null | undefined;
|
|
144
148
|
name?: string | null | undefined;
|
|
145
149
|
type?: string | null | undefined;
|
package/lib/general/domain.js
CHANGED
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
/// <reference types="mongoose/types/populate" />
|
|
16
16
|
/// <reference types="mongoose/types/query" />
|
|
17
17
|
/// <reference types="mongoose/types/schemaoptions" />
|
|
18
|
-
/// <reference types="mongoose/types/schematypes" />
|
|
19
18
|
/// <reference types="mongoose/types/session" />
|
|
20
19
|
/// <reference types="mongoose/types/types" />
|
|
21
20
|
/// <reference types="mongoose/types/utility" />
|
|
22
21
|
/// <reference types="mongoose/types/validation" />
|
|
23
22
|
/// <reference types="mongoose/types/virtuals" />
|
|
23
|
+
/// <reference types="mongoose/types/schematypes" />
|
|
24
24
|
/// <reference types="mongoose/types/inferschematype" />
|
|
25
25
|
/// <reference types="mongoose/types/inferrawdoctype" />
|
|
26
26
|
import { Schema, Document } from "mongoose";
|
|
@@ -79,7 +79,7 @@ export declare const NamecheapBuyRequestSchema: Schema<any, import("mongoose").M
|
|
|
79
79
|
name?: string | null | undefined;
|
|
80
80
|
price?: number | null | undefined;
|
|
81
81
|
available?: boolean | null | undefined;
|
|
82
|
-
}, import("mongoose").Types.Subdocument<import("
|
|
82
|
+
}, import("mongoose").Types.Subdocument<import("bson").ObjectId, any, {
|
|
83
83
|
name?: string | null | undefined;
|
|
84
84
|
price?: number | null | undefined;
|
|
85
85
|
available?: boolean | null | undefined;
|
|
@@ -96,7 +96,7 @@ export declare const NamecheapBuyRequestSchema: Schema<any, import("mongoose").M
|
|
|
96
96
|
name?: string | null | undefined;
|
|
97
97
|
price?: number | null | undefined;
|
|
98
98
|
available?: boolean | null | undefined;
|
|
99
|
-
}, import("mongoose").Types.Subdocument<import("
|
|
99
|
+
}, import("mongoose").Types.Subdocument<import("bson").ObjectId, any, {
|
|
100
100
|
name?: string | null | undefined;
|
|
101
101
|
price?: number | null | undefined;
|
|
102
102
|
available?: boolean | null | undefined;
|
|
@@ -108,12 +108,12 @@ export declare const NamecheapBuyRequestSchema: Schema<any, import("mongoose").M
|
|
|
108
108
|
id?: string | null | undefined;
|
|
109
109
|
ip?: string | null | undefined;
|
|
110
110
|
fullfilled?: boolean | null | undefined;
|
|
111
|
-
}>> & import("mongoose").FlatRecord<{
|
|
111
|
+
}>, {}, import("mongoose").ResolveSchemaOptions<import("mongoose").DefaultSchemaOptions>> & import("mongoose").FlatRecord<{
|
|
112
112
|
domains: import("mongoose").Types.DocumentArray<{
|
|
113
113
|
name?: string | null | undefined;
|
|
114
114
|
price?: number | null | undefined;
|
|
115
115
|
available?: boolean | null | undefined;
|
|
116
|
-
}, import("mongoose").Types.Subdocument<import("
|
|
116
|
+
}, import("mongoose").Types.Subdocument<import("bson").ObjectId, any, {
|
|
117
117
|
name?: string | null | undefined;
|
|
118
118
|
price?: number | null | undefined;
|
|
119
119
|
available?: boolean | null | undefined;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { KeitaroClicksInterval } from './keitaro-clicks';
|
|
2
|
+
export declare enum KeitaroOperator {
|
|
3
|
+
EQUALS = "EQUALS",
|
|
4
|
+
NOT_EQUAL = "NOT_EQUAL",
|
|
5
|
+
EQUALS_OR_GREATER_THAN = "EQUALS_OR_GREATER_THAN",
|
|
6
|
+
EQUALS_OR_LESS_THAN = "EQUALS_OR_LESS_THAN",
|
|
7
|
+
GREATER_THAN = "GREATER_THAN",
|
|
8
|
+
LESS_THAN = "LESS_THAN",
|
|
9
|
+
MATCH_REGEXP = "MATCH_REGEXP",
|
|
10
|
+
NOT_MATCH_REGEXP = "NOT_MATCH_REGEXP",
|
|
11
|
+
BEGINS_WITH = "BEGINS_WITH",
|
|
12
|
+
ENDS_WITH = "ENDS_WITH",
|
|
13
|
+
CONTAINS = "CONTAINS",
|
|
14
|
+
NOT_CONTAIN = "NOT_CONTAIN",
|
|
15
|
+
IN_LIST = "IN_LIST",
|
|
16
|
+
NOT_IN_LIST = "NOT_IN_LIST",
|
|
17
|
+
BETWEEN = "BETWEEN",
|
|
18
|
+
IS_SET = "IS_SET",
|
|
19
|
+
IS_NOT_SET = "IS_NOT_SET",
|
|
20
|
+
IS_TRUE = "IS_TRUE",
|
|
21
|
+
IS_FALSE = "IS_FALSE",
|
|
22
|
+
HAS_LABEL = "HAS_LABEL",
|
|
23
|
+
NOT_HAS_LABEL = "NOT_HAS_LABEL"
|
|
24
|
+
}
|
|
25
|
+
export interface IKeitaroConversionRangeRequest {
|
|
26
|
+
from?: string;
|
|
27
|
+
to?: string;
|
|
28
|
+
timezone?: string;
|
|
29
|
+
interval?: KeitaroClicksInterval;
|
|
30
|
+
}
|
|
31
|
+
export interface IKeitaroConversionFilterRequest {
|
|
32
|
+
name: string;
|
|
33
|
+
operator: KeitaroOperator;
|
|
34
|
+
expression?: string | number | Array<string | number>;
|
|
35
|
+
}
|
|
36
|
+
export interface IKeitaroConversionSortRequest {
|
|
37
|
+
name: string;
|
|
38
|
+
order: 'ASC' | 'DESC';
|
|
39
|
+
}
|
|
40
|
+
export interface IKeitaroConversionsRequest {
|
|
41
|
+
range: IKeitaroConversionRangeRequest;
|
|
42
|
+
limit?: number;
|
|
43
|
+
offset?: number;
|
|
44
|
+
columns?: string[];
|
|
45
|
+
filters?: IKeitaroConversionFilterRequest[];
|
|
46
|
+
sort?: IKeitaroConversionSortRequest[];
|
|
47
|
+
}
|
|
48
|
+
export interface IKeitaroConversionsResponse {
|
|
49
|
+
rows: any[];
|
|
50
|
+
total: number;
|
|
51
|
+
meta: string[];
|
|
52
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KeitaroOperator = void 0;
|
|
4
|
+
var KeitaroOperator;
|
|
5
|
+
(function (KeitaroOperator) {
|
|
6
|
+
KeitaroOperator["EQUALS"] = "EQUALS";
|
|
7
|
+
KeitaroOperator["NOT_EQUAL"] = "NOT_EQUAL";
|
|
8
|
+
KeitaroOperator["EQUALS_OR_GREATER_THAN"] = "EQUALS_OR_GREATER_THAN";
|
|
9
|
+
KeitaroOperator["EQUALS_OR_LESS_THAN"] = "EQUALS_OR_LESS_THAN";
|
|
10
|
+
KeitaroOperator["GREATER_THAN"] = "GREATER_THAN";
|
|
11
|
+
KeitaroOperator["LESS_THAN"] = "LESS_THAN";
|
|
12
|
+
KeitaroOperator["MATCH_REGEXP"] = "MATCH_REGEXP";
|
|
13
|
+
KeitaroOperator["NOT_MATCH_REGEXP"] = "NOT_MATCH_REGEXP";
|
|
14
|
+
KeitaroOperator["BEGINS_WITH"] = "BEGINS_WITH";
|
|
15
|
+
KeitaroOperator["ENDS_WITH"] = "ENDS_WITH";
|
|
16
|
+
KeitaroOperator["CONTAINS"] = "CONTAINS";
|
|
17
|
+
KeitaroOperator["NOT_CONTAIN"] = "NOT_CONTAIN";
|
|
18
|
+
KeitaroOperator["IN_LIST"] = "IN_LIST";
|
|
19
|
+
KeitaroOperator["NOT_IN_LIST"] = "NOT_IN_LIST";
|
|
20
|
+
KeitaroOperator["BETWEEN"] = "BETWEEN";
|
|
21
|
+
KeitaroOperator["IS_SET"] = "IS_SET";
|
|
22
|
+
KeitaroOperator["IS_NOT_SET"] = "IS_NOT_SET";
|
|
23
|
+
KeitaroOperator["IS_TRUE"] = "IS_TRUE";
|
|
24
|
+
KeitaroOperator["IS_FALSE"] = "IS_FALSE";
|
|
25
|
+
KeitaroOperator["HAS_LABEL"] = "HAS_LABEL";
|
|
26
|
+
KeitaroOperator["NOT_HAS_LABEL"] = "NOT_HAS_LABEL";
|
|
27
|
+
})(KeitaroOperator = exports.KeitaroOperator || (exports.KeitaroOperator = {}));
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.displayComparisonResults = void 0;
|
|
4
|
+
function displayComparisonResults(comparison) {
|
|
5
|
+
const isValidStatus = (status) => ['sale', 'rebill'].includes(status);
|
|
6
|
+
let wpTotalSum = comparison.wpConversions
|
|
7
|
+
.reduce((sum, conv) => sum + conv.sum, 0);
|
|
8
|
+
let keitaroTotalSum = comparison.keitaroConversions
|
|
9
|
+
.filter(conv => isValidStatus(conv.status))
|
|
10
|
+
.reduce((sum, conv) => sum + (parseFloat(conv.revenue) || 0), 0);
|
|
11
|
+
// Get all Keitaro rejected conversions
|
|
12
|
+
const allKeitaroRejected = [
|
|
13
|
+
...comparison.rejected.keitaro,
|
|
14
|
+
...comparison.matches
|
|
15
|
+
.filter(match => match.keitaro.status === 'rejected')
|
|
16
|
+
.map(match => match.keitaro)
|
|
17
|
+
];
|
|
18
|
+
// Group mismatches by project/offer
|
|
19
|
+
const wpMismatchesByProject = new Map();
|
|
20
|
+
const keitaroMismatchesByOffer = new Map();
|
|
21
|
+
const rejectedByOffer = new Map();
|
|
22
|
+
comparison.mismatches.onlyInWP.forEach(conv => {
|
|
23
|
+
if (!wpMismatchesByProject.has(conv.project)) {
|
|
24
|
+
wpMismatchesByProject.set(conv.project, { count: 0, sum: 0, conversions: [] });
|
|
25
|
+
}
|
|
26
|
+
const projectStats = wpMismatchesByProject.get(conv.project);
|
|
27
|
+
projectStats.count++;
|
|
28
|
+
projectStats.sum += conv.sum;
|
|
29
|
+
projectStats.conversions.push(conv);
|
|
30
|
+
});
|
|
31
|
+
// Include all conversions in mismatches, including rejected ones
|
|
32
|
+
[...comparison.mismatches.onlyInKeitaro, ...allKeitaroRejected].forEach(conv => {
|
|
33
|
+
if (!keitaroMismatchesByOffer.has(conv.offer)) {
|
|
34
|
+
keitaroMismatchesByOffer.set(conv.offer, { count: 0, sum: 0, conversions: [] });
|
|
35
|
+
}
|
|
36
|
+
const offerStats = keitaroMismatchesByOffer.get(conv.offer);
|
|
37
|
+
offerStats.count++;
|
|
38
|
+
offerStats.sum += parseFloat(conv.revenue) || 0;
|
|
39
|
+
offerStats.conversions.push(conv);
|
|
40
|
+
});
|
|
41
|
+
// Group rejected conversions by offer
|
|
42
|
+
allKeitaroRejected.forEach(conv => {
|
|
43
|
+
if (!rejectedByOffer.has(conv.offer)) {
|
|
44
|
+
rejectedByOffer.set(conv.offer, { count: 0, sum: 0, conversions: [] });
|
|
45
|
+
}
|
|
46
|
+
const offerStats = rejectedByOffer.get(conv.offer);
|
|
47
|
+
offerStats.count++;
|
|
48
|
+
offerStats.sum += parseFloat(conv.revenue) || 0;
|
|
49
|
+
offerStats.conversions.push(conv);
|
|
50
|
+
});
|
|
51
|
+
console.log('\n\x1b[1mЗагальна статистика:\x1b[0m');
|
|
52
|
+
console.log(`Всього конверсій у WP: ${comparison.wpConversions.length} (Сума: \x1b[33m$${wpTotalSum.toFixed(2)}\x1b[0m)`);
|
|
53
|
+
console.log(`Всього конверсій у Keitaro: ${comparison.keitaroConversions.filter(conv => isValidStatus(conv.status)).length} (Сума: \x1b[33m$${keitaroTotalSum.toFixed(2)}\x1b[0m)`);
|
|
54
|
+
console.log(`Співпадінь: ${comparison.matches.length}`);
|
|
55
|
+
console.log(`Відхилених конверсій: ${allKeitaroRejected.length}`);
|
|
56
|
+
const totalDiff = Math.abs(wpTotalSum - keitaroTotalSum);
|
|
57
|
+
console.log(`\x1b[1mЗагальна різниця:\x1b[0m \x1b[33m$${totalDiff.toFixed(2)}\x1b[0m`);
|
|
58
|
+
// Always show rejected conversions first if there are any
|
|
59
|
+
if (allKeitaroRejected.length > 0) {
|
|
60
|
+
const rejectedTotal = allKeitaroRejected.reduce((sum, conv) => sum + (parseFloat(conv.revenue) || 0), 0);
|
|
61
|
+
console.log('\n\x1b[1mВідхилені конверсії в Keitaro за офферами:\x1b[0m');
|
|
62
|
+
console.log(`Загальна кількість: ${allKeitaroRejected.length}`);
|
|
63
|
+
console.log(`Загальна сума: \x1b[33m$${rejectedTotal.toFixed(2)}\x1b[0m`);
|
|
64
|
+
for (const [offer, stats] of rejectedByOffer.entries()) {
|
|
65
|
+
console.log(`\n\x1b[33m${offer}:\x1b[0m`);
|
|
66
|
+
console.log(`Кількість: ${stats.count}, Сума: $${stats.sum.toFixed(2)}`);
|
|
67
|
+
stats.conversions.forEach(conv => {
|
|
68
|
+
const matchMark = comparison.matches.some(match => match.keitaro.sub_id === conv.sub_id) ? '[matched] ' : '';
|
|
69
|
+
console.log(` ${matchMark}${conv.sub_id} | ${conv.sale_datetime.split(' ')[0]} | $${conv.revenue}`);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
console.log('\n\x1b[1mВідсутні в Keitaro за проектами:\x1b[0m');
|
|
74
|
+
for (const [project, stats] of wpMismatchesByProject) {
|
|
75
|
+
console.log(`\n\x1b[31m${project}:\x1b[0m`);
|
|
76
|
+
console.log(`Кількість: ${stats.count}, Сума: $${stats.sum.toFixed(2)}`);
|
|
77
|
+
stats.conversions.forEach(conv => {
|
|
78
|
+
console.log(` ${conv.clickId} | ${conv.regDate.toISOString().split('T')[0]} | $${conv.sum}`);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
console.log('\n\x1b[1mВідсутні в WP за офферами:\x1b[0m');
|
|
82
|
+
for (const [offer, stats] of keitaroMismatchesByOffer) {
|
|
83
|
+
console.log(`\n\x1b[32m${offer}:\x1b[0m`);
|
|
84
|
+
console.log(`Кількість: ${stats.count}, Сума: $${stats.sum.toFixed(2)}`);
|
|
85
|
+
stats.conversions.forEach(conv => {
|
|
86
|
+
const statusMark = conv.status === 'rejected' ? '(rejected) ' : '';
|
|
87
|
+
const matchMark = comparison.matches.some(match => match.keitaro.sub_id === conv.sub_id) ? '[matched] ' : '';
|
|
88
|
+
console.log(` ${statusMark}${matchMark}${conv.sub_id} | ${conv.sale_datetime.split(' ')[0]} | $${conv.revenue}`);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
let mismatchWPSum = comparison.mismatches.onlyInWP
|
|
92
|
+
.reduce((sum, conv) => sum + conv.sum, 0);
|
|
93
|
+
let mismatchKeitaroSum = [...comparison.mismatches.onlyInKeitaro, ...allKeitaroRejected]
|
|
94
|
+
.reduce((sum, conv) => sum + (parseFloat(conv.revenue) || 0), 0);
|
|
95
|
+
console.log('\n\x1b[1mПідсумок розбіжностей:\x1b[0m');
|
|
96
|
+
console.log(`Сума відсутніх в Keitaro: \x1b[31m$${mismatchWPSum.toFixed(2)}\x1b[0m`);
|
|
97
|
+
console.log(`Сума відсутніх в WP: \x1b[32m$${mismatchKeitaroSum.toFixed(2)}\x1b[0m`);
|
|
98
|
+
console.log(`Різниця у відсутніх конверсіях: \x1b[33m$${Math.abs(mismatchWPSum - mismatchKeitaroSum).toFixed(2)}\x1b[0m`);
|
|
99
|
+
// Debug information
|
|
100
|
+
const matchingRejected = comparison.matches.filter(match => match.keitaro.status === 'rejected').length;
|
|
101
|
+
console.log('\n\x1b[1mДебаг інформація:\x1b[0m');
|
|
102
|
+
console.log(`Кількість конверсій відсутніх в WP: ${comparison.mismatches.onlyInKeitaro.length + comparison.rejected.keitaro.length + matchingRejected}`);
|
|
103
|
+
console.log(`З них:`);
|
|
104
|
+
console.log(`- Активних: ${comparison.mismatches.onlyInKeitaro.length}`);
|
|
105
|
+
console.log(`- Відхилених (унікальних): ${comparison.rejected.keitaro.length}`);
|
|
106
|
+
console.log(`- Відхилених (що є в WP): ${matchingRejected}`);
|
|
107
|
+
}
|
|
108
|
+
exports.displayComparisonResults = displayComparisonResults;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.displayComparisonResults = void 0;
|
|
27
|
+
const keitaro_service_1 = require("./network/keitaro/keitaro-service");
|
|
28
|
+
const keitaro_conversions_1 = require("./keitaro/keitaro-conversions");
|
|
29
|
+
const path = __importStar(require("path"));
|
|
30
|
+
const comparing_1 = require("./utils/comparing");
|
|
31
|
+
function displayComparisonResults(comparison) {
|
|
32
|
+
const isValidStatus = (status) => ['sale', 'rebill'].includes(status);
|
|
33
|
+
// Считаем общие суммы
|
|
34
|
+
let wpTotalSum = comparison.wpConversions
|
|
35
|
+
.reduce((sum, conv) => sum + conv.sum, 0);
|
|
36
|
+
let keitaroTotalSum = comparison.keitaroConversions
|
|
37
|
+
.filter((conv) => isValidStatus(conv.status))
|
|
38
|
+
.reduce((sum, conv) => sum + (parseFloat(conv.revenue) || 0), 0);
|
|
39
|
+
// Находим разницу
|
|
40
|
+
const totalDiff = keitaroTotalSum - wpTotalSum;
|
|
41
|
+
console.log('\n\x1b[1mЗагальна статистика:\x1b[0m');
|
|
42
|
+
console.log(`WP сума: $${wpTotalSum.toFixed(2)}`);
|
|
43
|
+
console.log(`Keitaro сума: $${keitaroTotalSum.toFixed(2)}`);
|
|
44
|
+
console.log(`Різниця: $${totalDiff.toFixed(2)}`);
|
|
45
|
+
// Получаем конверсии, которые есть в Keitaro, но нет в WP
|
|
46
|
+
const extraKeitaroConversions = comparison.mismatches.onlyInKeitaro
|
|
47
|
+
.filter(conv => isValidStatus(conv.status))
|
|
48
|
+
.sort((a, b) => (parseFloat(b.revenue) || 0) - (parseFloat(a.revenue) || 0));
|
|
49
|
+
// Группируем по офферам для удобства
|
|
50
|
+
const byOffer = new Map();
|
|
51
|
+
extraKeitaroConversions.forEach(conv => {
|
|
52
|
+
const offer = conv.offer || 'Unknown Offer';
|
|
53
|
+
if (!byOffer.has(offer)) {
|
|
54
|
+
byOffer.set(offer, { count: 0, sum: 0, conversions: [] });
|
|
55
|
+
}
|
|
56
|
+
const stats = byOffer.get(offer);
|
|
57
|
+
const revenue = parseFloat(conv.revenue) || 0;
|
|
58
|
+
stats.count++;
|
|
59
|
+
stats.sum += revenue;
|
|
60
|
+
stats.conversions.push(conv);
|
|
61
|
+
});
|
|
62
|
+
console.log('\n\x1b[1mКонверсії, які є в Keitaro, але відсутні в WP:\x1b[0m');
|
|
63
|
+
let totalExtraSum = 0;
|
|
64
|
+
for (const [offer, stats] of byOffer) {
|
|
65
|
+
console.log(`\n\x1b[33m${offer}:\x1b[0m`);
|
|
66
|
+
console.log(`Кількість: ${stats.count}, Сума: $${stats.sum.toFixed(2)}`);
|
|
67
|
+
stats.conversions.forEach(conv => {
|
|
68
|
+
if (conv.sub_id && conv.revenue) {
|
|
69
|
+
console.log(` ${conv.sub_id} | ${conv.revenue}`);
|
|
70
|
+
totalExtraSum += parseFloat(conv.revenue) || 0;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
console.log('\n\x1b[1mПідсумок:\x1b[0m');
|
|
75
|
+
console.log(`Загальна сума "зайвих" конверсій: \x1b[33m$${totalExtraSum.toFixed(2)}\x1b[0m`);
|
|
76
|
+
console.log('Це конверсії, які потрібно видалити з Keitaro, щоб суми співпадали з WP');
|
|
77
|
+
}
|
|
78
|
+
exports.displayComparisonResults = displayComparisonResults;
|
|
79
|
+
// Self-executing function to fetch and compare conversions
|
|
80
|
+
(async () => {
|
|
81
|
+
const request = {
|
|
82
|
+
range: {
|
|
83
|
+
from: '2025-01-01',
|
|
84
|
+
to: '2025-01-31',
|
|
85
|
+
timezone: 'Europe/Kyiv'
|
|
86
|
+
},
|
|
87
|
+
filters: [
|
|
88
|
+
{
|
|
89
|
+
name: 'status',
|
|
90
|
+
operator: keitaro_conversions_1.KeitaroOperator.IN_LIST,
|
|
91
|
+
expression: ['sale', 'rejected']
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'affiliate_network_id',
|
|
95
|
+
operator: keitaro_conversions_1.KeitaroOperator.EQUALS,
|
|
96
|
+
expression: 2
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
columns: [
|
|
100
|
+
'sign', 'version', 'campaign', 'campaign_group', 'landing_group', 'offer_group',
|
|
101
|
+
'landing', 'offer', 'affiliate_network', 'ts', 'stream', 'source',
|
|
102
|
+
'x_requested_with', 'referrer', 'search_engine', 'keyword', 'click_id',
|
|
103
|
+
'sub_id', 'visitor_code', 'campaign_id', 'campaign_group_id', 'offer_group_id',
|
|
104
|
+
'landing_group_id', 'landing_id', 'offer_id', 'affiliate_network_id', 'ts_id',
|
|
105
|
+
'stream_id', 'ad_campaign_id', 'external_id', 'creative_id',
|
|
106
|
+
'sub_id_1', 'sub_id_2', 'sub_id_3', 'sub_id_4', 'sub_id_5',
|
|
107
|
+
'sub_id_6', 'sub_id_7', 'sub_id_8', 'sub_id_9', 'sub_id_10',
|
|
108
|
+
'sub_id_11', 'sub_id_12', 'sub_id_13', 'sub_id_14', 'sub_id_15',
|
|
109
|
+
'sub_id_16', 'sub_id_17', 'sub_id_18', 'sub_id_19', 'sub_id_20',
|
|
110
|
+
'sub_id_21', 'sub_id_22', 'sub_id_23', 'sub_id_24', 'sub_id_25',
|
|
111
|
+
'sub_id_26', 'sub_id_27', 'sub_id_28', 'sub_id_29', 'sub_id_30',
|
|
112
|
+
'connection_type', 'operator', 'isp', 'country_code', 'country_flag',
|
|
113
|
+
'country', 'region', 'region_code', 'city', 'language', 'device_type',
|
|
114
|
+
'user_agent', 'os_icon', 'os', 'os_version', 'browser', 'browser_version',
|
|
115
|
+
'device_model', 'browser_icon', 'ip', 'ip_mask1', 'ip_mask2', 'ipv4only',
|
|
116
|
+
'ipv6only', 'cost', 'postback_datetime', 'sale_datetime', 'click_datetime',
|
|
117
|
+
'sale_period', 'status', 'previous_status', 'original_status',
|
|
118
|
+
'previous_conversion_id', 'params', 'conversion_id', 'tid',
|
|
119
|
+
'profitability', 'revenue', 'profit'
|
|
120
|
+
],
|
|
121
|
+
sort: [{
|
|
122
|
+
name: 'sale_datetime',
|
|
123
|
+
order: 'DESC'
|
|
124
|
+
}]
|
|
125
|
+
};
|
|
126
|
+
try {
|
|
127
|
+
const conversions = await keitaro_service_1.KeitaroService.getConversions(request);
|
|
128
|
+
const wpFilePath = path.join(process.cwd(), 'src', 'utils', 'wp-january.csv');
|
|
129
|
+
const comparison = await (0, comparing_1.compareConversions)(wpFilePath, conversions);
|
|
130
|
+
// Use our improved display function
|
|
131
|
+
displayComparisonResults(comparison);
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
console.error('Error fetching conversions:', error);
|
|
135
|
+
}
|
|
136
|
+
})();
|
|
@@ -151,7 +151,7 @@ async function addOffersToTraffleKeitaro(offers) {
|
|
|
151
151
|
let name = `${offer.offer.caption} ${offer.offer.geo} [el trafico] ${offer.trafficType}`;
|
|
152
152
|
const identicalOffer = allOffers.find(o => o.name.includes(name));
|
|
153
153
|
let offersGroupId = findMatchingOffersGroup(offersGroups, offer);
|
|
154
|
-
let affiliateId = await findMatchingAffiliateId(affiliateNetworks, offer)
|
|
154
|
+
let affiliateId = 160; // await findMatchingAffiliateId(affiliateNetworks, offer)
|
|
155
155
|
if (!identicalOffer) {
|
|
156
156
|
const offerPayload = {
|
|
157
157
|
name: name,
|
|
@@ -467,8 +467,7 @@ async function updateAppWithCampaignParams(existingCampaign, app, platform) {
|
|
|
467
467
|
async function cloneTraffleCampaign(app, platform, addDefaultStreams) {
|
|
468
468
|
const ORIGINAL_CLONE_CAMPAIGN_ID = 1925;
|
|
469
469
|
const appsflyerAvailability = app.platforms[platform].appsflyerParams?.apiToken ? "[AF]" : "";
|
|
470
|
-
|
|
471
|
-
let name = `[${app.id}] [${app.bundle}] ET [${app.name}] [Volodymyr Vinnik] [Android] ${appsflyerAvailability} ${app.domainParams.name}`;
|
|
470
|
+
let name = `[${app.id}] [${app.bundle}] ${app.name} [Volodymyr Vinnik] [El Trafico] [Android] ${appsflyerAvailability} ${app.domainParams.name}`;
|
|
472
471
|
let platformName = platform ? (0, app_1.getPlatformName)(platform) : null;
|
|
473
472
|
const platformCampaignName = `#${app.id} [➥] (${platformName})`;
|
|
474
473
|
const generateAlias = () => {
|
package/lib/offers/list.d.ts
CHANGED
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
/// <reference types="mongoose/types/populate" />
|
|
16
16
|
/// <reference types="mongoose/types/query" />
|
|
17
17
|
/// <reference types="mongoose/types/schemaoptions" />
|
|
18
|
-
/// <reference types="mongoose/types/schematypes" />
|
|
19
18
|
/// <reference types="mongoose/types/session" />
|
|
20
19
|
/// <reference types="mongoose/types/types" />
|
|
21
20
|
/// <reference types="mongoose/types/utility" />
|
|
22
21
|
/// <reference types="mongoose/types/validation" />
|
|
23
22
|
/// <reference types="mongoose/types/virtuals" />
|
|
23
|
+
/// <reference types="mongoose/types/schematypes" />
|
|
24
24
|
/// <reference types="mongoose/types/inferschematype" />
|
|
25
25
|
/// <reference types="mongoose/types/inferrawdoctype" />
|
|
26
26
|
import { Schema } from "mongoose";
|
|
@@ -85,7 +85,7 @@ export declare const SectionsListSchema: Schema<any, import("mongoose").Model<an
|
|
|
85
85
|
getOwnPropertyDescriptors?: {} | null | undefined;
|
|
86
86
|
fromEntries?: {} | null | undefined;
|
|
87
87
|
hasOwn?: {} | null | undefined;
|
|
88
|
-
}, import("mongoose").Types.Subdocument<import("
|
|
88
|
+
}, import("mongoose").Types.Subdocument<import("bson").ObjectId, any, {
|
|
89
89
|
prototype?: {
|
|
90
90
|
constructor: {
|
|
91
91
|
name?: unknown;
|
|
@@ -218,7 +218,7 @@ export declare const SectionsListSchema: Schema<any, import("mongoose").Model<an
|
|
|
218
218
|
getOwnPropertyDescriptors?: {} | null | undefined;
|
|
219
219
|
fromEntries?: {} | null | undefined;
|
|
220
220
|
hasOwn?: {} | null | undefined;
|
|
221
|
-
}, import("mongoose").Types.Subdocument<import("
|
|
221
|
+
}, import("mongoose").Types.Subdocument<import("bson").ObjectId, any, {
|
|
222
222
|
prototype?: {
|
|
223
223
|
constructor: {
|
|
224
224
|
name?: unknown;
|
|
@@ -305,7 +305,7 @@ export declare const SectionsListSchema: Schema<any, import("mongoose").Model<an
|
|
|
305
305
|
fromEntries?: {} | null | undefined;
|
|
306
306
|
hasOwn?: {} | null | undefined;
|
|
307
307
|
}>;
|
|
308
|
-
}>> & import("mongoose").FlatRecord<{
|
|
308
|
+
}>, {}, import("mongoose").ResolveSchemaOptions<import("mongoose").DefaultSchemaOptions>> & import("mongoose").FlatRecord<{
|
|
309
309
|
id: number;
|
|
310
310
|
name: string;
|
|
311
311
|
content: import("mongoose").Types.DocumentArray<{
|
|
@@ -351,7 +351,7 @@ export declare const SectionsListSchema: Schema<any, import("mongoose").Model<an
|
|
|
351
351
|
getOwnPropertyDescriptors?: {} | null | undefined;
|
|
352
352
|
fromEntries?: {} | null | undefined;
|
|
353
353
|
hasOwn?: {} | null | undefined;
|
|
354
|
-
}, import("mongoose").Types.Subdocument<import("
|
|
354
|
+
}, import("mongoose").Types.Subdocument<import("bson").ObjectId, any, {
|
|
355
355
|
prototype?: {
|
|
356
356
|
constructor: {
|
|
357
357
|
name?: unknown;
|
package/lib/offers/offer.d.ts
CHANGED
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
/// <reference types="mongoose/types/populate" />
|
|
16
16
|
/// <reference types="mongoose/types/query" />
|
|
17
17
|
/// <reference types="mongoose/types/schemaoptions" />
|
|
18
|
-
/// <reference types="mongoose/types/schematypes" />
|
|
19
18
|
/// <reference types="mongoose/types/session" />
|
|
20
19
|
/// <reference types="mongoose/types/types" />
|
|
21
20
|
/// <reference types="mongoose/types/utility" />
|
|
22
21
|
/// <reference types="mongoose/types/validation" />
|
|
23
22
|
/// <reference types="mongoose/types/virtuals" />
|
|
23
|
+
/// <reference types="mongoose/types/schematypes" />
|
|
24
24
|
/// <reference types="mongoose/types/inferschematype" />
|
|
25
25
|
/// <reference types="mongoose/types/inferrawdoctype" />
|
|
26
26
|
import { Document, Model, Schema } from "mongoose";
|
|
@@ -70,7 +70,7 @@ export declare const PartnerSchema: Schema<any, Model<any, any, any, any, any, a
|
|
|
70
70
|
partnerId?: number | null | undefined;
|
|
71
71
|
shortName?: string | null | undefined;
|
|
72
72
|
name?: string | null | undefined;
|
|
73
|
-
}>> & import("mongoose").FlatRecord<{
|
|
73
|
+
}>, {}, import("mongoose").ResolveSchemaOptions<import("mongoose").DefaultSchemaOptions>> & import("mongoose").FlatRecord<{
|
|
74
74
|
partnerId?: number | null | undefined;
|
|
75
75
|
shortName?: string | null | undefined;
|
|
76
76
|
name?: string | null | undefined;
|
|
@@ -80,7 +80,7 @@ export declare const PartnerSchema: Schema<any, Model<any, any, any, any, any, a
|
|
|
80
80
|
__v: number;
|
|
81
81
|
}>;
|
|
82
82
|
export declare const OfferSchema: Schema<any, Model<any, any, any, any, any, any>, {}, {}, {}, {}, import("mongoose").DefaultSchemaOptions, {
|
|
83
|
-
type:
|
|
83
|
+
type: IOfferType;
|
|
84
84
|
id?: number | null | undefined;
|
|
85
85
|
partnerId?: number | null | undefined;
|
|
86
86
|
name?: string | null | undefined;
|
|
@@ -102,7 +102,7 @@ export declare const OfferSchema: Schema<any, Model<any, any, any, any, any, any
|
|
|
102
102
|
bgNames: string[];
|
|
103
103
|
} | null | undefined;
|
|
104
104
|
}, Document<unknown, {}, import("mongoose").FlatRecord<{
|
|
105
|
-
type:
|
|
105
|
+
type: IOfferType;
|
|
106
106
|
id?: number | null | undefined;
|
|
107
107
|
partnerId?: number | null | undefined;
|
|
108
108
|
name?: string | null | undefined;
|
|
@@ -123,8 +123,8 @@ export declare const OfferSchema: Schema<any, Model<any, any, any, any, any, any
|
|
|
123
123
|
logoNames: string[];
|
|
124
124
|
bgNames: string[];
|
|
125
125
|
} | null | undefined;
|
|
126
|
-
}>> & import("mongoose").FlatRecord<{
|
|
127
|
-
type:
|
|
126
|
+
}>, {}, import("mongoose").ResolveSchemaOptions<import("mongoose").DefaultSchemaOptions>> & import("mongoose").FlatRecord<{
|
|
127
|
+
type: IOfferType;
|
|
128
128
|
id?: number | null | undefined;
|
|
129
129
|
partnerId?: number | null | undefined;
|
|
130
130
|
name?: string | null | undefined;
|
package/lib/offers/section.d.ts
CHANGED
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
/// <reference types="mongoose/types/populate" />
|
|
16
16
|
/// <reference types="mongoose/types/query" />
|
|
17
17
|
/// <reference types="mongoose/types/schemaoptions" />
|
|
18
|
-
/// <reference types="mongoose/types/schematypes" />
|
|
19
18
|
/// <reference types="mongoose/types/session" />
|
|
20
19
|
/// <reference types="mongoose/types/types" />
|
|
21
20
|
/// <reference types="mongoose/types/utility" />
|
|
22
21
|
/// <reference types="mongoose/types/validation" />
|
|
23
22
|
/// <reference types="mongoose/types/virtuals" />
|
|
23
|
+
/// <reference types="mongoose/types/schematypes" />
|
|
24
24
|
/// <reference types="mongoose/types/inferschematype" />
|
|
25
25
|
/// <reference types="mongoose/types/inferrawdoctype" />
|
|
26
26
|
import { Schema } from "mongoose";
|
|
@@ -43,7 +43,7 @@ export declare const OffersSectionSchema: Schema<any, import("mongoose").Model<a
|
|
|
43
43
|
id: number;
|
|
44
44
|
title?: any;
|
|
45
45
|
button?: any;
|
|
46
|
-
}>> & import("mongoose").FlatRecord<{
|
|
46
|
+
}>, {}, import("mongoose").ResolveSchemaOptions<import("mongoose").DefaultSchemaOptions>> & import("mongoose").FlatRecord<{
|
|
47
47
|
id: number;
|
|
48
48
|
title?: any;
|
|
49
49
|
button?: any;
|
package/lib/panel/user.d.ts
CHANGED
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
/// <reference types="mongoose/types/populate" />
|
|
16
16
|
/// <reference types="mongoose/types/query" />
|
|
17
17
|
/// <reference types="mongoose/types/schemaoptions" />
|
|
18
|
-
/// <reference types="mongoose/types/schematypes" />
|
|
19
18
|
/// <reference types="mongoose/types/session" />
|
|
20
19
|
/// <reference types="mongoose/types/types" />
|
|
21
20
|
/// <reference types="mongoose/types/utility" />
|
|
22
21
|
/// <reference types="mongoose/types/validation" />
|
|
23
22
|
/// <reference types="mongoose/types/virtuals" />
|
|
23
|
+
/// <reference types="mongoose/types/schematypes" />
|
|
24
24
|
/// <reference types="mongoose/types/inferschematype" />
|
|
25
25
|
/// <reference types="mongoose/types/inferrawdoctype" />
|
|
26
26
|
import { Document, Schema } from "mongoose";
|
|
@@ -42,15 +42,15 @@ export interface IPanelUser extends Document {
|
|
|
42
42
|
accessScopes: PanelUserAccessScope[];
|
|
43
43
|
}
|
|
44
44
|
export declare const PanelUserSchema: Schema<any, import("mongoose").Model<any, any, any, any, any, any>, {}, {}, {}, {}, import("mongoose").DefaultSchemaOptions, {
|
|
45
|
-
accessScopes: string[];
|
|
45
|
+
accessScopes: (string | PanelUserAccessScope)[];
|
|
46
46
|
passwordHash?: string | null | undefined;
|
|
47
47
|
username?: string | null | undefined;
|
|
48
48
|
}, Document<unknown, {}, import("mongoose").FlatRecord<{
|
|
49
|
-
accessScopes: string[];
|
|
49
|
+
accessScopes: (string | PanelUserAccessScope)[];
|
|
50
50
|
passwordHash?: string | null | undefined;
|
|
51
51
|
username?: string | null | undefined;
|
|
52
|
-
}>> & import("mongoose").FlatRecord<{
|
|
53
|
-
accessScopes: string[];
|
|
52
|
+
}>, {}, import("mongoose").ResolveSchemaOptions<import("mongoose").DefaultSchemaOptions>> & import("mongoose").FlatRecord<{
|
|
53
|
+
accessScopes: (string | PanelUserAccessScope)[];
|
|
54
54
|
passwordHash?: string | null | undefined;
|
|
55
55
|
username?: string | null | undefined;
|
|
56
56
|
}> & {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface WPConversion {
|
|
2
|
+
status: string;
|
|
3
|
+
regDate: Date;
|
|
4
|
+
qualDate: Date;
|
|
5
|
+
approveOrRejectDate: Date;
|
|
6
|
+
project: string;
|
|
7
|
+
offerName: string;
|
|
8
|
+
sum: number;
|
|
9
|
+
currency: string;
|
|
10
|
+
geo: string;
|
|
11
|
+
subId?: string;
|
|
12
|
+
clickId: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ConversionComparison {
|
|
15
|
+
wpConversions: WPConversion[];
|
|
16
|
+
keitaroConversions: any[];
|
|
17
|
+
matches: {
|
|
18
|
+
wp: WPConversion;
|
|
19
|
+
keitaro: any;
|
|
20
|
+
}[];
|
|
21
|
+
mismatches: {
|
|
22
|
+
onlyInWP: WPConversion[];
|
|
23
|
+
onlyInKeitaro: any[];
|
|
24
|
+
};
|
|
25
|
+
rejected: {
|
|
26
|
+
wp: WPConversion[];
|
|
27
|
+
keitaro: any[];
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export declare function parseWPConversions(filePath: string): Promise<WPConversion[]>;
|
|
31
|
+
export declare function compareConversions(wpFilePath: string, keitaroConversions: any[]): Promise<ConversionComparison>;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.compareConversions = exports.parseWPConversions = void 0;
|
|
27
|
+
const sync_1 = require("csv-parse/sync");
|
|
28
|
+
const fs = __importStar(require("fs"));
|
|
29
|
+
function parseDate(dateStr) {
|
|
30
|
+
const [month, day, year] = dateStr.split('/').map(num => parseInt(num));
|
|
31
|
+
return new Date(2000 + year, month - 1, day);
|
|
32
|
+
}
|
|
33
|
+
async function parseWPConversions(filePath) {
|
|
34
|
+
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
35
|
+
const records = (0, sync_1.parse)(fileContent, {
|
|
36
|
+
delimiter: ';',
|
|
37
|
+
columns: true,
|
|
38
|
+
skip_empty_lines: true
|
|
39
|
+
});
|
|
40
|
+
return records.map((record) => ({
|
|
41
|
+
status: record.Status,
|
|
42
|
+
regDate: parseDate(record.RegDate),
|
|
43
|
+
qualDate: parseDate(record.QualDate),
|
|
44
|
+
approveOrRejectDate: parseDate(record.Approve_or_Reject_Date),
|
|
45
|
+
project: record.Project,
|
|
46
|
+
offerName: record.Offer_Name,
|
|
47
|
+
sum: parseFloat(record.Sum),
|
|
48
|
+
currency: record.Currency,
|
|
49
|
+
geo: record.Geo,
|
|
50
|
+
subId: record.Sub_ID || undefined,
|
|
51
|
+
clickId: record.Click_ID
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
exports.parseWPConversions = parseWPConversions;
|
|
55
|
+
async function compareConversions(wpFilePath, keitaroConversions) {
|
|
56
|
+
const wpConversions = await parseWPConversions(wpFilePath);
|
|
57
|
+
const matches = [];
|
|
58
|
+
const onlyInWP = [];
|
|
59
|
+
const onlyInKeitaro = [];
|
|
60
|
+
const rejectedWP = [];
|
|
61
|
+
const rejectedKeitaro = [];
|
|
62
|
+
// Create a map of Keitaro conversions by their sub_id to match with WP's Click_ID
|
|
63
|
+
const keitaroMap = new Map(keitaroConversions.map(conv => [conv.sub_id, conv]));
|
|
64
|
+
// First, find matches and conversions only in WP
|
|
65
|
+
for (const wpConv of wpConversions) {
|
|
66
|
+
// Skip rejected conversions
|
|
67
|
+
if (wpConv.status === 'Удержан') {
|
|
68
|
+
rejectedWP.push(wpConv);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const keitaroMatch = keitaroMap.get(wpConv.clickId);
|
|
72
|
+
if (keitaroMatch) {
|
|
73
|
+
matches.push({ wp: wpConv, keitaro: keitaroMatch });
|
|
74
|
+
keitaroMap.delete(wpConv.clickId);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
onlyInWP.push(wpConv);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Remaining conversions in keitaroMap are only in Keitaro
|
|
81
|
+
// We need to check their status before adding them to onlyInKeitaro
|
|
82
|
+
for (const [_, conv] of keitaroMap) {
|
|
83
|
+
if (conv.status === 'rejected') {
|
|
84
|
+
rejectedKeitaro.push(conv);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
onlyInKeitaro.push(conv);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
wpConversions: wpConversions.filter(conv => conv.status !== 'Удержан'),
|
|
92
|
+
keitaroConversions: keitaroConversions.filter(conv => conv.status !== 'rejected'),
|
|
93
|
+
matches,
|
|
94
|
+
mismatches: {
|
|
95
|
+
onlyInWP,
|
|
96
|
+
onlyInKeitaro
|
|
97
|
+
},
|
|
98
|
+
rejected: {
|
|
99
|
+
wp: rejectedWP,
|
|
100
|
+
keitaro: rejectedKeitaro
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
exports.compareConversions = compareConversions;
|
|
@@ -1,48 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const sleep = require('sleep-promise');
|
|
4
3
|
const traffle_keitaro_service_1 = require("../network/keitaro/traffle/traffle-keitaro-service");
|
|
5
4
|
(async () => {
|
|
6
5
|
await traffle_keitaro_service_1.TraffleKeitaroService.addOffersToTraffleKeitaro([
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// {
|
|
35
|
-
// offer: {
|
|
36
|
-
// caption: "4rabet (chicken #2)",
|
|
37
|
-
// geo: "IN"
|
|
38
|
-
// },
|
|
39
|
-
// link: "https://click.traffprogo7.com/GUU0LPNx?landing=2689&sub_id3=chicken2",
|
|
40
|
-
// partnerName: "4rabet",
|
|
41
|
-
// trafficType: ITraffleTrafficType.ASO
|
|
42
|
-
// }
|
|
6
|
+
{
|
|
7
|
+
offer: {
|
|
8
|
+
caption: "Cafe Casino",
|
|
9
|
+
geo: "US"
|
|
10
|
+
},
|
|
11
|
+
link: "https://wow.itisok.work/click?pid=27930&offer_id=4773&l=1757406836",
|
|
12
|
+
partnerName: "Clickout",
|
|
13
|
+
trafficType: traffle_keitaro_service_1.ITraffleTrafficType.ASO
|
|
14
|
+
},
|
|
15
|
+
// {
|
|
16
|
+
// offer: {
|
|
17
|
+
// caption: "4rabet (chicken #1)",
|
|
18
|
+
// geo: "IN"
|
|
19
|
+
// },
|
|
20
|
+
// link: "https://click.traffprogo7.com/GUU0LPNx?landing=1803&sub_id3=chicken1",
|
|
21
|
+
// partnerName: "4rabet",
|
|
22
|
+
// trafficType: ITraffleTrafficType.ASO
|
|
23
|
+
// },
|
|
24
|
+
// {
|
|
25
|
+
// offer: {
|
|
26
|
+
// caption: "4rabet (chicken #2)",
|
|
27
|
+
// geo: "IN"
|
|
28
|
+
// },
|
|
29
|
+
// link: "https://click.traffprogo7.com/GUU0LPNx?landing=2689&sub_id3=chicken2",
|
|
30
|
+
// partnerName: "4rabet",
|
|
31
|
+
// trafficType: ITraffleTrafficType.ASO
|
|
32
|
+
// }
|
|
43
33
|
]);
|
|
44
34
|
// await TraffleKeitaroService.deleteOfferById(2070)
|
|
45
|
-
await
|
|
35
|
+
// await TraffleKeitaroService.updateOfferLinkById(2074, "https://click.traffprogo7.com/GUU0LPNx?landing=2689&sub_id3=chicken")
|
|
46
36
|
// await TraffleKeitaroService.updateOfferLinkById(2073, "https://click.traffprogo7.com/GUU0LPNx?landing=1803&sub_id3=chicken")
|
|
47
37
|
let offers = await traffle_keitaro_service_1.TraffleKeitaroService.getAllOffers();
|
|
48
38
|
console.log(offers);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bprotsyk/aso-core",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.140",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"scripts": {
|
|
@@ -31,7 +31,9 @@
|
|
|
31
31
|
"@types/styled-components": "^5.1.26",
|
|
32
32
|
"@types/unzipper": "^0.10.10",
|
|
33
33
|
"axios": "^1.4.0",
|
|
34
|
+
"bson": "^6.10.4",
|
|
34
35
|
"module-alias": "^2.2.2",
|
|
36
|
+
"mongodb": "^6.18.0",
|
|
35
37
|
"mongoose": "^8.10.0",
|
|
36
38
|
"mustache": "^4.2.0",
|
|
37
39
|
"react": "^18.3.1",
|
package/src/app/app.ts
CHANGED
package/src/general/domain.ts
CHANGED
|
@@ -29,6 +29,7 @@ export interface IDomain extends Document {
|
|
|
29
29
|
note: string,
|
|
30
30
|
proxied: boolean
|
|
31
31
|
appid: number
|
|
32
|
+
expirationMessageSent?: boolean
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
export interface IDomainsBuyRequestResponse {
|
|
@@ -103,5 +104,6 @@ export const DomainSchema = new Schema({
|
|
|
103
104
|
title: String,
|
|
104
105
|
note: String,
|
|
105
106
|
proxied: Boolean,
|
|
106
|
-
appid: Number
|
|
107
|
+
appid: Number,
|
|
108
|
+
expirationMessageSent: { type: Boolean, default: false }
|
|
107
109
|
})
|
|
@@ -215,7 +215,7 @@ async function addOffersToTraffleKeitaro(offers: ITraffleOffer[]) {
|
|
|
215
215
|
const identicalOffer = allOffers.find(o => o.name.includes(name));
|
|
216
216
|
|
|
217
217
|
let offersGroupId = findMatchingOffersGroup(offersGroups, offer)
|
|
218
|
-
let affiliateId = await findMatchingAffiliateId(affiliateNetworks, offer)
|
|
218
|
+
let affiliateId = 160 // await findMatchingAffiliateId(affiliateNetworks, offer)
|
|
219
219
|
if (!identicalOffer) {
|
|
220
220
|
const offerPayload = {
|
|
221
221
|
name: name,
|
|
@@ -577,8 +577,7 @@ async function cloneTraffleCampaign(app: IApp, platform: EPlatform, addDefaultSt
|
|
|
577
577
|
|
|
578
578
|
const ORIGINAL_CLONE_CAMPAIGN_ID = 1925;
|
|
579
579
|
const appsflyerAvailability = app.platforms[platform].appsflyerParams?.apiToken ? "[AF]" : "";
|
|
580
|
-
|
|
581
|
-
let name = `[${app.id}] [${app.bundle}] ET [${app.name}] [Volodymyr Vinnik] [Android] ${appsflyerAvailability} ${app.domainParams.name}`
|
|
580
|
+
let name = `[${app.id}] [${app.bundle}] ${app.name} [Volodymyr Vinnik] [El Trafico] [Android] ${appsflyerAvailability} ${app.domainParams.name}`
|
|
582
581
|
let platformName = platform ? getPlatformName(platform) : null;
|
|
583
582
|
const platformCampaignName = `#${app.id} [➥] (${platformName})`;
|
|
584
583
|
const generateAlias = () => {
|
|
@@ -1,40 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
import { EPlatform, IApp, PlugType, } from "../app/app"
|
|
3
|
-
import { AppType } from "../app/app-type"
|
|
4
|
-
import { IKeitaroCampaign, IKeitaroCampaignParameters } from "../keitaro/keitaro-campaign"
|
|
5
|
-
import { IKeitaroDomain } from "../keitaro/keitaro-domain"
|
|
6
|
-
import { KeitaroService } from "../network/keitaro/keitaro-service"
|
|
7
|
-
const sleep = require('sleep-promise');
|
|
8
|
-
import * as util from 'util';
|
|
9
|
-
import axios from "axios"
|
|
10
|
-
import { getTimestampsForTodayAndYesterday } from "./general"
|
|
11
|
-
import { KeitaroUtils } from "index"
|
|
12
|
-
import { rename } from "fs"
|
|
13
|
-
import { IKeitaroClicksRequest, KeitaroClicksInterval } from "../keitaro/keitaro-clicks"
|
|
14
|
-
import { IKeitaroClicksRangeRequest } from "../keitaro/keitaro-clicks"
|
|
1
|
+
|
|
15
2
|
import { ITraffleTrafficType, TraffleKeitaroService } from "../network/keitaro/traffle/traffle-keitaro-service"
|
|
16
|
-
import { OpenAI } from "../network/openai/openai"
|
|
17
3
|
|
|
18
4
|
(async () => {
|
|
19
5
|
await TraffleKeitaroService.addOffersToTraffleKeitaro([
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// offer: {
|
|
31
|
-
// caption: "4rabet (regpage)",
|
|
32
|
-
// geo: "IN"
|
|
33
|
-
// },
|
|
34
|
-
// link: "https://click.traffprogo7.com/GUU0LPNx?landing=54&sub_id3=reg_form",
|
|
35
|
-
// partnerName: "4rabet",
|
|
36
|
-
// trafficType: ITraffleTrafficType.ASO
|
|
37
|
-
// },
|
|
6
|
+
{
|
|
7
|
+
offer: {
|
|
8
|
+
caption: "Cafe Casino",
|
|
9
|
+
geo: "US"
|
|
10
|
+
},
|
|
11
|
+
link: "https://wow.itisok.work/click?pid=27930&offer_id=4773&l=1757406836",
|
|
12
|
+
partnerName: "Clickout",
|
|
13
|
+
trafficType: ITraffleTrafficType.ASO
|
|
14
|
+
},
|
|
15
|
+
|
|
38
16
|
// {
|
|
39
17
|
// offer: {
|
|
40
18
|
// caption: "4rabet (chicken #1)",
|
|
@@ -57,7 +35,7 @@ import { OpenAI } from "../network/openai/openai"
|
|
|
57
35
|
|
|
58
36
|
// await TraffleKeitaroService.deleteOfferById(2070)
|
|
59
37
|
|
|
60
|
-
await TraffleKeitaroService.updateOfferLinkById(2074, "https://click.traffprogo7.com/GUU0LPNx?landing=2689&sub_id3=chicken")
|
|
38
|
+
// await TraffleKeitaroService.updateOfferLinkById(2074, "https://click.traffprogo7.com/GUU0LPNx?landing=2689&sub_id3=chicken")
|
|
61
39
|
// await TraffleKeitaroService.updateOfferLinkById(2073, "https://click.traffprogo7.com/GUU0LPNx?landing=1803&sub_id3=chicken")
|
|
62
40
|
|
|
63
41
|
let offers = await TraffleKeitaroService.getAllOffers()
|
package/lib/templates/words.txt
DELETED
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
apple
|
|
2
|
-
banana
|
|
3
|
-
cherry
|
|
4
|
-
dragon
|
|
5
|
-
eagle
|
|
6
|
-
forest
|
|
7
|
-
garden
|
|
8
|
-
hammer
|
|
9
|
-
island
|
|
10
|
-
jungle
|
|
11
|
-
kitten
|
|
12
|
-
lemon
|
|
13
|
-
mountain
|
|
14
|
-
ocean
|
|
15
|
-
pencil
|
|
16
|
-
queen
|
|
17
|
-
river
|
|
18
|
-
sunset
|
|
19
|
-
tiger
|
|
20
|
-
umbrella
|
|
21
|
-
village
|
|
22
|
-
window
|
|
23
|
-
xylophone
|
|
24
|
-
yellow
|
|
25
|
-
zebra
|
|
26
|
-
adventure
|
|
27
|
-
beautiful
|
|
28
|
-
creative
|
|
29
|
-
delicious
|
|
30
|
-
excellent
|
|
31
|
-
fantastic
|
|
32
|
-
gorgeous
|
|
33
|
-
handsome
|
|
34
|
-
incredible
|
|
35
|
-
joyful
|
|
36
|
-
knowledge
|
|
37
|
-
luminous
|
|
38
|
-
magnificent
|
|
39
|
-
natural
|
|
40
|
-
outstanding
|
|
41
|
-
perfect
|
|
42
|
-
quality
|
|
43
|
-
radiant
|
|
44
|
-
spectacular
|
|
45
|
-
tremendous
|
|
46
|
-
ultimate
|
|
47
|
-
valuable
|
|
48
|
-
wonderful
|
|
49
|
-
amazing
|
|
50
|
-
brilliant
|
|
51
|
-
charming
|
|
52
|
-
delightful
|
|
53
|
-
elegant
|
|
54
|
-
fascinating
|
|
55
|
-
graceful
|
|
56
|
-
harmonious
|
|
57
|
-
inspiring
|
|
58
|
-
jubilant
|
|
59
|
-
kindhearted
|
|
60
|
-
loving
|
|
61
|
-
mysterious
|
|
62
|
-
nurturing
|
|
63
|
-
optimistic
|
|
64
|
-
peaceful
|
|
65
|
-
quintessential
|
|
66
|
-
radiant
|
|
67
|
-
serene
|
|
68
|
-
tranquil
|
|
69
|
-
uplifting
|
|
70
|
-
vibrant
|
|
71
|
-
whimsical
|
|
72
|
-
abundant
|
|
73
|
-
blessed
|
|
74
|
-
cheerful
|
|
75
|
-
dazzling
|
|
76
|
-
energetic
|
|
77
|
-
friendly
|
|
78
|
-
generous
|
|
79
|
-
hopeful
|
|
80
|
-
imaginative
|
|
81
|
-
jovial
|
|
82
|
-
knowledgeable
|
|
83
|
-
lively
|
|
84
|
-
majestic
|
|
85
|
-
noble
|
|
86
|
-
outstanding
|
|
87
|
-
passionate
|
|
88
|
-
quintessential
|
|
89
|
-
remarkable
|
|
90
|
-
splendid
|
|
91
|
-
treasured
|
|
92
|
-
unique
|
|
93
|
-
valuable
|
|
94
|
-
warmhearted
|
|
95
|
-
authentic
|
|
96
|
-
benevolent
|
|
97
|
-
charismatic
|
|
98
|
-
determined
|
|
99
|
-
enthusiastic
|
|
100
|
-
faithful
|
|
101
|
-
gracious
|
|
102
|
-
humble
|
|
103
|
-
inspiring
|
|
104
|
-
joyful
|
|
105
|
-
kind
|
|
106
|
-
loyal
|
|
107
|
-
magnificent
|
|
108
|
-
nurturing
|
|
109
|
-
optimistic
|
|
110
|
-
patient
|
|
111
|
-
quintessential
|
|
112
|
-
resilient
|
|
113
|
-
sincere
|
|
114
|
-
trustworthy
|
|
115
|
-
understanding
|
|
116
|
-
virtuous
|
|
117
|
-
wise
|
|
118
|
-
zealous
|
|
119
|
-
abundant
|
|
120
|
-
blessed
|
|
121
|
-
cheerful
|
|
122
|
-
dazzling
|
|
123
|
-
energetic
|
|
124
|
-
friendly
|
|
125
|
-
generous
|
|
126
|
-
hopeful
|
|
127
|
-
imaginative
|
|
128
|
-
jovial
|
|
129
|
-
knowledgeable
|
|
130
|
-
lively
|
|
131
|
-
majestic
|
|
132
|
-
noble
|
|
133
|
-
outstanding
|
|
134
|
-
passionate
|
|
135
|
-
quintessential
|
|
136
|
-
remarkable
|
|
137
|
-
splendid
|
|
138
|
-
treasured
|
|
139
|
-
unique
|
|
140
|
-
valuable
|
|
141
|
-
warmhearted
|
|
142
|
-
authentic
|
|
143
|
-
benevolent
|
|
144
|
-
charismatic
|
|
145
|
-
determined
|
|
146
|
-
enthusiastic
|
|
147
|
-
faithful
|
|
148
|
-
gracious
|
|
149
|
-
humble
|
|
150
|
-
inspiring
|
|
151
|
-
joyful
|
|
152
|
-
kind
|
|
153
|
-
loyal
|
|
154
|
-
magnificent
|
|
155
|
-
nurturing
|
|
156
|
-
optimistic
|
|
157
|
-
patient
|
|
158
|
-
quintessential
|
|
159
|
-
resilient
|
|
160
|
-
sincere
|
|
161
|
-
trustworthy
|
|
162
|
-
understanding
|
|
163
|
-
virtuous
|
|
164
|
-
wise
|
|
165
|
-
zealous
|
|
166
|
-
abundant
|
|
167
|
-
blessed
|
|
168
|
-
cheerful
|
|
169
|
-
dazzling
|
|
170
|
-
energetic
|
|
171
|
-
friendly
|
|
172
|
-
generous
|
|
173
|
-
hopeful
|
|
174
|
-
imaginative
|
|
175
|
-
jovial
|
|
176
|
-
knowledgeable
|
|
177
|
-
lively
|
|
178
|
-
majestic
|
|
179
|
-
noble
|
|
180
|
-
outstanding
|
|
181
|
-
passionate
|
|
182
|
-
quintessential
|
|
183
|
-
remarkable
|
|
184
|
-
splendid
|
|
185
|
-
treasured
|
|
186
|
-
unique
|
|
187
|
-
valuable
|
|
188
|
-
warmhearted
|
|
189
|
-
authentic
|
|
190
|
-
benevolent
|
|
191
|
-
charismatic
|
|
192
|
-
determined
|
|
193
|
-
enthusiastic
|
|
194
|
-
faithful
|
|
195
|
-
gracious
|
|
196
|
-
humble
|
|
197
|
-
inspiring
|
|
198
|
-
joyful
|
|
199
|
-
kind
|
|
200
|
-
loyal
|
|
201
|
-
magnificent
|
|
202
|
-
nurturing
|
|
203
|
-
optimistic
|
|
204
|
-
patient
|
|
205
|
-
quintessential
|
|
206
|
-
resilient
|
|
207
|
-
sincere
|
|
208
|
-
trustworthy
|
|
209
|
-
understanding
|
|
210
|
-
virtuous
|
|
211
|
-
wise
|
|
212
|
-
zealous
|
package/tsc
DELETED
|
File without changes
|