@pega/dx-component-builder-sdk 0.26.1 → 0.26.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SECURITY.md +10 -0
- package/package.json +9 -1
- package/src/tasks/create/templates/Constellation/field/Date/date.ts.mustache +1 -1
- package/src/tasks/create/templates/Constellation/field/DateTime/date-utils.ts.mustache +1 -1
- package/src/tasks/create/templates/Constellation/field/DateTime/date.ts.mustache +1 -1
- package/src/tasks/create/templates/Constellation/field/Decimal-Percentage/index.tsx.mustache +1 -1
- package/src/tasks/create/templates/Constellation/field/Picklist-Autocomplete/repeat-utils.ts.mustache +1 -1
- package/src/tasks/create/templates/Constellation/field/Picklist-Autocomplete/textformat-utils.tsx.mustache +2 -3
- package/src/tasks/create/templates/Constellation/field/Picklist-RadioButtons/textformat-utils.tsx.mustache +2 -3
- package/src/tasks/create/templates/Constellation/field/Text-URL/text-url.tsx.mustache +2 -3
- package/src/tasks/create/templates/Constellation/field/TimeOfDay/time-of-day.ts.mustache +1 -1
- package/src/tasks/create/templates/Constellation/template/DETAILS/utils.js.mustache +1 -1
- package/src/tasks/create/templates/Constellation/template/DETAILS-region/utils.ts.mustache +1 -1
- package/src/tasks/create/templates/Constellation/template/PAGE/utils.ts.mustache +1 -1
- package/src/tasks/create/templates/SDK-Angular/field/Boolean/boolean.component.html.mustache +2 -2
- package/src/tasks/create/templates/SDK-Angular/field/Boolean/boolean.component.ts.mustache +0 -2
- package/src/tasks/create/templates/SDK-Angular/field/DateTime/date-time.component.ts.mustache +27 -0
- package/src/tasks/create/templates/SDK-Angular/field/Picklist-Autocomplete/picklist-autocomplete.component.ts.mustache +1 -1
- package/.access_token +0 -1
- package/.agilestudio +0 -3
- package/.eslintrc.json +0 -18
- package/.prettierignore +0 -2
- package/.prettierrc.json +0 -1
- package/cspell.json +0 -26
- package/jest.config.cjs +0 -26
- package/pega-dx-component-builder-sdk-0.26.1.tgz +0 -0
- package/pega-dx-component-builder-sdk-0.26.4.tgz +0 -0
package/SECURITY.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Reporting Security Issues
|
|
2
|
+
|
|
3
|
+
Pegasystems takes security seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
|
|
4
|
+
|
|
5
|
+
To report a security issue, [email us](mailto:opensource@pega.com;security@pega.com) and include the word "SECURITY" in the subject line.
|
|
6
|
+
|
|
7
|
+
The Pega team will send a response indicating the next steps in handling your report. We may ask for additional information or guidance.
|
|
8
|
+
|
|
9
|
+
## Learning More About Security
|
|
10
|
+
To learn more about securing a Pega application or our security capabilities, please see the [security article](https://community.pega.com/knowledgebase/capabilities/security) on Pega Community and the [Pega Trust Center](https://www.pega.com/products/cloud/pega-trust-center).
|
package/package.json
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pega/dx-component-builder-sdk",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.2",
|
|
4
4
|
"description": "Utility for building custom UI components",
|
|
5
5
|
"bin": "./bin/index.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"bin",
|
|
8
|
+
"src",
|
|
9
|
+
"tests",
|
|
10
|
+
"README.md",
|
|
11
|
+
"LICENSE",
|
|
12
|
+
"SECURITY.md"
|
|
13
|
+
],
|
|
6
14
|
"scripts": {
|
|
7
15
|
"lint:es": "eslint .",
|
|
8
16
|
"lint:format": "prettier -c .",
|
|
@@ -153,7 +153,7 @@ export const getDayJSObject = text => {
|
|
|
153
153
|
* @returns {object} relative time from now
|
|
154
154
|
*/
|
|
155
155
|
export const getRelativeTime = time => {
|
|
156
|
-
let relativetime
|
|
156
|
+
let relativetime: string;
|
|
157
157
|
if (dayjs(time).isUTC()) {
|
|
158
158
|
relativetime = dayjs(time).fromNow();
|
|
159
159
|
} else {
|
|
@@ -62,7 +62,7 @@ export const getDayJSObject = (text: string) => {
|
|
|
62
62
|
* @returns {object} relative time from now
|
|
63
63
|
*/
|
|
64
64
|
export const getRelativeTime = (time: string) => {
|
|
65
|
-
let relativetime
|
|
65
|
+
let relativetime: string;
|
|
66
66
|
if (dayjs(time).isUTC()) {
|
|
67
67
|
relativetime = dayjs(time).fromNow();
|
|
68
68
|
} else {
|
|
@@ -98,7 +98,7 @@ export const getDayJSObject = text => {
|
|
|
98
98
|
* @returns {object} relative time from now
|
|
99
99
|
*/
|
|
100
100
|
export const getRelativeTime = time => {
|
|
101
|
-
let relativetime
|
|
101
|
+
let relativetime: string;
|
|
102
102
|
if (dayjs(time).isUTC()) {
|
|
103
103
|
relativetime = dayjs(time).fromNow();
|
|
104
104
|
} else {
|
package/src/tasks/create/templates/Constellation/field/Decimal-Percentage/index.tsx.mustache
CHANGED
|
@@ -95,7 +95,7 @@ function {{COMPONENT_CLASS_NAME}}(props: {{COMPONENT_CLASS_NAME}}Props) {
|
|
|
95
95
|
|
|
96
96
|
if (displayMode === 'LABELS_LEFT' || displayMode === 'DISPLAY_ONLY') {
|
|
97
97
|
let unit = 'percent';
|
|
98
|
-
let displayComp: any
|
|
98
|
+
let displayComp: any;
|
|
99
99
|
|
|
100
100
|
if (isTableFormatter) {
|
|
101
101
|
switch (formatter) {
|
|
@@ -343,7 +343,7 @@ export function prepareFilters(keys = [], data = {}, logicOperator = '') {
|
|
|
343
343
|
const filterConditions = {};
|
|
344
344
|
keys.forEach((key, index) => {
|
|
345
345
|
const value = data[key];
|
|
346
|
-
let filterExpression
|
|
346
|
+
let filterExpression;
|
|
347
347
|
if (value) {
|
|
348
348
|
filterExpression = getFilterExpression(key, value, 'EQ');
|
|
349
349
|
} else {
|
|
@@ -33,7 +33,6 @@ const isImage = url => /\.(jpg|jpeg|png|webp|avif|gif|svg)$/.test(url);
|
|
|
33
33
|
const TableImage = imageProps => {
|
|
34
34
|
const { value, altText, altTextOfImage, propaltTextOfImage, urlLabelSelection, urlLabel, propUrlLabel } = imageProps;
|
|
35
35
|
const demoButtonRef = useRef(null);
|
|
36
|
-
let imageDisplayComp = null;
|
|
37
36
|
const [images, setImages] = useState(null);
|
|
38
37
|
const imgDescription = {
|
|
39
38
|
id: 'url',
|
|
@@ -60,7 +59,7 @@ const TableImage = imageProps => {
|
|
|
60
59
|
};
|
|
61
60
|
let btnVal = value;
|
|
62
61
|
btnVal = urlLabelVal(urlLabelSelection, btnVal, urlLabel, propUrlLabel);
|
|
63
|
-
imageDisplayComp = (
|
|
62
|
+
const imageDisplayComp = (
|
|
64
63
|
<>
|
|
65
64
|
{btnVal !== null && (
|
|
66
65
|
<Button ref={demoButtonRef} variant='link' compact={false} onClick={onClick} autoFocus>
|
|
@@ -125,7 +124,7 @@ export const urlFormatter = (value, options) => {
|
|
|
125
124
|
customWidth
|
|
126
125
|
} = options;
|
|
127
126
|
|
|
128
|
-
let urlFormatComp
|
|
127
|
+
let urlFormatComp;
|
|
129
128
|
if ((displayAs === 'labelText' || (isTableFormatter && tableDisplayAs === 'link')) && (urlLabel !== '' || propUrlLabel !== '')) {
|
|
130
129
|
urlFormatComp = (
|
|
131
130
|
<URLDisplay target='_blank' value={value} displayText={urlLabelSelection === 'constant' ? urlLabel : propUrlLabel} variant='link' />
|
|
@@ -33,7 +33,6 @@ const isImage = url => /\.(jpg|jpeg|png|webp|avif|gif|svg)$/.test(url);
|
|
|
33
33
|
const TableImage = imageProps => {
|
|
34
34
|
const { value, altText, altTextOfImage, propaltTextOfImage, urlLabelSelection, urlLabel, propUrlLabel } = imageProps;
|
|
35
35
|
const demoButtonRef = useRef(null);
|
|
36
|
-
let imageDisplayComp = null;
|
|
37
36
|
const [images, setImages] = useState(null);
|
|
38
37
|
const imgDescription = {
|
|
39
38
|
id: 'url',
|
|
@@ -60,7 +59,7 @@ const TableImage = imageProps => {
|
|
|
60
59
|
};
|
|
61
60
|
let btnVal = value;
|
|
62
61
|
btnVal = urlLabelVal(urlLabelSelection, btnVal, urlLabel, propUrlLabel);
|
|
63
|
-
imageDisplayComp = (
|
|
62
|
+
const imageDisplayComp = (
|
|
64
63
|
<>
|
|
65
64
|
{btnVal !== null && (
|
|
66
65
|
<Button ref={demoButtonRef} variant='link' compact={false} onClick={onClick} autoFocus>
|
|
@@ -125,7 +124,7 @@ export const urlFormatter = (value, options) => {
|
|
|
125
124
|
customWidth
|
|
126
125
|
} = options;
|
|
127
126
|
|
|
128
|
-
let urlFormatComp
|
|
127
|
+
let urlFormatComp;
|
|
129
128
|
if ((displayAs === 'labelText' || (isTableFormatter && tableDisplayAs === 'link')) && (urlLabel !== '' || propUrlLabel !== '')) {
|
|
130
129
|
urlFormatComp = (
|
|
131
130
|
<URLDisplay target='_blank' value={value} displayText={urlLabelSelection === 'constant' ? urlLabel : propUrlLabel} variant='link' />
|
|
@@ -33,7 +33,6 @@ const isImage = url => /\.(jpg|jpeg|png|webp|avif|gif|svg)$/.test(url);
|
|
|
33
33
|
const TableImage = imageProps => {
|
|
34
34
|
const { value, altText, altTextOfImage, propaltTextOfImage, urlLabelSelection, urlLabel, propUrlLabel } = imageProps;
|
|
35
35
|
const demoButtonRef = useRef(null);
|
|
36
|
-
let imageDisplayComp = null;
|
|
37
36
|
const [images, setImages] = useState(null);
|
|
38
37
|
const imgDescription = {
|
|
39
38
|
id: 'url',
|
|
@@ -60,7 +59,7 @@ const TableImage = imageProps => {
|
|
|
60
59
|
};
|
|
61
60
|
let btnVal = value;
|
|
62
61
|
btnVal = urlLabelVal(urlLabelSelection, btnVal, urlLabel, propUrlLabel);
|
|
63
|
-
imageDisplayComp = (
|
|
62
|
+
const imageDisplayComp = (
|
|
64
63
|
<Fragment>
|
|
65
64
|
{btnVal !== null && (
|
|
66
65
|
<Button ref={demoButtonRef} variant='link' compact={false} onClick={onClick} autoFocus>
|
|
@@ -129,7 +128,7 @@ export const urlFormatter = (value, options) => {
|
|
|
129
128
|
customWidth
|
|
130
129
|
} = options;
|
|
131
130
|
|
|
132
|
-
let urlFormatComp
|
|
131
|
+
let urlFormatComp;
|
|
133
132
|
if ((displayAs === 'labelText' || (isTableFormatter && tableDisplayAs === 'link')) && (urlLabel !== '' || propUrlLabel !== '')) {
|
|
134
133
|
urlFormatComp = (
|
|
135
134
|
<URLDisplay target='_blank' value={value} displayText={urlLabelSelection === 'constant' ? urlLabel : propUrlLabel} variant='link' />
|
|
@@ -62,7 +62,7 @@ export const getDayJSObject = (text: string) => {
|
|
|
62
62
|
* @returns {object} relative time from now
|
|
63
63
|
*/
|
|
64
64
|
export const getRelativeTime = (time: string) => {
|
|
65
|
-
let relativetime
|
|
65
|
+
let relativetime: string;
|
|
66
66
|
if (dayjs(time).isUTC()) {
|
|
67
67
|
relativetime = dayjs(time).fromNow();
|
|
68
68
|
} else {
|
package/src/tasks/create/templates/SDK-Angular/field/Boolean/boolean.component.html.mustache
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
</span>
|
|
21
21
|
</div>
|
|
22
22
|
<div *ngIf="selectionMode === 'multi'; else single">
|
|
23
|
-
<mat-option *ngFor="let item of listOfCheckboxes">
|
|
23
|
+
<div class="mat-mdc-option" *ngFor="let item of listOfCheckboxes">
|
|
24
24
|
<mat-checkbox
|
|
25
25
|
[labelPosition]="'after'"
|
|
26
26
|
[checked]="item.selected"
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
(blur)="fieldOnBlur($event)"
|
|
31
31
|
>{{ item.text ?? item.value }}
|
|
32
32
|
</mat-checkbox>
|
|
33
|
-
</
|
|
33
|
+
</div>
|
|
34
34
|
</div>
|
|
35
35
|
<ng-template #single>
|
|
36
36
|
<mat-checkbox
|
|
@@ -3,7 +3,6 @@ import { CommonModule } from '@angular/common';
|
|
|
3
3
|
import { ReactiveFormsModule } from '@angular/forms';
|
|
4
4
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
5
5
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
6
|
-
import { MatOptionModule } from '@angular/material/core';
|
|
7
6
|
import { FieldBase } from '@pega/angular-sdk-components';
|
|
8
7
|
import { FieldWarningDirective } from '@pega/angular-sdk-components';
|
|
9
8
|
import { ComponentMapperComponent } from '@pega/angular-sdk-components';
|
|
@@ -38,7 +37,6 @@ interface {{COMPONENT_CLASS_NAME}}Props extends Omit<PConnFieldProps, 'value'> {
|
|
|
38
37
|
ReactiveFormsModule,
|
|
39
38
|
MatCheckboxModule,
|
|
40
39
|
MatFormFieldModule,
|
|
41
|
-
MatOptionModule,
|
|
42
40
|
FieldWarningDirective,
|
|
43
41
|
forwardRef(() => ComponentMapperComponent)
|
|
44
42
|
]
|
package/src/tasks/create/templates/SDK-Angular/field/DateTime/date-time.component.ts.mustache
CHANGED
|
@@ -97,6 +97,12 @@ export class {{COMPONENT_CLASS_NAME}}Component extends FieldBase implements OnIn
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
fieldOnDateChange(event: any) {
|
|
100
|
+
// owl picker emits null when the typed text can't be parsed; clear the input instead of defaulting to now
|
|
101
|
+
if (!event.value) {
|
|
102
|
+
this.fieldControl.setValue('');
|
|
103
|
+
handleEvent(this.actionsApi, 'changeNblur', this.propName, '');
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
100
106
|
// this comes from the date pop up
|
|
101
107
|
if (typeof event.value === 'object') {
|
|
102
108
|
// convert date to pega "date" format
|
|
@@ -106,4 +112,25 @@ export class {{COMPONENT_CLASS_NAME}}Component extends FieldBase implements OnIn
|
|
|
106
112
|
}
|
|
107
113
|
handleEvent(this.actionsApi, 'changeNblur', this.propName, event.value);
|
|
108
114
|
}
|
|
115
|
+
|
|
116
|
+
override getErrorMessage() {
|
|
117
|
+
// look for validation messages for json, pre-defined or just an error pushed from workitem (400)
|
|
118
|
+
if (this.fieldControl.hasError('message')) {
|
|
119
|
+
return this.angularPConnectData.validateMessage ?? '';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (this.fieldControl.hasError('required')) {
|
|
123
|
+
return 'You must enter a value';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (this.fieldControl.hasError('owlDateTimeParse')) {
|
|
127
|
+
return `${this.fieldControl.errors?.['owlDateTimeParse'].text} is not a valid date time value`;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (this.fieldControl.errors) {
|
|
131
|
+
return 'Invalid date time value';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return '';
|
|
135
|
+
}
|
|
109
136
|
}
|
|
@@ -415,7 +415,7 @@ export class {{COMPONENT_CLASS_NAME}}Component extends FieldBase implements OnIn
|
|
|
415
415
|
let key = '';
|
|
416
416
|
if (val) {
|
|
417
417
|
const index = this.options$?.findIndex(element => element.value === val);
|
|
418
|
-
key = index > -1 ?
|
|
418
|
+
key = index > -1 ? this.options$[index].key : val;
|
|
419
419
|
}
|
|
420
420
|
const value = key;
|
|
421
421
|
handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
|
package/.access_token
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"access_token":"eyJraWQiOiJkYjVlMjE5MDZlNjA5NDQ4N2I1OTdhNjY2YWU3YjA3OSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJhdWQiOiJ1cm46MTI3ODI1ODAwMjM4NzAzMTE4NTEiLCJzdWIiOiJBZG1pbkBsb2FudjIiLCJhcHBfbmFtZSI6IkxvYW5WMiIsIm5iZiI6MTY3MDM1Mjc0OCwiYXBwX3ZlcnNpb24iOiIwMS4wMS4wMSIsImlzcyI6InVybjpsb2NhbGhvc3QiLCJleHAiOjE2NzAzNTYzNDgsImlhdCI6MTY3MDM1Mjc0OCwianRpIjoiYTU4MzcyOGVhNGIwNzRmZjU1ZjU3MmNmNzNmMzhlNWIiLCJvcGVyYXRvcl9hY2Nlc3MiOiJMb2FuVjI6QXV0aG9ycyJ9.LiLs5f9I_6z-wLHFM30Yj_VIExxCITbARGaIGd0cBrPyN-28BrJcMmEx783PwNgQhlnoYr2JoGS6sC11Xb5TC9p2lOrou0aOGwNrdpo5MDiZ450m3czLKAZWd1OVsX_FPYFWE6wLP-5u20cE25ShLyEnKF_5tjr_kYBbJJ4UNwfk8lqdaqDw_myJc44lYBz5Ou3jUIlIR3ykLBjRTJviua91hF4ntdzdlQJ8_eWqmTOrLzmlke7dUUlILtebFPCFpe5qEaYs5IskbVlFvKH32jl1_dG4k4uzmHPdhGhKZMRwWQ1MKu_xF0Rzm5dMo94A3w6JqLW_x9rVj0KyfCnvZO6IeXMncv-dXHQ5ejFwPh_m7-7Gj9Z7i-L7Hpn6Gq_xR72m-6P8--0yvl8RbddC4JbyHgIrZfidbJu_HhpOH6V3eijgZmvir-A7soFNWatZsro5Btlr7_uJqS0HBWtNqKfEV6IJFidi9UbfiImO1pr8X2lhVgHPmih6c_hkVsqY62bGyXwiJuPB87HkG3aybCf9SkeaqdhHdIWJBXxRd55HVDfkaFV1LQdRJqW31xaFZpp4Uaw3INjqhUTPbJZ7l-7uOPXQwrgZmhwNianMGzCa6tcZm2XmgiC4KzQJUHfNPMbhiPCsKm8pjwIylK2hZvsnA9qmNTxm9YSB4SskIGs","token_type":"bearer","expires_in":3600}
|
package/.agilestudio
DELETED
package/.eslintrc.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"root": true,
|
|
3
|
-
"extends": ["@pega"],
|
|
4
|
-
"ignorePatterns": ["node_modules", "**/template/**"],
|
|
5
|
-
"env": {
|
|
6
|
-
"browser": false,
|
|
7
|
-
"node": true
|
|
8
|
-
},
|
|
9
|
-
"rules": {
|
|
10
|
-
"prettier/prettier": "off",
|
|
11
|
-
"sonarjs/cognitive-complexity": "off",
|
|
12
|
-
"sonarjs/no-identical-functions": "off",
|
|
13
|
-
"sonarjs/no-duplicate-string": "off",
|
|
14
|
-
"sonarjs/no-nested-template-literals": "off",
|
|
15
|
-
"no-console": "off",
|
|
16
|
-
"import/extensions": ["error", "ignorePackages"]
|
|
17
|
-
}
|
|
18
|
-
}
|
package/.prettierignore
DELETED
package/.prettierrc.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"@pega/prettier-config"
|
package/cspell.json
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": "0.2",
|
|
3
|
-
"import": "@pega/cspell-config",
|
|
4
|
-
"language": "en-US",
|
|
5
|
-
"ignorePaths": [
|
|
6
|
-
"package-lock.json",
|
|
7
|
-
"**/*.tsbuildinfo",
|
|
8
|
-
"**/node_modules/**",
|
|
9
|
-
"**/.DS_Store",
|
|
10
|
-
"**/*.zip",
|
|
11
|
-
"**/*.tgz"
|
|
12
|
-
],
|
|
13
|
-
"words": [
|
|
14
|
-
"avif",
|
|
15
|
-
"datapage",
|
|
16
|
-
"datasource",
|
|
17
|
-
"execa",
|
|
18
|
-
"listr",
|
|
19
|
-
"pascalcase",
|
|
20
|
-
"picklist",
|
|
21
|
-
"prpc",
|
|
22
|
-
"rawlist",
|
|
23
|
-
"ruleset",
|
|
24
|
-
"storysource"
|
|
25
|
-
]
|
|
26
|
-
}
|
package/jest.config.cjs
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
verbose: true,
|
|
3
|
-
roots: ['./tests'],
|
|
4
|
-
moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx'],
|
|
5
|
-
testEnvironment: 'jsdom',
|
|
6
|
-
transform: {
|
|
7
|
-
'^.+\\.[t|j]sx?$': 'babel-jest'
|
|
8
|
-
},
|
|
9
|
-
collectCoverage: true,
|
|
10
|
-
haste: {
|
|
11
|
-
retainAllFiles: true
|
|
12
|
-
},
|
|
13
|
-
testPathIgnorePatterns: [],
|
|
14
|
-
transformIgnorePatterns: [],
|
|
15
|
-
modulePathIgnorePatterns: [],
|
|
16
|
-
coveragePathIgnorePatterns: [],
|
|
17
|
-
collectCoverageFrom: ['./src/*.js'],
|
|
18
|
-
coverageThreshold: {
|
|
19
|
-
global: {
|
|
20
|
-
statements: 79,
|
|
21
|
-
branches: 74,
|
|
22
|
-
functions: 81,
|
|
23
|
-
lines: 80
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
};
|
|
Binary file
|
|
Binary file
|