@webex/webex-core 3.0.0-beta.2 → 3.0.0-beta.200
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.js +1 -11
- package/dist/config.js.map +1 -1
- package/dist/credentials-config.js +44 -64
- package/dist/credentials-config.js.map +1 -1
- package/dist/index.js +0 -76
- package/dist/index.js.map +1 -1
- package/dist/interceptors/auth.js +22 -55
- package/dist/interceptors/auth.js.map +1 -1
- package/dist/interceptors/default-options.js +0 -20
- package/dist/interceptors/default-options.js.map +1 -1
- package/dist/interceptors/embargo.js +0 -21
- package/dist/interceptors/embargo.js.map +1 -1
- package/dist/interceptors/network-timing.js +2 -21
- package/dist/interceptors/network-timing.js.map +1 -1
- package/dist/interceptors/payload-transformer.js +2 -22
- package/dist/interceptors/payload-transformer.js.map +1 -1
- package/dist/interceptors/rate-limit.js +25 -57
- package/dist/interceptors/rate-limit.js.map +1 -1
- package/dist/interceptors/redirect.js +4 -33
- package/dist/interceptors/redirect.js.map +1 -1
- package/dist/interceptors/request-event.js +3 -30
- package/dist/interceptors/request-event.js.map +1 -1
- package/dist/interceptors/request-logger.js +1 -30
- package/dist/interceptors/request-logger.js.map +1 -1
- package/dist/interceptors/request-timing.js +3 -22
- package/dist/interceptors/request-timing.js.map +1 -1
- package/dist/interceptors/response-logger.js +2 -31
- package/dist/interceptors/response-logger.js.map +1 -1
- package/dist/interceptors/user-agent.js +2 -29
- package/dist/interceptors/user-agent.js.map +1 -1
- package/dist/interceptors/webex-tracking-id.js +5 -28
- package/dist/interceptors/webex-tracking-id.js.map +1 -1
- package/dist/interceptors/webex-user-agent.js +5 -38
- package/dist/interceptors/webex-user-agent.js.map +1 -1
- package/dist/lib/batcher.js +3 -51
- package/dist/lib/batcher.js.map +1 -1
- package/dist/lib/credentials/credentials.js +55 -119
- package/dist/lib/credentials/credentials.js.map +1 -1
- package/dist/lib/credentials/grant-errors.js +0 -49
- package/dist/lib/credentials/grant-errors.js.map +1 -1
- package/dist/lib/credentials/index.js +1 -13
- package/dist/lib/credentials/index.js.map +1 -1
- package/dist/lib/credentials/scope.js +1 -7
- package/dist/lib/credentials/scope.js.map +1 -1
- package/dist/lib/credentials/token-collection.js +1 -7
- package/dist/lib/credentials/token-collection.js.map +1 -1
- package/dist/lib/credentials/token.js +39 -118
- package/dist/lib/credentials/token.js.map +1 -1
- package/dist/lib/page.js +13 -26
- package/dist/lib/page.js.map +1 -1
- package/dist/lib/services/constants.js +0 -2
- package/dist/lib/services/constants.js.map +1 -1
- package/dist/lib/services/index.js +1 -28
- package/dist/lib/services/index.js.map +1 -1
- package/dist/lib/services/interceptors/server-error.js +2 -23
- package/dist/lib/services/interceptors/server-error.js.map +1 -1
- package/dist/lib/services/interceptors/service.js +12 -34
- package/dist/lib/services/interceptors/service.js.map +1 -1
- package/dist/lib/services/metrics.js +0 -2
- package/dist/lib/services/metrics.js.map +1 -1
- package/dist/lib/services/service-catalog.js +10 -90
- package/dist/lib/services/service-catalog.js.map +1 -1
- package/dist/lib/services/service-fed-ramp.js +0 -2
- package/dist/lib/services/service-fed-ramp.js.map +1 -1
- package/dist/lib/services/service-host.js +47 -62
- package/dist/lib/services/service-host.js.map +1 -1
- package/dist/lib/services/service-registry.js +78 -90
- package/dist/lib/services/service-registry.js.map +1 -1
- package/dist/lib/services/service-state.js +3 -15
- package/dist/lib/services/service-state.js.map +1 -1
- package/dist/lib/services/service-url.js +4 -25
- package/dist/lib/services/service-url.js.map +1 -1
- package/dist/lib/services/services.js +122 -238
- package/dist/lib/services/services.js.map +1 -1
- package/dist/lib/stateless-webex-plugin.js +5 -28
- package/dist/lib/stateless-webex-plugin.js.map +1 -1
- package/dist/lib/storage/decorators.js +19 -62
- package/dist/lib/storage/decorators.js.map +1 -1
- package/dist/lib/storage/errors.js +0 -23
- package/dist/lib/storage/errors.js.map +1 -1
- package/dist/lib/storage/index.js +2 -16
- package/dist/lib/storage/index.js.map +1 -1
- package/dist/lib/storage/make-webex-plugin-store.js +11 -41
- package/dist/lib/storage/make-webex-plugin-store.js.map +1 -1
- package/dist/lib/storage/make-webex-store.js +8 -30
- package/dist/lib/storage/make-webex-store.js.map +1 -1
- package/dist/lib/storage/memory-store-adapter.js +1 -19
- package/dist/lib/storage/memory-store-adapter.js.map +1 -1
- package/dist/lib/webex-core-plugin-mixin.js +9 -29
- package/dist/lib/webex-core-plugin-mixin.js.map +1 -1
- package/dist/lib/webex-http-error.js +1 -31
- package/dist/lib/webex-http-error.js.map +1 -1
- package/dist/lib/webex-internal-core-plugin-mixin.js +9 -29
- package/dist/lib/webex-internal-core-plugin-mixin.js.map +1 -1
- package/dist/lib/webex-plugin.js +6 -40
- package/dist/lib/webex-plugin.js.map +1 -1
- package/dist/plugins/logger.js +3 -17
- package/dist/plugins/logger.js.map +1 -1
- package/dist/webex-core.js +84 -203
- package/dist/webex-core.js.map +1 -1
- package/dist/webex-internal-core.js +0 -10
- package/dist/webex-internal-core.js.map +1 -1
- package/package.json +14 -14
- package/src/config.js +9 -11
- package/src/credentials-config.js +110 -72
- package/src/index.js +4 -14
- package/src/interceptors/auth.js +36 -37
- package/src/interceptors/default-options.js +0 -1
- package/src/interceptors/embargo.js +1 -1
- package/src/interceptors/payload-transformer.js +1 -2
- package/src/interceptors/rate-limit.js +8 -5
- package/src/interceptors/redirect.js +14 -8
- package/src/interceptors/request-event.js +4 -8
- package/src/interceptors/request-logger.js +8 -5
- package/src/interceptors/response-logger.js +11 -8
- package/src/interceptors/user-agent.js +1 -2
- package/src/interceptors/webex-user-agent.js +3 -9
- package/src/lib/batcher.js +70 -69
- package/src/lib/credentials/credentials.js +131 -122
- package/src/lib/credentials/grant-errors.js +6 -7
- package/src/lib/credentials/index.js +1 -4
- package/src/lib/credentials/scope.js +1 -4
- package/src/lib/credentials/token-collection.js +1 -1
- package/src/lib/credentials/token.js +86 -80
- package/src/lib/page.js +10 -11
- package/src/lib/services/constants.js +3 -13
- package/src/lib/services/index.js +2 -2
- package/src/lib/services/interceptors/server-error.js +12 -7
- package/src/lib/services/interceptors/service.js +6 -5
- package/src/lib/services/metrics.js +1 -1
- package/src/lib/services/service-catalog.js +110 -100
- package/src/lib/services/service-fed-ramp.js +1 -2
- package/src/lib/services/service-host.js +10 -17
- package/src/lib/services/service-registry.js +69 -96
- package/src/lib/services/service-state.js +4 -6
- package/src/lib/services/service-url.js +24 -23
- package/src/lib/services/services.js +260 -251
- package/src/lib/stateless-webex-plugin.js +4 -2
- package/src/lib/storage/decorators.js +68 -66
- package/src/lib/storage/index.js +4 -6
- package/src/lib/storage/make-webex-plugin-store.js +34 -21
- package/src/lib/storage/make-webex-store.js +6 -7
- package/src/lib/storage/memory-store-adapter.js +3 -3
- package/src/lib/webex-core-plugin-mixin.js +10 -7
- package/src/lib/webex-http-error.js +7 -8
- package/src/lib/webex-internal-core-plugin-mixin.js +9 -6
- package/src/lib/webex-plugin.js +41 -34
- package/src/plugins/logger.js +8 -3
- package/src/webex-core.js +198 -117
- package/src/webex-internal-core.js +15 -9
- package/test/integration/spec/credentials/credentials.js +26 -30
- package/test/integration/spec/credentials/token.js +36 -33
- package/test/integration/spec/services/service-catalog.js +177 -156
- package/test/integration/spec/services/services.js +313 -304
- package/test/integration/spec/webex-core.js +98 -86
- package/test/unit/spec/_setup.js +26 -18
- package/test/unit/spec/credentials/credentials.js +217 -154
- package/test/unit/spec/credentials/token.js +94 -76
- package/test/unit/spec/interceptors/auth.js +291 -243
- package/test/unit/spec/interceptors/default-options.js +36 -24
- package/test/unit/spec/interceptors/embargo.js +32 -27
- package/test/unit/spec/interceptors/network-timing.js +2 -2
- package/test/unit/spec/interceptors/payload-transformer.js +61 -52
- package/test/unit/spec/interceptors/rate-limit.js +104 -75
- package/test/unit/spec/interceptors/redirect.js +22 -20
- package/test/unit/spec/interceptors/request-timing.js +18 -22
- package/test/unit/spec/interceptors/user-agent.js +28 -16
- package/test/unit/spec/interceptors/webex-tracking-id.js +14 -8
- package/test/unit/spec/interceptors/webex-user-agent.js +83 -37
- package/test/unit/spec/lib/batcher.js +36 -32
- package/test/unit/spec/lib/page.js +36 -32
- package/test/unit/spec/lib/webex-plugin.js +1 -1
- package/test/unit/spec/services/interceptors/server-error.js +67 -90
- package/test/unit/spec/services/interceptors/service.js +17 -28
- package/test/unit/spec/services/service-catalog.js +19 -27
- package/test/unit/spec/services/service-host.js +29 -26
- package/test/unit/spec/services/service-registry.js +128 -170
- package/test/unit/spec/services/service-state.js +13 -22
- package/test/unit/spec/services/service-url.js +24 -43
- package/test/unit/spec/services/services.js +85 -41
- package/test/unit/spec/storage/persist.js +6 -9
- package/test/unit/spec/storage/wait-for-value.js +22 -21
- package/test/unit/spec/webex-core.js +90 -57
- package/test/unit/spec/webex-internal-core.js +56 -31
|
@@ -4,11 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import {assert} from '@webex/test-helper-chai';
|
|
6
6
|
import sinon from 'sinon';
|
|
7
|
-
import WebexCore, {
|
|
8
|
-
MemoryStoreAdapter,
|
|
9
|
-
registerPlugin,
|
|
10
|
-
WebexPlugin
|
|
11
|
-
} from '@webex/webex-core';
|
|
7
|
+
import WebexCore, {MemoryStoreAdapter, registerPlugin, WebexPlugin} from '@webex/webex-core';
|
|
12
8
|
import {set} from 'lodash';
|
|
13
9
|
import {version} from '@webex/webex-core/package';
|
|
14
10
|
|
|
@@ -58,6 +54,18 @@ describe('Webex', () => {
|
|
|
58
54
|
});
|
|
59
55
|
});
|
|
60
56
|
|
|
57
|
+
describe('#request', () => {
|
|
58
|
+
it('exists', () => {
|
|
59
|
+
assert.property(webex, 'request');
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('#prepareFetchOptions', () => {
|
|
64
|
+
it('exists', () => {
|
|
65
|
+
assert.property(webex, 'prepareFetchOptions');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
61
69
|
describe('#initialize()', () => {
|
|
62
70
|
it('initializes without arguments', () => {
|
|
63
71
|
let webex;
|
|
@@ -88,16 +96,26 @@ describe('Webex', () => {
|
|
|
88
96
|
'data.credentials.authorization',
|
|
89
97
|
'data.credentials.authorization.access_token',
|
|
90
98
|
'data.credentials.authorization.supertoken',
|
|
91
|
-
'data.credentials.authorization.supertoken.access_token'
|
|
92
|
-
]
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
'data.credentials.authorization.supertoken.access_token',
|
|
100
|
+
]
|
|
101
|
+
.reduce(
|
|
102
|
+
(acc, path) =>
|
|
103
|
+
acc.concat(
|
|
104
|
+
['ST', 'Bearer ST'].map((str) => {
|
|
105
|
+
const obj = {
|
|
106
|
+
msg: `accepts token string "${str}" at path "${path
|
|
107
|
+
.split('.')
|
|
108
|
+
.slice(1)
|
|
109
|
+
.join('.')}"`,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
set(obj, path, str);
|
|
113
|
+
|
|
114
|
+
return obj;
|
|
115
|
+
})
|
|
116
|
+
),
|
|
117
|
+
[]
|
|
118
|
+
)
|
|
101
119
|
.forEach(({msg, data}) => {
|
|
102
120
|
it(msg, () => {
|
|
103
121
|
const webex = new WebexCore(data);
|
|
@@ -110,21 +128,35 @@ describe('Webex', () => {
|
|
|
110
128
|
});
|
|
111
129
|
});
|
|
112
130
|
|
|
113
|
-
|
|
114
131
|
describe('initializes with Bearer Token', () => {
|
|
115
132
|
[
|
|
116
133
|
['initializes with a correctly formatted token', 'Bearer 1234'],
|
|
117
|
-
[
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
[
|
|
134
|
+
[
|
|
135
|
+
'initializes and removes extra space from a token that has an extra space after Bearer',
|
|
136
|
+
'Bearer 1234',
|
|
137
|
+
],
|
|
138
|
+
[
|
|
139
|
+
'initializes and adds a space after Bearer from a token that has no spaces after Bearer',
|
|
140
|
+
'Bearer1234',
|
|
141
|
+
],
|
|
142
|
+
[
|
|
143
|
+
'initializes and trims whitespace from a token that has spaces before Bearer and after token',
|
|
144
|
+
' Bearer 1234 ',
|
|
145
|
+
],
|
|
146
|
+
[
|
|
147
|
+
'initializes and removes extra space and trims whitespace from a token that has spaces before and after Bearer and after token',
|
|
148
|
+
' Bearer 1234 ',
|
|
149
|
+
],
|
|
150
|
+
[
|
|
151
|
+
'initializes and trims whitspace and adds a space after Bearer from a token that has spaces before Bearer and after token and no spaces after Bearer',
|
|
152
|
+
' Bearer1234 ',
|
|
153
|
+
],
|
|
122
154
|
].forEach(([msg, token]) => {
|
|
123
155
|
it(msg, () => {
|
|
124
156
|
const webex = new WebexCore({
|
|
125
157
|
credentials: {
|
|
126
|
-
access_token: token
|
|
127
|
-
}
|
|
158
|
+
access_token: token,
|
|
159
|
+
},
|
|
128
160
|
});
|
|
129
161
|
|
|
130
162
|
assert.isTrue(webex.credentials.canAuthorize);
|
|
@@ -161,13 +193,13 @@ describe('Webex', () => {
|
|
|
161
193
|
'@': {
|
|
162
194
|
supertoken: {
|
|
163
195
|
// eslint-disable-next-line camelcase
|
|
164
|
-
access_token: 'AT'
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
})
|
|
169
|
-
}
|
|
170
|
-
}
|
|
196
|
+
access_token: 'AT',
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
}),
|
|
201
|
+
},
|
|
202
|
+
},
|
|
171
203
|
});
|
|
172
204
|
|
|
173
205
|
assert.isFalse(webex.loaded);
|
|
@@ -175,12 +207,11 @@ describe('Webex', () => {
|
|
|
175
207
|
|
|
176
208
|
return new Promise((resolve) => {
|
|
177
209
|
webex.once('loaded', resolve);
|
|
178
|
-
})
|
|
179
|
-
.
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
});
|
|
210
|
+
}).then(() => {
|
|
211
|
+
assert.isTrue(webex.loaded);
|
|
212
|
+
assert.equal(webex.credentials.supertoken.access_token, 'AT');
|
|
213
|
+
assert.isTrue(webex.canAuthorize);
|
|
214
|
+
});
|
|
184
215
|
});
|
|
185
216
|
|
|
186
217
|
it('emits the ready event when the storage layer has loaded and all plugins signal ready', () => {
|
|
@@ -190,20 +221,23 @@ describe('Webex', () => {
|
|
|
190
221
|
|
|
191
222
|
return new Promise((resolve) => {
|
|
192
223
|
webex.once('ready', resolve);
|
|
193
|
-
})
|
|
194
|
-
.then(() => assert.isTrue(webex.ready));
|
|
224
|
+
}).then(() => assert.isTrue(webex.ready));
|
|
195
225
|
});
|
|
196
226
|
|
|
197
227
|
it('allows plugins to control ready status', () => {
|
|
198
|
-
registerPlugin(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
228
|
+
registerPlugin(
|
|
229
|
+
'test',
|
|
230
|
+
WebexPlugin.extend({
|
|
231
|
+
namespace: 'test',
|
|
232
|
+
session: {
|
|
233
|
+
ready: {
|
|
234
|
+
default: false,
|
|
235
|
+
type: 'boolean',
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
}),
|
|
239
|
+
{replace: true}
|
|
240
|
+
);
|
|
207
241
|
|
|
208
242
|
const webex = new WebexCore();
|
|
209
243
|
|
|
@@ -220,15 +254,14 @@ describe('Webex', () => {
|
|
|
220
254
|
assert.isFalse(webex.test.ready);
|
|
221
255
|
assert.isFalse(webex.ready);
|
|
222
256
|
|
|
223
|
-
return new Promise((resolve) => webex.once('loaded', resolve))
|
|
224
|
-
.
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
});
|
|
257
|
+
return new Promise((resolve) => webex.once('loaded', resolve)).then(() => {
|
|
258
|
+
assert.isFalse(webex.ready);
|
|
259
|
+
assert.isFalse(webex.test.ready);
|
|
260
|
+
webex.test.ready = true;
|
|
261
|
+
assert.isTrue(webex.test.ready);
|
|
262
|
+
assert.isTrue(webex.ready);
|
|
263
|
+
assert.called(changeSpy);
|
|
264
|
+
assert.called(readySpy);
|
|
265
|
+
});
|
|
233
266
|
});
|
|
234
267
|
});
|
|
@@ -9,16 +9,20 @@ import WebexCore, {WebexPlugin, registerInternalPlugin} from '@webex/webex-core'
|
|
|
9
9
|
describe('Webex', () => {
|
|
10
10
|
describe('#internal', () => {
|
|
11
11
|
it('grants plugins access to their namepace config', () => {
|
|
12
|
-
registerInternalPlugin(
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
registerInternalPlugin(
|
|
13
|
+
'test',
|
|
14
|
+
WebexPlugin.extend({
|
|
15
|
+
namespace: 'test',
|
|
16
|
+
}),
|
|
17
|
+
{replace: true}
|
|
18
|
+
);
|
|
15
19
|
|
|
16
20
|
const webex = new WebexCore({
|
|
17
21
|
config: {
|
|
18
22
|
test: {
|
|
19
|
-
reachable: true
|
|
20
|
-
}
|
|
21
|
-
}
|
|
23
|
+
reachable: true,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
22
26
|
});
|
|
23
27
|
|
|
24
28
|
assert.isTrue(webex.internal.test.config.reachable);
|
|
@@ -27,26 +31,48 @@ describe('Webex', () => {
|
|
|
27
31
|
});
|
|
28
32
|
|
|
29
33
|
it('controls ready status', () => {
|
|
30
|
-
registerInternalPlugin(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
registerInternalPlugin(
|
|
35
|
+
'test',
|
|
36
|
+
WebexPlugin.extend({
|
|
37
|
+
namespace: 'test',
|
|
38
|
+
session: {
|
|
39
|
+
ready: {
|
|
40
|
+
default: false,
|
|
41
|
+
type: 'boolean',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
}),
|
|
45
|
+
{replace: true}
|
|
46
|
+
);
|
|
39
47
|
|
|
40
48
|
const webex = new WebexCore({
|
|
41
49
|
config: {
|
|
42
50
|
test: {
|
|
43
|
-
reachable: true
|
|
44
|
-
}
|
|
45
|
-
}
|
|
51
|
+
reachable: true,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
46
54
|
});
|
|
47
55
|
|
|
48
|
-
webex.internal.on('all', (ev) =>
|
|
49
|
-
|
|
56
|
+
webex.internal.on('all', (ev) =>
|
|
57
|
+
console.info(
|
|
58
|
+
'YYY',
|
|
59
|
+
ev,
|
|
60
|
+
webex.credentials.ready,
|
|
61
|
+
webex.internal.test.ready,
|
|
62
|
+
webex.internal.ready,
|
|
63
|
+
webex.ready
|
|
64
|
+
)
|
|
65
|
+
);
|
|
66
|
+
webex.on('all', (ev) =>
|
|
67
|
+
console.info(
|
|
68
|
+
'XXX',
|
|
69
|
+
ev,
|
|
70
|
+
webex.credentials.ready,
|
|
71
|
+
webex.internal.test.ready,
|
|
72
|
+
webex.internal.ready,
|
|
73
|
+
webex.ready
|
|
74
|
+
)
|
|
75
|
+
);
|
|
50
76
|
|
|
51
77
|
const changeSpy = sinon.spy();
|
|
52
78
|
|
|
@@ -60,17 +86,16 @@ describe('Webex', () => {
|
|
|
60
86
|
assert.isFalse(webex.internal.ready);
|
|
61
87
|
assert.isFalse(webex.ready);
|
|
62
88
|
|
|
63
|
-
return new Promise((resolve) => webex.once('loaded', resolve))
|
|
64
|
-
.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
});
|
|
89
|
+
return new Promise((resolve) => webex.once('loaded', resolve)).then(() => {
|
|
90
|
+
assert.isFalse(webex.internal.test.ready);
|
|
91
|
+
assert.isFalse(webex.internal.ready);
|
|
92
|
+
assert.isFalse(webex.ready);
|
|
93
|
+
webex.internal.test.ready = true;
|
|
94
|
+
assert.isTrue(webex.internal.ready);
|
|
95
|
+
assert.isTrue(webex.ready);
|
|
96
|
+
assert.called(changeSpy);
|
|
97
|
+
assert.called(readySpy);
|
|
98
|
+
});
|
|
74
99
|
});
|
|
75
100
|
});
|
|
76
101
|
});
|