@crowdin/app-project-module 0.86.1 → 0.88.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/index.js +2 -0
- package/out/modules/about.d.ts +9 -0
- package/out/modules/about.js +57 -0
- package/out/modules/api/api.js +13 -13
- package/out/modules/integration/handlers/main.js +2 -2
- package/out/modules/integration/types.d.ts +15 -12
- package/out/modules/integration/types.js +6 -1
- package/out/modules/integration/util/defaults.d.ts +5 -1
- package/out/modules/integration/util/defaults.js +52 -1
- package/out/static/css/about.css +128 -0
- package/out/static/img/crowdin.svg +16 -0
- package/out/static/img/crowdin_small.svg +8 -0
- package/out/static/js/form.js +3 -3
- package/out/types.d.ts +4 -0
- package/out/util/handlebars.js +3 -0
- package/out/views/about.handlebars +102 -0
- package/out/views/main.handlebars +34 -17
- package/package.json +1 -1
package/out/index.js
CHANGED
|
@@ -45,6 +45,7 @@ const form_data_display_1 = __importDefault(require("./modules/form-data-display
|
|
|
45
45
|
const form_data_save_1 = __importDefault(require("./modules/form-data-save"));
|
|
46
46
|
const install_1 = __importDefault(require("./modules/install"));
|
|
47
47
|
const manifest_1 = __importDefault(require("./modules/manifest"));
|
|
48
|
+
const about_1 = __importDefault(require("./modules/about"));
|
|
48
49
|
const subscription_paid_1 = __importDefault(require("./modules/subscription-paid"));
|
|
49
50
|
const uninstall_1 = __importDefault(require("./modules/uninstall"));
|
|
50
51
|
const status_1 = __importDefault(require("./modules/status"));
|
|
@@ -158,6 +159,7 @@ function addCrowdinEndpoints(app, clientConfig) {
|
|
|
158
159
|
app.set('view engine', 'handlebars');
|
|
159
160
|
app.get((0, util_1.getLogoUrl)(), (req, res) => res.sendFile(config.imagePath));
|
|
160
161
|
app.get('/manifest.json', json_response_1.default, (0, manifest_1.default)(config));
|
|
162
|
+
app.get('/', (0, about_1.default)(config));
|
|
161
163
|
if (((_a = config === null || config === void 0 ? void 0 : config.enableStatusPage) === null || _a === void 0 ? void 0 : _a.database) || ((_b = config === null || config === void 0 ? void 0 : config.enableStatusPage) === null || _b === void 0 ? void 0 : _b.filesystem)) {
|
|
162
164
|
app.set('trust proxy', 1);
|
|
163
165
|
const limiter = (0, express_rate_limit_1.rateLimit)({
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
import { Config, UnauthorizedConfig } from '../types';
|
|
3
|
+
export declare function getAboutPageOptions(config: Config | UnauthorizedConfig): Promise<{
|
|
4
|
+
name: string;
|
|
5
|
+
logo: string;
|
|
6
|
+
manifest: string;
|
|
7
|
+
storeLink: string;
|
|
8
|
+
}>;
|
|
9
|
+
export default function handle(config: Config | UnauthorizedConfig): (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.getAboutPageOptions = void 0;
|
|
16
|
+
const axios_1 = __importDefault(require("axios"));
|
|
17
|
+
const util_1 = require("../util");
|
|
18
|
+
const crowdin_client_1 = require("../middlewares/crowdin-client");
|
|
19
|
+
function getAboutPageOptions(config) {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
let detailPage = '';
|
|
22
|
+
if (!(config === null || config === void 0 ? void 0 : config.detailPage)) {
|
|
23
|
+
try {
|
|
24
|
+
detailPage = `https://store.crowdin.com/${config.identifier}`;
|
|
25
|
+
yield axios_1.default.get(detailPage);
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
detailPage = '';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
name: config.name,
|
|
33
|
+
logo: (0, util_1.getLogoUrl)(),
|
|
34
|
+
manifest: config.baseUrl + '/manifest.json',
|
|
35
|
+
storeLink: (config === null || config === void 0 ? void 0 : config.detailPage) || detailPage,
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
exports.getAboutPageOptions = getAboutPageOptions;
|
|
40
|
+
function handle(config) {
|
|
41
|
+
return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
if (config.projectIntegration) {
|
|
43
|
+
const jwtToken = (0, crowdin_client_1.getToken)(req);
|
|
44
|
+
if (!jwtToken) {
|
|
45
|
+
const options = yield getAboutPageOptions(config);
|
|
46
|
+
return res.render('about', options);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
next();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const options = yield getAboutPageOptions(config);
|
|
54
|
+
return res.render('about', options);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
exports.default = handle;
|
package/out/modules/api/api.js
CHANGED
|
@@ -191,7 +191,7 @@ function addDefaultApiEndpoints(app, config) {
|
|
|
191
191
|
config,
|
|
192
192
|
optional: false,
|
|
193
193
|
checkSubscriptionExpiration: true,
|
|
194
|
-
moduleKey:
|
|
194
|
+
moduleKey: 'crowdin-files-api',
|
|
195
195
|
}), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, crowdin_files_1.default)(config, config.projectIntegration));
|
|
196
196
|
/**
|
|
197
197
|
* @openapi
|
|
@@ -225,7 +225,7 @@ function addDefaultApiEndpoints(app, config) {
|
|
|
225
225
|
config,
|
|
226
226
|
optional: false,
|
|
227
227
|
checkSubscriptionExpiration: true,
|
|
228
|
-
moduleKey:
|
|
228
|
+
moduleKey: 'file-translation-progress-api',
|
|
229
229
|
}), (0, crowdin_file_progress_1.default)(config.projectIntegration));
|
|
230
230
|
/**
|
|
231
231
|
* @openapi
|
|
@@ -252,7 +252,7 @@ function addDefaultApiEndpoints(app, config) {
|
|
|
252
252
|
config,
|
|
253
253
|
optional: false,
|
|
254
254
|
checkSubscriptionExpiration: true,
|
|
255
|
-
moduleKey:
|
|
255
|
+
moduleKey: 'integration-files-api',
|
|
256
256
|
}), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, integration_data_1.default)(config.projectIntegration));
|
|
257
257
|
/**
|
|
258
258
|
* @openapi
|
|
@@ -280,7 +280,7 @@ function addDefaultApiEndpoints(app, config) {
|
|
|
280
280
|
config,
|
|
281
281
|
optional: false,
|
|
282
282
|
checkSubscriptionExpiration: true,
|
|
283
|
-
moduleKey:
|
|
283
|
+
moduleKey: 'crowdin-update-api',
|
|
284
284
|
}), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, crowdin_update_1.default)(config, config.projectIntegration));
|
|
285
285
|
/**
|
|
286
286
|
* @openapi
|
|
@@ -308,7 +308,7 @@ function addDefaultApiEndpoints(app, config) {
|
|
|
308
308
|
config,
|
|
309
309
|
optional: false,
|
|
310
310
|
checkSubscriptionExpiration: true,
|
|
311
|
-
moduleKey:
|
|
311
|
+
moduleKey: 'integration-update-api',
|
|
312
312
|
}), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, integration_update_1.default)(config, config.projectIntegration));
|
|
313
313
|
/**
|
|
314
314
|
* @openapi
|
|
@@ -338,7 +338,7 @@ function addDefaultApiEndpoints(app, config) {
|
|
|
338
338
|
config,
|
|
339
339
|
optional: false,
|
|
340
340
|
checkSubscriptionExpiration: true,
|
|
341
|
-
moduleKey:
|
|
341
|
+
moduleKey: 'job-get-api',
|
|
342
342
|
}), (0, job_info_1.default)(config));
|
|
343
343
|
/**
|
|
344
344
|
* @openapi
|
|
@@ -364,7 +364,7 @@ function addDefaultApiEndpoints(app, config) {
|
|
|
364
364
|
config,
|
|
365
365
|
optional: false,
|
|
366
366
|
checkSubscriptionExpiration: true,
|
|
367
|
-
moduleKey:
|
|
367
|
+
moduleKey: 'job-cancel-api',
|
|
368
368
|
}), (0, job_cancel_1.default)(config));
|
|
369
369
|
/**
|
|
370
370
|
* @openapi
|
|
@@ -390,7 +390,7 @@ function addDefaultApiEndpoints(app, config) {
|
|
|
390
390
|
config,
|
|
391
391
|
optional: false,
|
|
392
392
|
checkSubscriptionExpiration: true,
|
|
393
|
-
moduleKey:
|
|
393
|
+
moduleKey: 'settings-api',
|
|
394
394
|
}), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, settings_1.default)());
|
|
395
395
|
/**
|
|
396
396
|
* @openapi
|
|
@@ -413,7 +413,7 @@ function addDefaultApiEndpoints(app, config) {
|
|
|
413
413
|
config,
|
|
414
414
|
optional: false,
|
|
415
415
|
checkSubscriptionExpiration: true,
|
|
416
|
-
moduleKey:
|
|
416
|
+
moduleKey: 'settings-update-api',
|
|
417
417
|
}), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, settings_save_1.default)(config, config.projectIntegration));
|
|
418
418
|
/**
|
|
419
419
|
* @openapi
|
|
@@ -449,7 +449,7 @@ function addDefaultApiEndpoints(app, config) {
|
|
|
449
449
|
config,
|
|
450
450
|
optional: false,
|
|
451
451
|
checkSubscriptionExpiration: true,
|
|
452
|
-
moduleKey:
|
|
452
|
+
moduleKey: 'sync-settings-api',
|
|
453
453
|
}), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, sync_settings_1.default)());
|
|
454
454
|
/**
|
|
455
455
|
* @openapi
|
|
@@ -472,7 +472,7 @@ function addDefaultApiEndpoints(app, config) {
|
|
|
472
472
|
config,
|
|
473
473
|
optional: false,
|
|
474
474
|
checkSubscriptionExpiration: true,
|
|
475
|
-
moduleKey:
|
|
475
|
+
moduleKey: 'sync-settings-update-api',
|
|
476
476
|
}), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, sync_settings_save_1.default)(config, config.projectIntegration));
|
|
477
477
|
if (config.projectIntegration.loginForm) {
|
|
478
478
|
/**
|
|
@@ -497,7 +497,7 @@ function addDefaultApiEndpoints(app, config) {
|
|
|
497
497
|
config,
|
|
498
498
|
optional: false,
|
|
499
499
|
checkSubscriptionExpiration: true,
|
|
500
|
-
moduleKey:
|
|
500
|
+
moduleKey: 'login-data',
|
|
501
501
|
}), (req, res) => {
|
|
502
502
|
var _a, _b;
|
|
503
503
|
let fields = [];
|
|
@@ -527,7 +527,7 @@ function addDefaultApiEndpoints(app, config) {
|
|
|
527
527
|
config,
|
|
528
528
|
optional: false,
|
|
529
529
|
checkSubscriptionExpiration: false,
|
|
530
|
-
moduleKey:
|
|
530
|
+
moduleKey: 'login',
|
|
531
531
|
}), (0, integration_login_1.default)(config, config.projectIntegration));
|
|
532
532
|
}
|
|
533
533
|
}
|
|
@@ -77,8 +77,8 @@ function handle(config, integration) {
|
|
|
77
77
|
options.zenModeUrl = parentUrl.toString();
|
|
78
78
|
}
|
|
79
79
|
const configurationFields = yield integration.getConfiguration(req.crowdinContext.jwtPayload.context.project_id, req.crowdinApiClient, req.integrationCredentials);
|
|
80
|
-
options.configurationFields = configurationFields;
|
|
81
|
-
logger(`Adding configuration fields ${JSON.stringify(configurationFields, null, 2)}`);
|
|
80
|
+
options.configurationFields = (0, defaults_1.groupFieldsByCategory)(configurationFields);
|
|
81
|
+
logger(`Adding configuration fields ${JSON.stringify(options.configurationFields, null, 2)}`);
|
|
82
82
|
}
|
|
83
83
|
options.infoModal = integration.infoModal;
|
|
84
84
|
options.syncNewElements = integration.syncNewElements;
|
|
@@ -327,27 +327,23 @@ export interface OAuthLogin {
|
|
|
327
327
|
*/
|
|
328
328
|
performRefreshTokenRequest?: (currentCredentials: any, loginForm?: any) => Promise<any>;
|
|
329
329
|
}
|
|
330
|
-
export interface
|
|
330
|
+
export interface BaseTreeItem {
|
|
331
331
|
id: string;
|
|
332
332
|
name: string;
|
|
333
|
-
type: SourceFilesModel.FileType;
|
|
334
333
|
parentId?: string;
|
|
335
334
|
nodeType?: IntegrationTreeElementType;
|
|
336
335
|
customContent?: string;
|
|
337
336
|
labels?: LabelTreeElement[];
|
|
338
|
-
|
|
339
|
-
|
|
337
|
+
disabled?: boolean;
|
|
338
|
+
tooltip?: string;
|
|
340
339
|
path?: string;
|
|
341
340
|
}
|
|
342
|
-
export interface
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
nodeType?: IntegrationTreeElementType;
|
|
347
|
-
customContent?: string;
|
|
348
|
-
labels?: LabelTreeElement[];
|
|
349
|
-
path?: string;
|
|
341
|
+
export interface File extends BaseTreeItem {
|
|
342
|
+
type: SourceFilesModel.FileType;
|
|
343
|
+
failed?: boolean;
|
|
344
|
+
excludedTargetLanguages?: string[];
|
|
350
345
|
}
|
|
346
|
+
export type Folder = BaseTreeItem;
|
|
351
347
|
export type TreeItem = File | Folder;
|
|
352
348
|
/**
|
|
353
349
|
* 0 - folder
|
|
@@ -359,6 +355,7 @@ export type FormEntity = FormField | FormDelimiter;
|
|
|
359
355
|
export interface FormDelimiter {
|
|
360
356
|
label?: string;
|
|
361
357
|
labelHtml?: string;
|
|
358
|
+
category?: string;
|
|
362
359
|
}
|
|
363
360
|
export interface FormField {
|
|
364
361
|
key: string;
|
|
@@ -398,6 +395,8 @@ export interface FormField {
|
|
|
398
395
|
* only for notice type
|
|
399
396
|
*/
|
|
400
397
|
noIcon?: boolean;
|
|
398
|
+
category?: string;
|
|
399
|
+
position?: number;
|
|
401
400
|
}
|
|
402
401
|
type NoticeType = 'info' | 'warning' | 'danger' | 'success' | 'error' | 'dataLostWarning';
|
|
403
402
|
export interface IntegrationCredentials {
|
|
@@ -525,4 +524,8 @@ interface LoginFormTokenResponse {
|
|
|
525
524
|
expires_in: number;
|
|
526
525
|
refresh_token: string;
|
|
527
526
|
}
|
|
527
|
+
export declare enum DefaultCategory {
|
|
528
|
+
GENERAL = "General Settings",
|
|
529
|
+
SYNC = "Sync settings"
|
|
530
|
+
}
|
|
528
531
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SyncSchedule = exports.SyncCondition = exports.Provider = void 0;
|
|
3
|
+
exports.DefaultCategory = exports.SyncSchedule = exports.SyncCondition = exports.Provider = void 0;
|
|
4
4
|
var Provider;
|
|
5
5
|
(function (Provider) {
|
|
6
6
|
Provider["CROWDIN"] = "crowdin";
|
|
@@ -17,3 +17,8 @@ var SyncSchedule;
|
|
|
17
17
|
SyncSchedule[SyncSchedule["DISABLED"] = 0] = "DISABLED";
|
|
18
18
|
SyncSchedule[SyncSchedule["ACTIVE"] = 1 || 3 || 6 || 12 || 24] = "ACTIVE";
|
|
19
19
|
})(SyncSchedule = exports.SyncSchedule || (exports.SyncSchedule = {}));
|
|
20
|
+
var DefaultCategory;
|
|
21
|
+
(function (DefaultCategory) {
|
|
22
|
+
DefaultCategory["GENERAL"] = "General Settings";
|
|
23
|
+
DefaultCategory["SYNC"] = "Sync settings";
|
|
24
|
+
})(DefaultCategory = exports.DefaultCategory || (exports.DefaultCategory = {}));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Crowdin, { SourceFilesModel } from '@crowdin/crowdin-api-client';
|
|
2
2
|
import { Config } from '../../../types';
|
|
3
|
-
import { IntegrationLogic } from '../types';
|
|
3
|
+
import { FormEntity, FormField, IntegrationLogic } from '../types';
|
|
4
4
|
export declare function getRootFolder(config: Config, integration: IntegrationLogic, client: Crowdin, projectId: number): Promise<SourceFilesModel.Directory | undefined>;
|
|
5
5
|
export declare function getOauthRoute(integration: IntegrationLogic): string;
|
|
6
6
|
export declare function applyIntegrationModuleDefaults(config: Config, integration: IntegrationLogic): void;
|
|
@@ -12,3 +12,7 @@ export declare function constructOauthUrl({ config, integration, clientId, login
|
|
|
12
12
|
}): string | undefined;
|
|
13
13
|
export declare function getOAuthPollingId(clientId: string): string;
|
|
14
14
|
export declare function getOAuthLoginFormId(clientId: string): string;
|
|
15
|
+
export declare function groupFieldsByCategory(fields: FormEntity[]): {
|
|
16
|
+
name: string;
|
|
17
|
+
fields: FormField[];
|
|
18
|
+
}[];
|
|
@@ -32,8 +32,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
32
32
|
});
|
|
33
33
|
};
|
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
-
exports.getOAuthLoginFormId = exports.getOAuthPollingId = exports.constructOauthUrl = exports.applyIntegrationModuleDefaults = exports.getOauthRoute = exports.getRootFolder = void 0;
|
|
35
|
+
exports.groupFieldsByCategory = exports.getOAuthLoginFormId = exports.getOAuthPollingId = exports.constructOauthUrl = exports.applyIntegrationModuleDefaults = exports.getOauthRoute = exports.getRootFolder = void 0;
|
|
36
36
|
const crowdinAppFunctions = __importStar(require("@crowdin/crowdin-apps-functions"));
|
|
37
|
+
const types_1 = require("../types");
|
|
37
38
|
function getRootFolder(config, integration, client, projectId) {
|
|
38
39
|
return __awaiter(this, void 0, void 0, function* () {
|
|
39
40
|
if (!integration.withRootFolder) {
|
|
@@ -158,6 +159,7 @@ function applyIntegrationModuleDefaults(config, integration) {
|
|
|
158
159
|
label: 'Show In-Context Pseudo Language',
|
|
159
160
|
type: 'checkbox',
|
|
160
161
|
defaultValue: 'false',
|
|
162
|
+
category: types_1.DefaultCategory.GENERAL,
|
|
161
163
|
});
|
|
162
164
|
}
|
|
163
165
|
if (integration.withCronSync || integration.webhooks) {
|
|
@@ -167,6 +169,8 @@ function applyIntegrationModuleDefaults(config, integration) {
|
|
|
167
169
|
helpText: `Defines how often content is synced between ${config.name} and Crowdin. Make sure Auto Sync is enabled for selected directories and files in the dual pane view.`,
|
|
168
170
|
type: 'select',
|
|
169
171
|
defaultValue: '0',
|
|
172
|
+
category: types_1.DefaultCategory.SYNC,
|
|
173
|
+
position: 0,
|
|
170
174
|
options: [
|
|
171
175
|
{
|
|
172
176
|
value: '0',
|
|
@@ -200,6 +204,8 @@ function applyIntegrationModuleDefaults(config, integration) {
|
|
|
200
204
|
label: 'Automatically sync new translations from Crowdin',
|
|
201
205
|
type: 'checkbox',
|
|
202
206
|
dependencySettings: JSON.stringify([{ '#schedule-settings': { type: '!equal', value: ['0'] } }]),
|
|
207
|
+
category: types_1.DefaultCategory.SYNC,
|
|
208
|
+
position: 1,
|
|
203
209
|
});
|
|
204
210
|
}
|
|
205
211
|
if ((_o = integration.syncNewElements) === null || _o === void 0 ? void 0 : _o.integration) {
|
|
@@ -208,6 +214,8 @@ function applyIntegrationModuleDefaults(config, integration) {
|
|
|
208
214
|
label: `Automatically sync new content from ${config.name}`,
|
|
209
215
|
type: 'checkbox',
|
|
210
216
|
dependencySettings: JSON.stringify([{ '#schedule-settings': { type: '!equal', value: ['0'] } }]),
|
|
217
|
+
category: types_1.DefaultCategory.SYNC,
|
|
218
|
+
position: 2,
|
|
211
219
|
});
|
|
212
220
|
}
|
|
213
221
|
if (integration.uploadTranslations) {
|
|
@@ -217,14 +225,20 @@ function applyIntegrationModuleDefaults(config, integration) {
|
|
|
217
225
|
key: 'importEqSuggestions',
|
|
218
226
|
label: 'Add translations that are the same as the source text',
|
|
219
227
|
type: 'checkbox',
|
|
228
|
+
category: types_1.DefaultCategory.SYNC,
|
|
229
|
+
position: 3,
|
|
220
230
|
}, {
|
|
221
231
|
key: 'autoApproveImported',
|
|
222
232
|
label: 'Mark added translations as Approved in Crowdin',
|
|
223
233
|
type: 'checkbox',
|
|
234
|
+
category: types_1.DefaultCategory.SYNC,
|
|
235
|
+
position: 4,
|
|
224
236
|
}, {
|
|
225
237
|
key: 'translateHidden',
|
|
226
238
|
label: 'Add translations for hidden source strings in Crowdin',
|
|
227
239
|
type: 'checkbox',
|
|
240
|
+
category: types_1.DefaultCategory.SYNC,
|
|
241
|
+
position: 5,
|
|
228
242
|
});
|
|
229
243
|
}
|
|
230
244
|
defaultSettings.push({
|
|
@@ -233,6 +247,8 @@ function applyIntegrationModuleDefaults(config, integration) {
|
|
|
233
247
|
type: 'select',
|
|
234
248
|
defaultValue: '0',
|
|
235
249
|
dependencySettings: JSON.stringify([{ '#schedule-settings': { type: '!equal', value: ['0'] } }]),
|
|
250
|
+
category: types_1.DefaultCategory.SYNC,
|
|
251
|
+
position: 6,
|
|
236
252
|
options: [
|
|
237
253
|
{
|
|
238
254
|
value: '0',
|
|
@@ -366,3 +382,38 @@ function getOAuthLoginFormId(clientId) {
|
|
|
366
382
|
return `oauth_form_${clientId}`;
|
|
367
383
|
}
|
|
368
384
|
exports.getOAuthLoginFormId = getOAuthLoginFormId;
|
|
385
|
+
function groupFieldsByCategory(fields) {
|
|
386
|
+
const groupedFields = fields.reduce((acc, field) => {
|
|
387
|
+
if ('key' in field) {
|
|
388
|
+
const category = field.category || types_1.DefaultCategory.GENERAL;
|
|
389
|
+
if (!acc[category]) {
|
|
390
|
+
acc[category] = [];
|
|
391
|
+
}
|
|
392
|
+
acc[category].push(field);
|
|
393
|
+
}
|
|
394
|
+
return acc;
|
|
395
|
+
}, {});
|
|
396
|
+
// Sort fields by position within each category
|
|
397
|
+
Object.keys(groupedFields).forEach((category) => {
|
|
398
|
+
groupedFields[category].sort((a, b) => {
|
|
399
|
+
// If neither has position, maintain original order
|
|
400
|
+
if (!('position' in a) && !('position' in b)) {
|
|
401
|
+
return 0;
|
|
402
|
+
}
|
|
403
|
+
// If only one has position, the one without position goes to the end
|
|
404
|
+
if (!('position' in a)) {
|
|
405
|
+
return 1;
|
|
406
|
+
}
|
|
407
|
+
if (!('position' in b)) {
|
|
408
|
+
return -1;
|
|
409
|
+
}
|
|
410
|
+
// If both have position, sort by position value (lower numbers first)
|
|
411
|
+
return (a.position || 0) - (b.position || 0);
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
return Object.entries(groupedFields).map(([category, fields]) => ({
|
|
415
|
+
name: category,
|
|
416
|
+
fields,
|
|
417
|
+
}));
|
|
418
|
+
}
|
|
419
|
+
exports.groupFieldsByCategory = groupFieldsByCategory;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/* Base styles */
|
|
2
|
+
body {
|
|
3
|
+
margin: 0;
|
|
4
|
+
font-family: 'Noto Sans', sans-serif;
|
|
5
|
+
font-size: 1rem;
|
|
6
|
+
font-weight: 400;
|
|
7
|
+
line-height: 1.5;
|
|
8
|
+
color: rgba(38,50,56,.87);
|
|
9
|
+
text-align: left;
|
|
10
|
+
background-color: #fff;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
h1 {
|
|
14
|
+
font-family: 'Poppins', sans-serif;
|
|
15
|
+
line-height: 1.2;
|
|
16
|
+
color: #050c1a;
|
|
17
|
+
font-size: 2.33333rem;
|
|
18
|
+
letter-spacing: -.5px;
|
|
19
|
+
margin-bottom: 1.5rem;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
a {
|
|
23
|
+
color: #66bb6a;
|
|
24
|
+
text-decoration: none;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
a:hover {
|
|
28
|
+
color: #66bb6a;
|
|
29
|
+
text-decoration: underline;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
pre {
|
|
33
|
+
display: block;
|
|
34
|
+
font-size: 87.5%;
|
|
35
|
+
color: #212529;
|
|
36
|
+
background-color: #eceff1;
|
|
37
|
+
border: 0;
|
|
38
|
+
border-radius: .25rem;
|
|
39
|
+
padding: 1rem;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Layout */
|
|
43
|
+
.main {
|
|
44
|
+
padding-top: 64px;
|
|
45
|
+
padding-bottom: 3rem;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Navbar */
|
|
49
|
+
.crowdin-navbar {
|
|
50
|
+
min-width: 300px;
|
|
51
|
+
background-color: #fff;
|
|
52
|
+
border-bottom: 1px solid rgba(0,0,0,.1);
|
|
53
|
+
padding: 0 1.5rem 0 .75rem;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@media (min-width: 768px) {
|
|
57
|
+
.crowdin-navbar {
|
|
58
|
+
padding: 0 1.75rem;
|
|
59
|
+
justify-content: space-between;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.crowdin-navbar__nav-link > a {
|
|
64
|
+
color: rgba(38,50,56,.54);
|
|
65
|
+
font-family: Poppins, sans-serif;
|
|
66
|
+
font-weight: 500;
|
|
67
|
+
letter-spacing: .25px;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.crowdin-navbar__nav-link > a:hover {
|
|
71
|
+
color: #050c1a;
|
|
72
|
+
text-decoration: none;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@media (min-width: 992px) and (max-width:1439.98px) {
|
|
76
|
+
.crowdin-navbar__nav-link > a {
|
|
77
|
+
font-size: .875rem;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* Product template */
|
|
82
|
+
.crwd__product-template__header {
|
|
83
|
+
padding-top: 6rem;
|
|
84
|
+
font-size: 16px;
|
|
85
|
+
font-weight: 400;
|
|
86
|
+
line-height: 1.5;
|
|
87
|
+
font-family: 'Noto Sans', sans-serif;
|
|
88
|
+
color: rgba(40,44,52,0.87);
|
|
89
|
+
display: flex;
|
|
90
|
+
margin-bottom: 32px;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.crwd__product-single__photo-wrapper {
|
|
94
|
+
position: relative;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.description {
|
|
98
|
+
font-size: smaller;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.product-single__photo {
|
|
102
|
+
margin: 0 auto;
|
|
103
|
+
min-height: 1px;
|
|
104
|
+
width: 30%;
|
|
105
|
+
border-radius: 1rem;
|
|
106
|
+
border: 1px solid rgba(0,0,0,.1);
|
|
107
|
+
position: relative;
|
|
108
|
+
height: 0;
|
|
109
|
+
padding-bottom: 30%;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@media (min-width: 992px) {
|
|
113
|
+
.product-single__photo {
|
|
114
|
+
width: 100%;
|
|
115
|
+
padding-bottom: 100%;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.image-holder {
|
|
120
|
+
position: absolute;
|
|
121
|
+
left: 0;
|
|
122
|
+
top: 0;
|
|
123
|
+
padding: 1rem;
|
|
124
|
+
height: 100%;
|
|
125
|
+
width: 100%;
|
|
126
|
+
display: flex;
|
|
127
|
+
align-items: center;
|
|
128
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svg width="180" height="37" viewBox="0 0 180 37" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M46.5517 20.0596C46.5517 22.8097 47.3937 25.0143 49.0759 26.6769C50.7598 28.3377 53.0349 29.169 55.9047 29.169C58.7744 29.169 60.7057 28.4667 62.1406 27.0638C63.5754 25.6504 64.2929 24.0105 64.2929 22.1475V21.9784H60.1409V22.13C60.1409 22.8812 59.8129 23.5277 59.1586 24.0662C58.5025 24.6047 57.408 24.8749 55.8713 24.8749C54.1435 24.8749 52.8771 24.4531 52.0754 23.6114C51.2738 22.7696 50.8721 21.6473 50.8721 20.2444V19.3347C50.8721 17.9317 51.2791 16.8094 52.093 15.9677C52.9069 15.1259 54.1663 14.7042 55.8713 14.7042C57.3623 14.7042 58.4464 14.9621 59.1252 15.478C59.8146 15.9938 60.1584 16.6456 60.1584 17.4316V17.6006H64.3104L64.2929 17.381C64.2245 15.5058 63.4912 13.8799 62.0897 12.4978C60.6882 11.1054 58.6271 10.41 55.9047 10.41C53.0349 10.41 50.7581 11.2413 49.0759 12.9022C47.3919 14.5526 46.5517 16.7571 46.5517 19.5194V20.0579V20.0596Z" fill="#263238"/>
|
|
3
|
+
<path d="M67.7853 28.6635H72.0215V19.9184C72.0215 18.0031 72.9477 17.0132 73.716 16.473C74.4843 15.9223 75.3596 15.6486 76.3419 15.6486C76.6471 15.6486 76.9243 15.6661 77.1716 15.6992C77.4312 15.7323 77.6751 15.7724 77.8996 15.8177V10.6661C77.7873 10.6208 77.5891 10.5703 77.3067 10.5145C77.0348 10.4587 76.7699 10.4308 76.5103 10.4308C75.5052 10.4308 74.6071 10.701 73.816 11.2395C73.1038 11.724 72.5285 12.2973 72.0917 12.9544C72.0461 13.0223 71.9391 12.9944 71.9338 12.9125L71.5637 10.9188H67.7836V28.6635H67.7853Z" fill="#263238"/>
|
|
4
|
+
<path d="M79.6309 20.0596C79.6309 22.8097 80.5062 25.0143 82.2568 26.6768C84.0075 28.3377 86.3124 29.169 89.1716 29.169C92.0308 29.169 94.3182 28.3377 96.0688 26.6768C97.8317 25.016 98.7122 22.8097 98.7122 20.0596V19.5211C98.7122 16.7606 97.8317 14.5543 96.0688 12.9039C94.3182 11.243 92.0185 10.4117 89.1716 10.4117C86.3246 10.4117 84.0092 11.243 82.2568 12.9039C80.5062 14.5543 79.6309 16.7588 79.6309 19.5211V20.0596ZM83.9513 19.3364C83.9513 17.7993 84.4039 16.6769 85.3073 15.9694C86.2106 15.2618 87.4982 14.908 89.1716 14.908C90.845 14.908 92.115 15.2618 93.0184 15.9694C93.934 16.6769 94.3918 17.7993 94.3918 19.3364V20.2461C94.3918 21.8407 93.9393 22.9787 93.0359 23.6636C92.1431 24.3363 90.8555 24.6744 89.1716 24.6744C87.4876 24.6744 86.1948 24.3381 85.2915 23.6636C84.3986 22.9787 83.9531 21.839 83.9531 20.2461V19.3364H83.9513Z" fill="#263238"/>
|
|
5
|
+
<path d="M100.636 10.9154L105.957 28.6601H110.775L114.554 15.7742C114.594 15.6366 114.79 15.6331 114.834 15.7707L118.909 28.6601H123.726L129.081 10.9154H123.842L121.198 20.7986C121.086 21.2482 120.977 21.6909 120.875 22.1283C120.818 22.4037 120.721 22.8411 120.66 23.1182C120.646 23.1792 120.558 23.1809 120.544 23.1182C120.469 22.801 120.388 22.4716 120.298 22.1266C120.186 21.6769 120.062 21.2343 119.925 20.7968L116.976 10.9137H111.959C111.959 10.9137 108.998 20.9955 108.451 23.0049C108.428 23.092 108.304 23.0903 108.281 23.0049L105.215 10.9154H100.633H100.636Z" fill="#263238"/>
|
|
6
|
+
<path d="M130.469 20.0596C130.469 22.6859 131.186 24.8347 132.621 26.5078C134.067 28.1686 136.073 28.9999 138.638 28.9999C139.971 28.9999 141.123 28.7594 142.093 28.2767C142.769 27.9368 143.635 27.1752 144.112 26.7308C144.307 27.5464 144.568 28.6653 144.568 28.6653H148.768V2.85339H144.347V13.0555C143.783 12.2695 143.037 11.663 142.111 11.2378C141.185 10.8003 140.06 10.5808 138.739 10.5808C136.254 10.5808 134.254 11.4173 132.74 13.0886C131.227 14.7494 130.469 16.893 130.469 19.5193V20.0578V20.0596ZM134.791 20.2286L134.775 19.3538C134.775 18.0746 135.17 17.0411 135.961 16.2552C136.752 15.4587 137.978 15.0596 139.639 15.0596C140.802 15.0596 141.792 15.3298 142.604 15.8683C142.613 15.8735 142.62 15.8787 142.628 15.8839C143.716 16.6124 144.349 17.8463 144.349 19.1499V20.3698C144.349 21.71 143.681 22.9735 142.546 23.6967C142.537 23.7019 142.528 23.7072 142.52 23.7124C141.65 24.2509 140.644 24.521 139.504 24.521C137.831 24.521 136.629 24.1219 135.894 23.3255C135.159 22.5291 134.793 21.4956 134.793 20.2269L134.791 20.2286Z" fill="#263238"/>
|
|
7
|
+
<path d="M153.785 28.6636H158.005V10.9171H153.785V28.6618V28.6636ZM152.888 6.0688C152.888 6.83213 153.148 7.46126 153.667 7.95446C154.199 8.4372 154.942 8.6777 155.904 8.6777C156.865 8.6777 157.588 8.43023 158.107 7.93703C158.638 7.44383 158.903 6.81993 158.903 6.0688C158.903 5.31767 158.644 4.7112 158.123 4.21626C157.603 3.72306 156.858 3.47559 155.886 3.47559C154.914 3.47559 154.199 3.72306 153.667 4.21626C153.148 4.70945 152.888 5.32813 152.888 6.0688Z" fill="#263238"/>
|
|
8
|
+
<path d="M163.122 28.6635H167.342V21.466C167.342 17.3914 168.793 14.8087 171.95 14.8087C175.108 14.8087 175.781 16.6333 175.781 19.1952V28.6635H180V18.1408C180 15.1224 179.379 13.106 178.135 12.0969C176.892 11.0757 175.306 10.5651 173.373 10.5651C172.098 10.5651 170.917 10.8003 169.831 11.2726C168.856 11.6909 168.062 12.2869 167.449 13.0572C167.398 12.7836 167.12 10.9188 167.12 10.9188H163.12V28.6635H163.122Z" fill="#263238"/>
|
|
9
|
+
<path d="M26.3793 0H10.7379C9.0578 0 7.52231 0.287415 6.17175 0.825712C4.92783 1.3215 3.84078 2.03011 2.94207 2.923C2.00965 3.84937 1.27689 4.97716 0.775862 6.27144C0.269651 7.57911 0 9.05675 0 10.6683V26.2083C0 27.9214 0.291075 29.473 0.83788 30.8333C1.33828 32.0782 2.05284 33.163 2.95448 34.0647C3.85321 34.9634 4.94061 35.672 6.18987 36.1676C7.56348 36.7125 9.13276 37 10.8621 37H26.3793C28.1035 37 29.6653 36.7108 31.0345 36.1676C32.2875 35.6704 33.3793 34.9605 34.2869 34.0647C35.1956 33.1677 35.9111 32.0816 36.4103 30.8333C36.9544 29.4727 37.2414 27.9193 37.2414 26.2083V10.7917C37.2414 9.12246 36.965 7.60651 36.445 6.27144C35.9429 4.98255 35.2137 3.86223 34.2869 2.93533C33.3841 2.03248 32.2909 1.32162 31.0345 0.825712C29.6649 0.285152 28.1015 0 26.3793 0Z" fill="#263238"/>
|
|
10
|
+
<path d="M23.0401 22.6811C23.0276 22.5454 22.9159 22.0274 22.5559 22.0151C22.1959 22.0151 21.4387 22.0151 21.4387 22.0151C21.4387 22.0151 20.9794 22.0151 20.9794 22.4591C20.9918 23.3224 21.4883 24.0624 22.0966 24.5557C22.6056 24.9751 23.2263 25.1971 23.9339 25.1971C24.5545 25.1847 24.629 24.7407 24.3311 24.6051C23.8345 24.3707 23.189 23.8527 23.0525 22.6811H23.0401Z" fill="white"/>
|
|
11
|
+
<path d="M26.3793 10.7917C24.7788 10.7917 23.1783 10.9886 21.7241 11.3445C20.336 11.6842 19.0811 12.1687 18.0869 12.765C16.9945 13.4187 16.1503 14.208 15.5669 15.1207C15.0951 15.8607 14.7848 16.6624 14.6731 17.5257C14.6358 17.8094 14.611 18.6974 15.5545 18.9317C16.1379 19.0797 17.0565 19.1414 17.6648 19.2154C18.6579 19.3264 18.931 18.2287 19.0179 18.0437C19.8 15.8977 20.9669 14.4547 22.6303 13.505C23.645 12.9269 24.8704 12.5358 26.3793 12.3158C27.381 12.1697 28.5077 12.099 29.7807 12.099C30.2027 12.099 31.1834 12.1484 31.1834 11.6674C31.1834 11.2982 30.4118 11.0869 29.4827 10.9659C28.239 10.804 26.7133 10.804 26.3793 10.804V10.7917Z" fill="white"/>
|
|
12
|
+
<path d="M22.0221 27.084C20.8924 26.825 18.9931 25.604 18.5586 22.5084C18.4717 21.9287 18.149 21.645 17.6524 21.5464C16.9945 21.4107 15.84 21.349 15.4676 21.312C14.9338 21.2627 14.5365 21.571 14.5986 22.496C14.7103 23.902 15.2814 24.9997 16.2372 26.085C17.3669 27.3677 18.8565 28.1077 20.4455 28.0707C22.1959 28.0337 22.32 27.7254 22.3324 27.491C22.3324 27.2567 22.2207 27.121 22.0221 27.0717V27.084Z" fill="white"/>
|
|
13
|
+
<path d="M17.2676 29.674C15.5173 29.674 11.8428 26.8867 11.8428 22.5207C11.8428 21.756 11.3711 20.979 10.4028 20.6954C9.62071 20.461 8.50347 20.1157 7.79588 20.0787C6.09519 19.9677 6.18209 21.3737 6.23174 22.1137C6.39312 25.2094 7.77106 27.824 10.0428 29.304C10.9862 29.9207 12.1035 30.34 13.4193 30.5867C13.7297 30.6484 14.8345 30.8704 15.9517 30.8334C17.6773 30.7594 17.8511 30.266 17.8511 30.0687C17.8511 29.8097 17.6648 29.6864 17.2676 29.6864V29.674Z" fill="white"/>
|
|
14
|
+
<path d="M31.618 7.77002C30.9146 7.56828 30.202 7.39073 29.4829 7.2371C28.4593 7.01844 27.4224 6.8482 26.3794 6.72553C23.8095 6.42326 21.2031 6.40979 18.6704 6.67235C16.4384 6.908 13.9472 7.46039 11.7778 8.59635C9.51898 9.7791 7.60898 11.5945 6.70348 14.3437C6.51728 14.8987 6.1821 16.9337 8.14348 17.427C8.77659 17.5874 9.4221 17.871 10.0924 17.9944C12.0042 18.3397 12.4138 16.539 12.5256 16.1814C12.6373 15.836 12.7614 15.503 12.9104 15.1577C13.5187 13.8627 14.4249 12.765 15.4552 11.914C17.5904 10.138 20.2469 9.29935 22.829 8.89235C24.3311 8.65802 25.8331 8.55935 27.3352 8.59635C28.1839 8.61473 28.8917 8.64167 29.4829 8.67016C30.1291 8.7013 30.6358 8.73428 31.0346 8.75994C32.2292 8.83682 32.4554 8.84798 32.5614 8.54702C32.7352 8.05369 31.9159 7.84402 31.618 7.77002Z" fill="white"/>
|
|
15
|
+
<path d="M27.7324 14.837C22.6924 14.837 21.3766 17.353 21.0041 19.0304C20.8304 19.8444 21.3269 19.906 21.7862 19.9924C22.4317 20.1034 22.9531 20.0047 23.189 19.388C23.8966 17.4764 24.8648 15.6017 27.931 15.6017C28.2414 15.6017 28.5145 15.4044 28.5145 15.2194C28.5145 15.0344 28.3159 14.837 27.7448 14.837H27.7324Z" fill="white"/>
|
|
16
|
+
</svg>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<svg width="248" height="248" viewBox="0 0 248 248" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M163.024 177.312C157.024 177.312 151.667 175.514 147.239 171.995C141.954 167.851 137.739 161.674 137.597 154.402C137.525 150.727 141.525 150.727 141.525 150.727C141.525 150.727 148.025 150.649 151.167 150.649C154.31 150.727 155.238 155.106 155.381 156.2C156.595 166.053 162.166 170.353 166.452 172.308C169.023 173.481 168.38 177.156 163.024 177.312Z" fill="#263238"/>
|
|
3
|
+
<path d="M109.1 127.248C103.816 126.626 95.962 126.082 90.8924 124.839C82.6811 122.819 82.8953 115.438 83.2523 113.03C84.252 105.804 86.8939 99.1224 90.9638 92.9069C96.0334 85.2929 103.317 78.6112 112.67 73.1726C130.235 62.9947 154.798 57.323 181.788 57.323C201.567 57.323 222.202 59.8869 222.416 59.8869C224.273 60.12 225.63 61.907 225.558 63.927C225.487 65.9471 224.059 67.5009 222.202 67.6563C219.203 67.5786 216.276 67.5786 213.491 67.5786C186.001 67.5786 166.437 71.3079 151.87 79.3881C137.518 87.3129 127.522 99.4332 120.739 117.381C120.025 118.934 117.668 128.18 109.1 127.248Z" fill="#263238"/>
|
|
4
|
+
<path d="M133.089 201.326C119.451 201.326 106.594 195.437 96.863 184.681C88.6235 175.574 83.6513 166.388 82.7279 154.611C82.1597 146.917 85.5692 144.248 90.1862 144.719C93.3825 145.033 103.327 145.504 109.009 146.682C113.271 147.545 116.112 149.901 116.823 154.768C120.587 180.677 136.924 190.884 146.655 193.082C148.36 193.475 149.426 194.574 149.355 196.537C149.284 198.421 148.005 199.991 146.3 200.305C141.967 201.012 137.421 201.326 133.089 201.326Z" fill="#263238"/>
|
|
5
|
+
<path d="M94.2244 224.321C84.5472 224.321 75.0835 222.782 72.3796 222.296C60.9946 220.27 51.4598 216.786 43.2769 211.6C23.7091 199.203 11.8972 177.326 10.4741 151.397C10.1183 145.239 9.3356 133.49 23.9937 134.381C30.0419 134.705 39.6479 137.622 46.4077 139.567C54.8041 141.917 58.86 148.399 58.86 154.8C58.86 191.343 91.9474 215.489 106.392 215.489C112.583 215.489 110.306 222.134 107.602 222.863C102.834 224.159 96.7148 224.321 94.2244 224.321Z" fill="#263238"/>
|
|
6
|
+
<path d="M43.75 116.947C38.0259 115.921 32.445 113.554 27.0071 112.213C10.1926 108.031 13.0546 91.0665 14.6287 86.4112C29.9407 41.3568 78.5238 26.2861 117.734 22.262C154.654 18.4746 193.292 21.394 229.282 31.4149C232.216 32.2039 241.303 34.4132 236.079 39.8576C232.788 43.2505 219.98 39.6998 216.546 39.4631C195.438 37.885 174.545 37.6483 153.509 40.8834C131.257 44.2763 108.361 51.2988 89.972 66.1328C81.0997 73.3131 73.3006 82.466 68.0774 93.2758C66.7179 96.1164 65.6447 98.957 64.7145 101.798C63.7843 104.796 60.2783 119.867 43.75 116.947Z" fill="#263238"/>
|
|
7
|
+
<path d="M137.892 125.638C141.043 111.538 155.044 89.1945 198.377 90.7355C208.318 91.0437 203.768 97.8239 198.867 97.6698C174.365 96.8223 162.744 112.617 156.654 128.643C154.694 133.805 150.213 134.576 144.613 133.651C140.693 132.958 136.422 132.496 137.892 125.638Z" fill="#263238"/>
|
|
8
|
+
</svg>
|