@tylertech/forge 3.5.1 → 3.6.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/custom-elements.json +287 -198
- package/dist/checkbox/forge-checkbox.css +1 -0
- package/dist/lib.js +27 -19
- package/dist/lib.js.map +4 -4
- package/dist/radio/forge-radio.css +2 -0
- package/dist/switch/forge-switch.css +2 -0
- package/dist/vscode.css-custom-data.json +15 -0
- package/dist/vscode.html-custom-data.json +32 -47
- package/esm/app-bar/profile-button/app-bar-profile-button.js +5 -2
- package/esm/avatar/avatar-constants.d.ts +0 -7
- package/esm/avatar/avatar-constants.js +1 -10
- package/esm/avatar/avatar.d.ts +24 -21
- package/esm/avatar/avatar.js +68 -45
- package/esm/avatar/index.d.ts +1 -3
- package/esm/avatar/index.js +4 -6
- package/esm/button/base/base-button-adapter.js +1 -1
- package/esm/button-area/button-area.js +1 -1
- package/esm/checkbox/checkbox.d.ts +1 -0
- package/esm/checkbox/checkbox.js +2 -1
- package/esm/dialog/dialog-adapter.d.ts +7 -0
- package/esm/dialog/dialog-adapter.js +43 -19
- package/esm/dialog/dialog-constants.d.ts +6 -0
- package/esm/dialog/dialog-constants.js +6 -2
- package/esm/dialog/dialog-core.d.ts +8 -0
- package/esm/dialog/dialog-core.js +21 -1
- package/esm/dialog/dialog.d.ts +15 -0
- package/esm/dialog/dialog.js +14 -1
- package/esm/icon-button/icon-button-constants.d.ts +4 -0
- package/esm/icon-button/icon-button-constants.js +2 -0
- package/esm/icon-button/icon-button-core.d.ts +4 -4
- package/esm/icon-button/icon-button-core.js +16 -14
- package/esm/icon-button/icon-button.d.ts +32 -29
- package/esm/icon-button/icon-button.js +6 -31
- package/esm/profile-card/profile-card.js +5 -2
- package/esm/radio/radio/radio.d.ts +1 -0
- package/esm/radio/radio/radio.js +2 -1
- package/esm/split-view/split-view/split-view-adapter.js +1 -0
- package/esm/split-view/split-view-panel/split-view-panel.js +1 -1
- package/esm/switch/switch-adapter.d.ts +4 -4
- package/esm/switch/switch-adapter.js +5 -5
- package/esm/switch/switch-component-delegate.d.ts +7 -0
- package/esm/switch/switch-component-delegate.js +15 -0
- package/esm/switch/switch-constants.d.ts +10 -0
- package/esm/switch/switch-constants.js +5 -0
- package/esm/switch/switch-core.d.ts +9 -9
- package/esm/switch/switch-core.js +26 -25
- package/esm/switch/switch.d.ts +23 -7
- package/esm/switch/switch.js +26 -17
- package/esm/table/table-utils.js +6 -6
- package/esm/tabs/tab-bar/tab-bar-adapter.d.ts +0 -5
- package/esm/tabs/tab-bar/tab-bar-adapter.js +3 -11
- package/esm/tabs/tab-bar/tab-bar-constants.d.ts +0 -3
- package/esm/tabs/tab-bar/tab-bar-constants.js +0 -4
- package/esm/tabs/tab-bar/tab-bar-core.js +7 -7
- package/esm/tabs/tab-bar/tab-bar.d.ts +6 -3
- package/esm/tabs/tab-bar/tab-bar.js +6 -3
- package/package.json +1 -1
- package/sass/button-area/_core.scss +3 -0
- package/sass/checkbox/_core.scss +2 -2
- package/sass/core/styles/tokens/checkbox/_tokens.scss +1 -0
- package/sass/core/styles/tokens/radio/_tokens.scss +1 -0
- package/sass/core/styles/tokens/switch/_tokens.scss +1 -0
- package/sass/dialog/dialog.scss +5 -0
- package/sass/icon-button/icon-button.scss +10 -10
- package/sass/radio/radio/_core.scss +2 -2
- package/sass/switch/_core.scss +2 -2
- package/sass/switch/switch.scss +2 -2
- package/esm/avatar/avatar-adapter.d.ts +0 -36
- package/esm/avatar/avatar-adapter.js +0 -55
- package/esm/avatar/avatar-core.d.ts +0 -38
- package/esm/avatar/avatar-core.js +0 -101
|
@@ -38,6 +38,7 @@ $tokens: (
|
|
|
38
38
|
// Label
|
|
39
39
|
gap: utils.module-val(checkbox, gap, 0),
|
|
40
40
|
justify: utils.module-val(checkbox, justify, start),
|
|
41
|
+
align: utils.module-val(checkbox, align, center),
|
|
41
42
|
direction: utils.module-val(checkbox, direction, initial),
|
|
42
43
|
// State layer
|
|
43
44
|
state-layer-width: utils.module-ref(checkbox, state-layer-width, state-layer-size),
|
|
@@ -33,6 +33,7 @@ $tokens: (
|
|
|
33
33
|
// Label
|
|
34
34
|
gap: utils.module-val(radio, gap, 0),
|
|
35
35
|
justify: utils.module-val(radio, justify, start),
|
|
36
|
+
align: utils.module-val(radio, align, center),
|
|
36
37
|
direction: utils.module-val(radio, direction, initial),
|
|
37
38
|
// State layer
|
|
38
39
|
state-layer-width: utils.module-ref(radio, state-layer-width, state-layer-size),
|
|
@@ -52,6 +52,7 @@ $tokens: (
|
|
|
52
52
|
// Label
|
|
53
53
|
gap: utils.module-val(switch, gap, 0),
|
|
54
54
|
justify: utils.module-val(switch, justify, start),
|
|
55
|
+
align: utils.module-val(switch, align, center),
|
|
55
56
|
direction: utils.module-val(switch, direction, initial),
|
|
56
57
|
// State layer
|
|
57
58
|
state-layer-width: utils.module-ref(switch, state-layer-width, state-layer-size),
|
package/sass/dialog/dialog.scss
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* License: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
@use './core' as *;
|
|
7
|
+
@use '../utils/mixins' as utils;
|
|
7
8
|
@use './animations';
|
|
8
9
|
@use '../backdrop';
|
|
9
10
|
@use '../core/styles/theme';
|
|
@@ -55,6 +56,10 @@ $can-animate: '[visible]:not([animation-type=none])';
|
|
|
55
56
|
@include surface;
|
|
56
57
|
}
|
|
57
58
|
|
|
59
|
+
.visually-hidden {
|
|
60
|
+
@include utils.visually-hidden;
|
|
61
|
+
}
|
|
62
|
+
|
|
58
63
|
//
|
|
59
64
|
// Backdrop
|
|
60
65
|
//
|
|
@@ -131,49 +131,49 @@ forge-state-layer {
|
|
|
131
131
|
// Toggle
|
|
132
132
|
//
|
|
133
133
|
|
|
134
|
-
:host(:is(:not([toggle]), [toggle]:not([
|
|
134
|
+
:host(:is(:not([toggle]), [toggle]:not([pressed]))) {
|
|
135
135
|
slot[name='on'] {
|
|
136
136
|
display: none;
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
:host([toggle][
|
|
140
|
+
:host([toggle][pressed]) {
|
|
141
141
|
slot:not([name]) {
|
|
142
142
|
display: none;
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
:host([toggle][
|
|
146
|
+
:host([toggle][pressed]:is(:not([variant]), [variant='icon'])) {
|
|
147
147
|
.forge-icon-button {
|
|
148
148
|
@include toggle-on-icon;
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
:host([toggle][
|
|
152
|
+
:host([toggle][pressed][variant='outlined']) {
|
|
153
153
|
.forge-icon-button {
|
|
154
154
|
@include toggle-on-outlined;
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
:host([toggle]:not([
|
|
158
|
+
:host([toggle]:not([pressed])[variant='tonal']) {
|
|
159
159
|
.forge-icon-button {
|
|
160
160
|
@include toggle-tonal;
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
:host([toggle][
|
|
164
|
+
:host([toggle][pressed][variant='tonal']) {
|
|
165
165
|
.forge-icon-button {
|
|
166
166
|
@include toggle-on-tonal;
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
:host([toggle]:not([
|
|
170
|
+
:host([toggle]:not([pressed]):is([variant='filled'], [variant='raised'])) {
|
|
171
171
|
.forge-icon-button {
|
|
172
172
|
@include toggle-filled;
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
:host([toggle][
|
|
176
|
+
:host([toggle][pressed]:is([variant='filled'], [variant='raised'])) {
|
|
177
177
|
.forge-icon-button {
|
|
178
178
|
@include toggle-on-filled;
|
|
179
179
|
}
|
|
@@ -323,7 +323,7 @@ forge-state-layer {
|
|
|
323
323
|
}
|
|
324
324
|
|
|
325
325
|
// Toggle + tonal variant
|
|
326
|
-
:host([toggle]:not([
|
|
326
|
+
:host([toggle]:not([pressed])[theme='#{$theme}'][variant='tonal']) {
|
|
327
327
|
.forge-icon-button {
|
|
328
328
|
@include override(background-color, theme.variable(#{$theme}-container), value);
|
|
329
329
|
}
|
|
@@ -346,7 +346,7 @@ forge-state-layer {
|
|
|
346
346
|
}
|
|
347
347
|
|
|
348
348
|
// Toggle + filled & raised variants
|
|
349
|
-
:host([toggle]:not([
|
|
349
|
+
:host([toggle]:not([pressed])[theme='#{$theme}']:is([variant='filled'], [variant='raised'])) {
|
|
350
350
|
.forge-icon-button {
|
|
351
351
|
@include override(icon-color, theme.variable($theme), value);
|
|
352
352
|
@include override(background-color, theme.variable(#{$theme}-container), value);
|
|
@@ -16,8 +16,7 @@
|
|
|
16
16
|
@mixin radio {
|
|
17
17
|
position: relative;
|
|
18
18
|
flex-direction: #{token(direction)};
|
|
19
|
-
|
|
20
|
-
align-items: center;
|
|
19
|
+
align-items: #{token(align)};
|
|
21
20
|
justify-content: #{token(justify)};
|
|
22
21
|
gap: #{token(gap)};
|
|
23
22
|
|
|
@@ -34,6 +33,7 @@
|
|
|
34
33
|
justify-content: center;
|
|
35
34
|
|
|
36
35
|
display: flex;
|
|
36
|
+
flex-shrink: 0;
|
|
37
37
|
|
|
38
38
|
border-radius: #{token(shape)};
|
|
39
39
|
inline-size: #{token(state-layer-width)};
|
package/sass/switch/_core.scss
CHANGED
|
@@ -36,8 +36,7 @@ $_handle-on-translate: calc(#{token(track-width)} - #{$_track-border-radius} * 2
|
|
|
36
36
|
position: relative;
|
|
37
37
|
|
|
38
38
|
flex-direction: #{token(direction)};
|
|
39
|
-
|
|
40
|
-
align-items: center;
|
|
39
|
+
align-items: #{token(align)};
|
|
41
40
|
justify-content: #{token(justify)};
|
|
42
41
|
gap: #{token(gap)};
|
|
43
42
|
}
|
|
@@ -65,6 +64,7 @@ $_handle-on-translate: calc(#{token(track-width)} - #{$_track-border-radius} * 2
|
|
|
65
64
|
align-items: center;
|
|
66
65
|
|
|
67
66
|
display: flex;
|
|
67
|
+
flex-shrink: 0;
|
|
68
68
|
|
|
69
69
|
block-size: #{$_container-block-size};
|
|
70
70
|
|
package/sass/switch/switch.scss
CHANGED
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
// On
|
|
84
|
-
:host([
|
|
84
|
+
:host([checked]) {
|
|
85
85
|
.track {
|
|
86
86
|
@include track-on;
|
|
87
87
|
}
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
|
-
:host(:not([disabled]):not([readonly])[
|
|
130
|
+
:host(:not([disabled]):not([readonly])[checked]) {
|
|
131
131
|
.forge-switch {
|
|
132
132
|
.container:active {
|
|
133
133
|
.track {
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright Tyler Technologies, Inc.
|
|
4
|
-
* License: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
import { BaseAdapter, IBaseAdapter } from '../core/base/base-adapter';
|
|
7
|
-
import { IAvatarComponent } from './avatar';
|
|
8
|
-
export interface IAvatarAdapter extends IBaseAdapter {
|
|
9
|
-
setBackgroundImageUrl(url: string): Promise<boolean>;
|
|
10
|
-
removeBackgroundImage(): void;
|
|
11
|
-
setText(value: string): void;
|
|
12
|
-
clearText(): void;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* The DOM adapter behind the `<forge-avatar>` element.
|
|
16
|
-
*/
|
|
17
|
-
export declare class AvatarAdapter extends BaseAdapter<IAvatarComponent> implements IAvatarAdapter {
|
|
18
|
-
private _root;
|
|
19
|
-
private _defaultSlot;
|
|
20
|
-
constructor(component: IAvatarComponent);
|
|
21
|
-
/**
|
|
22
|
-
* Sets the background image URL.
|
|
23
|
-
* @param url The URL.
|
|
24
|
-
*/
|
|
25
|
-
setBackgroundImageUrl(url: string): Promise<boolean>;
|
|
26
|
-
/**
|
|
27
|
-
* Removes the background image URL.
|
|
28
|
-
*/
|
|
29
|
-
removeBackgroundImage(): void;
|
|
30
|
-
/**
|
|
31
|
-
* Sets the avatar text content.
|
|
32
|
-
* @param value The text value.
|
|
33
|
-
*/
|
|
34
|
-
setText(value: string): void;
|
|
35
|
-
clearText(): void;
|
|
36
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright Tyler Technologies, Inc.
|
|
4
|
-
* License: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
import { getShadowElement, removeAllChildren } from '@tylertech/forge-core';
|
|
7
|
-
import { BaseAdapter } from '../core/base/base-adapter';
|
|
8
|
-
import { AVATAR_CONSTANTS } from './avatar-constants';
|
|
9
|
-
/**
|
|
10
|
-
* The DOM adapter behind the `<forge-avatar>` element.
|
|
11
|
-
*/
|
|
12
|
-
export class AvatarAdapter extends BaseAdapter {
|
|
13
|
-
constructor(component) {
|
|
14
|
-
super(component);
|
|
15
|
-
this._root = getShadowElement(this._component, AVATAR_CONSTANTS.selectors.ROOT);
|
|
16
|
-
this._defaultSlot = getShadowElement(this._component, AVATAR_CONSTANTS.selectors.DEFAULT_SLOT);
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Sets the background image URL.
|
|
20
|
-
* @param url The URL.
|
|
21
|
-
*/
|
|
22
|
-
async setBackgroundImageUrl(url) {
|
|
23
|
-
// Set before loading image to prevent a flash of background color
|
|
24
|
-
this._root.classList.add('forge-avatar--image');
|
|
25
|
-
return new Promise(resolve => {
|
|
26
|
-
const image = new Image();
|
|
27
|
-
image.onload = () => {
|
|
28
|
-
this._root.style.backgroundImage = `url(${image.src})`;
|
|
29
|
-
resolve(true);
|
|
30
|
-
};
|
|
31
|
-
image.onerror = () => {
|
|
32
|
-
this._root.classList.remove('forge-avatar--image');
|
|
33
|
-
resolve(false);
|
|
34
|
-
};
|
|
35
|
-
image.src = url;
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Removes the background image URL.
|
|
40
|
-
*/
|
|
41
|
-
removeBackgroundImage() {
|
|
42
|
-
this._root.style.removeProperty('background-image');
|
|
43
|
-
this._root.classList.remove('forge-avatar--image');
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Sets the avatar text content.
|
|
47
|
-
* @param value The text value.
|
|
48
|
-
*/
|
|
49
|
-
setText(value) {
|
|
50
|
-
this._defaultSlot.textContent = value;
|
|
51
|
-
}
|
|
52
|
-
clearText() {
|
|
53
|
-
removeAllChildren(this._defaultSlot);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright Tyler Technologies, Inc.
|
|
4
|
-
* License: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
import { IAvatarAdapter } from './avatar-adapter';
|
|
7
|
-
export interface IAvatarCore {
|
|
8
|
-
imageUrl: string;
|
|
9
|
-
text: string;
|
|
10
|
-
letterCount: number;
|
|
11
|
-
}
|
|
12
|
-
export declare class AvatarCore implements IAvatarCore {
|
|
13
|
-
private _adapter;
|
|
14
|
-
private _imageUrl;
|
|
15
|
-
private _text;
|
|
16
|
-
private _letterCount;
|
|
17
|
-
private _initialized;
|
|
18
|
-
constructor(_adapter: IAvatarAdapter);
|
|
19
|
-
initialize(): void;
|
|
20
|
-
destroy(): void;
|
|
21
|
-
private _render;
|
|
22
|
-
private _setBackgroundImageUrl;
|
|
23
|
-
private _setText;
|
|
24
|
-
/**
|
|
25
|
-
* Gets the text content to display in the avatar.
|
|
26
|
-
* @param {string} value The text to parse.
|
|
27
|
-
*/
|
|
28
|
-
private _getTextContent;
|
|
29
|
-
/** Gets/sets the text to display. */
|
|
30
|
-
get text(): string;
|
|
31
|
-
set text(value: string);
|
|
32
|
-
/** Controls the number of letters to display from the text. By default the text is split on spaces and the first character of each word is used. */
|
|
33
|
-
get letterCount(): number;
|
|
34
|
-
set letterCount(value: number);
|
|
35
|
-
/** Sets the background image URL to use. */
|
|
36
|
-
get imageUrl(): string;
|
|
37
|
-
set imageUrl(value: string);
|
|
38
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright Tyler Technologies, Inc.
|
|
4
|
-
* License: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
import { isDefined, isString } from '@tylertech/forge-core';
|
|
7
|
-
import { AVATAR_CONSTANTS } from './avatar-constants';
|
|
8
|
-
export class AvatarCore {
|
|
9
|
-
constructor(_adapter) {
|
|
10
|
-
this._adapter = _adapter;
|
|
11
|
-
this._text = '';
|
|
12
|
-
this._letterCount = AVATAR_CONSTANTS.numbers.DEFAULT_LETTER_COUNT;
|
|
13
|
-
this._initialized = false;
|
|
14
|
-
}
|
|
15
|
-
initialize() {
|
|
16
|
-
this._render();
|
|
17
|
-
this._initialized = true;
|
|
18
|
-
}
|
|
19
|
-
destroy() {
|
|
20
|
-
this._initialized = false;
|
|
21
|
-
}
|
|
22
|
-
_render() {
|
|
23
|
-
this._setText();
|
|
24
|
-
this._setBackgroundImageUrl();
|
|
25
|
-
}
|
|
26
|
-
async _setBackgroundImageUrl() {
|
|
27
|
-
if (this._imageUrl) {
|
|
28
|
-
if (await this._adapter.setBackgroundImageUrl(this._imageUrl)) {
|
|
29
|
-
this._adapter.clearText();
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
this._adapter.removeBackgroundImage();
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
_setText() {
|
|
37
|
-
const data = this._getTextContent(this._text, this._letterCount);
|
|
38
|
-
if (data) {
|
|
39
|
-
this._adapter.setText(data);
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
this._adapter.clearText();
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Gets the text content to display in the avatar.
|
|
47
|
-
* @param {string} value The text to parse.
|
|
48
|
-
*/
|
|
49
|
-
_getTextContent(value, count) {
|
|
50
|
-
if (!value || !isString(value) || count <= 0) {
|
|
51
|
-
return '';
|
|
52
|
-
}
|
|
53
|
-
let text;
|
|
54
|
-
if (count === 1) {
|
|
55
|
-
text = value[0].toUpperCase();
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
const words = value.match(/\S+/g) || [];
|
|
59
|
-
text = words.slice(0, count).reduce((prev, curr) => (prev += curr[0].toUpperCase()), '');
|
|
60
|
-
}
|
|
61
|
-
return text;
|
|
62
|
-
}
|
|
63
|
-
/** Gets/sets the text to display. */
|
|
64
|
-
get text() {
|
|
65
|
-
return this._text;
|
|
66
|
-
}
|
|
67
|
-
set text(value) {
|
|
68
|
-
if (this._text !== value) {
|
|
69
|
-
this._text = value || '';
|
|
70
|
-
this._adapter.setHostAttribute(AVATAR_CONSTANTS.attributes.TEXT, this._text);
|
|
71
|
-
if (this._initialized) {
|
|
72
|
-
this._render();
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
/** Controls the number of letters to display from the text. By default the text is split on spaces and the first character of each word is used. */
|
|
77
|
-
get letterCount() {
|
|
78
|
-
return this._letterCount;
|
|
79
|
-
}
|
|
80
|
-
set letterCount(value) {
|
|
81
|
-
if (this._letterCount !== value) {
|
|
82
|
-
this._letterCount = value;
|
|
83
|
-
this._adapter.setHostAttribute(AVATAR_CONSTANTS.attributes.LETTER_COUNT, isDefined(this._letterCount) ? this._letterCount.toString() : '');
|
|
84
|
-
if (this._initialized) {
|
|
85
|
-
this._render();
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
/** Sets the background image URL to use. */
|
|
90
|
-
get imageUrl() {
|
|
91
|
-
return this._imageUrl;
|
|
92
|
-
}
|
|
93
|
-
set imageUrl(value) {
|
|
94
|
-
if (this._imageUrl !== value) {
|
|
95
|
-
this._imageUrl = value;
|
|
96
|
-
if (this._initialized) {
|
|
97
|
-
this._render();
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|