UNPKG

275 kBJavaScriptView Raw
1/******/ (function(modules) { // webpackBootstrap
2/******/ // The module cache
3/******/ var installedModules = {};
4/******/
5/******/ // The require function
6/******/ function __webpack_require__(moduleId) {
7/******/
8/******/ // Check if module is in cache
9/******/ if(installedModules[moduleId]) {
10/******/ return installedModules[moduleId].exports;
11/******/ }
12/******/ // Create a new module (and put it into the cache)
13/******/ var module = installedModules[moduleId] = {
14/******/ i: moduleId,
15/******/ l: false,
16/******/ exports: {}
17/******/ };
18/******/
19/******/ // Execute the module function
20/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21/******/
22/******/ // Flag the module as loaded
23/******/ module.l = true;
24/******/
25/******/ // Return the exports of the module
26/******/ return module.exports;
27/******/ }
28/******/
29/******/
30/******/ // expose the modules object (__webpack_modules__)
31/******/ __webpack_require__.m = modules;
32/******/
33/******/ // expose the module cache
34/******/ __webpack_require__.c = installedModules;
35/******/
36/******/ // define getter function for harmony exports
37/******/ __webpack_require__.d = function(exports, name, getter) {
38/******/ if(!__webpack_require__.o(exports, name)) {
39/******/ Object.defineProperty(exports, name, {
40/******/ configurable: false,
41/******/ enumerable: true,
42/******/ get: getter
43/******/ });
44/******/ }
45/******/ };
46/******/
47/******/ // getDefaultExport function for compatibility with non-harmony modules
48/******/ __webpack_require__.n = function(module) {
49/******/ var getter = module && module.__esModule ?
50/******/ function getDefault() { return module['default']; } :
51/******/ function getModuleExports() { return module; };
52/******/ __webpack_require__.d(getter, 'a', getter);
53/******/ return getter;
54/******/ };
55/******/
56/******/ // Object.prototype.hasOwnProperty.call
57/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
58/******/
59/******/ // __webpack_public_path__
60/******/ __webpack_require__.p = "";
61/******/
62/******/ // Load entry module and return exports
63/******/ return __webpack_require__(__webpack_require__.s = 4);
64/******/ })
65/************************************************************************/
66/******/ ([
67/* 0 */
68/***/ (function(module, exports, __webpack_require__) {
69
70"use strict";
71
72
73Object.defineProperty(exports, "__esModule", {
74 value: true
75});
76
77function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
78
79var Error = function Error(type) {
80 _classCallCheck(this, Error);
81
82 this.type = type;
83};
84
85exports.default = Error;
86
87/***/ }),
88/* 1 */
89/***/ (function(module, exports, __webpack_require__) {
90
91"use strict";
92
93
94Object.defineProperty(exports, "__esModule", {
95 value: true
96});
97
98var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
99
100var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* eslint-disable */
101
102
103var _flvdemux = __webpack_require__(7);
104
105var _flvdemux2 = _interopRequireDefault(_flvdemux);
106
107var _mediaInfo = __webpack_require__(10);
108
109var _mediaInfo2 = _interopRequireDefault(_mediaInfo);
110
111var _spsParser = __webpack_require__(2);
112
113var _spsParser2 = _interopRequireDefault(_spsParser);
114
115var _error = __webpack_require__(0);
116
117var _error2 = _interopRequireDefault(_error);
118
119function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
120
121function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
122
123var tagDemux = function () {
124 function tagDemux() {
125 _classCallCheck(this, tagDemux);
126
127 this.TAG = this.constructor.name;
128
129 this._config = {};
130
131 this._onError = null;
132 this._onMediaInfo = null;
133 this._onTrackMetadata = null;
134 this._onDataAvailable = null;
135
136 this._dataOffset = 0;
137 this._firstParse = true;
138 this._dispatch = false;
139
140 this._hasAudio = false;
141 this._hasVideo = false;
142
143 this._audioInitialMetadataDispatched = false;
144 this._videoInitialMetadataDispatched = false;
145
146 this._mediaInfo = new _mediaInfo2.default();
147 this._mediaInfo.hasAudio = this._hasAudio;
148 this._mediaInfo.hasVideo = this._hasVideo;
149 this._metadata = null;
150 this._audioMetadata = null;
151 this._videoMetadata = null;
152
153 this._naluLengthSize = 4;
154 this._timestampBase = 0; // int32, in milliseconds
155 this._timescale = 1000;
156 this._duration = 0; // int32, in milliseconds
157 this._durationOverrided = false;
158 this._referenceFrameRate = {
159 fixed: true,
160 fps: 23.976,
161 fps_num: 23976,
162 fps_den: 1000
163 };
164
165 this._videoTrack = { type: 'video', id: 1, sequenceNumber: 0, addcoefficient: 2, samples: [], length: 0 };
166 this._audioTrack = { type: 'audio', id: 2, sequenceNumber: 1, addcoefficient: 2, samples: [], length: 0 };
167
168 this._littleEndian = function () {
169 var buf = new ArrayBuffer(2);
170 new DataView(buf).setInt16(0, 256, true); // little-endian write
171 return new Int16Array(buf)[0] === 256; // platform-spec read, if equal then LE
172 }();
173 }
174
175 _createClass(tagDemux, [{
176 key: 'onMediaInfo',
177 value: function onMediaInfo(callback) {
178 this._onMediaInfo = callback;
179 }
180 }, {
181 key: 'parseMetadata',
182 value: function parseMetadata(arr) {
183 var data = _flvdemux2.default.parseMetadata(arr);
184 this._parseScriptData(data);
185 }
186 }, {
187 key: '_parseScriptData',
188 value: function _parseScriptData(obj) {
189 var scriptData = obj;
190
191 if (scriptData.hasOwnProperty('onMetaData')) {
192 if (this._metadata) {
193 console.log(this.TAG, 'Found another onMetaData tag!');
194 }
195 this._metadata = scriptData;
196 var onMetaData = this._metadata.onMetaData;
197
198 if (typeof onMetaData.hasAudio === 'boolean') {
199 // hasAudio
200 this._hasAudio = onMetaData.hasAudio;
201 this._mediaInfo.hasAudio = this._hasAudio;
202 }
203 if (typeof onMetaData.hasVideo === 'boolean') {
204 // hasVideo
205 this._hasVideo = onMetaData.hasVideo;
206 this._mediaInfo.hasVideo = this._hasVideo;
207 }
208 if (typeof onMetaData.audiodatarate === 'number') {
209 // audiodatarate
210 this._mediaInfo.audioDataRate = onMetaData.audiodatarate;
211 }
212 if (typeof onMetaData.videodatarate === 'number') {
213 // videodatarate
214 this._mediaInfo.videoDataRate = onMetaData.videodatarate;
215 }
216 if (typeof onMetaData.width === 'number') {
217 // width
218 this._mediaInfo.width = onMetaData.width;
219 }
220 if (typeof onMetaData.height === 'number') {
221 // height
222 this._mediaInfo.height = onMetaData.height;
223 }
224 if (typeof onMetaData.duration === 'number') {
225 // duration
226 if (!this._durationOverrided) {
227 var duration = Math.floor(onMetaData.duration * this._timescale);
228 this._duration = duration;
229 this._mediaInfo.duration = duration;
230 }
231 } else {
232 this._mediaInfo.duration = 0;
233 }
234 if (typeof onMetaData.framerate === 'number') {
235 // framerate
236 var fps_num = Math.floor(onMetaData.framerate * 1000);
237 if (fps_num > 0) {
238 var fps = fps_num / 1000;
239 this._referenceFrameRate.fixed = true;
240 this._referenceFrameRate.fps = fps;
241 this._referenceFrameRate.fps_num = fps_num;
242 this._referenceFrameRate.fps_den = 1000;
243 this._mediaInfo.fps = fps;
244 }
245 }
246 if (_typeof(onMetaData.keyframes) === 'object') {
247 // keyframes
248 this._mediaInfo.hasKeyframesIndex = true;
249 var keyframes = onMetaData.keyframes;
250 keyframes.times = onMetaData.times;
251 keyframes.filepositions = onMetaData.filepositions;
252 this._mediaInfo.keyframesIndex = this._parseKeyframesIndex(keyframes);
253 onMetaData.keyframes = null; // keyframes has been extracted, remove it
254 } else {
255 this._mediaInfo.hasKeyframesIndex = false;
256 }
257 this._dispatch = false;
258 this._mediaInfo.metadata = onMetaData;
259 console.log(this.TAG, 'Parsed onMetaData');
260 // if (this._mediaInfo.isComplete()) {
261 // this._onMediaInfo(this._mediaInfo);
262 // }
263 return this._mediaInfo;
264 }
265 }
266 }, {
267 key: '_parseKeyframesIndex',
268 value: function _parseKeyframesIndex(keyframes) {
269 var times = [];
270 var filepositions = [];
271
272 // ignore first keyframe which is actually AVC Sequence Header (AVCDecoderConfigurationRecord)
273 for (var i = 1; i < keyframes.times.length; i++) {
274 var time = this._timestampBase + Math.floor(keyframes.times[i] * 1000);
275 times.push(time);
276 filepositions.push(keyframes.filepositions[i]);
277 }
278
279 return {
280 times: times,
281 filepositions: filepositions
282 };
283 }
284
285 /**
286 * 传入tags输出moof和mdat
287 *
288 * @param {any} tags
289 *
290 * @memberof tagDemux
291 */
292
293 }, {
294 key: 'moofTag',
295 value: function moofTag(tags) {
296
297 for (var i = 0; i < tags.length; i++) {
298 this._dispatch = true;
299 this.parseChunks(tags[i]);
300 // console.log("tagTimestamp", tags[i].getTime(), tags[i]);
301 }
302 if (this._isInitialMetadataDispatched()) {
303 if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {
304 this._onDataAvailable(this._audioTrack, this._videoTrack);
305 }
306 }
307 }
308 }, {
309 key: 'parseChunks',
310 value: function parseChunks(flvtag) {
311
312 switch (flvtag.tagType) {
313 case 8:
314 // Audio
315 this._parseAudioData(flvtag.body.buffer, 0, flvtag.body.length, flvtag.getTime());
316 break;
317 case 9:
318 // Video
319 this._parseVideoData(flvtag.body.buffer, 0, flvtag.body.length, flvtag.getTime(), 0);
320 break;
321 case 18:
322 // ScriptDataObject
323 this.parseMetadata(flvtag.body);
324 break;
325 }
326 }
327 }, {
328 key: '_parseVideoData',
329 value: function _parseVideoData(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition) {
330 if (tagTimestamp == this._timestampBase && this._timestampBase != 0) {
331 throw new _error2.default(tagTimestamp + this._timestampBase + '夭寿啦这个视频不是从0开始');
332 // this.timestampBase(0);
333 }
334 if (dataSize <= 1) {
335 console.log(this.TAG, 'Flv: Invalid video packet, missing VideoData payload!');
336 return;
337 }
338 // 获取 video tag body 第一字节
339 var spec = new Uint8Array(arrayBuffer, dataOffset, dataSize)[0];
340 // 获取是否是关键帧
341 var frameType = (spec & 240) >>> 4;
342 // 获取编码格式
343 var codecId = spec & 15;
344
345 if (codecId !== 7) {
346 throw new _error2.default('Flv: Unsupported codec in video frame: ' + codecId);
347 // return;
348 }
349
350 this._parseAVCVideoPacket(arrayBuffer, dataOffset + 1, dataSize - 1, tagTimestamp, tagPosition, frameType);
351 }
352 }, {
353 key: '_parseAVCVideoPacket',
354 value: function _parseAVCVideoPacket(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition, frameType) {
355
356 if (dataSize < 4) {
357 console.log(this.TAG, 'Flv: Invalid AVC packet, missing AVCPacketType or/and CompositionTime');
358 return;
359 }
360
361 var le = this._littleEndian;
362 // 获取 video tag body 第2字节到结尾
363 var v = new DataView(arrayBuffer, dataOffset, dataSize);
364
365 // IF CodecID == 7 AVCPacketType
366 // 0 = AVC sequence header
367 // 1 = AVC NALU
368 // 2 = AVC end of sequence (lower level NALU sequence ender is not required or supported)
369 var packetType = v.getUint8(0);
370 // 3字节
371 // IF AVCPacketType == 1
372 // Composition time offset
373 // ELSE
374 // 0
375 var cts = v.getUint32(0, !le) & 0x00FFFFFF;
376
377 // IF AVCPacketType == 0 AVCDecoderConfigurationRecord(AVC sequence header)
378 // IF AVCPacketType == 1 One or more NALUs (Full frames are required)
379
380 /**
381 *AVCDecoderConfigurationRecord.包含着是H.264解码相关比较重要的sps和pps信息,
382 *再给AVC解码器送数据 流之前一定要把sps和pps信息送出,否则的话解码器不能正常解码。
383 *而且在解码器stop之后再次start之前,如seek、快进快退状态切换等,
384 *都 需要重新送一遍sps和pps的信息.AVCDecoderConfigurationRecord在FLV文件中一般情况也是出现1次,
385 *也就是第一个 video tag.
386 */
387 if (packetType === 0) {
388 // AVCDecoderConfigurationRecord
389 this._parseAVCDecoderConfigurationRecord(arrayBuffer, dataOffset + 4, dataSize - 4);
390 } else if (packetType === 1) {
391 // One or more Nalus
392 this._parseAVCVideoData(arrayBuffer, dataOffset + 4, dataSize - 4, tagTimestamp, tagPosition, frameType, cts);
393 } else if (packetType === 2) {
394 // empty, AVC end of sequence
395 } else {
396 throw new _error2.default('Flv: Invalid video packet type ' + packetType);
397 }
398 }
399
400 /**
401 * AVC 初始化
402 */
403
404 }, {
405 key: '_parseAVCDecoderConfigurationRecord',
406 value: function _parseAVCDecoderConfigurationRecord(arrayBuffer, dataOffset, dataSize) {
407 if (dataSize < 7) {
408 console.log(this.TAG, 'Flv: Invalid AVCDecoderConfigurationRecord, lack of data!');
409 return;
410 }
411
412 var meta = this._videoMetadata;
413 var track = this._videoTrack;
414 var le = this._littleEndian;
415 var v = new DataView(arrayBuffer, dataOffset, dataSize);
416
417 if (!meta) {
418 meta = this._videoMetadata = {};
419 meta.type = 'video';
420 meta.id = track.id;
421 meta.timescale = this._timescale;
422 meta.duration = this._duration;
423 } else {
424 if (typeof meta.avcc !== 'undefined') {
425 console.log(this.TAG, 'Found another AVCDecoderConfigurationRecord!');
426 }
427 }
428
429 var version = v.getUint8(0); // configurationVersion
430 var avcProfile = v.getUint8(1); // avcProfileIndication
431 var profileCompatibility = v.getUint8(2); // profile_compatibility
432 var avcLevel = v.getUint8(3); // AVCLevelIndication
433
434 if (version !== 1 || avcProfile === 0) {
435 this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord');
436 return;
437 }
438
439 this._naluLengthSize = (v.getUint8(4) & 3) + 1; // lengthSizeMinusOne
440 if (this._naluLengthSize !== 3 && this._naluLengthSize !== 4) {
441 // holy shit!!!
442 this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Strange NaluLengthSizeMinusOne: ' + (this._naluLengthSize - 1));
443 return;
444 }
445
446 var spsCount = v.getUint8(5) & 31; // numOfSequenceParameterSets
447 if (spsCount === 0 || spsCount > 1) {
448 this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid H264 SPS count: ' + spsCount);
449 return;
450 }
451
452 var offset = 6;
453
454 for (var i = 0; i < spsCount; i++) {
455 var len = v.getUint16(offset, !le); // sequenceParameterSetLength
456 offset += 2;
457
458 if (len === 0) {
459 continue;
460 }
461
462 // Notice: Nalu without startcode header (00 00 00 01)
463 var sps = new Uint8Array(arrayBuffer, dataOffset + offset, len);
464 offset += len;
465
466 var config = _spsParser2.default.parseSPS(sps);
467 meta.codecWidth = config.codec_size.width;
468 meta.codecHeight = config.codec_size.height;
469 meta.presentWidth = config.present_size.width;
470 meta.presentHeight = config.present_size.height;
471
472 meta.profile = config.profile_string;
473 meta.level = config.level_string;
474 meta.bitDepth = config.bit_depth;
475 meta.chromaFormat = config.chroma_format;
476 meta.sarRatio = config.sar_ratio;
477 meta.frameRate = config.frame_rate;
478
479 if (config.frame_rate.fixed === false || config.frame_rate.fps_num === 0 || config.frame_rate.fps_den === 0) {
480 meta.frameRate = this._referenceFrameRate;
481 }
482
483 var fps_den = meta.frameRate.fps_den;
484 var fps_num = meta.frameRate.fps_num;
485 meta.refSampleDuration = Math.floor(meta.timescale * (fps_den / fps_num));
486
487 var codecArray = sps.subarray(1, 4);
488 var codecString = 'avc1.';
489 for (var j = 0; j < 3; j++) {
490 var h = codecArray[j].toString(16);
491 if (h.length < 2) {
492 h = '0' + h;
493 }
494 codecString += h;
495 }
496 meta.codec = codecString;
497
498 var mi = this._mediaInfo;
499 mi.width = meta.codecWidth;
500 mi.height = meta.codecHeight;
501 mi.fps = meta.frameRate.fps;
502 mi.profile = meta.profile;
503 mi.level = meta.level;
504 mi.chromaFormat = config.chroma_format_string;
505 mi.sarNum = meta.sarRatio.width;
506 mi.sarDen = meta.sarRatio.height;
507 mi.videoCodec = codecString;
508
509 if (mi.hasAudio) {
510 if (mi.audioCodec != null) {
511 mi.mimeType = 'video/x-flv; codecs="' + mi.videoCodec + ',' + mi.audioCodec + '"';
512 }
513 } else {
514 mi.mimeType = 'video/x-flv; codecs="' + mi.videoCodec + '"';
515 }
516 if (mi.isComplete()) {
517 this._onMediaInfo(mi);
518 }
519 }
520
521 var ppsCount = v.getUint8(offset); // numOfPictureParameterSets
522 if (ppsCount === 0 || ppsCount > 1) {
523 this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid H264 PPS count: ' + ppsCount);
524 return;
525 }
526
527 offset++;
528
529 for (var _i = 0; _i < ppsCount; _i++) {
530 var _len = v.getUint16(offset, !le); // pictureParameterSetLength
531 offset += 2;
532
533 if (_len === 0) {
534 continue;
535 }
536
537 // pps is useless for extracting video information
538 offset += _len;
539 }
540
541 meta.avcc = new Uint8Array(dataSize);
542 meta.avcc.set(new Uint8Array(arrayBuffer, dataOffset, dataSize), 0);
543 console.log(this.TAG, 'Parsed AVCDecoderConfigurationRecord');
544
545 if (this._isInitialMetadataDispatched()) {
546 // flush parsed frames
547 if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {
548 this._onDataAvailable(this._audioTrack, this._videoTrack);
549 }
550 } else {
551 this._videoInitialMetadataDispatched = true;
552 }
553 // notify new metadata
554 this._dispatch = false;
555 // if (this._onTrackMetadata) {
556 // this._onTrackMetadata.call(null, meta);
557 // }
558
559 this._onTrackMetadata('video', meta);
560 }
561 }, {
562 key: 'timestampBase',
563 value: function timestampBase(i) {
564 this._timestampBase = i;
565 }
566
567 /**
568 * 普通的AVC 片段
569 */
570
571 }, {
572 key: '_parseAVCVideoData',
573 value: function _parseAVCVideoData(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition, frameType, cts) {
574
575 var le = this._littleEndian;
576 var v = new DataView(arrayBuffer, dataOffset, dataSize);
577
578 var units = [],
579 length = 0;
580
581 var offset = 0;
582 var lengthSize = this._naluLengthSize;
583 var dts = this._timestampBase + tagTimestamp;
584 var keyframe = frameType === 1; // from FLV Frame Type constants
585
586 while (offset < dataSize) {
587 if (offset + 4 >= dataSize) {
588 console.log(this.TAG, 'Malformed Nalu near timestamp ' + dts + ', offset = ' + offset + ', dataSize = ' + dataSize);
589 break; // data not enough for next Nalu
590 }
591 // Nalu with length-header (AVC1)
592 var naluSize = v.getUint32(offset, !le); // Big-Endian read
593 if (lengthSize === 3) {
594 naluSize >>>= 8;
595 }
596 if (naluSize > dataSize - lengthSize) {
597 console.log(this.TAG, 'Malformed Nalus near timestamp ' + dts + ', NaluSize > DataSize!');
598 return;
599 }
600
601 var unitType = v.getUint8(offset + lengthSize) & 0x1F;
602
603 if (unitType === 5) {
604 // IDR
605 keyframe = true;
606 }
607
608 var data = new Uint8Array(arrayBuffer, dataOffset + offset, lengthSize + naluSize);
609 var unit = { type: unitType, data: data };
610 units.push(unit);
611 length += data.byteLength;
612
613 offset += lengthSize + naluSize;
614 }
615
616 if (units.length) {
617 var track = this._videoTrack;
618 var avcSample = {
619 units: units,
620 length: length,
621 isKeyframe: keyframe,
622 dts: dts,
623 cts: cts,
624 pts: dts + cts
625 };
626 if (keyframe) {
627 avcSample.fileposition = tagPosition;
628 }
629 track.samples.push(avcSample);
630 track.length += length;
631 }
632 }
633 }, {
634 key: '_parseAudioData',
635 value: function _parseAudioData(arrayBuffer, dataOffset, dataSize, tagTimestamp) {
636 if (tagTimestamp == this._timestampBase && this._timestampBase != 0) {
637 console.log(tagTimestamp, this._timestampBase, '夭寿啦这个视频不是从0开始');
638 // timestampBase(0);
639 }
640
641 if (dataSize <= 1) {
642 console.log(this.TAG, 'Flv: Invalid audio packet, missing SoundData payload!');
643 return;
644 }
645
646 var meta = this._audioMetadata;
647 var track = this._audioTrack;
648
649 if (!meta || !meta.codec) {
650 // initial metadata
651 meta = this._audioMetadata = {};
652 meta.type = 'audio';
653 meta.id = track.id;
654 meta.timescale = this._timescale;
655 meta.duration = this._duration;
656
657 var le = this._littleEndian;
658 var v = new DataView(arrayBuffer, dataOffset, dataSize);
659
660 var soundSpec = v.getUint8(0);
661
662 var soundFormat = soundSpec >>> 4;
663 if (soundFormat !== 10) {
664 // AAC
665 // TODO: support MP3 audio codec
666 this._onError(DemuxErrors.CODEC_UNSUPPORTED, 'Flv: Unsupported audio codec idx: ' + soundFormat);
667 return;
668 }
669
670 var soundRate = 0;
671 var soundRateIndex = (soundSpec & 12) >>> 2;
672
673 var soundRateTable = [5500, 11025, 22050, 44100, 48000];
674
675 if (soundRateIndex < soundRateTable.length) {
676 soundRate = soundRateTable[soundRateIndex];
677 } else {
678 this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid audio sample rate idx: ' + soundRateIndex);
679 return;
680 }
681
682 var soundSize = (soundSpec & 2) >>> 1; // unused
683 var soundType = soundSpec & 1;
684
685 meta.audioSampleRate = soundRate;
686 meta.channelCount = soundType === 0 ? 1 : 2;
687 meta.refSampleDuration = Math.floor(1024 / meta.audioSampleRate * meta.timescale);
688 meta.codec = 'mp4a.40.5';
689 }
690
691 var aacData = this._parseAACAudioData(arrayBuffer, dataOffset + 1, dataSize - 1);
692 if (aacData == undefined) {
693 return;
694 }
695
696 if (aacData.packetType === 0) {
697 // AAC sequence header (AudioSpecificConfig)
698 if (meta.config) {
699 console.log(this.TAG, 'Found another AudioSpecificConfig!');
700 }
701 var misc = aacData.data;
702 meta.audioSampleRate = misc.samplingRate;
703 meta.channelCount = misc.channelCount;
704 meta.codec = misc.codec;
705 meta.config = misc.config;
706 // The decode result of an aac sample is 1024 PCM samples
707 meta.refSampleDuration = Math.floor(1024 / meta.audioSampleRate * meta.timescale);
708 console.log(this.TAG, 'Parsed AudioSpecificConfig');
709
710 if (this._isInitialMetadataDispatched()) {
711 // Non-initial metadata, force dispatch (or flush) parsed frames to remuxer
712 if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {
713 this._onDataAvailable(this._audioTrack, this._videoTrack);
714 }
715 } else {
716 this._audioInitialMetadataDispatched = true;
717 }
718 // then notify new metadata
719 this._dispatch = false;
720 this._onTrackMetadata('audio', meta);
721
722 var mi = this._mediaInfo;
723 mi.audioCodec = 'mp4a.40.' + misc.originalAudioObjectType;
724 mi.audioSampleRate = meta.audioSampleRate;
725 mi.audioChannelCount = meta.channelCount;
726 if (mi.hasVideo) {
727 if (mi.videoCodec != null) {
728 mi.mimeType = 'video/x-flv; codecs="' + mi.videoCodec + ',' + mi.audioCodec + '"';
729 }
730 } else {
731 mi.mimeType = 'video/x-flv; codecs="' + mi.audioCodec + '"';
732 }
733 if (mi.isComplete()) {
734 this._onMediaInfo(mi);
735 }
736 return;
737 } else if (aacData.packetType === 1) {
738 // AAC raw frame data
739 var dts = this._timestampBase + tagTimestamp;
740 var aacSample = { unit: aacData.data, dts: dts, pts: dts };
741 track.samples.push(aacSample);
742 track.length += aacData.data.length;
743 } else {
744 console.log(this.TAG, 'Flv: Unsupported AAC data type ' + aacData.packetType);
745 }
746 }
747 }, {
748 key: '_parseAACAudioData',
749 value: function _parseAACAudioData(arrayBuffer, dataOffset, dataSize) {
750 if (dataSize <= 1) {
751 console.log(this.TAG, 'Flv: Invalid AAC packet, missing AACPacketType or/and Data!');
752 return;
753 }
754
755 var result = {};
756 var array = new Uint8Array(arrayBuffer, dataOffset, dataSize);
757
758 result.packetType = array[0];
759
760 if (array[0] === 0) {
761 result.data = this._parseAACAudioSpecificConfig(arrayBuffer, dataOffset + 1, dataSize - 1);
762 } else {
763 result.data = array.subarray(1);
764 }
765
766 return result;
767 }
768 }, {
769 key: '_parseAACAudioSpecificConfig',
770 value: function _parseAACAudioSpecificConfig(arrayBuffer, dataOffset, dataSize) {
771 var array = new Uint8Array(arrayBuffer, dataOffset, dataSize);
772 var config = null;
773
774 var mpegSamplingRates = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];
775
776 /* Audio Object Type:
777 0: Null
778 1: AAC Main
779 2: AAC LC
780 3: AAC SSR (Scalable Sample Rate)
781 4: AAC LTP (Long Term Prediction)
782 5: HE-AAC / SBR (Spectral Band Replication)
783 6: AAC Scalable
784 */
785
786 var audioObjectType = 0;
787 var originalAudioObjectType = 0;
788 var audioExtensionObjectType = null;
789 var samplingIndex = 0;
790 var extensionSamplingIndex = null;
791 // debugger;
792 // 5 bits
793 audioObjectType = originalAudioObjectType = array[0] >>> 3;
794 // 4 bits
795 samplingIndex = (array[0] & 0x07) << 1 | array[1] >>> 7;
796 if (samplingIndex < 0 || samplingIndex >= mpegSamplingRates.length) {
797 this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: AAC invalid sampling frequency index!');
798 return;
799 }
800
801 var samplingFrequence = mpegSamplingRates[samplingIndex];
802
803 // 4 bits
804 var channelConfig = (array[1] & 0x78) >>> 3;
805 if (channelConfig < 0 || channelConfig >= 8) {
806 this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: AAC invalid channel configuration');
807 return;
808 }
809
810 if (audioObjectType === 5) {
811 // HE-AAC?
812 // 4 bits
813 extensionSamplingIndex = (array[1] & 0x07) << 1 | array[2] >>> 7;
814 // 5 bits
815 audioExtensionObjectType = (array[2] & 0x7C) >>> 2;
816 }
817
818 // workarounds for various browsers
819 var userAgent = self.navigator.userAgent.toLowerCase();
820
821 if (userAgent.indexOf('firefox') !== -1) {
822 // firefox: use SBR (HE-AAC) if freq less than 24kHz
823 if (samplingIndex >= 6) {
824 audioObjectType = 5;
825 config = new Array(4);
826 extensionSamplingIndex = samplingIndex - 3;
827 } else {
828 // use LC-AAC
829 audioObjectType = 2;
830 config = new Array(2);
831 extensionSamplingIndex = samplingIndex;
832 }
833 } else if (userAgent.indexOf('android') !== -1) {
834 // android: always use LC-AAC
835 audioObjectType = 2;
836 config = new Array(2);
837 extensionSamplingIndex = samplingIndex;
838 } else {
839 // for other browsers, e.g. chrome...
840 // Always use HE-AAC to make it easier to switch aac codec profile
841 audioObjectType = 5;
842 extensionSamplingIndex = samplingIndex;
843 config = new Array(4);
844
845 if (samplingIndex >= 6) {
846 extensionSamplingIndex = samplingIndex - 3;
847 } else if (channelConfig === 1) {
848 // Mono channel
849 audioObjectType = 2;
850 config = new Array(2);
851 extensionSamplingIndex = samplingIndex;
852 }
853 }
854
855 config[0] = audioObjectType << 3;
856 config[0] |= (samplingIndex & 0x0F) >>> 1;
857 config[1] = (samplingIndex & 0x0F) << 7;
858 config[1] |= (channelConfig & 0x0F) << 3;
859 if (audioObjectType === 5) {
860 config[1] |= (extensionSamplingIndex & 0x0F) >>> 1;
861 config[2] = (extensionSamplingIndex & 0x01) << 7;
862 // extended audio object type: force to 2 (LC-AAC)
863 config[2] |= 2 << 2;
864 config[3] = 0;
865 }
866
867 return {
868 config: config,
869 samplingRate: samplingFrequence,
870 channelCount: channelConfig,
871 codec: 'mp4a.40.' + audioObjectType,
872 originalAudioObjectType: originalAudioObjectType
873 };
874 }
875 }, {
876 key: '_isInitialMetadataDispatched',
877 value: function _isInitialMetadataDispatched() {
878 if (this._hasAudio && this._hasVideo) {
879 // both audio & video
880 return this._audioInitialMetadataDispatched && this._videoInitialMetadataDispatched;
881 }
882 if (this._hasAudio && !this._hasVideo) {
883 // audio only
884 return this._audioInitialMetadataDispatched;
885 }
886 if (!this._hasAudio && this._hasVideo) {
887 // video only
888 return this._videoInitialMetadataDispatched;
889 }
890 }
891 }]);
892
893 return tagDemux;
894}();
895
896exports.default = new tagDemux();
897
898/***/ }),
899/* 2 */
900/***/ (function(module, exports, __webpack_require__) {
901
902"use strict";
903
904
905Object.defineProperty(exports, "__esModule", {
906 value: true
907});
908
909var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
910 * reference flv.js
911 */
912/* eslint-disable */
913
914
915var _expGolomb = __webpack_require__(9);
916
917var _expGolomb2 = _interopRequireDefault(_expGolomb);
918
919function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
920
921function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
922
923var SPSParser = function () {
924 function SPSParser() {
925 _classCallCheck(this, SPSParser);
926 }
927
928 _createClass(SPSParser, null, [{
929 key: '_ebsp2rbsp',
930 value: function _ebsp2rbsp(uint8array) {
931 var src = uint8array;
932 var src_length = src.byteLength;
933 var dst = new Uint8Array(src_length);
934 var dst_idx = 0;
935
936 for (var i = 0; i < src_length; i++) {
937 if (i >= 2) {
938 // Unescape: Skip 0x03 after 00 00
939 if (src[i] === 0x03 && src[i - 1] === 0x00 && src[i - 2] === 0x00) {
940 continue;
941 }
942 }
943 dst[dst_idx] = src[i];
944 dst_idx++;
945 }
946
947 return new Uint8Array(dst.buffer, 0, dst_idx);
948 }
949 }, {
950 key: 'parseSPS',
951 value: function parseSPS(uint8array) {
952 var rbsp = SPSParser._ebsp2rbsp(uint8array);
953 var gb = new _expGolomb2.default(rbsp);
954
955 gb.readByte();
956 var profile_idc = gb.readByte(); // profile_idc
957 gb.readByte(); // constraint_set_flags[5] + reserved_zero[3]
958 var level_idc = gb.readByte(); // level_idc
959 gb.readUEG(); // seq_parameter_set_id
960
961 var profile_string = SPSParser.getProfileString(profile_idc);
962 var level_string = SPSParser.getLevelString(level_idc);
963 var chroma_format_idc = 1;
964 var chroma_format = 420;
965 var chroma_format_table = [0, 420, 422, 444];
966 var bit_depth = 8;
967
968 if (profile_idc === 100 || profile_idc === 110 || profile_idc === 122 || profile_idc === 244 || profile_idc === 44 || profile_idc === 83 || profile_idc === 86 || profile_idc === 118 || profile_idc === 128 || profile_idc === 138 || profile_idc === 144) {
969
970 chroma_format_idc = gb.readUEG();
971 if (chroma_format_idc === 3) {
972 gb.readBits(1); // separate_colour_plane_flag
973 }
974 if (chroma_format_idc <= 3) {
975 chroma_format = chroma_format_table[chroma_format_idc];
976 }
977
978 bit_depth = gb.readUEG() + 8; // bit_depth_luma_minus8
979 gb.readUEG(); // bit_depth_chroma_minus8
980 gb.readBits(1); // qpprime_y_zero_transform_bypass_flag
981 if (gb.readBool()) {
982 // seq_scaling_matrix_present_flag
983 var scaling_list_count = chroma_format_idc !== 3 ? 8 : 12;
984 for (var i = 0; i < scaling_list_count; i++) {
985 if (gb.readBool()) {
986 // seq_scaling_list_present_flag
987 if (i < 6) {
988 SPSParser._skipScalingList(gb, 16);
989 } else {
990 SPSParser._skipScalingList(gb, 64);
991 }
992 }
993 }
994 }
995 }
996 gb.readUEG(); // log2_max_frame_num_minus4
997 var pic_order_cnt_type = gb.readUEG();
998 if (pic_order_cnt_type === 0) {
999 gb.readUEG(); // log2_max_pic_order_cnt_lsb_minus_4
1000 } else if (pic_order_cnt_type === 1) {
1001 gb.readBits(1); // delta_pic_order_always_zero_flag
1002 gb.readSEG(); // offset_for_non_ref_pic
1003 gb.readSEG(); // offset_for_top_to_bottom_field
1004 var num_ref_frames_in_pic_order_cnt_cycle = gb.readUEG();
1005 for (var _i = 0; _i < num_ref_frames_in_pic_order_cnt_cycle; _i++) {
1006 gb.readSEG(); // offset_for_ref_frame
1007 }
1008 }
1009 gb.readUEG(); // max_num_ref_frames
1010 gb.readBits(1); // gaps_in_frame_num_value_allowed_flag
1011
1012 var pic_width_in_mbs_minus1 = gb.readUEG();
1013 var pic_height_in_map_units_minus1 = gb.readUEG();
1014
1015 var frame_mbs_only_flag = gb.readBits(1);
1016 if (frame_mbs_only_flag === 0) {
1017 gb.readBits(1); // mb_adaptive_frame_field_flag
1018 }
1019 gb.readBits(1); // direct_8x8_inference_flag
1020
1021 var frame_crop_left_offset = 0;
1022 var frame_crop_right_offset = 0;
1023 var frame_crop_top_offset = 0;
1024 var frame_crop_bottom_offset = 0;
1025
1026 var frame_cropping_flag = gb.readBool();
1027 if (frame_cropping_flag) {
1028 frame_crop_left_offset = gb.readUEG();
1029 frame_crop_right_offset = gb.readUEG();
1030 frame_crop_top_offset = gb.readUEG();
1031 frame_crop_bottom_offset = gb.readUEG();
1032 }
1033
1034 var sar_width = 1,
1035 sar_height = 1;
1036 var fps = 0,
1037 fps_fixed = true,
1038 fps_num = 0,
1039 fps_den = 0;
1040
1041 var vui_parameters_present_flag = gb.readBool();
1042 if (vui_parameters_present_flag) {
1043 if (gb.readBool()) {
1044 // aspect_ratio_info_present_flag
1045 var aspect_ratio_idc = gb.readByte();
1046 var sar_w_table = [1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2];
1047 var sar_h_table = [1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1];
1048
1049 if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {
1050 sar_width = sar_w_table[aspect_ratio_idc - 1];
1051 sar_height = sar_h_table[aspect_ratio_idc - 1];
1052 } else if (aspect_ratio_idc === 255) {
1053 sar_width = gb.readByte() << 8 | gb.readByte();
1054 sar_height = gb.readByte() << 8 | gb.readByte();
1055 }
1056 }
1057
1058 if (gb.readBool()) {
1059 // overscan_info_present_flag
1060 gb.readBool(); // overscan_appropriate_flag
1061 }
1062 if (gb.readBool()) {
1063 // video_signal_type_present_flag
1064 gb.readBits(4); // video_format & video_full_range_flag
1065 if (gb.readBool()) {
1066 // colour_description_present_flag
1067 gb.readBits(24); // colour_primaries & transfer_characteristics & matrix_coefficients
1068 }
1069 }
1070 if (gb.readBool()) {
1071 // chroma_loc_info_present_flag
1072 gb.readUEG(); // chroma_sample_loc_type_top_field
1073 gb.readUEG(); // chroma_sample_loc_type_bottom_field
1074 }
1075 if (gb.readBool()) {
1076 // timing_info_present_flag
1077 var num_units_in_tick = gb.readBits(32);
1078 var time_scale = gb.readBits(32);
1079 fps_fixed = gb.readBool(); // fixed_frame_rate_flag
1080
1081 fps_num = time_scale;
1082 fps_den = num_units_in_tick * 2;
1083 fps = fps_num / fps_den;
1084 }
1085 }
1086
1087 var sarScale = 1;
1088 if (sar_width !== 1 || sar_height !== 1) {
1089 sarScale = sar_width / sar_height;
1090 }
1091
1092 var crop_unit_x = 0,
1093 crop_unit_y = 0;
1094 if (chroma_format_idc === 0) {
1095 crop_unit_x = 1;
1096 crop_unit_y = 2 - frame_mbs_only_flag;
1097 } else {
1098 var sub_wc = chroma_format_idc === 3 ? 1 : 2;
1099 var sub_hc = chroma_format_idc === 1 ? 2 : 1;
1100 crop_unit_x = sub_wc;
1101 crop_unit_y = sub_hc * (2 - frame_mbs_only_flag);
1102 }
1103
1104 var codec_width = (pic_width_in_mbs_minus1 + 1) * 16;
1105 var codec_height = (2 - frame_mbs_only_flag) * ((pic_height_in_map_units_minus1 + 1) * 16);
1106
1107 codec_width -= (frame_crop_left_offset + frame_crop_right_offset) * crop_unit_x;
1108 codec_height -= (frame_crop_top_offset + frame_crop_bottom_offset) * crop_unit_y;
1109
1110 var present_width = Math.ceil(codec_width * sarScale);
1111
1112 gb.destroy();
1113 gb = null;
1114
1115 return {
1116 profile_string: profile_string, // baseline, high, high10, ...
1117 level_string: level_string, // 3, 3.1, 4, 4.1, 5, 5.1, ...
1118 bit_depth: bit_depth, // 8bit, 10bit, ...
1119 chroma_format: chroma_format, // 4:2:0, 4:2:2, ...
1120 chroma_format_string: SPSParser.getChromaFormatString(chroma_format),
1121
1122 frame_rate: {
1123 fixed: fps_fixed,
1124 fps: fps,
1125 fps_den: fps_den,
1126 fps_num: fps_num
1127 },
1128
1129 sar_ratio: {
1130 width: sar_width,
1131 height: sar_height
1132 },
1133
1134 codec_size: {
1135 width: codec_width,
1136 height: codec_height
1137 },
1138
1139 present_size: {
1140 width: present_width,
1141 height: codec_height
1142 }
1143 };
1144 }
1145 }, {
1146 key: '_skipScalingList',
1147 value: function _skipScalingList(gb, count) {
1148 var last_scale = 8,
1149 next_scale = 8;
1150 var delta_scale = 0;
1151 for (var i = 0; i < count; i++) {
1152 if (next_scale !== 0) {
1153 delta_scale = gb.readSEG();
1154 next_scale = (last_scale + delta_scale + 256) % 256;
1155 }
1156 last_scale = next_scale === 0 ? last_scale : next_scale;
1157 }
1158 }
1159 }, {
1160 key: 'getProfileString',
1161 value: function getProfileString(profile_idc) {
1162 switch (profile_idc) {
1163 case 66:
1164 return 'Baseline';
1165 case 77:
1166 return 'Main';
1167 case 88:
1168 return 'Extended';
1169 case 100:
1170 return 'High';
1171 case 110:
1172 return 'High10';
1173 case 122:
1174 return 'High422';
1175 case 244:
1176 return 'High444';
1177 default:
1178 return 'Unknown';
1179 }
1180 }
1181 }, {
1182 key: 'getLevelString',
1183 value: function getLevelString(level_idc) {
1184 return (level_idc / 10).toFixed(1);
1185 }
1186 }, {
1187 key: 'getChromaFormatString',
1188 value: function getChromaFormatString(chroma) {
1189 switch (chroma) {
1190 case 420:
1191 return '4:2:0';
1192 case 422:
1193 return '4:2:2';
1194 case 444:
1195 return '4:4:4';
1196 default:
1197 return 'Unknown';
1198 }
1199 }
1200 }]);
1201
1202 return SPSParser;
1203}();
1204
1205exports.default = SPSParser;
1206
1207/***/ }),
1208/* 3 */
1209/***/ (function(module, exports, __webpack_require__) {
1210
1211"use strict";
1212
1213
1214Object.defineProperty(exports, "__esModule", {
1215 value: true
1216});
1217
1218var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
1219
1220function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1221
1222/**
1223 * 代码借鉴了flv.js
1224 * 增加了自己的注释和写法
1225 */
1226/* eslint-disable */
1227var MP4 = function () {
1228 function MP4() {
1229 _classCallCheck(this, MP4);
1230 }
1231
1232 _createClass(MP4, null, [{
1233 key: 'init',
1234 value: function init() {
1235 MP4.types = {
1236 avc1: [],
1237 avcC: [],
1238 btrt: [],
1239 dinf: [],
1240 dref: [],
1241 esds: [],
1242 ftyp: [],
1243 hdlr: [],
1244 mdat: [],
1245 mdhd: [],
1246 mdia: [],
1247 mfhd: [],
1248 minf: [],
1249 moof: [],
1250 moov: [],
1251 mp4a: [],
1252 mvex: [],
1253 mvhd: [],
1254 sdtp: [],
1255 stbl: [],
1256 stco: [],
1257 stsc: [],
1258 stsd: [],
1259 stsz: [],
1260 stts: [],
1261 tfdt: [],
1262 tfhd: [],
1263 traf: [],
1264 trak: [],
1265 trun: [],
1266 trex: [],
1267 tkhd: [],
1268 vmhd: [],
1269 smhd: []
1270 };
1271
1272 for (var name in MP4.types) {
1273 if (MP4.types.hasOwnProperty(name)) {
1274 MP4.types[name] = [name.charCodeAt(0), name.charCodeAt(1), name.charCodeAt(2), name.charCodeAt(3)];
1275 }
1276 }
1277
1278 var constants = MP4.constants = {};
1279
1280 constants.FTYP = new Uint8Array([0x69, 0x73, 0x6F, 0x6D, // major_brand: isom isom MP4 Base Media v1 [IS0 14496-12:2003] ISO YES video/mp4
1281 0x0, 0x0, 0x0, 0x1, // minor_version: 0x01
1282 0x69, 0x73, 0x6F, 0x6D, // isom
1283 0x61, 0x76, 0x63, 0x31 // avc1
1284 ]);
1285
1286 constants.STSD_PREFIX = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags version字段后会有一个entry count字段
1287 0x00, 0x00, 0x00, 0x01 // entry_count 根据entry的个数,每个entry会有type信息,如“vide”、“sund”等,根据type不同sample description会提供不同的信息,例如对于video track,会有“VisualSampleEntry”类型信息,对于audio track会有“AudioSampleEntry”类型信息。
1288 ]);
1289
1290 constants.STTS = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
1291 0x00, 0x00, 0x00, 0x00 // entry_count 0个索引
1292 ]);
1293
1294 constants.STSC = constants.STCO = constants.STTS;
1295
1296 constants.STSZ = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
1297 0x00, 0x00, 0x00, 0x00, // sample_size
1298 0x00, 0x00, 0x00, 0x00 // sample_count
1299 ]);
1300
1301 constants.HDLR_VIDEO = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
1302 0x00, 0x00, 0x00, 0x00, // pre_defined
1303 0x76, 0x69, 0x64, 0x65, // handler_type: 'vide' 在media box中,该值为4个字符 “vide”— video track
1304 0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes
1305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 保留位
1306 0x56, 0x69, 0x64, 0x65, 0x6F, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x00 // name: VideoHandler 长度不定 track type name,以‘\0’结尾的字符串
1307 ]);
1308
1309 constants.HDLR_AUDIO = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
1310 0x00, 0x00, 0x00, 0x00, // pre_defined
1311 0x73, 0x6F, 0x75, 0x6E, // handler_type: 'soun'在media box中,该值为4个字符 “soun”— audio track
1312 0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes
1313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 保留位
1314 0x53, 0x6F, 0x75, 0x6E, 0x64, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x00 // name: SoundHandler 长度不定 track type name,以‘\0’结尾的字符串
1315 ]);
1316
1317 constants.DREF = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
1318 0x00, 0x00, 0x00, 0x01, // entry_count 1个url
1319 // url box开始
1320 0x00, 0x00, 0x00, 0x0C, // entry_size
1321 0x75, 0x72, 0x6C, 0x20, // type 'url '
1322 0x00, 0x00, 0x00, 0x01 // version(0) + flags 当“url”或“urn”的box flag为1时,字符串均为空。
1323 ]);
1324
1325 // Sound media header
1326 constants.SMHD = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags box版本,0或1,一般为0。
1327 0x00, 0x00, 0x00, 0x00 // balance(2) + reserved(2) 立体声平衡,[8.8] 格式值,一般为0,-1.0表示全部左声道,1.0表示全部右声道+2位保留位
1328 ]);
1329
1330 // video media header
1331 constants.VMHD = new Uint8Array([0x00, 0x00, 0x00, 0x01, // version(0) + flags
1332 0x00, 0x00, // graphicsmode: 2 bytes 视频合成模式,为0时拷贝原始图像,否则与opcolor进行合成 //理论上是4位啊 暂时保留
1333 0x00, 0x00, 0x00, 0x00, // opcolor: 3 * 2 bytes {red,green,blue}
1334 0x00, 0x00]);
1335 }
1336
1337 /**
1338 * 封装box
1339 */
1340
1341 }, {
1342 key: 'box',
1343 value: function box(type) {
1344 var size = 8;
1345 var result = null;
1346 var datas = Array.prototype.slice.call(arguments, 1);
1347 var arrayCount = datas.length;
1348
1349 for (var i = 0; i < arrayCount; i++) {
1350 size += datas[i].byteLength;
1351 }
1352 // box头部大小
1353 result = new Uint8Array(size);
1354 result[0] = size >>> 24 & 0xFF; // size
1355 result[1] = size >>> 16 & 0xFF;
1356 result[2] = size >>> 8 & 0xFF;
1357 result[3] = size & 0xFF;
1358 // 写入box的type
1359 result.set(type, 4); // type
1360
1361 var offset = 8;
1362 for (var _i = 0; _i < arrayCount; _i++) {
1363 // data body
1364 result.set(datas[_i], offset);
1365 offset += datas[_i].byteLength;
1366 }
1367
1368 return result;
1369 }
1370
1371 // 创建ftyp&moov
1372
1373 }, {
1374 key: 'generateInitSegment',
1375 value: function generateInitSegment(meta) {
1376 if (meta.constructor != Array) {
1377 meta = [meta];
1378 }
1379 var ftyp = MP4.box(MP4.types.ftyp, MP4.constants.FTYP);
1380 var moov = MP4.moov(meta);
1381
1382 var result = new Uint8Array(ftyp.byteLength + moov.byteLength);
1383 result.set(ftyp, 0);
1384 result.set(moov, ftyp.byteLength);
1385 return result;
1386 }
1387
1388 // Movie metadata box
1389
1390 }, {
1391 key: 'moov',
1392 value: function moov(meta) {
1393 var mvhd = MP4.mvhd(meta[0].timescale, meta[0].duration); // /moov里面的第一个box
1394 var vtrak = MP4.trak(meta[0]);
1395 var atrak = void 0;
1396 if (meta.length > 1) {
1397 atrak = MP4.trak(meta[1]);
1398 }
1399
1400 var mvex = MP4.mvex(meta);
1401 if (meta.length > 1) {
1402 return MP4.box(MP4.types.moov, mvhd, vtrak, atrak, mvex);
1403 } else {
1404 return MP4.box(MP4.types.moov, mvhd, vtrak, mvex);
1405 }
1406 }
1407
1408 // Movie header box
1409
1410 }, {
1411 key: 'mvhd',
1412 value: function mvhd(timescale, duration) {
1413 return MP4.box(MP4.types.mvhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags 1位的box版本+3位flags box版本,0或1,一般为0。(以下字节数均按version=0)
1414 0x00, 0x00, 0x00, 0x00, // creation_time 创建时间 (相对于UTC时间1904-01-01零点的秒数)
1415 0x00, 0x00, 0x00, 0x00, // modification_time 修改时间
1416 timescale >>> 24 & 0xFF, // timescale: 4 bytes 文件媒体在1秒时间内的刻度值,可以理解为1秒长度
1417 timescale >>> 16 & 0xFF, timescale >>> 8 & 0xFF, timescale & 0xFF, duration >>> 24 & 0xFF, // duration: 4 bytes 该track的时间长度,用duration和time scale值可以计算track时长,比如audio track的time scale = 8000, duration = 560128,时长为70.016,video track的time scale = 600, duration = 42000,时长为70
1418 duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, 0x00, 0x01, 0x00, 0x00, // Preferred rate: 1.0 推荐播放速率,高16位和低16位分别为小数点整数部分和小数部分,即[16.16] 格式,该值为1.0(0x00010000)表示正常前向播放
1419 0x01, 0x00, 0x00, 0x00, // PreferredVolume(1.0, 2bytes) + reserved(2bytes) 与rate类似,[8.8] 格式,1.0(0x0100)表示最大音量
1420 0x00, 0x00, 0x00, 0x00, // reserved: 4 + 4 bytes 保留位
1421 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----
1422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 视频变换矩阵 线性代数
1423 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // ----end composition matrix----
1424 0x00, 0x00, 0x00, 0x00, // ----begin pre_defined 6 * 4 bytes----
1425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre-defined 保留位
1426 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ----end pre_defined 6 * 4 bytes----
1427 0xFF, 0xFF, 0xFF, 0xFF // next_track_ID 下一个track使用的id号
1428 ]));
1429 }
1430
1431 // Track box
1432
1433 }, {
1434 key: 'trak',
1435 value: function trak(meta) {
1436 return MP4.box(MP4.types.trak, MP4.tkhd(meta), MP4.mdia(meta));
1437 }
1438
1439 // Track header box
1440
1441 }, {
1442 key: 'tkhd',
1443 value: function tkhd(meta) {
1444 var trackId = meta.id,
1445 duration = meta.duration;
1446 var width = meta.presentWidth,
1447 height = meta.presentHeight;
1448
1449 return MP4.box(MP4.types.tkhd, new Uint8Array([0x00, 0x00, 0x00, 0x07, // version(0) + flags 1位版本 box版本,0或1,一般为0。(以下字节数均按version=0)按位或操作结果值,预定义如下:
1450 // 0x000001 track_enabled,否则该track不被播放;
1451 // 0x000002 track_in_movie,表示该track在播放中被引用;
1452 // 0x000004 track_in_preview,表示该track在预览时被引用。
1453 // 一般该值为7,1+2+4 如果一个媒体所有track均未设置track_in_movie和track_in_preview,将被理解为所有track均设置了这两项;对于hint track,该值为0
1454 // hint track  这个特殊的track并不包含媒体数据,而是包含了一些将其他数据track打包成流媒体的指示信息。
1455 0x00, 0x00, 0x00, 0x00, // creation_time 创建时间(相对于UTC时间1904-01-01零点的秒数)
1456 0x00, 0x00, 0x00, 0x00, // modification_time 修改时间
1457 trackId >>> 24 & 0xFF, // track_ID: 4 bytes id号,不能重复且不能为0
1458 trackId >>> 16 & 0xFF, trackId >>> 8 & 0xFF, trackId & 0xFF, 0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes 保留位
1459 duration >>> 24 & 0xFF, // duration: 4 bytes track的时间长度
1460 duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes 保留位
1461 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // layer(2bytes) + alternate_group(2bytes) 视频层,默认为0,值小的在上层.track分组信息,默认为0表示该track未与其他track有群组关系
1462 0x00, 0x00, 0x00, 0x00, // volume(2bytes) + reserved(2bytes) [8.8] 格式,如果为音频track,1.0(0x0100)表示最大音量;否则为0 +保留位
1463 0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----
1464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // 视频变换矩阵
1465 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // ----end composition matrix----
1466 width >>> 8 & 0xFF, // //宽度
1467 width & 0xFF, 0x00, 0x00, height >>> 8 & 0xFF, // 高度
1468 height & 0xFF, 0x00, 0x00]));
1469 }
1470
1471 /**
1472 * “mdia”也是个container box,其子box的结构和种类还是比较复杂的。先来看一个“mdia”的实例结构树图。
1473 * 总体来说,“mdia”定义了track媒体类型以及sample数据,描述sample信息。一般“mdia”包含一个“mdhd”,
1474 * 一个“hdlr”和一个“minf”,其中“mdhd”为media header box,“hdlr”为handler reference box,
1475 * “minf”为media information box。
1476 *
1477 * mdia
1478 * mdhd
1479 * hdlr
1480 * minf
1481 * smhd
1482 * dinf
1483 * dref
1484 * url
1485 * stbl
1486 * stsd
1487 * mp4a
1488 * esds
1489 * stts
1490 * stsc
1491 * stsz
1492 * stco
1493 */
1494
1495 }, {
1496 key: 'mdia',
1497 value: function mdia(meta) {
1498 return MP4.box(MP4.types.mdia, MP4.mdhd(meta), MP4.hdlr(meta), MP4.minf(meta));
1499 }
1500
1501 // Media header box
1502
1503 }, {
1504 key: 'mdhd',
1505 value: function mdhd(meta) {
1506 var timescale = meta.timescale;
1507 var duration = meta.duration;
1508 return MP4.box(MP4.types.mdhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags // version(0) + flags box版本,0或1,一般为0。
1509 0x00, 0x00, 0x00, 0x00, // creation_time 创建时间
1510 0x00, 0x00, 0x00, 0x00, // modification_time修改时间
1511 timescale >>> 24 & 0xFF, // timescale: 4 bytes 文件媒体在1秒时间内的刻度值,可以理解为1秒长度
1512 timescale >>> 16 & 0xFF, timescale >>> 8 & 0xFF, timescale & 0xFF, duration >>> 24 & 0xFF, // duration: 4 bytes track的时间长度
1513 duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, 0x55, 0xC4, // language: und (undetermined) 媒体语言码。最高位为0,后面15位为3个字符(见ISO 639-2/T标准中定义)
1514 0x00, 0x00 // pre_defined = 0
1515 ]));
1516 }
1517
1518 // Media handler reference box
1519
1520 }, {
1521 key: 'hdlr',
1522 value: function hdlr(meta) {
1523 var data = null;
1524 if (meta.type === 'audio') {
1525 data = MP4.constants.HDLR_AUDIO;
1526 } else {
1527 data = MP4.constants.HDLR_VIDEO;
1528 }
1529 return MP4.box(MP4.types.hdlr, data);
1530 }
1531
1532 /**
1533 * “minf”存储了解释track媒体数据的handler-specific信息,media handler用这些信息将媒体时间映射到媒体数据并进行处理。“minf”中的信息格式和内容与媒体类型以及解释媒体数据的media handler密切相关,其他media handler不知道如何解释这些信息。“minf”是一个container box,其实际内容由子box说明。
1534 一般情况下,“minf”包含一个header box,一个“dinf”和一个“stbl”,其中,header box根据track type(即media handler type)分为“vmhd”、“smhd”、“hmhd”和“nmhd”,“dinf”为data information box,“stbl”为sample table box。下面分别介绍。
1535 *
1536 */
1537 // Media infomation box
1538
1539 }, {
1540 key: 'minf',
1541 value: function minf(meta) {
1542 // header box根据track type(即media handler type)分为“vmhd”、“smhd”、“hmhd”和“nmhd”
1543 var xmhd = null;
1544 if (meta.type === 'audio') {
1545 xmhd = MP4.box(MP4.types.smhd, MP4.constants.SMHD);
1546 } else {
1547 xmhd = MP4.box(MP4.types.vmhd, MP4.constants.VMHD);
1548 }
1549 return MP4.box(MP4.types.minf, xmhd, MP4.dinf(), MP4.stbl(meta));
1550 }
1551
1552 /**
1553 * Data Information Box
1554 * “dinf”解释如何定位媒体信息,是一个container box。“dinf”一般包含一个“dref”,即data reference box;
1555 * “dref”下会包含若干个“url”或“urn”,这些box组成一个表,用来定位track数据。
1556 * 简单的说,track可以被分成若干段,每一段都可以根据“url”或“urn”指向的地址来获取数据,
1557 * sample描述中会用这些片段的序号将这些片段组成一个完整的track。
1558 * 一般情况下,当数据被完全包含在文件中时,“url”或“urn”中的定位字符串是空的。
1559 */
1560
1561 }, {
1562 key: 'dinf',
1563 value: function dinf() {
1564 var result = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, MP4.constants.DREF));
1565 return result;
1566 }
1567
1568 /**
1569 * Sample Table Box(stbl)
1570 * “stbl”几乎是普通的MP4文件中最复杂的一个box了,首先需要回忆一下sample的概念。
1571 * sample是媒体数据存储的单位,存储在media的chunk中,chunk和sample的长度均可互不相同,如下图所示。
1572 “stbl”是一个container box,其子box包括:sample description box(stsd)、
1573 * time to sample box(stts)、sample size box(stsz或stz2)、
1574 * sample to chunk box(stsc)、chunk offset box(stco或co64)、
1575 * composition time to sample box(ctts)、sync sample box(stss)
1576 * stsd”必不可少,且至少包含一个条目,该box包含了data reference box进行sample数据检索的信息。
1577 * 没有“stsd”就无法计算media sample的存储位置。“stsd”包含了编码的信息,其存储的信息随媒体类型不同而不同。
1578 * stbl
1579 * stsd
1580 * avc1
1581 * avcC
1582 * stts
1583 * stsc
1584 * stsz
1585 * stco
1586 */
1587
1588 }, {
1589 key: 'stbl',
1590 value: function stbl(meta) {
1591 var result = MP4.box(MP4.types.stbl, // type: stbl
1592 MP4.stsd(meta), // Sample Description Table
1593 MP4.box(MP4.types.stts, MP4.constants.STTS), // Time-To-Sample 因为stts的entry count 为0
1594 // 所以没有关键帧index 的stss
1595 // 也没有CTTS box CTTS是记录偏移量
1596 MP4.box(MP4.types.stsc, MP4.constants.STSC), // Sample-To-Chunk
1597 MP4.box(MP4.types.stsz, MP4.constants.STSZ), // Sample size
1598 MP4.box(MP4.types.stco, MP4.constants.STCO) // Chunk offset
1599 );
1600 return result;
1601 }
1602
1603 /**
1604 * Sample Description Box(stsd)
1605 box header和version字段后会有一个entry count字段,
1606 * 根据entry的个数,每个entry会有type信息,如“vide”、“sund”等,
1607 * 根据type不同sample description会提供不同的信息,例如对于video track,
1608 * 会有“VisualSampleEntry”类型信息,对于audio track会有“AudioSampleEntry”类型信息。
1609 * * stsd
1610 * mp4a
1611 * esds
1612 *
1613 *
1614 *
1615 *
1616 * 4 bytes - length in total
1617 4 bytes - 4 char code of sample description table (stsd)
1618 4 bytes - version & flags
1619 4 bytes - number of sample entries (num_sample_entries)
1620 [
1621 4 bytes - length of sample entry (len_sample_entry)
1622 4 bytes - 4 char code of sample entry
1623 ('len_sample_entry' - 8) bytes of data
1624 ] (repeated 'num_sample_entries' times)
1625 (4 bytes - optional 0x00000000 as end of box marker )
1626 */
1627
1628 }, {
1629 key: 'stsd',
1630 value: function stsd(meta) {
1631 if (meta.type === 'audio') {
1632 return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.mp4a(meta));
1633 } else {
1634 return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.avc1(meta));
1635 }
1636 }
1637 }, {
1638 key: 'mp4a',
1639 value: function mp4a(meta) {
1640 var channelCount = meta.channelCount;
1641 var sampleRate = meta.audioSampleRate;
1642
1643 var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, // reserved(4) 6个字节,设置为0;
1644 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)
1645 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes 保留位
1646 0x00, 0x00, 0x00, 0x00, 0x00, channelCount, // channelCount(2) 单声道还是双声道
1647 0x00, 0x10, // sampleSize(2)
1648 0x00, 0x00, 0x00, 0x00, // reserved(4) 4字节保留位
1649 sampleRate >>> 8 & 0xFF, // Audio sample rate 显然要右移16位才有意义 template unsigned int(32) samplerate = {timescale of media}<<16;
1650 sampleRate & 0xFF, 0x00, 0x00]);
1651
1652 return MP4.box(MP4.types.mp4a, data, MP4.esds(meta));
1653 }
1654 }, {
1655 key: 'esds',
1656 value: function esds(meta) {
1657 var config = meta.config;
1658 var configSize = config.length;
1659 var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version 0 + flags
1660
1661 0x03, // descriptor_type MP4ESDescrTag
1662 0x17 + configSize, // length3
1663 0x00, 0x01, // es_id
1664 0x00, // stream_priority
1665
1666 0x04, // descriptor_type MP4DecConfigDescrTag
1667 0x0F + configSize, // length
1668 0x40, // codec: mpeg4_audio
1669 /**
1670 *当objectTypeIndication为0x40时,为MPEG-4 Audio(MPEG-4 Audio generally is thought of as AAC
1671 * but there is a whole framework of audio codecs that can Go in MPEG-4 Audio including AAC, BSAC, ALS, CELP,
1672 * and something called MP3On4),如果想更细分format为aac还是mp3,
1673 * 可以读取MP4DecSpecificDescr层data[0]的前五位
1674 */
1675 0x15, // stream_type: Audio
1676 0x00, 0x00, 0x00, // buffer_size
1677 0x00, 0x00, 0x00, 0x00, // maxBitrate
1678 0x00, 0x00, 0x00, 0x00, // avgBitrate
1679
1680 0x05 // descriptor_type MP4DecSpecificDescrTag
1681 ].concat([configSize]).concat(config).concat([0x06, 0x01, 0x02 // GASpecificConfig
1682 ]));
1683 return MP4.box(MP4.types.esds, data);
1684 }
1685
1686 /**
1687 * 改版
1688 *stsd下的avc1视频解析
1689 */
1690
1691 }, {
1692 key: 'avc1',
1693 value: function avc1(meta) {
1694 var avcc = meta.avcc;
1695 var width = meta.codecWidth,
1696 height = meta.codecHeight;
1697
1698 var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, // // reserved(4) 6个 保留位 Reserved:6个字节,设置为0;
1699 0x00, 0x00, 0x00, 0x01, // reserved(2) + {{{{data_reference_index(2) 数据引用索引}}}}
1700 0x00, 0x00, 0x00, 0x00, // pre_defined(2) + reserved(2)
1701 0x00, 0x00, 0x00, 0x00, // pre_defined: 3 * 4 bytes 3*4个字节的保留位
1702 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, width >>> 8 & 0xFF, // width: 2 bytes
1703 width & 0xFF, height >>> 8 & 0xFF, // height: 2 bytes
1704 height & 0xFF, 0x00, 0x48, 0x00, 0x00, // horizresolution: 4 bytes 常数
1705 0x00, 0x48, 0x00, 0x00, // vertresolution: 4 bytes 常数
1706 0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes 保留位
1707 0x00, 0x01, // frame_count
1708 // frame_count表明多少帧压缩视频存储在每个样本。默认是1,每样一帧;它可能超过1每个样本的多个帧数
1709 0x04, // strlen compressorname: 32 bytes String[32]
1710 // 32个8 bit 第一个8bit表示长度,剩下31个8bit表示内容
1711 0x67, 0x31, 0x31, 0x31, // compressorname: 32 bytes 翻译过来是g111
1712 0x00, 0x00, 0x00, 0x00, //
1713 0x00, 0x00, 0x00, 0x00, //
1714 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, // depth 颜色深度
1715 0xFF, 0xFF // pre_defined = -1
1716 ]);
1717 return MP4.box(MP4.types.avc1, data, MP4.box(MP4.types.avcC, avcc));
1718 }
1719
1720 // Movie Extends box
1721
1722 }, {
1723 key: 'mvex',
1724 value: function mvex(meta) {
1725 if (meta.length > 1) {
1726 return MP4.box(MP4.types.mvex, MP4.trex(meta[0]), MP4.trex(meta[1]));
1727 } else {
1728 return MP4.box(MP4.types.mvex, MP4.trex(meta[0]));
1729 }
1730 }
1731
1732 // Track Extends box
1733
1734 }, {
1735 key: 'trex',
1736 value: function trex(meta) {
1737 var trackId = meta.id;
1738 var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
1739 trackId >>> 24 & 0xFF, // track_ID
1740 trackId >>> 16 & 0xFF, trackId >>> 8 & 0xFF, trackId & 0xFF, 0x00, 0x00, 0x00, 0x01, // default_sample_description_index
1741 0x00, 0x00, 0x00, 0x00, // default_sample_duration
1742 0x00, 0x00, 0x00, 0x00, // default_sample_size
1743 0x00, 0x01, 0x00, 0x01 // default_sample_flags
1744 ]);
1745 // if (meta.type !== 'video') {
1746 // data[data.length - 1] = 0x00;
1747 // }
1748 return MP4.box(MP4.types.trex, data);
1749 }
1750
1751 // Movie fragment box
1752
1753 }, {
1754 key: 'moof',
1755 value: function moof(track, baseMediaDecodeTime) {
1756 return MP4.box(MP4.types.moof, MP4.mfhd(track.sequenceNumber), MP4.traf(track, baseMediaDecodeTime));
1757 }
1758 }, {
1759 key: 'mfhd',
1760 value: function mfhd(sequenceNumber) {
1761 var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, sequenceNumber >>> 24 & 0xFF, // sequence_number: int32
1762 sequenceNumber >>> 16 & 0xFF, sequenceNumber >>> 8 & 0xFF, sequenceNumber & 0xFF]);
1763 return MP4.box(MP4.types.mfhd, data);
1764 }
1765
1766 // Track fragment box
1767
1768 }, {
1769 key: 'traf',
1770 value: function traf(track, baseMediaDecodeTime) {
1771 var trackId = track.id;
1772
1773 // Track fragment header box
1774 var tfhd = MP4.box(MP4.types.tfhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) & flags
1775 trackId >>> 24 & 0xFF, // track_ID
1776 trackId >>> 16 & 0xFF, trackId >>> 8 & 0xFF, trackId & 0xFF]));
1777 // Track Fragment Decode Time
1778 var tfdt = MP4.box(MP4.types.tfdt, new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) & flags
1779 baseMediaDecodeTime >>> 24 & 0xFF, // baseMediaDecodeTime: int32
1780 baseMediaDecodeTime >>> 16 & 0xFF, baseMediaDecodeTime >>> 8 & 0xFF, baseMediaDecodeTime & 0xFF]));
1781 var sdtp = MP4.sdtp(track);
1782 var trun = MP4.trun(track, sdtp.byteLength + 16 + 16 + 8 + 16 + 8 + 8);
1783
1784 return MP4.box(MP4.types.traf, tfhd, tfdt, trun, sdtp);
1785 }
1786
1787 // Sample Dependency Type box
1788
1789 }, {
1790 key: 'sdtp',
1791 value: function sdtp(track) {
1792 var samples = track.samples || [];
1793 var sampleCount = samples.length;
1794 var data = new Uint8Array(4 + sampleCount);
1795 // 0~4 bytes: version(0) & flags
1796 for (var i = 0; i < sampleCount; i++) {
1797 var flags = samples[i].flags;
1798 data[i + 4] = flags.isLeading << 6 | // is_leading: 2 (bit)
1799 flags.dependsOn << 4 // sample_depends_on
1800 | flags.isDependedOn << 2 // sample_is_depended_on
1801 | flags.hasRedundancy; // sample_has_redundancy
1802 }
1803 return MP4.box(MP4.types.sdtp, data);
1804 }
1805
1806 // Track fragment run box
1807
1808 }, {
1809 key: 'trun',
1810 value: function trun(track, offset) {
1811 var samples = track.samples || [];
1812 var sampleCount = samples.length;
1813 var dataSize = 12 + 16 * sampleCount;
1814 var data = new Uint8Array(dataSize);
1815 offset += 8 + dataSize;
1816
1817 data.set([0x00, 0x00, 0x0F, 0x01, // version(0) & flags
1818 sampleCount >>> 24 & 0xFF, // sample_count
1819 sampleCount >>> 16 & 0xFF, sampleCount >>> 8 & 0xFF, sampleCount & 0xFF, offset >>> 24 & 0xFF, // data_offset
1820 offset >>> 16 & 0xFF, offset >>> 8 & 0xFF, offset & 0xFF], 0);
1821
1822 for (var i = 0; i < sampleCount; i++) {
1823
1824 var duration = samples[i].duration;
1825
1826 var size = samples[i].size;
1827 var flags = samples[i].flags;
1828 var cts = samples[i].cts;
1829 data.set([duration >>> 24 & 0xFF, // sample_duration
1830 duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, size >>> 24 & 0xFF, // sample_size
1831 size >>> 16 & 0xFF, size >>> 8 & 0xFF, size & 0xFF, flags.isLeading << 2 | flags.dependsOn, // sample_flags
1832 flags.isDependedOn << 6 | flags.hasRedundancy << 4 | flags.isNonSync, 0x00, 0x00, // sample_degradation_priority
1833 cts >>> 24 & 0xFF, // sample_composition_time_offset
1834 cts >>> 16 & 0xFF, cts >>> 8 & 0xFF, cts & 0xFF], 12 + 16 * i);
1835 }
1836 return MP4.box(MP4.types.trun, data);
1837 }
1838 }, {
1839 key: 'mdat',
1840 value: function mdat(data) {
1841 return MP4.box(MP4.types.mdat, data);
1842 }
1843 }]);
1844
1845 return MP4;
1846}();
1847
1848MP4.init();
1849
1850exports.default = MP4;
1851
1852/***/ }),
1853/* 4 */
1854/***/ (function(module, exports, __webpack_require__) {
1855
1856"use strict";
1857
1858
1859Object.defineProperty(exports, "__esModule", {
1860 value: true
1861});
1862
1863var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* eslint-disable */
1864
1865
1866var _flvParse = __webpack_require__(5);
1867
1868var _flvParse2 = _interopRequireDefault(_flvParse);
1869
1870var _tagdemux = __webpack_require__(1);
1871
1872var _tagdemux2 = _interopRequireDefault(_tagdemux);
1873
1874var _mp4remux = __webpack_require__(3);
1875
1876var _mp4remux2 = _interopRequireDefault(_mp4remux);
1877
1878var _mp4moof = __webpack_require__(11);
1879
1880var _mp4moof2 = _interopRequireDefault(_mp4moof);
1881
1882var _chimeeHelper = __webpack_require__(15);
1883
1884function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1885
1886function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
1887
1888function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
1889
1890function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1891
1892var flv2fmp4 = function () {
1893
1894 /**
1895 * Creates an instance of flv2fmp4.
1896 * config 里面有_isLive属性,是否是直播
1897 * @param {any} config
1898 *
1899 * @memberof flv2fmp4
1900 */
1901 function flv2fmp4(config) {
1902 _classCallCheck(this, flv2fmp4);
1903
1904 this._config = { _isLive: false };
1905 this._config = Object.assign(this._config, config);
1906
1907 // 外部方法赋值
1908 this.onInitSegment = null;
1909 this.onMediaSegment = null;
1910 this.onMediaInfo = null;
1911 this.seekCallBack = null;
1912
1913 // 内部使用
1914 this.loadmetadata = false;
1915 this.ftyp_moov = null;
1916 this.metaSuccRun = false;
1917 this.metas = [];
1918 this.parseChunk = null;
1919 this.hasVideo = false;
1920 this.hasAudio = false;
1921 this._error = null;
1922 // 临时记录seek时间
1923 this._pendingResolveSeekPoint = -1;
1924
1925 // 临时记录flv数据起始时间
1926 this._tempBaseTime = 0;
1927
1928 // 处理flv数据入口
1929 this.setflvBase = this.setflvBasefrist;
1930
1931 _tagdemux2.default._onTrackMetadata = this.Metadata.bind(this);
1932 _tagdemux2.default._onMediaInfo = this.metaSucc.bind(this);
1933 _tagdemux2.default._onDataAvailable = this.onDataAvailable.bind(this);
1934 _tagdemux2.default._onError = this.error.bind(this);
1935 this.m4mof = new _mp4moof2.default(this._config);
1936 this.m4mof.onMediaSegment = this.onMdiaSegment.bind(this);
1937 }
1938
1939 _createClass(flv2fmp4, [{
1940 key: 'seek',
1941 value: function seek(baseTime) {
1942 this.setflvBase = this.setflvBasefrist;
1943 if (baseTime == undefined || baseTime == 0) {
1944 baseTime = 0;
1945 this._pendingResolveSeekPoint = -1;
1946 }
1947 if (this._tempBaseTime != baseTime) {
1948 this._tempBaseTime = baseTime;
1949 _tagdemux2.default._timestampBase = baseTime;
1950 this.m4mof.seek(baseTime);
1951 this.m4mof.insertDiscontinuity();
1952 this._pendingResolveSeekPoint = baseTime;
1953 }
1954 }
1955
1956 /**
1957 * 不要主动调用这个接口!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1958 * 第一次接受数据,和seek时候接受数据入口,
1959 *
1960 * @param {any} arraybuff
1961 * @param {any} baseTime
1962 * @returns
1963 *
1964 * @memberof flv2fmp4
1965 */
1966
1967 }, {
1968 key: 'setflvBasefrist',
1969 value: function setflvBasefrist(arraybuff, baseTime) {
1970 var offset = 0;
1971 try {
1972 offset = _flvParse2.default.setFlv(new Uint8Array(arraybuff));
1973 } catch (error) {
1974 this.error(error);
1975 }
1976
1977 if (_flvParse2.default.arrTag.length > 0) {
1978 this.hasAudio = _flvParse2.default._hasAudio;
1979 this.hasVideo = _flvParse2.default._hasVideo;
1980 if (this._tempBaseTime != 0 && this._tempBaseTime == _flvParse2.default.arrTag[0].getTime()) {
1981 _tagdemux2.default._timestampBase = 0;
1982 }
1983 try {
1984 _tagdemux2.default.moofTag(_flvParse2.default.arrTag);
1985 } catch (error) {
1986 this.error(error);
1987 }
1988
1989 this.setflvBase = this.setflvBaseUsually;
1990 }
1991
1992 return offset;
1993 }
1994
1995 /**
1996 * 不要主动调用这个接口!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1997 * 后续接受数据接口
1998 * @param {any} arraybuff
1999 * @param {any} baseTime
2000 * @returns
2001 *
2002 * @memberof flv2fmp4
2003 */
2004
2005 }, {
2006 key: 'setflvBaseUsually',
2007 value: function setflvBaseUsually(arraybuff, baseTime) {
2008 var offset = 0;
2009 try {
2010 offset = _flvParse2.default.setFlv(new Uint8Array(arraybuff));
2011 } catch (error) {
2012 this.error(error);
2013 }
2014 if (_flvParse2.default.arrTag.length > 0) {
2015 try {
2016 _tagdemux2.default.moofTag(_flvParse2.default.arrTag);
2017 } catch (error) {
2018 this.error(error);
2019 }
2020 }
2021
2022 return offset;
2023 }
2024
2025 /**
2026 * 不要主动调用这个接口!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2027 * moof回调
2028 *
2029 * @param {any} track
2030 * @param {any} value
2031 *
2032 * @memberof flv2fmp4
2033 */
2034
2035 }, {
2036 key: 'onMdiaSegment',
2037 value: function onMdiaSegment(track, value) {
2038
2039 if (this.onMediaSegment) {
2040 this.onMediaSegment(new Uint8Array(value.data));
2041 }
2042 if (this._pendingResolveSeekPoint != -1 && track == 'video') {
2043 var seekpoint = this._pendingResolveSeekPoint;
2044 this._pendingResolveSeekPoint = -1;
2045 if (this.seekCallBack) {
2046 this.seekCallBack(seekpoint);
2047 }
2048 }
2049 }
2050
2051 /**
2052 *
2053 * 音频和视频的初始化tag
2054 *
2055 * @param {any} type
2056 * @param {any} meta
2057 *
2058 * @memberof flv2fmp4
2059 */
2060
2061 }, {
2062 key: 'Metadata',
2063 value: function Metadata(type, meta) {
2064 switch (type) {
2065 case 'video':
2066 this.metas.push(meta);
2067 this.m4mof._videoMeta = meta;
2068 if (this.hasVideo && !this.hasAudio) {
2069 this.metaSucc();
2070 return;
2071 }
2072 break;
2073 case 'audio':
2074 this.metas.push(meta);
2075 this.m4mof._audioMeta = meta;
2076 if (!this.hasVideo && this.hasAudio) {
2077 this.metaSucc();
2078 return;
2079 }
2080 break;
2081 }
2082 if (this.hasVideo && this.hasAudio && this.metaSuccRun && this.metas.length > 1) {
2083 this.metaSucc();
2084 }
2085 }
2086
2087 /**
2088 * metadata解读成功后触发及第一个视频tag和第一个音频tag
2089 *
2090 * @param {any} mi
2091 * @returns
2092 *
2093 * @memberof flv2fmp4
2094 */
2095
2096 }, {
2097 key: 'metaSucc',
2098 value: function metaSucc(mi) {
2099 if (this.onMediaInfo) {
2100 this.onMediaInfo(mi, { hasAudio: this.hasAudio, hasVideo: this.hasVideo });
2101 }
2102 // 获取ftyp和moov
2103 if (this.metas.length == 0) {
2104 this.metaSuccRun = true;
2105 return;
2106 }
2107
2108 this.ftyp_moov = _mp4remux2.default.generateInitSegment(this.metas);
2109 if (this.onInitSegment && this.loadmetadata == false) {
2110
2111 this.onInitSegment(this.ftyp_moov);
2112 this.loadmetadata = true;
2113 }
2114 }
2115 }, {
2116 key: 'onDataAvailable',
2117 value: function onDataAvailable(audiotrack, videotrack) {
2118 try {
2119 this.m4mof.remux(audiotrack, videotrack);
2120 } catch (e) {
2121 this.error(e);
2122 }
2123 }
2124
2125 /**
2126 * 传入flv的二进制数据
2127 * 统一入口
2128 * @param {any} arraybuff
2129 * @param {any} baseTime flv数据开始时间
2130 * @returns
2131 *
2132 * @memberof flv2fmp4
2133 */
2134
2135 }, {
2136 key: 'setflv',
2137 value: function setflv(arraybuff, baseTime) {
2138 return this.setflvBase(arraybuff, baseTime);
2139 }
2140
2141 /**
2142 *
2143 * 本地调试代码,不用理会
2144 * @param {any} arraybuff
2145 * @returns
2146 *
2147 * @memberof flv2fmp4
2148 */
2149
2150 }, {
2151 key: 'setflvloc',
2152 value: function setflvloc(arraybuff) {
2153 var offset = _flvParse2.default.setFlv(new Uint8Array(arraybuff));
2154
2155 if (_flvParse2.default.arrTag.length > 0) {
2156 return _flvParse2.default.arrTag;
2157 }
2158 }
2159
2160 /**
2161 *
2162 * 异常抛出处理
2163 * @param {any} e
2164 * @memberof flv2fmp4
2165 */
2166
2167 }, {
2168 key: 'error',
2169 value: function error(e) {
2170 if (this._error) {
2171 this._error(e);
2172 }
2173 }
2174 }]);
2175
2176 return flv2fmp4;
2177}();
2178
2179/**
2180 * 封装的对外类,有些方法不想对外暴露,所以封装这么一个类
2181 *
2182 * @class foreign
2183 */
2184
2185
2186var foreign = function (_CustEvent) {
2187 _inherits(foreign, _CustEvent);
2188
2189 function foreign(config) {
2190 _classCallCheck(this, foreign);
2191
2192 var _this = _possibleConstructorReturn(this, (foreign.__proto__ || Object.getPrototypeOf(foreign)).call(this));
2193
2194 _this.f2m = new flv2fmp4(config);
2195 _this.f2m._error = _this.error;
2196 // 外部方法赋值
2197 _this._onInitSegment = null;
2198 _this._onMediaSegment = null;
2199 _this._onMediaInfo = null;
2200 _this._seekCallBack = null;
2201 return _this;
2202 }
2203
2204 _createClass(foreign, [{
2205 key: 'error',
2206 value: function error(e) {
2207 this.emit('error', e.type);
2208 }
2209 /**
2210 *
2211 * 跳转
2212 * @param {any} basetime 跳转时间
2213 *
2214 * @memberof foreign
2215 */
2216
2217 }, {
2218 key: 'seek',
2219 value: function seek(basetime) {
2220 this.f2m.seek(basetime);
2221 }
2222
2223 /**
2224 * 传入flv的二进制数据
2225 * 统一入口
2226 * @param {any} arraybuff
2227 * @returns
2228 *
2229 * @memberof flv2fmp4
2230 */
2231
2232 }, {
2233 key: 'setflv',
2234 value: function setflv(arraybuff) {
2235 return this.f2m.setflv(arraybuff, 0);
2236 }
2237
2238 /**
2239 *
2240 * 本地调试代码,不用理会
2241 * @param {any} arraybuff
2242 * @returns
2243 *
2244 * @memberof flv2fmp4
2245 */
2246
2247 }, {
2248 key: 'setflvloc',
2249 value: function setflvloc(arraybuff) {
2250 return this.f2m.setflvloc(arraybuff);
2251 }
2252
2253 /**
2254 * 赋值初始化seg接受方法
2255 *
2256 *
2257 * @memberof foreign
2258 */
2259
2260 }, {
2261 key: 'onInitSegment',
2262 set: function set(fun) {
2263 this._onInitSegment = fun;
2264 this.f2m.onInitSegment = fun;
2265 }
2266
2267 /**
2268 * 赋值moof接受方法
2269 *
2270 *
2271 * @memberof foreign
2272 */
2273
2274 }, {
2275 key: 'onMediaSegment',
2276 set: function set(fun) {
2277 this._onMediaSegment = fun;
2278 this.f2m.onMediaSegment = fun;
2279 }
2280
2281 /**
2282 * 赋值metadata接受方法
2283 *
2284 *
2285 * @memberof foreign
2286 */
2287
2288 }, {
2289 key: 'onMediaInfo',
2290 set: function set(fun) {
2291 this._onMediaInfo = fun;
2292 this.f2m.onMediaInfo = fun;
2293 }
2294
2295 /**
2296 * 赋值是否跳转回调接受方法
2297 *
2298 *
2299 * @memberof foreign
2300 */
2301
2302 }, {
2303 key: 'seekCallBack',
2304 set: function set(fun) {
2305 this._seekCallBack = fun;
2306 this.f2m.seekCallBack = fun;
2307 }
2308 }]);
2309
2310 return foreign;
2311}(_chimeeHelper.CustEvent);
2312
2313exports.default = foreign;
2314
2315/***/ }),
2316/* 5 */
2317/***/ (function(module, exports, __webpack_require__) {
2318
2319"use strict";
2320
2321
2322Object.defineProperty(exports, "__esModule", {
2323 value: true
2324});
2325
2326var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* eslint-disable */
2327
2328
2329var _flvTag = __webpack_require__(6);
2330
2331var _flvTag2 = _interopRequireDefault(_flvTag);
2332
2333var _tagdemux = __webpack_require__(1);
2334
2335var _tagdemux2 = _interopRequireDefault(_tagdemux);
2336
2337var _error = __webpack_require__(0);
2338
2339var _error2 = _interopRequireDefault(_error);
2340
2341function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2342
2343function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2344
2345var FlvParse = function () {
2346 function FlvParse() {
2347 _classCallCheck(this, FlvParse);
2348
2349 this.tempUint8 = new Uint8Array();
2350 this.arrTag = [];
2351 this.index = 0;
2352 this.tempArr = [];
2353 this.stop = false;
2354 this.offset = 0;
2355 this.frist = true;
2356 this._hasAudio = false;
2357 this._hasVideo = false;
2358 }
2359
2360 /**
2361 * 接受 外部的flv二进制数据
2362 */
2363
2364
2365 _createClass(FlvParse, [{
2366 key: 'setFlv',
2367 value: function setFlv(uint8) {
2368 this.stop = false;
2369 this.arrTag = [];
2370 this.index = 0;
2371 this.tempUint8 = uint8;
2372 if (this.tempUint8.length > 13 && this.tempUint8[0] == 70 && this.tempUint8[1] == 76 && this.tempUint8[2] == 86) {
2373 this.probe(this.tempUint8.buffer);
2374 this.read(9); // 略掉9个字节的flv header tag
2375 this.read(4); // 略掉第一个4字节的 tag size
2376 this.parse();
2377 this.frist = false;
2378 return this.offset;
2379 } else if (!this.frist) {
2380 return this.parse();
2381 } else {
2382 return this.offset;
2383 }
2384 }
2385 }, {
2386 key: 'probe',
2387 value: function probe(buffer) {
2388 var data = new Uint8Array(buffer);
2389 var mismatch = { match: false };
2390
2391 if (data[0] !== 0x46 || data[1] !== 0x4C || data[2] !== 0x56 || data[3] !== 0x01) {
2392 return mismatch;
2393 }
2394
2395 var hasAudio = (data[4] & 4) >>> 2 !== 0;
2396 var hasVideo = (data[4] & 1) !== 0;
2397
2398 if (!hasAudio && !hasVideo) {
2399 return mismatch;
2400 }
2401 this._hasAudio = _tagdemux2.default._hasAudio = hasAudio;
2402 this._hasVideo = _tagdemux2.default._hasVideo = hasVideo;
2403 return {
2404 match: true,
2405 hasAudioTrack: hasAudio,
2406 hasVideoTrack: hasVideo
2407 };
2408 }
2409
2410 /**
2411 * 开始解析
2412 */
2413
2414 }, {
2415 key: 'parse',
2416 value: function parse() {
2417
2418 while (this.index < this.tempUint8.length && !this.stop) {
2419 this.offset = this.index;
2420
2421 var t = new _flvTag2.default();
2422 if (this.tempUint8.length - this.index >= 11) {
2423 t.tagType = this.read(1)[0]; // 取出tag类型
2424 t.dataSize = this.read(3); // 取出包体大小
2425 t.Timestamp = this.read(4); // 取出解码时间
2426 t.StreamID = this.read(3); // 取出stream id
2427 } else {
2428 this.stop = true;
2429 continue;
2430 }
2431 if (t.tagType == 18 || t.tagType == 8 || t.tagType == 9) {} else {
2432 throw new _error2.default('wrong tagType' + t.tagType);
2433 }
2434 if (this.tempUint8.length - this.index >= this.getBodySum(t.dataSize) + 4) {
2435 t.body = this.read(this.getBodySum(t.dataSize)); // 取出body
2436 if (t.tagType == 9 && this._hasVideo) {
2437 this.arrTag.push(t);
2438 }
2439 if (t.tagType == 8 && this._hasAudio) {
2440 this.arrTag.push(t);
2441 }
2442 if (t.tagType == 18) {
2443 this.arrTag.push(t);
2444 }
2445 this.read(4);
2446 } else {
2447 this.stop = true;
2448 continue;
2449 }
2450 this.offset = this.index;
2451 }
2452
2453 return this.offset;
2454 }
2455 }, {
2456 key: 'read',
2457 value: function read(length) {
2458 // let u8a = new Uint8Array(length);
2459 // u8a.set(this.tempUint8.subarray(this.index, this.index + length), 0);
2460 var u8a = this.tempUint8.slice(this.index, this.index + length);
2461 this.index += length;
2462 return u8a;
2463 }
2464
2465 /**
2466 * 计算tag包体大小
2467 */
2468
2469 }, {
2470 key: 'getBodySum',
2471 value: function getBodySum(arr) {
2472 var _str = '';
2473 _str += arr[0].toString(16).length == 1 ? '0' + arr[0].toString(16) : arr[0].toString(16);
2474 _str += arr[1].toString(16).length == 1 ? '0' + arr[1].toString(16) : arr[1].toString(16);
2475 _str += arr[2].toString(16).length == 1 ? '0' + arr[2].toString(16) : arr[2].toString(16);
2476 return parseInt(_str, 16);
2477 }
2478 }]);
2479
2480 return FlvParse;
2481}();
2482
2483exports.default = new FlvParse();
2484
2485/***/ }),
2486/* 6 */
2487/***/ (function(module, exports, __webpack_require__) {
2488
2489"use strict";
2490
2491
2492Object.defineProperty(exports, "__esModule", {
2493 value: true
2494});
2495
2496var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
2497
2498function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2499
2500/* eslint-disable */
2501var FlvTag = function () {
2502 function FlvTag() {
2503 _classCallCheck(this, FlvTag);
2504
2505 this.tagType = -1;
2506 this.dataSize = -1;
2507 this.Timestamp = -1;
2508 this.StreamID = -1;
2509 this.body = -1;
2510 this.time = -1;
2511 this.arr = [];
2512 }
2513
2514 _createClass(FlvTag, [{
2515 key: 'getTime',
2516 value: function getTime() {
2517 // this.Timestamp.pop();
2518 this.arr = [];
2519 for (var i = 0; i < this.Timestamp.length; i++) {
2520 this.arr.push(this.Timestamp[i].toString(16).length == 1 ? '0' + this.Timestamp[i].toString(16) : this.Timestamp[i].toString(16));
2521 }
2522 this.arr.pop();
2523 var time = this.arr.join('');
2524 this.time = parseInt(time, 16);
2525 return parseInt(time, 16);
2526 }
2527 }]);
2528
2529 return FlvTag;
2530}();
2531
2532exports.default = FlvTag;
2533
2534/***/ }),
2535/* 7 */
2536/***/ (function(module, exports, __webpack_require__) {
2537
2538"use strict";
2539
2540
2541Object.defineProperty(exports, "__esModule", {
2542 value: true
2543});
2544
2545var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* eslint-disable */
2546
2547
2548var _decodeUTF = __webpack_require__(8);
2549
2550var _decodeUTF2 = _interopRequireDefault(_decodeUTF);
2551
2552var _spsParser = __webpack_require__(2);
2553
2554var _spsParser2 = _interopRequireDefault(_spsParser);
2555
2556function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2557
2558function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2559
2560var le = function () {
2561 var buf = new ArrayBuffer(2);
2562 new DataView(buf).setInt16(0, 256, true); // little-endian write
2563 return new Int16Array(buf)[0] === 256; // platform-spec read, if equal then LE
2564}();
2565
2566var flvDemux = function () {
2567 function flvDemux() {
2568 _classCallCheck(this, flvDemux);
2569 }
2570
2571 _createClass(flvDemux, null, [{
2572 key: 'parseObject',
2573 value: function parseObject(arrayBuffer, dataOffset, dataSize) {
2574
2575 var name = flvDemux.parseString(arrayBuffer, dataOffset, dataSize);
2576 var value = flvDemux.parseScript(arrayBuffer, dataOffset + name.size);
2577 var isObjectEnd = value.objectEnd;
2578
2579 return {
2580 data: {
2581 name: name.data,
2582 value: value.data
2583 },
2584 size: value.size,
2585 objectEnd: isObjectEnd
2586 };
2587 }
2588 }, {
2589 key: 'parseVariable',
2590 value: function parseVariable(arrayBuffer, dataOffset, dataSize) {
2591 return flvDemux.parseObject(arrayBuffer, dataOffset, dataSize);
2592 }
2593 }, {
2594 key: 'parseLongString',
2595 value: function parseLongString(arrayBuffer, dataOffset, dataSize) {
2596
2597 var v = new DataView(arrayBuffer, dataOffset);
2598 var length = v.getUint32(0, !le);
2599
2600 var str = void 0;
2601 if (length > 0) {
2602 str = (0, _decodeUTF2.default)(new Uint8Array(arrayBuffer, dataOffset + 4, length));
2603 } else {
2604 str = '';
2605 }
2606
2607 return {
2608 data: str,
2609 size: 4 + length
2610 };
2611 }
2612 }, {
2613 key: 'parseDate',
2614 value: function parseDate(arrayBuffer, dataOffset, dataSize) {
2615
2616 var v = new DataView(arrayBuffer, dataOffset);
2617 var timestamp = v.getFloat64(0, !le);
2618 var localTimeOffset = v.getInt16(8, !le);
2619 timestamp += localTimeOffset * 60 * 1000; // get UTC time
2620
2621 return {
2622 data: new Date(timestamp),
2623 size: 8 + 2
2624 };
2625 }
2626 }, {
2627 key: 'parseString',
2628 value: function parseString(arrayBuffer, dataOffset, dataSize) {
2629 var v = new DataView(arrayBuffer, dataOffset);
2630 var length = v.getUint16(0, !le);
2631 var str = void 0;
2632 if (length > 0) {
2633 str = (0, _decodeUTF2.default)(new Uint8Array(arrayBuffer, dataOffset + 2, length));
2634 } else {
2635 str = '';
2636 }
2637 return {
2638 data: str,
2639 size: 2 + length
2640 };
2641 }
2642
2643 /**
2644 * 解析metadata
2645 */
2646
2647 }, {
2648 key: 'parseMetadata',
2649 value: function parseMetadata(arr) {
2650 var name = flvDemux.parseScript(arr, 0);
2651 var value = flvDemux.parseScript(arr, name.size, arr.length - name.size);
2652 // return {}
2653 var data = {};
2654 data[name.data] = value.data;
2655 return data;
2656 }
2657 }, {
2658 key: 'parseScript',
2659 value: function parseScript(arr, offset, dataSize) {
2660 var dataOffset = offset;
2661 var object = {};
2662 var uint8 = new Uint8Array(arr);
2663 var buffer = uint8.buffer;
2664 var dv = new DataView(buffer, 0, dataSize);
2665 var value = null;
2666 var objectEnd = false;
2667 var type = dv.getUint8(dataOffset);
2668 dataOffset += 1;
2669
2670 switch (type) {
2671 case 0:
2672 // Number(Double) type
2673 value = dv.getFloat64(dataOffset, !le);
2674 dataOffset += 8;
2675 break;
2676 case 1:
2677 {
2678 // Boolean type
2679 var b = dv.getUint8(dataOffset);
2680 value = !!b;
2681 dataOffset += 1;
2682 break;
2683 }
2684 case 2:
2685 {
2686 // String type
2687 // dataOffset += 1;
2688 var amfstr = flvDemux.parseString(buffer, dataOffset);
2689 value = amfstr.data;
2690 dataOffset += amfstr.size;
2691 break;
2692 }
2693 case 3:
2694
2695 {
2696 // Object(s) type
2697 value = {};
2698 var terminal = 0; // workaround for malformed Objects which has missing ScriptDataObjectEnd
2699 if ((dv.getUint32(dataSize - 4, !le) & 0x00FFFFFF) === 9) {
2700 terminal = 3;
2701 }
2702 while (dataOffset < dataSize - 4) {
2703 // 4 === type(UI8) + ScriptDataObjectEnd(UI24)
2704 var amfobj = flvDemux.parseObject(buffer, dataOffset, dataSize - offset - terminal);
2705
2706 if (amfobj.objectEnd) {
2707 break;
2708 }
2709 value[amfobj.data.name] = amfobj.data.value;
2710 // dataOffset += amfobj.size;
2711 dataOffset = amfobj.size;
2712 }
2713 if (dataOffset <= dataSize - 3) {
2714 var marker = v.getUint32(dataOffset - 1, !le) & 0x00FFFFFF;
2715 if (marker === 9) {
2716 dataOffset += 3;
2717 }
2718 }
2719 break;
2720 }
2721 case 8:
2722 {
2723 // ECMA array type (Mixed array)
2724 value = {};
2725 // dataOffset += 1;
2726 dataOffset += 4; // ECMAArrayLength(UI32)
2727 var _terminal = 0; // workaround for malformed MixedArrays which has missing ScriptDataObjectEnd
2728 if ((dv.getUint32(dataSize - 4, !le) & 0x00FFFFFF) === 9) {
2729 _terminal = 3;
2730 }
2731 while (dataOffset < dataSize - 8) {
2732 // 8 === type(UI8) + ECMAArrayLength(UI32) + ScriptDataVariableEnd(UI24)
2733 var amfvar = flvDemux.parseVariable(buffer, dataOffset);
2734
2735 if (amfvar.objectEnd) {
2736 break;
2737 }
2738 value[amfvar.data.name] = amfvar.data.value;
2739 dataOffset = amfvar.size;
2740 }
2741 if (dataOffset <= dataSize - 3) {
2742 var _marker = dv.getUint32(dataOffset - 1, !le) & 0x00FFFFFF;
2743 if (_marker === 9) {
2744 dataOffset += 3;
2745 }
2746 }
2747 break;
2748 }
2749 case 9:
2750 // ScriptDataObjectEnd
2751 value = undefined;
2752 dataOffset = 1;
2753 objectEnd = true;
2754 break;
2755 case 10:
2756 {
2757 // Strict array type
2758 // ScriptDataValue[n]. NOTE: according to video_file_format_spec_v10_1.pdf
2759 value = [];
2760 var strictArrayLength = dv.getUint32(dataOffset, !le);
2761 dataOffset += 4;
2762 for (var i = 0; i < strictArrayLength; i++) {
2763 var val = flvDemux.parseScript(buffer, dataOffset);
2764 value.push(val.data);
2765 dataOffset = val.size;
2766 }
2767 break;
2768 }
2769 case 11:
2770 {
2771 // Date type
2772 var date = flvDemux.parseDate(buffer, dataOffset + 1, dataSize - 1);
2773 value = date.data;
2774 dataOffset += date.size;
2775 break;
2776 }
2777 case 12:
2778 {
2779 // Long string type
2780 var amfLongStr = flvDemux.parseString(buffer, dataOffset + 1, dataSize - 1);
2781 value = amfLongStr.data;
2782 dataOffset += amfLongStr.size;
2783 break;
2784 }
2785 default:
2786 // ignore and skip
2787 dataOffset = dataSize;
2788 console.log('AMF', 'Unsupported AMF value type ' + type);
2789 }
2790 return {
2791 data: value,
2792 size: dataOffset
2793 };
2794 }
2795 }]);
2796
2797 return flvDemux;
2798}();
2799
2800exports.default = flvDemux;
2801
2802/***/ }),
2803/* 8 */
2804/***/ (function(module, exports, __webpack_require__) {
2805
2806"use strict";
2807
2808
2809Object.defineProperty(exports, "__esModule", {
2810 value: true
2811});
2812/* eslint-disable */
2813function decodeUTF8(uint8array) {
2814 var out = [];
2815 var input = uint8array;
2816 var i = 0;
2817 var length = uint8array.length;
2818
2819 while (i < length) {
2820 if (input[i] < 0x80) {
2821 out.push(String.fromCharCode(input[i]));
2822 ++i;
2823 continue;
2824 } else if (input[i] < 0xC0) {
2825 // fallthrough
2826 } else if (input[i] < 0xE0) {
2827 if (checkContinuation(input, i, 1)) {
2828 var ucs4 = (input[i] & 0x1F) << 6 | input[i + 1] & 0x3F;
2829 if (ucs4 >= 0x80) {
2830 out.push(String.fromCharCode(ucs4 & 0xFFFF));
2831 i += 2;
2832 continue;
2833 }
2834 }
2835 } else if (input[i] < 0xF0) {
2836 if (checkContinuation(input, i, 2)) {
2837 var _ucs = (input[i] & 0xF) << 12 | (input[i + 1] & 0x3F) << 6 | input[i + 2] & 0x3F;
2838 if (_ucs >= 0x800 && (_ucs & 0xF800) !== 0xD800) {
2839 out.push(String.fromCharCode(_ucs & 0xFFFF));
2840 i += 3;
2841 continue;
2842 }
2843 }
2844 } else if (input[i] < 0xF8) {
2845 if (checkContinuation(input, i, 3)) {
2846 var _ucs2 = (input[i] & 0x7) << 18 | (input[i + 1] & 0x3F) << 12 | (input[i + 2] & 0x3F) << 6 | input[i + 3] & 0x3F;
2847 if (_ucs2 > 0x10000 && _ucs2 < 0x110000) {
2848 _ucs2 -= 0x10000;
2849 out.push(String.fromCharCode(_ucs2 >>> 10 | 0xD800));
2850 out.push(String.fromCharCode(_ucs2 & 0x3FF | 0xDC00));
2851 i += 4;
2852 continue;
2853 }
2854 }
2855 }
2856 out.push(String.fromCharCode(0xFFFD));
2857 ++i;
2858 }
2859
2860 return out.join('');
2861}
2862
2863function checkContinuation(uint8array, start, checkLength) {
2864 var array = uint8array;
2865 if (start + checkLength < array.length) {
2866 while (checkLength--) {
2867 if ((array[++start] & 0xC0) !== 0x80) return false;
2868 }
2869 return true;
2870 } else {
2871 return false;
2872 }
2873}
2874exports.default = decodeUTF8;
2875
2876/***/ }),
2877/* 9 */
2878/***/ (function(module, exports, __webpack_require__) {
2879
2880"use strict";
2881
2882
2883Object.defineProperty(exports, "__esModule", {
2884 value: true
2885});
2886
2887var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
2888
2889function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2890
2891/**
2892 * reference flv.js
2893 */
2894/* eslint-disable */
2895// Exponential-Golomb buffer decoder
2896var ExpGolomb = function () {
2897 function ExpGolomb(uint8array) {
2898 _classCallCheck(this, ExpGolomb);
2899
2900 this.TAG = this.constructor.name;
2901
2902 this._buffer = uint8array;
2903 this._buffer_index = 0;
2904 this._total_bytes = uint8array.byteLength;
2905 this._total_bits = uint8array.byteLength * 8;
2906 this._current_word = 0;
2907 this._current_word_bits_left = 0;
2908 }
2909
2910 _createClass(ExpGolomb, [{
2911 key: 'destroy',
2912 value: function destroy() {
2913 this._buffer = null;
2914 }
2915 }, {
2916 key: '_fillCurrentWord',
2917 value: function _fillCurrentWord() {
2918 var buffer_bytes_left = this._total_bytes - this._buffer_index;
2919 if (buffer_bytes_left <= 0) {
2920 throw new IllegalStateException('ExpGolomb: _fillCurrentWord() but no bytes available');
2921 }
2922
2923 var bytes_read = Math.min(4, buffer_bytes_left);
2924 var word = new Uint8Array(4);
2925 word.set(this._buffer.subarray(this._buffer_index, this._buffer_index + bytes_read));
2926 this._current_word = new DataView(word.buffer).getUint32(0, false);
2927
2928 this._buffer_index += bytes_read;
2929 this._current_word_bits_left = bytes_read * 8;
2930 }
2931 }, {
2932 key: 'readBits',
2933 value: function readBits(bits) {
2934 if (bits > 32) {
2935 throw new InvalidArgumentException('ExpGolomb: readBits() bits exceeded max 32bits!');
2936 }
2937
2938 if (bits <= this._current_word_bits_left) {
2939 var _result = this._current_word >>> 32 - bits;
2940 this._current_word <<= bits;
2941 this._current_word_bits_left -= bits;
2942 return _result;
2943 }
2944
2945 var result = this._current_word_bits_left ? this._current_word : 0;
2946 result = result >>> 32 - this._current_word_bits_left;
2947 var bits_need_left = bits - this._current_word_bits_left;
2948
2949 this._fillCurrentWord();
2950 var bits_read_next = Math.min(bits_need_left, this._current_word_bits_left);
2951
2952 var result2 = this._current_word >>> 32 - bits_read_next;
2953 this._current_word <<= bits_read_next;
2954 this._current_word_bits_left -= bits_read_next;
2955
2956 result = result << bits_read_next | result2;
2957 return result;
2958 }
2959 }, {
2960 key: 'readBool',
2961 value: function readBool() {
2962 return this.readBits(1) === 1;
2963 }
2964 }, {
2965 key: 'readByte',
2966 value: function readByte() {
2967 return this.readBits(8);
2968 }
2969 }, {
2970 key: '_skipLeadingZero',
2971 value: function _skipLeadingZero() {
2972 var zero_count = void 0;
2973 for (zero_count = 0; zero_count < this._current_word_bits_left; zero_count++) {
2974 if ((this._current_word & 0x80000000 >>> zero_count) !== 0) {
2975 this._current_word <<= zero_count;
2976 this._current_word_bits_left -= zero_count;
2977 return zero_count;
2978 }
2979 }
2980 this._fillCurrentWord();
2981 return zero_count + this._skipLeadingZero();
2982 }
2983 }, {
2984 key: 'readUEG',
2985 value: function readUEG() {
2986 // unsigned exponential golomb
2987 var leading_zeros = this._skipLeadingZero();
2988 return this.readBits(leading_zeros + 1) - 1;
2989 }
2990 }, {
2991 key: 'readSEG',
2992 value: function readSEG() {
2993 // signed exponential golomb
2994 var value = this.readUEG();
2995 if (value & 0x01) {
2996 return value + 1 >>> 1;
2997 } else {
2998 return -1 * (value >>> 1);
2999 }
3000 }
3001 }]);
3002
3003 return ExpGolomb;
3004}();
3005
3006exports.default = ExpGolomb;
3007
3008/***/ }),
3009/* 10 */
3010/***/ (function(module, exports, __webpack_require__) {
3011
3012"use strict";
3013
3014
3015Object.defineProperty(exports, "__esModule", {
3016 value: true
3017});
3018
3019var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
3020
3021function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3022
3023/**
3024 * reference flv.js
3025 */
3026/* eslint-disable */
3027var MediaInfo = function () {
3028 function MediaInfo() {
3029 _classCallCheck(this, MediaInfo);
3030
3031 this.mimeType = null;
3032 this.duration = null;
3033
3034 this.hasAudio = null;
3035 this.hasVideo = null;
3036 this.audioCodec = null;
3037 this.videoCodec = null;
3038 this.audioDataRate = null;
3039 this.videoDataRate = null;
3040
3041 this.audioSampleRate = null;
3042 this.audioChannelCount = null;
3043
3044 this.width = null;
3045 this.height = null;
3046 this.fps = null;
3047 this.profile = null;
3048 this.level = null;
3049 this.chromaFormat = null;
3050 this.sarNum = null;
3051 this.sarDen = null;
3052
3053 this.metadata = null;
3054 this.segments = null; // MediaInfo[]
3055 this.segmentCount = null;
3056 this.hasKeyframesIndex = null;
3057 this.keyframesIndex = null;
3058 }
3059
3060 _createClass(MediaInfo, [{
3061 key: "isComplete",
3062 value: function isComplete() {
3063 var audioInfoComplete = this.hasAudio === false || this.hasAudio === true && this.audioCodec != null && this.audioSampleRate != null && this.audioChannelCount != null;
3064
3065 var videoInfoComplete = this.hasVideo === false || this.hasVideo === true && this.videoCodec != null && this.width != null && this.height != null && this.fps != null && this.profile != null && this.level != null && this.chromaFormat != null && this.sarNum != null && this.sarDen != null;
3066
3067 // keyframesIndex may not be present
3068 return this.mimeType != null && this.duration != null && this.metadata != null && this.hasKeyframesIndex != null && audioInfoComplete && videoInfoComplete;
3069 }
3070 }, {
3071 key: "isSeekable",
3072 value: function isSeekable() {
3073 return this.hasKeyframesIndex === true;
3074 }
3075 }]);
3076
3077 return MediaInfo;
3078}();
3079
3080exports.default = MediaInfo;
3081
3082/***/ }),
3083/* 11 */
3084/***/ (function(module, exports, __webpack_require__) {
3085
3086"use strict";
3087
3088
3089Object.defineProperty(exports, "__esModule", {
3090 value: true
3091});
3092
3093var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
3094 * reference flv.js
3095 */
3096/* eslint-disable */
3097
3098
3099var _aacSilent = __webpack_require__(12);
3100
3101var _aacSilent2 = _interopRequireDefault(_aacSilent);
3102
3103var _browser = __webpack_require__(13);
3104
3105var _browser2 = _interopRequireDefault(_browser);
3106
3107var _mp4remux = __webpack_require__(3);
3108
3109var _mp4remux2 = _interopRequireDefault(_mp4remux);
3110
3111var _mediaSegmentInfo = __webpack_require__(14);
3112
3113var _error = __webpack_require__(0);
3114
3115var _error2 = _interopRequireDefault(_error);
3116
3117function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
3118
3119function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3120
3121// Fragmented mp4 remuxer
3122var MP4Remuxer = function () {
3123 function MP4Remuxer(config) {
3124 _classCallCheck(this, MP4Remuxer);
3125
3126 this.TAG = this.constructor.name;
3127
3128 this._config = config;
3129 this._isLive = config.isLive === true;
3130
3131 this._dtsBase = -1;
3132 this._dtsBaseInited = false;
3133 this._audioDtsBase = Infinity;
3134 this._videoDtsBase = Infinity;
3135 this._audioNextDts = undefined;
3136 this._videoNextDts = undefined;
3137
3138 this._audioMeta = null;
3139 this._videoMeta = null;
3140
3141 this._audioSegmentInfoList = new _mediaSegmentInfo.MediaSegmentInfoList('audio');
3142 this._videoSegmentInfoList = new _mediaSegmentInfo.MediaSegmentInfoList('video');
3143
3144 this._onInitSegment = null;
3145 this._onMediaSegment = null;
3146
3147 // Workaround for chrome < 50: Always force first sample as a Random Access Point in media segment
3148 // see https://bugs.chromium.org/p/chromium/issues/detail?id=229412
3149 this._forceFirstIDR = !!(_browser2.default.chrome && (_browser2.default.version.major < 50 || _browser2.default.version.major === 50 && _browser2.default.version.build < 2661));
3150
3151 // Workaround for IE11/Edge: Fill silent aac frame after keyframe-seeking
3152 // Make audio beginDts equals with video beginDts, in order to fix seek freeze
3153 this._fillSilentAfterSeek = _browser2.default.msedge || _browser2.default.msie;
3154 }
3155
3156 _createClass(MP4Remuxer, [{
3157 key: 'destroy',
3158 value: function destroy() {
3159 this._dtsBase = -1;
3160 this._dtsBaseInited = false;
3161 this._audioMeta = null;
3162 this._videoMeta = null;
3163 this._audioSegmentInfoList.clear();
3164 this._audioSegmentInfoList = null;
3165 this._videoSegmentInfoList.clear();
3166 this._videoSegmentInfoList = null;
3167 this._onInitSegment = null;
3168 this._onMediaSegment = null;
3169 }
3170 }, {
3171 key: 'bindDataSource',
3172 value: function bindDataSource(producer) {
3173 producer.onDataAvailable = this.remux.bind(this);
3174 producer.onTrackMetadata = this._onTrackMetadataReceived.bind(this);
3175 return this;
3176 }
3177
3178 /* prototype: function onInitSegment(type: string, initSegment: ArrayBuffer): void
3179 InitSegment: {
3180 type: string,
3181 data: ArrayBuffer,
3182 codec: string,
3183 container: string
3184 }
3185 */
3186
3187 }, {
3188 key: 'insertDiscontinuity',
3189 value: function insertDiscontinuity() {
3190 this._audioNextDts = this._videoNextDts = undefined;
3191 }
3192 }, {
3193 key: 'seek',
3194 value: function seek(originalDts) {
3195 this._videoSegmentInfoList.clear();
3196 this._audioSegmentInfoList.clear();
3197 }
3198 }, {
3199 key: 'remux',
3200 value: function remux(audioTrack, videoTrack) {
3201 if (!this._onMediaSegment) {
3202 throw new _error2.default('MP4Remuxer: onMediaSegment callback must be specificed!');
3203 }
3204 if (!this._dtsBaseInited) {
3205 this._calculateDtsBase(audioTrack, videoTrack);
3206 }
3207 this._remuxVideo(videoTrack);
3208 this._remuxAudio(audioTrack);
3209 }
3210 }, {
3211 key: '_onTrackMetadataReceived',
3212 value: function _onTrackMetadataReceived(type, metadata) {
3213 var metabox = null;
3214
3215 if (type === 'audio') {
3216 this._audioMeta = metadata;
3217 metabox = _mp4remux2.default.generateInitSegment(metadata);
3218 console.log('msg+audio', metadata);
3219 } else if (type === 'video') {
3220 this._videoMeta = metadata;
3221 metabox = _mp4remux2.default.generateInitSegment(metadata);
3222 console.log('msg+video', metadata);
3223 } else {
3224 return;
3225 }
3226
3227 // dispatch metabox (Initialization Segment)
3228 if (!this._onInitSegment) {
3229 throw new _error2.default('MP4Remuxer: onInitSegment callback must be specified!');
3230 }
3231 this._onInitSegment(type, {
3232 type: type,
3233 data: metabox.buffer,
3234 codec: metadata.codec,
3235 container: type + '/mp4'
3236 });
3237 }
3238 }, {
3239 key: '_calculateDtsBase',
3240 value: function _calculateDtsBase(audioTrack, videoTrack) {
3241 if (this._dtsBaseInited) {
3242 return;
3243 }
3244
3245 if (audioTrack.samples && audioTrack.samples.length) {
3246 this._audioDtsBase = audioTrack.samples[0].dts;
3247 }
3248 if (videoTrack.samples && videoTrack.samples.length) {
3249 this._videoDtsBase = videoTrack.samples[0].dts;
3250 }
3251
3252 this._dtsBase = Math.min(this._audioDtsBase, this._videoDtsBase);
3253 this._dtsBaseInited = true;
3254 }
3255 }, {
3256 key: '_remuxAudio',
3257 value: function _remuxAudio(audioTrack) {
3258 var track = audioTrack;
3259 var samples = track.samples;
3260 var dtsCorrection = void 0;
3261 var firstDts = -1,
3262 lastDts = -1,
3263 lastPts = -1;
3264
3265 var remuxSilentFrame = false;
3266 var silentFrameDuration = -1;
3267
3268 if (!samples || samples.length === 0) {
3269 return;
3270 }
3271
3272 var bytes = 8 + track.length;
3273 var mdatbox = new Uint8Array(bytes);
3274 mdatbox[0] = bytes >>> 24 & 0xFF;
3275 mdatbox[1] = bytes >>> 16 & 0xFF;
3276 mdatbox[2] = bytes >>> 8 & 0xFF;
3277 mdatbox[3] = bytes & 0xFF;
3278
3279 mdatbox.set(_mp4remux2.default.types.mdat, 4);
3280
3281 var offset = 8; // size + type
3282 var mp4Samples = [];
3283
3284 while (samples.length) {
3285 var aacSample = samples.shift();
3286 var unit = aacSample.unit;
3287 var originalDts = aacSample.dts - this._dtsBase;
3288
3289 if (dtsCorrection == undefined) {
3290 if (this._audioNextDts == undefined) {
3291 if (this._audioSegmentInfoList.isEmpty()) {
3292 dtsCorrection = 0;
3293 if (this._fillSilentAfterSeek && !this._videoSegmentInfoList.isEmpty()) {
3294 remuxSilentFrame = true;
3295 }
3296 } else {
3297 var lastSample = this._audioSegmentInfoList.getLastSampleBefore(originalDts);
3298 if (lastSample != null) {
3299 var distance = originalDts - (lastSample.originalDts + lastSample.duration);
3300 if (distance <= 3) {
3301 distance = 0;
3302 }
3303 var expectedDts = lastSample.dts + lastSample.duration + distance;
3304 dtsCorrection = originalDts - expectedDts;
3305 } else {
3306 // lastSample == null
3307 dtsCorrection = 0;
3308 }
3309 }
3310 } else {
3311 dtsCorrection = originalDts - this._audioNextDts;
3312 }
3313 }
3314
3315 var dts = originalDts - dtsCorrection;
3316 if (remuxSilentFrame) {
3317 // align audio segment beginDts to match with current video segment's beginDts
3318 var videoSegment = this._videoSegmentInfoList.getLastSegmentBefore(originalDts);
3319 if (videoSegment != null && videoSegment.beginDts < dts) {
3320 silentFrameDuration = dts - videoSegment.beginDts;
3321 dts = videoSegment.beginDts;
3322 } else {
3323 remuxSilentFrame = false;
3324 }
3325 }
3326 if (firstDts === -1) {
3327 firstDts = dts;
3328 }
3329
3330 if (remuxSilentFrame) {
3331 remuxSilentFrame = false;
3332 samples.unshift(aacSample);
3333
3334 var frame = this._generateSilentAudio(dts, silentFrameDuration);
3335 if (frame == null) {
3336 continue;
3337 }
3338 var _mp4Sample = frame.mp4Sample;
3339 var _unit = frame.unit;
3340
3341 mp4Samples.push(_mp4Sample);
3342
3343 // re-allocate mdatbox buffer with new size, to fit with this silent frame
3344 bytes += _unit.byteLength;
3345 mdatbox = new Uint8Array(bytes);
3346 mdatbox[0] = bytes >>> 24 & 0xFF;
3347 mdatbox[1] = bytes >>> 16 & 0xFF;
3348 mdatbox[2] = bytes >>> 8 & 0xFF;
3349 mdatbox[3] = bytes & 0xFF;
3350 mdatbox.set(_mp4remux2.default.types.mdat, 4);
3351
3352 // fill data now
3353 mdatbox.set(_unit, offset);
3354 offset += _unit.byteLength;
3355 continue;
3356 }
3357
3358 var sampleDuration = 0;
3359
3360 if (samples.length >= 1) {
3361 var nextDts = samples[0].dts - this._dtsBase - dtsCorrection;
3362 sampleDuration = nextDts - dts;
3363 } else {
3364 if (mp4Samples.length >= 1) {
3365 // use second last sample duration
3366 sampleDuration = mp4Samples[mp4Samples.length - 1].duration;
3367 } else {
3368 // the only one sample, use reference sample duration
3369 sampleDuration = this._audioMeta.refSampleDuration;
3370 }
3371 }
3372
3373 var mp4Sample = {
3374 dts: dts,
3375 pts: dts,
3376 cts: 0,
3377 size: unit.byteLength,
3378 duration: sampleDuration,
3379 originalDts: originalDts,
3380 flags: {
3381 isLeading: 0,
3382 dependsOn: 1,
3383 isDependedOn: 0,
3384 hasRedundancy: 0
3385 }
3386 };
3387 mp4Samples.push(mp4Sample);
3388 mdatbox.set(unit, offset);
3389 offset += unit.byteLength;
3390 }
3391 var latest = mp4Samples[mp4Samples.length - 1];
3392 lastDts = latest.dts + latest.duration;
3393 this._audioNextDts = lastDts;
3394
3395 // fill media segment info & add to info list
3396 var info = new _mediaSegmentInfo.MediaSegmentInfo();
3397 info.beginDts = firstDts;
3398 info.endDts = lastDts;
3399 info.beginPts = firstDts;
3400 info.endPts = lastDts;
3401 info.originalBeginDts = mp4Samples[0].originalDts;
3402 info.originalEndDts = latest.originalDts + latest.duration;
3403 info.firstSample = new _mediaSegmentInfo.SampleInfo(mp4Samples[0].dts, mp4Samples[0].pts, mp4Samples[0].duration, mp4Samples[0].originalDts, false);
3404 info.lastSample = new _mediaSegmentInfo.SampleInfo(latest.dts, latest.pts, latest.duration, latest.originalDts, false);
3405 if (!this._isLive) {
3406 this._audioSegmentInfoList.append(info);
3407 }
3408
3409 track.samples = mp4Samples;
3410 track.sequenceNumber += track.addcoefficient;
3411
3412 var moofbox = _mp4remux2.default.moof(track, firstDts);
3413 track.samples = [];
3414 track.length = 0;
3415
3416 this._onMediaSegment('audio', {
3417 type: 'audio',
3418 data: this._mergeBoxes(moofbox, mdatbox).buffer,
3419 sampleCount: mp4Samples.length,
3420 info: info
3421 });
3422 }
3423 }, {
3424 key: '_generateSilentAudio',
3425 value: function _generateSilentAudio(dts, frameDuration) {
3426 console.log(this.TAG, 'GenerateSilentAudio: dts = ' + dts + ', duration = ' + frameDuration);
3427
3428 var unit = _aacSilent2.default.getSilentFrame(this._audioMeta.channelCount);
3429 if (unit == null) {
3430 console.log(this.TAG, 'Cannot generate silent aac frame for channelCount = ' + this._audioMeta.channelCount);
3431 return null;
3432 }
3433
3434 var mp4Sample = {
3435 dts: dts,
3436 pts: dts,
3437 cts: 0,
3438 size: unit.byteLength,
3439 duration: frameDuration,
3440 originalDts: dts,
3441 flags: {
3442 isLeading: 0,
3443 dependsOn: 1,
3444 isDependedOn: 0,
3445 hasRedundancy: 0
3446 }
3447 };
3448
3449 return {
3450 unit: unit,
3451 mp4Sample: mp4Sample
3452 };
3453 }
3454 }, {
3455 key: '_remuxVideo',
3456 value: function _remuxVideo(videoTrack) {
3457 var track = videoTrack;
3458 var samples = track.samples;
3459 var dtsCorrection = void 0;
3460 var firstDts = -1,
3461 lastDts = -1;
3462 var firstPts = -1,
3463 lastPts = -1;
3464
3465 if (!samples || samples.length === 0) {
3466 return;
3467 }
3468
3469 var bytes = 8 + videoTrack.length;
3470 var mdatbox = new Uint8Array(bytes);
3471 mdatbox[0] = bytes >>> 24 & 0xFF;
3472 mdatbox[1] = bytes >>> 16 & 0xFF;
3473 mdatbox[2] = bytes >>> 8 & 0xFF;
3474 mdatbox[3] = bytes & 0xFF;
3475 mdatbox.set(_mp4remux2.default.types.mdat, 4);
3476
3477 var offset = 8;
3478 var mp4Samples = [];
3479 var info = new _mediaSegmentInfo.MediaSegmentInfo();
3480
3481 while (samples.length) {
3482 var avcSample = samples.shift();
3483 var keyframe = avcSample.isKeyframe;
3484 var originalDts = avcSample.dts - this._dtsBase;
3485
3486 if (dtsCorrection == undefined) {
3487 if (this._videoNextDts == undefined) {
3488 if (this._videoSegmentInfoList.isEmpty()) {
3489 dtsCorrection = 0;
3490 } else {
3491 var lastSample = this._videoSegmentInfoList.getLastSampleBefore(originalDts);
3492 if (lastSample != null) {
3493 var distance = originalDts - (lastSample.originalDts + lastSample.duration);
3494 if (distance <= 3) {
3495 distance = 0;
3496 }
3497 var expectedDts = lastSample.dts + lastSample.duration + distance;
3498 dtsCorrection = originalDts - expectedDts;
3499 } else {
3500 // lastSample == null
3501 dtsCorrection = 0;
3502 }
3503 }
3504 } else {
3505 dtsCorrection = originalDts - this._videoNextDts;
3506 }
3507 }
3508
3509 var dts = originalDts - dtsCorrection;
3510 var cts = avcSample.cts;
3511 var pts = dts + cts;
3512
3513 if (firstDts === -1) {
3514 firstDts = dts;
3515 firstPts = pts;
3516 }
3517
3518 // fill mdat box
3519 var sampleSize = 0;
3520 while (avcSample.units.length) {
3521 var unit = avcSample.units.shift();
3522 var data = unit.data;
3523 mdatbox.set(data, offset);
3524 offset += data.byteLength;
3525 sampleSize += data.byteLength;
3526 }
3527
3528 var sampleDuration = 0;
3529
3530 if (samples.length >= 1) {
3531 var nextDts = samples[0].dts - this._dtsBase - dtsCorrection;
3532 sampleDuration = nextDts - dts;
3533 } else {
3534 if (mp4Samples.length >= 1) {
3535 // lastest sample, use second last duration
3536 sampleDuration = mp4Samples[mp4Samples.length - 1].duration;
3537 } else {
3538 // the only one sample, use reference duration
3539 sampleDuration = this._videoMeta.refSampleDuration;
3540 }
3541 }
3542
3543 if (keyframe) {
3544 var syncPoint = new _mediaSegmentInfo.SampleInfo(dts, pts, sampleDuration, avcSample.dts, true);
3545 syncPoint.fileposition = avcSample.fileposition;
3546 info.appendSyncPoint(syncPoint);
3547 }
3548
3549 var mp4Sample = {
3550 dts: dts,
3551 pts: pts,
3552 cts: cts,
3553 size: sampleSize,
3554 isKeyframe: keyframe,
3555 duration: sampleDuration,
3556 originalDts: originalDts,
3557 flags: {
3558 isLeading: 0,
3559 dependsOn: keyframe ? 2 : 1,
3560 isDependedOn: keyframe ? 1 : 0,
3561 hasRedundancy: 0,
3562 isNonSync: keyframe ? 0 : 1
3563 }
3564 };
3565
3566 mp4Samples.push(mp4Sample);
3567 }
3568 var latest = mp4Samples[mp4Samples.length - 1];
3569 lastDts = latest.dts + latest.duration;
3570 lastPts = latest.pts + latest.duration;
3571 this._videoNextDts = lastDts;
3572
3573 // fill media segment info & add to info list
3574 info.beginDts = firstDts;
3575 info.endDts = lastDts;
3576 info.beginPts = firstPts;
3577 info.endPts = lastPts;
3578 info.originalBeginDts = mp4Samples[0].originalDts;
3579 info.originalEndDts = latest.originalDts + latest.duration;
3580 info.firstSample = new _mediaSegmentInfo.SampleInfo(mp4Samples[0].dts, mp4Samples[0].pts, mp4Samples[0].duration, mp4Samples[0].originalDts, mp4Samples[0].isKeyframe);
3581 info.lastSample = new _mediaSegmentInfo.SampleInfo(latest.dts, latest.pts, latest.duration, latest.originalDts, latest.isKeyframe);
3582 if (!this._isLive) {
3583 this._videoSegmentInfoList.append(info);
3584 }
3585
3586 track.samples = mp4Samples;
3587 track.sequenceNumber += track.addcoefficient;
3588
3589 // workaround for chrome < 50: force first sample as a random access point
3590 // see https://bugs.chromium.org/p/chromium/issues/detail?id=229412
3591 if (this._forceFirstIDR) {
3592 var flags = mp4Samples[0].flags;
3593 flags.dependsOn = 2;
3594 flags.isNonSync = 0;
3595 }
3596
3597 var moofbox = _mp4remux2.default.moof(track, firstDts);
3598 track.samples = [];
3599 track.length = 0;
3600
3601 this._onMediaSegment('video', {
3602 type: 'video',
3603 data: this._mergeBoxes(moofbox, mdatbox).buffer,
3604 sampleCount: mp4Samples.length,
3605 info: info
3606 });
3607 }
3608 }, {
3609 key: '_mergeBoxes',
3610 value: function _mergeBoxes(moof, mdat) {
3611 var result = new Uint8Array(moof.byteLength + mdat.byteLength);
3612 result.set(moof, 0);
3613 result.set(mdat, moof.byteLength);
3614 return result;
3615 }
3616 }, {
3617 key: 'onInitSegment',
3618 get: function get() {
3619 return this._onInitSegment;
3620 },
3621 set: function set(callback) {
3622 this._onInitSegment = callback;
3623 }
3624
3625 /* prototype: function onMediaSegment(type: string, mediaSegment: MediaSegment): void
3626 MediaSegment: {
3627 type: string,
3628 data: ArrayBuffer,
3629 sampleCount: int32
3630 info: MediaSegmentInfo
3631 }
3632 */
3633
3634 }, {
3635 key: 'onMediaSegment',
3636 get: function get() {
3637 return this._onMediaSegment;
3638 },
3639 set: function set(callback) {
3640 this._onMediaSegment = callback;
3641 }
3642 }]);
3643
3644 return MP4Remuxer;
3645}();
3646
3647exports.default = MP4Remuxer;
3648
3649/***/ }),
3650/* 12 */
3651/***/ (function(module, exports, __webpack_require__) {
3652
3653"use strict";
3654
3655
3656Object.defineProperty(exports, "__esModule", {
3657 value: true
3658});
3659
3660var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
3661
3662function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3663
3664/**
3665 * reference flv.js
3666 */
3667/* eslint-disable */
3668var AAC = function () {
3669 function AAC() {
3670 _classCallCheck(this, AAC);
3671 }
3672
3673 _createClass(AAC, null, [{
3674 key: "getSilentFrame",
3675 value: function getSilentFrame(channelCount) {
3676 if (channelCount === 1) {
3677 return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]);
3678 } else if (channelCount === 2) {
3679 return new Uint8Array([0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80]);
3680 } else if (channelCount === 3) {
3681 return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x8e]);
3682 } else if (channelCount === 4) {
3683 return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38]);
3684 } else if (channelCount === 5) {
3685 return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38]);
3686 } else if (channelCount === 6) {
3687 return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2, 0x00, 0x20, 0x08, 0xe0]);
3688 }
3689 return null;
3690 }
3691 }]);
3692
3693 return AAC;
3694}();
3695
3696exports.default = AAC;
3697
3698/***/ }),
3699/* 13 */
3700/***/ (function(module, exports, __webpack_require__) {
3701
3702"use strict";
3703
3704
3705Object.defineProperty(exports, "__esModule", {
3706 value: true
3707});
3708/**
3709 * reference flv.js
3710 */
3711/* eslint-disable */
3712var Browser = {};
3713
3714function detect() {
3715 // modified from jquery-browser-plugin
3716
3717 var ua = self.navigator.userAgent.toLowerCase();
3718
3719 var match = /(edge)\/([\w.]+)/.exec(ua) || /(opr)[\/]([\w.]+)/.exec(ua) || /(chrome)[ \/]([\w.]+)/.exec(ua) || /(iemobile)[\/]([\w.]+)/.exec(ua) || /(version)(applewebkit)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec(ua) || /(webkit)[ \/]([\w.]+).*(version)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec(ua) || /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || /(msie) ([\w.]+)/.exec(ua) || ua.indexOf('trident') >= 0 && /(rv)(?::| )([\w.]+)/.exec(ua) || ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || [];
3720
3721 var platform_match = /(ipad)/.exec(ua) || /(ipod)/.exec(ua) || /(windows phone)/.exec(ua) || /(iphone)/.exec(ua) || /(kindle)/.exec(ua) || /(android)/.exec(ua) || /(windows)/.exec(ua) || /(mac)/.exec(ua) || /(linux)/.exec(ua) || /(cros)/.exec(ua) || [];
3722
3723 var matched = {
3724 browser: match[5] || match[3] || match[1] || '',
3725 version: match[2] || match[4] || '0',
3726 majorVersion: match[4] || match[2] || '0',
3727 platform: platform_match[0] || ''
3728 };
3729
3730 var browser = {};
3731 if (matched.browser) {
3732 browser[matched.browser] = true;
3733
3734 var versionArray = matched.majorVersion.split('.');
3735 browser.version = {
3736 major: parseInt(matched.majorVersion, 10),
3737 string: matched.version
3738 };
3739 if (versionArray.length > 1) {
3740 browser.version.minor = parseInt(versionArray[1], 10);
3741 }
3742 if (versionArray.length > 2) {
3743 browser.version.build = parseInt(versionArray[2], 10);
3744 }
3745 }
3746
3747 if (matched.platform) {
3748 browser[matched.platform] = true;
3749 }
3750
3751 if (browser.chrome || browser.opr || browser.safari) {
3752 browser.webkit = true;
3753 }
3754
3755 // MSIE. IE11 has 'rv' identifer
3756 if (browser.rv || browser.iemobile) {
3757 if (browser.rv) {
3758 delete browser.rv;
3759 }
3760 var msie = 'msie';
3761 matched.browser = msie;
3762 browser[msie] = true;
3763 }
3764
3765 // Microsoft Edge
3766 if (browser.edge) {
3767 delete browser.edge;
3768 var msedge = 'msedge';
3769 matched.browser = msedge;
3770 browser[msedge] = true;
3771 }
3772
3773 // Opera 15+
3774 if (browser.opr) {
3775 var opera = 'opera';
3776 matched.browser = opera;
3777 browser[opera] = true;
3778 }
3779
3780 // Stock android browsers are marked as Safari
3781 if (browser.safari && browser.android) {
3782 var android = 'android';
3783 matched.browser = android;
3784 browser[android] = true;
3785 }
3786
3787 browser.name = matched.browser;
3788 browser.platform = matched.platform;
3789
3790 for (var key in Browser) {
3791 if (Browser.hasOwnProperty(key)) {
3792 delete Browser[key];
3793 }
3794 }
3795 Object.assign(Browser, browser);
3796}
3797
3798detect();
3799
3800exports.default = Browser;
3801
3802/***/ }),
3803/* 14 */
3804/***/ (function(module, exports, __webpack_require__) {
3805
3806"use strict";
3807
3808
3809Object.defineProperty(exports, "__esModule", {
3810 value: true
3811});
3812
3813var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
3814
3815function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3816
3817/**
3818 * reference flv.js
3819 */
3820/* eslint-disable */
3821// Represents an media sample (audio / video)
3822var SampleInfo = exports.SampleInfo = function SampleInfo(dts, pts, duration, originalDts, isSync) {
3823 _classCallCheck(this, SampleInfo);
3824
3825 this.dts = dts;
3826 this.pts = pts;
3827 this.duration = duration;
3828 this.originalDts = originalDts;
3829 this.isSyncPoint = isSync;
3830 this.fileposition = null;
3831};
3832
3833// Media Segment concept is defined in Media Source Extensions spec.
3834// Particularly in ISO BMFF format, an Media Segment contains a moof box followed by a mdat box.
3835
3836
3837var MediaSegmentInfo = exports.MediaSegmentInfo = function () {
3838 function MediaSegmentInfo() {
3839 _classCallCheck(this, MediaSegmentInfo);
3840
3841 this.beginDts = 0;
3842 this.endDts = 0;
3843 this.beginPts = 0;
3844 this.endPts = 0;
3845 this.originalBeginDts = 0;
3846 this.originalEndDts = 0;
3847 this.syncPoints = []; // SampleInfo[n], for video IDR frames only
3848 this.firstSample = null; // SampleInfo
3849 this.lastSample = null; // SampleInfo
3850 }
3851
3852 _createClass(MediaSegmentInfo, [{
3853 key: "appendSyncPoint",
3854 value: function appendSyncPoint(sampleInfo) {
3855 // also called Random Access Point
3856 sampleInfo.isSyncPoint = true;
3857 this.syncPoints.push(sampleInfo);
3858 }
3859 }]);
3860
3861 return MediaSegmentInfo;
3862}();
3863
3864// Ordered list for recording video IDR frames, sorted by originalDts
3865
3866
3867var IDRSampleList = exports.IDRSampleList = function () {
3868 function IDRSampleList() {
3869 _classCallCheck(this, IDRSampleList);
3870
3871 this._list = [];
3872 }
3873
3874 _createClass(IDRSampleList, [{
3875 key: "clear",
3876 value: function clear() {
3877 this._list = [];
3878 }
3879 }, {
3880 key: "appendArray",
3881 value: function appendArray(syncPoints) {
3882 var list = this._list;
3883
3884 if (syncPoints.length === 0) {
3885 return;
3886 }
3887
3888 if (list.length > 0 && syncPoints[0].originalDts < list[list.length - 1].originalDts) {
3889 this.clear();
3890 }
3891
3892 Array.prototype.push.apply(list, syncPoints);
3893 }
3894 }, {
3895 key: "getLastSyncPointBeforeDts",
3896 value: function getLastSyncPointBeforeDts(dts) {
3897 if (this._list.length == 0) {
3898 return null;
3899 }
3900
3901 var list = this._list;
3902 var idx = 0;
3903 var last = list.length - 1;
3904 var mid = 0;
3905 var lbound = 0;
3906 var ubound = last;
3907
3908 if (dts < list[0].dts) {
3909 idx = 0;
3910 lbound = ubound + 1;
3911 }
3912
3913 while (lbound <= ubound) {
3914 mid = lbound + Math.floor((ubound - lbound) / 2);
3915 if (mid === last || dts >= list[mid].dts && dts < list[mid + 1].dts) {
3916 idx = mid;
3917 break;
3918 } else if (list[mid].dts < dts) {
3919 lbound = mid + 1;
3920 } else {
3921 ubound = mid - 1;
3922 }
3923 }
3924 return this._list[idx];
3925 }
3926 }]);
3927
3928 return IDRSampleList;
3929}();
3930
3931// Data structure for recording information of media segments in single track.
3932
3933
3934var MediaSegmentInfoList = exports.MediaSegmentInfoList = function () {
3935 function MediaSegmentInfoList(type) {
3936 _classCallCheck(this, MediaSegmentInfoList);
3937
3938 this._type = type;
3939 this._list = [];
3940 this._lastAppendLocation = -1; // cached last insert location
3941 }
3942
3943 _createClass(MediaSegmentInfoList, [{
3944 key: "isEmpty",
3945 value: function isEmpty() {
3946 return this._list.length === 0;
3947 }
3948 }, {
3949 key: "clear",
3950 value: function clear() {
3951 this._list = [];
3952 this._lastAppendLocation = -1;
3953 }
3954 }, {
3955 key: "_searchNearestSegmentBefore",
3956 value: function _searchNearestSegmentBefore(originalBeginDts) {
3957 var list = this._list;
3958 if (list.length === 0) {
3959 return -2;
3960 }
3961 var last = list.length - 1;
3962 var mid = 0;
3963 var lbound = 0;
3964 var ubound = last;
3965
3966 var idx = 0;
3967
3968 if (originalBeginDts < list[0].originalBeginDts) {
3969 idx = -1;
3970 return idx;
3971 }
3972
3973 while (lbound <= ubound) {
3974 mid = lbound + Math.floor((ubound - lbound) / 2);
3975 if (mid === last || originalBeginDts > list[mid].lastSample.originalDts && originalBeginDts < list[mid + 1].originalBeginDts) {
3976 idx = mid;
3977 break;
3978 } else if (list[mid].originalBeginDts < originalBeginDts) {
3979 lbound = mid + 1;
3980 } else {
3981 ubound = mid - 1;
3982 }
3983 }
3984 return idx;
3985 }
3986 }, {
3987 key: "_searchNearestSegmentAfter",
3988 value: function _searchNearestSegmentAfter(originalBeginDts) {
3989 return this._searchNearestSegmentBefore(originalBeginDts) + 1;
3990 }
3991 }, {
3992 key: "append",
3993 value: function append(mediaSegmentInfo) {
3994 var list = this._list;
3995 var msi = mediaSegmentInfo;
3996 var lastAppendIdx = this._lastAppendLocation;
3997 var insertIdx = 0;
3998
3999 if (lastAppendIdx !== -1 && lastAppendIdx < list.length && msi.originalBeginDts >= list[lastAppendIdx].lastSample.originalDts && (lastAppendIdx === list.length - 1 || lastAppendIdx < list.length - 1 && msi.originalBeginDts < list[lastAppendIdx + 1].originalBeginDts)) {
4000 insertIdx = lastAppendIdx + 1; // use cached location idx
4001 } else {
4002 if (list.length > 0) {
4003 insertIdx = this._searchNearestSegmentBefore(msi.originalBeginDts) + 1;
4004 }
4005 }
4006
4007 this._lastAppendLocation = insertIdx;
4008 this._list.splice(insertIdx, 0, msi);
4009 }
4010 }, {
4011 key: "getLastSegmentBefore",
4012 value: function getLastSegmentBefore(originalBeginDts) {
4013 var idx = this._searchNearestSegmentBefore(originalBeginDts);
4014 if (idx >= 0) {
4015 return this._list[idx];
4016 } else {
4017 // -1
4018 return null;
4019 }
4020 }
4021 }, {
4022 key: "getLastSampleBefore",
4023 value: function getLastSampleBefore(originalBeginDts) {
4024 var segment = this.getLastSegmentBefore(originalBeginDts);
4025 if (segment != null) {
4026 return segment.lastSample;
4027 } else {
4028 return null;
4029 }
4030 }
4031 }, {
4032 key: "getLastSyncPointBefore",
4033 value: function getLastSyncPointBefore(originalBeginDts) {
4034 var segmentIdx = this._searchNearestSegmentBefore(originalBeginDts);
4035 var syncPoints = this._list[segmentIdx].syncPoints;
4036 while (syncPoints.length === 0 && segmentIdx > 0) {
4037 segmentIdx--;
4038 syncPoints = this._list[segmentIdx].syncPoints;
4039 }
4040 if (syncPoints.length > 0) {
4041 return syncPoints[syncPoints.length - 1];
4042 } else {
4043 return null;
4044 }
4045 }
4046 }, {
4047 key: "type",
4048 get: function get() {
4049 return this._type;
4050 }
4051 }, {
4052 key: "length",
4053 get: function get() {
4054 return this._list.length;
4055 }
4056 }]);
4057
4058 return MediaSegmentInfoList;
4059}();
4060
4061/***/ }),
4062/* 15 */
4063/***/ (function(module, exports, __webpack_require__) {
4064
4065
4066/**
4067 * chimee-helper v0.1.8
4068 * (c) 2017 toxic-johann
4069 * Released under MIT
4070 */
4071
4072(function (global, factory) {
4073 true ? factory(exports) :
4074 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4075 (factory((global.chimeeHelper = global.chimeeHelper || {})));
4076}(this, (function (exports) { 'use strict';
4077
4078function unwrapExports (x) {
4079 return x && x.__esModule ? x['default'] : x;
4080}
4081
4082function createCommonjsModule(fn, module) {
4083 return module = { exports: {} }, fn(module, module.exports), module.exports;
4084}
4085
4086// 7.1.4 ToInteger
4087var ceil = Math.ceil;
4088var floor = Math.floor;
4089var _toInteger = function(it){
4090 return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
4091};
4092
4093// 7.2.1 RequireObjectCoercible(argument)
4094var _defined = function(it){
4095 if(it == undefined)throw TypeError("Can't call method on " + it);
4096 return it;
4097};
4098
4099// true -> String#at
4100// false -> String#codePointAt
4101var _stringAt = function(TO_STRING){
4102 return function(that, pos){
4103 var s = String(_defined(that))
4104 , i = _toInteger(pos)
4105 , l = s.length
4106 , a, b;
4107 if(i < 0 || i >= l)return TO_STRING ? '' : undefined;
4108 a = s.charCodeAt(i);
4109 return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
4110 ? TO_STRING ? s.charAt(i) : a
4111 : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
4112 };
4113};
4114
4115var _library = true;
4116
4117var _global = createCommonjsModule(function (module) {
4118// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
4119var global = module.exports = typeof window != 'undefined' && window.Math == Math
4120 ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();
4121if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef
4122});
4123
4124var _core = createCommonjsModule(function (module) {
4125var core = module.exports = {version: '2.4.0'};
4126if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef
4127});
4128
4129var _aFunction = function(it){
4130 if(typeof it != 'function')throw TypeError(it + ' is not a function!');
4131 return it;
4132};
4133
4134// optional / simple context binding
4135
4136var _ctx = function(fn, that, length){
4137 _aFunction(fn);
4138 if(that === undefined)return fn;
4139 switch(length){
4140 case 1: return function(a){
4141 return fn.call(that, a);
4142 };
4143 case 2: return function(a, b){
4144 return fn.call(that, a, b);
4145 };
4146 case 3: return function(a, b, c){
4147 return fn.call(that, a, b, c);
4148 };
4149 }
4150 return function(/* ...args */){
4151 return fn.apply(that, arguments);
4152 };
4153};
4154
4155var _isObject = function(it){
4156 return typeof it === 'object' ? it !== null : typeof it === 'function';
4157};
4158
4159var _anObject = function(it){
4160 if(!_isObject(it))throw TypeError(it + ' is not an object!');
4161 return it;
4162};
4163
4164var _fails = function(exec){
4165 try {
4166 return !!exec();
4167 } catch(e){
4168 return true;
4169 }
4170};
4171
4172// Thank's IE8 for his funny defineProperty
4173var _descriptors = !_fails(function(){
4174 return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;
4175});
4176
4177var document$1 = _global.document;
4178var is = _isObject(document$1) && _isObject(document$1.createElement);
4179var _domCreate = function(it){
4180 return is ? document$1.createElement(it) : {};
4181};
4182
4183var _ie8DomDefine = !_descriptors && !_fails(function(){
4184 return Object.defineProperty(_domCreate('div'), 'a', {get: function(){ return 7; }}).a != 7;
4185});
4186
4187// 7.1.1 ToPrimitive(input [, PreferredType])
4188
4189// instead of the ES6 spec version, we didn't implement @@toPrimitive case
4190// and the second argument - flag - preferred type is a string
4191var _toPrimitive = function(it, S){
4192 if(!_isObject(it))return it;
4193 var fn, val;
4194 if(S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it)))return val;
4195 if(typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it)))return val;
4196 if(!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it)))return val;
4197 throw TypeError("Can't convert object to primitive value");
4198};
4199
4200var dP = Object.defineProperty;
4201
4202var f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes){
4203 _anObject(O);
4204 P = _toPrimitive(P, true);
4205 _anObject(Attributes);
4206 if(_ie8DomDefine)try {
4207 return dP(O, P, Attributes);
4208 } catch(e){ /* empty */ }
4209 if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');
4210 if('value' in Attributes)O[P] = Attributes.value;
4211 return O;
4212};
4213
4214var _objectDp = {
4215 f: f
4216};
4217
4218var _propertyDesc = function(bitmap, value){
4219 return {
4220 enumerable : !(bitmap & 1),
4221 configurable: !(bitmap & 2),
4222 writable : !(bitmap & 4),
4223 value : value
4224 };
4225};
4226
4227var _hide = _descriptors ? function(object, key, value){
4228 return _objectDp.f(object, key, _propertyDesc(1, value));
4229} : function(object, key, value){
4230 object[key] = value;
4231 return object;
4232};
4233
4234var PROTOTYPE = 'prototype';
4235
4236var $export = function(type, name, source){
4237 var IS_FORCED = type & $export.F
4238 , IS_GLOBAL = type & $export.G
4239 , IS_STATIC = type & $export.S
4240 , IS_PROTO = type & $export.P
4241 , IS_BIND = type & $export.B
4242 , IS_WRAP = type & $export.W
4243 , exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {})
4244 , expProto = exports[PROTOTYPE]
4245 , target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] : (_global[name] || {})[PROTOTYPE]
4246 , key, own, out;
4247 if(IS_GLOBAL)source = name;
4248 for(key in source){
4249 // contains in native
4250 own = !IS_FORCED && target && target[key] !== undefined;
4251 if(own && key in exports)continue;
4252 // export native or passed
4253 out = own ? target[key] : source[key];
4254 // prevent global pollution for namespaces
4255 exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]
4256 // bind timers to global for call from export context
4257 : IS_BIND && own ? _ctx(out, _global)
4258 // wrap global constructors for prevent change them in library
4259 : IS_WRAP && target[key] == out ? (function(C){
4260 var F = function(a, b, c){
4261 if(this instanceof C){
4262 switch(arguments.length){
4263 case 0: return new C;
4264 case 1: return new C(a);
4265 case 2: return new C(a, b);
4266 } return new C(a, b, c);
4267 } return C.apply(this, arguments);
4268 };
4269 F[PROTOTYPE] = C[PROTOTYPE];
4270 return F;
4271 // make static versions for prototype methods
4272 })(out) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out;
4273 // export proto methods to core.%CONSTRUCTOR%.methods.%NAME%
4274 if(IS_PROTO){
4275 (exports.virtual || (exports.virtual = {}))[key] = out;
4276 // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%
4277 if(type & $export.R && expProto && !expProto[key])_hide(expProto, key, out);
4278 }
4279 }
4280};
4281// type bitmap
4282$export.F = 1; // forced
4283$export.G = 2; // global
4284$export.S = 4; // static
4285$export.P = 8; // proto
4286$export.B = 16; // bind
4287$export.W = 32; // wrap
4288$export.U = 64; // safe
4289$export.R = 128; // real proto method for `library`
4290var _export = $export;
4291
4292var _redefine = _hide;
4293
4294var hasOwnProperty = {}.hasOwnProperty;
4295var _has = function(it, key){
4296 return hasOwnProperty.call(it, key);
4297};
4298
4299var _iterators = {};
4300
4301var toString = {}.toString;
4302
4303var _cof = function(it){
4304 return toString.call(it).slice(8, -1);
4305};
4306
4307// fallback for non-array-like ES3 and non-enumerable old V8 strings
4308
4309var _iobject = Object('z').propertyIsEnumerable(0) ? Object : function(it){
4310 return _cof(it) == 'String' ? it.split('') : Object(it);
4311};
4312
4313// to indexed object, toObject with fallback for non-array-like ES3 strings
4314
4315var _toIobject = function(it){
4316 return _iobject(_defined(it));
4317};
4318
4319// 7.1.15 ToLength
4320var min = Math.min;
4321var _toLength = function(it){
4322 return it > 0 ? min(_toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
4323};
4324
4325var max = Math.max;
4326var min$1 = Math.min;
4327var _toIndex = function(index, length){
4328 index = _toInteger(index);
4329 return index < 0 ? max(index + length, 0) : min$1(index, length);
4330};
4331
4332// false -> Array#indexOf
4333// true -> Array#includes
4334
4335var _arrayIncludes = function(IS_INCLUDES){
4336 return function($this, el, fromIndex){
4337 var O = _toIobject($this)
4338 , length = _toLength(O.length)
4339 , index = _toIndex(fromIndex, length)
4340 , value;
4341 // Array#includes uses SameValueZero equality algorithm
4342 if(IS_INCLUDES && el != el)while(length > index){
4343 value = O[index++];
4344 if(value != value)return true;
4345 // Array#toIndex ignores holes, Array#includes - not
4346 } else for(;length > index; index++)if(IS_INCLUDES || index in O){
4347 if(O[index] === el)return IS_INCLUDES || index || 0;
4348 } return !IS_INCLUDES && -1;
4349 };
4350};
4351
4352var SHARED = '__core-js_shared__';
4353var store = _global[SHARED] || (_global[SHARED] = {});
4354var _shared = function(key){
4355 return store[key] || (store[key] = {});
4356};
4357
4358var id = 0;
4359var px = Math.random();
4360var _uid = function(key){
4361 return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
4362};
4363
4364var shared = _shared('keys');
4365var _sharedKey = function(key){
4366 return shared[key] || (shared[key] = _uid(key));
4367};
4368
4369var arrayIndexOf = _arrayIncludes(false);
4370var IE_PROTO$1 = _sharedKey('IE_PROTO');
4371
4372var _objectKeysInternal = function(object, names){
4373 var O = _toIobject(object)
4374 , i = 0
4375 , result = []
4376 , key;
4377 for(key in O)if(key != IE_PROTO$1)_has(O, key) && result.push(key);
4378 // Don't enum bug & hidden keys
4379 while(names.length > i)if(_has(O, key = names[i++])){
4380 ~arrayIndexOf(result, key) || result.push(key);
4381 }
4382 return result;
4383};
4384
4385// IE 8- don't enum bug keys
4386var _enumBugKeys = (
4387 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'
4388).split(',');
4389
4390// 19.1.2.14 / 15.2.3.14 Object.keys(O)
4391
4392
4393var _objectKeys = Object.keys || function keys(O){
4394 return _objectKeysInternal(O, _enumBugKeys);
4395};
4396
4397var _objectDps = _descriptors ? Object.defineProperties : function defineProperties(O, Properties){
4398 _anObject(O);
4399 var keys = _objectKeys(Properties)
4400 , length = keys.length
4401 , i = 0
4402 , P;
4403 while(length > i)_objectDp.f(O, P = keys[i++], Properties[P]);
4404 return O;
4405};
4406
4407var _html = _global.document && document.documentElement;
4408
4409// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
4410var IE_PROTO = _sharedKey('IE_PROTO');
4411var Empty = function(){ /* empty */ };
4412var PROTOTYPE$1 = 'prototype';
4413
4414// Create object with fake `null` prototype: use iframe Object with cleared prototype
4415var createDict = function(){
4416 // Thrash, waste and sodomy: IE GC bug
4417 var iframe = _domCreate('iframe')
4418 , i = _enumBugKeys.length
4419 , lt = '<'
4420 , gt = '>'
4421 , iframeDocument;
4422 iframe.style.display = 'none';
4423 _html.appendChild(iframe);
4424 iframe.src = 'javascript:'; // eslint-disable-line no-script-url
4425 // createDict = iframe.contentWindow.Object;
4426 // html.removeChild(iframe);
4427 iframeDocument = iframe.contentWindow.document;
4428 iframeDocument.open();
4429 iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
4430 iframeDocument.close();
4431 createDict = iframeDocument.F;
4432 while(i--)delete createDict[PROTOTYPE$1][_enumBugKeys[i]];
4433 return createDict();
4434};
4435
4436var _objectCreate = Object.create || function create(O, Properties){
4437 var result;
4438 if(O !== null){
4439 Empty[PROTOTYPE$1] = _anObject(O);
4440 result = new Empty;
4441 Empty[PROTOTYPE$1] = null;
4442 // add "__proto__" for Object.getPrototypeOf polyfill
4443 result[IE_PROTO] = O;
4444 } else result = createDict();
4445 return Properties === undefined ? result : _objectDps(result, Properties);
4446};
4447
4448var _wks = createCommonjsModule(function (module) {
4449var store = _shared('wks')
4450 , Symbol = _global.Symbol
4451 , USE_SYMBOL = typeof Symbol == 'function';
4452
4453var $exports = module.exports = function(name){
4454 return store[name] || (store[name] =
4455 USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : _uid)('Symbol.' + name));
4456};
4457
4458$exports.store = store;
4459});
4460
4461var def = _objectDp.f;
4462var TAG = _wks('toStringTag');
4463
4464var _setToStringTag = function(it, tag, stat){
4465 if(it && !_has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag});
4466};
4467
4468var IteratorPrototype = {};
4469
4470// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
4471_hide(IteratorPrototype, _wks('iterator'), function(){ return this; });
4472
4473var _iterCreate = function(Constructor, NAME, next){
4474 Constructor.prototype = _objectCreate(IteratorPrototype, {next: _propertyDesc(1, next)});
4475 _setToStringTag(Constructor, NAME + ' Iterator');
4476};
4477
4478// 7.1.13 ToObject(argument)
4479
4480var _toObject = function(it){
4481 return Object(_defined(it));
4482};
4483
4484// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
4485var IE_PROTO$2 = _sharedKey('IE_PROTO');
4486var ObjectProto = Object.prototype;
4487
4488var _objectGpo = Object.getPrototypeOf || function(O){
4489 O = _toObject(O);
4490 if(_has(O, IE_PROTO$2))return O[IE_PROTO$2];
4491 if(typeof O.constructor == 'function' && O instanceof O.constructor){
4492 return O.constructor.prototype;
4493 } return O instanceof Object ? ObjectProto : null;
4494};
4495
4496var ITERATOR = _wks('iterator');
4497var BUGGY = !([].keys && 'next' in [].keys());
4498var FF_ITERATOR = '@@iterator';
4499var KEYS = 'keys';
4500var VALUES = 'values';
4501
4502var returnThis = function(){ return this; };
4503
4504var _iterDefine = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){
4505 _iterCreate(Constructor, NAME, next);
4506 var getMethod = function(kind){
4507 if(!BUGGY && kind in proto)return proto[kind];
4508 switch(kind){
4509 case KEYS: return function keys(){ return new Constructor(this, kind); };
4510 case VALUES: return function values(){ return new Constructor(this, kind); };
4511 } return function entries(){ return new Constructor(this, kind); };
4512 };
4513 var TAG = NAME + ' Iterator'
4514 , DEF_VALUES = DEFAULT == VALUES
4515 , VALUES_BUG = false
4516 , proto = Base.prototype
4517 , $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]
4518 , $default = $native || getMethod(DEFAULT)
4519 , $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined
4520 , $anyNative = NAME == 'Array' ? proto.entries || $native : $native
4521 , methods, key, IteratorPrototype;
4522 // Fix native
4523 if($anyNative){
4524 IteratorPrototype = _objectGpo($anyNative.call(new Base));
4525 if(IteratorPrototype !== Object.prototype){
4526 // Set @@toStringTag to native iterators
4527 _setToStringTag(IteratorPrototype, TAG, true);
4528 // fix for some old engines
4529 if(!_library && !_has(IteratorPrototype, ITERATOR))_hide(IteratorPrototype, ITERATOR, returnThis);
4530 }
4531 }
4532 // fix Array#{values, @@iterator}.name in V8 / FF
4533 if(DEF_VALUES && $native && $native.name !== VALUES){
4534 VALUES_BUG = true;
4535 $default = function values(){ return $native.call(this); };
4536 }
4537 // Define iterator
4538 if((!_library || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){
4539 _hide(proto, ITERATOR, $default);
4540 }
4541 // Plug for library
4542 _iterators[NAME] = $default;
4543 _iterators[TAG] = returnThis;
4544 if(DEFAULT){
4545 methods = {
4546 values: DEF_VALUES ? $default : getMethod(VALUES),
4547 keys: IS_SET ? $default : getMethod(KEYS),
4548 entries: $entries
4549 };
4550 if(FORCED)for(key in methods){
4551 if(!(key in proto))_redefine(proto, key, methods[key]);
4552 } else _export(_export.P + _export.F * (BUGGY || VALUES_BUG), NAME, methods);
4553 }
4554 return methods;
4555};
4556
4557var $at = _stringAt(true);
4558
4559// 21.1.3.27 String.prototype[@@iterator]()
4560_iterDefine(String, 'String', function(iterated){
4561 this._t = String(iterated); // target
4562 this._i = 0; // next index
4563// 21.1.5.2.1 %StringIteratorPrototype%.next()
4564}, function(){
4565 var O = this._t
4566 , index = this._i
4567 , point;
4568 if(index >= O.length)return {value: undefined, done: true};
4569 point = $at(O, index);
4570 this._i += point.length;
4571 return {value: point, done: false};
4572});
4573
4574// call something on iterator step with safe closing on error
4575
4576var _iterCall = function(iterator, fn, value, entries){
4577 try {
4578 return entries ? fn(_anObject(value)[0], value[1]) : fn(value);
4579 // 7.4.6 IteratorClose(iterator, completion)
4580 } catch(e){
4581 var ret = iterator['return'];
4582 if(ret !== undefined)_anObject(ret.call(iterator));
4583 throw e;
4584 }
4585};
4586
4587// check on default Array iterator
4588var ITERATOR$1 = _wks('iterator');
4589var ArrayProto = Array.prototype;
4590
4591var _isArrayIter = function(it){
4592 return it !== undefined && (_iterators.Array === it || ArrayProto[ITERATOR$1] === it);
4593};
4594
4595var _createProperty = function(object, index, value){
4596 if(index in object)_objectDp.f(object, index, _propertyDesc(0, value));
4597 else object[index] = value;
4598};
4599
4600// getting tag from 19.1.3.6 Object.prototype.toString()
4601var TAG$1 = _wks('toStringTag');
4602var ARG = _cof(function(){ return arguments; }()) == 'Arguments';
4603
4604// fallback for IE11 Script Access Denied error
4605var tryGet = function(it, key){
4606 try {
4607 return it[key];
4608 } catch(e){ /* empty */ }
4609};
4610
4611var _classof = function(it){
4612 var O, T, B;
4613 return it === undefined ? 'Undefined' : it === null ? 'Null'
4614 // @@toStringTag case
4615 : typeof (T = tryGet(O = Object(it), TAG$1)) == 'string' ? T
4616 // builtinTag case
4617 : ARG ? _cof(O)
4618 // ES3 arguments fallback
4619 : (B = _cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
4620};
4621
4622var ITERATOR$2 = _wks('iterator');
4623var core_getIteratorMethod = _core.getIteratorMethod = function(it){
4624 if(it != undefined)return it[ITERATOR$2]
4625 || it['@@iterator']
4626 || _iterators[_classof(it)];
4627};
4628
4629var ITERATOR$3 = _wks('iterator');
4630var SAFE_CLOSING = false;
4631
4632try {
4633 var riter = [7][ITERATOR$3]();
4634 riter['return'] = function(){ SAFE_CLOSING = true; };
4635 Array.from(riter, function(){ throw 2; });
4636} catch(e){ /* empty */ }
4637
4638var _iterDetect = function(exec, skipClosing){
4639 if(!skipClosing && !SAFE_CLOSING)return false;
4640 var safe = false;
4641 try {
4642 var arr = [7]
4643 , iter = arr[ITERATOR$3]();
4644 iter.next = function(){ return {done: safe = true}; };
4645 arr[ITERATOR$3] = function(){ return iter; };
4646 exec(arr);
4647 } catch(e){ /* empty */ }
4648 return safe;
4649};
4650
4651_export(_export.S + _export.F * !_iterDetect(function(iter){ Array.from(iter); }), 'Array', {
4652 // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)
4653 from: function from(arrayLike/*, mapfn = undefined, thisArg = undefined*/){
4654 var O = _toObject(arrayLike)
4655 , C = typeof this == 'function' ? this : Array
4656 , aLen = arguments.length
4657 , mapfn = aLen > 1 ? arguments[1] : undefined
4658 , mapping = mapfn !== undefined
4659 , index = 0
4660 , iterFn = core_getIteratorMethod(O)
4661 , length, result, step, iterator;
4662 if(mapping)mapfn = _ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);
4663 // if object isn't iterable or it's array with default iterator - use simple case
4664 if(iterFn != undefined && !(C == Array && _isArrayIter(iterFn))){
4665 for(iterator = iterFn.call(O), result = new C; !(step = iterator.next()).done; index++){
4666 _createProperty(result, index, mapping ? _iterCall(iterator, mapfn, [step.value, index], true) : step.value);
4667 }
4668 } else {
4669 length = _toLength(O.length);
4670 for(result = new C(length); length > index; index++){
4671 _createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
4672 }
4673 }
4674 result.length = index;
4675 return result;
4676 }
4677});
4678
4679var from$1 = _core.Array.from;
4680
4681var from = createCommonjsModule(function (module) {
4682module.exports = { "default": from$1, __esModule: true };
4683});
4684
4685var _Array$from = unwrapExports(from);
4686
4687var toConsumableArray = createCommonjsModule(function (module, exports) {
4688"use strict";
4689
4690exports.__esModule = true;
4691
4692
4693
4694var _from2 = _interopRequireDefault(from);
4695
4696function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
4697
4698exports.default = function (arr) {
4699 if (Array.isArray(arr)) {
4700 for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
4701 arr2[i] = arr[i];
4702 }
4703
4704 return arr2;
4705 } else {
4706 return (0, _from2.default)(arr);
4707 }
4708};
4709});
4710
4711var _toConsumableArray = unwrapExports(toConsumableArray);
4712
4713var _addToUnscopables = function(){ /* empty */ };
4714
4715var _iterStep = function(done, value){
4716 return {value: value, done: !!done};
4717};
4718
4719// 22.1.3.4 Array.prototype.entries()
4720// 22.1.3.13 Array.prototype.keys()
4721// 22.1.3.29 Array.prototype.values()
4722// 22.1.3.30 Array.prototype[@@iterator]()
4723var es6_array_iterator = _iterDefine(Array, 'Array', function(iterated, kind){
4724 this._t = _toIobject(iterated); // target
4725 this._i = 0; // next index
4726 this._k = kind; // kind
4727// 22.1.5.2.1 %ArrayIteratorPrototype%.next()
4728}, function(){
4729 var O = this._t
4730 , kind = this._k
4731 , index = this._i++;
4732 if(!O || index >= O.length){
4733 this._t = undefined;
4734 return _iterStep(1);
4735 }
4736 if(kind == 'keys' )return _iterStep(0, index);
4737 if(kind == 'values')return _iterStep(0, O[index]);
4738 return _iterStep(0, [index, O[index]]);
4739}, 'values');
4740
4741// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
4742_iterators.Arguments = _iterators.Array;
4743
4744_addToUnscopables('keys');
4745_addToUnscopables('values');
4746_addToUnscopables('entries');
4747
4748var TO_STRING_TAG = _wks('toStringTag');
4749
4750for(var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++){
4751 var NAME = collections[i]
4752 , Collection = _global[NAME]
4753 , proto = Collection && Collection.prototype;
4754 if(proto && !proto[TO_STRING_TAG])_hide(proto, TO_STRING_TAG, NAME);
4755 _iterators[NAME] = _iterators.Array;
4756}
4757
4758var f$1 = _wks;
4759
4760var _wksExt = {
4761 f: f$1
4762};
4763
4764var iterator$2 = _wksExt.f('iterator');
4765
4766var iterator = createCommonjsModule(function (module) {
4767module.exports = { "default": iterator$2, __esModule: true };
4768});
4769
4770var _meta = createCommonjsModule(function (module) {
4771var META = _uid('meta')
4772 , setDesc = _objectDp.f
4773 , id = 0;
4774var isExtensible = Object.isExtensible || function(){
4775 return true;
4776};
4777var FREEZE = !_fails(function(){
4778 return isExtensible(Object.preventExtensions({}));
4779});
4780var setMeta = function(it){
4781 setDesc(it, META, {value: {
4782 i: 'O' + ++id, // object ID
4783 w: {} // weak collections IDs
4784 }});
4785};
4786var fastKey = function(it, create){
4787 // return primitive with prefix
4788 if(!_isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
4789 if(!_has(it, META)){
4790 // can't set metadata to uncaught frozen object
4791 if(!isExtensible(it))return 'F';
4792 // not necessary to add metadata
4793 if(!create)return 'E';
4794 // add missing metadata
4795 setMeta(it);
4796 // return object ID
4797 } return it[META].i;
4798};
4799var getWeak = function(it, create){
4800 if(!_has(it, META)){
4801 // can't set metadata to uncaught frozen object
4802 if(!isExtensible(it))return true;
4803 // not necessary to add metadata
4804 if(!create)return false;
4805 // add missing metadata
4806 setMeta(it);
4807 // return hash weak collections IDs
4808 } return it[META].w;
4809};
4810// add metadata on freeze-family methods calling
4811var onFreeze = function(it){
4812 if(FREEZE && meta.NEED && isExtensible(it) && !_has(it, META))setMeta(it);
4813 return it;
4814};
4815var meta = module.exports = {
4816 KEY: META,
4817 NEED: false,
4818 fastKey: fastKey,
4819 getWeak: getWeak,
4820 onFreeze: onFreeze
4821};
4822});
4823
4824var defineProperty = _objectDp.f;
4825var _wksDefine = function(name){
4826 var $Symbol = _core.Symbol || (_core.Symbol = _library ? {} : _global.Symbol || {});
4827 if(name.charAt(0) != '_' && !(name in $Symbol))defineProperty($Symbol, name, {value: _wksExt.f(name)});
4828};
4829
4830var _keyof = function(object, el){
4831 var O = _toIobject(object)
4832 , keys = _objectKeys(O)
4833 , length = keys.length
4834 , index = 0
4835 , key;
4836 while(length > index)if(O[key = keys[index++]] === el)return key;
4837};
4838
4839var f$2 = Object.getOwnPropertySymbols;
4840
4841var _objectGops = {
4842 f: f$2
4843};
4844
4845var f$3 = {}.propertyIsEnumerable;
4846
4847var _objectPie = {
4848 f: f$3
4849};
4850
4851// all enumerable object keys, includes symbols
4852
4853var _enumKeys = function(it){
4854 var result = _objectKeys(it)
4855 , getSymbols = _objectGops.f;
4856 if(getSymbols){
4857 var symbols = getSymbols(it)
4858 , isEnum = _objectPie.f
4859 , i = 0
4860 , key;
4861 while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))result.push(key);
4862 } return result;
4863};
4864
4865// 7.2.2 IsArray(argument)
4866
4867var _isArray = Array.isArray || function isArray(arg){
4868 return _cof(arg) == 'Array';
4869};
4870
4871// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)
4872var hiddenKeys = _enumBugKeys.concat('length', 'prototype');
4873
4874var f$5 = Object.getOwnPropertyNames || function getOwnPropertyNames(O){
4875 return _objectKeysInternal(O, hiddenKeys);
4876};
4877
4878var _objectGopn = {
4879 f: f$5
4880};
4881
4882// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
4883var gOPN$1 = _objectGopn.f;
4884var toString$1 = {}.toString;
4885
4886var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames
4887 ? Object.getOwnPropertyNames(window) : [];
4888
4889var getWindowNames = function(it){
4890 try {
4891 return gOPN$1(it);
4892 } catch(e){
4893 return windowNames.slice();
4894 }
4895};
4896
4897var f$4 = function getOwnPropertyNames(it){
4898 return windowNames && toString$1.call(it) == '[object Window]' ? getWindowNames(it) : gOPN$1(_toIobject(it));
4899};
4900
4901var _objectGopnExt = {
4902 f: f$4
4903};
4904
4905var gOPD$1 = Object.getOwnPropertyDescriptor;
4906
4907var f$6 = _descriptors ? gOPD$1 : function getOwnPropertyDescriptor(O, P){
4908 O = _toIobject(O);
4909 P = _toPrimitive(P, true);
4910 if(_ie8DomDefine)try {
4911 return gOPD$1(O, P);
4912 } catch(e){ /* empty */ }
4913 if(_has(O, P))return _propertyDesc(!_objectPie.f.call(O, P), O[P]);
4914};
4915
4916var _objectGopd = {
4917 f: f$6
4918};
4919
4920// ECMAScript 6 symbols shim
4921var META = _meta.KEY;
4922var gOPD = _objectGopd.f;
4923var dP$2 = _objectDp.f;
4924var gOPN = _objectGopnExt.f;
4925var $Symbol = _global.Symbol;
4926var $JSON = _global.JSON;
4927var _stringify = $JSON && $JSON.stringify;
4928var PROTOTYPE$2 = 'prototype';
4929var HIDDEN = _wks('_hidden');
4930var TO_PRIMITIVE = _wks('toPrimitive');
4931var isEnum = {}.propertyIsEnumerable;
4932var SymbolRegistry = _shared('symbol-registry');
4933var AllSymbols = _shared('symbols');
4934var OPSymbols = _shared('op-symbols');
4935var ObjectProto$1 = Object[PROTOTYPE$2];
4936var USE_NATIVE = typeof $Symbol == 'function';
4937var QObject = _global.QObject;
4938// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
4939var setter = !QObject || !QObject[PROTOTYPE$2] || !QObject[PROTOTYPE$2].findChild;
4940
4941// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
4942var setSymbolDesc = _descriptors && _fails(function(){
4943 return _objectCreate(dP$2({}, 'a', {
4944 get: function(){ return dP$2(this, 'a', {value: 7}).a; }
4945 })).a != 7;
4946}) ? function(it, key, D){
4947 var protoDesc = gOPD(ObjectProto$1, key);
4948 if(protoDesc)delete ObjectProto$1[key];
4949 dP$2(it, key, D);
4950 if(protoDesc && it !== ObjectProto$1)dP$2(ObjectProto$1, key, protoDesc);
4951} : dP$2;
4952
4953var wrap = function(tag){
4954 var sym = AllSymbols[tag] = _objectCreate($Symbol[PROTOTYPE$2]);
4955 sym._k = tag;
4956 return sym;
4957};
4958
4959var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function(it){
4960 return typeof it == 'symbol';
4961} : function(it){
4962 return it instanceof $Symbol;
4963};
4964
4965var $defineProperty = function defineProperty(it, key, D){
4966 if(it === ObjectProto$1)$defineProperty(OPSymbols, key, D);
4967 _anObject(it);
4968 key = _toPrimitive(key, true);
4969 _anObject(D);
4970 if(_has(AllSymbols, key)){
4971 if(!D.enumerable){
4972 if(!_has(it, HIDDEN))dP$2(it, HIDDEN, _propertyDesc(1, {}));
4973 it[HIDDEN][key] = true;
4974 } else {
4975 if(_has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false;
4976 D = _objectCreate(D, {enumerable: _propertyDesc(0, false)});
4977 } return setSymbolDesc(it, key, D);
4978 } return dP$2(it, key, D);
4979};
4980var $defineProperties = function defineProperties(it, P){
4981 _anObject(it);
4982 var keys = _enumKeys(P = _toIobject(P))
4983 , i = 0
4984 , l = keys.length
4985 , key;
4986 while(l > i)$defineProperty(it, key = keys[i++], P[key]);
4987 return it;
4988};
4989var $create = function create(it, P){
4990 return P === undefined ? _objectCreate(it) : $defineProperties(_objectCreate(it), P);
4991};
4992var $propertyIsEnumerable = function propertyIsEnumerable(key){
4993 var E = isEnum.call(this, key = _toPrimitive(key, true));
4994 if(this === ObjectProto$1 && _has(AllSymbols, key) && !_has(OPSymbols, key))return false;
4995 return E || !_has(this, key) || !_has(AllSymbols, key) || _has(this, HIDDEN) && this[HIDDEN][key] ? E : true;
4996};
4997var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){
4998 it = _toIobject(it);
4999 key = _toPrimitive(key, true);
5000 if(it === ObjectProto$1 && _has(AllSymbols, key) && !_has(OPSymbols, key))return;
5001 var D = gOPD(it, key);
5002 if(D && _has(AllSymbols, key) && !(_has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true;
5003 return D;
5004};
5005var $getOwnPropertyNames = function getOwnPropertyNames(it){
5006 var names = gOPN(_toIobject(it))
5007 , result = []
5008 , i = 0
5009 , key;
5010 while(names.length > i){
5011 if(!_has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META)result.push(key);
5012 } return result;
5013};
5014var $getOwnPropertySymbols = function getOwnPropertySymbols(it){
5015 var IS_OP = it === ObjectProto$1
5016 , names = gOPN(IS_OP ? OPSymbols : _toIobject(it))
5017 , result = []
5018 , i = 0
5019 , key;
5020 while(names.length > i){
5021 if(_has(AllSymbols, key = names[i++]) && (IS_OP ? _has(ObjectProto$1, key) : true))result.push(AllSymbols[key]);
5022 } return result;
5023};
5024
5025// 19.4.1.1 Symbol([description])
5026if(!USE_NATIVE){
5027 $Symbol = function Symbol(){
5028 if(this instanceof $Symbol)throw TypeError('Symbol is not a constructor!');
5029 var tag = _uid(arguments.length > 0 ? arguments[0] : undefined);
5030 var $set = function(value){
5031 if(this === ObjectProto$1)$set.call(OPSymbols, value);
5032 if(_has(this, HIDDEN) && _has(this[HIDDEN], tag))this[HIDDEN][tag] = false;
5033 setSymbolDesc(this, tag, _propertyDesc(1, value));
5034 };
5035 if(_descriptors && setter)setSymbolDesc(ObjectProto$1, tag, {configurable: true, set: $set});
5036 return wrap(tag);
5037 };
5038 _redefine($Symbol[PROTOTYPE$2], 'toString', function toString(){
5039 return this._k;
5040 });
5041
5042 _objectGopd.f = $getOwnPropertyDescriptor;
5043 _objectDp.f = $defineProperty;
5044 _objectGopn.f = _objectGopnExt.f = $getOwnPropertyNames;
5045 _objectPie.f = $propertyIsEnumerable;
5046 _objectGops.f = $getOwnPropertySymbols;
5047
5048 if(_descriptors && !_library){
5049 _redefine(ObjectProto$1, 'propertyIsEnumerable', $propertyIsEnumerable, true);
5050 }
5051
5052 _wksExt.f = function(name){
5053 return wrap(_wks(name));
5054 };
5055}
5056
5057_export(_export.G + _export.W + _export.F * !USE_NATIVE, {Symbol: $Symbol});
5058
5059for(var symbols = (
5060 // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14
5061 'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'
5062).split(','), i$1 = 0; symbols.length > i$1; )_wks(symbols[i$1++]);
5063
5064for(var symbols = _objectKeys(_wks.store), i$1 = 0; symbols.length > i$1; )_wksDefine(symbols[i$1++]);
5065
5066_export(_export.S + _export.F * !USE_NATIVE, 'Symbol', {
5067 // 19.4.2.1 Symbol.for(key)
5068 'for': function(key){
5069 return _has(SymbolRegistry, key += '')
5070 ? SymbolRegistry[key]
5071 : SymbolRegistry[key] = $Symbol(key);
5072 },
5073 // 19.4.2.5 Symbol.keyFor(sym)
5074 keyFor: function keyFor(key){
5075 if(isSymbol(key))return _keyof(SymbolRegistry, key);
5076 throw TypeError(key + ' is not a symbol!');
5077 },
5078 useSetter: function(){ setter = true; },
5079 useSimple: function(){ setter = false; }
5080});
5081
5082_export(_export.S + _export.F * !USE_NATIVE, 'Object', {
5083 // 19.1.2.2 Object.create(O [, Properties])
5084 create: $create,
5085 // 19.1.2.4 Object.defineProperty(O, P, Attributes)
5086 defineProperty: $defineProperty,
5087 // 19.1.2.3 Object.defineProperties(O, Properties)
5088 defineProperties: $defineProperties,
5089 // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
5090 getOwnPropertyDescriptor: $getOwnPropertyDescriptor,
5091 // 19.1.2.7 Object.getOwnPropertyNames(O)
5092 getOwnPropertyNames: $getOwnPropertyNames,
5093 // 19.1.2.8 Object.getOwnPropertySymbols(O)
5094 getOwnPropertySymbols: $getOwnPropertySymbols
5095});
5096
5097// 24.3.2 JSON.stringify(value [, replacer [, space]])
5098$JSON && _export(_export.S + _export.F * (!USE_NATIVE || _fails(function(){
5099 var S = $Symbol();
5100 // MS Edge converts symbol values to JSON as {}
5101 // WebKit converts symbol values to JSON as null
5102 // V8 throws on boxed symbols
5103 return _stringify([S]) != '[null]' || _stringify({a: S}) != '{}' || _stringify(Object(S)) != '{}';
5104})), 'JSON', {
5105 stringify: function stringify(it){
5106 if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined
5107 var args = [it]
5108 , i = 1
5109 , replacer, $replacer;
5110 while(arguments.length > i)args.push(arguments[i++]);
5111 replacer = args[1];
5112 if(typeof replacer == 'function')$replacer = replacer;
5113 if($replacer || !_isArray(replacer))replacer = function(key, value){
5114 if($replacer)value = $replacer.call(this, key, value);
5115 if(!isSymbol(value))return value;
5116 };
5117 args[1] = replacer;
5118 return _stringify.apply($JSON, args);
5119 }
5120});
5121
5122// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)
5123$Symbol[PROTOTYPE$2][TO_PRIMITIVE] || _hide($Symbol[PROTOTYPE$2], TO_PRIMITIVE, $Symbol[PROTOTYPE$2].valueOf);
5124// 19.4.3.5 Symbol.prototype[@@toStringTag]
5125_setToStringTag($Symbol, 'Symbol');
5126// 20.2.1.9 Math[@@toStringTag]
5127_setToStringTag(Math, 'Math', true);
5128// 24.3.3 JSON[@@toStringTag]
5129_setToStringTag(_global.JSON, 'JSON', true);
5130
5131_wksDefine('asyncIterator');
5132
5133_wksDefine('observable');
5134
5135var index = _core.Symbol;
5136
5137var symbol = createCommonjsModule(function (module) {
5138module.exports = { "default": index, __esModule: true };
5139});
5140
5141var _typeof_1 = createCommonjsModule(function (module, exports) {
5142"use strict";
5143
5144exports.__esModule = true;
5145
5146
5147
5148var _iterator2 = _interopRequireDefault(iterator);
5149
5150
5151
5152var _symbol2 = _interopRequireDefault(symbol);
5153
5154var _typeof = typeof _symbol2.default === "function" && typeof _iterator2.default === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof _symbol2.default === "function" && obj.constructor === _symbol2.default && obj !== _symbol2.default.prototype ? "symbol" : typeof obj; };
5155
5156function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
5157
5158exports.default = typeof _symbol2.default === "function" && _typeof(_iterator2.default) === "symbol" ? function (obj) {
5159 return typeof obj === "undefined" ? "undefined" : _typeof(obj);
5160} : function (obj) {
5161 return obj && typeof _symbol2.default === "function" && obj.constructor === _symbol2.default && obj !== _symbol2.default.prototype ? "symbol" : typeof obj === "undefined" ? "undefined" : _typeof(obj);
5162};
5163});
5164
5165var _typeof = unwrapExports(_typeof_1);
5166
5167// most Object methods by ES6 should accept primitives
5168
5169var _objectSap = function(KEY, exec){
5170 var fn = (_core.Object || {})[KEY] || Object[KEY]
5171 , exp = {};
5172 exp[KEY] = exec(fn);
5173 _export(_export.S + _export.F * _fails(function(){ fn(1); }), 'Object', exp);
5174};
5175
5176// 19.1.2.14 Object.keys(O)
5177
5178
5179_objectSap('keys', function(){
5180 return function keys(it){
5181 return _objectKeys(_toObject(it));
5182 };
5183});
5184
5185var keys$1 = _core.Object.keys;
5186
5187var keys = createCommonjsModule(function (module) {
5188module.exports = { "default": keys$1, __esModule: true };
5189});
5190
5191var _Object$keys = unwrapExports(keys);
5192
5193// 20.1.2.3 Number.isInteger(number)
5194var floor$1 = Math.floor;
5195var _isInteger = function isInteger(it){
5196 return !_isObject(it) && isFinite(it) && floor$1(it) === it;
5197};
5198
5199// 20.1.2.3 Number.isInteger(number)
5200
5201
5202_export(_export.S, 'Number', {isInteger: _isInteger});
5203
5204var isInteger$2 = _core.Number.isInteger;
5205
5206var isInteger$1 = createCommonjsModule(function (module) {
5207module.exports = { "default": isInteger$2, __esModule: true };
5208});
5209
5210var _Number$isInteger = unwrapExports(isInteger$1);
5211
5212var _stringWs = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
5213 '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';
5214
5215var space = '[' + _stringWs + ']';
5216var non = '\u200b\u0085';
5217var ltrim = RegExp('^' + space + space + '*');
5218var rtrim = RegExp(space + space + '*$');
5219
5220var exporter = function(KEY, exec, ALIAS){
5221 var exp = {};
5222 var FORCE = _fails(function(){
5223 return !!_stringWs[KEY]() || non[KEY]() != non;
5224 });
5225 var fn = exp[KEY] = FORCE ? exec(trim) : _stringWs[KEY];
5226 if(ALIAS)exp[ALIAS] = fn;
5227 _export(_export.P + _export.F * FORCE, 'String', exp);
5228};
5229
5230// 1 -> String#trimLeft
5231// 2 -> String#trimRight
5232// 3 -> String#trim
5233var trim = exporter.trim = function(string, TYPE){
5234 string = String(_defined(string));
5235 if(TYPE & 1)string = string.replace(ltrim, '');
5236 if(TYPE & 2)string = string.replace(rtrim, '');
5237 return string;
5238};
5239
5240var _stringTrim = exporter;
5241
5242var $parseFloat = _global.parseFloat;
5243var $trim = _stringTrim.trim;
5244
5245var _parseFloat$3 = 1 / $parseFloat(_stringWs + '-0') !== -Infinity ? function parseFloat(str){
5246 var string = $trim(String(str), 3)
5247 , result = $parseFloat(string);
5248 return result === 0 && string.charAt(0) == '-' ? -0 : result;
5249} : $parseFloat;
5250
5251// 20.1.2.12 Number.parseFloat(string)
5252_export(_export.S + _export.F * (Number.parseFloat != _parseFloat$3), 'Number', {parseFloat: _parseFloat$3});
5253
5254var _parseFloat$1 = parseFloat;
5255
5256var _parseFloat = createCommonjsModule(function (module) {
5257module.exports = { "default": _parseFloat$1, __esModule: true };
5258});
5259
5260var _Number$parseFloat = unwrapExports(_parseFloat);
5261
5262/**
5263 * toxic-predicate-functions v0.1.2
5264 * (c) 2017 toxic-johann
5265 * Released under MIT
5266 */
5267
5268/**
5269 * is void element or not ? Means it will return true when val is undefined or null
5270 * @param {Anything} obj
5271 * @return {Boolean} return true when val is undefined or null
5272 */
5273function isVoid(obj) {
5274 return obj === undefined || obj === null;
5275}
5276/**
5277 * to check whether a variable is array
5278 * @param {Anything} arr
5279 * @return {Boolean} true when it is a boolean
5280 */
5281function isArray(arr) {
5282 return Array.isArray(arr);
5283}
5284
5285/**
5286 * 判断是否为function
5287 * @param {Anything} obj [description]
5288 * @return {Boolean} [description]
5289 */
5290function isFunction(obj) {
5291 return typeof obj === 'function';
5292}
5293
5294/**
5295 * 判断是否是对象
5296 * @param {Anything} obj 传入对象
5297 * @return {Boolean} [description]
5298 */
5299function isObject$1(obj) {
5300 // incase of arrow function and array
5301 return Object(obj) === obj && String(obj) === '[object Object]' && !isFunction(obj) && !isArray(obj);
5302}
5303/**
5304 * to tell you if it's a real number
5305 * @param {Anything} obj
5306 * @return {Boolean} return true when it's a number
5307 */
5308function isNumber(obj) {
5309 return typeof obj === 'number';
5310}
5311/**
5312 * to tell you if the val can be transfer into data
5313 * @param {Anything} obj [description]
5314 * @return {Boolean} [description]
5315 */
5316function isNumeric(obj) {
5317 return !isArray(obj) && obj - _Number$parseFloat(obj) + 1 >= 0;
5318}
5319/**
5320 * 判断是否为整数
5321 * @param {Anything} obj [description]
5322 * @return {Boolean} [description]
5323 */
5324function isInteger(num) {
5325 return _Number$isInteger(num);
5326}
5327
5328/**
5329 * 判断是否为空
5330 * @param {Anything} obj [description]
5331 * @return {Boolean} [description]
5332 * @example
5333 * "", {}, [], 0, null, undefined, false 为空
5334 */
5335function isEmpty(obj) {
5336 if (isArray(obj)) {
5337 return obj.length === 0;
5338 } else if (isObject$1(obj)) {
5339 return _Object$keys(obj).length === 0;
5340 } else {
5341 return !obj;
5342 }
5343}
5344/**
5345 * 判断是否为事件
5346 * @param {Anything} obj [description]
5347 * @return {Boolean} [description]
5348 */
5349function isEvent(obj) {
5350 return obj instanceof Event || obj.originalEvent instanceof Event;
5351}
5352/**
5353 * 判断是否为blob
5354 * @param {Anything} obj [description]
5355 * @return {Boolean} [description]
5356 */
5357function isBlob(obj) {
5358 return obj instanceof Blob;
5359}
5360/**
5361 * 判断是否为file上传的文件
5362 * @param {Anything} obj [description]
5363 * @return {Boolean} [description]
5364 */
5365function isFile(obj) {
5366 return isBlob(obj) && isString(obj.name);
5367}
5368/**
5369 * 判断是否为日期对象
5370 * @param {Anything} obj [description]
5371 * @return {Boolean} [description]
5372 */
5373function isDate(obj) {
5374 return Object.prototype.toString.call(obj) === '[object Date]';
5375}
5376/**
5377 * 判断是否是string
5378 * @param {Anything} str [description]
5379 * @return {Boolean} [description]
5380 */
5381function isString(str) {
5382 return typeof str === 'string' || str instanceof String;
5383}
5384/**
5385 * is Boolean or not
5386 * @param {Anything} bool
5387 * @return {Boolean}
5388 */
5389function isBoolean(bool) {
5390 return typeof bool === 'boolean';
5391}
5392/**
5393 * is a promise or not
5394 * @param {Anything} obj
5395 * @return {boolean}
5396 */
5397function isPromise(obj) {
5398 return !!obj && ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
5399}
5400/**
5401 * is Primitive type or not, whick means it will return true when data is number/string/boolean/undefined/null
5402 * @param {Anyting} val
5403 * @return {Boolean} true when type is number/string/boolean/undefined/null
5404 */
5405function isPrimitive(val) {
5406 return isVoid(val) || isBoolean(val) || isString(val) || isNumber(val);
5407}
5408/**
5409 * 判断是否为url且必须要带有协议头
5410 * @param {Anything} str [description]
5411 * @return {Boolean} [description]
5412 */
5413function isUrl(str) {
5414 return isString(str) && !!str.match(/^((https?|ftp|rtsp|mms):\/\/)(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?(([0-9]{1,3}\.){3}[0-9]{1,3}|([0-9a-z_!~*'()-]+\.)*([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\.[a-z]{2,6}|localhost)(:[0-9]{1,4})?((\/?)|(\/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+\/?)$/i);
5415}
5416/**
5417 * to test if a HTML node
5418 * @param {Anything} obj [description]
5419 * @return {Boolean} [description]
5420 */
5421function isNode(obj) {
5422 return !!((typeof Node === 'undefined' ? 'undefined' : _typeof(Node)) === 'object' ? obj instanceof Node : obj && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && typeof obj.nodeType === 'number' && typeof obj.nodeName === 'string');
5423}
5424/**
5425 * to test if a HTML element
5426 * @param {Anything} obj [description]
5427 * @return {Boolean} [description]
5428 */
5429function isElement(obj) {
5430 return !!((typeof HTMLElement === 'undefined' ? 'undefined' : _typeof(HTMLElement)) === 'object' ? obj instanceof HTMLElement : obj && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && obj !== null && obj.nodeType === 1 && typeof obj.nodeName === 'string');
5431}
5432/**
5433 * check if node A is node B's parent or not
5434 * @param {Node} parent
5435 * @param {Node} child
5436 * @return {Boolean}
5437 */
5438function isChildNode(parent, child) {
5439 if (!isNode(parent) || !isNode(child)) {
5440 return false;
5441 }
5442 return child.parentNode === parent;
5443}
5444/**
5445 * check if node B is node A's posterrity or not
5446 * @param {Node} parent
5447 * @param {Node} child
5448 * @return {Boolean}
5449 */
5450function isPosterityNode(parent, child) {
5451 if (!isNode(parent) || !isNode(child)) {
5452 return false;
5453 }
5454 while (child.parentNode) {
5455 child = child.parentNode;
5456 if (child === parent) {
5457 return true;
5458 }
5459 }
5460 return false;
5461}
5462/**
5463 * check if the string is an HTMLString
5464 * @param {string} str only accept string
5465 * @return {Boolean}
5466 */
5467function isHTMLString(str) {
5468 return (/<[^>]+?>/.test(str)
5469 );
5470}
5471/**
5472 * check if is an error
5473 * @param {anything} val
5474 * @return {boolean}
5475 */
5476function isError(val) {
5477 return val instanceof Error;
5478}
5479
5480/**
5481 * toxic-utils v0.1.3
5482 * (c) 2017 toxic-johann
5483 * Released under MIT
5484 */
5485
5486/**
5487 * 生成深度遍历函数的处理器,常用于生成深度拷贝等
5488 * @param {Function} fn 遍历到深度变量的时候的操作
5489 * @return {Function} 可用的操作函数
5490 */
5491function genTraversalHandler(fn) {
5492 function recursiveFn(source, target, key) {
5493 if (isArray(source) || isObject$1(source)) {
5494 target = target || (isObject$1(source) ? {} : []);
5495 for (var _key in source) {
5496 target[_key] = recursiveFn(source[_key], target[_key], _key);
5497 }
5498 return target;
5499 }
5500 return fn(source, target, key);
5501 }
5502 return recursiveFn;
5503}
5504var _deepAssign = genTraversalHandler(function (val) {
5505 return val;
5506});
5507/**
5508 * 对象克隆
5509 * @param {Array|Object} source 传其他值会直接返回
5510 * @return {clone-target} [description]
5511 */
5512function deepClone(source) {
5513 if (isPrimitive(source)) {
5514 throw new TypeError('deepClone only accept non primitive type');
5515 }
5516 return _deepAssign(source);
5517}
5518/**
5519 * merge multiple objects
5520 * @param {...Object} args [description]
5521 * @return {merge-object} [description]
5522 */
5523function deepAssign() {
5524 for (var _len = arguments.length, args = Array(_len), _key2 = 0; _key2 < _len; _key2++) {
5525 args[_key2] = arguments[_key2];
5526 }
5527
5528 if (args.length < 2) {
5529 throw new Error('deepAssign accept two and more argument');
5530 }
5531 for (var i = args.length - 1; i > -1; i--) {
5532 if (isPrimitive(args[i])) {
5533 throw new TypeError('deepAssign only accept non primitive type');
5534 }
5535 }
5536 var target = args.shift();
5537 args.forEach(function (source) {
5538 return _deepAssign(source, target);
5539 });
5540 return target;
5541}
5542
5543/**
5544 * camelize any string, e.g hello world -> helloWorld
5545 * @param {string} str only accept string!
5546 * @return {string} camelize string
5547 */
5548function camelize(str, isBig) {
5549 return str.replace(/(^|[^a-zA-Z]+)([a-zA-Z])/g, function (match, spilt, initials, index) {
5550 return !isBig && index === 0 ? initials.toLowerCase() : initials.toUpperCase();
5551 });
5552}
5553/**
5554 * hypenate any string e.g hello world -> hello-world
5555 * @param {string} str only accept string
5556 * @return {string}
5557 */
5558function hypenate(str) {
5559 return camelize(str).replace(/([A-Z])/g, function (match) {
5560 return '-' + match.toLowerCase();
5561 });
5562}
5563
5564/**
5565 * bind the function with some context. we have some fallback strategy here
5566 * @param {function} fn the function which we need to bind the context on
5567 * @param {any} context the context object
5568 */
5569function bind(fn, context) {
5570 if (fn.bind) {
5571 return fn.bind(context);
5572 } else if (fn.apply) {
5573 return function __autobind__() {
5574 for (var _len2 = arguments.length, args = Array(_len2), _key3 = 0; _key3 < _len2; _key3++) {
5575 args[_key3] = arguments[_key3];
5576 }
5577
5578 return fn.apply(context, args);
5579 };
5580 } else {
5581 return function __autobind__() {
5582 for (var _len3 = arguments.length, args = Array(_len3), _key4 = 0; _key4 < _len3; _key4++) {
5583 args[_key4] = arguments[_key4];
5584 }
5585
5586 return fn.call.apply(fn, [context].concat(_toConsumableArray(args)));
5587 };
5588 }
5589}
5590
5591// ********************** 计算类 ************************
5592// 计算获取某种东西或者计算出某种东西
5593// ********************************************************
5594// 生成uuid
5595function uuid() {
5596 return S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4();
5597}
5598// 生成四个随机数
5599function S4() {
5600 return ((1 + Math.random()) * 0x10000 | 0).toString(16).substring(1);
5601}
5602// 生成任意长度的随机数
5603function rand(length) {
5604 var str = '';
5605 while (str.length < length) {
5606 str += S4();
5607 }
5608 return str.slice(0, length);
5609}
5610
5611// 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes)
5612_export(_export.S + _export.F * !_descriptors, 'Object', {defineProperty: _objectDp.f});
5613
5614var $Object = _core.Object;
5615var defineProperty$2 = function defineProperty(it, key, desc){
5616 return $Object.defineProperty(it, key, desc);
5617};
5618
5619var defineProperty$1 = createCommonjsModule(function (module) {
5620module.exports = { "default": defineProperty$2, __esModule: true };
5621});
5622
5623var _Object$defineProperty = unwrapExports(defineProperty$1);
5624
5625var _anInstance = function(it, Constructor, name, forbiddenField){
5626 if(!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)){
5627 throw TypeError(name + ': incorrect invocation!');
5628 } return it;
5629};
5630
5631var _forOf = createCommonjsModule(function (module) {
5632var BREAK = {}
5633 , RETURN = {};
5634var exports = module.exports = function(iterable, entries, fn, that, ITERATOR){
5635 var iterFn = ITERATOR ? function(){ return iterable; } : core_getIteratorMethod(iterable)
5636 , f = _ctx(fn, that, entries ? 2 : 1)
5637 , index = 0
5638 , length, step, iterator, result;
5639 if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!');
5640 // fast case for arrays with default iterator
5641 if(_isArrayIter(iterFn))for(length = _toLength(iterable.length); length > index; index++){
5642 result = entries ? f(_anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
5643 if(result === BREAK || result === RETURN)return result;
5644 } else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){
5645 result = _iterCall(iterator, f, step.value, entries);
5646 if(result === BREAK || result === RETURN)return result;
5647 }
5648};
5649exports.BREAK = BREAK;
5650exports.RETURN = RETURN;
5651});
5652
5653// 7.3.20 SpeciesConstructor(O, defaultConstructor)
5654var SPECIES = _wks('species');
5655var _speciesConstructor = function(O, D){
5656 var C = _anObject(O).constructor, S;
5657 return C === undefined || (S = _anObject(C)[SPECIES]) == undefined ? D : _aFunction(S);
5658};
5659
5660// fast apply, http://jsperf.lnkit.com/fast-apply/5
5661var _invoke = function(fn, args, that){
5662 var un = that === undefined;
5663 switch(args.length){
5664 case 0: return un ? fn()
5665 : fn.call(that);
5666 case 1: return un ? fn(args[0])
5667 : fn.call(that, args[0]);
5668 case 2: return un ? fn(args[0], args[1])
5669 : fn.call(that, args[0], args[1]);
5670 case 3: return un ? fn(args[0], args[1], args[2])
5671 : fn.call(that, args[0], args[1], args[2]);
5672 case 4: return un ? fn(args[0], args[1], args[2], args[3])
5673 : fn.call(that, args[0], args[1], args[2], args[3]);
5674 } return fn.apply(that, args);
5675};
5676
5677var process$1 = _global.process;
5678var setTask = _global.setImmediate;
5679var clearTask = _global.clearImmediate;
5680var MessageChannel = _global.MessageChannel;
5681var counter = 0;
5682var queue = {};
5683var ONREADYSTATECHANGE = 'onreadystatechange';
5684var defer;
5685var channel;
5686var port;
5687var run = function(){
5688 var id = +this;
5689 if(queue.hasOwnProperty(id)){
5690 var fn = queue[id];
5691 delete queue[id];
5692 fn();
5693 }
5694};
5695var listener = function(event){
5696 run.call(event.data);
5697};
5698// Node.js 0.9+ & IE10+ has setImmediate, otherwise:
5699if(!setTask || !clearTask){
5700 setTask = function setImmediate(fn){
5701 var args = [], i = 1;
5702 while(arguments.length > i)args.push(arguments[i++]);
5703 queue[++counter] = function(){
5704 _invoke(typeof fn == 'function' ? fn : Function(fn), args);
5705 };
5706 defer(counter);
5707 return counter;
5708 };
5709 clearTask = function clearImmediate(id){
5710 delete queue[id];
5711 };
5712 // Node.js 0.8-
5713 if(_cof(process$1) == 'process'){
5714 defer = function(id){
5715 process$1.nextTick(_ctx(run, id, 1));
5716 };
5717 // Browsers with MessageChannel, includes WebWorkers
5718 } else if(MessageChannel){
5719 channel = new MessageChannel;
5720 port = channel.port2;
5721 channel.port1.onmessage = listener;
5722 defer = _ctx(port.postMessage, port, 1);
5723 // Browsers with postMessage, skip WebWorkers
5724 // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
5725 } else if(_global.addEventListener && typeof postMessage == 'function' && !_global.importScripts){
5726 defer = function(id){
5727 _global.postMessage(id + '', '*');
5728 };
5729 _global.addEventListener('message', listener, false);
5730 // IE8-
5731 } else if(ONREADYSTATECHANGE in _domCreate('script')){
5732 defer = function(id){
5733 _html.appendChild(_domCreate('script'))[ONREADYSTATECHANGE] = function(){
5734 _html.removeChild(this);
5735 run.call(id);
5736 };
5737 };
5738 // Rest old browsers
5739 } else {
5740 defer = function(id){
5741 setTimeout(_ctx(run, id, 1), 0);
5742 };
5743 }
5744}
5745var _task = {
5746 set: setTask,
5747 clear: clearTask
5748};
5749
5750var macrotask = _task.set;
5751var Observer = _global.MutationObserver || _global.WebKitMutationObserver;
5752var process$2 = _global.process;
5753var Promise = _global.Promise;
5754var isNode$2 = _cof(process$2) == 'process';
5755
5756var _microtask = function(){
5757 var head, last, notify;
5758
5759 var flush = function(){
5760 var parent, fn;
5761 if(isNode$2 && (parent = process$2.domain))parent.exit();
5762 while(head){
5763 fn = head.fn;
5764 head = head.next;
5765 try {
5766 fn();
5767 } catch(e){
5768 if(head)notify();
5769 else last = undefined;
5770 throw e;
5771 }
5772 } last = undefined;
5773 if(parent)parent.enter();
5774 };
5775
5776 // Node.js
5777 if(isNode$2){
5778 notify = function(){
5779 process$2.nextTick(flush);
5780 };
5781 // browsers with MutationObserver
5782 } else if(Observer){
5783 var toggle = true
5784 , node = document.createTextNode('');
5785 new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new
5786 notify = function(){
5787 node.data = toggle = !toggle;
5788 };
5789 // environments with maybe non-completely correct, but existent Promise
5790 } else if(Promise && Promise.resolve){
5791 var promise = Promise.resolve();
5792 notify = function(){
5793 promise.then(flush);
5794 };
5795 // for other environments - macrotask based on:
5796 // - setImmediate
5797 // - MessageChannel
5798 // - window.postMessag
5799 // - onreadystatechange
5800 // - setTimeout
5801 } else {
5802 notify = function(){
5803 // strange IE + webpack dev server bug - use .call(global)
5804 macrotask.call(_global, flush);
5805 };
5806 }
5807
5808 return function(fn){
5809 var task = {fn: fn, next: undefined};
5810 if(last)last.next = task;
5811 if(!head){
5812 head = task;
5813 notify();
5814 } last = task;
5815 };
5816};
5817
5818var _redefineAll = function(target, src, safe){
5819 for(var key in src){
5820 if(safe && target[key])target[key] = src[key];
5821 else _hide(target, key, src[key]);
5822 } return target;
5823};
5824
5825var SPECIES$1 = _wks('species');
5826
5827var _setSpecies = function(KEY){
5828 var C = typeof _core[KEY] == 'function' ? _core[KEY] : _global[KEY];
5829 if(_descriptors && C && !C[SPECIES$1])_objectDp.f(C, SPECIES$1, {
5830 configurable: true,
5831 get: function(){ return this; }
5832 });
5833};
5834
5835var task = _task.set;
5836var microtask = _microtask();
5837var PROMISE = 'Promise';
5838var TypeError$1 = _global.TypeError;
5839var process = _global.process;
5840var $Promise = _global[PROMISE];
5841var process = _global.process;
5842var isNode$1 = _classof(process) == 'process';
5843var empty = function(){ /* empty */ };
5844var Internal;
5845var GenericPromiseCapability;
5846var Wrapper;
5847
5848var USE_NATIVE$1 = !!function(){
5849 try {
5850 // correct subclassing with @@species support
5851 var promise = $Promise.resolve(1)
5852 , FakePromise = (promise.constructor = {})[_wks('species')] = function(exec){ exec(empty, empty); };
5853 // unhandled rejections tracking support, NodeJS Promise without it fails @@species test
5854 return (isNode$1 || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise;
5855 } catch(e){ /* empty */ }
5856}();
5857
5858// helpers
5859var sameConstructor = function(a, b){
5860 // with library wrapper special case
5861 return a === b || a === $Promise && b === Wrapper;
5862};
5863var isThenable = function(it){
5864 var then;
5865 return _isObject(it) && typeof (then = it.then) == 'function' ? then : false;
5866};
5867var newPromiseCapability = function(C){
5868 return sameConstructor($Promise, C)
5869 ? new PromiseCapability(C)
5870 : new GenericPromiseCapability(C);
5871};
5872var PromiseCapability = GenericPromiseCapability = function(C){
5873 var resolve, reject;
5874 this.promise = new C(function($$resolve, $$reject){
5875 if(resolve !== undefined || reject !== undefined)throw TypeError$1('Bad Promise constructor');
5876 resolve = $$resolve;
5877 reject = $$reject;
5878 });
5879 this.resolve = _aFunction(resolve);
5880 this.reject = _aFunction(reject);
5881};
5882var perform = function(exec){
5883 try {
5884 exec();
5885 } catch(e){
5886 return {error: e};
5887 }
5888};
5889var notify = function(promise, isReject){
5890 if(promise._n)return;
5891 promise._n = true;
5892 var chain = promise._c;
5893 microtask(function(){
5894 var value = promise._v
5895 , ok = promise._s == 1
5896 , i = 0;
5897 var run = function(reaction){
5898 var handler = ok ? reaction.ok : reaction.fail
5899 , resolve = reaction.resolve
5900 , reject = reaction.reject
5901 , domain = reaction.domain
5902 , result, then;
5903 try {
5904 if(handler){
5905 if(!ok){
5906 if(promise._h == 2)onHandleUnhandled(promise);
5907 promise._h = 1;
5908 }
5909 if(handler === true)result = value;
5910 else {
5911 if(domain)domain.enter();
5912 result = handler(value);
5913 if(domain)domain.exit();
5914 }
5915 if(result === reaction.promise){
5916 reject(TypeError$1('Promise-chain cycle'));
5917 } else if(then = isThenable(result)){
5918 then.call(result, resolve, reject);
5919 } else resolve(result);
5920 } else reject(value);
5921 } catch(e){
5922 reject(e);
5923 }
5924 };
5925 while(chain.length > i)run(chain[i++]); // variable length - can't use forEach
5926 promise._c = [];
5927 promise._n = false;
5928 if(isReject && !promise._h)onUnhandled(promise);
5929 });
5930};
5931var onUnhandled = function(promise){
5932 task.call(_global, function(){
5933 var value = promise._v
5934 , abrupt, handler, console;
5935 if(isUnhandled(promise)){
5936 abrupt = perform(function(){
5937 if(isNode$1){
5938 process.emit('unhandledRejection', value, promise);
5939 } else if(handler = _global.onunhandledrejection){
5940 handler({promise: promise, reason: value});
5941 } else if((console = _global.console) && console.error){
5942 console.error('Unhandled promise rejection', value);
5943 }
5944 });
5945 // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
5946 promise._h = isNode$1 || isUnhandled(promise) ? 2 : 1;
5947 } promise._a = undefined;
5948 if(abrupt)throw abrupt.error;
5949 });
5950};
5951var isUnhandled = function(promise){
5952 if(promise._h == 1)return false;
5953 var chain = promise._a || promise._c
5954 , i = 0
5955 , reaction;
5956 while(chain.length > i){
5957 reaction = chain[i++];
5958 if(reaction.fail || !isUnhandled(reaction.promise))return false;
5959 } return true;
5960};
5961var onHandleUnhandled = function(promise){
5962 task.call(_global, function(){
5963 var handler;
5964 if(isNode$1){
5965 process.emit('rejectionHandled', promise);
5966 } else if(handler = _global.onrejectionhandled){
5967 handler({promise: promise, reason: promise._v});
5968 }
5969 });
5970};
5971var $reject = function(value){
5972 var promise = this;
5973 if(promise._d)return;
5974 promise._d = true;
5975 promise = promise._w || promise; // unwrap
5976 promise._v = value;
5977 promise._s = 2;
5978 if(!promise._a)promise._a = promise._c.slice();
5979 notify(promise, true);
5980};
5981var $resolve = function(value){
5982 var promise = this
5983 , then;
5984 if(promise._d)return;
5985 promise._d = true;
5986 promise = promise._w || promise; // unwrap
5987 try {
5988 if(promise === value)throw TypeError$1("Promise can't be resolved itself");
5989 if(then = isThenable(value)){
5990 microtask(function(){
5991 var wrapper = {_w: promise, _d: false}; // wrap
5992 try {
5993 then.call(value, _ctx($resolve, wrapper, 1), _ctx($reject, wrapper, 1));
5994 } catch(e){
5995 $reject.call(wrapper, e);
5996 }
5997 });
5998 } else {
5999 promise._v = value;
6000 promise._s = 1;
6001 notify(promise, false);
6002 }
6003 } catch(e){
6004 $reject.call({_w: promise, _d: false}, e); // wrap
6005 }
6006};
6007
6008// constructor polyfill
6009if(!USE_NATIVE$1){
6010 // 25.4.3.1 Promise(executor)
6011 $Promise = function Promise(executor){
6012 _anInstance(this, $Promise, PROMISE, '_h');
6013 _aFunction(executor);
6014 Internal.call(this);
6015 try {
6016 executor(_ctx($resolve, this, 1), _ctx($reject, this, 1));
6017 } catch(err){
6018 $reject.call(this, err);
6019 }
6020 };
6021 Internal = function Promise(executor){
6022 this._c = []; // <- awaiting reactions
6023 this._a = undefined; // <- checked in isUnhandled reactions
6024 this._s = 0; // <- state
6025 this._d = false; // <- done
6026 this._v = undefined; // <- value
6027 this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled
6028 this._n = false; // <- notify
6029 };
6030 Internal.prototype = _redefineAll($Promise.prototype, {
6031 // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)
6032 then: function then(onFulfilled, onRejected){
6033 var reaction = newPromiseCapability(_speciesConstructor(this, $Promise));
6034 reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
6035 reaction.fail = typeof onRejected == 'function' && onRejected;
6036 reaction.domain = isNode$1 ? process.domain : undefined;
6037 this._c.push(reaction);
6038 if(this._a)this._a.push(reaction);
6039 if(this._s)notify(this, false);
6040 return reaction.promise;
6041 },
6042 // 25.4.5.1 Promise.prototype.catch(onRejected)
6043 'catch': function(onRejected){
6044 return this.then(undefined, onRejected);
6045 }
6046 });
6047 PromiseCapability = function(){
6048 var promise = new Internal;
6049 this.promise = promise;
6050 this.resolve = _ctx($resolve, promise, 1);
6051 this.reject = _ctx($reject, promise, 1);
6052 };
6053}
6054
6055_export(_export.G + _export.W + _export.F * !USE_NATIVE$1, {Promise: $Promise});
6056_setToStringTag($Promise, PROMISE);
6057_setSpecies(PROMISE);
6058Wrapper = _core[PROMISE];
6059
6060// statics
6061_export(_export.S + _export.F * !USE_NATIVE$1, PROMISE, {
6062 // 25.4.4.5 Promise.reject(r)
6063 reject: function reject(r){
6064 var capability = newPromiseCapability(this)
6065 , $$reject = capability.reject;
6066 $$reject(r);
6067 return capability.promise;
6068 }
6069});
6070_export(_export.S + _export.F * (_library || !USE_NATIVE$1), PROMISE, {
6071 // 25.4.4.6 Promise.resolve(x)
6072 resolve: function resolve(x){
6073 // instanceof instead of internal slot check because we should fix it without replacement native Promise core
6074 if(x instanceof $Promise && sameConstructor(x.constructor, this))return x;
6075 var capability = newPromiseCapability(this)
6076 , $$resolve = capability.resolve;
6077 $$resolve(x);
6078 return capability.promise;
6079 }
6080});
6081_export(_export.S + _export.F * !(USE_NATIVE$1 && _iterDetect(function(iter){
6082 $Promise.all(iter)['catch'](empty);
6083})), PROMISE, {
6084 // 25.4.4.1 Promise.all(iterable)
6085 all: function all(iterable){
6086 var C = this
6087 , capability = newPromiseCapability(C)
6088 , resolve = capability.resolve
6089 , reject = capability.reject;
6090 var abrupt = perform(function(){
6091 var values = []
6092 , index = 0
6093 , remaining = 1;
6094 _forOf(iterable, false, function(promise){
6095 var $index = index++
6096 , alreadyCalled = false;
6097 values.push(undefined);
6098 remaining++;
6099 C.resolve(promise).then(function(value){
6100 if(alreadyCalled)return;
6101 alreadyCalled = true;
6102 values[$index] = value;
6103 --remaining || resolve(values);
6104 }, reject);
6105 });
6106 --remaining || resolve(values);
6107 });
6108 if(abrupt)reject(abrupt.error);
6109 return capability.promise;
6110 },
6111 // 25.4.4.4 Promise.race(iterable)
6112 race: function race(iterable){
6113 var C = this
6114 , capability = newPromiseCapability(C)
6115 , reject = capability.reject;
6116 var abrupt = perform(function(){
6117 _forOf(iterable, false, function(promise){
6118 C.resolve(promise).then(capability.resolve, reject);
6119 });
6120 });
6121 if(abrupt)reject(abrupt.error);
6122 return capability.promise;
6123 }
6124});
6125
6126var promise$1 = _core.Promise;
6127
6128var promise = createCommonjsModule(function (module) {
6129module.exports = { "default": promise$1, __esModule: true };
6130});
6131
6132var _Promise = unwrapExports(promise);
6133
6134/**
6135 * chimee-helper-utils v0.1.2
6136 * (c) 2017 toxic-johann
6137 * Released under MIT
6138 */
6139
6140// ********************** judgement ************************
6141/**
6142 * check if the code running in browser environment (not include worker env)
6143 * @returns {Boolean}
6144 */
6145var inBrowser = typeof window !== 'undefined' && Object.prototype.toString.call(window) !== '[object Object]';
6146
6147// ********************** 对象操作 ************************
6148/**
6149 * 转变一个类数组对象为数组
6150 */
6151function makeArray(obj) {
6152 return _Array$from(obj);
6153}
6154
6155/**
6156 * sort Object attributes by function
6157 * and transfer them into array
6158 * @param {Object} obj Object form from numric
6159 * @param {Function} fn sort function
6160 * @return {Array} the sorted attirbutes array
6161 */
6162function transObjectAttrIntoArray(obj) {
6163 var fn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (a, b) {
6164 return +a - +b;
6165 };
6166
6167 return _Object$keys(obj).sort(fn).reduce(function (order, key) {
6168 return order.concat(obj[key]);
6169 }, []);
6170}
6171// ********************** class operation ***************************
6172// class MixinBuilder {
6173// constructor (superclass) {
6174// this.superclass = superclass || class {};
6175// }
6176
6177// with (...mixins) {
6178// return mixins.reduce((c, mixin) => mixin(c), this.superclass);
6179// }
6180// }
6181// export const mix = (superclass) => {
6182// return new MixinBuilder(superclass);
6183// };
6184/**
6185 * run a queue one by one.If include function reject or return false it will stop
6186 * @param {Array} queue the queue which we want to run one by one
6187 * @return {Promise} tell us whether a queue run finished
6188 */
6189function runRejectableQueue(queue) {
6190 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
6191 args[_key - 1] = arguments[_key];
6192 }
6193
6194 return new _Promise(function (resolve, reject) {
6195 var step = function step(index) {
6196 if (index >= queue.length) {
6197 resolve();
6198 return;
6199 }
6200 var result = isFunction(queue[index]) ? queue[index].apply(queue, _toConsumableArray(args)) : queue[index];
6201 if (result === false) return reject('stop');
6202 return _Promise.resolve(result).then(function () {
6203 return step(index + 1);
6204 }).catch(function () {
6205 return reject('stop');
6206 });
6207 };
6208 step(0);
6209 });
6210}
6211/**
6212 * run a queue one by one.If include function return false it will stop
6213 * @param {Array} queue the queue which we want to run one by one
6214 * @return {boolean} tell the user if the queue run finished
6215 */
6216function runStoppableQueue(queue) {
6217 for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
6218 args[_key2 - 1] = arguments[_key2];
6219 }
6220
6221 var step = function step(index) {
6222 if (index >= queue.length) {
6223 return true;
6224 }
6225 var result = isFunction(queue[index]) ? queue[index].apply(queue, _toConsumableArray(args)) : queue[index];
6226 if (result === false) return false;
6227 return step(++index);
6228 };
6229 return step(0);
6230}
6231/**
6232 * set an attribute to an object which is frozen.
6233 * Means you can't remove it, iterate it or rewrite it.
6234 * @param {!primitive} obj
6235 * @param {string} key
6236 * @param {Anything} value
6237 */
6238function setFrozenAttr(obj, key, value) {
6239 if (isPrimitive(obj)) throw TypeError('setFrozenAttr obj parameter can not be primitive type');
6240 if (!isString(key)) throw TypeError('setFrozenAttr key parameter must be String');
6241 _Object$defineProperty(obj, key, {
6242 value: value,
6243 configurable: false,
6244 enumerable: false,
6245 writable: false
6246 });
6247}
6248/**
6249 * set attr on an Object. We will bind getter and setter on it if you provide to us
6250 * @param {!primitive} obj
6251 * @param {string} key
6252 * @param {Function} options.get
6253 * @param {Function} options.set
6254 * @param {String} prefix the origin data's prefix. We do not plan to save it by closure.
6255 */
6256function setAttrGetterAndSetter(obj, key) {
6257 var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
6258 get = _ref.get,
6259 set = _ref.set;
6260
6261 var prefix = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '__';
6262
6263 if (isPrimitive(obj)) throw TypeError('setFrozenAttr obj parameter can not be primitive type');
6264 if (!isString(key)) throw TypeError('setAttrGetterAndSetter key parameter must be String');
6265 var originalData = obj[key];
6266 if (!isFunction(get)) {
6267 _Object$defineProperty(obj, prefix + key, {
6268 value: originalData,
6269 configurable: true,
6270 writable: true,
6271 enumerable: false
6272 });
6273 get = function get() {
6274 return this[prefix + key];
6275 };
6276 if (set && isFunction(set)) {
6277 var originSetter = set;
6278 set = function set() {
6279 for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
6280 args[_key3] = arguments[_key3];
6281 }
6282
6283 this[prefix + key] = originSetter.call.apply(originSetter, [this].concat(args));
6284 };
6285 }
6286 }
6287 _Object$defineProperty(obj, key, { get: get, set: set });
6288}
6289
6290function checkContinuation(uint8array, start, checkLength) {
6291 var array = uint8array;
6292 if (start + checkLength < array.length) {
6293 while (checkLength--) {
6294 if ((array[++start] & 0xC0) !== 0x80) {
6295 return false;
6296 }
6297 }
6298 return true;
6299 } else {
6300 return false;
6301 }
6302}
6303
6304// decodeUTF8
6305function decodeUTF8(uint8array) {
6306 var out = [];
6307 var input = uint8array;
6308 var i = 0;
6309 var length = uint8array.length;
6310
6311 while (i < length) {
6312 if (input[i] < 0x80) {
6313 out.push(String.fromCharCode(input[i]));
6314 ++i;
6315 continue;
6316 } else if (input[i] < 0xC0) {
6317 // fallthrough
6318 } else if (input[i] < 0xE0) {
6319 if (checkContinuation(input, i, 1)) {
6320 var ucs4 = (input[i] & 0x1F) << 6 | input[i + 1] & 0x3F;
6321 if (ucs4 >= 0x80) {
6322 out.push(String.fromCharCode(ucs4 & 0xFFFF));
6323 i += 2;
6324 continue;
6325 }
6326 }
6327 } else if (input[i] < 0xF0) {
6328 if (checkContinuation(input, i, 2)) {
6329 var _ucs = (input[i] & 0xF) << 12 | (input[i + 1] & 0x3F) << 6 | input[i + 2] & 0x3F;
6330 if (_ucs >= 0x800 && (_ucs & 0xF800) !== 0xD800) {
6331 out.push(String.fromCharCode(_ucs & 0xFFFF));
6332 i += 3;
6333 continue;
6334 }
6335 }
6336 } else if (input[i] < 0xF8) {
6337 if (checkContinuation(input, i, 3)) {
6338 var _ucs2 = (input[i] & 0x7) << 18 | (input[i + 1] & 0x3F) << 12 | (input[i + 2] & 0x3F) << 6 | input[i + 3] & 0x3F;
6339 if (_ucs2 > 0x10000 && _ucs2 < 0x110000) {
6340 _ucs2 -= 0x10000;
6341 out.push(String.fromCharCode(_ucs2 >>> 10 | 0xD800));
6342 out.push(String.fromCharCode(_ucs2 & 0x3FF | 0xDC00));
6343 i += 4;
6344 continue;
6345 }
6346 }
6347 }
6348 out.push(String.fromCharCode(0xFFFD));
6349 ++i;
6350 }
6351 return out.join('');
6352}
6353
6354function debounce(func, wait, immediate) {
6355 // immediate默认为false
6356 var timeout = void 0,
6357 args = void 0,
6358 context = void 0,
6359 timestamp = void 0,
6360 result = void 0;
6361
6362 var later = function later() {
6363 // 当wait指定的时间间隔期间多次调用_.debounce返回的函数,则会不断更新timestamp的值,导致last < wait && last >= 0一直为true,从而不断启动新的计时器延时执行func
6364 var last = new Date() - timestamp;
6365
6366 if (last < wait && last >= 0) {
6367 timeout = setTimeout(later, wait - last);
6368 } else {
6369 timeout = null;
6370 if (!immediate) {
6371 result = func.apply(context, args);
6372 if (!timeout) context = args = null;
6373 }
6374 }
6375 };
6376
6377 return function () {
6378 context = this;
6379 args = arguments;
6380 timestamp = new Date();
6381 // 第一次调用该方法时,且immediate为true,则调用func函数
6382 var callNow = immediate && !timeout;
6383 // 在wait指定的时间间隔内首次调用该方法,则启动计时器定时调用func函数
6384 if (!timeout) timeout = setTimeout(later, wait);
6385 if (callNow) {
6386 result = func.apply(context, args);
6387 context = args = null;
6388 }
6389
6390 return result;
6391 };
6392}
6393
6394/**
6395 * 函数节流(控制函数执行频率)
6396 * @param {Function} func 要节流控制的函数,必填
6397 * @return {Number} wait 等待时长
6398 * @return {Object} options {
6399 * leading<是否首次调用立即执行,否:则按wait设定等待到期后调用才执行>:false,
6400 * trailing<是否在调用并未到期时启用定时器,以保证一定执行>:true
6401 * }
6402 * @return {Object} cxt 上下文对象
6403 * @return {Function}
6404 */
6405function throttle(func, wait, options, cxt) {
6406 /* options的默认值
6407 * 表示首次调用返回值方法时,会马上调用func;否则仅会记录当前时刻,当第二次调用的时间间隔超过wait时,才调用func。
6408 * options.leading = true;
6409 * 表示当调用方法时,未到达wait指定的时间间隔,则启动计时器延迟调用func函数,若后续在既未达到wait指定的时间间隔和func函数又未被调用的情况下调用返回值方法,则被调用请求将被丢弃。
6410 * options.trailing = true;
6411 * 注意:当options.trailing = false时,效果与上面的简单实现效果相同
6412 */
6413 var context = void 0,
6414 args = void 0,
6415 result = void 0;
6416 var timeout = null;
6417 var previous = 0;
6418 if (!options) options = {};
6419 var later = function later() {
6420 previous = options.leading === false ? 0 : new Date() - 0;
6421 timeout = null;
6422 result = func.apply(context, args);
6423 if (!timeout) context = args = null;
6424 };
6425 wait = wait || 0;
6426 return function () {
6427 var now = new Date();
6428 if (!previous && options.leading === false) previous = now;
6429 // 计算剩余时间
6430 var remaining = wait - (now - previous);
6431 if (cxt) {
6432 context = cxt;
6433 } else {
6434 context = this;
6435 }
6436
6437 args = arguments;
6438 // 当到达wait指定的时间间隔,则调用func函数
6439 // 精彩之处:按理来说remaining <= 0已经足够证明已经到达wait的时间间隔,但这里还考虑到假如客户端修改了系统时间则马上执行func函数。
6440 if (remaining <= 0 || remaining > wait) {
6441 // 由于setTimeout存在最小时间精度问题,因此会存在到达wait的时间间隔,但之前设置的setTimeout操作还没被执行,因此为保险起见,这里先清理setTimeout操作
6442 if (timeout) {
6443 clearTimeout(timeout);
6444 timeout = null;
6445 }
6446 previous = now;
6447 result = func.apply(context, args);
6448 if (!timeout) context = args = null;
6449 } else if (!timeout && options.trailing !== false) {
6450 // options.trailing=true时,延时执行func函数
6451 timeout = setTimeout(later, remaining);
6452 }
6453 return result;
6454 };
6455}
6456
6457// requestAnimationFrame
6458var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame || function (cb) {
6459 return setTimeout(cb, 17);
6460};
6461
6462// cancelAnimationFrame
6463var caf = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame || window.msCancelAnimationFrame || window.oCancelAnimationFrame || function (id) {
6464 clearTimeout(id);
6465};
6466
6467// 根据要求的位数,将9格式化为 09\009\0009...
6468function strRepeat(num, bit) {
6469 var pBit = bit;
6470 num = '' + (num || '');
6471 var numLen = num.length;
6472 bit = (bit || numLen) - numLen;
6473 var paddingStr = bit > 0 ? num.repeat ? '0'.repeat(bit) : new Array(bit + 1).join('0') : '';
6474 return (paddingStr + num).slice(0, pBit);
6475}
6476
6477// video 时间格式化
6478function formatTime(time) {
6479 var hh = Math.floor(time / 3600);
6480 time = Math.floor(time % 3600);
6481 var mm = strRepeat(Math.floor(time / 60), 2);
6482 time = Math.floor(time % 60);
6483 var ss = strRepeat(time, 2);
6484 return hh >= 1 ? hh + ':' + mm + ':' + ss : mm + ':' + ss;
6485}
6486
6487/**
6488 * 给obj对象扩展上trans方法,用以实现methodName对应的属性方法包装为静态函数且保持上下文的功能
6489 * @param {Object} obj 目标对象
6490 */
6491function addTransMethod(obj) {
6492 setFrozenAttr(obj, 'trans', function (methodName) {
6493 if (!obj.__fns) {
6494 setFrozenAttr(obj, '__fns', {});
6495 }
6496 if (!obj.__fns[methodName]) {
6497 obj.__fns[methodName] = function () {
6498 if (!isFunction(obj[methodName])) throw TypeError('obj.trans(methodName) parameter must be Function');
6499 return obj[methodName].apply(obj, arguments);
6500 };
6501 }
6502 return obj.__fns[methodName];
6503 });
6504}
6505
6506/**
6507 * 追加样式代码到head的style标签,不存在则创建
6508 * @param {String} cssText 样式文本
6509 * @return {HTMLElement}
6510 */
6511function appendCSS(cssText) {
6512 var doc = document;
6513 var styleEl = doc.querySelector('style');
6514 if (!styleEl) {
6515 styleEl = doc.createElement('style');
6516 var header = doc.querySelector('head');
6517 header && header.appendChild(styleEl);
6518 }
6519 styleEl.appendChild(doc.createTextNode(cssText));
6520 return styleEl;
6521}
6522
6523/**
6524 * 格式化日期对象为:年-月-日 时:分:秒.毫秒
6525 * @param {Date} date Date日期对象
6526 * @param {String} pattern 要输出的日期格式,默认:`yyyy-MM-dd hh:mm:ss.i`
6527 * @return {String}
6528 */
6529function formatDate() {
6530 var date = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Date();
6531 var pattern = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'yyyy-MM-dd hh:mm:ss.i';
6532
6533 var year = date.getFullYear().toString();
6534 var fields = {
6535 M: date.getMonth() + 1,
6536 d: date.getDate(),
6537 h: date.getHours(),
6538 m: date.getMinutes(),
6539 s: date.getSeconds(),
6540 i: date.getMilliseconds()
6541 };
6542 pattern = pattern.replace(/(y+)/ig, function (_, yearPattern) {
6543 return year.substr(4 - Math.min(4, yearPattern.length));
6544 });
6545
6546 var _loop = function _loop(i) {
6547 pattern = pattern.replace(new RegExp('(' + i + '+)', 'g'), function (_, pattStr) {
6548 return (fields[i] < 10 && pattStr.length > 1 ? '0' : '') + fields[i];
6549 });
6550 };
6551
6552 for (var i in fields) {
6553 _loop(i);
6554 }
6555 return pattern;
6556}
6557
6558/**
6559 * 读取本地存储的值(不支持localStorage则降级到cookie)
6560 * @param {String} key 目标数据key
6561 * @return {String}
6562 */
6563function getLocalStorage(key) {
6564 try {
6565 return window.localStorage.getItem(key);
6566 } catch (e) {
6567 try {
6568 var regRt = document.cookie.match(new RegExp('(^| )' + key + '=([^;]*)(;|$)'));
6569 return isArray(regRt) ? unescape(regRt[2]) : '';
6570 } catch (e) {
6571 return '';
6572 }
6573 }
6574}
6575/**
6576 * 将指定key对应值写入本地存储(不支持localStorage则降级到cookie)
6577 * @param {String} key
6578 * @param {String} val
6579 * @return {String}
6580 */
6581function setLocalStorage(key, val) {
6582 try {
6583 window.localStorage.setItem(key, val);
6584 } catch (e) {
6585 var expires = new Date();
6586 // 默认存储300天
6587 expires.setTime(expires.getTime() + 24 * 3600 * 1000 * 300);
6588 try {
6589 document.cookie = key + '=' + escape(val) + ';expires=' + expires.toUTCString() + ';path=/;';
6590 } catch (e) {}
6591 }
6592}
6593
6594var classCallCheck = createCommonjsModule(function (module, exports) {
6595"use strict";
6596
6597exports.__esModule = true;
6598
6599exports.default = function (instance, Constructor) {
6600 if (!(instance instanceof Constructor)) {
6601 throw new TypeError("Cannot call a class as a function");
6602 }
6603};
6604});
6605
6606var _classCallCheck = unwrapExports(classCallCheck);
6607
6608var createClass = createCommonjsModule(function (module, exports) {
6609"use strict";
6610
6611exports.__esModule = true;
6612
6613
6614
6615var _defineProperty2 = _interopRequireDefault(defineProperty$1);
6616
6617function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6618
6619exports.default = function () {
6620 function defineProperties(target, props) {
6621 for (var i = 0; i < props.length; i++) {
6622 var descriptor = props[i];
6623 descriptor.enumerable = descriptor.enumerable || false;
6624 descriptor.configurable = true;
6625 if ("value" in descriptor) descriptor.writable = true;
6626 (0, _defineProperty2.default)(target, descriptor.key, descriptor);
6627 }
6628 }
6629
6630 return function (Constructor, protoProps, staticProps) {
6631 if (protoProps) defineProperties(Constructor.prototype, protoProps);
6632 if (staticProps) defineProperties(Constructor, staticProps);
6633 return Constructor;
6634 };
6635}();
6636});
6637
6638var _createClass = unwrapExports(createClass);
6639
6640// 19.1.2.1 Object.assign(target, source, ...)
6641var $assign = Object.assign;
6642
6643// should work with symbols and should have deterministic property order (V8 bug)
6644var _objectAssign = !$assign || _fails(function(){
6645 var A = {}
6646 , B = {}
6647 , S = Symbol()
6648 , K = 'abcdefghijklmnopqrst';
6649 A[S] = 7;
6650 K.split('').forEach(function(k){ B[k] = k; });
6651 return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;
6652}) ? function assign(target, source){ // eslint-disable-line no-unused-vars
6653 var T = _toObject(target)
6654 , aLen = arguments.length
6655 , index = 1
6656 , getSymbols = _objectGops.f
6657 , isEnum = _objectPie.f;
6658 while(aLen > index){
6659 var S = _iobject(arguments[index++])
6660 , keys = getSymbols ? _objectKeys(S).concat(getSymbols(S)) : _objectKeys(S)
6661 , length = keys.length
6662 , j = 0
6663 , key;
6664 while(length > j)if(isEnum.call(S, key = keys[j++]))T[key] = S[key];
6665 } return T;
6666} : $assign;
6667
6668// 19.1.3.1 Object.assign(target, source)
6669
6670
6671_export(_export.S + _export.F, 'Object', {assign: _objectAssign});
6672
6673var assign$1 = _core.Object.assign;
6674
6675var assign = createCommonjsModule(function (module) {
6676module.exports = { "default": assign$1, __esModule: true };
6677});
6678
6679var _Object$assign = unwrapExports(assign);
6680
6681// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
6682_export(_export.S, 'Object', {create: _objectCreate});
6683
6684var $Object$1 = _core.Object;
6685var create$1 = function create(P, D){
6686 return $Object$1.create(P, D);
6687};
6688
6689var create = createCommonjsModule(function (module) {
6690module.exports = { "default": create$1, __esModule: true };
6691});
6692
6693var _Object$create = unwrapExports(create);
6694
6695/**
6696 * chimee-helper-events v0.1.0
6697 * (c) 2017 toxic-johann
6698 * Released under MIT
6699 */
6700
6701/**
6702* @module event
6703* @author huzunjie
6704* @description 自定义事件基础类
6705*/
6706
6707/* 缓存事件监听方法及包装,内部数据格式:
6708 * targetIndex_<type:'click|mouseup|done'>: [ [
6709 * function(){ ... handler ... },
6710 * function(){ ... handlerWrap ... handler.apply(target, arguments) ... },
6711 * isOnce
6712 * ]]
6713 */
6714var _evtListenerCache = _Object$create(null);
6715_evtListenerCache.count = 0;
6716
6717/**
6718 * 得到某对象的某事件类型对应的监听队列数组
6719 * @param {Object} target 发生事件的对象
6720 * @param {String} type 事件类型(这里的时间类型不只是名称,还是缓存标识,可以通过添加后缀来区分)
6721 * @return {Array}
6722 */
6723function getEvtTypeCache(target, type) {
6724
6725 var evtId = target.__evt_id;
6726 if (!evtId) {
6727
6728 /* 设置__evt_id不可枚举 */
6729 Object.defineProperty(target, '__evt_id', {
6730 writable: true,
6731 enumerable: false,
6732 configurable: true
6733 });
6734
6735 /* 空对象初始化绑定索引 */
6736 evtId = target.__evt_id = ++_evtListenerCache.count;
6737 }
6738
6739 var typeCacheKey = evtId + '_' + type;
6740 var evtTypeCache = _evtListenerCache[typeCacheKey];
6741 if (!evtTypeCache) {
6742 evtTypeCache = _evtListenerCache[typeCacheKey] = [];
6743 }
6744
6745 return evtTypeCache;
6746}
6747
6748/**
6749 * 触发事件监听方法
6750 * @param {Object} target 发生事件的对象
6751 * @param {String} type 事件类型
6752 * @param {Object} eventObj 触发事件时要传回的event对象
6753 * @return {undefined}
6754 */
6755function emitEventCache(target, type, eventObj) {
6756 var evt = _Object$create(null);
6757 evt.type = type;
6758 evt.target = target;
6759 if (eventObj) {
6760 _Object$assign(evt, isObject$1(eventObj) ? eventObj : { data: eventObj });
6761 }
6762 getEvtTypeCache(target, type).forEach(function (item) {
6763 (item[1] || item[0]).apply(target, [evt]);
6764 });
6765}
6766
6767/**
6768 * 添加事件监听到缓存
6769 * @param {Object} target 发生事件的对象
6770 * @param {String} type 事件类型
6771 * @param {Function} handler 监听函数
6772 * @param {Boolean} isOnce 是否单次执行
6773 * @param {Function} handlerWrap
6774 * @return {undefined}
6775 */
6776function addEventCache(target, type, handler) {
6777 var isOnce = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
6778 var handlerWrap = arguments[4];
6779
6780 if (isFunction(isOnce) && !handlerWrap) {
6781 handlerWrap = isOnce;
6782 isOnce = undefined;
6783 }
6784 var handlers = [handler, undefined, isOnce];
6785 if (isOnce && !handlerWrap) {
6786 handlerWrap = function handlerWrap() {
6787 removeEventCache(target, type, handler, isOnce);
6788
6789 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
6790 args[_key] = arguments[_key];
6791 }
6792
6793 handler.apply(target, args);
6794 };
6795 }
6796 if (handlerWrap) {
6797 handlers[1] = handlerWrap;
6798 }
6799 getEvtTypeCache(target, type).push(handlers);
6800}
6801
6802/**
6803 * 移除事件监听
6804 * @param {Object} target 发生事件的对象
6805 * @param {String} type 事件类型
6806 * @param {Function} handler 监听函数
6807 * @return {undefined}
6808 */
6809function removeEventCache(target, type, handler) {
6810 var isOnce = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
6811
6812 var typeCache = getEvtTypeCache(target, type);
6813
6814 if (handler || isOnce) {
6815 /* 有指定 handler 则清除对应监听 */
6816 var handlerId = -1;
6817 var handlerWrap = void 0;
6818 typeCache.find(function (item, i) {
6819 if ((!handler || item[0] === handler) && (!isOnce || item[2])) {
6820 handlerId = i;
6821 handlerWrap = item[1];
6822 return true;
6823 }
6824 });
6825 if (handlerId !== -1) {
6826 typeCache.splice(handlerId, 1);
6827 }
6828 return handlerWrap;
6829 } else {
6830 /* 未指定 handler 则清除type对应的所有监听 */
6831 typeCache.length = 0;
6832 }
6833}
6834
6835/**
6836 * @class CustEvent
6837 * @description
6838 * Event 自定义事件类
6839 * 1. 可以使用不传参得到的实例作为eventBus使用
6840 * 2. 可以通过指定target,用多个实例操作同一target对象的事件管理
6841 * 3. 当设定target时,可以通过设置assign为true,来给target实现"on\once\off\emit"方法
6842 * @param {Object} target 发生事件的对象(空则默认为event实例)
6843 * @param {Boolean} assign 是否将"on\once\off\emit"方法实现到target对象上
6844 * @return {event}
6845 */
6846var CustEvent = function () {
6847 function CustEvent(target, assign$$1) {
6848 var _this = this;
6849
6850 _classCallCheck(this, CustEvent);
6851
6852 /* 设置__target不可枚举 */
6853 Object.defineProperty(this, '__target', {
6854 writable: true,
6855 enumerable: false,
6856 configurable: true
6857 });
6858 this.__target = this;
6859
6860 if (target) {
6861
6862 if ((typeof target === 'undefined' ? 'undefined' : _typeof(target)) !== 'object') {
6863 throw new Error('CusEvent target are not object');
6864 }
6865 this.__target = target;
6866
6867 /* 为target实现on\once\off\emit */
6868 if (assign$$1) {
6869 ['on', 'once', 'off', 'emit'].forEach(function (mth) {
6870 target[mth] = _this[mth];
6871 });
6872 }
6873 }
6874 }
6875
6876 /**
6877 * 添加事件监听
6878 * @param {String} type 事件类型
6879 * @param {Function} handler 监听函数
6880 * @param {Boolean} isOnce 单次监听类型
6881 * @return {event}
6882 */
6883
6884
6885 _createClass(CustEvent, [{
6886 key: 'on',
6887 value: function on(type, handler) {
6888 var isOnce = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
6889
6890 addEventCache(this.__target, type, handler, isOnce);
6891 return this;
6892 }
6893
6894 /**
6895 * 添加事件监听,并且只执行一次
6896 * @param {String} type 事件类型
6897 * @param {Function} handler 监听函数
6898 * @return {event}
6899 */
6900
6901 }, {
6902 key: 'once',
6903 value: function once(type, handler) {
6904 return this.on(type, handler, true);
6905 }
6906
6907 /**
6908 * 移除事件监听
6909 * @param {String} type 事件类型
6910 * @param {Function} handler 监听函数(不指定handler则清除type对应的所有事件监听)
6911 * @param {Boolean} isOnce 单次监听类型
6912 * @return {event}
6913 */
6914
6915 }, {
6916 key: 'off',
6917 value: function off(type, handler) {
6918 var isOnce = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
6919
6920 removeEventCache(this.__target, type, handler, isOnce);
6921 return this;
6922 }
6923
6924 /**
6925 * 触发事件监听函数
6926 * @param {String} type 事件类型
6927 * @return {event}
6928 */
6929
6930 }, {
6931 key: 'emit',
6932 value: function emit(type, data) {
6933 emitEventCache(this.__target, type, { data: data });
6934 return this;
6935 }
6936 }]);
6937
6938 return CustEvent;
6939}();
6940
6941/**
6942 * chimee-helper-dom v0.1.0
6943 * (c) 2017 toxic-johann
6944 * Released under MIT
6945 */
6946
6947/**
6948 * chimee-helper-events v0.1.0
6949 * (c) 2017 toxic-johann
6950 * Released under MIT
6951 */
6952
6953/**
6954* @module event
6955* @author huzunjie
6956* @description 自定义事件基础类
6957*/
6958
6959/* 缓存事件监听方法及包装,内部数据格式:
6960 * targetIndex_<type:'click|mouseup|done'>: [ [
6961 * function(){ ... handler ... },
6962 * function(){ ... handlerWrap ... handler.apply(target, arguments) ... },
6963 * isOnce
6964 * ]]
6965 */
6966var _evtListenerCache$1 = _Object$create(null);
6967_evtListenerCache$1.count = 0;
6968
6969/**
6970 * 得到某对象的某事件类型对应的监听队列数组
6971 * @param {Object} target 发生事件的对象
6972 * @param {String} type 事件类型(这里的时间类型不只是名称,还是缓存标识,可以通过添加后缀来区分)
6973 * @return {Array}
6974 */
6975function getEvtTypeCache$1(target, type) {
6976
6977 var evtId = target.__evt_id;
6978 if (!evtId) {
6979
6980 /* 设置__evt_id不可枚举 */
6981 Object.defineProperty(target, '__evt_id', {
6982 writable: true,
6983 enumerable: false,
6984 configurable: true
6985 });
6986
6987 /* 空对象初始化绑定索引 */
6988 evtId = target.__evt_id = ++_evtListenerCache$1.count;
6989 }
6990
6991 var typeCacheKey = evtId + '_' + type;
6992 var evtTypeCache = _evtListenerCache$1[typeCacheKey];
6993 if (!evtTypeCache) {
6994 evtTypeCache = _evtListenerCache$1[typeCacheKey] = [];
6995 }
6996
6997 return evtTypeCache;
6998}
6999
7000/**
7001 * 触发事件监听方法
7002 * @param {Object} target 发生事件的对象
7003 * @param {String} type 事件类型
7004 * @param {Object} eventObj 触发事件时要传回的event对象
7005 * @return {undefined}
7006 */
7007function emitEventCache$1(target, type, eventObj) {
7008 var evt = _Object$create(null);
7009 evt.type = type;
7010 evt.target = target;
7011 if (eventObj) {
7012 _Object$assign(evt, isObject$1(eventObj) ? eventObj : { data: eventObj });
7013 }
7014 getEvtTypeCache$1(target, type).forEach(function (item) {
7015 (item[1] || item[0]).apply(target, [evt]);
7016 });
7017}
7018
7019/**
7020 * 添加事件监听到缓存
7021 * @param {Object} target 发生事件的对象
7022 * @param {String} type 事件类型
7023 * @param {Function} handler 监听函数
7024 * @param {Boolean} isOnce 是否单次执行
7025 * @param {Function} handlerWrap
7026 * @return {undefined}
7027 */
7028function addEventCache$1(target, type, handler) {
7029 var isOnce = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
7030 var handlerWrap = arguments[4];
7031
7032 if (isFunction(isOnce) && !handlerWrap) {
7033 handlerWrap = isOnce;
7034 isOnce = undefined;
7035 }
7036 var handlers = [handler, undefined, isOnce];
7037 if (isOnce && !handlerWrap) {
7038 handlerWrap = function handlerWrap() {
7039 removeEventCache$1(target, type, handler, isOnce);
7040
7041 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
7042 args[_key] = arguments[_key];
7043 }
7044
7045 handler.apply(target, args);
7046 };
7047 }
7048 if (handlerWrap) {
7049 handlers[1] = handlerWrap;
7050 }
7051 getEvtTypeCache$1(target, type).push(handlers);
7052}
7053
7054/**
7055 * 移除事件监听
7056 * @param {Object} target 发生事件的对象
7057 * @param {String} type 事件类型
7058 * @param {Function} handler 监听函数
7059 * @return {undefined}
7060 */
7061function removeEventCache$1(target, type, handler) {
7062 var isOnce = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
7063
7064 var typeCache = getEvtTypeCache$1(target, type);
7065
7066 if (handler || isOnce) {
7067 /* 有指定 handler 则清除对应监听 */
7068 var handlerId = -1;
7069 var handlerWrap = void 0;
7070 typeCache.find(function (item, i) {
7071 if ((!handler || item[0] === handler) && (!isOnce || item[2])) {
7072 handlerId = i;
7073 handlerWrap = item[1];
7074 return true;
7075 }
7076 });
7077 if (handlerId !== -1) {
7078 typeCache.splice(handlerId, 1);
7079 }
7080 return handlerWrap;
7081 } else {
7082 /* 未指定 handler 则清除type对应的所有监听 */
7083 typeCache.length = 0;
7084 }
7085}
7086
7087/**
7088 * @class CustEvent
7089 * @description
7090 * Event 自定义事件类
7091 * 1. 可以使用不传参得到的实例作为eventBus使用
7092 * 2. 可以通过指定target,用多个实例操作同一target对象的事件管理
7093 * 3. 当设定target时,可以通过设置assign为true,来给target实现"on\once\off\emit"方法
7094 * @param {Object} target 发生事件的对象(空则默认为event实例)
7095 * @param {Boolean} assign 是否将"on\once\off\emit"方法实现到target对象上
7096 * @return {event}
7097 */
7098var CustEvent$1 = function () {
7099 function CustEvent(target, assign$$1) {
7100 var _this = this;
7101
7102 _classCallCheck(this, CustEvent);
7103
7104 /* 设置__target不可枚举 */
7105 Object.defineProperty(this, '__target', {
7106 writable: true,
7107 enumerable: false,
7108 configurable: true
7109 });
7110 this.__target = this;
7111
7112 if (target) {
7113
7114 if ((typeof target === 'undefined' ? 'undefined' : _typeof(target)) !== 'object') {
7115 throw new Error('CusEvent target are not object');
7116 }
7117 this.__target = target;
7118
7119 /* 为target实现on\once\off\emit */
7120 if (assign$$1) {
7121 ['on', 'once', 'off', 'emit'].forEach(function (mth) {
7122 target[mth] = _this[mth];
7123 });
7124 }
7125 }
7126 }
7127
7128 /**
7129 * 添加事件监听
7130 * @param {String} type 事件类型
7131 * @param {Function} handler 监听函数
7132 * @param {Boolean} isOnce 单次监听类型
7133 * @return {event}
7134 */
7135
7136
7137 _createClass(CustEvent, [{
7138 key: 'on',
7139 value: function on(type, handler) {
7140 var isOnce = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
7141
7142 addEventCache$1(this.__target, type, handler, isOnce);
7143 return this;
7144 }
7145
7146 /**
7147 * 添加事件监听,并且只执行一次
7148 * @param {String} type 事件类型
7149 * @param {Function} handler 监听函数
7150 * @return {event}
7151 */
7152
7153 }, {
7154 key: 'once',
7155 value: function once(type, handler) {
7156 return this.on(type, handler, true);
7157 }
7158
7159 /**
7160 * 移除事件监听
7161 * @param {String} type 事件类型
7162 * @param {Function} handler 监听函数(不指定handler则清除type对应的所有事件监听)
7163 * @param {Boolean} isOnce 单次监听类型
7164 * @return {event}
7165 */
7166
7167 }, {
7168 key: 'off',
7169 value: function off(type, handler) {
7170 var isOnce = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
7171
7172 removeEventCache$1(this.__target, type, handler, isOnce);
7173 return this;
7174 }
7175
7176 /**
7177 * 触发事件监听函数
7178 * @param {String} type 事件类型
7179 * @return {event}
7180 */
7181
7182 }, {
7183 key: 'emit',
7184 value: function emit(type, data) {
7185 emitEventCache$1(this.__target, type, { data: data });
7186 return this;
7187 }
7188 }]);
7189
7190 return CustEvent;
7191}();
7192
7193/**
7194 * chimee-helper-utils v0.1.1
7195 * (c) 2017 toxic-johann
7196 * Released under MIT
7197 */
7198
7199// ********************** judgement ************************
7200/**
7201 * check if the code running in browser environment (not include worker env)
7202 * @returns {Boolean}
7203 */
7204var inBrowser$1 = typeof window !== 'undefined' && Object.prototype.toString.call(window) !== '[object Object]';
7205
7206// ********************** 对象操作 ************************
7207/**
7208 * 转变一个类数组对象为数组
7209 */
7210function makeArray$1(obj) {
7211 return _Array$from(obj);
7212}
7213
7214/**
7215* @module dom
7216* @author huzunjie
7217* @description 一些常用的DOM判断及操作方法,可以使用dom.$('*')包装DOM,实现类jQuery的链式操作;当然这里的静态方法也可以直接使用。
7218*/
7219
7220var _divEl = document.createElement('div');
7221var _textAttrName = 'innerText';
7222'textContent' in _divEl && (_textAttrName = 'textContent');
7223var _arrPrototype = Array.prototype;
7224
7225/**
7226 * 读取HTML元素属性值
7227 * @param {HTMLElement} el 目标元素
7228 * @param {String} attrName 目标属性名称
7229 * @return {String}
7230 */
7231function getAttr(el, attrName) {
7232 return el.getAttribute(attrName);
7233}
7234
7235/**
7236 * 设置HTML元素属性值
7237 * @param {HTMLElement} el 目标元素
7238 * @param {String} attrName 目标属性名称
7239 * @param {String} attrVal 目标属性值
7240 */
7241function setAttr(el, attrName, attrVal) {
7242 if (attrVal === undefined) {
7243 el.removeAttribute(attrName);
7244 } else {
7245 el.setAttribute(attrName, attrVal);
7246 }
7247}
7248
7249/**
7250 * 为HTML元素添加className
7251 * @param {HTMLElement} el 目标元素
7252 * @param {String} cls 要添加的className(多个以空格分割)
7253 */
7254function addClassName(el, cls) {
7255 if (!cls || !(cls = cls.trim())) {
7256 return;
7257 }
7258 var clsArr = cls.split(/\s+/);
7259 if (el.classList) {
7260 clsArr.forEach(function (c) {
7261 return el.classList.add(c);
7262 });
7263 } else {
7264 var curCls = ' ' + (el.className || '') + ' ';
7265 clsArr.forEach(function (c) {
7266 curCls.indexOf(' ' + c + ' ') === -1 && (curCls += ' ' + c);
7267 });
7268 el.className = curCls.trim();
7269 }
7270}
7271
7272/**
7273 * 为HTML元素移除className
7274 * @param {HTMLElement} el 目标元素
7275 * @param {String} cls 要移除的className(多个以空格分割)
7276 */
7277function removeClassName(el, cls) {
7278 if (!cls || !(cls = cls.trim())) {
7279 return;
7280 }
7281
7282 var clsArr = cls.split(/\s+/);
7283 if (el.classList) {
7284 clsArr.forEach(function (c) {
7285 return el.classList.remove(c);
7286 });
7287 } else {
7288 var curCls = ' ' + el.className + ' ';
7289 clsArr.forEach(function (c) {
7290 var tar = ' ' + c + ' ';
7291 while (curCls.indexOf(tar) !== -1) {
7292 curCls = curCls.replace(tar, ' ');
7293 }
7294 });
7295 el.className = curCls.trim();
7296 }
7297}
7298
7299/**
7300 * 检查HTML元素是否已设置className
7301 * @param {HTMLElement} el 目标元素
7302 * @param {String} className 要检查的className
7303 * @return {Boolean}
7304 */
7305function hasClassName(el, className) {
7306 return new RegExp('(?:^|\\s)' + className + '(?=\\s|$)').test(el.className);
7307}
7308
7309/**
7310 * 为HTML元素移除事件监听
7311 * @param {HTMLElement} el 目标元素
7312 * @param {String} type 事件名称
7313 * @param {Function} handler 处理函数
7314 * @param {Boolean} once 是否只监听一次
7315 * @param {Boolean} capture 是否在捕获阶段的监听
7316 */
7317function removeEvent(el, type, handler) {
7318 var once = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
7319 var capture = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
7320
7321 if (once) {
7322 /* 尝试从缓存中读取包装后的方法 */
7323 var handlerWrap = removeEventCache$1(el, type + '_once', handler);
7324 if (handlerWrap) {
7325 handler = handlerWrap;
7326 }
7327 }
7328 el.removeEventListener(type, handler, capture);
7329}
7330
7331/**
7332 * 为HTML元素添加事件监听
7333 * @param {HTMLElement} el 目标元素
7334 * @param {String} type 事件名称
7335 * @param {Function} handler 处理函数
7336 * @param {Boolean} once 是否只监听一次
7337 * @param {Boolean} capture 是否在捕获阶段监听
7338 */
7339function addEvent(el, type, handler) {
7340 var once = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
7341 var capture = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
7342
7343 if (once) {
7344 var oldHandler = handler;
7345 handler = function () {
7346 return function () {
7347 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
7348 args[_key] = arguments[_key];
7349 }
7350
7351 oldHandler.apply(this, args);
7352 removeEvent(el, type, handler, once, capture);
7353 };
7354 }();
7355 /* 将包装后的方法记录到缓存中 */
7356 addEventCache$1(el, type + '_once', oldHandler, handler);
7357 }
7358
7359 el.addEventListener(type, handler, capture);
7360}
7361
7362/**
7363 * 为HTML元素添加事件代理
7364 * @param {HTMLElement} el 目标元素
7365 * @param {String} selector 要被代理的元素
7366 * @param {String} type 事件名称
7367 * @param {Function} handler 处理函数
7368 * @param {Boolean} capture 是否在捕获阶段监听
7369 */
7370function addDelegate(el, selector, type, handler) {
7371 var capture = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
7372
7373
7374 var handlerWrap = function handlerWrap(e) {
7375 var targetEls = findParents(e.srcElement, el, true);
7376 var targetEl = query(selector, el, true).find(function (seEl) {
7377 return targetEls.find(function (tgEl) {
7378 return seEl === tgEl;
7379 });
7380 });
7381 targetEl && handler.apply(targetEl, arguments);
7382 };
7383 /* 将包装后的方法记录到缓存中 */
7384 addEventCache$1(el, type + '_delegate_' + selector, handler, handlerWrap);
7385 el.addEventListener(type, handlerWrap, capture);
7386}
7387
7388/**
7389 * 为HTML元素移除事件代理
7390 * @param {HTMLElement} el 目标元素
7391 * @param {String} selector 要被代理的元素
7392 * @param {String} type 事件名称
7393 * @param {Function} handler 处理函数
7394 * @param {Boolean} capture 是否在捕获阶段监听
7395 */
7396function removeDelegate(el, selector, type, handler) {
7397 var capture = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
7398
7399 /* 尝试从缓存中读取包装后的方法 */
7400 var handlerWrap = removeEventCache$1(el, type + '_delegate_' + selector, handler);
7401 handlerWrap && el.removeEventListener(type, handlerWrap, capture);
7402}
7403
7404/**
7405 * 读取HTML元素样式值
7406 * @param {HTMLElement} el 目标元素
7407 * @param {String} key 样式key
7408 * @return {String}
7409 */
7410function getStyle(el, key) {
7411 return (el.currentStyle || document.defaultView.getComputedStyle(el, null))[key] || el.style[key];
7412}
7413
7414/**
7415 * 设置HTML元素样式值
7416 * @param {HTMLElement} el 目标元素
7417 * @param {String} key 样式key
7418 * @param {String} val 样式值
7419 */
7420function setStyle(el, key, val) {
7421 if (isObject$1(key)) {
7422 for (var k in key) {
7423 setStyle(el, k, key[k]);
7424 }
7425 } else {
7426 el.style[key] = val;
7427 }
7428}
7429
7430/**
7431 * 根据选择器查询目标元素
7432 * @param {String} selector 选择器,用于 querySelectorAll
7433 * @param {HTMLElement} container 父容器
7434 * @param {Boolean} toArray 强制输出为数组
7435 * @return {NodeList|Array}
7436 */
7437function query(selector) {
7438 var container = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document;
7439 var toArray = arguments[2];
7440
7441 var retNodeList = container.querySelectorAll(selector);
7442 return toArray ? _Array$from(retNodeList) : retNodeList;
7443}
7444
7445/**
7446 * 从DOM树中移除el
7447 * @param {HTMLElement} el 目标元素
7448 */
7449function removeEl(el) {
7450 el.parentNode.removeChild(el);
7451}
7452
7453/**
7454 * 查找元素的父节点们
7455 * @param {HTMLElement} el 目标元素
7456 * @param {HTMLElement} endEl 最大父容器(不指定则找到html)
7457 * @param {Boolean} haveEl 包含当前元素
7458 * @param {Boolean} haveEndEl 包含设定的最大父容器
7459 */
7460function findParents(el) {
7461 var endEl = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
7462 var haveEl = arguments[2];
7463 var haveEndEl = arguments[3];
7464
7465 var retEls = [];
7466 if (haveEl) {
7467 retEls.push(el);
7468 }
7469 while (el && el.parentNode !== endEl) {
7470 el = el.parentNode;
7471 el && retEls.push(el);
7472 }
7473 if (haveEndEl) {
7474 retEls.push(endEl);
7475 }
7476 return retEls;
7477}
7478
7479/**
7480 * 根据选择器查询并得到目标元素的wrap包装器
7481 * @param {String} selector 选择器,另外支持 HTMLString||NodeList||NodeArray||HTMLElement
7482 * @param {HTMLElement} container 父容器
7483 * @return {Object}
7484 */
7485function $(selector, container) {
7486 return selector.constructor === NodeWrap ? selector : new NodeWrap(selector, container);
7487}
7488
7489/**
7490 * @class NodeWrap
7491 * @description
7492 * NodeWrap DOM包装器,用以实现基本的链式操作
7493 * new dom.NodeWrap('*') 相当于 dom.$('*')
7494 * 这里面用于DOM操作的属性方法都是基于上面静态方法实现,有需要可以随时修改补充
7495 * @param {String} selector 选择器(兼容 String||HTMLString||NodeList||NodeArray||HTMLElement)
7496 * @param {HTMLElement} container 父容器(默认为document)
7497 */
7498
7499var NodeWrap = function () {
7500 function NodeWrap(selector) {
7501 var container = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document;
7502
7503 _classCallCheck(this, NodeWrap);
7504
7505 var _this = this;
7506 _this.selector = selector;
7507
7508 /* String||NodeList||HTMLElement 识别处理 */
7509 var elsArr = void 0;
7510 if (selector && selector.constructor === NodeList) {
7511 /* 支持直接传入NodeList来构建包装器 */
7512 elsArr = makeArray$1(selector);
7513 } else if (isArray(selector)) {
7514 /* 支持直接传入Node数组来构建包装器 */
7515 elsArr = selector;
7516 } else if (isString(selector)) {
7517 if (selector.indexOf('<') === 0) {
7518 /* 支持直接传入HTML字符串来新建DOM并构建包装器 */
7519 _divEl.innerHTML = selector;
7520 elsArr = query('*', _divEl, true);
7521 } else {
7522 /* 支持直接传入字符串选择器来查找DOM并构建包装器 */
7523 elsArr = query(selector, container, true);
7524 }
7525 } else {
7526 /* 其他任意对象直接构建包装器 */
7527 elsArr = [selector];
7528 }
7529 _Object$assign(_this, elsArr);
7530
7531 /* NodeWrap本意可以 extends Array省略构造方法中下面这部分代码,但目前编译不支持 */
7532 _this.length = elsArr.length;
7533 }
7534
7535 /**
7536 * 循环遍历DOM集合
7537 * @param {Function} fn 遍历函数 fn(item, i)
7538 * @return {Object}
7539 */
7540
7541
7542 _createClass(NodeWrap, [{
7543 key: 'each',
7544 value: function each() {
7545 for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
7546 args[_key2] = arguments[_key2];
7547 }
7548
7549 _arrPrototype.forEach.apply(this, args);
7550 return this;
7551 }
7552 }, {
7553 key: 'push',
7554
7555
7556 /**
7557 * 添加元素到DOM集合
7558 * @param {HTMLElement} el 要加入的元素
7559 * @return {this}
7560 */
7561 value: function push() {
7562 for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
7563 args[_key3] = arguments[_key3];
7564 }
7565
7566 _arrPrototype.push.apply(this, args);
7567 return this;
7568 }
7569 }, {
7570 key: 'splice',
7571
7572
7573 /**
7574 * 截取DOM集合片段,并得到新的包装器splice
7575 * @param {Nubmer} start
7576 * @param {Nubmer} count
7577 * @return {NodeWrap} 新的DOM集合包装器
7578 */
7579 value: function splice() {
7580 for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
7581 args[_key4] = arguments[_key4];
7582 }
7583
7584 return $(_arrPrototype.splice.apply(this, args));
7585 }
7586 }, {
7587 key: 'find',
7588
7589
7590 /**
7591 * 查找子元素
7592 * @param {String} selector 选择器
7593 * @return {NodeWrap} 新的DOM集合包装器
7594 */
7595 value: function find(selector) {
7596 var childs = [];
7597 this.each(function (el) {
7598 childs = childs.concat(query(selector, el, true));
7599 });
7600 var childsWrap = $(childs);
7601 childsWrap.parent = this;
7602 childsWrap.selector = selector;
7603 return childsWrap;
7604 }
7605
7606 /**
7607 * 添加子元素
7608 * @param {HTMLElement} childEls 要添加的HTML元素
7609 * @return {this}
7610 */
7611
7612 }, {
7613 key: 'append',
7614 value: function append(childEls) {
7615 var childsWrap = $(childEls);
7616 var firstEl = this[0];
7617 childsWrap.each(function (newEl) {
7618 return firstEl.appendChild(newEl);
7619 });
7620 return this;
7621 }
7622
7623 /**
7624 * 将元素集合添加到指定容器
7625 * @param {HTMLElement} parentEl 要添加到父容器
7626 * @return {this}
7627 */
7628
7629 }, {
7630 key: 'appendTo',
7631 value: function appendTo(parentEl) {
7632 $(parentEl).append(this);
7633 return this;
7634 }
7635
7636 /**
7637 * DOM集合text内容读写操作
7638 * @param {String} val 文本内容(如果有设置该参数则执行写操作,否则执行读操作)
7639 * @return {this}
7640 */
7641
7642 }, {
7643 key: 'text',
7644 value: function text(val) {
7645 if (arguments.length === 0) {
7646 return this[0][_textAttrName];
7647 }
7648 return this.each(function (el) {
7649 el[_textAttrName] = val;
7650 });
7651 }
7652
7653 /**
7654 * DOM集合HTML内容读写操作
7655 * @param {String} html html内容(如果有设置该参数则执行写操作,否则执行读操作)
7656 * @return {this}
7657 */
7658
7659 }, {
7660 key: 'html',
7661 value: function html(_html) {
7662 if (arguments.length === 0) {
7663 return this[0].innerHTML;
7664 }
7665 return this.each(function (el) {
7666 el.innerHTML = _html;
7667 });
7668 }
7669
7670 /**
7671 * DOM集合属性读写操作
7672 * @param {String} name 属性名称
7673 * @param {String} val 属性值(如果有设置该参数则执行写操作,否则执行读操作)
7674 * @return {this}
7675 */
7676
7677 }, {
7678 key: 'attr',
7679 value: function attr(name, val) {
7680 if (arguments.length === 1) {
7681 return getAttr(this[0], name);
7682 }
7683 return this.each(function (el) {
7684 return setAttr(el, name, val);
7685 });
7686 }
7687
7688 /**
7689 * DOM集合dataset读写操作
7690 * @param {String} key 键名
7691 * @param {Any} val 键值(如果有设置该参数则执行写操作,否则执行读操作)
7692 * @return {this}
7693 */
7694
7695 }, {
7696 key: 'data',
7697 value: function data(key, val) {
7698 if (arguments.length === 0) {
7699 return this[0].dataset || {};
7700 }
7701 if (arguments.length === 1) {
7702 return (this[0].dataset || {})[key];
7703 }
7704 return this.each(function (el) {
7705 (el.dataset || (el.dataset = {}))[key] = val;
7706 });
7707 }
7708
7709 /**
7710 * DOM集合样式读写操作
7711 * @param {String} key 样式key
7712 * @param {String} val 样式值(如果有设置该参数则执行写操作,否则执行读操作)
7713 * @return {this}
7714 */
7715
7716 }, {
7717 key: 'css',
7718 value: function css(key, val) {
7719 if (arguments.length === 1 && !isObject$1(key)) {
7720 return getStyle(this[0], key);
7721 }
7722 return this.each(function (el) {
7723 return setStyle(el, key, val);
7724 });
7725 }
7726
7727 /**
7728 * 为DOM集合增加className
7729 * @param {String} cls 要增加的className
7730 * @return {this}
7731 */
7732
7733 }, {
7734 key: 'addClass',
7735 value: function addClass(cls) {
7736 return this.each(function (el) {
7737 return addClassName(el, cls);
7738 });
7739 }
7740
7741 /**
7742 * 移除当前DOM集合的className
7743 * @param {String} cls 要移除的className
7744 * @return {this}
7745 */
7746
7747 }, {
7748 key: 'removeClass',
7749 value: function removeClass(cls) {
7750 return this.each(function (el) {
7751 return removeClassName(el, cls);
7752 });
7753 }
7754
7755 /**
7756 * 检查索引0的DOM是否有className
7757 * @param {String} cls 要检查的className
7758 * @return {this}
7759 */
7760
7761 }, {
7762 key: 'hasClass',
7763 value: function hasClass(cls) {
7764 return hasClassName(this[0], cls);
7765 }
7766
7767 /**
7768 * 为DOM集合添加事件监听
7769 * @param {String} type 事件名称
7770 * @param {Function} handler 处理函数
7771 * @param {Boolean} once 是否只监听一次
7772 * @param {Boolean} capture 是否在捕获阶段监听
7773 * @return {this}
7774 */
7775
7776 }, {
7777 key: 'on',
7778 value: function on(type, handler) {
7779 var once = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
7780 var capture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
7781
7782 return this.each(function (el) {
7783 return addEvent(el, type, handler, once, capture);
7784 });
7785 }
7786
7787 /**
7788 * 为DOM集合解除事件监听
7789 * @param {String} type 事件名称
7790 * @param {Function} handler 处理函数
7791 * @param {Boolean} once 是否只监听一次
7792 * @param {Boolean} capture 是否在捕获阶段监听
7793 * @return {this}
7794 */
7795
7796 }, {
7797 key: 'off',
7798 value: function off(type, handler) {
7799 var once = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
7800 var capture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
7801
7802 return this.each(function (el) {
7803 return removeEvent(el, type, handler, once, capture);
7804 });
7805 }
7806
7807 /**
7808 * 为DOM集合绑定事件代理
7809 * @param {String} selector 目标子元素选择器
7810 * @param {String} type 事件名称
7811 * @param {Function} handler 处理函数
7812 * @param {Boolean} capture 是否在捕获阶段监听
7813 * @return {this}
7814 */
7815
7816 }, {
7817 key: 'delegate',
7818 value: function delegate(selector, type, handler) {
7819 var capture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
7820
7821 return this.each(function (el) {
7822 return addDelegate(el, selector, type, handler, capture);
7823 });
7824 }
7825
7826 /**
7827 * 为DOM集合解绑事件代理
7828 * @param {String} selector 目标子元素选择器
7829 * @param {String} type 事件名称
7830 * @param {Function} handler 处理函数
7831 * @param {Boolean} capture 是否在捕获阶段监听
7832 * @return {this}
7833 */
7834
7835 }, {
7836 key: 'undelegate',
7837 value: function undelegate(selector, type, handler) {
7838 var capture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
7839
7840 return this.each(function (el) {
7841 return removeDelegate(el, selector, type, handler, capture);
7842 });
7843 }
7844
7845 /**
7846 * 从DOM树中移除
7847 * @return {this}
7848 */
7849
7850 }, {
7851 key: 'remove',
7852 value: function remove() {
7853 return this.each(function (el) {
7854 return removeEl(el);
7855 });
7856 }
7857 }]);
7858
7859 return NodeWrap;
7860}();
7861
7862/**
7863 * chimee-helper-log v0.1.0
7864 * (c) 2017 songguangyu
7865 * Released under MIT
7866 */
7867
7868var Log = function () {
7869 function Log() {
7870 _classCallCheck(this, Log);
7871 }
7872
7873 _createClass(Log, null, [{
7874 key: 'error',
7875 value: function error(tag, msg) {
7876 if (!Log.ENABLE_ERROR) {
7877 return;
7878 }
7879
7880 if (!tag || Log.FORCE_GLOBAL_TAG) {
7881 tag = Log.GLOBAL_TAG;
7882 }
7883 var str = '[' + tag + '] > ' + msg;
7884
7885 if (console.error) {
7886 console.error(str);
7887 } else if (console.warn) {
7888 console.warn(str);
7889 } else {
7890 console.log(str);
7891 }
7892 }
7893 }, {
7894 key: 'info',
7895 value: function info(tag, msg) {
7896 if (!Log.ENABLE_INFO) {
7897 return;
7898 }
7899
7900 if (!tag || Log.FORCE_GLOBAL_TAG) {
7901 tag = Log.GLOBAL_TAG;
7902 }
7903
7904 var str = '[' + tag + '] > ' + msg;
7905
7906 if (console.info) {
7907 console.info(str);
7908 } else {
7909 console.log(str);
7910 }
7911 }
7912 }, {
7913 key: 'warn',
7914 value: function warn(tag, msg) {
7915 if (!Log.ENABLE_WARN) {
7916 return;
7917 }
7918
7919 if (!tag || Log.FORCE_GLOBAL_TAG) {
7920 tag = Log.GLOBAL_TAG;
7921 }
7922
7923 var str = '[' + tag + '] > ' + msg;
7924
7925 if (console.warn) {
7926 console.warn(str);
7927 } else {
7928 console.log(str);
7929 }
7930 }
7931 }, {
7932 key: 'debug',
7933 value: function debug(tag, msg) {
7934 if (!Log.ENABLE_DEBUG) {
7935 return;
7936 }
7937
7938 if (!tag || Log.FORCE_GLOBAL_TAG) {
7939 tag = Log.GLOBAL_TAG;
7940 }
7941
7942 var str = '[' + tag + '] > ' + msg;
7943
7944 if (console.debug) {
7945 console.debug(str);
7946 } else {
7947 console.log(str);
7948 }
7949 }
7950 }, {
7951 key: 'verbose',
7952 value: function verbose(tag, msg) {
7953 if (!Log.ENABLE_VERBOSE) {
7954 return;
7955 }
7956
7957 if (!tag || Log.FORCE_GLOBAL_TAG) {
7958 tag = Log.GLOBAL_TAG;
7959 }
7960
7961 console.log('[' + tag + '] > ' + msg);
7962 }
7963 }]);
7964
7965 return Log;
7966}();
7967
7968Log.GLOBAL_TAG = 'chimee';
7969Log.FORCE_GLOBAL_TAG = false;
7970Log.ENABLE_ERROR = true;
7971Log.ENABLE_INFO = true;
7972Log.ENABLE_WARN = true;
7973Log.ENABLE_DEBUG = true;
7974Log.ENABLE_VERBOSE = true;
7975
7976exports.Log = Log;
7977exports.genTraversalHandler = genTraversalHandler;
7978exports.deepClone = deepClone;
7979exports.deepAssign = deepAssign;
7980exports.camelize = camelize;
7981exports.hypenate = hypenate;
7982exports.bind = bind;
7983exports.uuid = uuid;
7984exports.S4 = S4;
7985exports.rand = rand;
7986exports.isVoid = isVoid;
7987exports.isArray = isArray;
7988exports.isFunction = isFunction;
7989exports.isObject = isObject$1;
7990exports.isNumber = isNumber;
7991exports.isNumeric = isNumeric;
7992exports.isInteger = isInteger;
7993exports.isEmpty = isEmpty;
7994exports.isEvent = isEvent;
7995exports.isBlob = isBlob;
7996exports.isFile = isFile;
7997exports.isDate = isDate;
7998exports.isString = isString;
7999exports.isBoolean = isBoolean;
8000exports.isPromise = isPromise;
8001exports.isPrimitive = isPrimitive;
8002exports.isUrl = isUrl;
8003exports.isNode = isNode;
8004exports.isElement = isElement;
8005exports.isChildNode = isChildNode;
8006exports.isPosterityNode = isPosterityNode;
8007exports.isHTMLString = isHTMLString;
8008exports.isError = isError;
8009exports.inBrowser = inBrowser;
8010exports.makeArray = makeArray;
8011exports.transObjectAttrIntoArray = transObjectAttrIntoArray;
8012exports.runRejectableQueue = runRejectableQueue;
8013exports.runStoppableQueue = runStoppableQueue;
8014exports.setFrozenAttr = setFrozenAttr;
8015exports.setAttrGetterAndSetter = setAttrGetterAndSetter;
8016exports.decodeUTF8 = decodeUTF8;
8017exports.debounce = debounce;
8018exports.throttle = throttle;
8019exports.raf = raf;
8020exports.caf = caf;
8021exports.strRepeat = strRepeat;
8022exports.formatTime = formatTime;
8023exports.addTransMethod = addTransMethod;
8024exports.appendCSS = appendCSS;
8025exports.formatDate = formatDate;
8026exports.getLocalStorage = getLocalStorage;
8027exports.setLocalStorage = setLocalStorage;
8028exports.emitEventCache = emitEventCache;
8029exports.addEventCache = addEventCache;
8030exports.removeEventCache = removeEventCache;
8031exports.CustEvent = CustEvent;
8032exports.getAttr = getAttr;
8033exports.setAttr = setAttr;
8034exports.addClassName = addClassName;
8035exports.removeClassName = removeClassName;
8036exports.hasClassName = hasClassName;
8037exports.removeEvent = removeEvent;
8038exports.addEvent = addEvent;
8039exports.addDelegate = addDelegate;
8040exports.removeDelegate = removeDelegate;
8041exports.getStyle = getStyle;
8042exports.setStyle = setStyle;
8043exports.query = query;
8044exports.removeEl = removeEl;
8045exports.findParents = findParents;
8046exports.$ = $;
8047exports.NodeWrap = NodeWrap;
8048
8049Object.defineProperty(exports, '__esModule', { value: true });
8050
8051})));
8052
8053
8054/***/ })
8055/******/ ]);
\No newline at end of file