@volcengine/veplayer 2.3.0-rc.3 → 2.4.0-rc.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/esm/index.d.ts +73 -3
- package/esm/veplayer.biz.live.development.js +92 -21
- package/esm/veplayer.biz.live.production.js +1 -1
- package/esm/veplayer.d.ts +290 -5
- package/esm/veplayer.development.css +1 -1
- package/esm/veplayer.development.js +217 -75
- package/esm/veplayer.live.d.ts +290 -5
- package/esm/veplayer.live.development.css +1 -1
- package/esm/veplayer.live.development.js +217 -75
- package/esm/veplayer.live.production.css +1 -1
- package/esm/veplayer.live.production.js +3 -3
- package/esm/veplayer.production.css +1 -1
- package/esm/veplayer.production.js +3 -3
- package/esm/veplayer.vod.d.ts +73 -3
- package/esm/veplayer.vod.development.css +1 -1
- package/esm/veplayer.vod.development.js +169 -68
- package/esm/veplayer.vod.production.css +1 -1
- package/esm/veplayer.vod.production.js +2 -2
- package/package.json +1 -1
- package/umd/index.d.ts +73 -3
- package/umd/veplayer.biz.live.development.js +92 -21
- package/umd/veplayer.biz.live.production.js +1 -1
- package/umd/veplayer.d.ts +290 -5
- package/umd/veplayer.development.css +1 -1
- package/umd/veplayer.development.js +217 -75
- package/umd/veplayer.live.d.ts +290 -5
- package/umd/veplayer.live.development.css +1 -1
- package/umd/veplayer.live.development.js +217 -75
- package/umd/veplayer.live.production.css +1 -1
- package/umd/veplayer.live.production.js +1 -1
- package/umd/veplayer.production.css +1 -1
- package/umd/veplayer.production.js +1 -1
- package/umd/veplayer.vod.d.ts +73 -3
- package/umd/veplayer.vod.development.css +1 -1
- package/umd/veplayer.vod.development.js +169 -68
- package/umd/veplayer.vod.production.css +1 -1
- package/umd/veplayer.vod.production.js +1 -1
- package/veplayer.d.ts +290 -5
- package/veplayer.live.d.ts +290 -5
- package/veplayer.vod.d.ts +73 -3
package/package.json
CHANGED
package/umd/index.d.ts
CHANGED
|
@@ -1366,6 +1366,34 @@ interface VePlayerBaseOptions extends Omit<PlayerOptions, "autoplay" | "i18n"> {
|
|
|
1366
1366
|
* @hidden
|
|
1367
1367
|
*/
|
|
1368
1368
|
preparePlugins?: PreparePlugins;
|
|
1369
|
+
/** {zh}
|
|
1370
|
+
* @brief 是否关闭 PC 端单击播放区域切换播放/暂停的能力,开启时,点击播放器区域可实现播放或暂停。
|
|
1371
|
+
* - `true`: 关闭;
|
|
1372
|
+
* - `false`: 开启。
|
|
1373
|
+
* @default false
|
|
1374
|
+
*/
|
|
1375
|
+
/** {en}
|
|
1376
|
+
* @brief Whether to disable the click-to-play feature.
|
|
1377
|
+
* - `true`: Disable.
|
|
1378
|
+
* - `false`: Enable. Play/pause the video on mounse click for the PCs.
|
|
1379
|
+
* @default false
|
|
1380
|
+
*/
|
|
1381
|
+
closeVideoClick?: boolean;
|
|
1382
|
+
/** {zh}
|
|
1383
|
+
* @brief PC 端时表示是否关闭双击播放器进入全屏的能力;移动端时表示是否关闭双击切换播放/暂停的能力。
|
|
1384
|
+
* - `true`: 关闭;
|
|
1385
|
+
* - `false`: 开启。
|
|
1386
|
+
* @default false
|
|
1387
|
+
*/
|
|
1388
|
+
/** {en}
|
|
1389
|
+
* @brief Whether to disable the double-click/tap action.
|
|
1390
|
+
* - `true`: Disable.
|
|
1391
|
+
* - `false`: Enable.
|
|
1392
|
+
* - For the PCs, double click on the video to enter or exit the full screen mode.
|
|
1393
|
+
* - For the mobiles, play/pause the video with double tap.
|
|
1394
|
+
* @default false
|
|
1395
|
+
*/
|
|
1396
|
+
closeVideoDblclick?: boolean;
|
|
1369
1397
|
}
|
|
1370
1398
|
/** {zh}
|
|
1371
1399
|
* @list option
|
|
@@ -1864,7 +1892,7 @@ declare class VePlayerBase {
|
|
|
1864
1892
|
* @param callback 表示事件的回调函数。
|
|
1865
1893
|
*/
|
|
1866
1894
|
/** {en}
|
|
1867
|
-
* @brief
|
|
1895
|
+
* @brief Add a one-time listener function for the specified event.
|
|
1868
1896
|
* @param event The event name.
|
|
1869
1897
|
* @param callback The callback function for the event.
|
|
1870
1898
|
*/
|
|
@@ -2139,7 +2167,8 @@ declare enum DynamicModule {
|
|
|
2139
2167
|
PluginShaka = "plugin:shaka",
|
|
2140
2168
|
PluginRtm = "plugin:rtm",
|
|
2141
2169
|
PluginXgvideo = "plugin:xgvideo",
|
|
2142
|
-
PluginDrm = "plugin:drm"
|
|
2170
|
+
PluginDrm = "plugin:drm",
|
|
2171
|
+
PluginAbr = "plugin:abr"
|
|
2143
2172
|
}
|
|
2144
2173
|
type ModulesMap = {
|
|
2145
2174
|
[DynamicModule.BizVod]: Exports;
|
|
@@ -2151,6 +2180,7 @@ type ModulesMap = {
|
|
|
2151
2180
|
[DynamicModule.PluginRtm]: Exports;
|
|
2152
2181
|
[DynamicModule.PluginXgvideo]: Exports;
|
|
2153
2182
|
[DynamicModule.PluginDrm]: Exports;
|
|
2183
|
+
[DynamicModule.PluginAbr]: Exports;
|
|
2154
2184
|
};
|
|
2155
2185
|
declare const register: (exports: {
|
|
2156
2186
|
[x: string]: any;
|
|
@@ -3639,6 +3669,34 @@ declare namespace strategy {
|
|
|
3639
3669
|
* @hidden
|
|
3640
3670
|
*/
|
|
3641
3671
|
preparePlugins?: PreparePlugins;
|
|
3672
|
+
/** {zh}
|
|
3673
|
+
* @brief 是否关闭 PC 端单击播放区域切换播放/暂停的能力,开启时,点击播放器区域可实现播放或暂停。
|
|
3674
|
+
* - `true`: 关闭;
|
|
3675
|
+
* - `false`: 开启。
|
|
3676
|
+
* @default false
|
|
3677
|
+
*/
|
|
3678
|
+
/** {en}
|
|
3679
|
+
* @brief Whether to disable the click-to-play feature.
|
|
3680
|
+
* - `true`: Disable.
|
|
3681
|
+
* - `false`: Enable. Play/pause the video on mounse click for the PCs.
|
|
3682
|
+
* @default false
|
|
3683
|
+
*/
|
|
3684
|
+
closeVideoClick?: boolean;
|
|
3685
|
+
/** {zh}
|
|
3686
|
+
* @brief PC 端时表示是否关闭双击播放器进入全屏的能力;移动端时表示是否关闭双击切换播放/暂停的能力。
|
|
3687
|
+
* - `true`: 关闭;
|
|
3688
|
+
* - `false`: 开启。
|
|
3689
|
+
* @default false
|
|
3690
|
+
*/
|
|
3691
|
+
/** {en}
|
|
3692
|
+
* @brief Whether to disable the double-click/tap action.
|
|
3693
|
+
* - `true`: Disable.
|
|
3694
|
+
* - `false`: Enable.
|
|
3695
|
+
* - For the PCs, double click on the video to enter or exit the full screen mode.
|
|
3696
|
+
* - For the mobiles, play/pause the video with double tap.
|
|
3697
|
+
* @default false
|
|
3698
|
+
*/
|
|
3699
|
+
closeVideoDblclick?: boolean;
|
|
3642
3700
|
}
|
|
3643
3701
|
/** {zh}
|
|
3644
3702
|
* @list option
|
|
@@ -3842,6 +3900,7 @@ declare namespace strategy {
|
|
|
3842
3900
|
readonly "plugin:rtm": "veplayer.plugin.rtm.[env].[ext]";
|
|
3843
3901
|
readonly "plugin:xgvideo": "veplayer.plugin.xgvideo.[env].[ext]";
|
|
3844
3902
|
readonly "plugin:drm": "veplayer.plugin.drm.[env].[ext]";
|
|
3903
|
+
readonly "plugin:abr": "veplayer.plugin.abr.[env].[ext]";
|
|
3845
3904
|
};
|
|
3846
3905
|
const enum State {
|
|
3847
3906
|
Fetching = 0,
|
|
@@ -3871,7 +3930,8 @@ declare namespace strategy {
|
|
|
3871
3930
|
PluginShaka = "plugin:shaka",
|
|
3872
3931
|
PluginRtm = "plugin:rtm",
|
|
3873
3932
|
PluginXgvideo = "plugin:xgvideo",
|
|
3874
|
-
PluginDrm = "plugin:drm"
|
|
3933
|
+
PluginDrm = "plugin:drm",
|
|
3934
|
+
PluginAbr = "plugin:abr"
|
|
3875
3935
|
}
|
|
3876
3936
|
type ModulesMap = {
|
|
3877
3937
|
[DynamicModule.BizVod]: Exports;
|
|
@@ -3883,6 +3943,7 @@ declare namespace strategy {
|
|
|
3883
3943
|
[DynamicModule.PluginRtm]: Exports;
|
|
3884
3944
|
[DynamicModule.PluginXgvideo]: Exports;
|
|
3885
3945
|
[DynamicModule.PluginDrm]: Exports;
|
|
3946
|
+
[DynamicModule.PluginAbr]: Exports;
|
|
3886
3947
|
};
|
|
3887
3948
|
class Loader {
|
|
3888
3949
|
readonly modules: Record<string, Module>;
|
|
@@ -4546,6 +4607,9 @@ declare namespace event {
|
|
|
4546
4607
|
AUTOPLAY_SUCCESS: string;
|
|
4547
4608
|
ERROR_REFRESH_CLICK: string;
|
|
4548
4609
|
SOURCE_CHANGE: string;
|
|
4610
|
+
SWITCH_DEFINITION_START: string;
|
|
4611
|
+
SWITCH_DEFINITION_SUCCESS: string;
|
|
4612
|
+
DOWN_DEFINITION: string;
|
|
4549
4613
|
};
|
|
4550
4614
|
const Events: {
|
|
4551
4615
|
SEI: string;
|
|
@@ -4571,6 +4635,9 @@ declare namespace event {
|
|
|
4571
4635
|
AUTOPLAY_SUCCESS: string;
|
|
4572
4636
|
ERROR_REFRESH_CLICK: string;
|
|
4573
4637
|
SOURCE_CHANGE: string;
|
|
4638
|
+
SWITCH_DEFINITION_START: string;
|
|
4639
|
+
SWITCH_DEFINITION_SUCCESS: string;
|
|
4640
|
+
DOWN_DEFINITION: string;
|
|
4574
4641
|
REPLAY: string;
|
|
4575
4642
|
ERROR: string;
|
|
4576
4643
|
PLAY: string;
|
|
@@ -4602,6 +4669,9 @@ declare namespace event {
|
|
|
4602
4669
|
COMPLETE: string;
|
|
4603
4670
|
DESTROY: string;
|
|
4604
4671
|
URL_CHANGE: string;
|
|
4672
|
+
LEAVE_PLAYER: string;
|
|
4673
|
+
ENTER_PLAYER: string;
|
|
4674
|
+
LOADING: string;
|
|
4605
4675
|
SEI_PARSED: string;
|
|
4606
4676
|
RETRY: string;
|
|
4607
4677
|
ROTATE: string;
|
|
@@ -32,27 +32,27 @@ var __publicField = (obj, key, value) => {
|
|
|
32
32
|
function create(errorCode, i18n) {
|
|
33
33
|
return new VeError(ERRORS[errorCode], i18n);
|
|
34
34
|
}
|
|
35
|
-
const DynamicModule$
|
|
36
|
-
const load$
|
|
35
|
+
const DynamicModule$4 = window["VePlayer"].DynamicModule;
|
|
36
|
+
const load$4 = window["VePlayer"].load;
|
|
37
37
|
async function isRTMSupported() {
|
|
38
|
-
const { RtmPlugin } = await load$
|
|
38
|
+
const { RtmPlugin } = await load$4(DynamicModule$4.PluginRtm);
|
|
39
39
|
return RtmPlugin.isSupported();
|
|
40
40
|
}
|
|
41
41
|
async function isRTMSupportCodec(codec = RTMCodec.H264) {
|
|
42
|
-
const { RtmPlugin } = await load$
|
|
42
|
+
const { RtmPlugin } = await load$4(DynamicModule$4.PluginRtm);
|
|
43
43
|
if (codec === RTMCodec.H264)
|
|
44
44
|
return RtmPlugin.isSupportedH264();
|
|
45
45
|
return false;
|
|
46
46
|
}
|
|
47
47
|
const strategy$1 = window["VePlayer"].strategy;
|
|
48
48
|
const util$4 = window["VePlayer"].util;
|
|
49
|
-
const DynamicModule$
|
|
50
|
-
const load$
|
|
49
|
+
const DynamicModule$3 = window["VePlayer"].DynamicModule;
|
|
50
|
+
const load$3 = window["VePlayer"].load;
|
|
51
51
|
const Codec$1 = window["VePlayer"].Codec;
|
|
52
52
|
const Sniffer$3 = window["VePlayer"].Sniffer;
|
|
53
53
|
const rtmStrategy = {
|
|
54
54
|
options: {},
|
|
55
|
-
module: DynamicModule$
|
|
55
|
+
module: DynamicModule$3.PluginRtm
|
|
56
56
|
};
|
|
57
57
|
const generateFallbackUrl = (url) => {
|
|
58
58
|
if (Sniffer$3.device === "pc") {
|
|
@@ -79,13 +79,13 @@ var __publicField = (obj, key, value) => {
|
|
|
79
79
|
backupStrategy = strategy$1.createHlsMseStrategy(options);
|
|
80
80
|
}
|
|
81
81
|
const [rtmCdn, backupCdn] = await Promise.all([
|
|
82
|
-
load$
|
|
82
|
+
load$3(rtmStrategy.module).then((module2) => {
|
|
83
83
|
return module2.RtmPlugin;
|
|
84
84
|
}).catch(() => void 0),
|
|
85
|
-
backupStrategy && load$
|
|
86
|
-
if ((backupStrategy == null ? void 0 : backupStrategy.module) === DynamicModule$
|
|
85
|
+
backupStrategy && load$3(backupStrategy.module).then((module2) => {
|
|
86
|
+
if ((backupStrategy == null ? void 0 : backupStrategy.module) === DynamicModule$3.PluginFlv) {
|
|
87
87
|
return module2.FlvPlugin;
|
|
88
|
-
} else if ((backupStrategy == null ? void 0 : backupStrategy.module) === DynamicModule$
|
|
88
|
+
} else if ((backupStrategy == null ? void 0 : backupStrategy.module) === DynamicModule$3.PluginHls) {
|
|
89
89
|
return module2.HlsPlugin;
|
|
90
90
|
}
|
|
91
91
|
}).catch(() => void 0)
|
|
@@ -2934,9 +2934,9 @@ var __publicField = (obj, key, value) => {
|
|
|
2934
2934
|
user_id: this._userId,
|
|
2935
2935
|
device_id: this._deviceId,
|
|
2936
2936
|
ext: {
|
|
2937
|
-
veplayer_version: "2.3.
|
|
2938
|
-
flv_version: "3.0.
|
|
2939
|
-
hls_version: "3.0.
|
|
2937
|
+
veplayer_version: "2.3.1-rc.0",
|
|
2938
|
+
flv_version: "3.0.17",
|
|
2939
|
+
hls_version: "3.0.17",
|
|
2940
2940
|
rts_version: "0.2.0-alpha.5"
|
|
2941
2941
|
}
|
|
2942
2942
|
});
|
|
@@ -3205,8 +3205,8 @@ var __publicField = (obj, key, value) => {
|
|
|
3205
3205
|
DECODE_INFO: "软解信息",
|
|
3206
3206
|
REFRESH: "刷新"
|
|
3207
3207
|
};
|
|
3208
|
-
const DynamicModule$
|
|
3209
|
-
const load$
|
|
3208
|
+
const DynamicModule$2 = window["VePlayer"].DynamicModule;
|
|
3209
|
+
const load$2 = window["VePlayer"].load;
|
|
3210
3210
|
const getDrmStrategy = async (options, player) => {
|
|
3211
3211
|
var _a;
|
|
3212
3212
|
const drmType = getDrmType(options.drm);
|
|
@@ -3214,7 +3214,7 @@ var __publicField = (obj, key, value) => {
|
|
|
3214
3214
|
try {
|
|
3215
3215
|
const { getDrmConfig, ...originFairplayConfig } = ((_a = options == null ? void 0 : options.drm) == null ? void 0 : _a.fairplay) ?? {};
|
|
3216
3216
|
const [drmPlugin, drmConfig] = await Promise.all([
|
|
3217
|
-
load$
|
|
3217
|
+
load$2(DynamicModule$2.PluginDrm).then((module2) => module2.DrmPlugin).catch(() => void 0),
|
|
3218
3218
|
getDrmConfig == null ? void 0 : getDrmConfig({
|
|
3219
3219
|
url: options.url
|
|
3220
3220
|
})
|
|
@@ -3238,6 +3238,55 @@ var __publicField = (obj, key, value) => {
|
|
|
3238
3238
|
}
|
|
3239
3239
|
return {};
|
|
3240
3240
|
};
|
|
3241
|
+
function isType(suffix) {
|
|
3242
|
+
return function(url) {
|
|
3243
|
+
return url == null ? void 0 : url.split("?")[0].toLowerCase().includes(suffix);
|
|
3244
|
+
};
|
|
3245
|
+
}
|
|
3246
|
+
const isHls = isType(".m3u8");
|
|
3247
|
+
const isMp4 = isType(".mp4");
|
|
3248
|
+
const isFlv = isType(".flv");
|
|
3249
|
+
const isRtm = isType(".sdp");
|
|
3250
|
+
const isDash = isType(".mpd");
|
|
3251
|
+
function getStreamType(url) {
|
|
3252
|
+
if (isHls(url)) {
|
|
3253
|
+
return "hls";
|
|
3254
|
+
}
|
|
3255
|
+
if (isFlv(url)) {
|
|
3256
|
+
return "flv";
|
|
3257
|
+
}
|
|
3258
|
+
if (isRtm(url)) {
|
|
3259
|
+
return "rtm";
|
|
3260
|
+
}
|
|
3261
|
+
if (isMp4(url)) {
|
|
3262
|
+
return "mp4";
|
|
3263
|
+
}
|
|
3264
|
+
if (isDash(url)) {
|
|
3265
|
+
return "dash";
|
|
3266
|
+
}
|
|
3267
|
+
return "unknown";
|
|
3268
|
+
}
|
|
3269
|
+
const DynamicModule$1 = window["VePlayer"].DynamicModule;
|
|
3270
|
+
const load$1 = window["VePlayer"].load;
|
|
3271
|
+
const getAbrStrategy = async (options) => {
|
|
3272
|
+
var _a, _b;
|
|
3273
|
+
const streamType = options.url && getStreamType(options.url);
|
|
3274
|
+
if (streamType === "rtm")
|
|
3275
|
+
return {};
|
|
3276
|
+
const abrOptions = streamType === "flv" ? (_a = options == null ? void 0 : options.flv) == null ? void 0 : _a.abr : (_b = options == null ? void 0 : options.hls) == null ? void 0 : _b.abr;
|
|
3277
|
+
if (!abrOptions) {
|
|
3278
|
+
return {};
|
|
3279
|
+
}
|
|
3280
|
+
const abrPlugin = await load$1(DynamicModule$1.PluginAbr).catch(() => void 0);
|
|
3281
|
+
return {
|
|
3282
|
+
options: {
|
|
3283
|
+
[streamType === "flv" ? "abr" : "hlsabr"]: abrOptions
|
|
3284
|
+
},
|
|
3285
|
+
plugins: [
|
|
3286
|
+
streamType === "flv" ? abrPlugin == null ? void 0 : abrPlugin.AbrPlugin : abrPlugin == null ? void 0 : abrPlugin.HlsAbrPlugin
|
|
3287
|
+
]
|
|
3288
|
+
};
|
|
3289
|
+
};
|
|
3241
3290
|
const DEFAULT_PLUGINS = window["VePlayer"].DEFAULT_PLUGINS;
|
|
3242
3291
|
const VePlayerBase = window["VePlayer"].VePlayerBase;
|
|
3243
3292
|
const VeI18n = window["VePlayer"].VeI18n;
|
|
@@ -3313,6 +3362,14 @@ var __publicField = (obj, key, value) => {
|
|
|
3313
3362
|
var _a;
|
|
3314
3363
|
(_a = this._player.plugins) == null ? void 0 : _a.infopanel.close();
|
|
3315
3364
|
}
|
|
3365
|
+
openAbr() {
|
|
3366
|
+
var _a, _b;
|
|
3367
|
+
(_b = (_a = this._player.plugins) == null ? void 0 : _a.abr) == null ? void 0 : _b.switchAbr(true);
|
|
3368
|
+
}
|
|
3369
|
+
closeAbr() {
|
|
3370
|
+
var _a, _b;
|
|
3371
|
+
(_b = (_a = this._player.plugins) == null ? void 0 : _a.abr) == null ? void 0 : _b.switchAbr(false);
|
|
3372
|
+
}
|
|
3316
3373
|
/** {zh}
|
|
3317
3374
|
* @brief 调用此方法更新 DRM 鉴权配置。
|
|
3318
3375
|
* @hidden
|
|
@@ -3321,6 +3378,14 @@ var __publicField = (obj, key, value) => {
|
|
|
3321
3378
|
var _a, _b, _c;
|
|
3322
3379
|
(_c = (_b = (_a = this._player) == null ? void 0 : _a.plugins) == null ? void 0 : _b.drm) == null ? void 0 : _c.updateDrmConfig(config);
|
|
3323
3380
|
}
|
|
3381
|
+
async switch(target, options) {
|
|
3382
|
+
var _a, _b, _c;
|
|
3383
|
+
const { abr, ...rest } = options ?? {};
|
|
3384
|
+
if (abr) {
|
|
3385
|
+
(_c = (_b = (_a = this._player) == null ? void 0 : _a.plugins) == null ? void 0 : _b.abr) == null ? void 0 : _c.updateConfig(abr);
|
|
3386
|
+
}
|
|
3387
|
+
return super.switch(target, rest);
|
|
3388
|
+
}
|
|
3324
3389
|
}
|
|
3325
3390
|
async function createLivePlayer(options) {
|
|
3326
3391
|
var _a, _b;
|
|
@@ -3345,15 +3410,21 @@ var __publicField = (obj, key, value) => {
|
|
|
3345
3410
|
};
|
|
3346
3411
|
},
|
|
3347
3412
|
async preparePlugins(url) {
|
|
3348
|
-
const [typeStrategy, drmStrategy] = await Promise.all([
|
|
3413
|
+
const [typeStrategy, drmStrategy, abrStrategy] = await Promise.all([
|
|
3349
3414
|
getTypeStrategy({ ...finalOptions, url }, player),
|
|
3350
|
-
getDrmStrategy({ ...finalOptions, url }, player)
|
|
3415
|
+
getDrmStrategy({ ...finalOptions, url }, player),
|
|
3416
|
+
getAbrStrategy({ ...finalOptions, url })
|
|
3351
3417
|
]);
|
|
3352
3418
|
const { options: options2, plugins } = typeStrategy ?? {};
|
|
3353
3419
|
const { options: drmOptions, plugins: drmPlugins } = drmStrategy ?? {};
|
|
3420
|
+
const { options: abrOptions, plugins: abrPlugins } = abrStrategy ?? {};
|
|
3354
3421
|
return {
|
|
3355
|
-
options: Object.assign({}, options2, drmOptions),
|
|
3356
|
-
plugins: [
|
|
3422
|
+
options: Object.assign({}, options2, drmOptions, abrOptions),
|
|
3423
|
+
plugins: [
|
|
3424
|
+
...plugins ?? [],
|
|
3425
|
+
...drmPlugins ?? [],
|
|
3426
|
+
...abrPlugins ?? []
|
|
3427
|
+
]
|
|
3357
3428
|
};
|
|
3358
3429
|
}
|
|
3359
3430
|
},
|